Я хочу использовать детектор краев Canny от OpenCV, например, этот вопрос. Например:
cv::Canny(image,contours,10,350);
Тем не менее, я хочу не только получить окончательное пороговое изображение, но и получить детектированный угол края каждого пикселя. Возможно ли это в OpenCV?
canny
не дает вам это напрямую.
Тем не менее, вы можете рассчитать угол из преобразования Собеля, которое используется внутри 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])
}
Вместо использования для цикла вы также можете предоставить dx
а также dy
градиенты к phase
функция, которая возвращает серое изображение направления углов, а затем передает его applyColorMap
и затем замаскируйте его краями, чтобы фон был черным.
Вот рабочий процесс:
Получить углы
Mat angles;
phase(dx, dy, angles, true);
true
Аргумент указывает на то, что углы возвращаются в градусах.
Измените диапазон углов на 0-255, чтобы преобразовать в CV_8U без потери данных.
angles = angles / 360 * 255;
Обратите внимание, что angles
все еще в CV_64F
типа, как это происходит из функции Собеля
Преобразовать в CV_8U
angles.convertTo(angles, CV_8U);
Применить цветную карту на ваш выбор
applyColorMap(angles, angles, COLORMAP_HSV);
в этом случае я выбираю карту цветов HSV. Смотрите это для получения дополнительной информации: https://www.learnopencv.com/applycolormap-for-pseudocoloring-in-opencv-c-python/
Примените маску краев, чтобы фон был черным
Mat colored;
angles.copyTo(colored, contours);
Наконец отображение изображения: 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);