上期我们一起学习来了图像处理中64个常用的算子,
机器视觉算法(第10期)----图像处理中64个常用的算子从今天我们仍将以OpenCV为工具,来学习下算法中常用的绘图和注释有哪些?

1. 绘图

我们常常会想要画一幅图像或者在某些图片上画一些东西,为了实现这个目标,OpenCV提供了一大批可以供我们画直线,矩形,圆等图形的函数。一般情况下,绘图函数可以在任意深度的图像上工作,但是通常情况下只对前前三个通道有作用,大多数绘图函数都支持操作对象的颜色,宽度,线型和亚像素对齐等参数。

1.1. cv::circle()

在图像img上画一个圆。

void circle(
    cv::Mat& img, // Image to be drawn on
    cv::Point center, // Location of circle center
    int radius, // Radius of circle
    const cv::Scalar& color, // Color, RGB form
    int thickness = 1, // Thickness of line
    int lineType = 8, // Connectedness, 4 or 8
    int shift = 0 // Bits of radius to treat as fraction
);
1.2. cv::clipLine()

该函数用来判断点pt1和点pt2连接的直线是否在一个矩形范围内。下面第一种函数的形式,是使用了一个Rect,只有当直线完全在指定的矩形范围外的时候,该函数才会返回false;第二种形式是用了一个Size,该Size表示的矩形范围是从(0,0)开始的,如下:

bool clipLine( // True if any part of line in 'imgRect'
    cv::Rect imgRect, // Rectangle to clip to
    cv::Point& pt1, // First endpoint of line, overwritten
    cv::Point& pt2 // Second endpoint of line, overwritten
);

bool clipLine( // True if any part of line in image size
    cv::Size imgSize, // Size of image, implies rectangle at 0,0
    cv::Point& pt1, // First endpoint of line, overwritten
    cv::Point& pt2 // Second endpoint of line, overwritten
);
1.3. cv::ellipse()

该函数和circle()函数非常类似,主要区别在于axes参数,这是一个Size类型,其中height和width参数分别表示椭圆长轴和短轴的长度,angle是主轴的角度(单位是度)。计算方法是从水平方向(x轴正方向)开始逆时针旋转。类似的startAngle和endAngle参数分别表示圆弧的起始和终止角度,如果要得到一个完整的椭圆,这两个参数要分别设置为0和360.
另外一种画法就是制定一个边界框,用RotatedRect类型表示的边界框就同时指定了椭圆的大小和朝向。

bool ellipse(
    cv::Mat& img, // Image to be drawn on
    cv::Point center, // Location of ellipse center
    cv::Size axes, // Length of major and minor axes
    double angle, // Tilt angle of major axis
    double startAngle, // Start angle for arc drawing
    double endAngle, // End angle for arc drawing
    const cv::Scalar& color, // Color, BGR form
    int thickness = 1, // Thickness of line
    int lineType = 8, // Connectedness, 4 or 8
    int shift = 0 // Bits of radius to treat as fraction
);

bool ellipse(
    cv::Mat& img, // Image to be drawn on
    const cv::RotatedRect& rect, // Rotated rectangle bounds ellipse
    const cv::Scalar& color, // Color, BGR form
    int thickness = 1, // Thickness of line
    int lineType = 8, // Connectedness, 4 or 8
    int shift = 0 // Bits of radius to treat as fraction
);
1.4. cv::ellipse2Poly()

给定一个椭圆参数,跟ellipse()函数类似,和用来指定下一个采样点的角度delta参数后,该函数就会计算出一系列点,可以用这些点作为顶点的多边形来近似指定的椭圆弧,计算的点通过参数pts返回。

void ellipse2Poly(
    cv::Point center, // Location of ellipse center
    cv::Size axes, // Length of major and minor axes
    double angle, // Tilt angle of major axis
    double startAngle, // Start angle for arc drawing
    double endAngle, // End angle for arc drawing
    int delta, // Angle between sequential vertices
    vector<cv::Point>& pts // Result, STL-vector of points
);
1.5. cv::fillConvexPoly()

该函数用来绘制一个填充的多边形,该函数比fillPoly()速度快的多。但是对于有自交点的多边形不能正常工作,pts中的点将被按顺序用直线段连接起来,第一个点和最后一个点之间也会连接起来。

void fillConvexPoly(
    cv::Mat& img, // Image to be drawn on
    const cv::Point* pts, // C-style array of points
    int npts, // Number of points in 'pts'
    const cv::Scalar& color, // Color, BGR form
    int lineType = 8, // Connectedness, 4 or 8
    int shift = 0 // Bits of radius to treat as fraction
);
1.6. cv::fillPoly()

这个函数可以绘制任意数量的填充的多边形,和fillConvexPoly()不同的是这个函数可以处理自交点的情况。

void fillPoly(
    cv::Mat& img, // Image to be drawn on
    const cv::Point* pts, // C-style array of arrays of points
    int npts, // Number of points in 'pts[i]'
    int ncontours, // Number of arrays in 'pts'
    const cv::Scalar& color, // Color, BGR form
    int lineType = 8, // Connectedness, 4 or 8
    int shift = 0, // Bits of radius to treat as fraction
    cv::Point offset = Point() // Uniform offset applied to all points
);
1.7. cv::line()

该函数在图像img上绘制一条从pt1到pt2的直线,直线自动被图像边缘截断。

void line(
    cv::Mat& img, // Image to be drawn on
    cv::Point pt1, // First endpoint of line
    cv::Point pt2 // Second endpoint of line
    const cv::Scalar& color, // Color, BGR form
    int lineType = 8, // Connectedness, 4 or 8
    int shift = 0 // Bits of radius to treat as fraction
);
1.8. cv::rectangle()

在图像img上绘制一个由pt1和pt2或者r确定的矩形。

void rectangle(
    cv::Mat& img, // Image to be drawn on
    cv::Point pt1, // First corner of rectangle
    cv::Point pt2 // Opposite corner of rectangle
    const cv::Scalar& color, // Color, BGR form
    int lineType = 8, // Connectedness, 4 or 8
    int shift = 0 // Bits of radius to treat as fraction
);

void rectangle(
    cv::Mat& img, // Image to be drawn on
    cv::Rect r, // Rectangle to draw
    const cv::Scalar& color, // Color, BGR form
    int lineType = 8, // Connectedness, 4 or 8
    int shift = 0 // Bits of radius to treat as fraction
);
1.9. cv::polyLines()

该函数可以绘制任意数量的未填充的多边形,可以处理包括有自交点的多边形在内的普通多边形。

void polyLines(
    cv::Mat& img, // Image to be drawn on
    const cv::Point* pts, // C-style array of arrays of points
    int npts, // Number of points in 'pts[i]'
    int ncontours, // Number of arrays in 'pts'
    bool isClosed, // If true, connect last and first pts
    const cv::Scalar& color, // Color, BGR form
    int lineType = 8, // Connectedness, 4 or 8
    int shift = 0 // Bits of radius to treat as fraction
);
1.10. cv::LineIterator

cv::LineIterator对象是一个用来顺序得到网格线每一个像素的迭代器,可以更灵活的处理直线上的像素值。

LineIterator::LineIterator(
    cv::Mat& img, // Image to be drawn on
    cv::Point pt1, // First endpoint of line
    cv::Point pt2 // Second endpoint of line
    int lineType = 8, // Connectedness, 4 or 8
    bool leftToRight = false // If true, always start steps on the left
);
2. 注释

绘图的另外一种形式就是画文字,OpenCV提供了两种文字的绘制函数,如下:

2.1 cv::putText()

这是OpenCV中主要文字绘制方法,它可以简单的在图像上绘制一些文字。

void cv::putText(
    cv::Mat& img, // Image to be drawn on
    const string& text, // write this (often from cv::format)
    cv::Point origin, // Upper-left corner of text box
    int fontFace, // Font (e.g., cv::FONT_HERSHEY_PLAIN)
    double fontScale, // size (a multiplier, not "points"!)
    cv::Scalar color, // Color, RGB form
    int thickness = 1, // Thickness of line
    int lineType = 8, // Connectedness, 4 or 8
    bool bottomLeftOrigin = false // true='origin at lower left'
);
2.2. cv::getTextSize()

该函数回答了如果把文字绘制出来将有多大的问题,而不是实际的将文字绘制出来。它的结果以baseLine的参数传递出来,该参数是和文字最低点相关的文字基线的y坐标值。

cv::Size cv::getTextSize(
    const string& text,
    cv::Point origin,
    int fontFace,
    double fontScale,
    int thickness,
    int* baseLine
);

至此,我们一起学习了OpenCV中都有哪些函数可以用来绘图和注释文字等,希望对我们的学习有所帮助。下一期我们将一起学习经常用到的滤波和卷积的相关操作。