# Canny using separate functions

Hi! I've tried to write Canny edge detector using OpenCV's functions for better understanding. As I can see, my own pipeline has wrong results after non-maximum suppression.

  cv::GaussianBlur(input, blur, cv::Size(5, 5), 1.4, 1.4);
cv::Sobel(blur, dx, CV_32F, 1, 0, 3);
cv::Sobel(blur, dy, CV_32F, 0, 1, 3);
cv::cartToPolar(dx, dy, magnitudes, angles);

cv::Mat edges = cv::Mat::zeros(img.size(), CV_8UC1);
for (int y = 1; y < angles.rows - 1; ++y) {
for (int x = 1; x < angles.cols - 1; ++x) {
float a = angles.at<float>(y, x);
float m = magnitudes.at<float>(y, x);
if (a > CV_PI) {
a -= CV_PI;
}

if (a < CV_PI / 8 || a > CV_PI - CV_PI / 8) {
if (m > magnitudes.at<float>(y, x + 1) &&
m > magnitudes.at<float>(y, x - 1)) {
edges.at<uint8_t>(y, x) = 255;
}
} else if (a < 0.5f * CV_PI - CV_PI / 8) {
if (m > magnitudes.at<float>(y - 1, x + 1) &&
m > magnitudes.at<float>(y + 1, x - 1)) {
edges.at<uint8_t>(y, x) = 255;
}
} else if (a < 0.5f * CV_PI + CV_PI / 8) {
if (m > magnitudes.at<float>(y - 1, x) &&
m > magnitudes.at<float>(y + 1, x)) {
edges.at<uint8_t>(y, x) = 255;
}
} else {
if (m > magnitudes.at<float>(y - 1, x - 1) &&
m > magnitudes.at<float>(y + 1, x + 1)) {
edges.at<uint8_t>(y, x) = 255;
}
}
}
}


Float32 input.

OpenCV's Canny output

cv::Canny(input, output, 100, 200, 3, true);


My

Next steps of method only reduces number of edge pixels. Thus my mistake already here.
Based on OpenCV 3.2.x doc and OpenCV 2.4.x doc.
Version of Opencv: 3.1.0-dev

Please tell me if I have obvious misunderstanding. Thanks!

Update: Problem solved, removed gaussian blur (not used in OpenCV's implementation) and edited conditions (two '>' replaced to '>=' and swapped diagonals).

  cv::Sobel(blur, dx, CV_32F, 1, 0, 3);
cv::Sobel(blur, dy, CV_32F, 0, 1, 3);
cv::cartToPolar(dx, dy, magnitudes, angles);

cv::Mat edges = cv::Mat::zeros(img.size(), CV_8UC1);
for (int y = 1; y < angles.rows - 1; ++y) {
for (int x = 1; x < angles.cols - 1; ++x) {
float a = angles.at<float>(y, x);
float m = magnitudes.at<float>(y, x);
if (a > CV_PI) {
a -= CV_PI;
}

if (a < CV_PI / 8 || a > CV_PI - CV_PI / 8) {
if (m >= magnitudes.at<float>(y, x + 1) &&
m > magnitudes.at<float>(y, x - 1)) {
edges.at<uint8_t>(y, x) = 255;
}
} else if (a < 0.5f * CV_PI - CV_PI / 8) {
if (m > magnitudes.at<float>(y - 1, x - 1) &&
m > magnitudes.at<float>(y + 1, x + 1)) {
edges.at<uint8_t>(y, x) = 255;
}
} else if (a < 0.5f * CV_PI + CV_PI / 8) {
if (m > magnitudes.at<float>(y - 1, x) &&
m >= magnitudes.at<float>(y + 1, x)) {
edges.at<uint8_t>(y, x) = 255;
}
} else {
if (m > magnitudes.at<float>(y - 1, x + 1) &&
m > magnitudes.at<float>(y + 1, x - 1)) {
edges.at<uint8_t>(y, x) = 255;
}
}
}
}

edit retag close merge delete

Sort by ยป oldest newest most voted

I have found this article with "Linking of the Anchors by Smart Routing" procedure. I will try it.

more

Official site

GitHub

Wiki

Documentation

## Stats

Asked: 2016-12-26 03:48:17 -0500

Seen: 357 times

Last updated: Dec 27 '16