如何平滑OpenCV中的曲线(轮廓)?

Adr*_*ian 11 curve opencv smoothing

我正在处理黑白图像,就像链接中的第一个一样:http: //imageshack.us/g/33/firstwm.png/ 它有很多"噪音"所以我在它上面应用了一个中值滤镜来平滑它,从而获得第二张照片.

cvSmooth(TempImage, TempImage, CV_MEDIAN, 5, 0);
Run Code Online (Sandbox Code Playgroud)

在此之后,我获得轮廓并将其绘制在另一个图像上,如链接中的第3张图片.我的问题是轮廓仍然有点像素化(前卫).有没有办法平滑B&W图像,以获得更好的轮廓?或者也许用轮廓做点什么.我也尝试过不同内核的Dilate和Erode但问题仍然存在.谢谢你的帮助.

编辑:也尝试过:

cvSmooth(TempImage, TempImage, CV_GAUSSIAN, 9, 9, 3);
cvThreshold(TempImage, TempImage, 127, 255, CV_THRESH_BINARY);
Run Code Online (Sandbox Code Playgroud)

与中值滤波器相同的结果,确定,但仍然留下一些像素化的轮廓.

swa*_*log 8

在此输入图像描述

如果这是你想要的平滑结果,可以通过高斯模糊,然后进行阈值处理来获得.即使用cvSmoothCV_GAUSSIAN作为paramater.接下来是一个cvThreshold.

如果你想要一个比阈值更平滑的过渡(像这样),你可以通过调整水平(重新映射颜色范围,以便保留一些边缘过渡)来实现.

更新要解释如何在阈值处理上获得平滑(消除锯齿)的边缘,请考虑阈值处理的作用.它基本上处理图像中的每个像素,一次一个.如果像素值低于阈值,则将其设置为黑色(0),否则将其设置为白色(255).

因此,阈值运算符非常简单,但是,可以使用任何其他通用映射函数.基本上它是一个函数f(i),其中i强度像素值(范围为0-255)并且f(i)是映射值.对于阈值,此功能很简单

 f(i) = {   0, for i  < threshold
          255, for i >= threshold
Run Code Online (Sandbox Code Playgroud)

你所拥有的是一个平滑的图像(通过使用高斯内核的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
Run Code Online (Sandbox Code Playgroud)

并获得所需的输出.我将快速浏览一下,看看它是否已在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
Run Code Online (Sandbox Code Playgroud)