Обработать сообщение изображения глубины из ROS с помощью OpenCV

#image #opencv #image-processing #ros

#изображение #opencv #обработка изображений #ros

Вопрос:

итак, в настоящее время я пишу скрипт на python, который должен получать сообщение изображения ros, а затем преобразовывать его в cv2, чтобы я мог выполнять дальнейшую обработку. Прямо сейчас программа просто получает изображение, а затем выводит его в маленьком окне, а также сохраняет его в формате png. Вот мой код:

 #! /usr/bin/python
import rospy 
from sensor_msgs.msg import Image

from cv_bridge import CvBridge, CvBridgeError
import cv2



bridge = CvBridge()


def image_callback(msg):
     print("Received an image!")

     print(msg.encoding)


try:
    # Convert your ROS Image message to OpenCV2
    # Converting the rgb8 image of the front camera, works fine

    cv2_img = bridge.imgmsg_to_cv2(msg, 'rgb8')

    # Converting the depth images, does not work 

    #cv2_img = bridge.imgmsg_to_cv2(msg, '32FC1')        
    
    
    

except CvBridgeError, e:
    print(e)

else:
    # Save your OpenCV2 image as a png
    cv2.imwrite('camera_image.png', cv2_img)
    cv2.imshow('pic', cv2_img)
    cv2.waitKey(0)

def main():
    rospy.init_node('image_listener')
    #does not work:
    #image_topic = "/pepper/camera/depth/image_raw"
    #works fine:
    image_topic = "/pepper/camera/front/image_raw"
    rospy.Subscriber(image_topic, Image, image_callback)
rospy.spin()


if __name__ == '__main__':
     main()
  

Итак, моя проблема в том, что мой код работает отлично, если я использую данные фронтальной камеры, но не работает для изображений глубины.
Чтобы убедиться, что я получаю правильный тип кодировки, я использовал команду msg.encoding, которая сообщает мне тип кодировки текущего сообщения ros.
Cv2.imshow работает точно так же, как и для снимков с фронтальной камеры, и показывает мне то же самое, что я получил бы, если бы использовал ros image_view, но как только я попробую это с изображением глубины, я просто получаю полностью черное или белое изображение, в отличие от того, что показывает мне image_view

Вот изображение глубины, которое я получаю при использовании image_view

Вот изображение глубины, которое я получаю при использовании скрипта и cv2.imshow

Есть ли у кого-нибудь опыт работы с изображениями глубины с помощью cv2 и может ли он помочь мне заставить его работать и с изображениями глубины? Я действительно был бы признателен за любую помощь 🙂

С наилучшими пожеланиями

Комментарии:

1. Я действительно ничего не знаю о ROS, но хотел бы отметить, что формат PNG не может хранить 32-разрядные числа с плавающей запятой. Я думаю, вам нужно либо написать TIFF, который может хранить 32-битные числа с плавающей запятой, либо преобразовать в 16-битный unsigned, который может хранить PNG.

Ответ №1:

Вы могли бы попробовать следующим образом получить изображения глубины,

     import rospy
    from cv_bridge import CvBridge, CvBridgeError
    from sensor_msgs.msg import Image
    import numpy as np
    import cv2

    def convert_depth_image(ros_image):
        cv_bridge = CvBridge()
        try:
            depth_image = cv_bridge.imgmsg_to_cv2(ros_image, desired_encoding='passthrough')
        except CvBridgeError, e:
            print e
        depth_array = np.array(depth_image, dtype=np.float32)
        np.save("depth_img.npy", depth_array)
        rospy.loginfo(depth_array)
        #To save image as png
        # Apply colormap on depth image (image must be converted to 8-bit per pixel first)
        depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.03), cv2.COLORMAP_JET)
        cv2.imwrite("depth_img.png", depth_colormap)
        #Or you use 
        # depth_array = depth_array.astype(np.uint16)
        # cv2.imwrite("depth_img.png", depth_array)


    def pixel2depth():
        rospy.init_node('pixel2depth',anonymous=True)
        rospy.Subscriber("/pepper/camera/depth/image_raw", Image,callback=convert_depth_image, queue_size=1)
        rospy.spin()

    if __name__ == '__main__':
        pixel2depth()
  

Комментарии:

1. Здравствуйте, я попробовал оба из них, первый с цветовой картой привел к синему изображению, а второй — только к черному изображению

2. Я также попытался его реализовать. Те же результаты, только синее изображение