Ask Your Question

Revision history [back]

C++ OPENCV std::out_of_range error

Hello everyone,

I've a project with OPENCV/C++ which is about rectangle detection and Wrap Transformation. So far, I had good results. But I have some problems efficiency.

Firs of all I found contours with FindContours. And then I've found the corner points with approxPolyDP. And I've sorted the each corner by Amplitude and Angle. I determine the minimum and maximum amplitudes and minimum and maximum angles. so I've found the 4 corners of the image. and then I used the WrapTransformation. So I had a proper rectangle like this:

Here is the Original Image and thresholded in colors and Wrapped that I took from webcam: colors and Wrapped that I took from webcam: OPENCV

But when I put my hand to front of pattern I get "std::out_of_range" error.

terminate called after throwing an instance of 'std::out_of_range' what(): vector::_M_range_check: __n (which is 3) >= this->size() (which is 3)

Well, what could be the problem? Is it something related with adding data to vectors?

Here is the full code for this process:

Mat gray, tresh, blur;

medianBlur(input, blur, 5); cvtColor(blur, gray, COLOR_BGR2GRAY); threshold(gray, tresh, min, max, THRESH_BINARY);

vector<vector<point> > contours;

vector<vector<point> > approxPol; vector<vec4i> hierarchy;

findContours(tresh, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);

int size = contours.size();

vector<vector<vector<double> > > corns(size, vector<vector<double> >(4, vector<double>(4))); corns.resize(size, vector<vector<double> >(4, vector<double>(4))); Mat out; double amplitude, angle;

if(size == 16){

for (int k = 0; k < size; k++) {

    approxPolyDP(contours[k], contours[k], 10, true);



        for (int i = 0; i < 4; i++) {

            amplitude = sqrt(pow(contours[k].at(i).x, 2) + pow(contours[k].at(i).y, 2));
            angle = atan2(contours[k].at(i).y, contours[k].at(i).x) * 180 / CV_PI;

            string coord_x = intToString(contours[k].at(i).x);
            string coord_y = intToString(contours[k].at(i).y);

            corns[k][i][0] = contours[k].at(i).x;
            corns[k][i][1] = contours[k].at(i).y;
            corns[k][i][2] = amplitude;
            corns[k][i][3] = angle;


        }

}
contours.clear();

imshow("circles", input);
int count = corns.size();

if (count == 16) {

    vector<vector<double> > dots;
    dots.resize(64, vector<double>(4));


        int index = 0;
        for (int i = 0; i < count; i++) {
            for (int k = 0; k < 4; k++) {
                for (int t = 0; t < 4; t++) {

                    dots[index][t] = corns[i][k][t];

                }

                index++;
            }

        }


        Point2f p[4];

        std::sort(dots.begin(), dots.end(), &Amplitude);
        int last = dots.size() - 1, first = 0;;

        // min amp
        p[0].x = dots[first][0];
        p[0].y = dots[first][1];

        // max amp
        p[3].x = dots[last][0];
        p[3].y = dots[last][1];

        std::sort(dots.begin(), dots.end(), &Angles);

        // min angle
        p[1].x = dots[first][0];
        p[1].y = dots[first][1];

        // max angle

        p[2].x = dots[last][0];
        p[2].y = dots[last][1];

        dots.clear();
        Mat getted = input.clone();
        float sizes = 500;
        Mat  transform_matrix;
        Point2f d[4] = { { 0,0 },{ sizes,0 },{ 0,sizes },{ sizes,sizes } };
        transform_matrix = getPerspectiveTransform(p, d);
        cv::warpPerspective(getted, out, transform_matrix, Size(sizes, sizes));
        cv::imshow("Wrapped", out);


        cout << size << endl << count << endl;
    }
    else {
        contours.clear();
        corns.clear();
        out.release();
    }


}else {
    contours.clear();
    out.release();
}

C++ OPENCV std::out_of_range error

Hello everyone,

I've a project with OPENCV/C++ which is about rectangle detection and Wrap Transformation. So far, I had good results. But I have some problems efficiency.

Firs of all I found contours with FindContours. And then I've found the corner points with approxPolyDP. And I've sorted the each corner by Amplitude and Angle. I determine the minimum and maximum amplitudes and minimum and maximum angles. so I've found the 4 corners of the image. and then I used the WrapTransformation. So I had a proper rectangle like this:

Here is the Original Image and thresholded in colors and Wrapped that I took from webcam: colors and Wrapped that I took from webcam: OPENCV

But when I put my hand to front of pattern I get "std::out_of_range" error.

terminate called after throwing an instance of 'std::out_of_range' what(): vector::_M_range_check: __n (which is 3) >= this->size() (which is 3)

Well, what could be the problem? Is it something related with adding data to vectors?

Here is the full code for this process:

Mat gray, tresh, blur;

blur; medianBlur(input, blur, 5); cvtColor(blur, gray, COLOR_BGR2GRAY); threshold(gray, tresh, min, max, THRESH_BINARY);

vector<vector<point> THRESH_BINARY); vector<vector<Point> > contours;

vector<vector<point> contours; vector<vector<Point> > approxPol; vector<vec4i> hierarchy;

vector<Vec4i> hierarchy; findContours(tresh, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);

CV_CHAIN_APPROX_SIMPLE); int size = contours.size();

contours.size(); vector<vector<vector<double> > > corns(size, vector<vector<double> >(4, vector<double>(4))); corns.resize(size, vector<vector<double> >(4, vector<double>(4))); Mat out; double amplitude, angle;

angle; if(size == 16){

16){
for (int k = 0; k < size; k++) {
approxPolyDP(contours[k], contours[k], 10, true);
for (int i = 0; i < 4; i++) {
amplitude = sqrt(pow(contours[k].at(i).x, 2) + pow(contours[k].at(i).y, 2));
angle = atan2(contours[k].at(i).y, contours[k].at(i).x) * 180 / CV_PI;
string coord_x = intToString(contours[k].at(i).x);
string coord_y = intToString(contours[k].at(i).y);
corns[k][i][0] = contours[k].at(i).x;
corns[k][i][1] = contours[k].at(i).y;
corns[k][i][2] = amplitude;
corns[k][i][3] = angle;
}
}
contours.clear();
imshow("circles", input);
int count = corns.size();
if (count == 16) {
vector<vector<double> > dots;
dots.resize(64, vector<double>(4));
int index = 0;
for (int i = 0; i < count; i++) {
for (int k = 0; k < 4; k++) {
for (int t = 0; t < 4; t++) {
dots[index][t] = corns[i][k][t];
}
index++;
}
}
Point2f p[4];
std::sort(dots.begin(), dots.end(), &Amplitude);
int last = dots.size() - 1, first = 0;;
// min amp
p[0].x = dots[first][0];
p[0].y = dots[first][1];
// max amp
p[3].x = dots[last][0];
p[3].y = dots[last][1];
std::sort(dots.begin(), dots.end(), &Angles);
// min angle
p[1].x = dots[first][0];
p[1].y = dots[first][1];
// max angle
p[2].x = dots[last][0];
p[2].y = dots[last][1];
dots.clear();
Mat getted = input.clone();
float sizes = 500;
Mat transform_matrix;
Point2f d[4] = { { 0,0 },{ sizes,0 },{ 0,sizes },{ sizes,sizes } };
transform_matrix = getPerspectiveTransform(p, d);
cv::warpPerspective(getted, out, transform_matrix, Size(sizes, sizes));
cv::imshow("Wrapped", out);
cout << size << endl << count << endl;
}
else {
contours.clear();
corns.clear();
out.release();
}
}else {
contours.clear();
out.release();
}