去除噪音以在OpenCV中创建蒙版

时间:2016-04-20 08:40:59

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

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

图片1:

[![在此处输入图片说明]

图片2:

[![在此处输入图片说明]

图像包含前景对象和带纹理的背景。 这两个图像大致相同,只是在图像2中,前景对象可能已经改变了一点(它可以被旋转,翻译或/和缩放)。

使用OpenCV,我做了以下几点:

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

我认为我接近目标,但由于背景区域仍然存在噪音,我仍然无法获得前景物体的干净遮罩。

enter image description here

为了创建前景对象的干净遮罩,有什么方法可以去除image_absdiff_invert.png(上图)上的所有噪点?

1 个答案:

答案 0 :(得分: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;
}