3

我想使用 OpenCV 的 Canny 边缘检测器,例如这个问题中概述的。例如:

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

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

4

2 回答 2

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])
    }
于 2013-10-23T01:00:45.350 回答
2

除了使用 for 循环,您还可以为函数提供渐变,dx该函数返回角度方向的灰度图像,然后将其传递给函数,然后用边缘对其进行遮罩,因此背景为黑色。dyphaseapplyColorMap

这是工作流程:

  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);
    

如果您的源是视频或网络摄像头,在应用边缘掩码之前,您必须清除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);
于 2018-05-02T14:51:26.397 回答