Как сгладить кривые (контуры) в 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 ответов


enter image description here

если это результат сглаживания, который вы ищете,его можно получить, выполнив размытие Гаусса, а затем порог. Т. е. использование 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