利用海康威视相机拍出来的视频是H265格式的,相比于常规的H264编码,压缩率更高,但因此如果直接用正常取流方法读取,会出现无法读取的情况
1. 如图h265码流取出图片为灰屏
?2 、解决灰屏问题
import subprocess
import cv2
# 将h265流转换opencv可编译格式返回
def get_frame_from_rtsp(rtsp_url):
# ( linux,windwos) docker容器内部使用 两者兼容 当环境为linux时将传输协议改为tcp,否则转换失败 ( '-rtsp_transport', 'tcp')
command = [
'ffmpeg',
# rtsp_transport 参数,通过设定这个参数值为 tcp ,使得ffmpeg强制使用tcp协议传输RTSP流(RTSP流模式使用UDP方式传输)。
'-rtsp_transport', 'tcp',
# 设置探测大小,指定用于探测输入流的大小。在这里,150M 表示 150 兆字节的探测大小。
'-analyzeduration', '150M',
'-probesize', '150M',
# 指定输入文件(RTSP 流)的 URL。
'-i', rtsp_url,
'-vf', 'fps=1,scale=1920:1080', # 设置帧率和图像大小
# 指定输出格式为图像流。在这里,将输出格式设置为图像流,以便后续通过管道读取。
'-f', 'image2pipe',
# 设置像素格式为 BGR24。在这里,将像素格式设置为 24 位 BGR 格式,即每个像素占据 3 字节。
'-pix_fmt', 'bgr24',
# 设置视频编解码器为原始视频。 如果设置为264需要额外增添参数 '-vcodec', 'libx264'
'-vcodec', 'rawvideo', '-'
]
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# 从 ffmpeg 进程中读取一帧数据
raw_frame = process.stdout.read(1920 * 1080 * 3)
if not raw_frame:
return None
# 将帧数据转换为 numpy 数组
frame = np.frombuffer(raw_frame, dtype=np.uint8).reshape((1080, 1920, 3))
return frame
frame = get_frame_from_rtsp(path)
if frame is not None:
# FILE_SAVE_PATH保存路径地址
img_path = os.path.join(FILE_SAVE_PATH,'2023')
cv2.imwrite(img_path, frame) # 存储为图像
else
print('无法获取到图像')
3、转换完成h265码流图片?