根据 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
答案 0 :(得分:1)
如果我们打破断言消息,它会检查一些事情 -
contour1.checkVector(2) >= 0 && contour2.checkVector(2) >= 0
contour1.depth() == CV_32F || contour1.depth() == CV_32S
contour1.depth() == contour2.depth()
听起来你知道上面的第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;
}