Pepper机器人平板显示摄像头画面失败(黑屏)技术求助
问题诊断与解决
单张图片显示黑屏的原因及修复
你的代码核心问题是图片文件名错误:ALPhotoCapture.takePictures生成的文件名并非你指定的image.jpg,而是会自动在文件名后添加时间戳(格式为[前缀]_[时间戳].jpg),比如image_1716213600.jpg。直接读取image.jpg会找不到文件,导致平板显示黑屏。
修复后的代码
import qi import time import glob import os # Connect to Pepper's session session = qi.Session() session.connect("tcp://<PEPPER_IP_ADDRESS>:9559") # Get the services tablet_service = session.service("ALTabletService") photo_capture_service = session.service("ALPhotoCapture") # Configure camera photo_capture_service.setResolution(2) # 640x480 photo_capture_service.setCameraID(0) # Front camera save_path = "/home/nao/recordings/cameras/" prefix = "image" # Take picture photo_capture_service.takePictures(1, save_path, prefix) time.sleep(1) # 缩短等待时间,足够保存即可 # 获取最新生成的图片文件 image_pattern = os.path.join(save_path, f"{prefix}_*.jpg") latest_image = max(glob.glob(image_pattern), key=os.path.getctime) # 显示图片(直接传机器人本地路径更可靠) tablet_service.showImage(latest_image) time.sleep(5) # 延长显示时间以便观察 # Cleanup:可选删除临时图片 os.remove(latest_image) session.close()
额外注意事项
- 确保平板已解除屏保:在Choregraphe的
Settings里找到平板设置,关闭自动锁屏。 - 检查
ALTabletService状态:可以先调用tablet_service.showWebview("http://www.aldebaran.com")测试平板是否能正常显示内容,排除硬件连接问题。
实时摄像头画面的实现方案
如果要实现实时画面,ALPhotoCapture的单张拍摄方式效率太低,推荐使用**ALVideoDevice获取视频流**,再通过网页推流到平板:
实现思路
- 使用
ALVideoDevice订阅摄像头视频流,获取每一帧图像数据。 - 在机器人上启动一个简单的HTTP服务器,将视频帧转为MJPEG流。
- 用
ALTabletService.showWebview打开这个MJPEG流的URL,实现实时显示。
示例代码框架
import qi import time import cv2 import numpy as np from http.server import BaseHTTPRequestHandler, HTTPServer import threading # 全局变量存储视频帧 current_frame = None class MJPEGHandler(BaseHTTPRequestHandler): def do_GET(self): global current_frame if self.path == '/stream': self.send_response(200) self.send_header('Content-type', 'multipart/x-mixed-replace; boundary=frame') self.end_headers() while True: if current_frame is not None: _, jpeg = cv2.imencode('.jpg', current_frame) self.wfile.write(b'--frame\r\n') self.send_header('Content-type', 'image/jpeg') self.send_header('Content-length', str(len(jpeg))) self.end_headers() self.wfile.write(jpeg.tobytes()) self.wfile.write(b'\r\n') time.sleep(0.03) # 控制帧率(约30fps) def start_server(): server = HTTPServer(('', 8080), MJPEGHandler) server.serve_forever() # 主逻辑 session = qi.Session() session.connect("tcp://<PEPPER_IP_ADDRESS>:9559") # 启动HTTP服务器线程 server_thread = threading.Thread(target=start_server) server_thread.daemon = True server_thread.start() # 获取视频服务 video_service = session.service("ALVideoDevice") resolution = 2 # 640x480 color_space = 13 # RGB fps = 30 client_name = "PepperCameraStream" video_client = video_service.subscribe(client_name, resolution, color_space, fps) # 获取平板服务 tablet_service = session.service("ALTabletService") # 打开平板网页显示流(机器人IP替换为实际地址) tablet_service.showWebview(f"http://<PEPPER_IP_ADDRESS>:8080/stream") try: while True: # 获取视频帧 image_data = video_service.getImageRemote(video_client) if image_data is None: time.sleep(0.01) continue # 解析图像数据 width = image_data[0] height = image_data[1] channels = image_data[2] array = image_data[6] # 转为OpenCV格式 frame = np.frombuffer(array, dtype=np.uint8).reshape((height, width, channels)) frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR) current_frame = frame time.sleep(1/fps) finally: # 清理资源 video_service.unsubscribe(video_client) tablet_service.hideWebview() session.close()
注意事项
- 需要在机器人上安装OpenCV:通过SSH连接机器人,执行
pip install opencv-python(如果使用Python 2则用pip2)。 - 确保机器人和平板在同一局域网,平板能访问机器人的8080端口。
- 帧率可根据机器人性能调整,避免占用过多CPU资源。
内容的提问来源于stack exchange,提问作者Sebastian789
相关产品推荐
相关产品推荐

