Ask Your Question
0

Contour fn is not working well and not getting subpixel image by warpaffine fn

asked 2017-03-22 06:26:06 -0600

Ashiq KS gravatar image

updated 2017-03-22 06:28:30 -0600

berak gravatar image

There are no errors while compiling here in the image i need to draw a contour over only a rectangular subpixel image but contours are drawn all over the image and rectangle,moreover subpixel image is not cropped.pls help me with a soln

Mat src; Mat src_gray;
int thresh = 100;
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
  src = imread( argv[1], 1 );

  /// 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 );

  createTrackbar( " Threshold:", "Source", &thresh, max_thresh, thresh_callback );
  thresh_callback( 0, 0 );
// rect is the RotatedRect (I got it from a contour...)
        RotatedRect rect;
        // matrices we'll use
        Mat M, rotated, cropped;
        // get angle and size from the bounding box
        float angle = rect.angle;
        Size rect_size = rect.size;
        if (rect.angle < -45.) {
            angle += 90.0;
            swap(rect_size.width, rect_size.height);
        }
        // get the rotation matrix
        M = getRotationMatrix2D(rect.center, angle, 1.0);
        // perform the affine transformation
        warpAffine(src, rotated, M, src.size(), INTER_CUBIC);
        // crop the resulting image
        getRectSubPix(rotated, rect_size, rect.center, cropped);
  waitKey(0);
  return(0);
}

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

  /// Detect edges using Threshold
  threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY );
  /// Find contours
  findContours( threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );

  /// Approximate contours to polygons + get bounding rects and circles
  vector<vector<Point> > contours_poly( contours.size() );
  vector<Rect> boundRect( contours.size() );
  vector<Point2f>center( contours.size() );
  vector<float>radius( contours.size() );

  for( int i = 0; i < contours.size(); i++ )
     { approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
       boundRect[i] = boundingRect( Mat(contours_poly[i]) );
       minEnclosingCircle( (Mat)contours_poly[i], center[i], radius[i] );
     }


  /// Draw polygonal contour + bonding rects + circles
  Mat drawing = Mat::zeros( threshold_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_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
       rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 );
       circle( drawing, center[i], (int)radius[i], color, 2, 8, 0 );
     }

  /// Show in a window
  namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
  imshow( "Contours", drawing );
}
edit retag flag offensive close merge delete

Comments

could you add your image ?

berak gravatar imageberak ( 2017-03-22 06:45:45 -0600 )edit

i have only one karma point.The image is only a small rectangle shaped thing over white background,where the window is full of image

Ashiq KS gravatar imageAshiq KS ( 2017-03-22 07:28:34 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2017-03-22 07:36:01 -0600

berak gravatar image

updated 2017-03-22 12:00:30 -0600

"shaped thing over white background," - since opencv wants white contours on dark bg, you probably have to use THRESH_INVERT. also visualizing the binary image using imshow() might be helpful.

then, to see the outcome of your contours finding / warping, you'd need to run it in a loop, not only once:

 thresh_callback( 0, 0 );
// rect is the RotatedRect (I got it from a contour...)
while(true) {
        RotatedRect rect;
        // matrices we'll use
        Mat M, rotated, cropped;
        // get angle and size from the bounding box
        float angle = rect.angle;
        Size rect_size = rect.size;
        if (rect.angle < -45.) {
            angle += 90.0;
            swap(rect_size.width, rect_size.height);
        }
        // get the rotation matrix
        M = getRotationMatrix2D(rect.center, angle, 1.0);
        // perform the affine transformation
        warpAffine(src, rotated, M, src.size(), INTER_CUBIC);
        // crop the resulting image
        getRectSubPix(rotated, rect_size, rect.center, cropped);

        if (waitKey(10) > 0 ) break;
}
edit flag offensive delete link more

Comments

Ok . let me try this.i will let you know the result.What about cropping? Moreover i use single channel image,but there is a fn Mat drawing = Mat::zeros(threshold_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_poly, i, color, 1, 8, vector<vec4i>(), 0, Point()); rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0); //circle(drawing, center[i], (int)radius[i], color, 2, 8, 0); } will it cause a problem?

Ashiq KS gravatar imageAshiq KS ( 2017-03-22 10:31:58 -0600 )edit

I changed the THRESH_BINARY in threshold fn to THRESH_BINARY_INV, but it showing some command error.Here i put the code to find contour with the change and the command window error. OpenCV Error:Assertion failed < scn==3||scn==4> in cv::cvtColor, file C:\build\master_winpack-build-win64-vc14\opencv\modules\imgproc\src\color.cpp,line 9748

Ashiq KS gravatar imageAshiq KS ( 2017-03-22 11:38:01 -0600 )edit
  • " will it cause a problem?" - i don't think so, drawinig is independant from anything else
  • "scn==3||scn==4" -- most likely, your image was not read.

then, imho, the main problem is, that you would need a loop around the Rotated rect ---> waitKey() code, currently that part is only evaluated once, with invalid threshold params(0,0)

berak gravatar imageberak ( 2017-03-22 11:50:52 -0600 )edit

how to give loop around rotated rect

Ashiq KS gravatar imageAshiq KS ( 2017-03-22 11:55:52 -0600 )edit

^^ see update

berak gravatar imageberak ( 2017-03-22 12:01:09 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2017-03-22 06:26:06 -0600

Seen: 963 times

Last updated: Mar 22 '17