2

According to the matchShapes documentation, the input can be either gray scale images or contours. But when I tried two gray scale images, I got an assertion failed error. Upon further exploration, I found from here that the Mat object has to be a 1D vector and of type CV_32FC2 or CV_32SC2.

Using this answer, I converted the images to vector array of float after converting them to CV_32FC2. I still get an assertion error.

Can anyone tell me how can I compare 2 grayscale images using matchShapes function?

UPDATE

the error message

  OpenCV Error: Assertion failed (contour1.checkVector(2) >= 0 && contour2.checkVector(2) >= 0 && (contour1.depth() == CV_32F || contour1.depth() == CV_32S) && contour1.depth() == contour2.depth()) in matchShapes, file /home/tonystark/Opencv/modules/imgproc/src/contours.cpp, line 1936
  terminate called after throwing an instance of 'cv::Exception'
  what():  /home/tonystark/Opencv/modules/imgproc/src/contours.cpp:1936: error: (-215) contour1.checkVector(2) >= 0 && contour2.checkVector(2) >= 0 && (contour1.depth() == CV_32F || contour1.depth() == CV_32S) && contour1.depth() == contour2.depth() in function matchShapes

when I used

    pkg-config --modversion opencv

it says the version as 2.4.9

Community
  • 1
  • 1
Lakshmi Narayanan
  • 5,220
  • 13
  • 50
  • 92

1 Answers1

1

If we break the assertion message down, it's checking for a few things --

  1. contour1.checkVector(2) >= 0 && contour2.checkVector(2) >= 0
  2. contour1.depth() == CV_32F || contour1.depth() == CV_32S
  3. contour1.depth() == contour2.depth()

It sounds like you are aware of parts 2 and 3 above, so I'll hazard a guess that it's failing on part 1.

According to the OpenCV documentation, checkVector is a function that

returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise

This is unfortunately a rather cryptic message. As I understand it, it's checking the dimensionality of the input dimension -- in this case, the failing assertion is passing in 2, and verifying that its dimension is greater than 0. This precludes the possibility of having an empty array, and verifies that the other dimension exists. TLDR; it's checking if the input is a 1D array of sufficient dimension.

I'd guess that your error is a result of passing in a vector of vector of points -- instead, you have to pass in a single 'shape' at a time to matchShapes, i.e. a vector of points

here's a little test-case that, although not particularly interesting, should run without problems --

#include <cstdlib>
#include <ctime>    
#include <iostream> 
#include <vector>
#include <opencv2/opencv.hpp>

int main(int argc, char* argv[]) {

    std::srand(std::time(0));

    std::vector<cv::Point> random_pointsA;
    for (int i = 0; i < 1000; ++i) {
      auto rand_x = std::rand() % 255; 
      auto rand_y = std::rand() % 255; 
      random_pointsA.emplace_back(rand_x, rand_y);
    }

    std::vector<cv::Point> random_pointsB;
    for (int i = 0; i < 1000; ++i) {
      auto rand_x = std::rand() % 255; 
      auto rand_y = std::rand() % 255; 
      random_pointsB.emplace_back(rand_x, rand_y);
    }

    auto match_val = cv::matchShapes(random_pointsA, random_pointsB, CV_CONTOURS_MATCH_I1, 0);
    std::cout << "match val: " << match_val << std::endl;
}
alrikai
  • 4,123
  • 3
  • 24
  • 23
  • 1
    Does matchShapes() actually - as claimed in the documentation - take an image as input? – jtlz2 Jul 19 '17 at 11:10