第十二篇【传奇开心果系列】Python的OpenCV技术点案例示例:视频流处理
传奇开心果短博文系列
- 系列短博文目录
- Python的OpenCV技术点案例示例短博文系列
- 短博文目录
- 一、前言
- 二、视频流处理介绍
- 三、实时视频流处理示例代码
- 四、视频流分析示例代码
- 五、归纳总结
系列短博文目录
Python的OpenCV技术点案例示例短博文系列
短博文目录
一、前言
OpenCV视频流处理介绍:包括实时视频流处理、视频流分析等功能。OpenCV提供了丰富的功能和工具来进行视频流处理和分析。
二、视频流处理介绍
下面是关于实时视频流处理和视频流分析的分别介绍:
-
实时视频流处理:
-视频捕捉:OpenCV可以直接从摄像头或其他视频源中捕捉实时视频流。
-视频显示:可以将捕捉到的实时视频流显示在窗口中,以便实时查看。
-视频写入:可以将处理后的视频流保存为视频文件。
-
视频流分析:
-视频帧处理:可以逐帧对视频进行处理,例如图像滤波、边缘检测等。
-目标检测与跟踪:可以使用机器学习和深度学习算法来检测和跟踪视频中的目标,如人脸识别、目标检测等。
-运动检测:可以通过比较连续帧之间的差异来检测视频中的运动物体。
-视频编解码:可以对视频进行编码和解码,以减小文件大小或实现特定的视频格式要求。
-光流估计:可以分析视频序列中物体的运动情况,如物体的速度和方向等。
通过结合OpenCV的图像处理、机器学习和深度学习功能,可以实现更复杂的视频流处理和分析任务,如实时人脸识别、行为分析、视频内容理解等。OpenCV提供了丰富的函数和算法库,使得视频流处理变得更加简单和高效。
三、实时视频流处理示例代码
- 视频捕捉示例代码
以下是使用OpenCV进行视频捕捉的示例代码:
import cv2
# 打开摄像头
cap = cv2.VideoCapture(0)
while True:
# 逐帧捕捉视频
ret, frame = cap.read()
# 在窗口中显示视频帧
2.imshow('Video Capture', frame)
# 按下 'q' 键退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放摄像头资源
cap.release()
# 关闭窗口
cv2.destroyAllWindows()
在这个示例中,我们首先使用cv2.VideoCapture
函数打开摄像头。参数0
表示使用默认的摄像头设备,如果有多个摄像头,可以根据需要选择对应的设备。
然后,我们进入一个循环,使用cap.read()
逐帧捕捉视频。函数返回值ret
表示捕捉是否成功,frame
是捕捉到的视频帧。
接着,我们使用cv2.imshow()
在窗口中显示捕捉到的视频帧。第一个参数是窗口的名称,第二个参数是要显示的图像。
在循环中,我们还检查按键事件,如果按下了键盘上的 ‘q’ 键,就退出循环。
最后,我们释放摄像头资源,使用cap.release()
函数,关闭窗口,使用cv2.destroyAllWindows()
函数。
通过这段代码,你可以实时捕捉到摄像头的视频流,并在窗口中显示出来。你可以根据需要对每一帧进行处理,如图像滤波、目标检测等。
- 视频显示示例代码
以下是使用OpenCV进行视频显示的示例代码:
import cv2
# 打开视频文件
cap = cv2.VideoCapture('video.mp4')
while cap.isOpened():
# 逐帧读取视频
ret, frame = cap.read()
# 如果视频读取成功
if ret:
# 在窗口中显示视频帧
cv2.imshow('Video Display', frame)
# 按下 'q' 键退出循环
if cv2.waitKey(25) & 0xFF == ord('q'):
break
else:
break
# 释放视频资源
cap.release()
# 关闭窗口
cv2.destroyAllWindows()
在这个示例中,我们首先使用cv2.VideoCapture
函数打开视频文件。参数可以是视频文件的路径,也可以是摄像头设备的索引。
然后,我们进入一个循环,使用cap.read()
逐帧读取视频。函数返回值ret
表示读取是否成功,frame
是读取到的视频帧。
接着,我们使用cv2.imshow()
在窗口中显示读取到的视频帧。第一个参数是窗口的名称,第二个参数是要显示的图像。
在循环中,我们还检查按键事件,如果按下了键盘上的 ‘q’ 键,就退出循环。
最后,我们释放视频资源,使用cap.release()
函数,关闭窗口,使用cv2.destroyAllWindows()
函数。
通过这段代码,你可以打开并显示视频文件,逐帧播放视频内容。你可以根据需要对每一帧进行处理,如图像滤波、目标检测等。
- 视频写入示例代码
以下是使用OpenCV进行视频写入的示例代码:
import cv2
# 获取视频源
cap = cv2.VideoCapture(0)
# 获取视频的宽度和高度
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 创建视频写入对象
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (width, height))
while cap.isOpened():
# 逐帧读取视频
ret, frame = cap.read()
if ret:
# 在窗口中显示视频帧
cv2.imshow('Video Capture', frame)
# 将视频帧写入视频文件
out.write(frame)
# 按下 'q' 键退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
# 释放资源
cap.release()
out.release()
# 关闭窗口
cv2.destroyAllWindows()
在这个示例中,我们首先使用cv2.VideoCapture
函数获取视频源。参数可以是视频文件的路径,也可以是摄像头设备的索引。
然后,我们使用cap.get()
方法获取视频的宽度和高度,以便后续创建视频写入对象。
接着,我们使用cv2.VideoWriter
创建视频写入对象。参数'output.avi'
表示输出视频文件的名称,fourcc
表示视频编码格式,20.0
表示帧率,(width, height)
表示视频的宽度和高度。
在循环中,我们使用cap.read()
逐帧读取视频。如果读取成功,我们将视频帧显示在窗口中,然后使用out.write()
将视频帧写入视频文件。
同时,我们还检查按键事件,如果按下了键盘上的 ‘q’ 键,就退出循环。
最后,我们释放资源,包括视频源和视频写入对象,使用cap.release()
和out.release()
函数,关闭窗口,使用cv2.destroyAllWindows()
函数。
通过这段代码,你可以从摄像头捕捉实时视频,并将视频帧写入到指定的视频文件中。你可以根据需要进行视频处理和分析,然后将处理后的视频保存下来。
四、视频流分析示例代码
- 视频帧处理示例代码
以下是使用OpenCV对视频帧进行处理的示例代码:
import cv2
# 打开视频文件
cap = cv2.VideoCapture('video.mp4')
while cap.isOpened():
# 逐帧读取视频
ret, frame = cap.read()
# 如果视频读取成功
if ret:
# 在窗口中显示原始视频帧
cv2.imshow('Original Frame', frame)
# 进行视频帧处理,例如图像滤波、边缘检测等
processed_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 在窗口中显示处理后的视频帧
cv2.imshow('Processed Frame', processed_frame)
# 按下 'q' 键退出循环
if cv2.waitKey(25) & 0xFF == ord('q'):
break
else:
break
# 释放视频资源
cap.release()
# 关闭窗口
cv2.destroyAllWindows()
在这个示例中,我们首先使用cv2.VideoCapture
函数打开视频文件。
然后,我们进入一个循环,使用cap.read()
逐帧读取视频。函数返回值ret
表示读取是否成功,frame
是读取到的视频帧。
接着,我们可以在窗口中显示原始视频帧,使用cv2.imshow('Original Frame', frame)
。
然后,我们进行视频帧处理,例如将彩色帧转换为灰度帧,使用cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
。
最后,我们可以在窗口中显示处理后的视频帧,使用cv2.imshow('Processed Frame', processed_frame)
。
在循环中,我们还检查按键事件,如果按下了键盘上的 ‘q’ 键,就退出循环。
最后,我们释放视频资源,使用cap.release()
函数,关闭窗口,使用cv2.destroyAllWindows()
函数。
通过这段代码,你可以打开并读取视频文件的每一帧,并对每一帧进行处理,如图像滤波、边缘检测等。你可以根据需要进行各种图像处理操作,并在窗口中显示原始视频帧和处理后的视频帧。
- 目标检测与跟踪示例代码
以下是使用OpenCV进行目标检测和跟踪的示例代码:
import cv2
# 加载预训练的目标检测模型和跟踪器
net = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'res10_300x300_ssd_iter_140000.caffemodel')
tracker = cv2.TrackerCSRT_create()
# 打开摄像头
cap = cv2.VideoCapture(0)
# 选择要跟踪的目标
ret, frame = cap.read()
bbox = cv2.selectROI('Select Target', frame)
tracker.init(frame, bbox)
while True:
# 逐帧捕捉视频
ret, frame = cap.read()
if ret:
# 对当前帧进行目标检测
blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0))
net.setInput(blob)
detections = net.forward()
# 获取检测到的目标框
for i in range(detections.shape[2]):
confidence = detections[0, 0, i, 2]
if confidence > 0.5:
box = detections[0, 0, i, 3:7] * np.array([frame.shape[1], frame.shape[0], frame.shape[1], frame.shape[0]])
(startX, startY, endX, endY) = box.astype("int")
# 在图像中绘制目标框
cv2.rectangle(frame, (startX, startY), (endX, endY), (0, 255, 0), 2)
# 更新跟踪器
ret, bbox = tracker.update(frame)
if ret:
# 在图像中绘制跟踪框
(x, y, w, h) = [int(v) for v in bbox]
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 255), 2)
# 显示视频帧
cv2.imshow('Object Detection and Tracking', frame)
# 按下 'q' 键退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放摄像头资源
cap.release()
# 关闭窗口
cv2.destroyAllWindows()
在这个示例中,我们首先加载预训练的目标检测模型和跟踪器。net
使用了基于SSD的Caffe模型进行目标检测,tracker
使用了CSRT算法进行目标跟踪。你需要提前下载并指定相应的模型文件。
然后,我们打开摄像头,并选择要跟踪的目标。通过cv2.selectROI
函数在窗口中选择一个感兴趣的区域作为目标框,并使用tracker.init
方法初始化跟踪器。
接着,我们进入一个循环,逐帧捕捉视频。对于每一帧,我们首先使用目标检测模型对当前帧进行目标检测,得到检测到的目标框。然后,我们在图像中绘制检测到的目标框。
接着,我们使用跟踪器对目标进行跟踪。tracker.update
方法会更新目标框的位置,并返回一个布尔值表示是否成功跟踪。
最后,我们在图像中绘制跟踪框,并显示视频帧。同时,我们还检查按键事件,如果按下了键盘上的 ‘q’ 键,就退出循环。
最后,我们释放摄像头资源,使用cap.release()
函数,关闭窗口,使用cv2.destroyAllWindows()
函数。
通过这段代码,你可以打开摄像头并实时进行目标检测和跟踪,将检测到的目标框和跟踪框绘制在视频帧中,实现目标的实时跟踪。
- 运动检测示例代码
以下是使用OpenCV进行运动检测的示例代码:
import cv2
# 打开摄像头
cap = cv2.VideoCapture(0)
# 读取第一帧作为背景帧
ret, background = cap.read()
background_gray = cv2.cvtColor(background, cv2.COLOR_BGR2GRAY)
background_gray = cv2.GaussianBlur(background_gray, (21, 21), 0)
while True:
# 逐帧捕捉视频
ret, frame = cap.read()
if ret:
# 将当前帧转换为灰度图像
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray_frame = cv2.GaussianBlur(gray_frame, (21, 21), 0)
# 计算当前帧与背景帧的差异
frame_delta = cv2.absdiff(background_gray, gray_frame)
threshold = cv2.threshold(frame_delta, 30, 255, cv2.THRESH_BINARY)[1]
# 对阈值图像进行轮廓检测
contours, _ = cv2.findContours(threshold.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 绘制检测到的运动目标框
for contour in contours:
if cv2.contourArea(contour) > 1000:
(x, y, w, h) = cv2.boundingRect(contour)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 显示视频帧
cv2.imshow('Motion Detection', frame)
# 按下 'q' 键退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放摄像头资源
cap.release()
# 关闭窗口
cv2.destroyAllWindows()
在这个示例中,我们首先打开摄像头。
然后,我们读取第一帧作为背景帧,并将其转换为灰度图像。通过使用高斯模糊cv2.GaussianBlur
来减少噪声对后续运动检测的影响。
接着,我们进入一个循环,逐帧捕捉视频。对于每一帧,我们将其转换为灰度图像,并进行高斯模糊处理。
然后,我们计算当前帧与背景帧之间的差异,通过cv2.absdiff
函数得到差值图像。然后,使用阈值处理cv2.threshold
将差值图像转换为二值图像。
接着,我们使用轮廓检测cv2.findContours
对阈值图像进行运动目标的检测。通过设置面积阈值来过滤掉较小的轮廓。
最后,我们在原始视频帧中绘制检测到的运动目标框,并显示视频帧。同时,我们还检查按键事件,如果按下了键盘上的 ‘q’ 键,就退出循环。
最后,我们释放摄像头资源,使用cap.release()
函数,关闭窗口,使用cv2.destroyAllWindows()
函数。
通过这段代码,你可以打开摄像头并实时进行运动检测,将检测到的运动目标框绘制在视频帧中,实现对运动目标的实时检测。
- 视频编解码示例代码
以下是使用OpenCV进行视频编解码的示例代码:
视频编码示例代码:
import cv2
# 打开摄头
cap = cv2.VideoCapture(0)
# 获取摄像头的宽度和高度
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 创建视频编码器
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (width, height))
while True:
# 逐帧捕捉视频
ret, frame = cap.read()
if ret:
# 将视频帧写入视频文件
out.write(frame)
# 显示视频帧
cv2.imshow('Video Encoding', frame)
# 按下 'q' 键退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放资源
cap.release()
out.release()
# 关闭窗口
cv2.destroyAllWindows()
视频解码示例代码:
import cv2
# 打开视频文件
cap = cv2.VideoCapture('video.mp4')
while True:
# 逐帧读取视频
ret, frame = cap.read()
if ret:
# 显示视频帧
cv2.imshow('Video Decoding', frame)
# 按下 'q' 键退出循环
if cv2.waitKey(25) & 0xFF == ord('q'):
break
else:
break
# 释放资源
cap.release()
# 关闭窗口
cv2.destroyAllWindows()
视频编码示例代码中,我们首先打开摄像头。
然后,我们获取摄像头的宽度和高度,以便后续创建视频编码器。
接着,我们进入一个循环,逐帧捕捉视频。对于每一帧,我们将其写入到视频文件中,使用out.write(frame)
。
同时,我们显示视频帧,使用cv2.imshow('Video Encoding', frame)
。
在循环中,我们还检查按键事件,如果按下了键盘上的 ‘q’ 键,就退出循环。
最后,我们释放资源,包括摄像头和视频编码器,使用cap.release()
和out.release()
函数,关闭窗口,使用cv2.destroyAllWindows()
函数。
通过这段代码,你可以打开摄像头并实时进行视频编码,将视频帧写入到指定的视频文件中。
视频解码示例代码中,我们首先打开视频文件。
然后,我们进入一个循环,逐帧读取视频。对于每一帧,我们显示视频帧,使用cv2.imshow('Video Decoding', frame)
。
在循环中,我们还检查按键事件,如果按下了键盘上的 ‘q’ 键,就退出循环。
最后,我们释放资源,包括视频文件,使用cap.release()
函数,关闭窗口,使用cv2.destroyAllWindows()
函数。
通过这段代码,你可以打开视频文件并逐帧读取视频,实现视频的解码和播放。
- 光流估计示例代码
以下是使用OpenCV进行光流估计的示例代码:
import cv2
# 打开视频文件
cap = cv2.VideoCapture('video.mp4')
# 创建Lucas-Kanade光流算法对象
lk_params = dict(winSize=(15, 15), maxLevel=2, criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
# 读取第一帧
ret, old_frame = cap.read()
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)
# 创建用于绘制光流的颜色
color = (0, 255, 0)
while True:
# 逐帧读取视频
ret, frame = cap.read()
if ret:
# 将当前帧转换为灰度图像
frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 计算光流
p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, None, None, **lk_params)
# 选择良好的跟踪点
good_new = p1[st == 1]
good_old = p0[st == 1]
# 绘制光流轨迹
for i, (new, old) in enumerate(zip(good_new, good_old)):
a, b = new.ravel()
c, d = old.ravel()
frame = cv2.line(frame, (a, b), (c, d), color, 2)
frame = cv2.circle(frame, (a, b), 3, color, -1)
# 更新上一帧的图像和追踪点
old_gray = frame_gray.copy()
p0 = good_new.reshape(-1, 1, 2)
# 显示视频帧
cv2.imshow('Optical Flow', frame)
# 按下 'q' 键退出循环
if cv2.waitKey(25) & 0xFF == ord('q'):
break
else:
break
# 释放资源
cap.release()
# 关闭窗口
cv2.destroyAllWindows()
在这个示例中,我们首先打开视频文件。
然后,我们创建Lucas-Kanade光流算法对象,并设置相关参数。
接着,我们读取第一帧,并将其转换为灰度图像。
进入一个循环,逐帧读取视频。对于每一帧,我们将其转换为灰度图像。
然后,使用cv2.calcOpticalFlowPyrLK
函数计算光流,得到新的跟踪点和状态。
接着,我们选择良好的跟踪点,通过筛选状态为1的跟踪点。
然后,我们绘制光流轨迹,在当前帧上绘制线条和圆点。
最后,我们更新上一帧的图像和跟踪点,将当前帧的灰度图像赋值给上一帧的灰度图像,并更新跟踪点。
同时,我们显示视频帧,使用cv2.imshow('Optical Flow', frame)
。
在循环中,我们还检查按键事件,如果按下了键盘上的 ‘q’ 键,就退出循环。
最后,我们释放资源,包括视频文件,使用cap.release()
函数,关闭窗口,使用cv2.destroyAllWindows()
函数。
通过这段代码,你可以打开视频文件并逐帧读取视频,实现光流估计,并在视频帧上绘制光流轨迹。
五、归纳总结
OpenCV是一个强大的计算机视觉库,提供了丰富的功能和工具来处理视频流。下面是关于OpenCV视频流处理的归纳总结:
-
打开视频流:使用
cv2.VideoCapture
函数可以打开本地视频文件或者摄像头设备,获取视频流。 -
读取视频帧:使用
cap.read()
函数逐帧读取视频流,返回布尔值和当前帧图像。 -
显示视频帧:使用
cv2.imshow
函数可以在窗口中显示视频帧。 -
保存视频帧:使用
cv2.VideoWriter
可以创建一个视频编写器,将视频帧写入到视频文件中。 -
视频编解码:通过指定视频编解码器(如XVID)和帧率,可以将视频帧编码为视频文件或从视频文件解码为视频帧。
-
图像处理:对每一帧进行图像处理操作,如图像滤波、边缘检测、图像转换等。
-
目标检测与跟踪:使用预训练的目标检测模型和跟踪算法,对视频帧中的目标进行检测和跟踪,并在图像上绘制目标框。
-
运动检测:通过计算帧间差异或光流估计,检测视频帧中的运动目标,并在图像上绘制运动目标框。
-
光流估计:使用Lucas-Kanade光流算法或其他光流估计算法,计算视频帧中的像素位移,并在图像上绘制光流轨迹。
-
视频分割:使用背景建模或基于像素相似度的方法,将视频帧分割为前景和背景,并实现视频分割效果。
-
视频流处理:可以对视频流进行实时处理,如实时显示、实时图像处理、实时目标检测与跟踪等。
-
释放资源:在处理完视频流后,需要释放相关资源,如关闭视频文件或释放摄像头资源。
通过上述功能和工具,OpenCV提供了丰富的视频流处理功能,可以实现各种视频处理任务,如视频分析、目标跟踪、运动检测、光流估计等。使用OpenCV,你可以轻松处理视频流并实现自己的计算机视觉应用。