要求:
视频帧满足R(x,y)>𝐺(𝑥,𝑦)>𝐵(𝑥,𝑦)、R(x,y)>190,𝐺(𝑥,𝑦)>100、𝐵(𝑥,𝑦)<140、Y(x,y)≥Cr(x,y)、𝐶𝑟(x,y)≥Cb(x,y)、Y(x,y)>𝑌通道均值、Cr(x,y)>𝐶𝑟通道均值、Cb(x,y)<𝐶𝑏通道均值条件且满足利用帧差法的动态规则条件的为1,把满足条件的区域用红色的方框给框出来,并给出“有火情”的警告,其他的为0给出“无火情”的警告,展示处理后的视频,读出来处理后视频的所有帧,并保存下来
import cv2
import numpy as np
# 初始化 prev_frame 变量
prev_frame = np.array([])
# 读取视频文件
cap = cv2.VideoCapture('video.mp4')
# 获取视频的帧率
fps = int(cap.get(cv2.CAP_PROP_FPS))
# 获取视频的宽和高
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 打开视频文件的输出流
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('output.mp4', fourcc, fps, (width, height))
while(cap.isOpened()):
# 读取一帧视频
ret, frame = cap.read()
if ret:
# 提取 R、G 和 B 通道
R = frame[:,:,2]
G = frame[:,:,1]
B = frame[:,:,0]
# 进行颜色阈值筛选
mask = (R>G) & (R>190) & (G>100) & (B<140)
# 转换为 YCrCb 颜色空间
YCrCb = cv2.cvtColor(frame, cv2.COLOR_BGR2YCrCb)
Y = YCrCb[:,:,0]
Cr = YCrCb[:,:,1]
Cb = YCrCb[:,:,2]
# 计算通道均值
mean_Y = np.mean(Y)
mean_Cr = np.mean(Cr)
mean_Cb = np.mean(Cb)
# 判断条件是否满足
mask = mask & (Y>=Cr) & (Cr>=Cb) & (Y>mean_Y) & (Cr>mean_Cr) & (Cb<mean_Cb)
# 进行帧差处理
if len(prev_frame) != 0:
diff = cv2.absdiff(frame, prev_frame)
gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5,5), 0)
_, thresh = cv2.threshold(blur, 20, 255, cv2.THRESH_BINARY)
# 判断帧差结果是否满足条件
mask = mask & (thresh==255)
# 找到符合条件的像素坐标范围
coords = np.where(mask==True)
top = np.min(coords[0])
bottom = np.max(coords[0])
left = np.min(coords[1])
right = np.max(coords[1])
# 如果有符合条件的像素,则画框并标注
if np.sum(mask) > 0:
# 画出符合条件的矩形框和标注
cv2.rectangle(frame, (left, top), (right, bottom), color=(0, 0, 255), thickness=2)
cv2.putText(frame, "Y", (50,50), cv2.FONT_HERSHEY_SIMPLEX, 2, (0,0,255), 2)
else:
cv2.putText(frame, "N", (50,50), cv2.FONT_HERSHEY_SIMPLEX, 2, (0,255,0), 2)
# 展示处理后的视频
cv2.imshow('frame', frame)
# 写入处理后的视频到输出流
out.write(frame)
# 按下 q 键结束循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 保存当前帧作为下一帧的前一帧
prev_frame = frame.copy()
else:
break
# 释放资源
cap.release()
out.release()
cv2.destroyAllWindows()
程序中对帧差结果的判断条件是:
1.必须是帧差图中像素值为255的区域才能进行后续处理;
2.颜色阈值筛选、颜色空间转换后的二值化图像以及帧差图中的像素值同时为255的区域才会被认为是 有火情的像素。
也就是说,在颜色筛选和帧差处理后,只有同时被二者判定为符合条件的像素点才会被认为是有火情的像素,在这些像素点组成的边框中标出火情。
检测效果: