Как сгладить кривые (контуры) в OpenCV?
Я работаю над черно-белым изображением, как и первое из ссылки : http://imageshack.us/g/33/firstwm.png/ Он имеет много "шума", поэтому я применил медианный фильтр над ним, чтобы сгладить его, получив второе изображение.
cvSmooth(TempImage, TempImage, CV_MEDIAN, 5, 0);
после этого я получаю контуры и рисую их на другом изображении, таком как 3-е изображение из ссылки. Моя проблема в том, что контуры все еще немного неровные(острые). Есть ли способ сгладить изображение B&W еще больше, чтобы получить лучшие контуры? Или, может быть, сделать что-то с контурами. Я также попытался расширить и размыть с различными ядрами, но проблема остается той же. Спасибо за все, что помогает.
изменить: Также попробовал:
cvSmooth(TempImage, TempImage, CV_GAUSSIAN, 9, 9, 3);
cvThreshold(TempImage, TempImage, 127, 255, CV_THRESH_BINARY);
те же результаты, что и медианный фильтр, хорошо, но все же оставляет некоторые пиксельные контуры.
1 ответов
если это результат сглаживания, который вы ищете,его можно получить, выполнив размытие Гаусса, а затем порог. Т. е. использование cvSmooth
С CV_GAUSSIAN
в качестве параметра. Затем cvThreshold
.
если вы хотите более плавный переход, чем порог (например,этой), вы можете получить это с регулировкой уровней (переназначение цветового диапазона, чтобы сохранить некоторые из краевых переходов).
обновление в объясните, как получить гладкий (сглаженный) край на пороге, рассмотрите, что делает порог. Он в основном обрабатывает каждый пиксель изображения, по одному за раз. Если значение пикселя ниже порогового значения, оно равно черному (0), если нет-белому (255).
таким образом, оператор порога очень прост, однако можно использовать любую другую общую функцию отображения. В основном это функция f(i)
, где i
интенсивность пиксела (в диапазоне 0-255) и f(i)
- сопоставленное значение. Для порога эта функция проста
f(i) = { 0, for i < threshold
255, for i >= threshold
у вас есть сглаженное изображение (cvSmooth с использованием гауссова ядра, которое дает вам "самое гладкое" сглаживание, если это имеет смысл). Таким образом, у вас есть мягкий переход значений по краям, в диапазоне от 0 до 255. Что вы хотите сделать, так это сделать этот переход намного меньше, так что вы получите хорошее преимущество. Если вы идете по баллистике, вы идете прямо от 0 до 255, что совпадает с двоичным кодом обмолот вы уже сделали.
теперь рассмотрим функцию, которая отображает, возможно, диапазон значений интенсивности 4 (127 +- 4) в полный диапазон 0-255. Т. е.
f(i) = { 0, for i < 123
255, for i >= 131
linear mapping, for 123 <= i < 131
и вы получаете желаемый результат. Я быстро взгляну и посмотрю, реализован ли он уже в openCV. Хотя не должно быть слишком сложно закодировать его самостоятельно.
обновление 2 Версия контура будет примерно такой:
f(i) = { 255, for i < 122
linear mapping (255->0), for 122 <= i < 126
0, for 126 <= i < 127
linear mapping (0->255), for 127 <= i < 131
255, for 131 <= i