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

标签 opencv curve smoothing

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

cvSmooth(TempImage, TempImage, CV_MEDIAN, 5, 0);

在此之后,我得到了轮廓并将它们绘制在另一个图像上,例如链接中的第 3 张图片。 我的问题是轮廓仍然有点像素化(前卫)。有没有办法使黑白图像更加平滑以获得更好的轮廓?或者用轮廓做点什么。 我也尝试过使用不同内核的 D​​ilate 和 Erode,但问题仍然存在。 感谢您提供的任何帮助。

编辑: 也试过:

cvSmooth(TempImage, TempImage, CV_GAUSSIAN, 9, 9, 3);
cvThreshold(TempImage, TempImage, 127, 255, CV_THRESH_BINARY);

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

最佳答案

enter image description here

如果这是您想要的平滑结果,可以通过执行高斯模糊,然后进行阈值处理来获得。 IE。使用 cvSmoothCV_GAUSSIAN 作为参数。后跟 cvThreshold

如果您想要比阈值化(如 this)更平滑的过渡,您可以通过调整级别(重新映射颜色范围以便保留一些边缘过渡)来实现。

更新 要解释如何在阈值上获得平滑(抗锯齿)边缘,请考虑阈值的作用。它基本上一次处理图像中的每个像素。如果像素值低于阈值,则设置为黑色(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

关于opencv - 我如何平滑 OpenCV 中的曲线(轮廓)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7416025/

相关文章:

python - Opencv:使用 python 导入 highgui

android - 在 Canvas 上画一颗心

java - 在 Matlab/Java 中将手部运动建模为 3D 曲线

algorithm - 用指数平滑和不规则事件估计事件的发生率

python - 如果它们相交,则合并两个区域

c++ - findHomography 返回的 mask 参数值代表什么?

python - python OpenCV(cv2)putText方法中的中文编码

qt - 使用 N 个点创建弯曲路径

css - 平滑地放慢动画

python - 没有循环的python中的均值滤波器