RotateRect(旋轉矩形)的傾斜旋轉變換矯正


在Opencv中的圖像處理中,經常要用到minAreaRect()函數求最小外接矩形,該函數的返回值就是一個RotatedRect類對象。

 RotatedRect類定義如下:

class CV_EXPORTS RotatedRect
{
  public:
  //! various constructors
  RotatedRect();
  RotatedRect(const Point2f& center, const Size2f& size, float angle);
  RotatedRect(const CvBox2D& box);

  //! returns 4 vertices of the rectangle
  void points(Point2f pts[]) const;
  //! returns the minimal up-right rectangle containing the rotated rectangle
  Rect boundingRect() const;
  //! conversion to the old-style CvBox2D structure
  operator CvBox2D() const;

  Point2f center; //< the rectangle mass center
  Size2f size; //< width and height of the rectangle
  float angle; //< the rotation angle. When the angle is 0, 90, 180, 270 etc., the rectangle becomes an up-right rectangle.
};

 


類中定義了矩形的中心點center、尺寸size(包括width、height)、旋轉角度angle共3個成員變量;

points()函數用於求矩形的4個頂點,boundingRect()函數求包含最小外接矩形的,與坐標軸平行(或垂直)的最小矩形。

 

正確理解這些變量在圖形中的對應關系,是正確應用該類的基礎。先上示意圖:

 

根據上圖,說明以下幾點:

1.  Opencv采用通用的圖像坐標系,左上角為原點O(0,0),X軸向右遞增,Y軸向下遞增,單位為像素。

2. 矩形4個頂點位置的確定,是理解其它各變量的基礎,其中p[0]點是關鍵。

    頂點p[0]的位置可以這樣理解:

      ⓐ 如果沒有對邊與Y軸平行,則Y坐標最大的點為p[0]點,如矩形(2)(3)(4);

      ⓑ 如果有對邊與Y軸平等,則有兩個Y坐標最大的點,此時,取左側的點為p[0]點,如矩形(1)。

3. p[0]~p[3]按順時針次序依次排列。

4. p[0]到p[3]之間的距離寬width,其鄰邊為高height。

5. 角度angle以穿過p[0],且平行於X軸的直線為始邊,按逆時針方向旋轉到寬邊p[0]p[3]所經過的角度,

    取負值,取值范圍為(-90, 0]。

6. 中心點center為矩形對角線的交點。

 

#include<opencv2/opencv.hpp>

using namespace std;

void main(){
    string path = "";
    Mat img = imread(path);
    Mat img_gray;
    cvtColor(img,img_gray,COLOR_BGR2GRAY);
    Mat thresh_img(img.size(),CV_8UC1);
    threshold(img_gray, thresh_img,230,255,THRESH_BINARY_INV);

    imshow("thresh",thresh_img);
    waitKey();

    vector<vector<Point>> contours;
    findContours(thresh_img, contours,CV_RET_EXTERNAL,CV_CHAIN_APPROX_NONE);
    RotatedRect mr = minAreaRect(Mat(contours[0]));
    Mat Drawing(img.size(), img.type(), Scalar(255,255,255));
    Point2f vectpoint[4];
    mr.points(vectpoint);
    for (int i = 0; i < 4; i++){
        line(Drawing, vectpoint[(i+1)%4], Scalar(255,0,0),2);
    }
    imshow("drawing",Drawing);
    waitkey();

    float angle = 0.0;
    Size si = mr.size;
    if (mr.size.width <= mr.size.height){
        angle = mr.angle + 90;
        int tm = si.width;
        si.width = si.height;
        si.height = tm;
        //swap(si.width, si.height);
    } else {
        angle = mr.angle;
    }
    Mat rotmat = getRotationMatrix2D(mr.center, angle, 1);
    
    Mat deal_img;
    warpAffine(img, deal_img, rotmat, img.size(), CV_INTER_CUBIC);

    imshow("deal_img",deal_img);
    waitkey();
    gerRectSubpix(deal_img, si, mr.center, rRect);
    imshow("截取的的矩形區域",rRect);
    waitKey();
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM