图像梯度
清晰图像和模糊图像之间的差别在哪里呢?
从逻辑上考虑,图像模糊是因为图像中物体的轮廓不明显,轮廓边缘灰度变化不强烈,层次感不强造成的
反过来考虑,轮廓边缘灰度变化明显些,层次感强些是不是图像就更清晰些呢。
那么,这种灰度变化明显不明显怎样去定义呢?
知道微分就是求函数的变化率,即导数(梯度),那么对于图像来说,可不可以用微分来表示图像灰度的变化率呢,当然是可以的,前面我们提到过,图像就是函数嘛。
因为图像是一个离散的二维函数,ϵϵ不能无限小,我们的图像是按照像素来离散的,最小的ϵϵ就是1像素。因此,上面的图像微分又变成了如下的形式(ϵ=1ϵ=1):
这分别是图像在(x, y)点处x方向和y方向上的梯度,从上面的表达式可以看出来,图像的梯度相当于2个相邻像素之间的差值。
图片演示梯度过程
我们先考虑下x方向,选取某个像素,假设其像素值是100,沿x方向的相邻像素分别是90,90,90,则根据上面的计算其x方向梯度分别是10,0,0。这里只取变化率的绝对值,表明变化的大小即可。
我们看到,100和90之间亮度相差10,并不是很明显,与一大群90的连续灰度值在一起,轮廓必然是模糊的。我们注意到,如果相邻像素灰度值有变化,那么梯度就有值,如果相邻像素灰度值没有变化,那么梯度就为0。如果我们把梯度值与对应的像素相加,那么灰度值没有变化的,像素值不变,而有梯度值的,灰度值变大了。
我们看到,相加后的新图像,原图像像素点100与90亮度只相差10,现在是110与90,亮度相差20了,对比度显然增强了,尤其是图像中物体的轮廓和边缘,与背景大大加强了区别,这就是用梯度来增强图像的原理。
二 索贝尔算子
代码
import cv2 as cv #图像梯度:索贝尔算子 def sobel_image(image): grad_x=cv.Sobel(image,cv.CV_32F,1,0) #x方向导数 grad_y=cv.Sobel(image,cv.CV_32F,0,1) #y方向导数 gradx=cv.convertScaleAbs(grad_x) #颜色变化在水平分层 grady=cv.convertScaleAbs(grad_y) #颜色变化在垂直分层 cv.imshow("X方向", gradx) # 颜色变化在水平分层 cv.imshow("Y方向", grady) # 颜色变化在垂直分层 gradxy=cv.addWeighted(gradx,0.5,grady,0.5,0) cv.imshow('merge',gradxy) src = cv.imread("ying.jpg") cv.imshow("before", src) sobel_image(src) cv.waitKey(0) cv.destroyAllWindows()
效果展示
三 scharr算子
代码
import cv2 as cv #图像梯度:scharr算子:增强边缘 def scharr_image(image): grad_x = cv.Scharr(image, cv.CV_32F, 1, 0)#x方向导数 grad_y = cv.Scharr(image, cv.CV_32F, 0, 1)#y方向导数 gradx = cv.convertScaleAbs(grad_x) grady = cv.convertScaleAbs(grad_y) cv.imshow("X -go", gradx)#颜色变化在水平分层 cv.imshow("Y -go", grady)#颜色变化在垂直分层 gradxy = cv.addWeighted(gradx, 0.5, grady, 0.5, 0) cv.imshow("merge", gradxy) src = cv.imread("ying.jpg") cv.imshow("before", src) scharr_image(src) cv.waitKey(0) cv.destroyAllWindows()
效果展示
四 拉普拉斯算子
代码
import cv2 as cv #图像梯度:scharr算子:增强边缘 def lapalian_image(image): dst=cv.Laplacian(image,cv.CV_32F) lpls=cv.convertScaleAbs(dst) cv.imshow('lpls',lpls) src = cv.imread("ying.jpg") cv.imshow("before", src) lapalian_image(src) cv.waitKey(0) cv.destroyAllWindows()
效果展示