【发布时间】:2016-03-14 02:16:34
【问题描述】:
我已经使用 A-KAZE 特征描述符训练了 BOW 码本(词汇表),并尝试使用 BFMatcher 和 knnMatch 将新提取的特征与码本进行比较。
相反,我收到以下错误,
OpenCV Error: Assertion failed (_queryDescriptors.type() == trainDescType) in knnMatchImpl, file /home/cecilia/opencv-3.0.0/modules/features2d/src/matchers.cpp, line 722 terminate called after throwing an instance of 'cv::Exception' what(): /home/cecilia/opencv-3.0.0/modules/features2d/src/matchers.cpp:722: error: (-215) _queryDescriptors.type() == trainDescType in function knnMatchImpl
我使用了以下示例
我的直觉是我错误地将码本添加到匹配器中,但我找不到任何支持另一种方法的文档或示例。如何将我的密码本与新示例一起使用。
MCVE
/* BOWTest.cpp*/
#include <opencv2/imgcodecs.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>
#include <stdio.h>
#include <dirent.h>
using namespace cv;
using namespace std;
std::string outputFile = "test_codebook.png";
std::string trainingDir = "dataset/";
std::string outputPrefix = "output/res_custom_";
void train(Mat codebook, int codebook_n, Ptr<Feature2D> akaze);
void test(Mat codebook, Ptr<Feature2D> akaze);
int main(int ac, char** av) {
Ptr<Feature2D> feature = AKAZE::create();
Mat codebook;
int codebook_n = 100;
//train(codebook, codebook_n, feature);
test(codebook, feature);
}
//I included the train method to show how the codebook is trained, but it is not actually called in this example
void train(Mat codebook, int codebook_n, Ptr<Feature2D> akaze){
//defining terms for bowkmeans trainer
TermCriteria tc(TermCriteria::MAX_ITER + TermCriteria::EPS, 10, 0.001);
int retries = 1;
int flags = KMEANS_PP_CENTERS;
BOWKMeansTrainer bowTrainer(codebook_n, tc, retries, flags);
int i = 0;
unsigned long numPoints = 0;
DIR *d;
struct dirent *dir;
d = opendir(trainingDir.c_str());
if (d) {
while ((dir = readdir(d)) != NULL){
try {
Mat img;
std::string imgName = trainingDir + dir->d_name;
i = i + 1;
printf("%d, %lu: %s ...", i,numPoints, imgName.c_str());
img = imread(imgName, CV_LOAD_IMAGE_COLOR);
if(img.empty()){ //not image
printf("bad.\n");
continue;
}
printf("loaded.\n");
resize(img, img, Size(200, 200));
Mat features;
vector<KeyPoint> keypoints;
akaze->detectAndCompute(img, Mat(), keypoints, features);
features.convertTo(features, CV_32F);
bowTrainer.add(features);
Mat res;
drawKeypoints(img, keypoints, res);
std::string output_img = outputPrefix + dir->d_name;
imwrite(output_img, res);
numPoints += features.rows;
}catch(int e){
cout << "An exception occurred. Nr. " << e << '\n';
}
}
printf("Read images!");
closedir(d);
codebook = bowTrainer.cluster();
imwrite(outputFile, codebook);
}
}
void test(Mat codebook, Ptr<Feature2D> akaze){
codebook = imread(outputFile);
int codebook_n = codebook.rows;
BFMatcher matcher(NORM_L2);
matcher.add(std::vector<cv::Mat>(1, codebook));
Mat res(Size(codebook_n * 10, 3*10), CV_8UC3, Scalar(0));
vector<int> res_idx(codebook_n, 0);
try {
Mat img;
String imgName = trainingDir + "dog1.jpeg";
img = imread(imgName, CV_LOAD_IMAGE_COLOR);
if(img.empty()){ //not image
printf("bad.\n");
}else{
printf("loaded.\n");
resize(img, img, Size(200, 200));
Mat features;
vector<KeyPoint> keypoints;
akaze->detectAndCompute(img, noArray(), keypoints, features);
features.convertTo(features, CV_32F);
vector< vector< DMatch > > nn_matches;
matcher.knnMatch(features, nn_matches, 1);
printf("%d matched keypoints", nn_matches.size());
}
}catch(int e){
cout << "An exception occurred. Nr. " << e << '\n';
}
}
test_codebook.png
dog1.jpeg
输出
loaded.
OpenCV Error: Assertion failed (_queryDescriptors.type() == trainDescType) in knnMatchImpl, file /home/cecilia/opencv-3.0.0/modules/features2d/src/matchers.cpp, line 722
terminate called after throwing an instance of 'cv::Exception'
what(): /home/cecilia/opencv-3.0.0/modules/features2d/src/matchers.cpp:722: error: (-215) _queryDescriptors.type() == trainDescType in function knnMatchImpl
【问题讨论】:
-
你有一些概念上的错误,这就是你的实现崩溃的原因。在解决这些问题之前,您能解释一下您要做什么吗?您想在训练图像中找到最接近的吗?或者您想将测试图像分类为属于特定类别?
-
@Miki 此时,我不想执行任何分类任务。我只是想从测试示例中提取特征。稍后,我将使用该功能进行对象验证。我想比较两个图像是否包含相同的对象。目前,我只是在尝试评估新图像中检测到的 Akaze 特征的数量以及它们对应的码本单词。
-
答案应该可以帮助您前进。请让我知道它是否适合您。