我们常常会想要画一幅图片,或者在某个其他地方得来的图片上画些东西。为了实现这个目标,OpenCV提供了一大批可以供我们画直线、矩形、圆等图形的函数。本文记录相关内容。
简介
- OpenCV的绘图函数可以在任意深度的图像上工作,但在大多数情况下,它们只对图像的前三个通道有影响,如果是单通道图像,则默认只影响第一个通道。大多数绘图函数都支持操作对象的颜色、宽度、线型(与直线平滑度有关)和亚像素对齐等参数。
- 本文基于 《学习 OpenCV3 》中第六章的内容整理 Python OpenCV 绘图函数。
内容列表
序号 | 函数 | 描述 |
---|---|---|
1 | cv2.circle() | 画一个简单圆 |
2 | cv2.clipLine() | 判断一条直线是否在给定的矩形内 |
3 | cv2.ellipse() | 画一个椭圆(可以倾斜,或者只有部分圆弧) |
4 | cv2.ellipse2Poly() | 计算一个近似椭圆的多边形 |
5 | cv2.fillConvexPoly() | 画一个填充的简单多边形 |
6 | cv2.fillPoly() | 画一个填充的任意多边形 |
7 | cv2.line() | 画一个简单直线 |
8 | cv2.rectangle() | 画一个简单矩形 |
9 | cv2.polylines() | 画多重折线 |
10 | cv2.putText() | 在图像中绘制指定文字 |
11 | cv2.getTextSize() | 获取一个文字的宽度和高度 |
矩阵操作
0. 基础引用
- 之后对上述函数进行示例演示
- 所有代码默认引用如下包
import cv2
import numpy as np
import mtutils as mt
from mtutils import PIS
- 示例图片
img1.jpg
和img2.jpg
- 查看 opencv 某函数
func
文档可以运行:
print(cv2.<func>.__doc__)
-
lineType
是绘图常用参数之一,表示绘制时线条的绘制方式,lineType
参数可选4
,8和cv2.LINE_AA
,分别表示直线是“4邻域连接”或者“8邻域连接”或者是平滑处理。
-
thickness
thickness
参数是指线宽的像素数。对于圆、矩形和其他封闭图形,thickness
参数可以被设置为cv2.FILLED
(相当于-1),表示填充整个图形。
1. cv2.circle()
画一个简单圆
- 函数使用
cv2.circle(img, center, radius, color, thickness=1, lineType=8, shift=0)
- 示例代码
canvas = np.zeros([400, 400, 3], dtype='uint8')
center = [150, 150]
radius = 50
color = [255, 255, 0]
thickness = 4
lineType = 8
shift = 0
cv2.circle(canvas, center, radius, color, thickness, lineType, shift)
PIS(canvas)
2. cv2.clipLine()
判断一条直线是否在给定的矩形内
- 函数使用
cv2.clipLine(imgRect, pt1, pt2)
点都是 (x, y) 的格式,rect 为 (x, y, w, h) 格式
只有当直线完全在指定的矩形范围之外时,函数cv2.clipLine()
才会返回False
rec = [20, 20, 80, 80]
point1 = [210, 110]
point2 = [110, 110]
res = cv2.clipLine(rec, point1, point2)
-->
res
(False, (210, 110), (110, 110))
3. cv2.ellipse()
画一个椭圆(可以倾斜,或者只有部分圆弧)
- 函数使用
cv2.ellipse(img, [center, axes, angle], color, thickness=1, lineType=8)
- 参数说明
参数 | 含义 |
---|---|
img | 图像 |
center | 中心坐标 (x, y) |
axes | 长短轴长度 (长轴长度, 短轴长度) |
angle | 角度 (角度制) |
color | 颜色 |
thickness | 线条粗细程度 |
lineType | 线型 |
- 示例代码
canvas = np.zeros([400, 400, 3], dtype='uint8')
center = [150, 150]
axes = [100, 70]
angle = 45
startAngle = 0
endAngle = 270
color = [255, 0, 255]
thickness = -1
cv2.ellipse(canvas, [center, axes, angle], color, thickness)
PIS(canvas)
4. cv2.ellipse2Poly()
计算一个近似椭圆的多边形
- 函数使用
cv2.ellipse2Poly(center, axes, angle, startAngle, endAngle, delta)
delta
为间隔角度,'angle
, startAngle
, endAngle
, delta
’均为角度制
- 示例代码
canvas = np.zeros([400, 400, 3], dtype='uint8')
center = [150, 150]
axes = [100, 70]
angle = 45
startAngle = 0
endAngle = 270
delta = 30
color = [0, 255, 255]
points = cv2.ellipse2Poly(center, axes, angle, startAngle, endAngle, delta)
cv2.fillPoly(canvas, [points], color)
PIS(canvas)
-->
points
array([[221, 221],
[186, 236],
[142, 228],
[101, 199],
[ 72, 158],
[ 64, 114],
[ 79, 79],
[114, 64],
[158, 72],
[199, 101]])
5. cv2.fillConvexPoly()
画一个填充的简单多边形
- 函数用法
cv2.fillConvexPoly(img, pts, color)
这个函数用来绘制一个填充的多边形。这个函数比 cv2.fi11Po1y()
速度快很多,因为它使用了更简单的算法。需要注意的是cv2.fillConvexPoly()
使用的算法在多边形有自交点时不能正确工作。
pts
中的点将被按顺序用直线段连接起来,第一个点和最后一个点之间也会连接起来(也就是说多边形被认为是封闭的)
- 示例代码
canvas = np.zeros([300, 300, 3], dtype='uint8')
porints = np.array([[20, 50], [130, 30], [125, 100]])
color = [0, 255, 0]
cv2.fillConvexPoly(canvas, porints, color)
PIS(canvas)
6. cv2.fillPoly()
画一个填充的任意多边形
- 函数使用
cv2.fillPoly(canvas, [points1, points2, ...], color)
- 示例代码
canvas = np.zeros([300, 300, 3], dtype='uint8')
porints1 = np.array([[20, 50], [130, 30], [125, 100]])
porints2 = porints1[:, ::-1]
color = [0, 0, 255]
cv2.fillPoly(canvas, [porints1, porints2], color)
PIS(canvas)
7. cv2.line()
画一个简单直线
- 函数使用
cv2.line(img, pt1, pt2, color, thickness, lineType, shift)
- 示例代码
canvas = np.zeros([300, 300, 3], dtype='uint8')
pt1 = [12, 186]
pt2 = [192, 399]
color = [255, 255, 255]
cv2.line(canvas, pt1, pt2, color, thickness=5)
PIS(canvas)
8. cv2.rectangle()
画一个简单矩形
- 函数使用
cv2.rectangle(img, pt1, pt2, color, thickness, lineType)
- 示例代码
canvas = np.zeros([300, 300, 3], dtype='uint8')
pt1 = [12, 186]
pt2 = [192, 199]
color = [255, 255, 255]
cv2.rectangle(canvas, pt1, pt2, color, thickness=5)
PIS(canvas)
9. cv2.polylines()
画多重折线
- 函数使用
cv2.polylines(img, pts, isclosed, color, thickness, lineType)
- 示例代码
canvas = np.zeros([300, 300, 3], dtype='uint8')
pts1 =np.array([[12, 186], [56, 96], [156, 198], [222, 29]])
pts2 = np.array([[192, 199], [98, 65], [299, 365], [55, 99]])
color = [255, 255, 255]
cv2.polylines(canvas, [pts1, pts2], True, color, thickness=5)
PIS(canvas)
10. cv2.putText()
在图像中绘制指定文字
- 函数使用
cv2.putText(canvas, text, origin, fontFace, fontScale, color, thickness=1, lineType=8, bottomLeftOrigin=False)
- 参数说明
参数 | 说明 |
---|---|
canvas | 画布 |
text | 文字字符,无法正确绘制中文 |
origin | 文字左上角坐标 |
fontFace | 字体 |
fontScale | 文字尺寸 |
color | 文字颜色 |
bottomLeftOrigin | 偏移从左下角计算 |
- fontFace
标识符 | 描述 |
---|---|
cv2.FONT_HERSHEY_SIMPLEX | 普通大小无衬线字体 |
cv2.FONT_HERSHEY_PLAIN | 小号无衬线字体 |
cv2.FONT_HERSHEY_DUPLEX | 普通大小无衬线字体,比cv2.FONT_HERSHEY_SIMPLEX更复杂 |
cv2.FONT_HERSHEY_COMPLEX | 普通大小无衬线字体;比cv2.FONT_HERSHEY_DUPLEX更复杂 |
cv2.FONT_HERSHEY_TRIPLEX | 普通大小无衬线字体;比cv2.FONT_HERSHEY_COMPLEX更复杂 |
cv2.FONT_HERSHEY_COMPLEX_SMALL | 小号版本的cv2.FONT_HERSHEY_COMPLEX |
cv2.FONT_HERSHEY_SCRIPT_SIMPLEX | 手写体 |
cv2.FONT_HERSHEY_SCRIPT_COMPLEX | 比cv2.FONT_HERSHEY SCRIPT SIMPLEX更复杂的变体 |
- 示例代码
canvas = np.zeros([200, 600, 3], dtype='uint8')
text = 'hello world! 表独立兮山之上'
origin = [20, 100]
fontFace=cv2.FONT_HERSHEY_TRIPLEX
fontScale = 1.3
color = [255, 255, 0]
thickness = 2
lineType = 8
bottomLeftOrigin = False
cv2.putText(canvas, text, origin, fontFace, fontScale, color, thickness, lineType, bottomLeftOrigin)
PIS(canvas)
11. cv2.getTextSize()
获取一个文字的宽度和高度
- 函数使用
cv2.getTextSize(text, fontFace, fontScale, thickness)
cv2.getTextSize()
函数回答了如果把文字绘制出来将有多大的问题(使用一组参数而不用实际将文字绘制到图上)。
- 示例代码
text = 'hello world!'
origin = [20, 100]
fontFace=cv2.FONT_HERSHEY_TRIPLEX
fontScale = 1.3
thickness = 2
res = cv2.getTextSize(text, fontFace, fontScale, thickness)
-->
res
((271, 28), 13)
示例源码
- https://github.com/zywvvd/Python_Practise
参考资料
- 《学习 OpenCV3》 第五章