8

I have 2 cv::Mat array (with same size), and when I want to compare them (if identical), I used cv::compare

cv::compare(mat1,mat2,dst,cv::CMP_EQ);

Is there any function that return true/false?

Quyền Anh
  • 103
  • 1
  • 1
  • 10

3 Answers3

12

If you need to compare 2 cv::Mat by sizes, then you might check

if(mat1.size() == mat2.size())
    //do stuff
else
    //do other stuff

If you need to check if 2 cv::Mat are equal, you can perform the AND XOR operator and check if the result is a cv::Mat full of zeros:

cv::bitwise_xor(mat1, mat2, dst);        
if(cv::countNonZero(dst) > 0) //check non-0 pixels
   //do stuff in case cv::Mat are not the same
else
  //do stuff in case they are equal
madduci
  • 2,635
  • 1
  • 32
  • 51
  • 1
    not sure which one is faster, but `dst = mat1-mat2;` followed by the countNonZero would do the same (result inverted). – Micka Sep 04 '14 at 08:25
  • 1
    the bit operators perform a little bit faster than the difference, that's why I proposed bitwose_and – madduci Sep 04 '14 at 08:42
  • 1
    See answer by J. Roy: bitwise_xor should be used rather than bitwise_and. – sircolinton Nov 16 '16 at 17:25
  • @sircolinton I've corrected that, thanks – madduci Nov 16 '16 at 17:53
  • @madduci Thanks, corrected my vote correspondingly :-) – sircolinton Nov 23 '16 at 20:42
  • 1
    dst = mat1-mat2 is returning a clamped value range, so any pixel of mat2 that is bigger than the according one in mat 1 is returning 0. So only dst = (mat1-mat2) + (mat2-mat1) will work, and now its obvious that the bitwise must be faster! – Patrick Z Feb 11 '21 at 13:24
  • Would you say this is faster than `bool eq = cv::countNonZero(a!=b) == 0;` from the other question? – pooya13 Nov 05 '21 at 02:26
6

If you need to check if 2 cv::Mat are equal, you can perform the AND operator and check if the result is a cv::Mat full of zeros:

The AND operator is not the good one for this task. If a matrix is all 0, it will always return true regardless if the other matrix is all 0 or not.

The XOR must be used in this case.

Here the modified version of blackibiza code:

cv::bitwise_xor(mat1, mat2, dst);        
if(cv::countNonZero(dst) > 0) //check non-0 pixels
   //do stuff in case cv::Mat are not the same
else
  //do stuff in case they are equal
J. Roy
  • 61
  • 1
  • 3
0

This function returns true/false based on similarity (untested)

bool MyCompare(Mat img1, Mat img2)
{
    int threshold = (double)(img1.rows * img1.cols) * 0.7; 

    cv::compare(img1 , img2  , result , cv::CMP_EQ );
    int similarPixels  = countNonZero(result);

    if ( similarPixels  > threshold ) {
        return true;
    }
    return false;
}
N1C0
  • 121
  • 4
  • here you compare them based on a threshold. If you want to understand if they are fully equal, you must compare the single bits or set threshold to zero – madduci Sep 04 '14 at 08:15