目录
计算梯度
1-sobel算子
2-scharr算子
3-Laplacian算子
4-总结
5-补充说明
计算梯度
梯度:两侧灰度值之差,通常在边缘梯度较大
1-sobel算子
1.是图像边缘检测的中重要算子之一
2.与梯度密不可分
3.读入的是灰度图(只有一个通道)
这里以3*3的图像和卷积核为例:
注意:这里进行的是卷积运算(对应位置相乘最后相加),而不是矩阵运算
解释一下:相当于图像的右边减去左边(很好理解:右边正的,左边负的,做加法)
相当于图像的下边减去上边
dst=cv2.Sobel(src,ddepth,dx,dy,ksize)
src:图像
ddepth:图像深度,通常取-1
dx,dy:方向
ksize:大小如3*3
import cv2
img=cv2.imread('erosion.jpg')
def cv_show(img,name):
cv2.imshow(name,img)
cv2.waitKey(0)
cv2.destroyAllWindows()
sobelx=cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)#先算水平的,不算竖直的
cv_show(sobelx,'sobelx')
cv2.CV_64F是一个常量,用于示64位浮点数据类型。数据类型通常用于表示图像中的像素值,或者在需要高精度的数学运算中使用,特别是在边缘检测、图像滤波或任何需要保持微小变化的操作中。
注意:白:255,黑:0
右减左:左半部分:>0;右半部分:<0
而负数会被截断成0:所以右半边显示不清楚
所以这边用cv2.convertScaleAbs()函数
sobelx=cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelx=cv2.convertScaleAbs(sobelx)
cv_show(sobelx,'sobelx')
sobely=cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely=cv2.convertScaleAbs(sobely)
cv_show(sobely,'sobely')
再对x、y进行求和:
sobelxy=cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show(sobelxy,'sobelxy')
图1,x方向上
图2,y方向上
图3,x、y方向上
如果直接计算:
sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)
sobely=cv2.convertScaleAbs(sobelxy)
cv_show(sobelxy,'sobelxy')
图像的效果不是很好(重影加模糊),所以建议分开来
下面是一份完整的代码
import cv2
img=cv2.imread('girl.jpg',cv2.IMREAD_GRAYSCALE)#读入灰度图
def cv_show(img,name):
cv2.imshow(name,img)
cv2.waitKey()
cv2.destroyAllWindows()
sobelx=cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelx=cv2.convertScaleAbs(sobelx)
cv_show(sobelx,'sobelx')
sobely=cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely=cv2.convertScaleAbs(sobely)
cv_show(sobely,'sobely')
sobelxy=cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show(sobelxy,'sobelxy')
2-scharr算子
简单介绍:(chatgpt3.5)Scharr算子是一种用于图像处理中边缘检测的滤波器。Scharr算子在提取图像边缘时具有更好的性能,尤其是在处理高斯噪声的图像时。
Scharr算子的主要优点包括:(与sobel算子做比较)
对噪声具有更好的抵抗能力对高斯噪声进行边缘检测时表现更好。在边缘方向的平滑性更好,这使得检测到的边缘更连续、更准确。Scharr算子的权重分布更加均匀,这有助于提高边缘检测的准确性。
import cv2
def cv_show(img,name):
cv2.imshow(name,img)
cv2.waitKey()
cv2.destroyAllWindows()
img=cv2.imread('girl.jpg')
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')
3-Laplacian算子
是一种常用于图像处理和计算机视觉中的边缘检测算子,用于检测图像中的二阶变化。它对图像中的边缘和区域的灰度变化进行了敏感的检测。
laplacian=cv2.Laplacian(img,cv2.CV_64F)
laplacian=cv2.convertScaleAbs(laplacian)
cv_show(laplacian,'laplacian')
4-总结
这里提供一份完整的代码,得到三图对比:
import cv2
import numpy as np
img=cv2.imread('girl.jpg')
def cv_show(img,name):
cv2.imshow(name,img)
cv2.waitKey()
cv2.destroyAllWindows()
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)
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)
laplacian=cv2.Laplacian(img,cv2.CV_64F)
laplacian=cv2.convertScaleAbs(laplacian)
cv_show(laplacian,'laplacian')
res=np.hstack((sobelxy,scharrxy,laplacian))
cv_show(res,'res')
5-补充说明
在这里简单说明图像一阶二阶变化的含义:这边可以理解为图像的导数,但是图像是由像素构成的,像素只是离散的整数,不是连续的函数,所以这边可以理解为灰度值的变化率。在数字图像处理中,这些梯度或导数通常是离散的,因为它们是基于离散的像素值计算的。但是,如果我们使用某种形式的插值或平滑技术,例如使用卷积核来计算梯度,那么结果可能会变得相对平滑,不再是完全的离散值。
图像的二阶变化:图像中灰度值变化的曲率或变化的速度。
精彩内容
发表评论