C++ OpenCV功能检测和匹配-图形匹配上的segfault
以下,C++ OpenCV功能检测和匹配-图形匹配上的segfault,c++,opencv,segmentation-fault,surf,object-detection,C++,Opencv,Segmentation Fault,Surf,Object Detection,以下, 我正在尝试构建一个应用程序来识别视频中的对象。 我的程序由以下步骤组成(请参见下面每个步骤的代码示例): 将要识别的对象的图像读取到cv::Mat对象中 检测对象中的关键点并计算描述符 阅读视频的每一帧 检测关键点并计算帧描述符 将框架的描述符与对象的描述符匹配 得出结果 问题:第6步导致分段错误(参见下面的代码)。 问题:是什么原因造成的,我如何修复 谢谢大家! 注意事项: SurfFeatureDetector detector(500); SurfDescriptorExtract
我正在尝试构建一个应用程序来识别视频中的对象。
我的程序由以下步骤组成(请参见下面每个步骤的代码示例):
cv::Mat
对象中问题:是什么原因造成的,我如何修复 谢谢大家! 注意事项:
SurfFeatureDetector detector(500);
SurfDescriptorExtractor extractor;
vector<KeyPoint> keypoints_object;
Mat descriptors_object;
detector.detect(object , keypoints_object);
extractor.compute(object, keypoints_object, descriptors_object);
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);
}
drawMatches(…)的行代码>没有故障
SurfFeatureDetector detector(500);
SurfDescriptorExtractor extractor;
vector<KeyPoint> keypoints_object;
Mat descriptors_object;
detector.detect(object , keypoints_object);
extractor.compute(object, keypoints_object, descriptors_object);
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);
}
通过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);
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);
}
surfeaturedetector检测器(500);
表面描述符牵引器;
矢量关键点;
Mat描述符\u对象;
检测器。检测(对象、关键点和对象);
计算(对象、关键点对象、描述符对象);
步骤3-6:
SurfFeatureDetector detector(500);
SurfDescriptorExtractor extractor;
vector<KeyPoint> keypoints_object;
Mat descriptors_object;
detector.detect(object , keypoints_object);
extractor.compute(object, keypoints_object, descriptors_object);
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);
}
视频捕获(视频文件);
namedWindow(“输出”,0);
BFMatcher匹配器(NORM_L2,true);
矢量关键点;
向量匹配;
垫架,
产出,
描述符框架;
while(true)
{
//步骤3:
捕获>>帧;
if(frame.empty())
{
打破
}
CVT颜色(边框、边框、CV_rgb2灰色);
//步骤4:
检测器。检测(帧、关键点和帧);
计算(框架、关键点框架、描述符框架);
//步骤5:
匹配(描述符\框架,描述符\对象,匹配);
//步骤6:
drawMatches(对象、关键点\对象、帧、关键点\帧、匹配、输出);
imshow(“输出”,Output);
等待键(1);
}
故障前的屏幕截图:
第22帧(全黑):
第23帧(发生SEGFULT时):
您是否尝试过在调试器中运行程序
只是一个猜测,drawmatch在没有比赛的情况下会出错??如果(!matches.empty())在
drawMatches
之前,请尝试添加。顺便问一下,在调用matcher.matches(…)
之前,您确定matches
已清空吗?如果没有,您应该在每次循环迭代时手动执行。问题在于drawMatches中参数的顺序。
正确的顺序是:
drawMatches(frame, keypoints_frame, object, keypoints_object, matches, output);
说明:
Mat object;
object = imread(OBJECT_FILE, CV_LOAD_IMAGE_GRAYSCALE);
在步骤5中,我使用matcher
对象的match
方法:
matcher.match(descriptors_frame, descriptors_object, matches);
问题是
调用参数顺序不正确的drawMatches时:
drawMatches(object, keypoints_object, frame, keypoints_frame, matches, output);
该方法在不正确的图像中查找匹配的坐标,这可能会导致尝试访问“越界”像素;因此分割错误。谢谢您的回复。是的,我确实尝试过通过调试器运行程序,但是因为我使用的是OpenCV DLL,所以我无法进入库的代码。我只知道问题出在drawMatches
上。此外,我怀疑这是图书馆本身的问题;我想我用错了。另外,问题不在于匹配
,因为存在其他空帧,其中匹配
为空,并且问题不会发生。顺便说一句,我在每次迭代中清空匹配的对象(尽管我认为这不是真的必要);我不是在这里写的。试着在调试模式下编译OpenCV。使用CMake应该非常简单。使用minGW,您应该生成linux生成文件。但它也适用于VC++2010 express,就在上周。谢谢你,这是个好主意,但解决方案实际上简单得多,由于注意力不够,我错过了它(见我的答案)。