使用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进行点对点传输,或增强通信设备进行充分测试

相关推荐
芒果de香蕉皮30 分钟前
mavlink移植到单片机stm32f103c8t6,实现接收和发送数据
stm32·单片机·嵌入式硬件·算法·无人机
EasyNVR17 小时前
互联网视频云平台EasyDSS无人机推流直播技术如何助力野生动植物保护工作?
音视频·无人机·视频监控
云卓SKYDROID17 小时前
无人机察打一体系统设计优缺点!
科技·无人机·科普·云卓科技·察打一体飞机
后厂村路钢铁侠3 天前
基于PX4的多无人机集群中的的配置
无人机
创小董4 天前
高海拔低温地区无人机大载重吊运技术详解
无人机
创小董4 天前
垂起固定翼无人机大面积森林草原巡检技术详解
无人机
IT猿手4 天前
基于PWLCM混沌映射的麋鹿群优化算法(Elk herd optimizer,EHO)的多无人机协同路径规划,MATLAB代码
算法·elk·机器学习·matlab·无人机·聚类·强化学习
创小董4 天前
无人机飞防高效率喷洒技术详解
无人机
云卓SKYDROID5 天前
反无人机防御系统概述!
无人机·科普·高科技·云卓科技
EasyDSS5 天前
视频直播点播平台EasyDSS与无人机技术的森林防火融合应用
音视频·无人机