图像边缘检测
边缘检测是图形图像处理、计算机视觉和机器视觉中的一个基本工具,通常用于特征提取和特征检测,旨在检测一张数字图像中有明显变化的边缘或者不连续的区域。
yuan=cv2.imread('yuan.png')
cv2.imshow('yuan',yuan)
cv2.waitKey(0)
yuan_x=cv2.Sobel(yuan,-1,dx=1,dy=0)
cv2.imshow('yuan_x',yuan_x)
cv2.waitKey(0)
yuan_x_64=cv2.Sobel(yuan,cv2.CV_64F,dx=1,dy=0)
cv2.imshow('yuan_x_64',yuan_x_64)
cv2.waitKey(0)
yuan_x_full=cv2.convertScaleAbs(yuan_x_64)
cv2.imshow('yuan_x_full',yuan_x_full)
cv2.waitKey(0)
yuan_y=cv2.Sobel(yuan,-1,dx=0,dy=1)
cv2.imshow('yuan_y',yuan_y)
cv2.waitKey(0)
yuan_y_64=cv2.Sobel(yuan,cv2.CV_64F,dx=0,dy=1)
cv2.imshow('yuan_y_64',yuan_y_64)
cv2.waitKey(0)
yuan_y_full=cv2.convertScaleAbs(yuan_y_64)
cv2.imshow('yuan_y_full',yuan_x_full)
cv2.waitKey(0)
yuan_xy=cv2.Sobel(yuan,-1,dx=1,dy=1)
cv2.imshow('yuan_xy',yuan_xy)
cv2.waitKey(0)
yuan_xy_full=cv2.addWeighted(yuan_x_full,1,yuan_y_full,1,0)
cv2.imshow('yuan_xy_full',yuan_xy_full)
cv2.waitkey(0)
Sobel算子
Sobel 算子是一种离散的微分算子,该算子结合了高斯平滑和微分求导运算。该算子利用局部差分寻找边缘,计算所得的是一个梯度的近似值。
Sobel算子包含2组3×3的矩阵,分别为横向和纵向模板,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。
函数介绍
cv2.Sobel(src, ddepth, dx, dy[, ksize[, scale[, delta[, borderType]]]])
src:输入图像
ddepth: 输出图像的深度(可以理解为数据类型),-1表示与原图像相同的深度
dx,dy:当组合为dx=1,dy=0时求x方向的一阶导数,当组合为dx=0,dy=1时求y方向的一阶导数(如果同时为1,通常效果不佳)
ksize:(可选参数)Sobel算子的大小,必须是1,3,5或者7,默认为3。
Scharr算子
Scharr 算子是 Soble 算子在 ksize=3 时的优化,与 Soble 的速度相同,且精度更高。Scharr 算子与 Sobel 算子的不同点是在平滑部分,其中心元素占的权重更重,相当于使用较小标准差的高斯函数,也就是更瘦高的模板。
函数介绍
cv.Scharr(src, ddepth, dx, dy[, dst[, scale[, delta[, borderType]]]])
src:输入图像
ddepth:输出图片的数据深度,由输入图像的深度进行选择
dx:x 轴方向导数的阶数
dy:y 轴方向导数的阶数
Laplacian算子
函数介绍
cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])
参数说明:
src:输入图像,可以是灰度图像,也可以是多通道的彩色图像
ddepth:输出图片的数据深度:
ksize:计算二阶导数滤波器的孔径大小,必须为正奇数,可选项
scale:缩放比例因子,可选项,默认值为 1
delta:输出图像的偏移量,可选项,默认值为 0
imge=cv2.imread('img.png',cv2.IMREAD_GRAYSCALE)
img=cv2.resize(imge, (600, 600))
# sobal算子
img_x_64=cv2.Sobel(img,cv2.CV_64F,dx=1,dy=0)
img_x_full=cv2.convertScaleAbs(img_x_64)
img_y_64=cv2.Sobel(img,cv2.CV_64F,dx=0,dy=1)
img_y_full=cv2.convertScaleAbs(img_y_64)
img_xy_sobel_full=cv2.addWeighted(img_x_full,1,img_y_full,1,0)
cv2.imshow('img_xy_sobel_full',img_xy_sobel_full)
cv2.waitKey(0)
#Scharr算子
img_x_64=cv2.Scharr(img,cv2.CV_64F,dx=1,dy=0)
img_x_full=cv2.convertScaleAbs(img_x_64)
img_y_64=cv2.Scharr(img,cv2.CV_64F,dx=0,dy=1)
img_y_full=cv2.convertScaleAbs(img_y_64)
img_xy_scharr_full=cv2.addWeighted(img_x_full,1,img_y_full,1,0)
cv2.imshow('img_xy_scharr_full',img_xy_scharr_full)
cv2.waitKey(0)
#拉普拉斯
img_lap=cv2.Laplacian(img,cv2.CV_64F)
cv2.imshow('img_lap',img_lap)
cv2.waitKey(0)
Canny边缘检测
函数介绍
cv.Canny( image, threshold1, threshold2[, apertureSize[, L2gradient]])
image 为输入图像。
threshold1 表示处理过程中的第一个阈值。fL
threshold2 表示处理过程中的第二个阈值。fH
Canny边缘检测的优点:
-
低错误率。因为一般的边缘检测算子可能存在检测到伪边缘的情况,因此Canny算法检测到的边缘尽可能地是真实的边缘。
-
较好地定位边缘点。由检测器标记的边缘点与真实边缘点中心尽可能地接近。
-
单一的边缘响应。图像中的边缘只标记出一次。
Canny边缘检测分为4个部分
1、图像降噪 2、梯度计算 3、非极大值抑制 4、双阈值边界跟踪
-
图像降噪
图像去噪是进行边缘检测的第一步,通过去噪可以去除图像中的一些噪点,从而使边缘检测时免受噪点干扰。高斯滤波。
-
梯度计算
要进行边缘检测,就需要得到图像梯度信息,根据图像的梯度幅值和梯度方向来确定边缘,一般均采用sobel算子对图像进行梯度幅值与梯度方向计算。
-
非极大值抑制
一阶微分在灰度值斜坡过渡时不为零且存在较粗的边缘,较粗的边缘会增大边缘检测的误差,因此需要细化边缘,一种较为常用的方法是非极大值抑制
非极大值抑制:即在梯度图像中寻找梯度方向上的最大值作为边缘,不是梯度方向上的最大值则抑制为0。因为梯度方向是灰度变化最大的方向。比较梯度图像中每一点的灰度值与梯度方向上至少两个梯度图像像素点灰度值的大小,根据上述大小关系来确定是否保留该点的灰度值。
-
双阈值边界跟踪
双阈值处理就是根据实际情况需要设置一个灰度高阈值和一个灰度低阈值对NMS后的图像进行过滤,使得得到的边缘尽可能是真实的边缘。
imge=cv2.imread('img.png',cv2.IMREAD_GRAYSCALE)
img=cv2.resize(imge, (500, 500))
cv2.imshow('img_original',img)
cv2.waitKey(0)
img_canny=cv2.Canny(img,100,150)
cv2.imshow('img_canny_100-150',img_canny)
cv2.waitKey(0)
img_canny=cv2.Canny(img,200,250)
cv2.imshow('img_canny_200-250',img_canny)
cv2.waitKey(0)