0

I am trying to write code to find out if two images are the same. I was able to read the images in as BGR and was able to subtract one from another. I need to do a check and see if the difference contains only zeros. I know there is a function called countNonZero, but it only works on single channel, not 3 channels. An solution I had was looping through the entire matrix and checking if everything is zero, but that is too slow. Is there any efficient way of checking? Here is my code below.

int main(int argc, char** argv)
{
  if(argc != 3)
  {
    printf("usage: DisplayImage.out <testImg.png> <copy.png>\n");
    return -1; 
  }

  Mat image;
  Mat copy;
  Mat output;

  image = imread(argv[1], 1); 
  copy = imread(argv[2], 1); 

  absdiff(image, copy, output);

  if(countNonZero(output) == 0)
  {
    cout << "Same" << endl;
  }
  else
  {
    cout << "Different" << endl;
  }

  imshow("outut", output);
  waitKey();
  return 0;
}
Programmer
  • 105
  • 2
  • 11
  • 2
    If I were doing this, I would read the files, then start comparing each CPU-sized word of the data in a for loop. As soon as a difference is found, exit. If you get to the end, pass. This will be faster than storing an array of differences to RAM and comparing after the fact. I even bet a loop like this would vectorize well. Whether or not to read the whole files into memory depends on how big they are I guess. – Michael Dorgan Jun 27 '19 at 23:34

2 Answers2

2

You can do this:

Mat diff_im = image - copy;
double s = cv::sum(diff_im)[0];
Julian
  • 909
  • 8
  • 21
1

You can also use the norm() function of the OpenCV with the norm type NORM_L2

double rst = cv::norm(img1, img2, cv::NORM_L2);

The result will be zero in case the images are completely the same.

The more similar, the closer to zero.

Bahramdun Adil
  • 5,907
  • 7
  • 35
  • 68