在opencv中使用一组点构建一个矩形

时间:2013-12-08 14:13:33

标签: opencv computer-vision

我正在尝试使用opencv构建一个带有这些点的矩形,但我不知道该怎么做呢?我想构建矩形以获得四个角点。

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

2 个答案:

答案 0 :(得分:3)

方法1

当您的图像包含不代表矩形边的轮廓时,此方法非常有用

  1. 首先,您需要找到每个轮廓的中心, 你可以继续查找OpenCV momentminEnclosingCircle之后的findcontour。现在你有一套 表示矩形的点。
  2. 下一步是将点分类为顶部,底部,左侧和右侧的矩形边。这是找到位于同一行的点,linkdiscussion可能会有所帮助。
  3. 排序后(对位于同一行的点进行分类),您可以通过扩展这些直线找到顶部,底部,右侧和左侧,并找到每条线的四个intersection,其中最小y值代表顶部,最小x代表左,最大x代表右和最大y支架的底部。
  4. 修改

    方法2

    您可以简单地找到如下所述的四个角落,而不是完成上述所有步骤。

    • 找到所有轮廓的中心点。
    • 找到最小x和最大x的点,它们代表两个角。
    • 找到最小y和最大y的点,这将代表另外两个角。
    • 现在,您可以通过查看这些值来决定左上角,右上角,左下角和右下角。

      - >从四个点集合考虑具有最小y值的两个点的集合。现在考虑这两个点,你的左上角是最小x值的点,右上角是最大x的点。

      - >类似地,从剩余的两个点(具有最大y值的点集)中找到具有最小x值的点,其将在左下角,具有最大x的点将在右下角。

    方法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();
    

    <强>结果: enter image description here

答案 1 :(得分:0)

这篇文章似乎是关于梯形的,而不是关于矩形的。

对于寻找有关矩形的解决方案的每个人: 我将所有点合并为一个轮廓:How to merge contours in opencv?。 然后围绕该轮廓创建一个矩形并绘制它:

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)