我正在尝试创建一个视觉词汇包,但我遇到了一个问题。每次运行程序时,我都会遇到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;
}
答案 0 :(得分:1)
char fullPath[] = "./";
strcat(fullPath, argv[1]);
strcat(fullPath, de->d_name);
你的代码部分是一个严重的错误(未定义的行为,但很可能是seg错误)。
strcat 不为连接分配任何额外空间。它只覆盖第一个字符串中终止空值后面的内容。
您的fullPath
被分配了足够的空间用于最初的2个字符加上终止空值。无论如何,终止null可能是属于程序其他部分的内存。
如果您知道操作系统的最大文件路径长度,则可以使用粗略修正,将max加2作为数字(或命名常量)放在fullPath声明中的[]之间。
粗略的修正是计算你想要构建的字符串所需的长度和malloc那么大的空间(一定要计算终止空值)并在那里组合三个字符串。