一、Sobel算法
1、算法概述
? ?Sobel边缘检测算法比较简单,实际应用中效率比canny边缘检测效率要高,但是边缘不如Canny检测的准确,然而在很多实际应用的场合,sobel边缘却是首选,Sobel算子是高斯平滑与微分操作的结合体,所以其抗噪声能力很强,用途较多。尤其是在对效率要求较高,而对细纹理不太关系的时候。 ? ?使用Sobel算子提取图像边缘分3个步骤:
- 提取X方向的边缘,X方向一阶Sobel边缘检测算法为:
[
?
1
0
1
?
2
0
2
?
1
0
1
]
(1)
\left[ \begin{matrix} -1 & 0 & 1\\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{matrix} \right] \tag{1}
????1?2?1?000?121????(1) - 提取Y方向的边缘,Y方向一阶Sobel边缘检测算法为:
[
?
1
?
2
?
1
0
0
0
1
2
1
]
(2)
\left[ \begin{matrix} -1 & -2 & -1\\ 0 & 0 & 0 \\ 1 & 2 & 1 \end{matrix} \right] \tag{2}
????101??202??101????(2) - 综合两个方向的边缘信息得到整幅图像的边缘。
2、主要函数
Sobel_x_or_y = cv2.Sobel(src, ddepth, dx, dy, dst, ksize, scale, delta, borderType)
src :传入的图像ddepth :图像的深度dx 、dy :指的是求导的阶数,0表示这个方向上没有求导,所填的数一般为0、1、2。ksize :是Sobel算子的大小,即卷积核的大小,必须为奇数1、3、5、7。如果ksize=-1,就演变成为3x3的Scharr算子,scale是缩放导数的比例常数,默认情况为没有伸缩系数。borderType :是判断图像边界的模式,这个参数默认值为cv2.BORDER_DEFAULT。dst 及dst 之后的参数都是可选参数。
二、C++代码
#include <iostream>
#include <opencv2\opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("1.jpg");
Mat gray_img;
cvtColor(img, gray_img, COLOR_BGR2GRAY);
Mat resultX, resultY, resultXY;
Sobel(img, resultX, CV_16S, 2, 0, 1);
convertScaleAbs(resultX, resultX);
Sobel(img, resultY, CV_16S, 0, 1, 3);
convertScaleAbs(resultY, resultY);
resultXY = resultX + resultY;
imshow("resultX", resultX);
imshow("resultY", resultY);
imshow("resultXY", resultXY);
waitKey(0);
return 0;
}
三、python代码
import cv2
img = cv2.imread("1.jpg")
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
x = cv2.Sobel(gray_img, cv2.CV_16S, 1, 0)
y = cv2.Sobel(gray_img, cv2.CV_16S, 0, 1)
Scale_absX = cv2.convertScaleAbs(x)
Scale_absY = cv2.convertScaleAbs(y)
result = cv2.addWeighted(Scale_absX, 0.5, Scale_absY, 0.5, 0)
cv2.imshow('img', gray_img)
cv2.imshow('Scale_absX', Scale_absX)
cv2.imshow('Scale_absY', Scale_absY)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
四、结果展示
1、灰度图
2、X方向一阶边缘
2、Y方向一阶边缘
3、整幅图像的一阶边缘
五、相关链接
[1] python+OpenCV图像处理(八)边缘检测
|