Ask Your Question
0

Vector Subscript Out of Range - what does it mean and how to solve it?

asked 2015-09-17 04:36:46 -0600

zms gravatar image

updated 2015-09-17 04:48:57 -0600

Hello, I had been using the code for single image and it had working fine. But today I want to have it to run using video. Error now vector subscript out of range. What is that mean?

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#define PI 3.14159265
#include <iostream>
#include <windows.h>
#include <fstream>
#include <time.h>

using namespace cv;
using namespace std;

int edgeThresh = 1;
int lowThreshold,minthreshold;
int const max_lowThreshold = 100;
int const max_houghlowThreshold = 100;
int ratio = 3;
int kernel_size = 3;
Mat frame, frame_gray, dst, cdst,imHSV, frame_rgb, draw;
Mat hsv_channels[3];
int flag_off=0;
ofstream outputfile;
double pixelwhitevalue [5];
char filename[80];
RNG rng(12345);
double TOTALM00;
double TOTALLength;   

    int main(int argc, char** argv)
    {
    VideoCapture cap("C:\\db\\Day3Full\\13pm.wmv"); 
    Mat mask =imread("c:\\db\\maskcrop.jpg",1);

    while(1)
    {

       bool bSuccess = cap.read(frame); // read a new frame from video

        if (!bSuccess) //if not success, break loop
        {
                        cout << "Cannot read the frame from video file" << endl;
                        break;
        }

      imshow("MyVideo", frame); 
      draw = frame.clone();

      Rect rectangle (0,200,frame.cols,frame.rows/2);
      frame = frame(rectangle);
      bitwise_and(frame,mask,frame);    
      imshow("aftermask",frame);

      cvtColor(frame, frame_gray, CV_BGR2GRAY);
      threshold(frame_gray, frame_gray, 190, 255, THRESH_BINARY);

      erode(frame_gray, frame_gray, Mat());
      dilate(frame_gray, frame_gray, Mat());    

      imshow("clean binary", frame_gray);   

      vector< vector<Point> > contours;
      findContours(frame_gray, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);

     vector<Moments> mu(contours.size() );
     for( int i = 0; i < contours.size(); i++ )
     { 
         mu[i] = moments( contours[i], false ); 
        TOTALM00 = TOTALM00 + mu[i].m00;
     }

    Moments mom = cv::moments(contours[0]); 
    double hu[7];
    HuMoments(mom, hu); 

    vector<Point2f> mc( contours.size() );

    for( int i = 0; i < contours.size(); i++ )
    {
         mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); 
         std::cout << "x1 " << mc[i] << std::endl; 
    }

   Point2f a = mc[0];
   Point2f b = mc[1];
   double res = cv::norm(a-b);
   std::cout << "Res" <<res << std::endl;

   drawContours(frame, contours, -1, Scalar(0,0,255), 2);

   printf("\t Info: Area and Contour Length \n");
   for( int i = 0; i< contours.size(); i++ )
   {
       printf(" * Contour[%d] - Area (M_00) = %.2f - Area OpenCV: %.2f - Length: %.2f - Hu:%.2f\n", i, mu[i].m00, contourArea(contours[i]), arcLength( contours[i], false ),hu[5]);
       TOTALLength = TOTALLength + arcLength( contours[i], false );
   }

  switch(waitKey(1)){

    case 27:
        return 0;

   }
  }
  }

image description

edit retag flag offensive close merge delete

Comments

Where does the error arise?

LorenaGdL gravatar imageLorenaGdL ( 2015-09-17 04:44:35 -0600 )edit

sorry I forgot to put the error message

zms gravatar imagezms ( 2015-09-17 04:49:30 -0600 )edit
3

That is not really helpful. The error indicates you're trying to access a vector element that doesn't exist. You should carefully debug your program and see what line is throwing the error. I'd dare to say that it's caused by Moments mom = cv::moments(contours[0]); in some frame where no contours are found, but it's just a risky guess...

LorenaGdL gravatar imageLorenaGdL ( 2015-09-17 04:58:35 -0600 )edit

Hello, I had debug the code one by one and found out the culprit is from this statement. Some of the images I have thresholded would have more than 3 centroids. THis statement below is to calculate the eucladian distance from 2 centroids. Now would it cause a problems if there are more points of centroid detected?

   Point2f a = mc[0];
   Point2f b = mc[1];
   double res = cv::norm(a-b);
   std::cout << "Res" <<res << std::endl;
zms gravatar imagezms ( 2015-09-18 03:02:09 -0600 )edit
1

U r CORRECT!! :) I just realized some of my images do not return any centroid.. Thanks so much everyone!!

zms gravatar imagezms ( 2015-09-18 03:59:39 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2015-09-18 03:40:38 -0600

updated 2015-09-18 04:10:02 -0600

SOLUTION grabbed from comments:

To avoid the error the @LorenaGdL is talking about, you could add

if(!contours.empty()){
   Moments mom = cv::moments(contours[0]);
}

And then you will be safe nevertheless.

No the problem is probably here that if there are NO 2 centroids, then the norm function will indeed give you problems. Add the following check before these lines of code.

if(mc.size() < 2){
   cerr << "not enough points to match." << endl;
   return -1;
}

This line will check if their is enough data for the norm function.

edit flag offensive delete link more

Comments

@zms could you accept the solution?

StevenPuttemans gravatar imageStevenPuttemans ( 2015-09-18 04:10:26 -0600 )edit
1

DONE! :) here it is

zms gravatar imagezms ( 2015-09-18 04:50:05 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2015-09-17 04:36:46 -0600

Seen: 2,980 times

Last updated: Sep 18 '15