0
点赞
收藏
分享

微信扫一扫

【OpenCV学习】绘制图形其二

Brose 2022-05-24 阅读 64

绘制图形其二

画多边形

画多边形就是画很多直线(线段),所以画多边形会接收一个点集的集合,是个三维数组,如果你使用二维数组来绘画的画,就会出现如下的效果:

from cv2 import cv2
import numpy as np
# 创建纯黑的背景图用来画图形
img = np.zeros((480, 640, 3), np.uint8)
# polylines(img, pts, isClosed, color, thickness=None, lineType=None, shift=None)
# polylines(图片, int32以上类型点集的集合(三维), 图形是否闭合, bgr颜色, 线宽, 线型(1/4/[8]/16), 坐标缩放比例)
pts = np.array([(320, 40), (20, 320), (620, 320)], np.int32)
cv2.polylines(img, pts, True, (0, 0, 255), 5)
cv2.imshow('draw', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

然后你会收获一个报错:

在这里插入图片描述

OpenCV(3.4.1) Error: Assertion failed (p.checkVector(2, 4) >= 0) in cv::polylines, file C:\projects\opencv-python\opencv\modules\imgproc\src\drawing.cpp, line 2441
Traceback (most recent call last):
  File "G:/opencvStudy/note/demo.py", line 18, in <module>
    cv2.polylines(img, pts, True, (0, 0, 255), 5)
cv2.error: OpenCV(3.4.1) C:\projects\opencv-python\opencv\modules\imgproc\src\drawing.cpp:2441: error: (-215) p.checkVector(2, 4) >= 0 in function cv::polylines

在当中捕获到了一个非常重要的判断:p.checkVector(2, 4) >= 0 ,这说明了什么?说明他检查维度必须是三维的,因为一个多边形,可以是由多组图形合体形成的,比如我下面这个小栗子:

from cv2 import cv2
import numpy as np
# 创建纯黑的背景图用来画图形
img = np.zeros((480, 640, 3), np.uint8)
# polylines(img, pts, isClosed, color, thickness=None, lineType=None, shift=None)
# polylines(图片, int32以上类型点集的集合(三维), 图形是否闭合, bgr颜色, 线宽, 线型(1/4/[8]/16), 坐标缩放比例)
pts1 = np.array([(320, 40), (20, 320), (620, 320)], np.int32)
pts2 = np.array([(20, 140), (620, 140), (320, 420)], np.int32)
cv2.polylines(img, [pts1, pts2], True, (0, 0, 255), 5)
cv2.imshow('draw', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

就画出来了由两个三角形组成的六边形:

在这里插入图片描述

当中 isClosed 代表图形是否闭合,如果闭合的话,会首尾相连,否则会止步于最后一点。

填充多边形

因为是填充,所以必定会闭合图形,然后在封闭的图形中填充颜色。但他有个小小的要注意的地方,就拿填充上面六边形来说,如果你用画六边形的方法填充他,那你铁定获得了6个相连的填充三角形:

from cv2 import cv2
import numpy as np
# 创建纯黑的背景图用来画图形
img = np.zeros((480, 640, 3), np.uint8)
# fillPoly(img, pts, color, lineType=None, shift=None, offset=None)
# fillPoly(图片, int32以上类型点集的集合(三维), bgr颜色, 线型(1/4/[8]/16), 坐标缩放比例, 坐标偏移量(x, y))
pts1 = np.array([(320, 40), (20, 320), (620, 320)], np.int32)
pts2 = np.array([(20, 140), (620, 140), (320, 420)], np.int32)
cv2.fillPoly(img, [pts1, pts2], (0, 255, 0))
cv2.imshow('draw', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果图:

在这里插入图片描述

那如何让他填充实体的六边形呢?答案也很简单,分开来填充~

from cv2 import cv2
import numpy as np
# 创建纯黑的背景图用来画图形
img = np.zeros((480, 640, 3), np.uint8)
# fillPoly(img, pts, color, lineType=None, shift=None, offset=None)
# fillPoly(图片, int32以上类型点集的集合(三维), bgr颜色, 线型(1/4/[8]/16), 坐标缩放比例, 坐标偏移(x, y))
pts1 = np.array([(320, 40), (20, 320), (620, 320)], np.int32)
pts2 = np.array([(20, 140), (620, 140), (320, 420)], np.int32)
cv2.fillPoly(img, [pts1], (0, 255, 0))
cv2.fillPoly(img, [pts2], (0, 255, 0))
cv2.imshow('draw', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

这下就得到了整个正六边形的填充体了:

在这里插入图片描述

添加文字

字体格式:
在这里插入图片描述
方法说明看注释:

from cv2 import cv2
import numpy as np
# 创建纯黑的背景图用来画图形
img = np.zeros((480, 640, 3), np.uint8)
# putText(img, text, org, fontFace, fontScale, color, thickness=None, lineType=None, bottomLeftOrigin=None)
# putText(图片, 文字(英文), 左下角坐标, 字体格式, 字体大小, color, thickness=None, lineType=None, bottomLeftOrigin=None)
cv2.putText(img, 'OpenCV', (50, 150), cv2.FONT_HERSHEY_COMPLEX, 4, (0, 0, 255))
cv2.putText(img, '你好cv2!!', (50, 350), cv2.FONT_HERSHEY_COMPLEX, 4, (0, 0, 255))
cv2.imshow('draw', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

打印结果,发现中文以及中文符号都变成问号了,只有英文和英文标点和数字能正常显示。可以看出OpenCV实际上是一点也不支持中文的,字体都是英文字体:
在这里插入图片描述

如何让图片上有中文?
这里有一种 “曲线救国” 的方式——使用 Pillow 库绘制中文。
实际上这里的绘制中文,跟OpenCV完全没有关系(毕竟我们不会大佬那种修改C++的方式)。

from cv2 import cv2
import numpy as np
from PIL import ImageFont, ImageDraw, Image
# 纯白
# img = np.full((617, 821, 3), 255, np.uint8)
# 读取背景图片
img = cv2.imread('./cat.jpeg')
# 导入字体文件
font = ImageFont.truetype('./113.ttf', 64)
# 创建一个pillow的图片
img_pil = Image.fromarray(img)
draw = ImageDraw.Draw(img_pil)
# 利用draw去绘制中文
draw.text((250, 300), '你好cv2!!', font=font, fill=(0, 0, 255))
# 重新变回ndarray
img = np.array(img_pil)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行效果图:

在这里插入图片描述

这下中文可以正常显示出来了,Nice!

举报

相关推荐

0 条评论