目录
1.导入库
首先需要导入库,代码如下:
import cv2
import numpy as np
2.读入视频
导完库后就用如下代码读入视频:
cor_x, cor_y = -1, -1
camera = cv2.VideoCapture('cat_Trim.mp4') # 从文件读取视频,只需要修改成自己的视频路径即可进行测试
cor = np.array([[1, 1]]) # 初始值并无意义,只是为了能够使用np.row_stack函数
3.获取视频的帧率
fps = camera.get(cv2.CAP_PROP_FPS) # 获取视频帧率
print('视频帧率:%d fps' % fps)
4.用鼠标截取感兴趣区域
def MouseAction(event, x, y, flags, param):
# 创建回调函数 (event:指触发的阶跃信号,比如鼠标左键按下, x, y:指鼠标的实时坐标, flags:鼠标的保持信号,如鼠标保持按下
# param自己需要使用的参数状态
global cor_x, cor_y, cor # 将变量变为全局变量,使之在函数外也能用
if event == cv2.EVENT_LBUTTONDOWN:
cor_x, cor_y = x, y # 将鼠标点击的x,y坐标赋予全局变量cor_x, cor_y
cor_m = [cor_x, cor_y]
cor = np.row_stack((cor, cor_m)) # 将鼠标点击的x,y坐标进行矩阵合并,并赋予全局变量
elif event == cv2.EVENT_LBUTTONUP:
cv2.line(img, (cor_x, cor_y), (cor_x, cor_y), (255, 255, 0), 7)
# 当鼠标左键由按下变松开时在原地划线 从左到右分别是 (读入的图片, 开始坐标, 结束坐标, 颜色(b, g, r), 线条粗细)
5.逐帧采集视频并显示一帧图片来选择roi区域
grabbed, img = camera.read() # 逐帧采集视频流
img = cv2.resize(img, (1280, 720))
def cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=30):
if (isinstance(img, np.ndarray)): # 判断是否OpenCV图片类型
img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# 创建一个可以在给定图像上绘图的对象
draw = ImageDraw.Draw(img)
# 字体的格式
fontStyle = ImageFont.truetype(
"simsun.ttc", textSize, encoding="utf-8")
# 绘制文本
draw.text(position, text, textColor, font=fontStyle)
# 转换回OpenCV格式
return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
img = cv2AddChineseText(img, "利用鼠标点击 左上,右下的顺序来框出整个红绿灯区域和黄灯灯芯区域", [20, 20], (255, 255, 0), 30)
cv2.namedWindow('Traffic light')
cv2.setMouseCallback('Traffic light', MouseAction) # 将回调函数与opencv绑定
# 显示视频画面,并在视频中选取整个红绿灯区域和黄灯区域
while True:
cv2.imshow("Traffic light", img)
k = cv2.waitKey(1) & 0xFF
if k == ord(' '): # 空格退出操作
break
cv2.destroyAllWindows() # 关闭页面
全部代码
import cv2
import numpy as np
import time
from PIL import Image, ImageDraw, ImageFont
cor_x, cor_y = -1, -1
camera = cv2.VideoCapture('cat_Trim.mp4') # 从文件读取视频,只需要修改成自己的视频路径即可进行测试
cor = np.array([[1, 1]]) # 初始值并无意义,只是为了能够使用np.row_stack函数
def MouseAction(event, x, y, flags, param):
# 创建回调函数 (event:指触发的阶跃信号,比如鼠标左键按下, x, y:指鼠标的实时坐标, flags:鼠标的保持信号,如鼠标保持按下
# param自己需要使用的参数状态
global cor_x, cor_y, cor # 将变量变为全局变量,使之在函数外也能用
if event == cv2.EVENT_LBUTTONDOWN:
cor_x, cor_y = x, y # 将鼠标点击的x,y坐标赋予全局变量cor_x, cor_y
cor_m = [cor_x, cor_y]
cor = np.row_stack((cor, cor_m)) # 将鼠标点击的x,y坐标进行矩阵合并,并赋予全局变量
elif event == cv2.EVENT_LBUTTONUP:
cv2.line(img, (cor_x, cor_y), (cor_x, cor_y), (255, 255, 0), 7)
# 当鼠标左键由按下变松开时在原地划线 从左到右分别是 (读入的图片, 开始坐标, 结束坐标, 颜色(b, g, r), 线条粗细)
grabbed, img = camera.read() # 逐帧采集视频流
img = cv2.resize(img, (1280, 720))
def cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=30):
if (isinstance(img, np.ndarray)): # 判断是否OpenCV图片类型
img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# 创建一个可以在给定图像上绘图的对象
draw = ImageDraw.Draw(img)
# 字体的格式
fontStyle = ImageFont.truetype(
"simsun.ttc", textSize, encoding="utf-8")
# 绘制文本
draw.text(position, text, textColor, font=fontStyle)
# 转换回OpenCV格式
return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
img = cv2AddChineseText(img, "利用鼠标点击 左上,右下的顺序来框出整个红绿灯区域和黄灯灯芯区域", [20, 20], (255, 255, 0), 30)
cv2.namedWindow('Traffic light')
cv2.setMouseCallback('Traffic light', MouseAction) # 将回调函数与opencv绑定
# 显示视频画面,并在视频中选取整个红绿灯区域和黄灯区域
while True:
cv2.imshow("Traffic light", img)
k = cv2.waitKey(1) & 0xFF
if k == ord(' '): # 空格退出操作
break
cv2.destroyAllWindows() # 关闭页面
while True:
grabbed, frame = camera.read() # 逐帧采集视频流
if not grabbed:
break
frame = cv2.resize(frame, (1280, 720))
frame_data = np.array(frame) # 每一帧循环存入数组
box_data = frame_data[cor[1, 1]:cor[2, 1], cor[1, 0]:cor[2, 0]] # 取矩形目标区域
yellow_box = frame_data[cor[3, 1]:cor[4, 1], cor[3, 0]:cor[4, 0]]
yellow_max = np.max(yellow_box)
b, g, r = cv2.split(box_data) # 将截取的区域分割为b,g,r单通道颜色图片
max_g = np.max(g)
max_r = np.max(r)
if yellow_max >= 245: # 判断黄灯区域中发光值最大的像素点是不是大于245
choose_box = cv2.rectangle(frame, tuple(cor[1, :]), tuple(cor[2, :]), (0, 255, 255), 2)
cv2.putText(frame, "yellow", (cor[1, 0], cor[1, 1]), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 255, 255),
2) # 显示yellow文本信息
elif max_g >= 245:
choose_box = cv2.rectangle(frame, tuple(cor[1, :]), tuple(cor[2, :]), (0, 255, 0), 2)
cv2.putText(frame, "green", (cor[1, 0], cor[1, 1]), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 255, 0), 2) # 显示green文本信息
elif max_r >= 245:
choose_box = cv2.rectangle(frame, tuple(cor[1, :]), tuple(cor[2, :]), (0, 0, 255), 2)
cv2.putText(frame, "red", (cor[1, 0], cor[1, 1]), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 255), 2) # 显示red文本信息
time.sleep(0.141)
cv2.imshow('video', frame) # 显示采集到的视频流
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
camera.release()
cv2.destroyAllWindows()
效果展示