Putra
Putra

Reputation: 136

Noise removal to create mask in OpenCV

I need to create a mask to retrieve an object (foreground object) based on two related images.

Image 1:

[![enter image description here]

Image 2:

[![enter image description here]

The images contain a foreground object and a background with texture. The two images are mostly the same except that in image2, the foreground object may have changed a little bit (it could have been rotated, translated or/and scaled).

Using OpenCV, I did the followings:

I think I am close to my goal but I still can not get clean mask of foreground object due to remaining noises on the background area.

enter image description here

What is the solution to remove all noise on the image_absdiff_invert.png (above) in order to create a clean mask of the foreground object ?

Upvotes: 3

Views: 3373

Answers (1)

Micka
Micka

Reputation: 20160

I just tried it.

Using morphological operations is often a bit tricky (trial and error) and gives me this result:

enter image description here

While using a median filter might be a good pre-processing (or maybe even enough for your contour extraction) and gives this result (this is just median blur from the input image, no morphological operations yet):

enter image description here

here's the test code:

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;
}

Upvotes: 2

Related Questions