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算子的边缘定位更精确,可以检测到更细的边缘。

相关推荐
好家伙VCC41 分钟前
**神经编码新视角:用Python实现生物启发的神经信号压缩与解码算法**在人工智能飞速发展的今天
java·人工智能·python·算法
Navicat中国41 分钟前
如何使用 Ollama 配置 AI 助手 | Navicat 教程
数据库·人工智能·ai·navicat·ollama
@小匠5 小时前
Read Frog:一款开源的 AI 驱动浏览器语言学习扩展
人工智能·学习
网教盟人才服务平台8 小时前
“方班预备班盾立方人才培养计划”正式启动!
大数据·人工智能
芯智工坊8 小时前
第15章 Mosquitto生产环境部署实践
人工智能·mqtt·开源
菜菜艾8 小时前
基于llama.cpp部署私有大模型
linux·运维·服务器·人工智能·ai·云计算·ai编程
TDengine (老段)8 小时前
TDengine IDMP 可视化 —— 分享
大数据·数据库·人工智能·时序数据库·tdengine·涛思数据·时序数据
小真zzz8 小时前
搜极星:第三方多平台中立GEO洞察专家全面解析
人工智能·搜索引擎·seo·geo·中立·第三方平台
GreenTea9 小时前
从 Claw-Code 看 AI 驱动的大型项目开发:2 人 + 10 个自治 Agent 如何产出 48K 行 Rust 代码
前端·人工智能·后端
火山引擎开发者社区9 小时前
秒级创建实例,火山引擎 Milvus Serverless 让 AI Agent 开发更快更省
人工智能