# 【OpenCV教程】如何优雅地画出一个几何图形

@[TOC](https://github.com/UnderTurrets/notes/blob/master/Computer_Vision/OpenCV/%E6%96%87%E7%AB%A0%E7%9B%AE%E5%BD%95/README.md)

***

## 1.直线

### 1.1 API

```cpp
CV_EXPORTS_W void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,int thickness = 1, int lineType = LINE_8, int shift = 0);
```

* 参数如下

| 参数          | 含义                      |
| ----------- | ----------------------- |
| img(image)  | 绘制多边形的画布，数据类型Mat        |
| pt1(point1) | 端点1                     |
| pt2(point2) | 端点2                     |
| color       | 绘制线条的颜色                 |
| thickness   | 绘制线条的粗细                 |
| lineType    | 绘制线条的连通类型               |
| shift       | 坐标点小数点位数(not important) |

### 1.2 连通类型

```cpp
enum LineTypes {
    FILLED  = -1,
    LINE_4  = 4, //!< 4-connected line
    LINE_8  = 8, //!< 8-connected line
    LINE_AA = 16 //!< antialiased line
};
```

* LINE\_4与LINE\_8差别不大，而LINE\_AA的抗锯齿效果显著

## 2.正矩形

### 2.1API

```cpp
CV_EXPORTS_W void rectangle(InputOutputArray img, Point pt1, Point pt2,
                          const Scalar& color, int thickness = 1,
                          int lineType = LINE_8, int shift = 0);
```

* 参数如下

| 参数          | 含义                       |
| ----------- | ------------------------ |
| img(image)  | 绘制多边形的画布，数据类型Mat         |
| pt1(point1) | 左上角端点                    |
| pt2(point2) | 右下角端点                    |
| color       | 绘制线条的颜色                  |
| thickness   | 绘制线条的粗细。**若取负值，则表示进行填充** |
| lineType    | 绘制线条的连通类型                |
| shift       | 坐标点小数点位数(not important)  |

```cpp
CV_EXPORTS_W void rectangle(InputOutputArray img, Rect rec,
                          const Scalar& color, int thickness = 1,
                          int lineType = LINE_8, int shift = 0);
```

* 参数如下

| 参数         | 含义                       |
| ---------- | ------------------------ |
| img(image) | 绘制多边形的画布，数据类型Mat         |
| rec(rect)  | 一个矩形                     |
| color      | 绘制线条的颜色                  |
| thickness  | 绘制线条的粗细。**若取负值，则表示进行填充** |
| lineType   | 绘制线条的连通类型                |
| shift      | 坐标点小数点位数(not important)  |

## 3.圆形

### 3.1 API

```cpp
CV_EXPORTS_W void circle(InputOutputArray img, Point center, int radius,
                       const Scalar& color, int thickness = 1,
                       int lineType = LINE_8, int shift = 0);
```

* 参数如下

| 参数         | 含义                       |
| ---------- | ------------------------ |
| img(image) | 绘制多边形的画布，数据类型Mat         |
| center     | 圆心坐标                     |
| radius     | 半径                       |
| color      | 绘制线条的颜色                  |
| thickness  | 绘制线条的粗细。**若取负值，则表示进行填充** |
| lineType   | 绘制线条的连通类型                |
| shift      | 坐标点小数点位数(not important)  |

## 4.椭圆

### 4.1 API

```cpp
CV_EXPORTS_W void ellipse(InputOutputArray img, Point center, Size axes,
                        double angle, double startAngle, double endAngle,
                        const Scalar& color, int thickness = 1,
                        int lineType = LINE_8, int shift = 0);
```

* 参数如下

| 参数         | 含义                                |
| ---------- | --------------------------------- |
| img(image) | 绘制多边形的画布，数据类型Mat                  |
| center     | 圆心坐标                              |
| axes       | （x方向上半轴长，y方向上半轴长）                 |
| angle      | **顺时针偏角**                         |
| startAngle | 以x方向上的正半轴为起点，偏移一定角度后的起点，从此起点开始画椭圆 |
| endAngle   | 以x方向上的正半轴为起点，偏移一定角度后的终点，到此为止结束画椭圆 |
| color      | 绘制线条的颜色                           |
| thickness  | 绘制线条的粗细。**若取负值，则表示进行填充**          |
| lineType   | 绘制线条的连通类型                         |
| shift      | 坐标点小数点位数(not important)           |

### 4.2 效果

```cpp
Mat canvas(Size(1000,1000),CV_8U,Scalar(255));
ellipse(canvas,Point2f(500,500),Size(50,100),0,0,90,Scalar(0,0,0),5);
imshow("canvas",canvas);
waitKey();
```

![](https://cdn.jsdelivr.net/gh/UnderTurrets/ImageHosting/Computer_Vision/OpenCV/assets%E3%80%90OpenCV%E6%95%99%E7%A8%8B%E3%80%91%E5%A6%82%E4%BD%95%E4%BC%98%E9%9B%85%E5%9C%B0%E7%94%BB%E5%87%BA%E4%B8%80%E4%B8%AA%E5%87%A0%E4%BD%95%E5%9B%BE%E5%BD%A2/asd841298dhas.png)

```
Mat canvas(Size(1000,1000),CV_8U,Scalar(255));
ellipse(canvas,Point2f(500,500),Size(50,100),20,0,360,Scalar(0,0,0),5);
imshow("canvas",canvas);
waitKey();
```

![](https://cdn.jsdelivr.net/gh/UnderTurrets/ImageHosting/Computer_Vision/OpenCV/assets%E3%80%90OpenCV%E6%95%99%E7%A8%8B%E3%80%91%E5%A6%82%E4%BD%95%E4%BC%98%E9%9B%85%E5%9C%B0%E7%94%BB%E5%87%BA%E4%B8%80%E4%B8%AA%E5%87%A0%E4%BD%95%E5%9B%BE%E5%BD%A2/48asd44c84as.png)

```
Mat canvas(Size(1000,1000),CV_8U,Scalar(255));
ellipse(canvas,Point2f(500,500),Size(50,100),20,0,180,Scalar(0,0,0),5);
imshow("canvas",canvas);
waitKey();
```

![](https://cdn.jsdelivr.net/gh/UnderTurrets/ImageHosting/Computer_Vision/OpenCV/assets%E3%80%90OpenCV%E6%95%99%E7%A8%8B%E3%80%91%E5%A6%82%E4%BD%95%E4%BC%98%E9%9B%85%E5%9C%B0%E7%94%BB%E5%87%BA%E4%B8%80%E4%B8%AA%E5%87%A0%E4%BD%95%E5%9B%BE%E5%BD%A2/aksdj8782qwqd.png)

## 5 斜矩形

### 5.1 API(通过RotatedRect类和line函数实现)

```cpp
class CV_EXPORTS RotatedRect
{
public:
    //! default constructor
    RotatedRect();
   
    /*center：质心坐标
      size：（x方向上全边长，y方向上全边长）
      angle：顺时针偏角
    */
    RotatedRect(const Point2f& center, const Size2f& size, float angle);

    /**
    三点确定一矩形，记得要互相垂直
     */
    RotatedRect(const Point2f& point1, const Point2f& point2, const Point2f& point3);

    /** 返回四个角点坐标，要用Point2f类型的数组对象作为参数传入，不能是仅仅是Point类型的数组对象*/
    void points(Point2f pts[]) const;

    //! returns the minimal up-right integer rectangle containing the rotated rectangle
    Rect boundingRect() const;

    //! returns the minimal (exact) floating point rectangle containing the rotated rectangle, not intended for use with images
    Rect_<float> boundingRect2f() const;

    //! returns the rectangle mass center
    Point2f center;

    //! returns width and height of the rectangle
    Size2f size;

    //! returns the rotation angle. When the angle is 0, 90, 180, 270 etc., the rectangle becomes an up-right rectangle.
    float angle;
};
```

下面是自定义的一个快捷画斜矩形的函数

```cpp
void drawRotatedRect(InputOutputArray img, RotatedRect rRect,const Scalar& color, int thickness = 1,int lineType = LINE_8, int shift = 0){
    Point2f vertices[4];
    rRect.points(vertices);
    for(int i=0;i<4;i++){
        line(img,vertices[i],vertices[(i+1)%4],color,lineType,shift);
    }
}
```

## 6.多边形

### 6.1 API

#### 绘制方式一

```cpp
CV_EXPORTS_W void polylines(InputOutputArray img, InputArrayOfArrays pts,
                            bool isClosed, const Scalar& color,
                            int thickness = 1, int lineType = LINE_8, int shift = 0 );
```

* 参数如下

| 参数          | 含义                                                                                                      |
| ----------- | ------------------------------------------------------------------------------------------------------- |
| img(image)  | 绘制多边形的画布，数据类型Mat                                                                                        |
| pts(points) | 多边形角点的坐标点集，数据类型`vector<Point>或vector<vector<Point>>`，**若为`vector<Point2f>或vector<vector<Point2f>>`会报错** |
| isClosed    | 多边形是否闭合，如果isClosed为真，那么pts的最后一个点将和第一个点连起来，否则轮廓被认为是不封闭的。                                                 |
| color       | 绘制线条的颜色                                                                                                 |
| thickness   | 绘制线条的粗细。**若取负值，则表示进行填充**                                                                                |
| lineType    | 绘制线条的连通类型                                                                                               |
| shift       | 坐标点小数点位数(not important)                                                                                 |

#### 绘制方式二

```cpp
CV_EXPORTS void polylines(InputOutputArray img, const Point* const* pts, const int* npts,
                          int ncontours, bool isClosed, const Scalar& color,
                          int thickness = 1, int lineType = LINE_8, int shift = 0 );
```

* 参数如下

| 参数                  | 含义                                                                                                     |
| ------------------- | ------------------------------------------------------------------------------------------------------ |
| img(image)          | 绘制多边形的画布，数据类型Mat                                                                                       |
| pts(points)         | **多个多边形的角点坐标点集的地址的数组**。如果有3个四边形的角点坐标点集Point\[3]\[4]，那么pts={Point\[0]\[0],Point\[1]\[0],Point\[2]\[0],} |
| npts(number points) | **多个多边形的角点坐标点集的元素个数排列成的数组，用来指示需要用到pts\[i]中的几个元素**。如果有3个四边形的角点坐标点集Point\[3]\[4]，那么npts={4，4，4，}         |
| ncontours           | 多边形的数量                                                                                                 |
| isClosed            | 多边形是否闭合，如果isClosed为真，那么pts的最后一个点将和第一个点连起来，否则轮廓被认为是不封闭的。                                                |
| color               | 绘制线条的颜色                                                                                                |
| thickness           | 绘制线条的粗细。**若取负值，则表示进行填充**                                                                               |
| lineType            | 绘制线条的连通类型                                                                                              |
| shift               | 坐标点小数点位数(not important)                                                                                |
