matchShapes使用灰度图像opencv

时间:2015-04-24 18:40:56

标签: opencv template-matching

根据 matchShapes 文档,输入可以是灰度图像或轮廓。但是当我尝试两个灰度图像时,我得到了一个断言失败的错误。经过进一步的探索,我从here发现Mat对象必须是一维向量,类型为CV_32FC2或CV_32SC2。

使用this答案,我将图像转换为CV_32FC2后将其转换为float的矢量数组。我仍然得到一个断言错误。

有谁能告诉我如何使用 matchShapes 功能比较2个灰度图像?

更新

错误消息

  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

当我使用

    pkg-config --modversion opencv

它说版本为2.4.9

1 个答案:

答案 0 :(得分:1)

如果我们打破断言消息,它会检查一些事情 -

  1. contour1.checkVector(2) >= 0 && contour2.checkVector(2) >= 0
  2. contour1.depth() == CV_32F || contour1.depth() == CV_32S
  3. contour1.depth() == contour2.depth()
  4. 听起来你知道上面的第2部分和第3部分,所以我猜测它在第1部分失败了。

    根据OpenCV文档,checkVector是一个

    的函数
      如果矩阵是1通道(N x ptdim)或ptdim通道(1 x N)或(N x 1),则

    返回N;否则为负数

    不幸的是,这是一个相当神秘的信息。据我了解,它检查输入维度的维度 - 在这种情况下,失败的断言传入2,并验证其维度大于0.这排除了有一个空数组的可能性,并验证其他维度是否存在。 TLDR;它检查输入是否是足够维度的一维数组。

    我猜你的错误是传递点矢量矢量的结果 - 相反,你必须传递一个单一的形状'在matchShapes的时间,即点矢量

    这是一个小小的测试用例,虽然不是特别有趣,但应该没有问题 -

    #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;
    }