图像梯度与几种算子的opencv实现

1、 Sobel算子函数

OpenCV使用Sobel 算子的方法是cv2.Sobel()

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

参数:

  • src 原图像

  • ddepth 输出图像的深度,具体关系:

输入图像深度(src.depth())输出图像深度(ddepth)
cv2.CV_8U-1/cv2.CV_16S/cv2.CV_32F/cv2.CV_64F
cv2.CV_16U/cv2.CV_16S-1/cv2.CV_32F/cv2.CV_64F
cv2.CV_32F-1/cv2.CV_32F/cv2.CV_64F
cv2.CV_64F-1/cv2.CV_64F
  • dx:x方向上的求导阶数

  • dy:y方向上的求导阶数

  • ksize:Sobel核的大小。该值为-1时,会使用Scharr算子进行运算

  • scale:计算导数时采用的缩放因子,默认为1,是没有缩放的

  • delta:加在目标图像dst上的值,默认为0

  • borderType:边界样式,默认值为cv2.BORDER_DEFAULT。

关于参数ddepth

该值为-1时,让处理结果与原始图像保持一致,但是直接将ddepth设置为-1,得到的结果可能是错误的。计算梯度值可能出现负数,当处理的图像是8位图类型,ddepth的值为-1时,运算结果也是8位图类型,负数会自动截断为0,发生信息丢失。为了避免信息丢失,要先使用更高的数据类型cv2.CV_64F,再通过取绝对值将其映射到cv2.CV_8U类型。所以,通常将ddepth值设置为“cv2.CV_8U”,并使用函数cv2.convertScaleAbs()对函数cv2.Sobel()的计算结果取绝对值。

注意:x方向和y方向的边缘叠加时,应先令dx=1,dy=0,得到一个结果;再令dx=0,dy=1,得到一个结果。将两个结果相加,而不是同时令dx=1和dy=1。

import cv2

#读取图像
img = cv2.imread('图片路径',0)

#计算x方向边缘信息
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)
#计算y方向边缘信息
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5)
#求绝对值
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.convertScaleAbs(sobely)
#x方向和y方向的边缘叠加
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)

#显示图像
cv2.imshow("origin image",img)
cv2.imshow("x",sobelx)
cv2.imshow("y",sobely)
cv2.imshow("xy",sobelxy)

cv2.waitKey(0)
cv2.destroyAllWindows()

 

2、 Scharr算子

OpenCV使用Scharr算子的函数是cv2.Scharr()

dst = cv2.Scharr(src,ddepth,dx,dy,scale,delta,borderType)

参数:

  • src 原图像

  • ddepth 输出图像的深度,该值与函数cv2.Sobel()中的参数ddepth的含义相同。

  • dx x方向上的求导阶数

  • dy y方向上的求导阶数

  • scale 计算导数时采用的缩放因子,默认为1,是没有缩放的

  • delta 加在目标图像dst上的值,默认为0

  • borderType 边界样式,默认值为cv2.BORDER_DEFAULT。

在cv2.Sobel()中,ksize=-1时,则会使用Scharr算子。所以下面两个语句等价:

dst = cv2.Scharr(src,ddepth,dx,dy)dst = cv2.Sobel(src,ddepth,dx,dy,-1)

注意:

  • 参数ddepth的值应该设置为“cv2.CV_64F”,并对函数cv2.Scharr()的计算结果取绝对值。

  • dx和dy不能同时为1,否则语句是错误的。

  • 计算x方向和y方向的边缘叠加时,应先令dx=1,dy=0,得到一个结果;再令dx=0,dy=1,得到一个结果。将两个结果相加,而不是同时令dx=1和dy=1。

代码示例:

import cv2

#读取图像
img = cv2.imread('img.png',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)

#显示图像
cv2.imshow("origin image",img)
cv2.imshow("x",scharrx)
cv2.imshow("y",scharry)
cv2.imshow("xy",scharrxy)

cv2.waitKey(0)
cv2.destroyAllWindows()

结果:x方向:

 y方向:

x方向和y方向的边缘叠加

3、 Laplacian算子

OpenCV使用Laplacian算子的函数是cv2.Laplacian()

dst = cv2.Laplacian(src,ddepth,ksize,scale,delta,borderType)

参数:

  • src 原图像

  • ddepth 输出图像的深度,该值与函数cv2.Sobel()中的参数ddepth的含义相同。

  • ksize 计算二阶导数的核尺寸大小,必须为正的奇数。

  • scale 计算导数时采用的缩放因子,默认为1,是没有缩放的

  • delta 加在目标图像dst上的值,默认为0

  • borderType 边界样式,默认值为cv2.BORDER_DEFAULT。

该函数分别对x和y方向进行二次求导:

注意:当ksize=1时,计算时采用如下3×3的核:

代码:

import cv2

#读取图像
img = cv2.imread('5907dfd8407ca2407d082c90bf6d290.png',0)

#计算边缘信息
laplace = cv2.Laplacian(img,cv2.CV_64F)
#求绝对值
laplace = cv2.convertScaleAbs(laplace)

#显示图像
cv2.imshow("origin image",img)
cv2.imshow("laplace",laplace)

cv2.waitKey(0)
cv2.destroyAllWindows()

4、 Canny函数

OpenCV使用函数cv2.Cannyl()实现Canny边缘检测

edges = cv2.Canny(image,threshold1,threshold2,apertureSize,L2gradient)

参数:

  • image 输入图像,必须为8位图像

  • threshold1 第一个阈值

  • threshold2 第二个阈值

  • apertureSize Sobel算子的大小

  • L2gradient 计算图像梯度幅度的表示。默认值为False,使用L1范数计算;如果为True,则使用更精确的L2范数计算。

图片

代码示例:

import cv2

#读取图像,为8位灰度图像
img = cv2.imread('img.png',cv2.IMREAD_GRAYSCALE)

#canny边缘检测
#去噪
img = cv2.GaussianBlur(img,(3,3),0)
#threshold1为128,threshold2为200时的边缘检测结果
canny1 = cv2.Canny(img, 128, 200)
#threshold1为32,threshold2为128时的边缘检测结果
canny2 = cv2.Canny(img, 32, 128)

#显示图像
cv2.imshow("origin image",img)
cv2.imshow("canny1",canny1)
cv2.imshow("canny2",canny2)

cv2.waitKey(0)
cv2.destroyAllWindows()

 threshold1为128,threshold2为200时的边缘检测结果

threshold1为32,threshold2为128时的边缘检测结果 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值