Jack welch
Jack welch

Reputation: 1707

Building a rectangle with a group of points in opencv

I am trying to build a rectangle using opencv with these points but I am not sure how to go about it? I would like to build the rectangle to be able to get the four corner points.

enter image description here enter image description here enter image description here

Upvotes: 2

Views: 5822

Answers (2)

user_cr
user_cr

Reputation: 120

This post seems to be about trapezoids, not about rectangles.

For everyone looking for a solution regarding rectangles: I merged all my points into one contour: How to merge contours in opencv?. Then create a rectangle around that contour & draw it :

rect = cv2.minAreaRect(merged_contour)
box = cv2.boxPoints(rect)
box = np.intp(box) #np.intp: Integer used for indexing (same as C ssize_t; normally either int32 or int64)
cv2.drawContours(image, [box], 0, (0,0,255), 1)

Upvotes: 0

Haris
Haris

Reputation: 14053

Method 1

This method will be useful when your image contains contour which not represent your rectangle sides

  1. Here first thing you need to do is find the centre of each contour, you may proceed with find OpenCV moment or minEnclosingCircle after findcontour. Now you have set of points representing your rectangle.
  2. Next step is classify the points to sides of rectangle like top, bottom, left and right. That is find the points which are lying on the same line these link and discussion might be helpful.
  3. After sorting(classify the points which lies on same line) you can easily find out top, bottom, right and left by extending these the lines and find four intersection of each line, where the minimum y-value stand for top, minimum x stand for left, maximum x stand for right and maximum y stand of bottom.

Edit:

Method 2

Instead of doing all above step you can simply find out four corners as described below.

  • Find centre points of all contour.
  • Find points with minimum x and maximum x which will represent two corner.
  • Find points with minimum y and maximum y which will represent the other two corner.
  • Now you can decide which point top left, top right, bottom left and bottom right by looking on these values.

    -> From set of four points consider set of two points with minimum y-value. Now consider these two points and your top left corner will be point with minimum x value and top right corner will be the point with maximum x.

    -> Similarly from the remaining two points(Set of points with maximum y values) find the point with minimum x value which will be bottom left and points with maximum x will be bottom right corner.

Code for method 2

Mat src=imread("src.png",0);
    vector< vector <Point> > contours; // Vector for storing contour
    vector< Vec4i > hierarchy;
    findContours( src, contours, hierarchy,CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE ); // Find the contours in the image

    vector<Point2f>center( contours.size() );
    vector<float>radius( contours.size() );
    for( int i = 0; i< contours.size(); i++ ){
        minEnclosingCircle(contours[i], center[i], radius[i] );
        circle(src,center[i],radius[i], Scalar(255),1,8,0);
    }

float top_left=0, top_right=0, bot_left=0,bot_right=0;
float idx_min_x=0,idx_min_y=0,idx_max_x=0,idx_max_y=0;

for( int i = 0; i< contours.size(); i++ ){

   if(center[idx_max_x].x<center[i].x) idx_max_x=i;
   if(center[idx_min_x].x>center[i].x) idx_min_x=i;

   if(center[idx_max_y].y<center[i].y) idx_max_y=i;
   if(center[idx_max_y].y>center[i].y) idx_min_y=i;
  }


vector<Point2f>corners;
corners.push_back (center[idx_max_x]);
corners.push_back (center[idx_min_x]);
corners.push_back (center[idx_max_y]);
corners.push_back (center[idx_min_y]);

Point tmp;

for( int i = 0; i< corners.size(); i++ ) {
 for( int j = 0; j< corners.size()-1; j++ ) {
  if(corners[j].y>corners[j+1].y){
  tmp=corners[j+1];
  corners[j+1]=corners[j];
  corners[j]=tmp;
  }
}
}

if(corners[0].x>corners[1].x){ top_left=1; top_right=0;}
else { top_left=0; top_right=1;}

if(corners[2].x>corners[3].x){ bot_left=3; bot_right=2;}
else { bot_left=2; bot_right=3;}

 line(src,corners[top_left],corners[top_right], Scalar(255),1,8,0);
 line(src,corners[bot_left],corners[bot_right], Scalar(255),1,8,0);

 line(src,corners[top_left],corners[bot_left], Scalar(255),1,8,0);
 line(src,corners[top_right],corners[bot_right], Scalar(255),1,8,0);
imshow("src",src);

waitKey();

Result: enter image description here

Upvotes: 3

Related Questions