2014-10-20 3 views
1

C++에서 Bag Of Words를 사용하고 있는데 샘플 코드가 있지만이 오류는 계속 던져 버리고 그 이유를 모르겠습니다.C++ Bag of Words - 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) cv :: kmeans 파일 C : \ buildslave64 \ win64_amdoc1 \ 2_4_PackSlave-win32-vc11-shared \ opencv \ modules \ core \ src \ matrix.cpp 줄 2701

도움주세요.

편집이에 나누기

라인 :

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

편집 2

Ive come across this,하지만 난 내 원인을 돕기 위해 번역하는 방법을 확실입니다.

+0

그래서 당신이 할 수있는 한 가지는 단정을 유발하는 선을 파악하는 것입니다. 그 후에 어떤 기능이 고장 났는지 알 수 있습니다. 그런 다음 OpenCV 설명서를 읽고 해당 기능에 대해 읽고 사용중인 매개 변수 중 하나가 해당 인터페이스를 준수하지 않는지 확인하십시오. – Svalorzen

+0

@Svalorzen 부울 라인을 보여주기 위해 편집 됨 – MLMLTL

+0

@MLMLTL 문제와 관련이 없지만,'new char []'를 호출하는 대신'std :: string'을 사용해야합니다. – PaulMcKenzie

답변

1

내가 OpenCV 전문가가 아니기 때문에 코드가하는 일을 100 % 확신 할 수는 없습니다. 그러나 어떤 식 으로든 input을 초기화하지 않는 것을 볼 수 있습니다. 이것은 아마도 당신이 원하는 디스크립터를 얻지 못하게 할 것이고 따라서 아무 것도하지 않을 것이다. 그런 다음 실제 데이터가 들어 있기 때문에 코드가 손상 될 수 있지만 아무 것도 없습니다.

일반적으로 OpenCV 또는 다른 종류의 더러워진 라이브러리를 다루는 경우 단계별로 진행하고 그 결과를 확인하는 것이 모든 단계에서 기대하는 바입니다. 큰 코드를 복사하여 작동하도록 기대하는 것은 절대로 최선의 행동 길은 아닙니다.

+0

입력 = imread (파일 이름, 문자열)을로드하기 전에 실제로 if : input (입력. 비어있는) 0); // 예, 이것은 없습니다. 멋지게 발견! – berak

+0

내가 왜 코드를 복사했는지 알지 못한다. (처음에는 거기에 있었다 - 코드를 사용하기 위해 코드를 가지고 놀았을 때 그것을 잃어 버렸을 가능성이 높다.) 그러나 추가 된 경우에도, 많이 좋아[email protected] – MLMLTL

+0

@ MLMLTL이 문제는 OpenCV 코드에서 특정 행렬 ('featuresUnclustered'라고 생각 함)이 정상적인 값인지 검사하는 어설 션에서 비롯됩니다. 특히'dims <= 2','CV_32F' 타입이어야하며 클러스터링은'K> 0'을 사용해야합니다. 코드에서 백 트레이스 변수를 검사하고 처리중인 값이 정상적인지 여부를 확인해야합니다. 당신이 사용하는 전화가 당신의 입력 데이터와 함께 제공 될 것으로 기대되는 것이 무엇인지 모르겠으니, 당신은 나보다 더 나은 위치에있어 가치가 어디서 잘못되었는지 알아 내야합니다. – Svalorzen

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