使用ROS节点进行多无人机的画面同步接收

由于需要在ubuntu18.04下基于python3进行图像处理,18.04ROS中默认使用python2的cv_bridge,为方便进行图像传输,本文直接将图片编码为字符串后传输,并在主机端进行解码显示。同时,在主机端对多个无人机画面同步显示。

无人机端

python 复制代码
#!/usr/bin/env python3
# coding:utf-8
import rospy
from cv_bridge import CvBridge, CvBridgeError
import cv2
import numpy as np


from std_msgs.msg import String
import base64



def encode_image(img):
    _, buffer = cv2.imencode('.jpg', img)
    img_str = base64.b64encode(buffer).decode('utf-8')
    return img_str

if __name__=="__main__":
    
    cap = cv2.VideoCapture(0)
    
    # 检查摄像头是否成功打开
    if not cap.isOpened():
        print("无法打开摄像头0,尝试使用配置1")
        # 尝试打开另一个摄像头(配置1)
        cap = cv2.VideoCapture(1)

    rospy.init_node('yolo_detector_node', anonymous=True)
    bridge = CvBridge()

    image_pub = rospy.Publisher('/image_topic_7', String, queue_size=10)


    while not rospy.is_shutdown():
        ret, cv_image = cap.read()

        x_position_denied = drone_x + x_offset
        y_position_denied = drone_y + y_offset
        pos_text = f"uav:7 pos: {x_position_denied:.2f},{y_position_denied:.2f}"
        cv2.putText(cv_image, pos_text, (10, 50), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 255), 4)    


        encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 50]

        _, buffer = cv2.imencode('.jpg', cv_image, encode_param)
        encoded_img_str = base64.b64encode(buffer).decode('utf-8')
        image_pub.publish(encoded_img_str)

        cv2.imshow("cv_image",cv_image)
        if cv2.waitKey(10) & 0xFF == ord("q"):
            break

    cap.release()
    output.release()
    cv2.destroyAllWindows()

主机端

python 复制代码
#!/usr/bin/env python3
# coding:utf-8
import cv2
import base64
import numpy as np
import rospy
import time
from std_msgs.msg import String

# 初始化一个列表来存储每个图片
images = [None] * 8
# 初始化一个列表来存储每张图片的最后更新时间
last_update_time = [0] * 8
# 设置黑色占位图的大小为 320x240
placeholder_image = np.zeros((240, 320, 3), dtype=np.uint8)

# 用于指示是否有新的图像更新
new_image_received = False
# 设置超时时间(秒)
timeout_duration = 2.0  # 2秒内没有更新则置为黑色

def decode_image(img_str):
    img_bytes = base64.b64decode(img_str)
    img_np = np.frombuffer(img_bytes, dtype=np.uint8)
    img = cv2.imdecode(img_np, cv2.IMREAD_COLOR)
    img_resized = cv2.resize(img, (320, 240))
    return img_resized

def image_callback(msg, index):
    global images, last_update_time, new_image_received
    try:
        # 解码并存储图像
        images[index] = decode_image(msg.data)
        last_update_time[index] = time.time()  # 更新图像的接收时间
        new_image_received = True  # 标记有新图像更新
    except Exception as e:
        rospy.logwarn(f"Failed to decode image at index {index}: {e}")
        images[index] = None  # 如果解码失败,使用None表示

def update_display():
    # 检查每张图像是否超时
    current_time = time.time()
    for i in range(len(images)):
        if current_time - last_update_time[i] > timeout_duration:
            images[i] = placeholder_image  # 如果超时,将该图像置为黑色

    # 拼接图像,未接收到的图像用黑色占位图代替
    resized_images = [img if img is not None else placeholder_image for img in images]
    row1 = np.hstack(resized_images[:4])
    row2 = np.hstack(resized_images[4:])
    combined_image = np.vstack((row1, row2))

    # 显示组合图像
    cv2.imshow("Combined Image (with placeholders)", combined_image)
    cv2.waitKey(1)

def image_receiver():
    global new_image_received
    rospy.init_node('image_receiver', anonymous=True)

    # 创建8个订阅者,每个接收一个图片主题
    for i in range(8):
        rospy.Subscriber(f'/image_topic_{i}', String, image_callback, i)

    # 在接收节点运行时显示窗口
    cv2.namedWindow("Combined Image (with placeholders)", cv2.WINDOW_NORMAL)
    cv2.resizeWindow("Combined Image (with placeholders)", 1280, 480)

    # 循环刷新显示
    rate = rospy.Rate(10)  # 控制刷新率
    while not rospy.is_shutdown():
        # 只有在接收到新图像时才更新显示
        if new_image_received:
            update_display()
            new_image_received = False  # 重置标志
        rate.sleep()

    # 退出时关闭窗口
    cv2.destroyAllWindows()

if __name__ == '__main__':
    try:
        image_receiver()
    except rospy.ROSInterruptException:
        pass

从而实现多机画面实时显示在终端

待解决

基于ROS主节点传输过多消息导致通道堵塞,可能由于电台通信堵塞或机载板处理能力较差,导致画面越多延迟越大,可尝试绕过ROS进行点对点传输,或增强通信设备进行充分测试

相关推荐
进制树4 小时前
【飞控开发实战·⑲】ROS2无人机开发环境搭建:Jazzy安装、工作空间与hello_drone节点实战
开发语言·安全·无人机·课程设计
向哆哆1 天前
无人机灾害场景人体目标检测数据集分享(适用于YOLO系列深度学习分类检测任务)
yolo·目标检测·无人机
haishikeji696_1 天前
市域低空巡查平台架构|无人机管理系统、飞控管理平台、无人机巡检平台、无人机智慧巡查系统
架构·无人机·低空经济·无人机管理系统·飞控管理平台
Ricardo-Yang1 天前
无人机单目深度估计测试:ZipDepth 与 AerialMetric
人工智能·算法·机器学习·计算机视觉·无人机
沈阳昊天环宇无人机小编辑3 天前
无人机测绘点云实操体验与丹东作业筹备展望,沈阳无人机外出测绘作业
无人机
workflower4 天前
智能无人机成低空经济核心赛道
运维·人工智能·机器学习·机器人·云计算·无人机
tianxuanjg4 天前
0.005mm 高精度 CNC 加工:机器人薄壁复杂零件变形控制与全维度品控方案
经验分享·机器人·无人机·制造·材质
沈阳昊天环宇无人机小编辑4 天前
无人机执照对直招军士招录与发展的赋能作用,文案由沈阳昊天环宇编辑整理 | 聚焦新质战斗力,助力青年直招军士梦
无人机
airobotcn4 天前
空地一体化巡检机器人系统落地实战指南
安全·机器人·无人机·智慧园区·巡逻
tianxuanjg4 天前
机器人精密零件:为何样品合格,批量却频频超差?
人工智能·经验分享·机器人·无人机·制造·材质