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')
相关推荐
L.fountain15 分钟前
图像自回归生成(Auto-regressive image generation)实战学习(一)
人工智能·深度学习·学习·计算机视觉·图像自回归
摘星编程26 分钟前
Ascend C编程语言详解:打造高效AI算子的利器
c语言·开发语言·人工智能
phoenix@Capricornus29 分钟前
气泡自动计数——数字图像处理设计题
计算机视觉
技术净胜30 分钟前
MATLAB进行图像分割从基础阈值到高级分割
opencv·计算机视觉·matlab
DisonTangor36 分钟前
【小米拥抱开源】小米MiMo团队开源309B专家混合模型——MiMo-V2-Flash
人工智能·开源·aigc
hxxjxw1 小时前
Pytorch分布式训练/多卡训练(六) —— Expert Parallelism (MoE的特殊策略)
人工智能·pytorch·python
Robot侠1 小时前
视觉语言导航从入门到精通(一)
网络·人工智能·microsoft·llm·vln
掘金一周1 小时前
【用户行为监控】别只做工具人了!手把手带你写一个前端埋点统计 SDK | 掘金一周 12.18
前端·人工智能·后端
神州问学1 小时前
世界模型:AI的下一个里程碑
人工智能
zhaodiandiandian1 小时前
AI深耕产业腹地 新质生产力的实践路径与价值彰显
人工智能