700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > OpenCV边缘检测(Sobel Scharr Laplace Canny)

OpenCV边缘检测(Sobel Scharr Laplace Canny)

时间:2022-07-09 22:41:45

相关推荐

OpenCV边缘检测(Sobel Scharr Laplace Canny)

对于图像的处理,基本的步骤是这样的:

取得图像数据 —— 将图像进行平滑处理 —— 进行边缘检测,阈值分析 —— 进行形态学的操作 —— 获取某些特征点 —— 分析数据

那么在这里,我就讲解下边缘检测的这部分,然后后续再进行其他的讲解。

在OpenCV中,边缘检测的方法有以下几种:

Sobel

Scharr

Laplace

Canny

其中前三种的边缘检测是带方向的

那么我们就先从Sobel算子开始讲起吧!

先来看看Sobel方法的定义

def Sobel

(src,ddepth,dx,dy,dst=None,ksize=None,scale=None,delta=None,borderType=None)

ddepth:图像的颜色深度,针对不同的输入图像,输出目标图像有不同的深度,具体组合如下:

- 若src.depth() = CV_8U, 取ddepth =-1/CV_16S/CV_32F/CV_64F

- 若src.depth() = CV_16U/CV_16S, 取ddepth =-1/CV_32F/CV_64F

- 若src.depth() = CV_32F, 取ddepth =-1/CV_32F/CV_64F

- 若src.depth() = CV_64F, 取ddepth = -1/CV_64F

dx:int类型的,表示x方向的差分阶数,1或0

dy:int类型的,表示y方向的差分阶数,1或0

kSize:模板大小,前面虽然提到过,不过对于Sobel算子这里要补充下,这里的取值为1,3,5,7,当不输入的时候,默认为3。特殊的,当kSize = 1的时候,采用的模板为1*3或者3*1 而非平时的那些格式。

接下来看Scharr的定义

def Scharr(src, ddepth, dx, dy, dst=None, scale=None, delta=None, borderType=None)

会看到参数和Sobel算子一致,不过,该函数与Sobel的区别在于,Scharr仅作用于大小为3的内核。具有和sobel算子一样的速度,但结果更为精确

接下来我们看下这俩的比较:

第一列显示的Sobel算子的在默认3*3模板下的图像,第二列显示的是Scahrr算子在默认3*3模板下的图像,会发现有明显的不同,Scharr给出的更为精确。第三列放的原图像和Sobel算子x=1 y=1的情况。 代码如下:

import cv2img = cv2.imread("C:/Users/DELL/Desktop/img.jpg")gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)sobel_x = cv2.Sobel(gray, cv2.CV_8U, 1, 0)sobel_y = cv2.Sobel(gray, cv2.CV_8U, 0, 1)sobel = cv2.Sobel(gray, cv2.CV_8U, 1, 1)scharr_x = cv2.Scharr(gray, cv2.CV_8U, 1, 0)scharr_y = cv2.Scharr(gray, cv2.CV_8U, 0, 1)cv2.imshow("src", img)cv2.imshow("Sobel_x", sobel_x)cv2.imshow("Sobel_y", sobel_y)cv2.imshow("Sobel", sobel)cv2.imshow("Scharr_x", scharr_x)cv2.imshow("Scharr_y", scharr_y)cv2.waitKey(0)

接下来讲下Laplace

def Laplacian(src,ddepth,dst=None,ksize=None,scale=None,delta=None,borderType=None)

scale:Double类型的,计算拉普拉斯可选比例因子,有默认值1

delta:加到输出像素的值,默认为0

borderType:边界模式。默认值BORDER_DEFAULT

Laplace其实利用Sobel算子的运算,它通过Sobel算子运算出图像在x方向和y方向的导数,来得到我们载入图像的拉普拉斯变换结果。

这里简单看下Laplace的说明,就在方法里面的

The function calculates the Laplacian of the source image by adding up the second x and y. derivatives calculated using the Sobel operator:

由于这个,我这里特意选取了同样kSize的两种方法做下比较:

发现Laplace的轮廓更为清晰。

我觉得Laplace算是Sobel的升级版。

代码如下:

import cv2img = cv2.imread("C:/Users/DELL/Desktop/img.jpg")gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)laplace = cv2.Laplacian(gray, cv2.CV_8U, ksize=3)sobel = cv2.Sobel(gray, cv2.CV_8U, 1, 1)cv2.imshow("Laplace", laplace)cv2.imshow("Sobel", sobel)cv2.waitKey(0)

最后讲下Canny函数:

def Canny(image,threshold1,threshold2,edges=None,apertureSize=None,L2gradient=None)

threshold1:int类型的,低阈值

threshold2:int类型的,高阈值

edeges:单通道存储边缘的输出图像

apertureSize:Sobel算子内核(kSize)大小

L2gradiend:Bool类型的,为真表示使用更精确的L2范数进行计算(两个方向的倒数的平方再开放),为假表示用L1范数(直接将两个方向导数的绝对值相加)

由于和阈值相关,那么我们这里就不指定阈值了,使用进度条的方式来调整阈值获得我们想要图像,直接上图,进度值直接看图吧:

会发现,当我们改变阈值后,图像后渐渐过滤掉一些背景,当然,重在阈值的选取上,当阈值选大的时候,也是会将图像的特征完全损坏的。

代码如下:

import cv2img = cv2.imread("C:/Users/DELL/Desktop/img.jpg")gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)gauss = cv2.GaussianBlur(gray, (3, 3), 1)def doCanny(x):position = cv2.getTrackbarPos("CannyBar", "Canny")canny = cv2.Canny(gauss, position, position*2.5)cv2.imshow("Canny", canny)cv2.namedWindow("Canny")cv2.createTrackbar("CannyBar", "Canny", 1, 100, doCanny)cv2.waitKey(0)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。
扩展阅读