Opencv 图像梯度计算

4.1 Sobel算子

Sobel算子主要计算图像在水平和垂直方向上的梯度,从而检测图像中的边缘。

Sobel算子通过两个3×3的卷积核分别计算水平方向和垂直方向的梯度:
G x = [ − 1 0 + 1 − 2 0 + 2 − 1 0 + 1 ] ∗ A and G y = [ − 1 − 2 − 1 0 0 0 + 1 + 2 + 1 ] ∗ A \mathbf{G}_x = \begin{bmatrix}-1 & 0 & +1 \\-2 & 0 & +2 \\-1 & 0 & +1\end{bmatrix} * \mathbf{A} \quad \text{and} \quad\mathbf{G}_y = \begin{bmatrix}-1 & -2 & -1 \\0 & 0 & 0 \\+1 & +2 & +1\end{bmatrix} * \mathbf{A} Gx= −1−2−1000+1+2+1 ∗AandGy= −10+1−20+2−10+1 ∗A

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

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

  • ddepth:图像的深度。-1表示和输入和输出一样大小
  • dx和dy分别表示水平和竖直方向,1表示计算,0表示不计算
  • ksize是Sobel算子的大小

接下来利用Sobel算子计算水平方向上的梯度

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

由于梯度计算中有可能会出现截断或溢出的现象,因此采用64位浮点类型来存储数据

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

为什么右边检测不到边缘呢?

注意水平方向的梯度计算是边的右边减去左边,⚪的左边计算白到黑是正数,那么右边黑到白就是负数了,所有的负数会被截断成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)
cv_show(sobelxy, 'sobelxy')

不建议直接计算两个方向,上下左右四个点的部分边界会不明显

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)
cv2.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)
# 最后一个参数gamma可以是任何实数,正值会使图像变亮,负值会使图像变暗,0表示没有影响
cv_show(sobelxy,'sobelxy')

4.2 Scharr算子

G x = [ − 3 0 3 − 10 0 10 − 3 0 3 ] ∗ A and G y = [ − 3 − 10 − 3 0 0 0 − 3 − 10 − 3 ] ∗ A \mathbf{G}_x = \begin{bmatrix}-3 & 0 & 3 \\-10 & 0 & 10 \\-3 & 0 & 3\end{bmatrix} * \mathbf{A} \quad \text{and} \quad\mathbf{G}_y = \begin{bmatrix}-3 & -10 & -3 \\0 & 0 & 0 \\-3 & -10 & -3\end{bmatrix} * \mathbf{A} Gx= −3−10−30003103 ∗AandGy= −30−3−100−10−30−3 ∗A

python 复制代码
# cv2.Scharr 函数中没有 ksize 参数,卷积核大小是固定的
scharrx = cv2.Scharr(img, cv2.CV_64F, 1, 0)
scharrx = cv2.convertScaleAbs(scharrx)
scharry = cv2.Scharr(img, cv2.CV_64F, 0, 1)
scharry = cv2.convertScaleAbs(scharry)
scharrxy = cv2.addWeighted(scharrx, 0.5, scharry, 0.5, 0)
cv_show(scharrxy, 'scharrxy')

4.3 laplacian算子

G = [ 0 1 0 1 − 4 1 0 1 0 ] \mathbf{G} = \begin{bmatrix}0 & 1 & 0 \\1 & -4 & 1 \\0 & 1 & 0\end{bmatrix} G= 0101−41010

python 复制代码
laplacian = cv2.Laplacian(img, cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)
cv_show(laplacian, 'laplacian')
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算子的边缘定位更精确,可以检测到更细的边缘。

相关推荐
云知谷39 分钟前
【C++基本功】C++适合做什么,哪些领域适合哪些领域不适合?
c语言·开发语言·c++·人工智能·团队开发
rit84324991 小时前
基于MATLAB实现基于距离的离群点检测算法
人工智能·算法·matlab
初学小刘2 小时前
深度学习:从图片数据到模型训练(十分类)
人工智能·深度学习
递归不收敛3 小时前
大语言模型(LLM)入门笔记:嵌入向量与位置信息
人工智能·笔记·语言模型
之墨_3 小时前
【大语言模型】—— 自注意力机制及其变体(交叉注意力、因果注意力、多头注意力)的代码实现
人工智能·语言模型·自然语言处理
从孑开始4 小时前
ManySpeech.MoonshineAsr 使用指南
人工智能·ai·c#·.net·私有化部署·语音识别·onnx·asr·moonshine
涛涛讲AI4 小时前
一段音频多段字幕,让音频能够流畅自然对应字幕 AI生成视频,扣子生成剪映视频草稿
人工智能·音视频·语音识别
可触的未来,发芽的智生4 小时前
新奇特:黑猫警长的纳米世界,忆阻器与神经网络的智慧
javascript·人工智能·python·神经网络·架构
WWZZ20255 小时前
快速上手大模型:机器学习2(一元线性回归、代价函数、梯度下降法)
人工智能·算法·机器学习·计算机视觉·机器人·大模型·slam
AKAMAI5 小时前
数据孤岛破局之战 :跨业务分析的难题攻坚
运维·人工智能·云计算