前视声呐目标识别定位(六)-代码解析之目标截图并传输

news2024/10/9 4:02:19

前视声呐目标识别定位(一)-基础知识

前视声呐目标识别定位(二)-目标识别定位模块   

前视声呐目标识别定位(三)-部署至机器人

前视声呐目标识别定位(四)-代码解析之启动识别模块

前视声呐目标识别定位(五)-代码解析之修改声呐参数

前视声呐目标识别定位(六)-代码解析之目标截图并传输

前视声呐目标识别定位(七)-代码解析之录制数据包

前视声呐目标识别定位(八)-代码解析之各模块通信

前视声呐目标识别定位(九)-声呐驱动  

        识别目标后,截取目标框大小的图片,压缩传输。

1、test_client.py

        python3 test_client.py 7 1

elif cmd == str(7):
    print("sent capture object img cmd...")
    arrBuff = bytearray(b'\xff\xbb\xff\xbb\xee\xff\xee\xff')

        在协议文件中,启动识别并截图的协议为:

        故模块将该数据包发送至auv_server。

2、auv_server.py

def test_cmd(self):
    while True:
        self.test_conn, self.test_addr = self.test_server.accept()
        test_cmd_msg = self.test_conn.recv(1024)
        if len(test_cmd_msg)>0:
            self.conn.send(test_cmd_msg)

        直接将指令转发至center_server

3、center_server.py

# send the control_center cmd from auv to the control_center module on nx
def recv_control_center_msg(self):
    while True:          
        cmd_msg = self.nx_client.recv(1024)
        if len(cmd_msg) > 3:
            # send the control_center cmd to the control_center module
            if cmd_msg[-4:] == b'\xee\xff\xee\xff':
                self.control_center_socket.send(cmd_msg)
            # send the sonar parameters cmd to the sonar module
            elif cmd_msg[-4:] == b'\xee\xaa\xee\xff':
                self.sonar_param_socket.send(cmd_msg)
            else:
                print("cmd from auv error, no such cmd...")

        根据'\ee\ff\ee\ff'判断为不带参数的指令,转control_center.py

4、control_center.py

def rcev_cmd(self):
...

    # capture the object image and sent back to auv
    elif recvmsg[0:4] == self.capture_object_img_msg[0:4]:
        if self.capture_img_subprocess:
            self.capture_img_subprocess.kill()
            self.capture_img_subprocess = subprocess.Popen(self.capture_object_img_cmd, shell=True, executable="/bin/bash")

....

        根据'\ff\bb\ff\bb'判断为启动识别程序。

self.capture_object_img_cmd = 'ros2 topic pub --once /yolov5/capture_object_image std_msgs/msg/Bool data:\ true'

        发布/yolov5/capture_object_image。

5、yolov5_sonar.py

        监听到topic: /yolov5/capture_object_image

class Yolo_Dect(Node):
    def __init__(self):
    ...
        self.object_image_capture_sub = self.create_subscription(Bool, "/yolov5/capture_object_image", self.object_image_capture_callback, 1)
    ...

        
    def object_image_capture_callback(self, msg):
        if msg.data:
            self.object_image_capture_flag = True

        获取截图数据:

def image_callback(self, image):
    ...
    # capture the image to transport
    if self.object_image_capture_flag:
        self.image_capture = np.frombuffer(image.data, dtype=np.uint8).reshape(
                image.height, image.width, -1)
        self.capture_image_h = image.height
        self.capture_image_w = image.width
        self.capture_image_channel = len(image.data) / (image.height * image.width)

     逐个将目标截图并压缩编码,每个目标截图长度和宽度均不小于300像素,通过image_min_length设置,通过image_quality(0-100)可以设置压缩图像的质量,质量越小,压缩后的图片大小越小,然后传输。

        协议文件中,目标图片的协议为:

def dectshow(self, org_img, boxs, sonar_azimuth, sonar_range):
    ...
    # tcp transport the cut and compressed object images data
    # ensure get the image
    if self.capture_image_h * self.capture_image_w > 0:
        object_image_num = len(self.objects_azimuth_range.object_azimuth_range)
        # ensure object in the image
        if object_image_num > 0:
        #if object_image_num > 1:   #ensure several object for test
            try:                    
                object_image_count = 0
                for object_a_r in self.objects_azimuth_range.object_azimuth_range:
                    # cut the object in the image
                    if object_a_r.xmax - object_a_r.xmin < (self.image_min_length / 2):
                        cut_xmin = int((object_a_r.xmin + object_a_r.xmax) / 2.0 - self.image_min_length / 2)
                        cut_xmax = int((object_a_r.xmin + object_a_r.xmax) / 2.0 + self.image_min_length / 2)
                    else:
                        cut_xmin = int(object_a_r.xmin - 50)
                        cut_xmax = int(object_a_r.xmax + 50)

                    if object_a_r.ymax - object_a_r.ymin < (self.image_min_length / 2):
                        cut_ymin = int((object_a_r.ymin + object_a_r.ymax) / 2.0 - self.image_min_length / 2)
                        cut_ymax = int((object_a_r.ymin + object_a_r.ymax) / 2.0 + self.image_min_length / 2)
                    else:
                        cut_ymin = int(object_a_r.ymin - 50)
                        cut_ymax = int(object_a_r.ymax + 50)
                    cut_image = self.image_capture[max(0, cut_ymin) : min(self.image_capture.shape[0], cut_ymax), max(0, cut_xmin) : min(self.image_capture.shape[1], cut_xmax)]
                            
                    # get the class, probability, azimuth and range of the object
                    img_buff = bytearray(b'\xff\xbb\xff\xbb')
                    img_buff += bytearray(object_image_num.to_bytes(4, byteorder='little'))
                    img_buff += bytearray(object_image_count.to_bytes(4, byteorder='little'))
                    object_class = self.object_name[object_a_r.class_name]
                    img_buff += bytearray(object_class.to_bytes(4, byteorder='little')) 
                    img_buff += struct.pack('<f', object_a_r.probability) 
                    img_buff += struct.pack('<f', object_a_r.object_azimuth)
                    img_buff += struct.pack('<f', object_a_r.object_range)

                    # get the height, width and channel of the object image
                    cut_img_height = cut_image.shape[0]
                    cut_img_width = cut_image.shape[1]
                    cut_img_channel = cut_image.shape[2]
                    img_buff += bytearray(cut_img_height.to_bytes(4, byteorder='little')) 
                    img_buff += bytearray(cut_img_width.to_bytes(4, byteorder='little')) 
                    img_buff += bytearray(cut_img_channel.to_bytes(4, byteorder='little'))                            
                            
                    # encode the object image
                    encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), self.image_quality]
                    result, encode_image = cv2.imencode('.jpg', cut_image, encode_param)
                    # get object image data length
                    cut_image_data_len = len(encode_image)
                    img_buff += bytearray(cut_image_data_len.to_bytes(4, byteorder='little'))
                    # objcet image data
                    img_buff += bytearray(encode_image)

                    #print("the trans image length is", len(encode_image))
                        
                    img_buff += bytearray(b'\xff\xb0\xff\xb0')
                    self.yolo_client.sendall(img_buff)

                    #print("sent image " + str(object_image_count))
                    object_image_count += 1
                        
                self.capture_image_h = 0
                self.capture_image_w = 0
                self.image_capture = None
                self.object_image_capture_flag = False

            except Exception as e:
                self.capture_image_h = 0
                self.capture_image_w = 0
                self.image_capture = None
                print("image transport error... ", e)

目标图片数据传输至server_center.py

6、server_center.py

# recv sonar img and send to auv
def rcv_sonar_img_msg(self):
    self.sonar_param_socket, self.sonar_param_addr = self.sonar_param_server.accept()
    while True:
        img_msg = self.sonar_param_socket.recv(65536)
        if img_msg[0:4] == b'\xff\xcc\xff\xcc':
            self.nx_client.sendall(img_msg)
        if img_msg == b'':
            self.sonar_param_socket, self.sonar_param_addr = self.sonar_param_server.accept()

目标图片传输至auv_server.py

7、auv_server.py

# receive the data from auv
def recv_msg(self):
    ...
    # object images
    if pkg_head == b'\xff\xbb\xff\xbb':
        # object num in one image capture
        object_num = struct.unpack('i',recv_msg[4:8])[0]

        # current object info in the objects of the captured image
        object_info = object()
        cur_object_num = struct.unpack('i',recv_msg[8:12])[0]
        object_info.object_class = struct.unpack('i', recv_msg[12:16])[0]
        object_info.object_probability = struct.unpack('f', recv_msg[16:20])[0]
        object_info.object_azimuth = struct.unpack('f', recv_msg[20:24])[0]
        object_info.object_range = struct.unpack('f', recv_msg[24:28])[0]
        self.recv_images.object_info.append(object_info)
        # current object image info
        img_height = struct.unpack('i',recv_msg[28:32])[0]
        img_width = struct.unpack('i',recv_msg[32:36])[0]
        img_channel = struct.unpack('i',recv_msg[36:40])[0]
        img_data_len = struct.unpack('i',recv_msg[40:44])[0]

        img_data = recv_msg[44:44 + img_data_len]
        pkg_end = recv_msg[44 + img_data_len : 48 + img_data_len]
        #print(pkg_end)

        if pkg_end == b'\xff\xb0\xff\xb0':
            self.recv_images.object_image_data.append(img_data)

        if self.object_count < object_num:
            self.object_count += 1
                
        if self.object_count == object_num:
            self.display_image_flag = True
            self.object_count = 0

最后通过display_objects_image展示目标图片。

此外关于目标识别模块,还有一个功能是实时将目标的信息传输给auv辅助导航,目标信息的协议参见协议文件。

为了看log调试方便,这个功能我注释掉了,如果不需要图片信息的话,可以将其打开,在yolov5_sonar.py中:

# self.yolo_client.sendall(pkg_buff)

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

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

相关文章

leetcode刷题-代码训练营-第7章-回溯算法1

回溯法模板 void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择&#xff1a;本层集合中元素&#xff08;树中节点孩子的数量就是集合的大小&#xff09;) {处理节点;backtracking(路径&#xff0c;选择列表); // 递归回溯&#xff0c;撤销处理结果} }理解 从…

红蓝色WordPress外贸建站模板

红蓝色WordPress外贸建站模板 https://www.mymoban.com/wordpress/5.html

爬虫部署平台crawlab使用说明

Crawlab 是一个基于 Go 语言的分布式网络爬虫管理平台&#xff0c;它支持 Python、Node.js、Jar、EXE 等多种类型的爬虫。 Crawlab 提供了一个可视化的界面&#xff0c;并且可以通过简单的配置来管理和监控爬虫程序。 以下是 Crawlab 的一些主要优点&#xff1a; 集中管理&am…

DFS:深搜+回溯+剪枝解决组合问题

创作不易&#xff0c;感谢支持!!! 一、电话号码的组合 . - 力扣&#xff08;LeetCode&#xff09; class Solution { public:string hash[10]{"","","abc","def","ghi","jkl","mno","pqrs"…

2024年 前端JavaScript 进阶 第3天 笔记

3.1-JS进阶-内容和两种编程思想 3.2-构造函数实现封装以及存在 3.3-原型对象prototype 3.4-数组扩展案例-求最大值和数组求和 3.5-constructor属性以及应用 3.6-对象原型proto 3.7-原型继承 3.8-原型链以及instanceof运算符 3.9-综合案例-模态框构造函数写法 3.10-综合案例-0pe…

vtk,ITK,DICOM3.0

(14 封私信 / 80 条消息) VTK ITK OPENCV&#xff0c;从图像处理的角度来说&#xff0c;哪种用的人多&#xff1f; - 知乎 (zhihu.com) 医学领域&#xff1a;通常要求使用ITK和VTK。 ITK做底层处理算法。 VTK做可视化显示。 ITK:Insight Segment and Regestration Toolkit …

Redis的5大常见数据类型的用法

上一篇文章我们讲了Redis的10大应用场景&#xff0c;这一篇文章就针对Redis的常用数据结构进行一个说明&#xff0c;通过示例的形式演示每一种数据结构如何使用。 当涉及Redis的数据操作时&#xff0c;不同数据类型对应的不同数据结构&#xff0c;如下就对5大常用的数据类型进行…

我与C++的爱恋:内联函数,auto

​ ​ &#x1f525;个人主页&#xff1a;guoguoqiang. &#x1f525;专栏&#xff1a;我与C的爱恋 ​ 一、内联函数 1.内联函数的概念 内联函数目的是减少函数调用的开销&#xff0c;通过将每个调用点将函数展开来实现。这种方法仅适用于那些函数体小、调用频繁的函数。 …

Fusion360修改嘉立创EDA专业版生成的3D外壳文件

需要第三方软件的原因 嘉立创EDA专业版生成电路板的3D外壳文件是比较快捷的&#xff0c;但如果侧面精密开孔或者添加其它非常规的元素还是有些局限。嘉立创EDA专业版可以把3D外壳文件导出&#xff0c;这就大大方便了第三方软件的修改。 本文是利用Fusion360修改3D外壳文件&…

C++ | string类学习 | string的常见接口使用方式

目录 为什么要学习string类&#xff1f; C语言中的字符串 OOP面向对象编程 两个面试题 标准库中的string类 string类了解 string类的文档介绍 总结 string类的常用接口说明 string类对象的常见构造 string类对象的容量操作 size()和length() clear() resize(size…

【C语言】【Leetcode】2437. 有效时间的数目

文章目录 题目思路一、枚举思路二、回溯 题目 链接: link 思路一、枚举 这题的可以简单的看成 h1 h2 : m1 m2 的情况&#xff0c;其中 h1 和 h2 有关&#xff0c; m1 和 m2 有关&#xff0c;数目不多可以直接暴力枚举解决 int countTime(char * time) {int countHour 0;i…

SQLite下一代查询规划器(十)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLite 查询优化器概述&#xff08;九&#xff09; 下一篇&#xff1a;SQLite的架构&#xff08;十一&#xff09; 1. 引言 “查询规划器”的任务是弄清楚 找出完成 SQL 语句的最佳算法或“查询计划”。 从 SQLi…

Markdown介绍

一.Markdown基本介绍&#x1f357; Markdown 是一种轻量级标记语言&#xff0c;用于简单、易读易写的文本格式编写。它设计初衷是让人们能够使用普通文本编辑器编写格式简单的文档&#xff0c;并且可以转换成有效的HTML。Markdown 的语法非常简洁直观&#xff0c;通过使用特定…

BIT-5-动态内存管理(C语言进阶)

本章重点 为什么存在动态内存分配动态内存函数的介绍 mallocfreecallocrealloc常见的动态内存错误几个经典的笔试题柔性数组 1. 为什么存在动态内存分配 我们已经掌握的内存开辟方式有&#xff1a; int val 20;//在栈空间上开辟四个字节 char arr[10] {0};//在栈空间上开辟…

好物视频素材在哪找?视频素材大全app下载

创作优质视频内容不仅仅是一种艺术&#xff0c;也是一种科学&#xff0c;需要对素材的深刻理解和精心挑选。掌握了这些高清无水印视频素材&#xff0c;您就拥有了创作引人入胜视频内容的强大工具。以下是更多精选的视频素材网站&#xff0c;旨在为您的视频项目提供更广阔的视野…

uniapp uni.scss中使用@mixin混入,在文件引入@include 样式不生效 Error: Undefined mixin.(踩坑记录一)

问题&#xff1a; 在uni.scss文件定义mixin 2. 在vue文件引入: 3. 出现报错信息: 4. 问题思考&#xff1a; 是不是需要引入uni.scss &#xff1f; 答案不需要 uni.scss是一个特殊文件&#xff0c;在代码中无需 import 这个文件即可在scss代码中使用这里的样式变量。uni-app的…

算法day30 回溯6

332 重新安排行程 给你一份航线列表 tickets &#xff0c;其中 tickets[i] [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。 所有这些机票都属于一个从 JFK&#xff08;肯尼迪国际机场&#xff09;出发的先生&#xff0c;所以该行程必须从 JFK …

LoRa物联网行业解决方案 1

1 行业应用 智慧停车 智能抄表 智慧牧场 智能生产 智能物流 智能健康 2 物联网智慧农场项目需求 3 为什么选lora&#xff1f; 4 设计 5 模块性能参数 sx1278 lora扩频无线模块 SEMTECH公司SX1278芯片 LoRa 扩频技术 通信距离10000米 SPI通信接口 mcu选型 硬件平台介绍 …

【Web】2024红明谷CTF初赛个人wp(2/4)

目录 ezphp playground 时间原因只打了2个小时&#xff0c;出了2道&#xff0c;简单记录一下 ezphp 参考文章 PHP filter chains: file read from error-based oracle https://github.com/synacktiv/php_filter_chains_oracle_exploit 用上面的脚本爆出部分源码&#xff…

算法打卡day34|动态规划篇02| Leetcode 62.不同路径、63. 不同路径 II

算法题 Leetcode 62.不同路径 题目链接:62.不同路径 大佬视频讲解&#xff1a;不同路径视频讲解 个人思路 这道题非常经典&#xff0c;课后题也有&#xff0c;思路就是先初始化第一行和第一列的值&#xff0c;然后利用动规把到每一步计算出来&#xff0c;这样到终点就知道其左…