图像的卷积,可以理解为kernel和像素点pixel之间的运算。
把kernel旋转180度(图像是反过来的),使其中心压在图片的第一个像素点,然后每个点和kernel对应的数值相乘,然后把各个值累加得到一个新的值,取代kernel中心压着的像素值。在进行这个运算时,需要copy一下原图或者创建一个size一样的图片,不能直接在原图上修改。
例:
注意:
在图片的某一像素点周围没有足够的值时,比如左上角,忽略最外边的一圈像素或者给边缘插值,然后计算再把边缘扔掉。
New value取值为0-255,小于0认为是0,大于255认为是255。
kernel一般取奇数矩阵
图像边缘提取
图像边缘来源于不同颜色、纹理、光照、表面。
Step edge(阶跃函数) 一阶导数 一个峰值
Ramp edge(缓慢上升) 二阶导数 两个峰值
Peak edge(矩形信号) 一阶导数 一个峰值
图像的导数可以用梯度来表示,但是计算梯度比较麻烦而且效率略低。计算导数需要用到剑减法来求变化率,这就衍生出一些算子,类似于通过分配权重的方式计算梯度。
Sobel算子其主要用于边缘检测,在技术上它是以离散型的差分算子,用来运算图像亮度函数的梯度的近似值,Sobel算子是典型的基于一阶导数的边缘检测算子,由于该算子中引入了类似局部平均的运算,因此对噪声具有平滑作用,能很好的消除噪声的影响。Sobel算子对于象素的位置的影响做了加权,与Prewitt算子、Roberts算子相比因此效果更好。
Gx = [[-1,0,1],[-2,0,2],[-1,0,1]]
Gy = [[-1,-2,-1],[0,0,0],[1,2,1]]
Gxy = |Gx|+|Gy|
Prewitt 算子
Gx |
|
Gy |
||||
-1 |
-1 |
-1 |
|
-1 |
0 |
1 |
0 |
0 |
0 |
|
-1 |
0 |
1 |
1 |
1 |
1 |
|
-1 |
0 |
1 |
Laplacian算子
四邻域 kernel = [[0,1,0],[1,-4,1],[0,1,0]]
八邻域 kernel = [[1,1,1],[1,-8,1],[1,1,1]]
Laplacian算子默认四邻域
sobel算子和Laplacian算子的API及其使用
1 def soble_demo(src):
2 gray_x = cv.Sobel(src, cv.CV_32F, 1, 0)
3 # gray_x = cv.Scharr(src, cv.CV_32F, 1, 0) (增强版Sobel)
4 gray_y = cv.Sobel(src, cv.CV_32F, 0, 1)
5 grayx = cv.convertScaleAbs(gray_x) #取绝对值
6 grayy = cv.convertScaleAbs(gray_y)
7 cv.imshow("gradient_x", grayx)
8 cv.imshow("gradient_y", grayy)
9 Gxy = cv.addWeighted(grayx, 0.5, grayy, 0.5, 0)
10 cv.imshow("gradient_xy", Gxy)
1 def Laplacian_demo(src):
2 kernel = np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]])
3 dst = cv.filter2D(src, cv.CV_32F, kernel=kernel)
4 dst = cv.convertScaleAbs(dst)
5 cv.imshow("laplacian_8_demo", dst)
6 #自定义八邻域算子
7 dst2 = cv.Laplacian(src, cv.CV_32F)
8 dst2 = cv.convertScaleAbs(dst2)
9 cv.imshow("Laplacian_4_demo", dst2)
除噪(conherence incorherene)
高斯滤波
Derta 越大平滑越厉害
对图像做平均,使中心点获得更多的权重,边缘较少,以达到去除噪点的目的
中值滤波(median filter) kernel各个值都是1/9 参数就是kernel的大小
每个点获得同样的权重,有时候会丢失原来的属性