how to check whether two matrices are identical in OpenCV

前端 未结 9 1729
南方客
南方客 2020-11-28 10:44

I have two instances of cv::Mat : m1 and m2. They are of the same numeric type and sizes. Is there any function in OpenCV that returns whether the matrices are identical (ha

相关标签:
9条回答
  • 2020-11-28 10:52

    I use this:

    bool areEqual(const cv::Mat& a, const cv::Mat& b) {
        cv::Mat temp;
        cv::bitwise_xor(a,b,temp); //It vectorizes well with SSE/NEON
        return !(cv::countNonZero(temp) );
    }
    

    If you have to do this operation many times, you can make this into a class, have temp as member and prevent the image to be allocated every time. Detail: Make temp mutable so that areEqual can be a const method.

    Note though that cv::countNonZero only works with cv::Mat of one channel. It's overkill, but in that case one could use cv::split to split each channel into separate images and do cv::countNonZero on them.

    0 讨论(0)
  • 2020-11-28 10:54

    As mentioned by Acme, you can use cv::compare although it is not as clean as you might hope.
    In the following example, cv::compare is called by using the != operator:

    // Get a matrix with non-zero values at points where the 
    // two matrices have different values
    cv::Mat diff = a != b;
    // Equal if no elements disagree
    bool eq = cv::countNonZero(diff) == 0;
    

    Presumably it would be quicker to just iterate through comparing the elements though? If you know the type you could use the STL equal function:

    bool eq = std::equal(a.begin<uchar>(), a.end<uchar>(), b.begin<uchar>());
    
    0 讨论(0)
  • 2020-11-28 10:55

    For multichannel images, you could use cv::Mat::reshape to create a single channel image without any extra overhead.

    An update of Antonio's answer would be

    bool areEqual(const cv::Mat& a, const cv::Mat& b)
    {
        cv::Mat temp;
        cv::bitwise_xor(a,b,temp);
        return !(cv::countNonZero(temp.reshape(1)));
    }
    
    0 讨论(0)
  • 2020-11-28 10:59

    Use cv::compare combined with cv::countNonZero.

    An SO question that might help you further OpenCV compare two images and get different pixels

    0 讨论(0)
  • 2020-11-28 11:00

    As mentioned by Acme and Tim, you can use cv::compare. This is the code I use to compare my cv::Mat:

     bool matIsEqual(const cv::Mat mat1, const cv::Mat mat2){
        // treat two empty mat as identical as well
        if (mat1.empty() && mat2.empty()) {
            return true;
        }
        // if dimensionality of two mat is not identical, these two mat is not identical
        if (mat1.cols != mat2.cols || mat1.rows != mat2.rows || mat1.dims != mat2.dims) {
            return false;
        }
        cv::Mat diff;
        cv::compare(mat1, mat2, diff, cv::CMP_NE);
        int nz = cv::countNonZero(diff);
        return nz==0;
    }
    

    It is important to stand out that the function cv::countNonZero only works with cv::Mat of one channel, so if you need to compare two cv::Mat images, you need first to convert your cv::Mat in this way:

    Mat gray1, gray2;
    cvtColor(InputMat1, gray1, CV_BGR2GRAY);
    cvtColor(InputMat2, gray2, CV_BGR2GRAY);
    

    where InputMat1 and InputMat2 are the cv::Mat you want to compare. After that you can call the function:

    bool equal = matsEqual(gray1, gray2);
    

    I took this code of this site: OpenCV: compare whether two Mat is identical

    I hope this help you.

    0 讨论(0)
  • 2020-11-28 11:02

    The following will work also for multi-channel matrices:

    bool isEqual = (sum(img1 != img2) == Scalar(0,0,0,0));
    

    Since sum accepts matrices with 1 to 4 channels, and returns a Scalar, where the element at [0] is the result of the sum for first channel, and so on.

    0 讨论(0)
提交回复
热议问题