使用imutils包的VideoStream读取视频流,丢帧率达20%

最近在读取相机RTSP流,发现OpenCV不如使用imutils包读取的快:

import _thread
from imutils.video import VideoStream
import imutils
import time
import numpy as np
import cv2

# # 为线程定义一个函数
def cam1( threadName):
    cap = VideoStream('test.mp4').start()
    n=0
    while True:
        img = cap.read()
        n=n+1
        cv2.putText(img, str(n), (50, 300), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (255, 255, 255), 2)
        cv2.imshow('frame11', img)
        cv2.waitKey(1)
    cap.release()

OpenCV读取方式:

def cam2(threadName):
    n=0
    cap = cv2.VideoCapture('test.mp4')
    while True:
        ret, img = cap.read()
        if ret:
            n = n + 1
            cv2.putText(img, str(n), (50, 300), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (255, 255, 255), 2)
            cv2.imshow('frame22222222222', img)
            cv2.waitKey(1)
    cap.release()

如果开两个线程读取摄像头竟然不同步,于是读取同一段视频,发现一段视频上面读取380帧,OpenCV读取443帧,故得出如上读取方式存在丢帧现象,大家使用时谨慎使用。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是一个使用 socket 自定义数据帧传输视频的示例代码: ```python import cv2 import numpy as np import struct import socket # 定义视频编解码器 fourcc = cv2.VideoWriter_fourcc(*'XVID') # 打开本地摄像头 cap = cv2.VideoCapture(0) # 设置视频帧大小 cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) # 定义数据帧头部 HEADERSIZE = 4 # 定义服务器 IP 和端口号 SERVER_IP = 'localhost' SERVER_PORT = 1234 # 创建 socket 对象 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((SERVER_IP, SERVER_PORT)) # 不断读取视频帧并传输 while True: # 读取视频帧 ret, frame = cap.read() # 编码视频帧 _, img_encoded = cv2.imencode('.jpg', frame, [cv2.IMWRITE_JPEG_QUALITY, 90]) # 构造数据帧 msg = struct.pack('>I', len(img_encoded)) + img_encoded # 发送数据帧 s.sendall(msg) # 接收服务器确认信息 data = s.recv(1024) print(data.decode()) # 关闭 socket 对象和摄像头 s.close() cap.release() ``` 在服务器端,我们可以使用以下代码来接收数据帧并显示视频: ```python import cv2 import numpy as np import struct import socket # 定义视频编解码器 fourcc = cv2.VideoWriter_fourcc(*'XVID') # 创建 VideoWriter 对象 out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480)) # 定义数据帧头部 HEADERSIZE = 4 # 定义服务器 IP 和端口号 SERVER_IP = 'localhost' SERVER_PORT = 1234 # 创建 socket 对象并绑定端口号 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((SERVER_IP, SERVER_PORT)) s.listen(1) # 等待客户端连接 conn, addr = s.accept() print('Connected by', addr) # 不断接收数据帧并显示 while True: # 接收数据帧头部 data = conn.recv(HEADERSIZE) # 如果头部为空,说明客户端已经关闭连接 if not data: break # 解析数据帧头部,获取数据帧大小 msglen = struct.unpack('>I', data)[0] # 接收数据帧 data = conn.recv(msglen) # 将数据帧转换成图像 img = cv2.imdecode(np.frombuffer(data, np.uint8), cv2.IMREAD_COLOR) # 显示图像 cv2.imshow('frame', img) # 写入视频文件 out.write(img) # 发送确认信息 conn.sendall(b'OK') # 按下 q 键退出循环 if cv2.waitKey(1) & 0xFF == ord('q'): break # 关闭 socket 对象和视频文件 conn.close() s.close() out.release() cv2.destroyAllWindows() ``` 注意:这只是一个简单的示例代码,实际应用中需要考虑数据的失和重传,以及帧、码等问题。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值