Athena
Athena

Reputation: 543

findContours does not find the contours in opencv

I've been trying to load an image from camera but I face an error. I believe that findContours function has got a problem. Here is the code:

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace cv;
using namespace std;

Mat src; Mat src_gray;
int max_thresh = 255;
RNG rng(12345);

/// Function header
void thresh_callback(int, void* );

/** @function main */
int main( int argc, char** argv )
{
  /// Load source image and convert it to gray
  VideoCapture cap(1);
  cap>>src;

  /// Convert image to gray and blur it
  cvtColor( src, src_gray, CV_BGR2GRAY );
  blur( src_gray, src_gray, Size(3,3) );

  /// Create Window
  char* source_window = "Source";
  namedWindow( source_window, CV_WINDOW_AUTOSIZE );
  imshow( source_window, src );

  thresh_callback( 0, 0 );

  waitKey(0);
  return(0);
}

/** @function thresh_callback */
void thresh_callback(int, void* )
{
  Mat canny_output;
  vector<vector<Point> > contours;
  vector<Vec4i> hierarchy;

  /// Detect edges using canny
  Canny( src_gray, canny_output, 100, 100*2, 3 );
  /// Find contours
  findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );

  /// Draw contours
  Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
  for( int i = 0; i< contours.size(); i++ )
     {
       Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
       drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
     }

  /// Show in a window
  namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
  imshow( "Contours", drawing );
}

And here is the error:

I would appreciate any help.

Upvotes: 1

Views: 836

Answers (2)

Arya Sadeghi
Arya Sadeghi

Reputation: 500

I have had the same problem (or at least a similar one) with that function. I was not able to fix it, so I used the old C style cvFindContours function instead. I have included an example function in wich I used the cvFindContours function to clean up a blob image. This might not be the fastest solution, but at leas it works.

void filtBproject(Mat& Bproject){

    Scalar          color       = CV_RGB(255,255,255); // text color
    IplImage*       BprojectIpl =  &IplImage(Bproject);
    CvMemStorage*   storage     = cvCreateMemStorage(0);
    CvSeq*          contours    = 0;
    int             numCont     = 0;
    int             contAthresh = 45;

    numCont= cvFindContours( BprojectIpl, storage, &contours, sizeof(CvContour),
                    CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );

    cvSet(BprojectIpl, cvScalar(0,0,0));
    for( ; contours != 0; contours = contours->h_next )
        {

            if ( (cvContourArea(contours, CV_WHOLE_SEQ) > contAthresh) ){
                cvDrawContours( BprojectIpl, contours, color, color, -1, CV_FILLED, 8 );
            }
        }
}

Upvotes: 1

hariprasad
hariprasad

Reputation: 858

The exception could be thrown at Canny calling .Canny can only take single channel image as input but you did not seemed to be make an attempt to make src_gray as single channel after cvtColor calling(cvtColor always give dst type same as src type unless specified).This could be problem for findContours which will also only take single channelled 8 bit image

Upvotes: 0

Related Questions