sobel边缘检测_c++实现
!转载请注明出处
算法步骤:
-
输入图像
-
x,y两个方向卷积核在图像上滑动
Gx = f(x+1, y-1) + 2 * f(x+1, y) + f(x +1, y+1) - (f(x-1, y-1) + 2 * f(x-1, y) + f(x-1, y-1))
Gy = f(x-1, y-1) + 2 * f(x, y-1) + f(x+1, y-1) - (f(x-1, y+1) + 2 * f(x, y+1) + f(x+1, y+1)) -
G=sqrt(Gx * Gx+Gy * Gy)
-
输出G
代码如下:
/*created at 2019/4/14*/
#include <iostream>
#include <opencv2/opencv.hpp>
cv::Mat bgr2gray(cv::Mat src)
{
int chans = src.channels();
cv::Mat gray;
if(chans > 1)
cvtColor(src, gray, CV_BGR2GRAY);
else
src.copyTo(gray);
return gray;
}
void sobel_detect(cv::Mat src, cv::Mat& dst)
{
cv::Mat in_src = bgr2gray(src);
int rows = src.rows, cols = src.cols;
for(int r = 1; r < rows - 1; ++r)
for(int c = 1; c < cols -1; ++c)
{
float Gx = in_src.at<uchar>(r-1,c+1) + 2*in_src.at<uchar>(r,c+1) + in_src.at<uchar>(r+1,c+1) -
(in_src.at<uchar>(r-1,c-1) + 2*in_src.at<uchar>(r,c-1) + in_src.at<uchar>(r+1,c-1));
float Gy = in_src.at<uchar>(r-1,c-1) + 2*in_src.at<uchar>(r-1,c) + in_src.at<uchar>(r-1,c+1) -
(in_src.at<uchar>(r+1,c-1) + 2*in_src.at<uchar>(r+1,c) + in_src.at<uchar>(r+1,c+1));
float G = sqrt(Gx * Gx + Gy * Gy);
if(G > 255)
dst.at<uchar>(r,c) = 255;
else
dst.at<uchar>(r,c) = G;
}
}
int main()
{
cv::Mat src = cv::imread("lena.jpg");
cv::Mat dst(src.rows, src.cols, CV_8UC1);
sobel_detect(src, dst);
cv::imshow("sobel.jpg", dst);
cv::waitKey(0);
return 0;
}
原图:
输出: