I want to compare two images and find same and different parts of images. I tired "cv::compare and cv::absdiff" methods but confused which one can good for my case. Both show me different results. So how i can achieve my desired task ?
1 Answer
Here's an example how you can use cv::absdiff to find image similarities:
int main() { cv::Mat input1 = cv::imread("../inputData/Similar1.png"); cv::Mat input2 = cv::imread("../inputData/Similar2.png"); cv::Mat diff; cv::absdiff(input1, input2, diff); cv::Mat diff1Channel; // WARNING: this will weight channels differently! - instead you might want some different metric here. e.g. (R+B+G)/3 or MAX(R,G,B) cv::cvtColor(diff, diff1Channel, CV_BGR2GRAY); float threshold = 30; // pixel may differ only up to "threshold" to count as being "similar" cv::Mat mask = diff1Channel < threshold; cv::imshow("similar in both images" , mask); // use similar regions in new image: Use black as background cv::Mat similarRegions(input1.size(), input1.type(), cv::Scalar::all(0)); // copy masked area input1.copyTo(similarRegions, mask); cv::imshow("input1", input1); cv::imshow("input2", input2); cv::imshow("similar regions", similarRegions); cv::imwrite("../outputData/Similar_result.png", similarRegions); cv::waitKey(0); return 0; } Using those 2 inputs:
You'll observe that output (black background):
16 Comments
shahzaib
Thanks for the great example :).
shahzaib
I implemented your code, but result was not 100 percent accurate as you got in your example. I do not know how to post images in comment here to show you.
Micka
probably because of noise between the images. using absdiff for similarity is a very simple approach! you can upload images on image hosting websites and copy link to comment
shahzaib
Micka
you can vary "threshold" to adjust the result but it wont help in all cases, since "per-pixel" similarity might not be the perfect solution at all.
|



cv::absdiffshould more often be suitable because it tells you how much each pixel differs from the one in the other image. But keep in mind that both methods are only meaningful if both images are perfectly aligned. For example it might be ok to usecv::absdiffto compare a lossy compressed and a non-compressed image but it might not be suitable to compare two images of the same scene with slightly different camera position and/or different illumination.