You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Choregraph与naoqi获取NAO6前置摄像头流并网络传输?

解决方案:Choregraphe自定义Python盒子实现高帧率摄像头流

一、核心思路:使用ALVideoDevice的视频订阅机制

NAOqi的ALVideoDevice提供视频订阅接口,比单次调用getImageLocal/Remote效率高得多,能稳定获取15-30fps的流(取决于摄像头配置)。我们可以在Choregraphe的自定义Python盒子里实现订阅、帧处理、网络传输的逻辑,无需额外安装ROS或GStreamer。

二、具体实现步骤

1. 新建Choregraphe自定义Python盒子

打开Choregraphe,拖入一个Python Script盒子,命名为CameraStreamSender。

2. 编写Python代码(盒子内部)

代码逻辑:

  • 初始化时订阅前置摄像头
  • 循环获取订阅的视频帧
  • 将帧编码为JPEG(减少传输体积)
  • 通过TCP发送到本地服务器
import naoqi
import numpy as np
import cv2
import socket
from naoqi import ALProxy

class CameraStreamSender(naoqi.ALModule):
    def __init__(self, name):
        naoqi.ALModule.__init__(self, name)
        # 初始化视频代理
        self.video_proxy = ALProxy("ALVideoDevice")
        # 订阅前置摄像头:QVGA分辨率、BGR色彩空间、30fps
        self.camera_client = self.video_proxy.subscribeCamera(
            "CameraStreamClient",
            0,  # 0=前置摄像头,1=后置摄像头
            naoqi.ALVideoDevice.kQVGA,
            naoqi.ALVideoDevice.kBGRColorSpace,
            30
        )
        # 配置服务器连接:替换为你的本地服务器IP和端口
        self.server_ip = "192.168.1.100"
        self.server_port = 5000
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.connect((self.server_ip, self.server_port))
        
        # 启动帧处理循环
        self.is_running = True
        self.video_proxy.registerImageCallback(self.camera_client, self.getName(), "process_frame")

    def process_frame(self, frame_id, _, frame_data):
        if not self.is_running:
            return
        # 解析帧数据
        width, height, _, buffer = frame_data
        # 转换为OpenCV格式
        img = np.frombuffer(buffer, dtype=np.uint8).reshape((height, width, 3))
        # JPEG编码降低传输体积
        _, encoded_img = cv2.imencode('.jpg', img, [int(cv2.IMWRITE_JPEG_QUALITY), 80])
        # 先发数据长度(解决粘包问题),再发图像数据
        data_len = len(encoded_img)
        self.socket.sendall(data_len.to_bytes(4, byteorder='big'))
        self.socket.sendall(encoded_img.tobytes())

    def onStop(self):
        # 停止时清理资源
        self.is_running = False
        self.video_proxy.unsubscribe(self.camera_client)
        self.socket.close()

3. 本地服务器接收脚本

在本地PC运行以下代码,用于接收摄像头流并进行姿态追踪:

import socket
import cv2
import numpy as np

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("0.0.0.0", 5000))
server_socket.listen(1)
print("等待NAO机器人连接...")
client_socket, addr = server_socket.accept()
print(f"已连接:{addr}")

while True:
    # 接收数据长度
    len_data = client_socket.recv(4)
    if not len_data:
        break
    data_len = int.from_bytes(len_data, byteorder='big')
    # 接收完整图像数据
    img_data = b''
    while len(img_data) < data_len:
        chunk = client_socket.recv(min(data_len - len(img_data), 4096))
        if not chunk:
            break
        img_data += chunk
    # 解码为OpenCV图像
    img = cv2.imdecode(np.frombuffer(img_data, dtype=np.uint8), cv2.IMREAD_COLOR)
    # 在此添加你的人体姿态追踪逻辑
    cv2.imshow("NAO Camera Stream", img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

client_socket.close()
server_socket.close()
cv2.destroyAllWindows()

4. Choregraphe工程配置

  • 将Python盒子拖入主流程,放在后台循环任务中,确保机器人在自主模式下持续运行该模块。
  • 运行前确认机器人与本地PC在同一局域网,且先启动服务器脚本。
  • 可按需调整摄像头分辨率(如kVGA即640x480)或JPEG质量,平衡帧率与画质。

三、关键优化点

  • 分辨率选择:QVGA(320x240)足以满足姿态追踪需求,且帧率稳定;更高分辨率会降低帧率。
  • 色彩空间:使用BGR格式直接兼容OpenCV,减少转换开销。
  • 传输协议:TCP比UDP更可靠,适合对帧完整性要求高的姿态追踪场景。
  • 资源清理:必须在盒子停止时取消摄像头订阅、关闭socket,避免机器人资源泄漏。

内容的提问来源于stack exchange,提问作者fluxt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 00:43:14