分段故障11或(-215)N> = K.

时间:2015-07-08 12:31:34

标签: c++ opencv3.0

我正在尝试创建一个视觉词汇包,但我遇到了一个问题。每次运行程序时,我都会遇到segmentation fault: 11错误,或者如果我更改了dictSize变量,我会得到error: (-215) N >= K in function kmeans。我尝试使用不同的图像调整图像大小,但似乎没有任何帮助。这就是我现在所拥有的:

#include <opencv2/core/core.hpp>
#include "opencv2/highgui/highgui.hpp"
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/xfeatures2d.hpp>

#include <iostream>
#include <stdio.h>
#include <dirent.h>
#include <string.h>

using namespace std;
using namespace cv;

int main(int argc, const char** argv) {

    //=================================== LEARN ===================================

    struct dirent *de = NULL;
    DIR *d = NULL;
    d = opendir(argv[1]);
    if(d == NULL)
    {
        perror("Couldn't open directory");
        return(2);
    }

    Mat input;
    vector<KeyPoint> keypoints;
    Mat descriptor;
    Mat featuresUnclustered;
    Ptr<DescriptorExtractor> detector = xfeatures2d::SIFT::create();


    while((de = readdir(d))){
          if ((strcmp(de->d_name,".") != 0) && (strcmp(de->d_name,"..") != 0)  && (strcmp(de->d_name,".DS_Store") != 0)) {

            char fullPath[] = "./";
            strcat(fullPath, argv[1]);
            strcat(fullPath, de->d_name);
            printf("Current File: %s\n",fullPath);

            input = imread(fullPath,CV_LOAD_IMAGE_GRAYSCALE);
            cout << "Img size => x: " << input.size().width << ", y: " << input.size().height << endl;
            // If the incoming frame is too big, resize it
            if (input.size().width > 3000) {
                double ratio = (3000.0)/(double)input.size().width;
                resize(input, input, cvSize(0, 0), ratio, ratio); 
                cout << "New size => x: " << input.size().width << ", y: " << input.size().height << endl;
            }

            detector->detect(input, keypoints);
            detector->compute(input, keypoints, descriptor);
            featuresUnclustered.push_back(descriptor);
        }
    }

    closedir(d);

    int dictSize = 200;
    TermCriteria tc(CV_TERMCRIT_ITER,100,0.001);
    int retries = 1;
    int flags = KMEANS_PP_CENTERS;
    BOWKMeansTrainer bowTrainer(dictSize,tc,retries,flags);
    Mat dictionary = bowTrainer.cluster(featuresUnclustered);
    FileStorage fs("dict.yml",FileStorage::WRITE);
    fs << "vocabulary" << dictionary;
    fs.release();

    return 0;
}

1 个答案:

答案 0 :(得分:1)

    char fullPath[] = "./";
    strcat(fullPath, argv[1]);
    strcat(fullPath, de->d_name);

你的代码部分是一个严重的错误(未定义的行为,但很可能是seg错误)。 strcat 为连接分配任何额外空间。它只覆盖第一个字符串中终止空值后面的内容。 您的fullPath被分配了足够的空间用于最初的2个字符加上终止空值。无论如何,终止null可能是属于程序其他部分的内存。

如果您知道操作系统的最大文件路径长度,则可以使用粗略修正,将max加2作为数字(或命名常量)放在fullPath声明中的[]之间。

粗略的修正是计算你想要构建的字符串所需的长度和malloc那么大的空间(一定要计算终止空值)并在那里组合三个字符串。