opencv 提供了对图像、视频、绘图的基本操作。主要包括图像的加载、存储,视频的读取以及存储,以及一些绘图函数。
pip install opencv-python==4.5.5.64 -i https://pypi.tuna.tsinghua.edu.cn/simple
import cv2 import matplotlib.pyplot as plt import torch import numpy as np from PIL import Image, ImageDraw, ImageFont
1. 图像
opencv 读取的图像为 BGR,并不是 RGB,这个和 PIL 图像是不同。当使用 matplotlib.pyplot.imshow 函数显示由 cv 打开的图像时,需要先将 BGR 转换成 RGB。
另外,读取图像时,需要指定以彩色模式读取,还是灰色模式读取。彩色模式具有 3 通道,灰色图则只有 1 通道,读取的图像像素值范围 [0, 255]
def test01(): # 读取图像 # cv2.IMREAD_COLOR 以彩色图模式读取 # cv2.IMREAD_GRAYSCALE 以灰度图模式读取 img1 = cv2.imread('demo.png', cv2.IMREAD_COLOR) img2 = cv2.imread('demo.png', cv2.IMREAD_GRAYSCALE) # cv2 读取图像通道是 BGR,转换为 RGB img1_rgb = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB) img2_rgb = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB) # 图像显示 plt.subplot(121) # 要求: (H,W,C) plt.imshow(img1_rgb) plt.subplot(122) plt.imshow(img2_rgb) plt.show() # 保存图像 cv2.imwrite('test1.png', img1) cv2.imwrite('test2.png', img2)
2. 视频
opencv 也提供了逐帧读取视频的操作,视频来源主要为摄像头或者本地视频文件。我们显示视频文件,只需要逐帧读取图像,将其显示到指定窗口内即可。
摄像头视频:
def test02(): # 打开摄像头 camera = cv2.VideoCapture(0) while True: # status 表示读取是否成功 # frame 表示读取到的帧图像 status, frame = camera.read() # 将图像从 BGR 转换为 RGB frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # 向 frame 窗口绘制帧图像 cv2.imshow('frame', frame) # 退出按钮 if cv2.waitKey(1) & 0xFF == ord('q'): break # 释放设备资源 camera.release() cv2.destroyAllWindows()
视频文件:
def test03(): # 打开文件 video = cv2.VideoCapture('demo.mp4') # 视频熟悉 video_w = int(video.get(cv2.CAP_PROP_FRAME_WIDTH)) video_h = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)) video_fps = video.get(cv2.CAP_PROP_FPS) video_cnt = video.get(cv2.CAP_PROP_FRAME_COUNT) # fourcc: Four-Character Codes, 用来确定视频的编码格式 # cv2.VideoWriter_fourcc(‘I’,’4’,’2’,’0’),该参数是 YUV 编码类型,文件名后缀为.avi # cv2.VideoWriter_fourcc(‘P’,’I’,’M’,’I’),该参数是 MPEG-1 编码类型,文件名后缀为.avi # cv2.VideoWriter_fourcc(‘X’,’V’,’I’,’D’),该参数是 MPEG-4 编码类型,文件名后缀为.avi # cv2.VideoWriter_fourcc(‘T’,’H’,’E’,’O’),该参数是 Ogg Vorbis,文件名后缀为.ogv # cv2.VideoWriter_fourcc(‘F’,’L’,’V’,1),该参数是 Flash 视频,文件名后缀为.flv fourcc = cv2.VideoWriter_fourcc(*'XVID') # 输出图像大小要和读取大小一致,否则写入失败 video_writer = cv2.VideoWriter('demo.avi', fourcc, video_fps, (video_w, video_h)) while True: # status 表示读取是否成功 # frame 表示读取到的帧图像 status, frame = video.read() # status 为 False 表示读取完毕 if not status: break # 将图像从 BGR 转换为 RGB frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # 显示图像 cv2.imshow('frame', frame) # 保存视频 frame = cv2.flip(frame, 0) video_writer.write(frame) # 退出按钮 if cv2.waitKey(25) & 0xFF == ord('q'): break # 释放设备资源 video.release() video_writer.release() cv2.destroyAllWindows()
3. 绘图
绘图方法相对都比较简单,直接看示例代码即可。
def test04(): # 创建画布 cavas = np.zeros((512, 512, 3), np.uint8) # 绘制直线 start = (20, 20) # 起始点 end = (300, 300) # 终点 color = (255, 255, 0) # 颜色 thick = 5 # 粗细 cv2.line(cavas, start, end, color, thick) # 绘制矩形 start = (100, 100) # 起始点 end = (400, 400) # 终点 color = (255, 150, 0) # 颜色 thick = 5 # 线条粗细 cv2.rectangle(cavas, start, end, color, thick) # 绘制圆形 center = (250, 250) # 圆心 radius = 100 # 半径 color = (255, 150, 0) # 颜色 thick = -1 # -1 表示填充 cv2.circle(cavas, center, radius, color, thick) # 多边形 lines = np.array([(510, 450), (120, 90), (300, 250), (10, 500)]).astype(np.int32) close = True # 是否闭合 color = (0, 0, 255) # 颜色 thick = 5 # 线条粗细 cv2.polylines(cavas, [lines], close, color, thick) # 绘制文字 # 1. 不支持中文 # font = cv2.FONT_HERSHEY_SIMPLEX # cv2.putText(cavas, 'hello', (100,200), font, 2, color, 2) # 2. 使用 PIL 绘制 cavas = cv2.cvtColor(cavas, cv2.COLOR_BGR2RGB) cavas = Image.fromarray(cavas) pen = ImageDraw.Draw(cavas) font = ImageFont.truetype('SimHei.ttf', size=30, encoding='utf-8') pen.text((250,250), '中国', color=(255, 255, 0), font=font) print(cavas) cavas = cv2.cvtColor(np.asarray(cavas), cv2.COLOR_BGR2RGB) # 显示图像 cv2.imshow('cavas', cavas) cv2.waitKey(0)