之所以写这篇博客,主要还是想介绍一下fourcc编码
1 读取摄像头
1.1 正常读取一个摄像头
1、读取摄像头
import cv2
cap = cv2.VideoCapture(0)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
print("Opening the camera failed!")
cv2.imshow("frame", frame)
key = cv2.waitKey(1)
if key == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
1.2 获取摄像头属性和设置摄像头属性
opencv-python默认读取摄像头的分辨率为:640x480 ,下面我们将:
import cv2
cap = cv2.VideoCapture(0)
fps = cap.get(cv2.CAP_PROP_FPS)
print(f"camera fps: {fps}")
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
print(f"camera resolution: ({width}x{height})")
cap.set(3, 1280)
cap.set(4, 720)
width2 = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
height2 = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
print(f"camera resolution: ({width2}x{height2})")
while cap.isOpened():
ret, frame = cap.read()
if not ret:
print("Opening the camera failed!")
cv2.imshow("frame", frame)
key = cv2.waitKey(1)
if key == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
1.3 把摄像头流保存成视频
1、把摄像头流保存成mp4视频文件
import cv2
cap = cv2.VideoCapture(0)
fps = int(cap.get(cv2.CAP_PROP_FPS))
cap.set(3, 1280)
cap.set(4, 720)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
print(f"camera resolution: ({width}x{height})")
size = (int(width), int(height))
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
videowriter = cv2.VideoWriter()
videowriter.open("output.mp4", fourcc, fps, size, True)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
print("Opening the camera failed!")
videowriter.write(frame)
cv2.imshow("frame", frame)
key = cv2.waitKey(1)
if key == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
通过上面代码保存的视频,你会发现:
- 视频帧率是
fps=30 - 视频分辨率是
1280x720 ,就是720P的
2、保存的视频,如果你去播放一下会发现速度特别快,像是倍速播放一样,这是为什么呢?
我们先来计算读取一帧需要的大概时间:
import cv2
import time
cap = cv2.VideoCapture(0)
fps = int(cap.get(cv2.CAP_PROP_FPS))
cap.set(3, 1280)
cap.set(4, 720)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
print(f"camera resolution: ({width}x{height})")
size = (int(width), int(height))
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
videowriter = cv2.VideoWriter()
videowriter.open("output.mp4", fourcc, fps, size, True)
while cap.isOpened():
start = time.time()
ret, frame = cap.read()
if not ret:
print("Opening the camera failed!")
videowriter.write(frame)
cv2.imshow("frame", frame)
key = cv2.waitKey(1)
if key == ord("q"):
break
end = time.time()
print(f"Read a frame time: {(end-start)*1000:.3f}ms")
cap.release()
cv2.destroyAllWindows()
输出结果,大概读取一帧的时间是100ms ,按照这个时间,while循环 处理完一帧数据之后,就会循环下一帧数据,这个循环的速度大概相当于是100fps
Read a frame time: 99.573ms
Read a frame time: 100.382ms
Read a frame time: 99.949ms
Read a frame time: 100.631ms
Read a frame time: 98.024ms
Read a frame time: 101.144ms
Read a frame time: 100.274ms
Read a frame time: 100.390ms
因此,如果我们要把上面循环的速度也变成30fps,就需要控制一下循环的速度,因此只要在每帧读完之后睡眠一下,就可以大概控制帧率为30fps了 ,睡眠时间(参考):
s
l
e
e
p
_
t
i
m
e
=
1000
w
e
b
c
a
m
_
f
p
s
=
1000
m
s
30
f
p
s
sleep\_time = \frac{1000}{webcam\_fps}=\frac{1000ms}{30fps}
sleep_time=webcam_fps1000?=30fps1000ms?
此时,用下面的代码再保存一下视频看看效果吧:
import cv2
import time
cap = cv2.VideoCapture(0)
fps = cap.get(cv2.CAP_PROP_FPS)
cap.set(3, 1280)
cap.set(4, 720)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
print(f"camera resolution: ({width}x{height})")
size = (int(width), int(height))
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
videowriter = cv2.VideoWriter()
videowriter.open("output.mp4", fourcc, fps, size, True)
while cap.isOpened():
start = time.time()
ret, frame = cap.read()
if not ret:
print("Opening the camera failed!")
videowriter.write(frame)
cv2.imshow("frame", frame)
key = cv2.waitKey(1)
if key == ord("q"):
break
end = time.time()
print(f"Read a frame time: {(end-start)*1000:.3f}ms")
time.sleep(1/fps)
cap.release()
videowriter.release()
cv2.destroyAllWindows()
实际测试,即使我把睡眠时间调整到0.1s ,保存的视频播放依然很快,目前我不知道怎么解决了,如有知道如何解决,请留言,谢谢!
2 更多关于视频捕获属性 cv2.CAP_PROP
opencv 官网video I/O模块的doc
1、获取属性
2、设置属性
3、更多CAP_PROP属性介绍
视频捕获属性(VideoCaptureProperties )
参数 | 视频捕获属性(VideoCaptureProperties ) | 属性功能描述 |
---|
cv2.VideoCapture.get(0) | cv2.CAP_PROP_POS_MSEC = 0 | 视频文件的当前位置(播放)以毫秒为单位 | cv2.VideoCapture.get(1) | cv2.CAP_PROP_POS_FRAMES = 1 | 基于以0开始的被捕获或解码的帧索引 | cv2.VideoCapture.get(2) | cv2.CAP_PROP_POS_AVI_RATIO = 2 | 视频文件的相对位置(播放):0=电影开始,1=影片的结尾。 | cv2.VideoCapture.get(3) | cv2.CAP_PROP_FRAME_WIDTH = 3 | 在视频流的帧的宽度 | cv2.VideoCapture.get(4) | cv2.CAP_PROP_FRAME_HEIGHT = 4 | 在视频流的帧的高度 | cv2.VideoCapture.get(5) | cv2.CAP_PROP_FPS = 5 | 帧速率 | cv2.VideoCapture.get(6) | cv2.CAP_PROP_FOURCC = 6 | 编解码的4字-字符代码 | cv2.VideoCapture.get(7) | cv2.CAP_PROP_FRAME_COUNT = 7 | 视频文件中的帧数 | cv2.VideoCapture.get(8) | cv2.CAP_PROP_FORMAT = 8 | 返回对象的格式 | cv2.VideoCapture.get(9) | cv2.CAP_PROP_MODE = 9 | 返回后端特定的值,该值指示当前捕获模式 | cv2.VideoCapture.get(10) | cv2.CAP_PROP_BRIGHTNESS = 10 | 图像的亮度(仅适用于照相机) | cv2.VideoCapture.get(11) | cv2.CAP_PROP_CONTRAST = 11 | 图像的对比度(仅适用于照相机) | cv2.VideoCapture.get(12) | cv2.CAP_PROP_SATURATION = 12 | 图像的饱和度(仅适用于照相机) | cv2.VideoCapture.get(13) | cv2.CAP_PROP_HUE = 13 | 图像色调(仅适用于照相机) | cv2.VideoCapture.get(14) | cv2.CAP_PROP_GAIN = 14 | 图像增益(仅适用于照相机)(Gain在摄影中表示白平衡提升) | cv2.VideoCapture.get(15) | cv2.CAP_PROP_EXPOSURE = 15 | 曝光(仅适用于照相机) | cv2.VideoCapture.get(16) | cv2.CAP_PROP_CONVERT_RGB = 16 | 指示是否应将图像转换为RGB布尔标志 | cv2.VideoCapture.get(17) | cv2.CAP_PROP_WHITE_BALANCE_BLUE_U = 17 | × 暂时不支持 | cv2.VideoCapture.get(18) | cv2.CAP_PROP_RECTIFICATION = 18 | 立体摄像机的矫正标注(目前只有DC1394 v.2.x后端支持这个功能) | cv2.VideoCapture.get(19) | cv2.CAP_PROP_MONOCHROME = 19 | - | cv2.VideoCapture.get(20) | cv2.CAP_PROP_SHARPNESS = 20 | - | cv2.VideoCapture.get(21) | cv2.CAP_PROP_AUTO_EXPOSURE = 21 | - | cv2.VideoCapture.get(22) | cv2.CAP_PROP_GAMMA = 22 | - | cv2.VideoCapture.get(23) | cv2.CAP_PROP_TEMPERATURE = 23 | - | cv2.VideoCapture.get(24) | cv2.CAP_PROP_TRIGGER = 24 | - | cv2.VideoCapture.get(25) | cv2.CAP_PROP_TRIGGER_DELAY = 25 | - | cv2.VideoCapture.get(26) | cv2.CAP_PROP_WHITE_BALANCE_RED_V = 26 | - | cv2.VideoCapture.get(27) | cv2.CAP_PROP_ZOOM = 27 | - | cv2.VideoCapture.get(28) | cv2.CAP_PROP_FOCUS = 28 | - | cv2.VideoCapture.get(29) | cv2.CAP_PROP_GUID = 29 | - | cv2.VideoCapture.get(30) | cv2.CAP_PROP_ISO_SPEED = 30 | - | cv2.VideoCapture.get(32) | cv2.CAP_PROP_BACKLIGHT = 32 | - | cv2.VideoCapture.get(33) | cv2.CAP_PROP_PAN = 33 | - | cv2.VideoCapture.get(34) | cv2.CAP_PROP_TILT = 34 | - | cv2.VideoCapture.get(35) | cv2.CAP_PROP_ROLL = 35 | - | cv2.VideoCapture.get(36) | cv2.CAP_PROP_IRIS = 36 | - | cv2.VideoCapture.get(37) | cv2.CAP_PROP_SETTINGS = 37 | 弹出视频/摄像机过滤器对话框(注意:当前仅DSHOW后端支持。属性值将被忽略) | cv2.VideoCapture.get(38) | cv2.CAP_PROP_BUFFERSIZE = 38 | - | cv2.VideoCapture.get(39) | cv2.CAP_PROP_AUTOFOCUS = 39 | - | cv2.VideoCapture.get(40) | cv2.CAP_PROP_SAR_NUM = 40 | sample aspect ratio: num/den (num) | cv2.VideoCapture.get(41) | cv2.CAP_PROP_SAR_DEN = 41 | 采样长宽比:num / den(den)(Sample aspect ratio: num/den (den)) | cv2.VideoCapture.get(42) | cv2.CAP_PROP_BACKEND = 42 | 当前后端(枚举VideoCaptureAPI)。 只读属性。 | cv2.VideoCapture.get(43) | cv2.CAP_PROP_CHANNEL = 43 | 视频输入或通道数(仅适用于支持的摄像头) | cv2.VideoCapture.get(44) | cv2.CAP_PROP_AUTO_WB = 44 | 启用/禁用自动白平衡 | cv2.VideoCapture.get(45) | cv2.CAP_PROP_WB_TEMPERATURE = 45 | 白色平衡色温 | cv2.VideoCapture.get(46) | cv2.CAP_PROP_CODEC_PIXEL_FORMAT = 46 | (只读)编解码器的像素格式。 4-character code-请参见VideoWriter :: fourcc。 AV_PIX_FMT_ *的子集;如果未知,则为-1 | cv2.VideoCapture.get(47) | cv2.CAP_PROP_BITRATE = 47 | (只读)视频比特率,单位为千比特/秒(kbits/s) | cv2.VideoCapture.get(48) | cv2.CAP_PROP_ORIENTATION_META = 48 | 只读)由stream meta定义的帧旋转(仅适用于FFmpeg后端) | cv2.VideoCapture.get(49) | cv2.CAP_PROP_ORIENTATION_AUTO = 49 | 如果为true -旋转CvCapture的输出帧考虑视频文件的元数据(仅适用于FFmpeg后端) |
3 视频四字符编码foucc
1、我们在保存视频之前,需要先设置保存视频的编码格式
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
也可以写成如下的形式:
fourcc = cv2.VideoWriter_fourcc("M", "P", "4", "V")
2、fourcc为四个字符 用来表示编码格式
3、定义保存视频编码格式
◆ fourcc()
static int cv::VideoWriter::fourcc ( char c1,
char c2,
char c3,
char c4
)
cv.VideoWriter_fourcc( c1, c2, c3, c4 ) -> retval
4、fourcc的编码格式有很多,具体可以去这里查看
|