简体   繁体   English

c ++ Bag of Words - OpenCV:断言失败

[英]c++ Bag Of Words - OpenCV: Assertion Failed

I'm trying to get to grips with Bag Of Words in c++ and I have some sample code, but this Error keeps on throwing it and I don't know why. 我试图用c ++中的Bag Of Words来处理,我有一些示例代码,但是这个错误一直在抛出它,我不知道为什么。

I'm completely new to this and am very much lost. 我对此完全陌生,而且非常失落。

Here's the entirety of the code: 这是完整的代码:

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

But then it throws this up: 但后来它抛出了这个:

OpenCV Error: Assertion failed (data.dims <= 2 && type == 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 OpenCV错误:cv :: kmeans中的断言失败(data.dims <= 2 && type == CV_32F && K> 0),文件C:\\ buildslave64 \\ win64_amdoc1 \\ 2_4_PackSlave-win32-vc11-shared \\ opencv \\ modules \\ core \\ src \\ matrix.cpp,第2701行

Help, please. 请帮助。

EDIT 编辑

Line that it breaks on: 它打破的线:

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

EDIT 2 编辑2

Ive come across this , but i am unsure how to translate it to help with my cause. 我遇到过这个 ,但我不确定如何翻译它以帮助我的事业。

I'm not 100% sure of what the code is doing since I'm not an OpenCV expert. 因为我不是OpenCV专家,所以我不能100%确定代码在做什么。 However I can see that you are not initializing input in any way. 但是我可以看到你没有以任何方式初始化input This probably results in you not getting the descriptors you want, and thus not really doing anything. 这可能会导致您无法获得所需的描述符,从而无法做任何事情。 The code then probably breaks since it expects actual data in, but there is none. 然后代码可能会中断,因为它期望实际数据,但没有。

In general, when dealing with OpenCV or other big "kind of messy" libraries I would advise you to proceed step by step, and checking that results are what you expect every step of the way. 一般来说,在处理OpenCV或其他大型“杂乱”库时,我建议你一步一步地进行,并检查结果是你期望的每一步。 Copy-pasting a big blob of code and expecting it to work is never the best course of action. 复制粘贴大量代码并期望它能够正常工作,这绝不是最好的行动方案。

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

Make sure that your image directory in 1st step is correct. 确保第1步中的图像目录正确无误。 It should exist training images as 0.jpg, 50.jpg, ... etc. Cause in a lot of situations, this error occurs when image is not loaded. 它应该存在训练图像为0.jpg,50.jpg,...等。在很多情况下,导致图像未加载时会出现此错误。 You can add following codes after imread to check. 您可以在imread之后添加以下代码进行检查。 Hope it can work. 希望它能奏效。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM