0
votes

I try to make a dictionary of descriptors by using OpenCV. When I use method .cluster() of BOWKmeansTrainer, my application throws unhandled exception

OpenCV Error: Assertion failed (data.dims <= 2 && type == CV_32F && K > 0) in un known function, file ......\src\opencv\modules\core\src\matrix.cpp, line 2485 Unknown exception

I can't understand why it happens. I tried to change parameters, but it didn't help.

Could You give me some ideas how I can solve this problem?

int main(int argc, char* argv[]) {

const int countClusters = 2;

vector<string> fileList;

GetFilesInFolder(folder_one, fileList);

vector<bool> trainMask(fileList.size());
InitRandomBoolVector(trainMask, 0.1);

Ptr<FeatureDetector> keypointsDetector = FeatureDetector::create("HARRIS");

Ptr<DescriptorExtractor> descriptorsExtractor = DescriptorExtractor::create("BRIEF");

Mat descriptors;
Mat voc;

TermCriteria tc(TermCriteria::COUNT + TermCriteria::EPS, 10, 0.001);
BOWKMeansTrainer bowTrainer(vocSize,tc);
for(int i = 0;i < filesList.size();i++)
{
    if(is_voc.at(i))
    {
        vector<KeyPoint> keypoints;
        Mat image = imread(filesList.at(i));

        keypointsDetector->detect(image,keypoints);
        descriptorsExtractor->compute(image,keypoints,descriptors);
        bowTrainer.add(descriptors);
    }
}
try
{
    voc = bowTrainer.cluster();
}
catch(std::exception ex)
{
    printf(ex.what());
}


return 0;

}

1
The exception message is telling you what the problem is. Read it slowly and carefully.karlphillip
I help him: dimensions <= 2 AND type == CV_32F AND K > 0. So either choose another type or get more dimensions.Thomas Jungblut
I have the same exception which is quite hard to understand. In particular, I do not understand what dimensions <=2 means. Is there anyone suggesting to read the exception carefully who is also able to explain what those dimensions are ?Antonio Sesto

1 Answers

0
votes

Have you checked that the keypoints and descriptors that you are feeding into the BOWKMeansTrainer are valid? I think this might be a good place to start.

I was able to feed descriptors into a BOWKMeansTrainer using SIFT, but not sure about using this with HARRIS/BRIEF. Here is the code for the SIFT method:

    Mat allDescriptors;
    SiftDescriptorExtractor detector;
    for (int i = 1; i <= 10; i++) {
        // get keypoints
        vector<KeyPoint> keypoints;
        // assuming you have a function intToString that converts your iterator to a string,
        // this line creates a file path, e.g. /home/ubuntu/1.jpg to /home.ubuntu/10.jpg
        string imagePath = "<put path to your image here>" + "/" + intToString(i) + ".jpg";
        Mat imageToUse = imread(imagePath, CV_LOAD_IMAGE_GRAYSCALE); //Load as grayscale
        detector.detect(imageToUse, keypoints);
        // get descriptors
        Mat descriptors;
        detector.compute(imageToUse, keypoints,descriptors);
        // load descriptors into your descriptor array
        allDescriptors.push_back(descriptors);
    }

This code uses the SiftDescriptorExtractor for both the key point detection and descriptor extraction. If you save the key points and descriptors to a file you can see that they are Mats of dimension 128*n. Try saving your descriptors in a file and check that they have the dimensions you expect.

If it's not this, then it may be the parms you are using for the trainer.

Good luck. BOWKMeans is really difficult to set up.