python实现简单的视频传输与处理
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python实现简单的视频传输与处理,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3814字,纯文字阅读大概需要6分钟。
内容图文
![python实现简单的视频传输与处理](/upload/InfoBanner/zyjiaocheng/618/076ab87002d1428cbf5a06e5f9d5f2c2.jpg)
1. opencv从摄像头抽帧
camera = cv2.VideoCapture(0)
if camera.isOpened():
success, frame = camera.read()
if success:
print('capture success')
2. RGB转YUV编码,JPG格式压缩
# 直接压缩到最小
result, img_code = cv2.imencode('.jpg', frame)
# 可以指定压缩后的图像质量
img_quality = 15
result, img_code = cv2.imencode('.jpg', frame, [int(cv2.IMWRITE_JPEG_QUALITY), img_quality])
# 这里,img_code经过编码后,可以直接tobytes写入文件了。
3. numpy ndarray 转bytes
buffer = frame.tobytes()
4. numpy ndarray 从buffer读取图像矩阵
# buffer中读取矩阵需要手动指定dtype,之后reshape调整shape,因此如果通过网络传输矩阵,需要同时传输其dtype和shape。
buffer = numpy.frombuffer(frame.tobytes(), frame.dtype)
buffer.reshape(frame.shape)
5. 图像转为矩阵
frame = cv2.imdecode(numpy.frombuffer(img_code.tobytes(), img_code.dtype), -1)
img = Image.fromarray(frame)
# 一般来说,图像矩阵元素类型为 uint8 , 解码时可直接指定dtype为 numpy.uint8
6. BGR 转 RGB 的几种方式
# 如果发现图片显示的时候颜色不对劲,红色变成了蓝色,说明颜色信息放反了,需要转换一下
# opencv默认使用BGR格式保存图像
frame = frame[:, :, [2, 1, 0]]
frame = frame[:, :, ::-1]
frame = frame[..., ::-1]
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
7. opencv 、socket 实现简单的视频处理(不带音频)
视频源
—> 生产者
—> 中间处理
—> 消费者
视频源:可以是静态视频文件,也可以是一些实时视频流。
生产者:opencv的VideoCapture,从视频源抽帧。
中间处理:图像处理程序等。
消费者:播放器、视频封装程序等。
server.py
class FrameProducer(threading.Thread):
def __init__(self, frame_stack):
super(FrameProducer, self).__init__()
self.camera = cv2.VideoCapture(0)
self.running = True
self.frame_stack: Stack = frame_stack
def run(self) -> None:
while self.running:
if self.camera.isOpened():
res, frame = self.camera.read()
if res:
print('clip a frame from camera')
self.frame_stack.push(frame)
class Sender(threading.Thread):
def __init__(self, sock: socket.socket, frame_stack: Stack):
super(Sender, self).__init__()
self.client: socket = sock
self.resolution = (640, 480)
self.img_quality = 15
self.running = True
self.frame_stack = frame_stack
def run(self) -> None:
while self.running:
frame = self.frame_stack.pop()
if frame is not None:
print('got a frame from stack')
frame = cv2.resize(frame, self.resolution)
result, img_encode = cv2.imencode('.jpg', frame, [int(cv2.IMWRITE_JPEG_QUALITY), self.img_quality])
data = img_encode.tostring()
msg = Message(data, *self.resolution)
try:
self.client.send(msg.get_head())
self.client.send(msg.get_body())
print(msg.length)
except Exception as ex:
self.running = False
print(ex)
client.py
class Receiver(threading.Thread):
def __init__(self, _sock: socket.socket, frame_stack: Stack):
super(Receiver, self).__init__()
self.sock = _sock
self.running = True
self.frame_stack = frame_stack
def run(self) -> None:
try:
while self.running:
head = self.sock.recv(Message.head_length)
msg = Message()
msg.parse_head(head)
data = self.sock.recv(msg.length)
msg.parse_body(data)
print(msg.length, len(msg.data))
frame = cv2.imdecode(np.frombuffer(msg.data, np.uint8), -1)
self.frame_stack.push(frame)
except Exception as ex:
print(ex)
self.running = False
class Consumer(threading.Thread):
def __init__(self, frame_stack: Stack):
super(Consumer, self).__init__()
self.frame_stack = frame_stack
self.running = True
def run(self) -> None:
while self.running:
frame = self.frame_stack.pop()
if frame is not None:
cv2.imshow('image', frame)
if cv2.waitKey(100) & 0xFF == ord('q'):
break
可能遇到的问题:
- 如果消费者这边处理速度低于opencv抽帧的速度,由于opencv自带帧缓冲区,每一帧图像都不会被丢弃,会使帧数据在缓冲区堆积,结果处理后的视频延时越来越高。消费者端,准备一个栈,将接收到的帧存放到栈里,用于丢帧,防止实时视频的延时累加。每当栈内积压的数据超过一个阀值,就将栈内数据清空,防止内存溢出。
- 直接使用socket时需要注意socket的粘包问题。粘包问题可以通过多种方式解决,如定界符加转义、固定报文长度、固定首部长度并在首部指明数据部分长度。
内容总结
以上是互联网集市为您收集整理的python实现简单的视频传输与处理全部内容,希望文章能够帮你解决python实现简单的视频传输与处理所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。