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

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

无人机端

#!/usr/bin/env python3
# coding:utf-8
import rospy
from cv_bridge import CvBridge, CvBridgeError
import cv2
import numpy as npfrom std_msgs.msg import String
import base64def encode_image(img):_, buffer = cv2.imencode('.jpg', img)img_str = base64.b64encode(buffer).decode('utf-8')return img_strif __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_offsety_position_denied = drone_y + y_offsetpos_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"):breakcap.release()output.release()cv2.destroyAllWindows()

主机端

#!/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_resizeddef image_callback(msg, index):global images, last_update_time, new_image_receivedtry:# 解码并存储图像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_receivedrospy.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进行点对点传输,或增强通信设备进行充分测试

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

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

相关文章

UE5 设置Sequence播完后返回起始位置

UE5 的sequence中,播放完毕,动画会停到最后一帧, 需要播放完毕后,设置sequence为起始位置 蓝图中控制方法: 链接:UE5 设置Sequence播完后返回起始位置 posted by anonymous | blueprintUE | PasteBin F…

德语常用口语学习柯桥小语种学习到泓畅学校,专业外语培训

问候与应答 Guten Morgen!(早上好!)Guten Tag!(白天好!)Guten Abend!(晚上好!)Hallo!(你好!)Wie geht es Ihnen?(您好吗&…

破解企业数字化转型之道:数字化?转型?

在当今的商业浪潮中,企业纷纷踏上了数字化转型之路,然而,真正洞悉数字化转型的深层含义者寥寥无几。笔者前面发过一篇文章>>数字化转型,90%都是吹牛,引起热议。文章指出多数企业的数字化转型仅是随波逐流&#x…

HTML学习

一、HTML的基本构成 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>星星(xingxing.com)</title> </head> <body><h1>我的第一个标题</h1><p>我的第一个段落。</p><a h…

为什么人们仍然对云安全感到困惑?

云安全服务商公司的一份报告发现&#xff0c;接受调查的公司中有74%暴露了存储或其他错误配置。这为网络罪犯打开了一扇危险的大门。总的来说&#xff0c;云安全越来越糟糕。安全工具的可用性和质量越来越好&#xff0c;但确认云计算基础设施的人却越来越笨。有些东西必须要放弃…

计算机网络基础(3)_应用层自定义协议与序列化

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 计算机网络基础(3)_应用层自定义协议与序列化 收录于专栏【计算机网络】 本专栏旨在分享学习计算机网络的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&a…

前言 --- 《跟着小王学Python》

前言 《跟着小王学Python》 是一套精心设计的Python学习教程&#xff0c;适合各个层次的学习者。本教程从基础语法入手&#xff0c;逐步深入到高级应用&#xff0c;以实例驱动的方式&#xff0c;帮助学习者逐步掌握Python的核心概念。通过开发游戏、构建Web应用、编写网络爬虫、…

【C#设计模式(8)——过滤器模式(Adapter Pattern)】

前言 滤液器模式可以很方便地实现对一个列表中的元素进行过滤的功能&#xff0c;能方便地修改滤器的现实&#xff0c;符合开闭原则。 代码 //过滤接口public interface IFilter{List<RefuseSorting> Filter(List<RefuseSorting> refuseList);}//垃圾分类public cla…

开源共建 | 长安链开发常见问题及规避

长安链开源社区鼓励社区成员参与社区共建&#xff0c;参与形式包括不限于代码贡献、文章撰写、社区答疑等。腾讯云区块链王燕飞在参与长安链测试工作过程中&#xff0c;深入细致地总结了长安链实际开发应用中的常见问题及其有效的规避方法&#xff0c;相关内容多次解答社区成员…

什么是RAG? LangChain的RAG实践!

1. 什么是RAG RAG的概念最先在2020年由Facebook的研究人员在论文《Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks》中提出来。在这篇论文中他们提出了两种记忆类型&#xff1a; 基于预训练模型&#xff08;当时LLM的概念不像现在这么如日中天&#xff0…

第二十一章、Qt对XML文件进行读写操作详解

目录 一、XML文件的简介 二、QXML的接口介绍 三、XML示例 四、QXML的介绍 5.1、QDomDocument详解 5.2、QDomElement详解 5.3、QDomAttr详解 六、使用QXML解析XML示例 七、构建并保存xml 一、XML文件的简介 可扩展标记语言 (Extensible Markup Language, XML) ,标准通…

03-axios常用的请求方法、axios错误处理

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…

小小的mfc100u.dll文件到底是什么?mfc100u.dll丢失的解决方法有哪些?

对于许多电脑用户来说&#xff0c;软件突然无法启动并显示“mfc100u.dll丢失”是一件非常头疼的事情。你可能正急于完成一份重要的文档&#xff0c;或者沉浸在紧张刺激的游戏关卡中&#xff0c;而这个错误提示就像一盆冷水&#xff0c;无情地浇灭了你的热情。这个小小的mfc100u…

华为eNSP:MSTP

一、什么是MSTP&#xff1f; 1、MSTP是IEEE 802.1S中定义的生成树协议&#xff0c;MSTP兼容STP和RSTP&#xff0c;既可以快速收敛&#xff0c;也提供了数据转发的多个冗余路径&#xff0c;在数据转发过程中实现VLAN数据的负载均衡。 2、MSTP可以将一个或多个VLAN映射到一个Inst…

使用cloudflare搭建私人docker镜像站

背景 大家是否也有docker镜像拉取速度慢&#xff0c;甚至直接拉不下来的情况&#xff0c;我们可以使用cloudflare加速拉取镜像。 申请域名 开始前需要准备cloudflare账号并自购一个域名。域名可以在云厂商购买&#xff0c;可以看到非主流域名比较实惠。 购买完成后在域名控…

晶振选择指南:应对温度波动的关键因素

晶振的选择对于电子设备来说至关重要&#xff0c;尤其是在面对温度波动的情况下。晶振作为时钟信号源&#xff0c;其性能直接影响到设备的稳定性和可靠性。因此&#xff0c;在选择晶振时&#xff0c;需要根据实际应用场景以及对时钟精度的要求来进行。以下是一些建议&#xff1…

gpu-V100显卡相关知识

一、定义 RuntimeError: FlashAttention only supports Ampere GPUs or newer.torch attention注意力接口学习V100 架构是什么&#xff1f; 二、实现 RuntimeError: FlashAttention only supports Ampere GPUs or newer. 报错原因分析&#xff1a; GPU机器配置低&#xff0c;…

【go从零单排】HTTP客户端和服务端

&#x1f308;Don’t worry , just coding! 内耗与overthinking只会削弱你的精力&#xff0c;虚度你的光阴&#xff0c;每天迈出一小步&#xff0c;回头时发现已经走了很远。 &#x1f4d7;概念 在 Go 语言中&#xff0c;net/http 包提供了强大的 HTTP 客户端和服务器功能。 &…

从Web2到Web3:区块链推动的数字进化之路

互联网的演变从最初的Web1到如今的Web3&#xff0c;代表了技术和用户需求的深刻变化。Web3是一个基于区块链技术的全新互联网架构&#xff0c;旨在解决传统互联网&#xff08;即Web2&#xff09;中数据集中化和隐私保护等问题。通过去中心化的机制&#xff0c;Web3不仅能够增强…

vue自定义计算器组件

自定义组件实现以下简单的计算器功能&#xff1a; 创建计算器组件文件calculator.vue&#xff0c;代码如下&#xff1a; <template><div class"calculator"><!-- 当前运算过程显示区域 --><div class"expression">{{ currentExpr…