-1

When I run the following code, error occurs saying VECTOR SUBSCRIPT OUT OF RANGE. I get the error when calling boundingRect. Debugger says "Vector subscript out of Range" when I print the vector contours, it has zero size. I can't figure it out.

I am new to Visual C++ as well as OpenCV. It will be helpful if anyone can give me the reason and a remedy for this error.

#include "opencv2/opencv.hpp"
#include "opencv2\imgproc\imgproc.hpp"
#include "opencv2\core\core.hpp"
#include <iostream>
#include <Windows.h>

using namespace cv;
using namespace std;

/// Global variables
Mat src, src_hsv, src_bin, src_edge, src_drawing;
Mat srcclone, srcclone1;
Mat cropped, cropped_hsv, cropped_bin, cropped_edge, cropped_drawing;


///-HSV parameters -//
Scalar min_src_hsv = Scalar(49, 14, 154);
Scalar max_src_hsv = Scalar(107, 85, 255);

Scalar min_cropped_hsv = Scalar(61, 0, 235);
Scalar max_cropped_hsv = Scalar(255, 255, 255);

///Canny parameters
int lowThreshold = 45;
int ratio = 3;
int kernel_size = 3;

int lowThresholdCropped = 120;
int ratioCropped = 3;
int kernel_sizeCropped = 3;

///Contour detection
cv::vector<vector<Point> > contours;
cv::vector<Vec4i> hierarchy;
double largest_Perimeter = 0;
int largest_Perimeter_contIndex;

Rect boundingrect;

RNG rng(12345);

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProcessingFunction(int, void*)
{
    srcclone = src.clone();
    /// Convert the image to HSV
    cvtColor(src, src_hsv, CV_BGR2HSV);
    inRange(src_hsv, min_src_hsv, max_src_hsv, src_bin);

    //namedWindow("Binary Image", CV_WINDOW_AUTOSIZE);
    imshow("Binary Image", src_bin);

    /// Reduce noise of the input image with a kernel 3x3 many times as possible :D
    blur(src_bin, src_bin, Size(3, 3));

    /// Canny edge detection for the blurred src_bin image
    Canny(src_bin, src_edge, lowThreshold, lowThreshold*ratio, kernel_size);

    ///Morphological opening for the edges, apply this accordingly :D
    dilate(src_edge, src_edge, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
    erode(src_edge, src_edge, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));

    /// Find contours of the edge image
    findContours(src_edge, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

    ///Find contour with the max perimeter
    cout << "Contour Size : " << contours.size() << endl;
    for (int i = 0; i < contours.size(); i++)
    {
        double a = arcLength(contours[i], false);

        if (a > largest_Perimeter)
        {
            largest_Perimeter = a;
            largest_Perimeter_contIndex = i;
        }
    }
    cout << "Largest Contour Index : " << largest_Perimeter_contIndex << endl;
    cout << "largest perimeter :" << largest_Perimeter << endl;

    ///Draw largest perimeter
    src_drawing = Mat::zeros(src_edge.size(), CV_8UC3);
    Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
    drawContours(src_drawing, contours, largest_Perimeter_contIndex, color, 2, 8, hierarchy, 0, Point());
    Mat src_drawingclone = src_drawing.clone();

    ///Bounding Rectangle
    boundingrect = boundingRect(contours[largest_Perimeter_contIndex]);
    rectangle(src_drawing, boundingrect, Scalar(255, 255, 0), 2);
    cout << "x:" << boundingrect.x << "  y:" << boundingrect.y << endl;
    cout << "h:" << boundingrect.height << "  w:" << boundingrect.width;

    Sleep(3000);
}


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


int main()
{
    VideoCapture cap(0); // open the default camera
    if (!cap.isOpened())  // check if we succeeded
    {
        cout << "Cap not opened" << endl;
    }

    bool readSuccess = true;

    while (readSuccess)
    {
        readSuccess = false;

        while (!readSuccess)
        {
            readSuccess = cap.read(src); // get a new frame from camera
        }


        if (!src.data)
        {
            return -1;
        }

        if (readSuccess)
        {
            cout << "Image read" << endl;
            ProcessingFunction(0, 0);
        }

        if (waitKey(30) == 27) break;
    }
    // the camera will be deinitialized automatically in VideoCapture destructor
    return 0;
}
DDD3
  • 5
  • 6
  • Where do you get that error? Line one? What is the debugger telling you? – rene Dec 14 '14 at 13:51
  • 1
    I get the error when calling boundingRect. Debugger says "Vector subscript out of Range" when I print the vector contours, it has zero size. I can't figure it out. – DDD3 Dec 14 '14 at 14:02
  • 1
    How about editing that info into your question? – rene Dec 14 '14 at 14:10

1 Answers1

1

you don't catch the case, where it did not find any contours.

so:

//
// please, get rid of the global variables !!
// this has to go *inside* void ProcessingFunction(int, void*)
// you need to re-initialize it for every call !
//

int largest_Perimeter_contIndex = -1; // something invalid

...

if ( largest_Perimeter_contIndex > -1 )
{
    ///Draw largest perimeter
    src_drawing = Mat::zeros(src_edge.size(), CV_8UC3);
    Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
    drawContours(src_drawing, contours, largest_Perimeter_contIndex, color, 2, 8, hierarchy, 0, Point());
    Mat src_drawingclone = src_drawing.clone();

    ///Bounding Rectangle
    boundingrect = boundingRect(contours[largest_Perimeter_contIndex]);
    rectangle(src_drawing, boundingrect, Scalar(255, 255, 0), 2);
    cout << "x:" << boundingrect.x << "  y:" << boundingrect.y << endl;
    cout << "h:" << boundingrect.height << "  w:" << boundingrect.width;
}
berak
  • 39,159
  • 9
  • 91
  • 89