2014-10-20 137 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; 
    }