openCV实战-系列教程4:图像梯度计算(Sobel算子/开运算/梯度计算方法/scharr算子/lapkacian算子)、源码解读

1、sobel算子

先读进来一个原型白色图

python 复制代码
img = cv2.imread('pie.png',cv2.IMREAD_GRAYSCALE)
cv2.imshow("img",img)
cv2.waitKey()
cv2.destroyAllWindows()

打印结果:

如图有两个3*3的卷积核,其中A是原始图片中的一个3*3的区域,这个A和3*3的卷积核所谓对应位置相乘的结果就分别是左右梯度和上下梯度

假如A是这个矩阵:

那么Gx的计算结果就为:-x1+x3-2x4+2x6-x7+x9

代码实现就很简单了,直接一行就行:

python 复制代码
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)

cv_show(sobelx,'sobelx')

dst = cv2.Sobel(src, ddepth, dx, dy, ksize)

  • src:原始图像
  • ddepth:图像的深度
  • dx和dy分别表示水平和竖直方向
  • ksize是Sobel算子的大小,就是一个卷积核的大小

打印一个图片可以做出一个函数:

python 复制代码
def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()

将上面的结果打印出来:

python 复制代码
cv_show(sobelx,'sobelx')

因为我们指定的是dx=1,dy=0,所以只计算了水平方向,很显然只有边界的地方才会有梯度

2、梯度计算方法

安装第1节的计算方法,白色减去黑色结果是正的,黑色减去白色结果就会为负数,而openCV的像素值在0-255,所以会将负数显示为0。如果加上绝对值就可以显示成右边的一圈白色了。

python 复制代码
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
cv_show(sobelx,'sobelx')

打印结果:

同样的方法计算一下上下梯度:

python 复制代码
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely)  
cv_show(sobely,'sobely')

打印结果:

分别计算水平方向和竖直方向再打印:

python 复制代码
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show(sobelxy,'sobelxy')

打印结果:

不建议直接把dx和dy都直接设置成1:

python 复制代码
sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)
sobelxy = cv2.convertScaleAbs(sobelxy) 
cv_show(sobelxy,'sobelxy')

打印结果:

换一个图做一遍,先打印原图:

python 复制代码
img = cv2.imread('lena.jpg',cv2.IMREAD_GRAYSCALE)
cv_show(img,'img')

打印结果:

python 复制代码
img = cv2.imread('lena.jpg',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely)
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show(sobelxy,'sobelxy')

第二行、第四行分别计算sobelx和sobely,第三行、第五行分别取绝对值,第六行最后融合在一起

,打印结果:

3、scharr算子和lapkacian算子

scharr夏尔

lapkacian拉普拉斯

scharr算子就是让结果更加敏感一些,lapkacian算子在推导过程使用了二阶导,lapkacian对噪音点会比较敏感,但是对于梯度的计算或者说边缘检测就不是那么友好了,所以lapkacian算子经常和其他方法结合在一起进行使用。

如上图,它不是和其他算子一样,有一个左右和上下的计算,它将目标像素值乘以-4然后加上上下左右的值。因为lapkacian没有分水平和竖直两个方式,所以不需要分开再合并了。

将三种方法都做一遍,放在一起进行比较:

python 复制代码
#不同算子的差异
img = cv2.imread('lena.jpg',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)   
sobely = cv2.convertScaleAbs(sobely)  
sobelxy =  cv2.addWeighted(sobelx,0.5,sobely,0.5,0)  

scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)
scharry = cv2.Scharr(img,cv2.CV_64F,0,1)
scharrx = cv2.convertScaleAbs(scharrx)   
scharry = cv2.convertScaleAbs(scharry)  
scharrxy =  cv2.addWeighted(scharrx,0.5,scharry,0.5,0) 

laplacian = cv2.Laplacian(img,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)   

res = np.hstack((sobelxy,scharrxy,laplacian))
cv_show(res,'res')

打印结果:

很明显scharr算子更加敏感一下,计算出了更多的细节和线条

最后看看原始图长什么样子:

python 复制代码
img = cv2.imread('lena.jpg',cv2.IMREAD_GRAYSCALE)
cv_show(img,'img')
相关推荐
AI绘画咪酱3 分钟前
Stable Diffusion【进阶篇】:如何实现人脸一致
人工智能·深度学习·学习·机器学习·ai作画·stable diffusion
vx_33076231723 分钟前
vos3000外呼系统怎么给普通用户开通播放下载录音权限?
运维·服务器·人工智能·ai·媒体
孔令飞5 分钟前
如何使用Docker在本地运行一个大模型?
人工智能·云原生·go
蚝油菜花11 分钟前
这个开源AI平台把文生图/音/字全包了!Pollinations.AI:提供完全免费的AI内容生成
人工智能·开源
补三补四17 分钟前
CNN卷积神经网络
人工智能·深度学习·神经网络·机器学习·cnn
山茶君_nlefer17 分钟前
高德AI MCP + Cursor 旅行规划神器。用它直接生成五一出行旅行计划!【附详细教程+提示词】
人工智能
AI_Auto18 分钟前
AI Agent系列(九) -Data Agent(数据分析智能体)
人工智能·数据挖掘·数据分析
zozowind19 分钟前
1Panel快速安装Dify指南
人工智能·后端
蚝油菜花19 分钟前
测试工程师要失业?Magnitude:开源AI Agent驱动的端到端测试框架,让Web测试更智能,自动完善测试用例!
人工智能·开源
卓豪终端管理32 分钟前
如何安全地管理固定功能设备?
java·大数据·开发语言·网络·人工智能·安全