崩溃错误:矢量下标超出范围

时间:2013-05-17 11:39:07

标签: c++ opencv

此程序在编译器中不显示任何错误,但有1个警告 警告C4018:'<' :签名/未签名不匹配“

此外,当我运行该程序时,它崩溃说“矢量下标超出范围” 我真的需要你的帮助来追踪这个错误:(

#include <stdio.h>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2\imgproc\imgproc.hpp"
#include "opencv2\video\video.hpp"
#include <iostream>
#include <string>
#include <vector>
#include <set>

using namespace cv;
using namespace std;

int main()
{
    Mat img1 = imread("0000.jpg", 1);
    Mat img2 = imread("0001.jpg", 1);
    vector<Point2f> j_pts;
    vector<DMatch>* matches = new vector<DMatch>;
    vector<Point2f> to_find;

    // Detect keypoints in the left and right images
    FastFeatureDetector detector(50);
    vector<KeyPoint> left_keypoints,right_keypoints;
    detector.detect(img1, left_keypoints);
    detector.detect(img2, right_keypoints);
    vector<Point2f>left_points;

    //KeyPointsToPoints(left_keypoints,left_points);
    KeyPoint::convert(left_keypoints,left_points);
    vector<Point2f>right_points(left_points.size());
    // making sure images are grayscale

    Mat prevgray,gray;
    if (img1.channels() == 3) {
        cvtColor(img1,prevgray,CV_RGB2GRAY);
        cvtColor(img2,gray,CV_RGB2GRAY);
    } else {
        prevgray = img1;
        gray = img2;
    }

    // Calculate the optical flow field:
    // how each left_point moved across the 2 images
    vector<uchar>vstatus; vector<float>verror;
    calcOpticalFlowPyrLK
        (prevgray, gray, left_points, right_points,vstatus, verror);

    // First, filter out the points with high error
    vector<Point2f>right_points_to_find;
    vector<int>right_points_to_find_back_index;
    for (unsigned int i=0; i<vstatus.size(); i++) {
        if (vstatus[i] &&verror[i] < 12.0) {
            // Keep the original index of the point in the
            // optical flow array, for future use
            right_points_to_find_back_index.push_back(i);
            // Keep the feature point itself
            right_points_to_find.push_back(j_pts[i]);
        } else {
            vstatus[i] = 0; // a bad flow
        }
    }

    // for each right_point see which detected feature it belongs to
    Mat right_points_to_find_flat =
        Mat(right_points_to_find).reshape(1,to_find.size()); //flatten array
    vector<Point2f>right_features; // detected features
    KeyPoint::convert(right_keypoints,right_features);
    Mat right_features_flat =
        Mat(right_features).reshape(1,right_features.size());

    // Look around each OF point in the right image
    // for any features that were detected in its area
    // and make a match.
    BFMatcher matcher(CV_L2);
    vector<vector<DMatch>>nearest_neighbors;
    matcher.radiusMatch
        (right_points_to_find_flat,right_features_flat,nearest_neighbors,2.0f);

    // Check that the found neighbors are unique (throw away neighbors
    // that are too close together, as they may be confusing)
    std::set<int>found_in_right_points; // for duplicate prevention
    for(int i=0;i<nearest_neighbors.size();i++) {
        DMatch _m;
        if(nearest_neighbors[i].size()==1) {
            _m = nearest_neighbors[i][0]; // only one neighbor
        } else if(nearest_neighbors[i].size()>1) {
            // 2 neighbors ¿ check how close they are
            double ratio = nearest_neighbors[i][0].distance /
                nearest_neighbors[i][1].distance;
            if(ratio < 0.7) { // not too close
                // take the closest (first) one
                _m = nearest_neighbors[i][0];
            } else { // too close ¿ we cannot tell which is better
                continue; // did not pass ratio test ¿ throw away
            }
        } else {
            continue; // no neighbors... :(
        }
        // prevent duplicates
        if (found_in_right_points.find(_m.trainIdx) == found_in_right_points.
                end()) {
            // The found neighbor was not yet used:
            // We should match it with the original indexing
            // ofthe left point
            _m.queryIdx = right_points_to_find_back_index[_m.queryIdx];
            matches->push_back(_m); // add this match
            found_in_right_points.insert(_m.trainIdx);
        }
    }

    cout<<"pruned "<< matches->size() <<" / "<<nearest_neighbors.size()
        <<" matches"<<endl;
    return 0;
}

2 个答案:

答案 0 :(得分:1)

你永远不会向j_pts添加任何内容,所以当你到达

right_points_to_find.push_back(j_pts[i]);

任何指数超出范围。

答案 1 :(得分:0)

  1. 对于您的警告,只需将for循环中的整数类型更改为unsigned int,如下所示:

    for(unsigned int i=0; i<nearest_neighbors.size();i++)
    
  2. 对于您的错误,请忘记j_pts并将点直接添加到矢量点,如下所示:

    right_points_to_find.push_back(right_points[i]);
    
  3. 祝你好运!