Я пытаюсь создать программу «Сумка визуальных слов», но у меня возникает проблема. Каждый раз, когда я запускаю программу, я либо получаю ошибку segmentation fault: 11
, либо если я изменяю переменную dictSize, я получаю error: (-215) N >= K in function kmeans
. Я попытался изменить размер изображений, используя разные, но ничего не помогает. Вот то, что я до сих пор:Любая ошибка сегментации 11 или (-215) N> = K
#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;
}
Вышеуказанный ответ сфокусирован только на ошибку seg, которая, по-видимому, является фокусом исходного вопроса. Есть еще что-то, что я считал бы «неправильным» с исходным кодом, например, идея добавления «./» к указанному каталогу. Мои предложения по исправлению ** того, как вы это делаете, не должны рассматриваться как одобрение идеи о том, что вы должны это делать. Я не пытаюсь переписать всю вашу программу лучше. – JSF
Кроме того, ваша манипуляция строками C в коде C++ неразумна. Хотя мой ответ был направлен на устранение ошибки seg из-за неправильного использования строк C, ваш лучший выбор заключался бы в сокращении использования строк C. Преобразуйте строки C в std :: string перед тем, как манипулировать ими, а затем войдите в std :: string как строку C после манипуляции, когда вам понадобится снова строка C. – JSF
Эй, JSF, как вы могли заметить, я полный новичок на C++. Я исправил то, что вы указали, но это не решило мою проблему. Я посмотрю, смогу ли я это исправить. – ruben1691