Get angle from OpenCV Canny edge detector

南楼画角 提交于 2019-12-10 10:07:13

问题


I want to use OpenCV's Canny edge detector, such as is outlined in this question. For example:

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

However, I wish to not only get the final thresholded image out, but I also wish to get the detected edge angle at each pixel. Is this possible in OpenCV?


回答1:


canny doesn't give you this directly. However, you can calculate the angle from the Sobel transform, which is used internally in canny().

Pseudo code:

    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])
    }



回答2:


Instead of using for loop you can also provide dx and dy gradients to phase function that returns grayscale image of angles direction, then pass it to applyColorMap function and then mask it with edges, so the background is black.

Here is the workflow:

  1. Get the angles

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

    true argument idicates that the angles are returned in degrees.

  2. Change the range of angles to 0-255 so you can convert to CV_8U without data loss

    angles = angles / 360 * 255;
    

    note that angles is still in CV_64F type as it comes from Sobel function

  3. Convert to CV_8U

    angles.convertTo(angles, CV_8U);
    
  4. Apply color map of your choice

    applyColorMap(angles, angles, COLORMAP_HSV);
    

    in this case I choose HSV colormap. See this for more info: https://www.learnopencv.com/applycolormap-for-pseudocoloring-in-opencv-c-python/

  5. Apply the edges mask so the background is black

    Mat colored;
    angles.copyTo(colored, contours);
    
  6. Finally display image :D

    imshow("Colored angles", colored);
    

In case your source is a video or webcam, before applying the mask of edges you addtionlly must clear colored image, to prevent aggregation:

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

Full code here:

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


来源:https://stackoverflow.com/questions/19530060/get-angle-from-opencv-canny-edge-detector

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!