Search code examples
imageopencvcomputer-visionsubtraction

OpenCv subtract same image but from different sources


I need to subtract two images:

  1. img1 is original image act as objectObject Image (img1)
  2. img2 is clicked using camera act as sceneScene Image (img2)
  3. Result Image: drive.google.com/open?id=0B0IUdCi6RzGcRENDSEdoa3dRN2c&authuser=0 (I cannot add more than two links)

Before calling subtract method following steps are performed:

  1. object image (img1) is located in scene image (img2) using findHomography and perspectiveTransform methods.

  2. 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


Solution

  • 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:

    enter image description here

    template mask image after dilation:

    enter image description here

    difference image: input - template

    enter image description here

    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.

    enter image description here