【问题标题】:Noise removal to create mask in OpenCV在 OpenCV 中去除噪声以创建掩码
【发布时间】:2016-04-20 08:40:58
【问题描述】:

我需要创建一个蒙版来根据两个相关图像检索一个对象(前景对象)。

图片1:

[![在此处输入图片描述]

图 2:

[![在此处输入图片描述]

图像包含一个前景对象和一个带纹理的背景。 这两个图像几乎相同,只是在 image2 中,前景对象可能发生了一些变化(它可能已被旋转、平移或/和缩放)。

使用 OpenCV,我做了以下事情:

  • 执行图像对齐(使用findTransformECC 和参数cv::MOTION_AFFINE)以获得前景变换;
  • 根据上面的变换矩阵对image1进行变换(使用cv::warpAffine和参数cv::INTER_LINEAR + cv::WARP_INVERSE_MAP);
  • 在 image2 和已经转换的 image1 之间做绝对差异(cv::absdiff & cv::threshold with param cv::THRESH_BINARY_INV)。

我想我已经接近我的目标了,但由于背景区域上残留的噪音,我仍然无法获得干净的前景对象蒙版。

去除 image_absdiff_invert.png(上图)上的所有噪点以创建前景对象的干净蒙版的解决方案是什么?

【问题讨论】:

  • 这里是 image2.png
    查看 imgur.com 上的帖子
    跨度>
  • image2.png [链接] (i.imgur.com/aAafY4K.jpg?1)
  • 尝试腐蚀掩码一次,然后是扩张(打开运算符),然后使用几个关闭运算符(扩张后腐蚀)
  • 米卡,谢谢你的提示。我明天试试。我想在打开和关闭之后我可以做 findcountor 来获取前景对象。

标签: c++ opencv image-processing noise-reduction


【解决方案1】:

我刚试过。

使用形态学操作通常有点棘手(反复试验),并给出了以下结果:

虽然使用中值滤波器可能是一个很好的预处理(甚至可能足以提取轮廓)并给出这个结果(这只是来自输入图像的中值模糊,还没有形态学操作):

这是测试代码:

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);
猜你喜欢
  • 2017-07-05
  • 2014-05-22
  • 1970-01-01
  • 2012-07-03
  • 1970-01-01
  • 2017-06-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多