图像梯度-sobel算子


(1)理论部分


x 水平方向的梯度, 其实也就是右边 - 左边,有的权重为1,有的为2 。
若是计算出来的值很大 说明是一个边界 。

在这里插入图片描述
y 竖直方向的梯度,其实也就是下面减上面,权重1,或2 。
若是计算出来的值很大 说明是一个边界 。

在这里插入图片描述
图像的梯度为:
在这里插入图片描述
有时简化为:
在这里插入图片描述
即:
在这里插入图片描述


(2)程序部分


函数:Sobel

在这里插入图片描述
ddepth 通常取 -1,表示取值范围为0-255,这样会导致结果溢出,检测不出边缘,故使用cv2.CV_64F增大数值范围。但是一般增大范围也没用,因为负值会默认为0,故要结合convertScaleAbs使用,将负数调为正数。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
通常不写后面两个参数

计算sobel算子 两种方式:
1,dx=1 dy=1 这种方法不太严谨
2,分别计算dx dy 再相加 为了防止相加之后大于255溢出 通常加个系数
在这里插入图片描述
在这里插入图片描述
用下面这个函数实现
在这里插入图片描述
结果= 图像1 *系数 + 图像2 *系数 + 修正值

将ddepth 分别设置为-1 和 cv2.CV_64F对比 发现均没有检测到全部的边界。原因是计算结果仍然为负数。

import cv2
a=cv2.imread('image\\sobel.bmp',cv2.IMREAD_GRAYSCALE)
sobelx=cv2.Sobel(a,-1,1,0)
sobelx1=cv2.Sobel(a,cv2.CV_64F,1,0)
cv2.imshow('a',a)
cv2.imshow('sobelx',sobelx)
cv2.imshow('sobelx1',sobelx1)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述

正确的如下所示:

import cv2

a=cv2.imread('image\\sobel.bmp',cv2.IMREAD_GRAYSCALE)
sobelx=cv2.Sobel(a,-1,1,0)             #水平梯度
sobelx1=cv2.Sobel(a,cv2.CV_64F,1,0)    #水平梯度
sobelx2=cv2.convertScaleAbs(sobelx1)   #负数取绝对值
cv2.imshow('a',a)
cv2.imshow('sobelx',sobelx)
cv2.imshow('sobelx1',sobelx1)
cv2.imshow('sobelx2',sobelx2)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述

import cv2
a=cv2.imread('image\\sobel.bmp',cv2.IMREAD_GRAYSCALE)
sobelx=cv2.Sobel(a,cv2.CV_64F,1,0)    #水平梯度
sobely=cv2.Sobel(a,cv2.CV_64F,0,1)    #竖直梯度
sobelx=cv2.convertScaleAbs(sobelx)    #负数取绝对值
sobely=cv2.convertScaleAbs(sobely)    #负数取绝对值
sobelxy=cv2.addWeighted(sobelx,0.5,sobely,0.5,0)  #求sobel算子,系数为0.5,0.5。修正值为0
cv2.imshow('a',a)
cv2.imshow('sobelx',sobelx)
cv2.imshow('sobelx1',sobely)
cv2.imshow('sobelxy',sobelxy)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述

对比一下fx fy 均为1的情况,发现只检测到一些点

import cv2
a=cv2.imread('image\\sobel.bmp',cv2.IMREAD_GRAYSCALE)
sobelx=cv2.Sobel(a,cv2.CV_64F,1,0)    #水平梯度
sobely=cv2.Sobel(a,cv2.CV_64F,0,1)    #竖直梯度
sobelx=cv2.convertScaleAbs(sobelx)    #负数取绝对值
sobely=cv2.convertScaleAbs(sobely)    #负数取绝对值
sobelxy=cv2.addWeighted(sobelx,0.5,sobely,0.5,0)  #求sobel算子,系数为0.5,0.5。修正值为0
sobelxy11=cv2.Sobel(a,cv2.CV_64F,1,1)
sobelxy11=cv2.convertScaleAbs(sobelxy11)
cv2.imshow('a',a)
cv2.imshow('sobelxy',sobelxy)
cv2.imshow('sobelxy11',sobelxy11)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/sundanping_123/article/details/86499500