c++ - OpenCV 功能检测和匹配 - 绘图匹配段错误

标签 c++ opencv segmentation-fault surf object-detection

正在关注 this example ,
我正在尝试构建一个应用程序来识别视频中的对象。
我的程序由以下步骤组成(请参阅下面每个步骤的代码示例):

  1. 将待识别物体的图像读入cv::Mat对象。
  2. 检测对象中的关键点并计算描述符。
  3. 阅读视频的每一帧,
  4. 检测帧的关键点并计算描述符,
  5. 将框架的描述符与对象的描述符相匹配,
  6. 绘制结果。

问题:第 6 步导致段错误(参见下面的代码)。
问题:是什么原因造成的,我该如何解决?

谢谢!

注意事项:

  1. 程序在段错误之前运行了几帧。崩溃发生在第 23 帧,这是视频中包含任何内容(即不是全黑)的第一帧。
  2. 通过删除 drawMatches(...); 行,没有崩溃。
  3. 在 Windows 7、OpenCV 2.4.2、MinGW 上运行。

调试尝试:

通过 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);
}

段错误之前的屏幕截图: Screenshot

第 22 帧(全黑): Frame 22

第 23 帧(出现段错误): Frame 23

最佳答案

问题出在 drawMatches 中的参数顺序。
正确的顺序是:

drawMatches(frame, keypoints_frame, object, keypoints_object, matches, output);

解释:

在第 5 步中,我使用了 matcher 对象的 match 方法:

matcher.match(descriptors_frame, descriptors_object, matches);

signature of this method

void match( const Mat& queryDescriptors, const Mat& trainDescriptors,
            CV_OUT vector<DMatch>& matches, const Mat& mask=Mat() ) const;

这意味着 matches 包含 from trainDescriptors to queryDescriptors 的匹配项。< br/> 在我的例子中,火车描述符属于 object,查询描述符属于 frame,因此 matches 包含匹配项 from 对象 框架

The signature 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);

该方法在不正确的图像中查找匹配项的坐标,这可能会导致尝试访问“越界”像素;因此出现段错误。

关于c++ - OpenCV 功能检测和匹配 - 绘图匹配段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13001158/

相关文章:

C 链表 - 条件跳转或移动取决于未初始化值链表

c++ - 从非 ui 类到 Qt UI 的回调函数

c++ - 在 native C++ 中检查多个文件 md5s

python-3.x - Qt : Session management error in opencv python

opencv - 我怎样才能匹配两个撕裂的边缘?

java - 如何使用分水岭改进图像分割?

改变静态数组

c++ - 了解 C++ 中的指针初始化行为

c++ - 类与辅助例程 - C++

c++ - 如何删除放入 std::cout 的最后一个字符?