Extract largest contour in very colorful image in OpenCV

asked 2016-07-20 23:38:09 -0500

astronaut gravatar image

I have an image of object with lots of different color and other small contours. I would like to find the largest contour in the image (airplane door). The image (door) can contain lots of painting and logos . So I just wont to find the exact door contour . I have some code in C++ and OpenCv . It works for normal door but when its very colorful it is not so good. I include the code and some image results. Here the part of the code. I played with the threshold but can not get better results. Also is it possible to extract that door contour automatically with image processing without playing with the threshold? Here my sample 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 thresh = 5;
 int max_thresh = 600;
 RNG rng(12345);

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

int main()
{
    src = imread("door3.jpg");
    resize(src, src, Size(640,480), 0, 0, INTER_CUBIC);
    // convert to grayscale (you could load as grayscale instead)
      cvtColor( src, src_gray, CV_BGR2GRAY );
      blur( src_gray, src_gray, Size(1,3) );

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

      createTrackbar( " Canny thresh:", "Source", &thresh, max_thresh, thresh_callback );
      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;
      vector<vector<Point> > largestContour;
      int largestArea = -1;
      int size=5;

      /// Detect edges using canny
      Canny( src_gray, canny_output, thresh, thresh*5.5, 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 );
      vector<vector<Point> > polyContours( contours.size() );

      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() );
          approxPolyDP( Mat(contours[i]), polyContours[i], 3, true );

         }
      for( int i = 0; i < contours.size(); i++ )
          {
              int area = fabs(contourArea(polyContours[i],false));
              if(area > largestArea && area > size)
              {
                  largestArea = area;
                  largestContour.push_back(polyContours[i]);              }
          }
         //Scalar color = Scalar( 255 );

          if(largestContour.size()>0)
          //drawContours( drawing, largestContour, 0, color, 1, 8, vector<Vec4i>(), 0, Point() );

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

Here the source and result images

source image

results

edit retag flag offensive close merge delete

Comments

Were you able to find an answer?

gurankas gravatar imagegurankas ( 2017-09-01 05:21:58 -0500 )edit