三、绘制基本图形
利用OpenCV提供的绘制图形API,可以轻松的在图像上绘制各种图形,比如直线、矩形、圆和椭圆等。
1、绘制直线
line()
用法:
cv2.line(img, pt1, pt2, color, thickness, lineType, shift)
参数说明:
- img:在哪个图像上画线
- pt1, pt2:开始点, 结束点:指定线的开始与结束位置
- color:颜色
- (0, 0, 255):红
- (0, 255, 0):绿
- (255, 0, 0):蓝
- thickness:线宽
- lineType:线型(可取值-1, 4, 8, 18), 默认为8
- shift:坐标缩放比例
import cv2 import numpy as np img = np.zeros((480, 640, 3), np.uint8) # 划线, 坐标点(x, y) cv2.line(img, (20, 20), (400, 400), (0, 0, 255), 5, 16) cv2.imshow('draw', img) cv2.waitKey(0) cv2.destroyAllWindows()
2、绘制矩形
rectangle()
用法:
cv2.rectangle(img, pt1, pt2, color, thickness, lineType, shift)
参数说明:
rectangle()用法 和 line()用法 完全一致。
import cv2 import numpy as np img = np.zeros((480, 640, 3), np.uint8) cv2.rectangle(img, (20, 20), (400, 400), (0, 255, 0), 5) cv2.imshow('draw', img) cv2.waitKey(0) cv2.destroyAllWindows()
3、绘制圆
circle()
用法:
cv2.circle()(img, center, radius, color, thickness, lineType, shift)
参数说明:
- img:在哪个图像上绘制圆
- center:圆心坐标
- radius:半径大小
- color:颜色
- thickness:线宽
- lineType:线型
- shift:坐标缩放比例
import cv2 import numpy as np img = np.zeros((480, 640, 3), np.uint8) cv2.circle(img, (320, 240), 100, (255, 0, 0), 5, 16) cv2.imshow('draw', img) cv2.waitKey(0) cv2.destroyAllWindows()
4、绘制椭圆
ellipse()
用法:
cv2.ellipse(img, center, axes, angle, startAngle, endAngle, color, thickness, lineType, shift)
参数说明:
- img:在哪个图像上绘制椭圆
- center:中心点
- axes:长宽的一半
- angle:角度
- startAngle:从哪个角度开始
- endAngle:从哪个角度结束
- color:颜色
- thickness:线宽
- lineType:线型
- shift:坐标缩放比例
import cv2 import numpy as np img = np.zeros((480, 640, 3), np.uint8) cv2.ellipse(img, (320, 240), (100, 50), 0, 0, 360, (255, 255, 255), 5, 16) cv2.imshow('draw', img) cv2.waitKey(0) cv2.destroyAllWindows()
5、绘制和填充多边形
polylines()
:绘制多边形
cv2.polylines(img, pts, isClosed, color, thickness, lineType, shift)
参数说明:
- img:在哪个图像上绘制和填充多边形
- pts:多边形的点集,必须是int32位
- isClosed:是否闭合
- color:颜色
- thickness:线宽
- lineType:线型
- shift:坐标缩放比例
import cv2 import numpy as np img = np.zeros((480, 640, 3), np.uint8) pts = np.array([(300, 10), (150, 100), (450, 100)], np.int32) cv2.polylines(img, [pts], True, (0, 255, 255), 5, 16) cv2.imshow('draw', img) cv2.waitKey(0) cv2.destroyAllWindows()
fillPoly
:填充多边形
cv2.fillPoly(img, pts, color)
fillPoly用法 和 polylines用法 完全一致。
import cv2 import numpy as np img = np.zeros((480, 640, 3), np.uint8) pts = np.array([(300, 10), (150, 100), (450, 100)], np.int32) cv2.fillPoly(img, [pts], (0, 255, 255), 16) cv2.imshow('draw', img) cv2.waitKey(0) cv2.destroyAllWindows()
6、绘制文本及中文文本
putText()
用法:
cv2.putText(img, text, org, fontFace, fontScale, color, thickness, lineType, bottomLeftOrigin)
参数说明:
- img:在哪个图像上绘制文本
- text:文本内容
- org:文本在图像中的左下角坐标
- fontFace:字体类型即字体
- fontScale:字体大小
- color:颜色
- thickness:线宽
- lineType:线型
- bottomLeftOrigin:文字方向(默认为False),若为True,则文字翻转呈现。
import cv2 import numpy as np img = np.zeros((480, 640, 3), np.uint8) cv2.putText(img, 'Hello OpenCV', (25, 200), cv2.FONT_HERSHEY_COMPLEX, 2.5, (0, 0, 255)) cv2.imshow('draw', img) cv2.waitKey(0) cv2.destroyAllWindows()
若使用其绘制中文文本时:
cv2.putText(img, '你好啊,计算机视觉', (25, 200), cv2.FONT_HERSHEY_COMPLEX, 2.5, (0, 0, 255))
OpenCV没有办法直接绘制中文,会出现乱码情况!但是可以使用 Pillow 包,代码如下所示:
import cv2 import numpy as np from PIL import ImageFont, ImageDraw, Image # 纯红 img = np.full((480, 640, 3), fill_value=[0, 0, 255], dtype=np.uint8) # 导入字体文件 font = ImageFont.truetype('../resource/msyhbd.ttc', 40) # 创建一个Pillow图片 img_pil = Image.fromarray(img) draw = ImageDraw.Draw(img_pil) # 利用draw去绘制中文 draw.text((10, 150), '你好,OpenCV(计算机视觉)!', font=font, fill=(0, 255, 0, 0)) # 重新变回ndarray img = np.array(img_pil) cv2.imshow('img', img) cv2.waitKey(0) cv2.destroyAllWindows()
7、鼠标绘制基本图形
主要功能: 可以通过鼠标进行基本图形的绘制
- 画直线:当用户按下
l
键,此时鼠标即可画直线 - 画矩形:当用户按下
r
键,此时鼠标即可画矩形 - 画圆:当用户按下
c
键,此时鼠标即可画圆
import cv2 import numpy as np # current_shape: 0-line直线, 1-rectangle矩形, 2-circle圆 current_shape = 0 # start_position:鼠标的坐标 start_position = (0, 0) # 显示窗口和背景 img = np.zeros((480, 640, 3), np.uint8) # 鼠标回调函数 def mouse_callback(event, x, y, flags, userdata): global current_shape, start_position # 全局变量的声明 if event == cv2.EVENT_LBUTTONDOWN: start_position = (x, y) # 每次按下鼠标左键都会获得一个值 elif event == cv2.EVENT_LBUTTONUP: if current_shape == 0: cv2.line(img, start_position, (x, y), (0, 0, 255), 3) elif current_shape == 1: cv2.rectangle(img, start_position, (x, y), (0, 0, 255), 3) elif current_shape == 2: a = (x - start_position[0]) b = (y - start_position[1]) r = int((a ** 2 + b ** 2) ** 0.5) # 计算圆的半径 cv2.circle(img, start_position, r, (0, 0, 255), 3) else: print('error:no shape') # 创建窗口 cv2.namedWindow('draw', cv2.WINDOW_NORMAL) # 设置鼠标回调 cv2.setMouseCallback('draw', mouse_callback) while True: cv2.imshow('draw', img) key = cv2.waitKey(1) & 0xFF if key == ord('q'): break elif key == ord('l'): current_shape = 0 # line直线 elif key == ord('r'): current_shape = 1 # rectangle矩形 elif key == ord('c'): current_shape = 2 # circle圆 cv2.destroyAllWindows()