从OpenCV Canny边缘探测器获取角度

时间:2013-10-22 23:22:33

标签: c++ c opencv image-processing edge-detection

我想使用OpenCV的Canny边缘检测器,如this question中概述的那样。例如:

cv::Canny(image,contours,10,350); 

但是,我希望不仅能够获得最终的阈值图像,而且还希望在每个像素处获得检测到的边缘角度。这在OpenCV中是否可行?

2 个答案:

答案 0 :(得分:3)

canny并未直接向您提供此信息。 但是,您可以通过Sobel变换计算角度,该变换在canny()内部使用。

伪代码:

    cv::Canny(image,contours,10,350);
    cv::Sobel(image, dx, CV_64F, 1, 0, 3, 1, 0, cv::BORDER_REPLICATE);
    cv::Sobel(image, dy, CV_64F, 0, 1, 3, 1, 0, cv::BORDER_REPLICATE);

    cv::Mat angle(image.size(), CV_64F)

    foreach (i,j) such that contours[i, j] > 0
    {
        angle[i, j] = atan2(dy[i,j], dx[i , j])
    }

答案 1 :(得分:1)

您还可以向dx函数提供dyphase渐变,而不是使用for循环,它会返回角度方向的灰度图像,然后将其传递给applyColorMap函数,然后用边缘遮住它,所以背景是黑色的。

以下是工作流程:

  1. 获取角度

    Mat angles;
    phase(dx, dy, angles, true);
    

    true参数表示角度以度为单位返回。

  2. 将角度范围更改为0-255,以便转换为CV_8U而不会丢失数据

    angles = angles / 360 * 255;
    

    请注意angles仍为CV_64F类型,因为它来自Sobel函数

  3. 转换为CV_8U

    angles.convertTo(angles, CV_8U);
    
  4. 应用您选择的彩色地图

    applyColorMap(angles, angles, COLORMAP_HSV);
    

    在这种情况下,我选择HSV色彩映射。有关详情,请参阅此处:https://www.learnopencv.com/applycolormap-for-pseudocoloring-in-opencv-c-python/

  5. 应用边缘蒙版,使背景为黑色

    Mat colored;
    angles.copyTo(colored, contours);
    
  6. 最后显示图片:D

    imshow("Colored angles", colored);
    
  7. 如果您的来源是视频或网络摄像头,在应用边缘遮罩之前,您必须清除colored图像,以防止聚合:

    colored.release();
    angles.copyTo(colored, contours);
    

    完整代码:

    Mat angles, colored;
    
    phase(dx, dy, angles, true);
    angles = angles / 360 * 255;
    angles.convertTo(angles, CV_8U);
    applyColorMap(angles, angles, COLORMAP_HSV);
    colored.release();
    angles.copyTo(colored, contours);
    imshow("Colored angles", colored);