Frage

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?

War es hilfreich?

Lösung

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

Andere Tipps

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);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top