2014-10-20 76 views
1

我想要抓住bag的单词在c + +和我有一些示例代码,但这个错误不断抛出它,我不知道为什么。C++一袋词 - OpenCV:断言失败

我完全不熟悉这一点,我非常失落。

下面的代码的整体:

#include "stdafx.h" 
#include <opencv/cv.h> 
#include <opencv/highgui.h> 
#include <opencv2/nonfree/features2d.hpp> 

using namespace cv; 
using namespace std; 

#define DICTIONARY_BUILD 1 // set DICTIONARY_BUILD 1 to do Step 1, otherwise it goes to step 2 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
#if DICTIONARY_BUILD == 1 

//Step 1 - Obtain the set of bags of features. 

//to store the input file names 
char * filename = new char[100];   
//to store the current input image 
Mat input; 

//To store the keypoints that will be extracted by SIFT 
vector<KeyPoint> keypoints; 
//To store the SIFT descriptor of current image 
Mat descriptor; 
//To store all the descriptors that are extracted from all the images. 
Mat featuresUnclustered; 
//The SIFT feature extractor and descriptor 
SiftDescriptorExtractor detector; 

//I select 20 (1000/50) images from 1000 images to extract feature descriptors and build the vocabulary 
for(int f=0;f<999;f+=50){  
    //create the file name of an image 
    sprintf(filename,"G:\\testimages\\image\\%i.jpg",f); 

    //open the file 
    input = imread(filename, CV_LOAD_IMAGE_GRAYSCALE); // -- Forgot to add in 

    //detect feature points 
    detector.detect(input, keypoints); 
    //compute the descriptors for each keypoint 
    detector.compute(input, keypoints,descriptor);  
    //put the all feature descriptors in a single Mat object 
    featuresUnclustered.push_back(descriptor);  
    //print the percentage 
    printf("%i percent done\n",f/10); 
} 


//Construct BOWKMeansTrainer 
//the number of bags 
int dictionarySize=200; 
//define Term Criteria 
TermCriteria tc(CV_TERMCRIT_ITER,100,0.001); 
//retries number 
int retries=1; 
//necessary flags 
int flags=KMEANS_PP_CENTERS; 
//Create the BoW (or BoF) trainer 
BOWKMeansTrainer bowTrainer(dictionarySize,tc,retries,flags); 
//cluster the feature vectors 
Mat dictionary; 


dictionary=bowTrainer.cluster(featuresUnclustered); // -- BREAKS 


//store the vocabulary 
FileStorage fs("dictionary.yml", FileStorage::WRITE); 
fs << "vocabulary" << dictionary; 
fs.release(); 

#else 
//Step 2 - Obtain the BoF descriptor for given image/video frame. 

//prepare BOW descriptor extractor from the dictionary  
Mat dictionary; 
FileStorage fs("dictionary.yml", FileStorage::READ); 
fs["vocabulary"] >> dictionary; 
fs.release(); 

//create a nearest neighbor matcher 
Ptr<DescriptorMatcher> matcher(new FlannBasedMatcher); 
//create Sift feature point extracter 
Ptr<FeatureDetector> detector(new SiftFeatureDetector()); 
//create Sift descriptor extractor 
Ptr<DescriptorExtractor> extractor(new SiftDescriptorExtractor);  
//create BoF (or BoW) descriptor extractor 
BOWImgDescriptorExtractor bowDE(extractor,matcher); 
//Set the dictionary with the vocabulary we created in the first step 
bowDE.setVocabulary(dictionary); 

//To store the image file name 
char * filename = new char[100]; 
//To store the image tag name - only for save the descriptor in a file 
char * imageTag = new char[10]; 

//open the file to write the resultant descriptor 
FileStorage fs1("descriptor.yml", FileStorage::WRITE); 

//the image file with the location. change it according to your image file location 
sprintf(filename,"G:\\testimages\\image\\1.jpg");  
//read the image 
Mat img=imread(filename,CV_LOAD_IMAGE_GRAYSCALE);  
//To store the keypoints that will be extracted by SIFT 
vector<KeyPoint> keypoints;  
//Detect SIFT keypoints (or feature points) 
detector->detect(img,keypoints); 
//To store the BoW (or BoF) representation of the image 
Mat bowDescriptor;  
//extract BoW (or BoF) descriptor from given image 
bowDE.compute(img,keypoints,bowDescriptor); 

//prepare the yml (some what similar to xml) file 
sprintf(imageTag,"img1");   
//write the new BoF descriptor to the file 
fs1 << imageTag << bowDescriptor;  

//You may use this descriptor for classifying the image. 

//release the file storage 
fs1.release(); 
#endif 
printf("\ndone\n"); 
return 0; 
} 

但随后它引发该作业:

OpenCV的错误:断言失败(data.dims < = 2 & &类型== CV_32F & & K> 0)in cv :: kmeans,file C:\ buildslave64 \ win64_amdoc1 \ 2_4_PackSlave-win32-vc11-shared \ opencv \ modules \ core \ src \ matrix.cpp,line 2701

请帮忙。

编辑

线,它打破上:

dictionary = bowTrainer.cluster(featuresUnclustered); // -- Breaks 

EDIT 2

Ive come across this,但我不知道该如何翻译它来帮助我的事业。

+0

所以,你可以做的一件事就是找出触发断言的那一行。之后,你会知道哪个功能正在中断。然后你可以进入OpenCV文档并阅读该函数,看看你使用的参数是否不尊重它的接口。 – Svalorzen 2014-10-20 14:52:29

+0

@Svalorzen编辑以显示破坏它的行 – MLMLTL 2014-10-20 15:04:17

+0

@MLMLTL与您的问题无关,但您确实应该使用'std :: string'而不是那些对'new char []'的调用。 – PaulMcKenzie 2014-10-20 15:28:01

回答

1

因为我不是OpenCV专家,所以我并不是100%确定代码的功能。不过,我可以看到你没有以任何方式初始化input。这可能会导致你没有得到你想要的描述符,因此不会做任何事情。该代码可能会因为预计实际数据而中断,但没有。

一般来说,在处理OpenCV或其他大型“杂乱”库时,我会建议你一步步地进行,并检查结果是你期望的每一步。复制粘贴一大块代码并期望它能够工作并不是最好的行为方式。

+0

input = imread(filename, 0); //是的,这是缺少的。很好地发现! – berak 2014-10-20 15:27:04

+0

我不知道为什么当我复制代码的时候(最初是在那里 - 很可能是在代码运行的时候丢失了它),但即使添加了它,它也没有。 t做得很好。@Svaloren – MLMLTL 2014-10-20 15:36:02

+0

@MLMLTL问题源于OpenCV代码中的一个断言,该断言检查特定矩阵(我认为它是'featuresUnclustered')具有理智的值;特别是它必须具有'dims <= 2',类型为'CV_32F',并且您的集群使用'K> 0'。你必须检查你的变量回溯到你的代码中,并找出你正在处理的值是否理智。我不知道你所使用的电话预计会给你的输入数据,所以你比我更好地找出价值出错的地方。 – Svalorzen 2014-10-20 15:39:03

1
if (allDescriptors.type() != CV_32F) 
{ 
    allDescriptors.convertTo(allDescriptors, CV_32F); 
} 
0

确保第一步中的图像目录是正确的。它应该存在培训图像为0.jpg,50.jpg,...等。在很多情况下会导致此错误发生在未加载图像时。您可以在imread检查后添加以下代码。希望它能工作。

if(input.empty()) 
    { 
     cout << "Error: Image cannot be loaded !" << endl; 
     system("Pause"); 
     return -1; 
    }