Reputation: 136
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:
findTransformECC
with param cv::MOTION_AFFINE
) to get transformation of foreground;cv::warpAffine
with param cv::INTER_LINEAR
+ cv::WARP_INVERSE_MAP
) based on the transform matrix above;cv::absdiff
& cv::threshold
with param cv::THRESH_BINARY_INV
) between image2 and already transformed image1. 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.
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
Reputation: 20160
I just tried it.
Using morphological operations is often a bit tricky (trial and error) and gives me this result:
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):
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