Reputation: 11917
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?
Upvotes: 3
Views: 6143
Reputation: 544
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:
Get the angles
Mat angles;
phase(dx, dy, angles, true);
true
argument idicates that the angles are returned in degrees.
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
Convert to CV_8U
angles.convertTo(angles, CV_8U);
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/
Apply the edges mask so the background is black
Mat colored;
angles.copyTo(colored, contours);
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);
Upvotes: 3
Reputation: 11941
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])
}
Upvotes: 3