OpenCV - 绘图

2022-08-09 15:12:00 浏览数 (1)

我们常常会想要画一幅图片,或者在某个其他地方得来的图片上画些东西。为了实现这个目标,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. 基础引用
  • 之后对上述函数进行示例演示
  • 所有代码默认引用如下包
代码语言:javascript复制
import cv2
import numpy as np
import mtutils as mt
from mtutils import PIS

  • 示例图片 img1.jpgimg2.jpg
  • 查看 opencv 某函数 func 文档可以运行:
代码语言:javascript复制
print(cv2.<func>.__doc__)

  • lineType 是绘图常用参数之一,表示绘制时线条的绘制方式,lineType 参数可选4 ,8和 cv2.LINE_AA,分别表示直线是“4邻域连接”或者“8邻域连接”或者是平滑处理。
  • thickness thickness参数是指线宽的像素数。对于圆、矩形和其他封闭图形,thickness参数可以被设置为cv2.FILLED(相当于-1),表示填充整个图形。
1. cv2.circle()

画一个简单圆

  • 函数使用
代码语言:javascript复制
cv2.circle(img, center, radius, color, thickness=1, lineType=8, shift=0)

  • 示例代码
代码语言:javascript复制
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()

判断一条直线是否在给定的矩形内

  • 函数使用
代码语言:javascript复制
cv2.clipLine(imgRect, pt1, pt2) 

点都是 (x, y) 的格式,rect 为 (x, y, w, h) 格式

只有当直线完全在指定的矩形范围之外时,函数cv2.clipLine() 才会返回False

代码语言:javascript复制
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()

画一个椭圆(可以倾斜,或者只有部分圆弧)

  • 函数使用
代码语言:javascript复制
cv2.ellipse(img, [center, axes, angle], color, thickness=1, lineType=8) 

  • 参数说明

参数

含义

img

图像

center

中心坐标 (x, y)

axes

长短轴长度 (长轴长度, 短轴长度)

angle

角度 (角度制)

color

颜色

thickness

线条粗细程度

lineType

线型

  • 示例代码
代码语言:javascript复制
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()

计算一个近似椭圆的多边形

  • 函数使用
代码语言:javascript复制
cv2.ellipse2Poly(center, axes, angle, startAngle, endAngle, delta)

delta 为间隔角度,'angle, startAngle, endAngle, delta’均为角度制

  • 示例代码
代码语言:javascript复制
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()

画一个填充的简单多边形

  • 函数用法
代码语言:javascript复制
cv2.fillConvexPoly(img, pts, color) 

这个函数用来绘制一个填充的多边形。这个函数比 cv2.fi11Po1y() 速度快很多,因为它使用了更简单的算法。需要注意的是cv2.fillConvexPoly() 使用的算法在多边形有自交点时不能正确工作。

pts 中的点将被按顺序用直线段连接起来,第一个点和最后一个点之间也会连接起来(也就是说多边形被认为是封闭的)

  • 示例代码
代码语言:javascript复制
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()

画一个填充的任意多边形

  • 函数使用
代码语言:javascript复制
cv2.fillPoly(canvas, [points1, points2, ...], color)

  • 示例代码
代码语言:javascript复制
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()

画一个简单直线

  • 函数使用
代码语言:javascript复制
cv2.line(img, pt1, pt2, color, thickness, lineType, shift) 

  • 示例代码
代码语言:javascript复制
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()

画一个简单矩形

  • 函数使用
代码语言:javascript复制
cv2.rectangle(img, pt1, pt2, color, thickness, lineType) 

  • 示例代码
代码语言:javascript复制
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()

画多重折线

  • 函数使用
代码语言:javascript复制
cv2.polylines(img, pts, isclosed, color, thickness, lineType)

  • 示例代码
代码语言:javascript复制
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()

在图像中绘制指定文字

  • 函数使用
代码语言:javascript复制
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更复杂的变体

  • 示例代码
代码语言:javascript复制
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()

获取一个文字的宽度和高度

  • 函数使用
代码语言:javascript复制
cv2.getTextSize(text, fontFace, fontScale, thickness) 

cv2.getTextSize() 函数回答了如果把文字绘制出来将有多大的问题(使用一组参数而不用实际将文字绘制到图上)。

  • 示例代码
代码语言:javascript复制
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》 第五章

0 人点赞