OpenCV中的噪声去除以创建掩膜

3

我需要创建一个遮罩来基于两个相关的图像检索对象(前景对象)。

图像1:

[![enter image description here]

图像2:

[![enter image description here]

这些图像包含前景对象和带有纹理的背景。这两个图像大部分相同,除了在图像2中,前景对象可能略微改变(它可以被旋转、平移或/和缩放)。

使用OpenCV,我做了以下操作:

  • 执行图像对齐(使用findTransformECC和参数cv::MOTION_AFFINE)以获取前景的变换;
  • 根据上述变换矩阵对图像1进行变换(使用cv::warpAffine和参数cv::INTER_LINEAR+cv::WARP_INVERSE_MAP);
  • 在图像2和已经变换的图像1之间进行绝对差分(cv::absdiff&cv::threshold和参数cv::THRESH_BINARY_INV)。

我认为我已经接近我的目标,但由于背景区域上仍然存在噪声,我仍然无法获得干净的前景对象遮罩。

enter image description here

如何消除图像_absdiff_invert.png(上面的图像)上的所有噪声,以创建前景对象的干净遮罩?


这是image2.png的图片 <blockquote class="imgur-embed-pub" lang="en" data-id="aAafY4K"><a href="//imgur.com/aAafY4K">在imgur.com上查看帖子</a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script> - Putra
image2.png [链接](http://i.imgur.com/aAafY4K.jpg?1) - Putra
尝试对掩模进行一次腐蚀,然后进行膨胀(开运算),接着使用多个闭合运算符(膨胀后跟腐蚀)。 - Micka
Micka,谢谢你的提示。明天我会试一下。我猜在打开和关闭之后,可以使用findcontour来获取前景对象。 - Putra
1个回答

2
我刚刚尝试了一下。
使用形态学操作通常有点棘手(试错),并给我这个结果: enter image description here 而使用中值滤波可能是一个很好的预处理方法(或者甚至足够用于轮廓提取),并给出这个结果(这只是输入图像的中值模糊,还没有进行形态学操作): enter image description here 以下是测试代码:
int main(int argc, char* argv[])
{
    cv::Mat input = cv::imread("C:/StackOverflow/Input/maskNoise.png", CV_LOAD_IMAGE_GRAYSCALE);

    cv::Mat mask = input.clone();

    cv::dilate(mask, mask, cv::Mat());
    cv::dilate(mask, mask, cv::Mat());
    cv::erode(mask, mask, cv::Mat());
    cv::erode(mask, mask, cv::Mat());

    cv::erode(mask, mask, cv::Mat());
    cv::erode(mask, mask, cv::Mat());
    //cv::erode(mask, mask, cv::Mat());
    //cv::erode(mask, mask, cv::Mat());
    //cv::dilate(mask, mask, cv::Mat());
    //cv::dilate(mask, mask, cv::Mat());
    cv::dilate(mask, mask, cv::Mat());
    cv::dilate(mask, mask, cv::Mat());

    cv::Mat median;
    cv::medianBlur(input, median, 7);

    cv::Mat resizedIn;
    cv::Mat resizedMask;
    cv::Mat resizedMedian;
    cv::resize(mask, resizedMask, cv::Size(), 0.5, 0.5);
    cv::resize(median, resizedMedian, cv::Size(), 0.5, 0.5);
    cv::resize(input, resizedIn, cv::Size(), 0.5, 0.5);

    cv::imshow("input", resizedIn);
    cv::imshow("mask", resizedMask);
    cv::imshow("median", resizedMedian);

    cv::imwrite("C:/StackOverflow/Output/maskNoiseMorph.png", mask);
    cv::imwrite("C:/StackOverflow/Output/maskNoiseMedian.png", median);
    cv::waitKey(0);
    return 0;
}

我可以确认这个解决方案,谢谢Micka-san。我只需要添加形态学闭合操作 cv::Mat closing;cv::Mat structuringElement = getStructuringElement(cv::MORPH_RECT, cv::Size(33, 33)); cv::morphologyEx(median, closing, cv::MORPH_CLOSE, structuringElement); - Putra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接