Section 4 Drawing Functions
The drawing function is suitable for matrices/images of arbitrary depth. You can use anti-aliasing to render the boundaries of the shape (currently only implemented for 8-bit images). All functions include the parameter color (using RGB values (which can be constructed using the Scalar constructor)) for color images and the brightness for grayscale images. For color images, the channel order is usually blue, green, and red. This is the expectation of imshow, imread and imwrite. Therefore, if you use the Scalar constructor to form a color, its appearance should be similar to:
Scalar ( b l u e _ c o m p o n e n t , g r e e n _ c o m p o n e n t , r e d _ c o m p o n e n t [ , a l p h a _ c o m p o n e n t ] ) \texttt{Scalar} (blue \_ component, green \_ component, red \_ component[, alpha \_ component]) Scalar(blue_component,green_component,red_component[,alpha_component])
If you use your own image rendering and I/O functions, you can use any channel order. The drawing function processes each channel independently, and does not depend on the order of the channels, or even the color space used. You can use cvtColor to convert the entire image from BGR to RGB or a different color space.
If part or all of the drawn figure is outside the image, the drawing function will crop it. Similarly, many drawing functions can handle pixel coordinates specified with sub-pixel precision. This means that coordinates can be passed as fixed-point numbers encoded as integers. The number of decimal places is specified by the shift parameter, and the calculation method of real point coordinates is Point (x, y) → Point2f (x ∗ 2 − shift, y ∗ 2 − shift) \texttt{Point}(x,y)\rightarrow\texttt {Point2f}(x*2^{-shift},y*2^{-shift})Point(x,and )→Point2f(x∗2−shift,Y∗2− S h i f t )This function is particularly effective when rendering anti-aliased shapes.
Note that when the target image is 4 channels, these functions do not support alpha transparency processing. In this case, only copy color[3] to the redrawn pixel. Therefore, if you want to draw semi-transparent shapes, you can draw them in a separate buffer and then blend them with the main image.
1、cv::arrowedLine、cv::line
1) cv::arrowedLine : draw an arrow line segment from the first point to the second point.
void cv::arrowedLine(InputOutputArray img,Point pt1,Point pt2,const Scalar & color,int thickness = 1,int line_type = 8,int shift = 0,double tipLength = 0.1)
The function cv::arrowedLine draws an arrow between the pt1 and pt2 points of the image.
parameter name | Parameter Description. |
---|---|
img | The drawn image. |
pt1 | Starting point position |
pt2 | The point where the arrow points |
color | Line color |
thickness | Line thickness |
line_type | Line type, please refer to LineTypes |
shift | The number of decimal places in point coordinates. |
tipLength | The length of the arrow tip (relative to the length of the arrow) |
2、cv::circle
Draw a circle by specifying the center position and radius.
void cv::circle(InputOutputArray img,Point center,int radius,const Scalar & color,int thickness = 1,int lineType = LINE_8,int shift = 0)
parameter name | Parameter Description |
---|---|
img | The image used to draw a circle. |
center | Center position |
radius | radius |
color | colour |
thickness | The thickness of the circular profile (if positive). Negative values, such as FILLED , indicate that a solid circle is to be drawn. |
lineType | The type of circle border. Reference LineTypes |
shift | The number of decimal places in the center coordinate and radius value. |
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
int main()
{
// 创建图像
cv::Mat image = cv::Mat::zeros(cv::Size(512,512),CV_8UC3);
// 绘制空心圆
cv::circle(image,cv::Point(image.cols/2,image.rows/2),100,cv::Scalar(255,0,0),2);
// 绘制实心圆
cv::circle(image,cv::Point(image.cols/2,image.rows/2),75,cv::Scalar(0,255,0),-1);
// 显示图像
cv::imshow("src",image);
cv::waitKey();
cv::destroyAllWindows();
return 0;
}
3、clipLine
Determine whether a straight line is within the rectangle.
bool cv::clipLine(Size imgSize,Point & pt1,Point & pt2)
The function cv::clipLine calculates a part of the line segment within the entire specified rectangle. If the line segment is completely outside the rectangle, false is returned. Otherwise, it returns true.
parameter name | Parameter Description |
---|---|
imgSize | Image size. The rectangle of the image is Rect(0, 0, imgSize.width, imgSize.height). |
pt1 | The first point |
pt2 | Second point |
The other overloaded functions are as follows:
- bool cv::clipLine(Rect imgRect,Point & pt1,Point & pt2)
- bool cv::clipLine(Size2l imgSize,Point2l & pt1,Point2l & pt2)
cv::Rect rect(0,0,200,100);
cv::Point p1(10,10);
cv::Point p2(203,105);
cout << "is line in rectangle?"<<cv::clipLine(rect,p1,p2);
4、cv::drawContours
Draw outline outline or fill outline.
void cv::drawContours(InputOutputArray image,InputArrayOfArrays contours,int contourIdx,const Scalar & color,int thickness = 1,int lineType = LINE_8,InputArray hierarchy = noArray(),int maxLevel = INT_MAX,Point offset = Point())
If thickness ≥ 0, the function draws the contour contour in the image; if thickness <0, the function fills the area enclosed by the contour.
The parameters are as follows:
parameter name | Parameter Description |
---|---|
image | Target image |
contours | All input contours. Each contour is stored as a point vector. |
contourIdx | Indicates the parameters of the outline to be drawn. If it is negative, all contours are drawn. |
color | The color of the outline. |
thickness | The thickness of the line that draws the outline. If it is a negative number (for example, thickness = FILLED , the inside of the contour is drawn. |
lineType | Line connection type, refer to LineTypes |
hierarchy | Optional information about the hierarchy. Only needed if you only want to draw some contours (see maxLevel). |
maxLevel | The maximum level to draw the contour. If it is 0, only the specified outline is drawn. If it is 1, the function will draw contours and all nested contours. If it is 2, the function will draw contours, all nested contours, all nested-to-nested contours, and so on. This parameter is only considered if there is a hierarchical structure available. |
offset | Optional contour offset parameters. Move all drawn contours to the specified offset = (dx, dy). |
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
int main()
{
// 读取图像
cv::String fileName = "images/leaf.jpg";
cv::Mat src = cv::imread(fileName);
cv::Mat gray;
cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);
if(src.data == NULL){
printf("Image failed to read\n");
return -1;
}
cv::imshow("src",src);
cv::Mat dst = cv::Mat::zeros(src.rows, src.cols, CV_8UC3);
vector<vector<cv::Point> > contours;
vector<cv::Vec4i> hierarchy;
// 阈值化图像
cv::threshold(gray, gray, 100, 255, cv::THRESH_BINARY);
// 查找轮廓
cv::findContours( gray, contours, hierarchy,
cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE );
cv::Scalar color(255,0,255);
cv::drawContours( dst, contours,-1, color);
// 显示图像
cv::imshow("src",src);
cv::imshow("dst",dst);
cv::waitKey();
cv::destroyAllWindows();
return 0;
}
5 、 cv :: drawMarker
Draw a logo at the specified position.
void cv::drawMarker(InputOutputArray img,Point position,const Scalar & color,int markerType = MARKER_CROSS,int markerSize = 20,int thickness = 1,int line_type = 8)
The function cv::drawMarker draws a marker at a given position of the image. Several marker types are currently supported, please refer to MarkerTypes for more information.
type name | Type description |
---|---|
MARKER_CROSS | The crosshair marks the shape. |
MARKER_TILTED_CROSS | The 45-degree inclined crosshair marks the shape. |
MARKER_STAR | Star mark shape, combination of cross and oblique cross. |
MARKER_DIAMOND | Diamond mark shape. |
MARKER_SQUARE | Square mark shape. |
MARKER_TRIANGLE_UP | The upward triangle marks the shape. |
MARKER_TRIANGLE_DOWN | The downward-pointing triangle marks the shape. |
The parameters are as follows:
parameter name | Parameter Description. |
---|---|
img | Drawn target image |
position | The anchor point of the crosshair. |
color | Line color |
markType | Marker type, please refer to MarkerTypes |
thickness | Line thickness |
line_type | Line type, please refer to LineTypes |
markerSize | The length of the marker axis [default = 20 pixels] |
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
int main()
{
// 创建图像
cv::Mat image(cv::Size(512,512),CV_8UC3);
cv::Point center(image.cols / 2,image.rows / 2);
// 绘制标记
cv::drawMarker(image,center,cv::Scalar(0,0,255),cv::MarkerTypes::MARKER_CROSS,40,3);
// 显示
cv::imshow("image",image);
cv::waitKey();
cv::destroyAllWindows();
return 0;
}
6 、 cv :: eclipse
Draw a simple or rough ellipse arc or filled ellipse sector.
void cv::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)
具有更多参数的函数cv :: ellipse会绘制椭圆轮廓,填充的椭圆,椭圆弧或填充的椭圆扇形。 绘图代码使用一般参数形式。 使用分段线性曲线来近似椭圆弧边界。 如果需要更多控制椭圆的渲染,则可以使用ellipse2Poly检索曲线,然后使用折线对其进行渲染或使用fillPoly对其进行填充。 如果您使用函数的第一个变体,并且想绘制整个椭圆而不是圆弧,请传递startAngle = 0和endAngle = 360。 如果startAngle大于endAngle,则会交换它们。 下图说明了绘制蓝色弧的参数的含义。
参数如下:
参数名称 | 参数描述 |
---|---|
img | 所要绘制的图像。 |
center | 椭圆中心 |
axes | 椭圆主轴尺寸的一半。 |
angle | 椭圆旋转角度,以度为单位。 |
startAngle | 椭圆弧的起始角度,以度为单位。 |
endAngle | 椭圆弧的终止角度,以度为单位。 |
color | 椭圆颜色 |
thickness | 椭圆弧轮廓的粗细(如果为正)。 否则,这表明将绘制一个填充的椭圆形扇区。 |
lineType | 椭圆边界线条样式。参考 LineTypes |
shift | 中心坐标和轴值中的小数位数。 |
另外的重载函数如下:
- void cv::ellipse(InputOutputArray img,const RotatedRect & box,const Scalar & color,int thickness = 1,int lineType = LINE_8)
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
int main()
{
// 创建图像
cv::Mat image(cv::Size(512,512),CV_8UC3);
// 中心点
cv::Point center(image.cols / 2 ,image.rows / 2);
// 绘制椭圆
cv::ellipse(image,center,cv::Size(image.cols / 2,image.rows / 4),
45,0,360,cv::Scalar( 0, 0, 255 ),3);
cv::ellipse(image,center,cv::Size(image.cols / 6,image.rows / 4),
45,0,360,cv::Scalar( 0, 255, 0 ),-1);
// 显示图像
cv::imshow("image",image);
cv::waitKey();
cv::destroyAllWindows();
return 0;
}
6、cv::ellipse2Poly
用折线近似椭圆弧。
void cv::ellipse2Poly(Point center,Size axes,int angle,int arcStart,int arcEnd,int delta,std::vector< Point > & pts)
函数ellipse2Poly计算近似于指定椭圆弧的折线的顶点。 由椭圆使用。 如果arcStart大于arcEnd,则将它们交换。
参数如下:
参数名称 | 参数描述 |
---|---|
center | 弧的中心。 |
axes | 椭圆主轴尺寸的一半。详细可以参考 ellipse 。 |
angle | 椭圆的旋转角度,以度为单位。详细可以参考 ellipse |
arcStart | 椭圆弧的起始角度,以度为单位。 |
arcEnd | 椭圆弧的终止角度,以度为单位。 |
delta | 后续折线顶点之间的角度。 它定义了近似精度。 |
pts | 折线顶点的输出向量。 |
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
int main()
{
// 创建图像
cv::Mat image(cv::Size(512,512),CV_8UC3);
// 中心点
cv::Point center(image.cols / 2 ,image.rows / 2);
vector<cv::Point2d> pts;
// 生成椭圆近似折线
cv::ellipse2Poly(center,cv::Size(image.cols/4,image.rows / 2),45,0,360,1,pts);
cout <<"point.size:"<< pts.size() << endl;
// 绘制
for(int i = 0;i < pts.size() - 1;i++){
cv::Point2d pt1 = pts[i];
cv::Point2d pt2 = pts[i + 1];
cv::line(image,pt1,pt2,cv::Scalar(0,0,255),3);
}
// 显示图像
cv::imshow("image",image);
cv::waitKey();
cv::destroyAllWindows();
return 0;
}
7、cv::fillConvexPoly
填充凸多边形。
void cv::fillConvexPoly (InputOutputArray img,InputArray points,const Scalar & color,int lineType = LINE_8,int shift = 0)
函数cv :: fillConvexPoly绘制一个填充的凸多边形。 该函数比函数fillPoly快得多。 它不仅可以填充凸多边形,而且可以填充任何不具有自相交的单调多边形,即,其轮廓与每个水平线(扫描线)相交的多边形最多两次(尽管其最顶部和/或底部边缘可能是 水平)。
参数如下:
参数名称 | 参数类型 |
---|---|
img | 绘制图像 |
points | 多边形顶点。 |
color | 多边形颜色 |
lineType | 多边形边界的线条类型. 参考LineTypes |
shift | 顶点坐标中的小数位数。 |
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
int main()
{
// 创建图像
cv::Mat image(cv::Size(512,512),CV_8UC3);
// 定义凸多边形顶点
cv::Point PointArray[4];
PointArray[0] = cv::Point(50,10);
PointArray[1] = cv::Point(300,12);
PointArray[2] = cv::Point(350,250);
PointArray[3] = cv::Point(9,250);
// 填充凸多边形。
cv::fillConvexPoly(image,PointArray,4,cv::Scalar(0,255,0));
// 显示图像
cv::imshow("image",image);
cv::waitKey();
cv::destroyAllWindows();
return 0;
}
8、cv::fillPoly
填充以一个或多个多边形为边界的区域。
void cv::fillPoly(InputOutputArray img,InputArrayOfArrays pts,const Scalar & color,int lineType = LINE_8,int shift = 0,Point offset = Point())
函数cv :: fillPoly填充由多个多边形轮廓所界定的区域。 该功能可以填充复杂区域,例如,带有孔的区域,具有自相交的轮廓(部分轮廓)等等。
参数如下:
参数名称 | 参数描述 |
---|---|
img | 绘制图像。 |
pts | 多边形数组,其中每个多边形都表示为点数组。 |
color | 多边形颜色。 |
lineType | 多边形边界的线条类型. 参考LineTypes |
shift | 顶点坐标中的小数位数。 |
offset | 轮廓所有点的可选偏移量。 |
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
// 创建图像
cv::Mat image(cv::Size(512,512),CV_8UC3);
// 多边形顶点
Point pts[1][6];
pts[0][0] = Point(100, 100);
pts[0][1] = Point(100, 200);
pts[0][2] = Point(150, 250);
pts[0][3] = Point(200, 200);
pts[0][4] = Point(200, 100);
pts[0][5] = Point(100, 100);
const Point* ppts[] = { pts[0] }; //指针
int npt[] = { 6 };
Scalar color = Scalar(255, 0, 0);
// 填充多边形
fillPoly(image, ppts, npt, 1, color, 8);
// 显示图像
cv::imshow("image",image);
cv::waitKey();
cv::destroyAllWindows();
return 0;
}
9、cv::polylines
绘制多条多边形曲线。
void cv::polylines(InputOutputArray img,InputArrayOfArrays pts,bool isClosed,const Scalar & color,int thickness = 1,int lineType = LINE_8,int shift = 0)
参数名称 | 参数描述 |
---|---|
img | 所要绘制的图像 |
pts | 多边形曲线数组。 |
isClosed | 指示绘制的折线是否闭合的标志。 如果它们是闭合的,则该函数将从每个曲线的最后一个顶点到其第一个顶点绘制一条直线。 |
color | 折线颜色。 |
thickness | 折线边缘的厚度。 |
lineType | 线段的类型。请参考 LineTypes |
shift | 顶点坐标中的小数位数。 |
#include <opencv2/opencv.hpp>
using namespace std;
int main(void)
{
// 创建图像
cv::Mat image(512, 512, CV_8UC3);
// 多边形顶点
vector<cv::Point> p;
int n = 5;
for (int i = 0; i < n; i++) {
p.push_back(cv::Point(cos(CV_PI * (2.0*i/n - 0.5)) * 180 + 200, sin(CV_PI * (2.0*i/n - 0.5)) * 180 + 200));
}
// 绘制多边形
cv::polylines(image, p, true, cv::Scalar(255, 0, 0), 2, cv::LINE_AA);
p.clear();
for (int i = 0; i < n; i++) {
p.push_back(cv::Point(cos(CV_PI * (2.0*i/n - 0.5)) * 140 + 200, sin(CV_PI * (2.0*i/n - 0.5)) * 140 + 200));
}
// 填充多边形
cv::fillConvexPoly(image, p, cv::Scalar(0, 0, 255), cv::LINE_AA);
cv::imshow("image", image);
vector<vector<cv::Point>> ps(16);
for (int n = 0; n < 16; n++) {
cv::Point p0((n % 4) * 100 + 50, (n / 4) * 100 + 50);
for (int i = 0; i < n + 3; i++) {
cv::Point pa(cos(CV_PI * (2.0*i/(n+3) - 0.5)) * 40, sin(CV_PI * (2.0*i/(n+3) - 0.5)) * 40);
ps[n].push_back(p0 + pa);
}
}
image = cv::Scalar(255, 255, 255);
cv::fillPoly(image, ps, cv::Scalar(0, 255, 255), cv::LINE_AA);
cv::polylines(image, ps, true, cv::Scalar(0, 0, 0), 3, cv::LINE_AA);
cv::imshow("image2", image);
cv::waitKey();
cv::destroyAllWindows();
return 0;
}
10、cv::getFontScaleFromHeight、cv::getTextSize、cv::putText
1)cv::getFontScaleFromHeight:计算用于实现给定高度(以像素为单位)的特定于字体的大小。
double cv::getFontScaleFromHeight(const int fontFace,const int pixelHeight,const int thickness = 1)
参数名称 | 参数描述 |
---|---|
fontFace | 使用的字体, 请参考 cv::HersheyFonts. |
pixelHeight | 像素高度,用于计算fontScale |
thickness | 用于渲染文本的线的粗细。有关详细信息,请参见putText。 |
2)cv::getTextSize:计算文本字符串的宽度和高度(包含指定文本的框的大小)。
Size cv::getTextSize(const String & text,int fontFace,double fontScale,int thickness,int * baseLine)
参数如下:
参数名称 | 参数描述 | |
---|---|---|
text | 所要绘制的图像 | |
fontFace | 所要使用的字体。 请参考 HersheyFonts. | |
fontScale | 字体比例因子乘以特定于字体的基本大小。 | |
thickness | 用于渲染文本的线的粗细。 请详细参考 putText | |
[out] | baseLine | 基线相对于最底下的文本点的y坐标。 |
函数cv :: getTextSize计算并返回包含指定文本的框的大小。 也就是说,以下代码呈现了一些文本,其周围的紧实框和基线:
String text = "Funny text inside the box";
int fontFace = FONT_HERSHEY_SCRIPT_SIMPLEX;
double fontScale = 2;
int thickness = 3;
Mat img(600, 800, CV_8UC3, Scalar::all(0));
int baseline=0;
Size textSize = getTextSize(text, fontFace,
fontScale, thickness, &baseline);
baseline += thickness;
// center the text
Point textOrg((img.cols - textSize.width)/2,
(img.rows + textSize.height)/2);
// draw the box
rectangle(img, textOrg + Point(0, baseline),
textOrg + Point(textSize.width, -textSize.height),
Scalar(0,0,255));
// ... and the baseline first
line(img, textOrg + Point(0, thickness),
textOrg + Point(textSize.width, thickness),
Scalar(0, 0, 255));
// then put the text itself
putText(img, text, textOrg, fontFace, fontScale,
Scalar::all(255), thickness, 8);
3)cv::putText:绘制文本字符串。
void cv::putText(InputOutputArray img,const String & text,Point org,int fontFace,double fontScale,Scalar color,int thickness = 1,int lineType = LINE_8,bool bottomLeftOrigin = false)
函数cv :: putText在图像中呈现指定的文本字符串。 无法使用指定字体呈现的符号将替换为问号。 有关文本呈现代码示例,请参见getTextSize。
参数如下:
参数名称 | 参数描述 |
---|---|
img | 绘制的图像. |
text | 气概绘制的文本 |
org | 图像中文本字符串的左下角。 |
fontFace | 所要使用的字体。 请参考 HersheyFonts. |
fontScale | 字体比例因子乘以特定于字体的基本大小。 |
color | 文本颜色 |
thickness | 用于绘制文本的线条的粗细。 |
lineType | 线条类型,请参考LineTypes |
bottomLeftOrigin | 如果为true,则图像数据原点位于左下角。 否则,它位于左上角。 |
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
int main()
{
//创建空白图用于绘制文字
cv::Mat image = cv::Mat::zeros(cv::Size(640, 480), CV_8UC3);
//设置蓝色背景
image.setTo(cv::Scalar(100, 0, 0));
//设置绘制文本的相关参数
std::string text = "Hello World!";
int font_face = cv::FONT_HERSHEY_COMPLEX;
double font_scale = 2;
int thickness = 2;
int baseline;
//获取文本框的长宽
cv::Size text_size = cv::getTextSize(text, font_face, font_scale, thickness, &baseline);
//将文本框居中绘制
cv::Point origin;
origin.x = image.cols / 2 - text_size.width / 2;
origin.y = image.rows / 2 - text_size.height / 2;
cv::putText(image, text, origin, font_face, font_scale, cv::Scalar(0, 255, 255), thickness, 8, 0);
//显示绘制解果
cv::imshow("image", image);
cv::waitKey(0);
return 0;
}
11、cv::rectangle
绘制一个简单的,粗的或实心的直角矩形。
void cv::rectangle(InputOutputArray img,Point pt1,Point pt2,const Scalar & color,int thickness = 1,int lineType = LINE_8,int shift = 0)
函数cv :: rectangle绘制一个矩形轮廓或一个填充的矩形,其两个相对角为pt1和pt2。
参数如下:
参数名称 | 参数描述 |
---|---|
img | 所要绘制的图像. |
pt1 | 矩形的顶点。 |
pt2 | 与pt1相反的矩形的顶点。 |
color | 矩形的颜色或亮度(灰度图像)。 |
thickness | The thickness of the lines that make up the rectangle. Negative values, such as FILLED , indicate that the function must draw a filled rectangle. |
lineType | Line type, please refer to LineTypes |
shift | The number of decimal places in point coordinates. |
Other overloaded functions are as follows:
- void cv::rectangle (InputOutputArray img,Rect rec,const Scalar & color,int thickness = 1,int lineType = LINE_8,int shift = 0)
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
int main()
{
//创建图像
cv::Mat image = cv::Mat::zeros(cv::Size(640, 480), CV_8UC3);
// 绘制空心矩形
cv::rectangle(image,cv::Point(100,100),cv::Point(300,300),cv::Scalar(0,255,0),3);
// 填充矩形
cv::rectangle(image,cv::Point(120,120),cv::Point(280,280),cv::Scalar(0,0,255),-1);
//显示绘制
cv::imshow("image", image);
cv::waitKey();
cv::destroyAllWindows();
return 0;
}