I need to subtract two images:
Before calling subtract method following steps are performed:
object image (img1) is located in scene image (img2) using findHomography
and perspectiveTransform
methods.
Fix perspective using getPerspectiveTransform
and warpPerspective
methods
then subtract
method is called but the output image contains lines/contours which should have been subtracted.
As per my observation this might be due to noise present in one image, it does not appear to be as sharp as img1, I tried calling subtract after sharpening it but it did not work.
Any suggestion/guidance is appriciated
To remove unsharpness artifacts and slightly imperfect alignment issues, you can try to just dilate the template image. You'll lose some input information though.
If you want to do it "better", I would suggest you to to try find each contour of the template image in the input image (e.g. with active contours). Everything that remains, should be a user input.
But here the simple version with dilation:
Input:
input mask image:
template mask image after dilation:
difference image: input - template
please mind that I dont use any perspective correction, which might or might not improve the results!
int main()
{
// edited image:
cv::Mat input = cv::imread("../inputData/earth-science-worksheet-edited.png");
cv::Mat grayInput;
cv::cvtColor(input,grayInput,CV_BGR2GRAY);
cv::Mat maskInput = grayInput < 150; // find everything that isn't "white" on your sheet of paper
// template image:
cv::Mat templateImage = cv::imread("../inputData/earth-science-worksheet-printable.png");
cv::Mat grayTemplate;
cv::cvtColor(templateImage,grayTemplate,CV_BGR2GRAY);
cv::Mat maskTemplate = grayTemplate < 150; // find everything that isn't "white" on your sheet of paper
// dilate the template image to overcome sharpness effects and imperfect alignment
cv::dilate(maskTemplate, maskTemplate, cv::Mat(), cv::Point(-1,-1),1);
// compute the difference image
cv::Mat difference = maskInput - maskTemplate;
cv::imshow("input", input);
cv::imshow("mask template", maskTemplate);
cv::imshow("mask input", maskInput);
cv::imshow("difference", difference);
cv::waitKey(0);
return 0;
}
if changed to cv::dilate(maskTemplate, maskTemplate, cv::Mat(), cv::Point(-1,-1),2);
you lose a little more of the "input", but you remove the other noise pixel.