您的位置:首页 > 其它

图像边缘检测

2015-08-26 22:59 253 查看
本文提供两种思路,实现自然图像的边缘检测,并对两种方法的检测效果进行对比。

方法一:调用OpenCV中提供的函数,如Sobel(), Canny()…

方法二:基于图像检测算子的原理,自定义模板。再基于自定义模板对整个图像遍历,从而实现图像边缘检测。本文基于sobel算子实现边缘检测。

具体代码如下,并在VS2010上测试通过:

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"

#include <iostream>
using namespace std;
using namespace cv;

//方法一: 调用OpenCV中提供的函数
void EdgeDetectionBySobel(Mat srcImg)
{
Mat dstImgX, dstImgY, dstImg;
Sobel(srcImg, dstImgY, -1, 1, 0);
Sobel(srcImg, dstImgX, -1, 0, 1);
Sobel(srcImg, dstImg, -1, 1, 1);
imshow("Y方向的梯度", dstImgY);
imshow("X方向的梯度", dstImgX);
imshow("合并的梯度", dstImg);
waitKey(0);
}

//方法二: 自定义函数,效果很一般
void CustomSobelForEdgeDetection(Mat srcImg)
{
//double val = 1.414;//异向扩散
double val = 2;//同向扩散

double sobelTempalteX[3][3] =
{
{-1, -val, -1},
{0, 0, 0},
{1, val, 1},
};
double sobelTempalteY[3][3] =
{
{-1, 0, 1},
{-val, 0, val},
{-1, 0, 1},
};
Mat dstImgX = Mat::zeros(srcImg.size(), CV_8UC1);
Mat dstImgY = Mat::zeros(srcImg.size(), CV_8UC1);

//srcImg.data()快速获取图像灰度值
for(int i = 1; i < dstImgX.rows - 1; i++)//外循环
for(int j = 1; j < dstImgX.cols - 1; j++)
{
uchar temp = 0;
for(int m = -1; m <= 1; m++)//内循环
for(int n = -1; n <= 1; n++)
{
temp += srcImg.data[(i + m) * dstImgX.cols + (j + n)] * sobelTempalteX[m]
;
}
dstImgX.data[i * dstImgX.cols + j] = temp;
}
imshow("X方向的梯度", dstImgX);

for(int i = 1; i < dstImgY.rows - 1; i++)//外循环
for(int j = 1; j < dstImgY.cols - 1; j++)
{
uchar temp = 0;
for(int m = -1; m <= 1; m++)//内循环
for(int n = -1; n <= 1; n++)
{
temp += srcImg.data[(i + m) * dstImgY.cols + (j + n)] * sobelTempalteY[m]
;
}
dstImgY.data[i * dstImgY.cols + j] = temp;
}
imshow("Y方向的梯度", dstImgY);

waitKey(0);
}

int main(int argc, char* argv[])
{
Mat srcImg = imread("D:/openCV/data/naturalImage/data/leda.jpg", 0);
//EdgeDetectionBySobel(srcImg);
CustomSobelForEdgeDetection(srcImg);
return 0;
}


方法一种效果图如下所示:



方法二种效果图如下所示:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: