版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/abcvincent/article/details/79155317
opencv实现了一些边缘检测算法的函数,定型的是Canny(),Sobel(),Laplacian();边缘算子在图像识别及检测中是一个很重要的方法,在人类识别物体时也多依赖边缘轮廓,因为在一般情况下边缘特征不受光照影响;同样图像只剩边缘后像素量也会极大减少,这样对于处理是有益的。
至于算子的算法和原理大家可以找专业资料研读一下,大部分根据图像梯度特征来寻找边缘;
话不多说,下面看代码:
////////////////////////////////
//图像边缘检测
int threshval = 60;//初始化阈值
static void on_trackbar(int, void*)//轨迹条的回调函数
{
Mat srcImg = imread("D:/ImageTest/sudoku.png");
Mat dstImg;
Canny(srcImg,//输入图像
dstImg,//输出图像
threshval,//第一个阈值
threshval*3,//第二个阈值
3);//1,3,5,7,Sobel 算子内核大小 .
// threshold1和threshold2 当中的小阈值用来控制边缘连接,大的阈值用来控制强边缘的初始分割。
imshow("Canny", dstImg);
}
void imgEdge()//图像边缘检测
{
Mat srcImg = imread("D:/ImageTest/sudoku.png");
///Canny边缘检测
// Mat dstImg;
// Canny(srcImg,//输入图像
// dstImg,//输出图像
// 10,//第一个阈值
// 80,//第二个阈值
// 3);//1,3,5,7,Sobel 算子内核大小 .
// // threshold1和threshold2 当中的小阈值用来控制边缘连接,大的阈值用来控制强边缘的初始分割。;
namedWindow("Canny", 1 ); //创建处理窗口
createTrackbar(
"Threshold", //const char* trackbarName,滑条名字
"Canny",//const char* windowName,名字对应窗口名字,不然不显示
&threshval,//int* value,显示时候滑条初始值
100, //int count,最大值
on_trackbar//CvTrackbarCallback onChange,滑动时候触发函数
);//创建轨迹条
on_trackbar(threshval, 0);
/////Sobel边缘检测
Mat grad_x, grad_y;
Mat abs_grad_x, abs_grad_y, dst;
//因为Sobel求出来的结果有正负,8位无符号表示不全,故用16位有符号表示
Sobel(srcImg, //输入图像
grad_x, //输出图像
CV_16S, //输出图像深度
1, //x方向的差分
0, //y方向的差分,这里需要x方向的图像,所以y方向的图像为0;
3, //ksize核的大小,默认3,只能取1,3,5,7;
1, //放缩比例默认1,表示不放缩
1, //delta值,默认0;
BORDER_DEFAULT);//边界模式
convertScaleAbs(grad_x, abs_grad_x);//将16位有符号转化为8位无符号
Sobel(srcImg, grad_y, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT);
convertScaleAbs(grad_y, abs_grad_y);
addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst);
//扩展 Sobel 核的大小,必须是 1, 3, 5 或 7。 除了尺寸为 1, 其它情况下, aperture_size ×aperture_size 可分离内核将用来计算差分。
///Laplacian边缘检测
Mat dst2;
Mat abs_dst;
Laplacian(srcImg, //输入图像
dst2, //输出图像
CV_16S, //输出图像深度
3, //Ksize,滤波器孔径大小,必须为整奇数;
1, //放缩比例
0, //delta值
BORDER_DEFAULT);//边界模式
convertScaleAbs(dst2, abs_dst);
imshow("src", srcImg);
// imshow("Canny", dstImg);
imshow("Sobel X direction", abs_grad_x);
imshow("Sobel Y direction", abs_grad_y);
imshow("Sobel combine", dst);
imshow("Laplacian", abs_dst);
waitKey(0);
}
结果如下: