ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

How to convert Python script to ROS script? (Measuring distance between two points using RealSense depth camera)

asked 2023-04-13 18:47:28 -0500

Vuro H gravatar image

I have written a Python script which uses a RealSense depth camera to measure the distance between two points in the input image. The distance returned is very accurate. I have tried converting this Python script to a rospy script, but I do not get the same result. I'm not sure if I'm not subscribing to the correct ROS topics or not handling the data correctly. The working Python script is written as follows - how can I convert this to a ROS script, please?

import pyrealsense2 as rs
import math

class distance_measure:
    def __init__(self):
        self.pipeline = rs.pipeline()
        self.pipeline.start(rs.config())
        print("Class initialized")

    def depth_cam(self):
        align_to = rs.stream.color
        align = rs.align(align_to)

        for i in range(5):
            self.pipeline.wait_for_frames()
            print("Received frame", i)

        while True:
            frames = self.pipeline.wait_for_frames()
            aligned_frames = align.process(frames)
            color_frame = aligned_frames.get_color_frame()
            self.depth_frame = aligned_frames.get_depth_frame()

            self.color_intrin = color_frame.profile.as_video_stream_profile().intrinsics

            self.x1 = 480
            self.y1 = 550
            self.x2 = 810
            self.y2 = self.y1
            ans = self.calculate_distance()
            print('distance:',ans)

            break

    def calculate_distance(self):
        udist = self.depth_frame.get_distance(self.x1, self.y1)
        vdist = self.depth_frame.get_distance(self.x2, self.y2)
        print(udist,vdist)

        point1 = rs.rs2_deproject_pixel_to_point(self.color_intrin, [self.x1, self.y1], udist)
        point2 = rs.rs2_deproject_pixel_to_point(self.color_intrin, [self.x2, self.y2], vdist)
        print(str(point1)+str(point2))

        dist = math.sqrt(math.pow(point1[0] - point2[0], 2) + math.pow(point1[1] - point2[1], 2) + math.pow(point1[2] - point2[2], 2))
        return dist


if __name__ == '__main__':
    distance_measure().depth_cam()
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2023-04-14 08:58:24 -0500

Ranjit Kathiriya gravatar image

You need to follow this steps,

  1. Create a ROS node
  2. Create a subscriber to receive the depth image data
  3. Extract the depth values of the two points from the depth image data
  4. Calculate the distance between the two points using the extracted depth values
  5. Publish the calculated distance to a ROS topic

Or else, you can also use realsense-ros package to achieve the results. You can calculate the distance of two specific points by this answer #q372672, then subscribe to the camera of real sense and follow others' steps.

#!/usr/bin/env python

import rospy
import cv_bridge
import numpy as np
import pyrealsense2 as rs
from sensor_msgs.msg import Image
from cv_bridge import CvBridge

class distance_measure:
    def __init__(self):
        self.pipeline = rs.pipeline()
        self.pipeline.start(rs.config())
        self.bridge = CvBridge()
        self.sub = rospy.Subscriber('/camera/depth/image_raw', Image, self.depth_callback)
        self.pub = rospy.Publisher('/distance', Float32, queue_size=5)

    def depth_callback(self, data):
        cv_image = self.bridge.imgmsg_to_cv2(data, desired_encoding="passthrough")
        self.depth_frame = cv2.convertScaleAbs(cv_image, alpha=0.01)

        self.color_intrin = rs.video_stream_profile(self.pipeline.get_active_profile().get_stream(rs.stream.color)).get_intrinsics()

        self.x1 = 480
        self.y1 = 550
        self.x2 = 810
        self.y2 = self.y1
        ans = self.calculate_distance()
        self.pub.publish(ans)

    def calculate_distance(self):
        udist = self.depth_frame[self.y1, self.x1]
        vdist = self.depth_frame[self.y2, self.x2]

        point1 = rs.rs2_deproject_pixel_to_point(self.color_intrin, [self.x1, self.y1], udist)
        point2 = rs.rs2_deproject_pixel_to_point(self.color_intrin, [self.x2, self.y2], vdist)

        dist = math.sqrt(math.pow(point1[0] - point2[0], 2) + math.pow(point1[1] - point2[1], 2) + math.pow(point1[2] - point2[2], 2))
        return dist

if __name__ == '__main__':
    rospy.init_node('distance_measure')
    distance_measure()
    rospy.spin()
edit flag offensive delete link more

Comments

Thanks for your answer, Ranjit. Unfortunately your script does not work for me. I'm not sure if this is a personal problem or a general problem, but I don't seem to be able to use the RealSense pipeline and ROS topics at the same time. Since I want to subscribe and publish to other ROS topics, do you know how to achieve the goal without using RealSense pipeline + dependencies? Thanks again for your help with this.

Vuro H gravatar image Vuro H  ( 2023-04-16 14:23:51 -0500 )edit

I just thought this should work, I have not tested it myself, You can also use with ros1 package realsense2_camera.

Note: you need to subscribe to depth channel for calculation of distance rest code is going to be same.

Ranjit Kathiriya gravatar image Ranjit Kathiriya  ( 2023-04-17 01:59:14 -0500 )edit

If the code you have is working you can also simply convert it into a publisher node by adding about a dozen lines of code. Then you'll get your distance as you have been and publish that distance to the ROS environment for your other nodes to make use of.

The tutorial here provides a great guide for doing so.

i0nly gravatar image i0nly  ( 2023-04-17 07:34:49 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2023-04-13 18:47:28 -0500

Seen: 379 times

Last updated: Apr 14 '23