Следующий этот пример,
Я пытаюсь создать приложение для распознавания объектов в видео.
Моя программа состоит из следующих шагов (см. Пример кода каждого шага ниже):
cv::Mat
объект.Проблема: 6-й шаг вызывает ошибку сегментации (см. Код ниже).
Вопрос: Что вызывает это, и как я могу это исправить?
Спасибо!
Заметки:
drawMatches(...);
есть нет авария.Попытка отладки:
Запуск программы через gdb выдает следующее сообщение:
Program received signal SIGSEGV, Segmentation fault.
0x685585db in _fu156___ZNSs4_Rep20_S_empty_rep_storageE () from c:\opencv\build\install\bin\libopencv_features2d242.dll
Шаг 1 — чтение изображения объекта:
Mat object;
object = imread(OBJECT_FILE, CV_LOAD_IMAGE_GRAYSCALE);
Шаг 2 — Обнаружение ключевых точек в объекте и вычислительных дескрипторов:
SurfFeatureDetector detector(500);
SurfDescriptorExtractor extractor;
vector<KeyPoint> keypoints_object;
Mat descriptors_object;
detector.detect(object , keypoints_object);
extractor.compute(object, keypoints_object, descriptors_object);
Шаги 3-6:
VideoCapture capture(VIDEO_FILE);
namedWindow("Output",0);
BFMatcher matcher(NORM_L2,true);
vector<KeyPoint> keypoints_frame;
vector<DMatch> matches;
Mat frame,
output,
descriptors_frame;
while (true)
{
//step 3:
capture >> frame;
if(frame.empty())
{
break;
}
cvtColor(frame,frame,CV_RGB2GRAY);
//step 4:
detector.detect(frame, keypoints_frame);
extractor.compute(frame, keypoints_frame, descriptors_frame);
//step 5:
matcher.match(descriptors_frame, descriptors_object, matches);
//step 6:
drawMatches(object, keypoints_object, frame, keypoints_frame, matches, output);
imshow("Output", output);
waitKey(1);
}
Снимок экрана непосредственно перед сегфолтом:
Рамка 22 (полностью черная):
Кадр 23 (в котором происходит segfault):
Проблема была с порядком параметров в drawMatches
,
Правильный порядок:
drawMatches(frame, keypoints_frame, object, keypoints_object, matches, output);
Объяснение:
На шаге 5 я использую match
метод matcher
объект:
matcher.match(descriptors_frame, descriptors_object, matches);
подпись этого метода является
void match( const Mat& queryDescriptors, const Mat& trainDescriptors,
CV_OUT vector<DMatch>& matches, const Mat& mask=Mat() ) const;
Который означает, что matches
содержит совпадения от trainDescriptors
в queryDescriptors
,
В моем случае дескрипторы поездов имеют object
и дескрипторы запроса имеют frame
, так matches
содержит совпадения от object
в frame
,
Подпись из drawMatches
является
void drawMatches( const Mat& img1, const vector<KeyPoint>& keypoints1,
const Mat& img2, const vector<KeyPoint>& keypoints2,
const vector<DMatch>& matches1to2,
... );
При звонке drawMatches
с некорректный порядок параметров:
drawMatches(object, keypoints_object, frame, keypoints_frame, matches, output);
метод ищет координаты совпадений на неверном изображении, что может привести к попытке доступа к пикселям «за пределами»; Таким образом, ошибка сегментации.
Вы пробовали запустить свою прогу в отладчике?
Просто догадываюсь, что drawmatch — это segfaulting, когда нет совпадений для рисования ?? попробуйте добавить if (!matches.empty())
до drawMatches
, Кстати, ты уверен? matches
опустошается перед звонком matcher.matches(...)
? Если нет, вы должны делать это вручную на каждой итерации цикла.