RK3588——网口实时传输视频

news2024/11/27 4:27:07

由于通过流媒体服务器传输画面延迟太高的问题,不知道是没有调试到合适的参数还是其他什么问题。诞生了这篇博客。

RK3588板端上接摄像头,采集画面,通过网口实时传输给上位机并显示。

第一代版本

RK3588代码
import cv2
import socket
import struct

# 配置
SERVER_IP = '192.168.137.1'  # 上位机的IP地址
PORT = 5000  # 端口号

# 创建一个socket对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 打开摄像头
cap = cv2.VideoCapture(23)

if not cap.isOpened():
    print("无法打开摄像头")
    exit()

while True:
    # 读取摄像头帧
    ret, frame = cap.read()
    if not ret:
        print("无法读取帧")
        break
    frame = cv2.resize(frame,(320,240))
    # 对帧进行编码
    encoded, buffer = cv2.imencode('.jpg', frame)

    if not encoded:
        print("编码帧失败")
        break

    # 发送数据
    data = buffer.tobytes()
    print(len(data))
    print(len(struct.pack('L', len(data))))
    print(struct.pack('L', len(data)))
    # 发送数据大小
    client_socket.sendto(struct.pack('L', len(data)), (SERVER_IP, PORT))
    # 发送数据
    client_socket.sendto(data, (SERVER_IP, PORT))

# 释放资源
cap.release()
client_socket.close()

上位机代码(windows系统)

import cv2
import socket
import numpy as np

# 配置
PORT = 5000  # 端口号

# 创建一个socket对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(('0.0.0.0', PORT))

# 创建窗口并设置为全屏模式
cv2.namedWindow('Video Stream', cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty('Video Stream', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)

while True:
    # 接收数据大小
    data_size, _ = server_socket.recvfrom(8)

    # 接收的视频数据长度
    data_size = int.from_bytes(data_size, byteorder='little')

    # 接收视频数据
    data, _ = server_socket.recvfrom(data_size)

    # 解码
    np_data = np.frombuffer(data, dtype=np.uint8)
    frame = cv2.imdecode(np_data, cv2.IMREAD_COLOR)

    if frame is None:
        print("解码帧失败")
        continue

    # 显示帧
    cv2.imshow('Video Stream', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放资源
server_socket.close()
cv2.destroyAllWindows()

测试视频

遗留问题:视频每帧只能一次传输完毕,且每帧的大小不能过大,不然会报错。

第二代版本

通过分组发送帧图像的方式,即segment_size,优化了帧图像必须要一次传输的问题。

并且把b'\xff\xff'当作一帧画面传输完成的表中,暂时还没发现什么问题。

RK3588代码
import cv2
import socket

# 配置
SERVER_IP = '192.168.137.1'  # 上位机的IP地址
PORT = 5000  # 端口号

# 创建一个socket对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 打开摄像头
cap = cv2.VideoCapture(23)

if not cap.isOpened():
    print("无法打开摄像头")
    exit()

frame_count = 0
segment_size = 65000 #32678 # 一组数据的大小
while True:
    # 读取摄像头帧
    ret, frame = cap.read()
    if not ret:
        print("无法读取帧")
        break

    # 对帧进行编码
    encoded, buffer = cv2.imencode('.jpg', frame)

    if not encoded:
        print("编码帧失败")
        break

    # 发送数据
    data = buffer.tobytes()
    data_len = len(data) # 一帧图像的数据大小
    print(data_len)
    # 发送数据

    time = data_len // segment_size # 需要发多少组
    left = data_len % segment_size # 剩下多少个
    if time > 0:
        for i in range(time): # 遍历发送所有的组
            start_pos = i*segment_size 
            end_pos = (i+1)*segment_size
            client_socket.sendto(data[start_pos:end_pos], (SERVER_IP, PORT))
    # 发送剩下的,并且加上结束帧标识符
    client_socket.sendto(data[time*segment_size:data_len] + b'\xff\xff', (SERVER_IP, PORT))

    frame_count +=1
# 释放资源
cap.release()
client_socket.close()
上位机代码(windows系统)

 

import cv2
import socket
import numpy as np

# 配置
PORT = 5000  # 端口号

# 创建一个socket对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(('0.0.0.0', PORT))
# 一组数据的大小
segment_size = 65000 #32678

while True:
    data_byte = b''
    # 接收视频数据
    data, _ = server_socket.recvfrom(segment_size)
    while (b'\xff\xff' not in data):
        data_byte += data
        data, _ = server_socket.recvfrom(segment_size)
    # 把分组发送的字节相加
    data_byte += data
    #去除最后两个结束帧标识符
    rev_data = data_byte[:-2]

    # 解码
    np_data = np.frombuffer(rev_data, dtype=np.uint8)
    frame = cv2.imdecode(np_data, cv2.IMREAD_COLOR)

    if frame is None:
        print("解码帧失败")
        continue

    # 显示帧
    cv2.imshow('Video Stream', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放资源
server_socket.close()
cv2.destroyAllWindows()

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2062963.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI智能体:我用扣子给詹杜库做了一套超酷炫的手办

杀疯了! 在巴黎奥运会今日的男篮决赛中,库里开启了杀神模式。 末节关键时刻投中 4 记三分,直接带走比赛,看得我都跪了。 库里在 2012 年未能入选梦之队,2016 年 NBA 季后赛夺冠后太过疲惫,2021 年东京奥…

真实护网,看这一篇就够了!【护网行动】

如果一个白帽黑客没参过护网,那他可能要回炉重造了。那么网安领域最出名的护网是什么?12年攻防老手告诉你答案。 1.什么是护网? 护网行动是由机关单位主办的网络攻防比赛,一般是每年的6~9月份会举行,分为国家级、省级…

如何给两台机器集群设置VIP(虚拟IP)

原文链接:https://www.cnblogs.com/qianz/articles/16825567.html 一、环境准备 1.集群 IP部署 172.16.30.181是主节点,172.16.30.182是备节点,VIP是172.16.30.183 我是在openstack上搭建的集群,建议大家将需要用到的IP都固定到…

java多线程(五)线程间通信

线程间通信是并发编程中的一个重要概念,它允许多个线程之间交换信息或共享数据。 以下是几种常见的线程间通信方式及其示例: 1. 共享内存 共享内存是最基本的线程间通信方式。多个线程可以访问同一块内存区域,通过读写这块内存区域来实现数…

【问题解决】 PyAutoGUI was unable to import pyscreeze.

解决方案: 打开终端(winr 输入cmd回车)执行 pip install pyscreeze 再执行:pip install pillow

详解并掌握AXI4总线协议(四)、AXI4_FULL_SLAVE接口源码分析以及仿真验证

系列文章目录 详解并掌握AXI4总线协议(一)、AXI4-FULL接口介绍 详解并掌握AXI4总线协议(二)、AXI4_FULL_MASTER接口源码分析以及仿真验证 详解并掌握AXI4总线协议(三)、基于AXI4_FULL接口的BRAM读写仿真验…

免费好用!阿里这5款AI神器,太强了,打工人必备!(建议收藏)

大家好,我是程序员X小鹿,前互联网大厂程序员,自由职业2年,也一名 AIGC 爱好者,持续分享更多前沿的「AI 工具」和「AI副业玩法」,欢迎一起交流~ 《黑神话:悟空》太爆了!最近感觉都要被…

Eclipse部署一个项目到Tomcat和部署多个项目到Tomcat

Eclipse部署一个项目到Tomcat: https://blog.csdn.net/weixin_42334396/article/details/105902994 Eclipse部署多个项目到Tomcat: https://blog.csdn.net/zhanglin1220/article/details/82056185 使用cmd方法强制关闭端口,解除端口占用方法&…

2.初识springcloud

文章目录 1.什么是SpringCloud1.1版本的介绍 2.Spring Cloud实现方案3.环境搭建4.服务拆分原则5.数据准备5.1订单服务5.2商品服务 大家好,我是晓星航。今天为大家带来的是 初识springcloud 相关的讲解!😀 1.什么是SpringCloud 简单来说&…

Excel表格添加趋势线_数据拟合

一个曲线通过补偿算法拟合为另一个曲线,通常可以通过多种数学和计算技术实现。这里也可以通过Excel表格添加趋势线,然后对趋势线进行拟合,得到趋势预测公式来达到数据补偿。 通过把你需要的数据导入到Excel表格中。 通过 “ 插入 ” --> “…

从单一到互联:KNX网关如何改变你的家居生活

从单一到互联:KNX网关如何改变你的家居生活 在科技日新月异的今天,家居生活正经历着一场前所未有的变革。从过去单一、孤立的设备操作,到如今智能、互联的生态系统,KNX网关作为这一转变的关键角色,正悄然改变着我们的日…

探索Unity3D URP后处理在UI控件Image上的应用

探索Unity3D URP后处理在UI控件Image上的应用 前言初识URP配置后处理效果将后处理应用于UI控件方法一:自定义Shader方法二:RenderTexture的使用 实践操作步骤一:创建RenderTexture步骤二:UI渲染至RenderTexture步骤三:…

养宠家庭一定要试 希喂、美的两大品牌宠物空气净化器性能对比

随着养宠家庭的增多,宠物市场上产品也在不断丰富。这段时间最热门的产品非宠物空气净化器莫属,讨论度非常高,大家对它的评价褒贬不一。作为三只毛孩子的家长,它们的毛发清理问题一直令我头大,所以决定试试号称专为吸附…

科技守护健康:氧气检测仪的工作原理与应用深探

科技守护健康:氧气检测仪的工作原理与应用深探 在科技飞速进步的今天,我们身边的许多设备都融入了科技的智慧,其中氧气检测仪便是守护人类健康与安全的重要一环。它以其独特的工作原理,在工业生产、医疗护理等多个领域发挥着至关重…

数字图像处理【15】特征检测——SIFT特征检测

一、引入SIFT算法 上一篇文章我们重温学习了Harris角点检测算法的基本原理,但在实际生产使用Harris检测角点的时候,会发现一个问题,就是用于检测的输入图像的尺寸大小会直接影响到Harris的检测结果。这是为什么呢?主要是Harris角…

引领未来的NVR方案:海思3520D芯片与全套NVR模组源代码解析

随着视频监控技术的发展,NVR(网络视频录像机)已成为安全保障系统的核心设备。市场上NVR芯片方案主要由几大厂商主导,其中海思35XX系列在中高端市场占据主导地位,特别适用于图像处理和多种应用场景。 我们研发了一款基…

探索提示工程 Prompt Engineering的奥妙

一、探索提示工程 1. 介绍通用人工智能和专用人工智能 人工智能(AI)可以分为通用人工智能(AGI)和专用人工智能(Narrow AI)。AGI是一种能够理解、学习和执行任何人类可以完成的任务的智能。与此相对&#x…

嵌入式学习day17(数据结构)

大纲 数据结构、算法数据结构: 1. 线性表:顺序表、链表(单向链表,单向循环链表,双向链表,双向循环链表)、栈(顺序栈,链式栈)、队列(循…

得物App白屏优化系列|网络篇

一、背景 图片加载作为重中之重的App体验指标,端侧的白屏问题则是其中最为严重的问题之一。想象一下如果你在浏览交易商品、社区帖子等核心场景下,图片无法完成加载是多么糟糕的体验。 网络作为图片资源加载的最主要来源途径,如果不能够快速…

医疗器械维修零基础也可以学吗?

最近您是不是在纠结:医疗器械维修,零基础能学吗?别担心,答案就在这里!亲爱的朋友,零基 础绝对不是您追求医疗器械维修技能的绊脚石。我们有精心设计的课程,就像为您量身打造的成长阶梯。 无论您…