OpenCV - 删除"白色"来自图像的伪像并拟合曲线

时间:2014-04-04 02:59:54

标签: c++ opencv

我有一张图片,我需要删除" white"不代表检测到的曲线的工件。我想保留表示曲线的白色像素,但是,删除远离曲线的像素异常值。删除工件后,我想为图像中的点拟合一条平滑的曲线。

这是我的形象:

white detected curve

图像是仅具有黑点和白点的8位灰度图像。 "曲线中的白色像素"是感兴趣的领域,其中大多数只是一个像素厚。一些白色像素彼此连接,但不是全部。一些白色像素散布在一起。我想删除这些白色像素,因为它们对整体形状没有贡献,因为我想为它们拟合平滑的曲线。

到目前为止,我已尝试执行dilation,然后执行erosionclosingblack hat操作。他们似乎都没有给我我期望的结果。 我还尝试迭代图像中的所有点,找到亮点,查看该像素周围的3x3邻域,并将值设置为0,如果它没有超过两个等于它自己的邻居。

为了达到理想的效果,我可以申请什么?此外,一旦我有我的决赛"清洁"输出,如何将平滑曲线拟合到图像中的点?

1 个答案:

答案 0 :(得分:0)

我不知道如何拟合曲线,你会很高兴在另一个问题中提出这个问题。


关于噪音:这个功能应该可以解决问题,我已经用它去除了黑色和等待图像中的噪点。 这是本书的代码示例:

  

掌握实用计算机视觉项目的OpenCV - Daniel Lelis   巴乔

我在这个函数被实例化的标题中添加了这些包含:

#include  "opencv2/opencv.hpp"
#include <stdio.h>
#include <iostream>
#include <vector>

using namespace cv;
using namespace std;

mask是要过滤的图像,它会删除分析周围任意5个像素中没有点的点... 希望它有所帮助

void removePepperNoise(Mat &mask)
{
// For simplicity, ignore the top & bottom row border.
for (int y=2; y<mask.rows-2; y++) {
    // Get access to each of the 5 rows near this pixel.
    uchar *pThis = mask.ptr(y);
    uchar *pUp1 = mask.ptr(y-1);
    uchar *pUp2 = mask.ptr(y-2);
    uchar *pDown1 = mask.ptr(y+1);
    uchar *pDown2 = mask.ptr(y+2);

    // For simplicity, ignore the left & right row border.
    pThis += 2;
    pUp1 += 2;
    pUp2 += 2;
    pDown1 += 2;
    pDown2 += 2;
    for (int x=2; x<mask.cols-2; x++) {
        uchar v = *pThis;   // Get the current pixel value (either 0 or 255).
        // If the current pixel is black, but all the pixels on the 2-pixel-radius-border are white
        // (ie: it is a small island of black pixels, surrounded by white), then delete that island.
        if (v == 0) {
            bool allAbove = *(pUp2 - 2) && *(pUp2 - 1) && *(pUp2) && *(pUp2 + 1) && *(pUp2 + 2);
            bool allLeft = *(pUp1 - 2) && *(pThis - 2) && *(pDown1 - 2);
            bool allBelow = *(pDown2 - 2) && *(pDown2 - 1) && *(pDown2) && *(pDown2 + 1) && *(pDown2 + 2);
            bool allRight = *(pUp1 + 2) && *(pThis + 2) && *(pDown1 + 2);
            bool surroundings = allAbove && allLeft && allBelow && allRight;
            if (surroundings == true) {
                // Fill the whole 5x5 block as white. Since we know the 5x5 borders
                // are already white, just need to fill the 3x3 inner region.
                *(pUp1 - 1) = 255;
                *(pUp1 + 0) = 255;
                *(pUp1 + 1) = 255;
                *(pThis - 1) = 255;
                *(pThis + 0) = 255;
                *(pThis + 1) = 255;
                *(pDown1 - 1) = 255;
                *(pDown1 + 0) = 255;
                *(pDown1 + 1) = 255;
            }
            // Since we just covered the whole 5x5 block with white, we know the next 2 pixels
            // won't be black, so skip the next 2 pixels on the right.
            pThis += 2;
            pUp1 += 2;
            pUp2 += 2;
            pDown1 += 2;
            pDown2 += 2;
        }
        // Move to the next pixel.
        pThis++;
        pUp1++;
        pUp2++;
        pDown1++;
        pDown2++;
    }
}