【opencv学习之二十六】边缘检测算子:Canny,Sobel,Laplacian

版权声明:本文为博主原创文章,未经博主允许不得转载。 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);
}
结果如下:



猜你喜欢

转载自blog.csdn.net/abcvincent/article/details/79155317