ROS节点检测ArUco标签并记录空间坐标

简介: 利用Realsense D435i相机检测ArUco标签,使用Python程序订阅相机的ROS话题,记录Time和标签的XYZ值,储存在一个csv文件中;当出现识别不到标签或者反馈坐标为0,0,0的情况时,不进行记录。

实验目的:

利用Realsense D435i相机检测ArUco标签,使用Python程序订阅相机的ROS话题,记录Time和标签的XYZ值,储存在一个csv文件中;当出现识别不到标签或者反馈坐标为0,0,0的情况时,不进行记录。

程序内容:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rospy
import csv
from sensor_msgs.msg import Image, CameraInfo
from geometry_msgs.msg import PointStamped
from cv_bridge import CvBridge
import cv2
import os
from datetime import datetime
aruco_pub = None
camera_info = None
depth_image_msg = None
csv_data = []
def detect_aruco(image):
    global csv_data
    aruco_dict = cv2.aruco.Dictionary_get(cv2.aruco.DICT_ARUCO_ORIGINAL)
    cv_image = CvBridge().imgmsg_to_cv2(image, "bgr8")
    gray = cv2.cvtColor(cv_image, cv2.COLOR_BGR2GRAY)
    parameters = cv2.aruco.DetectorParameters_create()
    corners, ids, _ = cv2.aruco.detectMarkers(gray, aruco_dict, parameters=parameters)
    if ids is None:
        rospy.loginfo("No ArUco marker found in the image.")
    else:
        for i in range(len(ids)):
            aruco_id = ids[i][0]
            aruco_center_x = int((corners[i][0][0][0] + corners[i][0][1][0] + corners[i][0][2][0] + corners[i][0][3][0]) / 4)
            aruco_center_y = int((corners[i][0][0][1] + corners[i][0][1][1] + corners[i][0][2][1] + corners[i][0][3][1]) / 4)
            try:
                depth_image_msg = rospy.wait_for_message("/camera/depth/image_rect_raw", Image, timeout=1.0)
            except rospy.ROSException:
                rospy.logwarn("Failed to get depth image.")
                return
            depth_image = CvBridge().imgmsg_to_cv2(depth_image_msg, "passthrough")
            aruco_center_x = min(max(0, aruco_center_x), depth_image.shape[1] - 1)
            aruco_center_y = min(max(0, aruco_center_y), depth_image.shape[0] - 1)
            depth = depth_image[aruco_center_y, aruco_center_x]
            if depth != 0:
                if camera_info is not None:
                    K = camera_info.K
                    Z = depth / 1000.0
                    X = (aruco_center_x - K[2]) * Z / K[0]
                    Y = (aruco_center_y - K[5]) * Z / K[4]
                    rospy.loginfo("Detected ArUco marker with ID: {}. 3D Coordinates: ({}, {}, {})".format(aruco_id, X, Y, Z))
                    # 记录数据到csv_data列表
                    csv_data.append([rospy.Time.now().to_sec(), X, Y, Z])
def image_callback(data):
    global depth_image_msg
    detect_aruco(data)
def camera_info_callback(data):
    global camera_info
    camera_info = data
def main():
    global aruco_pub, csv_data
    rospy.init_node('aruco_detection_node', anonymous=True)
    image_sub = rospy.Subscriber("/camera/color/image_raw", Image, image_callback)
    camera_info_sub = rospy.Subscriber("/camera/color/camera_info", CameraInfo, camera_info_callback)
    # 不再发布3D坐标信息到话题/aruco_info,因此这里不需要创建Publisher了
    rospy.spin()
    # 保存数据到csv文件
    if csv_data:
        folder_path = "aruco_tracks"
        if not os.path.exists(folder_path):
            os.makedirs(folder_path)
        file_name = datetime.now().strftime("%Y%m%d_%H%M%S") + ".csv"
        file_path = os.path.join(folder_path, file_name)
        with open(file_path, mode='w') as file:
            writer = csv.writer(file)
            writer.writerow(['Time', 'X', 'Y', 'Z'])
            writer.writerows(csv_data)
if __name__ == "__main__":
    try:
        main()
    except rospy.ROSInterruptException:
        pass
相关实践学习
Docker镜像管理快速入门
本教程将介绍如何使用Docker构建镜像,并通过阿里云镜像服务分发到ECS服务器,运行该镜像。
阿里云资源编排ROS使用教程
资源编排(Resource Orchestration)是一种简单易用的云计算资源管理和自动化运维服务。用户通过模板描述多个云计算资源的依赖关系、配置等,并自动完成所有资源的创建和配置,以达到自动化部署、运维等目的。编排模板同时也是一种标准化的资源和应用交付方式,并且可以随时编辑修改,使基础设施即代码(Infrastructure as Code)成为可能。 产品详情:https://www.aliyun.com/product/ros/
目录
相关文章
|
8月前
|
存储 缓存 算法
【ROS】如何让ROS中节点获取数据 III --参数服务器通信及ros常用工具指令介绍
相较于之前的通信模型,参数服务器是最为简单的。在之前的模型中,ROSMASTER都是扮演一个帮二者连接在一起的桥梁。
181 0
|
2月前
|
C++ Python
[ROS2] --- 手动编写一个节点
[ROS2] --- 手动编写一个节点
34 1
|
8月前
|
算法 中间件 C语言
【ROS】如何让ROS中节点实现数据交换Ⅱ --服务通信
在ros中,一个节点想要获取某种服务(例如:一个节点想要获取此时的相机数据,节点就需要向相机发送一个请求,而相机接收到请求后可以根据消息类型将数据类型返回),这就是基本的服务通信使用场景。
101 0
|
8月前
|
消息中间件 算法 机器人
【ROS】如何让ROS中节点实现数据交换Ⅰ--ROS话题通信
比较常用的目前就这一些,之后的命令现用现学就好了
169 1
【3. 初学ROS,年轻人的第一个Node节点】
【3. 初学ROS,年轻人的第一个Node节点】
66 0
|
Shell
奥比中光ROS启动节点运行异常退出:[camera/driver-2] process has finished cleanly
奥比中光ROS启动节点运行异常退出:[camera/driver-2] process has finished cleanly
339 0
奥比中光ROS启动节点运行异常退出:[camera/driver-2] process has finished cleanly
|
C++ Python
ROS学习-理解ROS节点
ROS学习-理解ROS节点
206 0
ROS学习-理解ROS节点

推荐镜像

更多