You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am currently working on a project where I need to decompress images coming from a Basler camera in a ROS2 environment using the Pylon SDK in Python (or any other method that can achieve this goal) to visualize them in RVIZ2. The images are published to a ROS2 topic as sensor_msgs/Image messages, but they are actually compressed and appear as static noise when visualized in RVIZ2. My objective is to decompress these images and publish them again in a decompressed format that can be visualized correctly in RVIZ2.
Issue and Steps to Reproduce
I am using the following Python code to attempt to decompress the images using the Pylon SDK (still experminting):
#!/usr/bin/env python3importrclpyfromrclpy.nodeimportNodefromsensor_msgs.msgimportImagefrompypylonimportpylonfromcv_bridgeimportCvBridgeimportnumpyasnpimportcv2classPylonImageDecompressorNode(Node):
def__init__(self):
super().__init__('pylon_image_decompressor')
self.bridge=CvBridge()
# Set up the Pylon image decompressorself.decompressor=pylon.ImageDecompressor()
# Subscriber to the compressed image topic (published as Image)self.image_sub=self.create_subscription(
Image, # Message type for the incoming image even if it is compressed'/my_camera/pylon_ros2_camera_node/image_raw', # The actual topic with compressed dataself.image_callback,
10
)
# Publisher to output the decompressed imageself.image_pub=self.create_publisher(
Image, # Message type: Image'pylon/camera/decompressed_image', # Topic to publish to10
)
defimage_callback(self, msg):
self.get_logger().info('Received a compressed image wrapped in an Image message.')
try:
# Extract raw data from the ROS2 Image messagenp_arr=np.frombuffer(msg.data, np.uint8)
# Calculate buffer size in bytesbuffer_size=np_arr.size*np_arr.itemsize# Create a Pylon image objectpylon_image=pylon.PylonImage()
# Attach the raw buffer to the Pylon image object using the correct parameterspylon_image.AttachUserBuffer(
np_arr.ctypes.data, # Pointer to the databuffer_size, # Size of the data in bytespylon.PixelType_Mono8, # EPixelType for mono8 formatmsg.width, # Image widthmsg.height, # Image height0, # PaddingX (no padding in mono8 format)pylon.ImageOrientation_TopDown# Image orientation (default TopDown)
)
# Decompress the image using the Pylon SDKdecompressed_image=self.decompressor.DecompressImage(pylon_image)
# Convert the decompressed Pylon image to a numpy array (OpenCV format)img_array=decompressed_image.GetArray()
# Determine the correct encoding formatiflen(img_array.shape) ==2orimg_array.shape[2] ==1:
img_array=cv2.cvtColor(img_array, cv2.COLOR_GRAY2BGR)
encoding="bgr8"else:
encoding="bgr8"# Convert the numpy array (OpenCV image) to a ROS Image messageimage_msg=self.bridge.cv2_to_imgmsg(img_array, encoding=encoding)
# Publish the decompressed image to the ROS topicself.image_pub.publish(image_msg)
self.get_logger().info("Published decompressed image.")
# Release resourcesdecompressed_image.Release()
exceptExceptionase:
self.get_logger().error(f"Error decompressing image: {e}")
defdestroy_node(self):
super().destroy_node()
defmain(args=None):
rclpy.init(args=args)
node=PylonImageDecompressorNode()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
if__name__=='__main__':
main()
I have also used this to successfully decompress images directly from a connected camera (will not work with pylon_ros2_driver):
#!/usr/bin/env python3importrclpyfromrclpy.nodeimportNodefromsensor_msgs.msgimportImagefrompypylonimportpylon# Pylon SDK for Basler camera interactionfromcv_bridgeimportCvBridge# Bridge between ROS 2 image messages and OpenCVimportnumpyasnp# NumPy for array manipulationimportcv2# OpenCV library for image processingclassPylonImageDecompressorNode(Node):
def__init__(self):
# Initialize the node with the name 'pylon_image_decompressor'super().__init__('pylon_image_decompressor')
# Create a publisher to output the decompressed imageself.image_pub=self.create_publisher(
Image, # Message type: Image'pylon/camera/decompressed_image', # Topic to publish to10# Queue size for outgoing messages
)
# Initialize CvBridge to convert between ROS and OpenCV imagesself.bridge=CvBridge()
# Set up the Basler cameraself.camera=self.setup_camera()
# Set up the Pylon image decompressorself.decompressor=pylon.ImageDecompressor()
# Retrieve and set the compression descriptor from the cameradescriptor=self.camera.BslImageCompressionBCBDescriptor.GetAll()
self.decompressor.SetCompressionDescriptor(descriptor)
# Start grabbing images from the cameraself.camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly)
# Main loop for grabbing and processing imagesself.timer=self.create_timer(0.1, self.process_images)
defsetup_camera(self):
# Get the first available camera devicecamera=pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateFirstDevice())
camera.Open()
# Configure the camera settingscamera.Width.SetValue(2600) # Example width, set according to your camera specscamera.Height.SetValue(2128) # Example height, set according to your camera specscamera.ImageCompressionMode.SetValue('BaslerCompressionBeyond')
camera.ImageCompressionRateOption.SetValue('Lossless')
camera.BslImageCompressionRatio.SetValue(90.0)
self.get_logger().info(f"Camera {camera.GetDeviceInfo().GetModelName()} initialized with compression settings.")
returncameradefprocess_images(self):
ifself.camera.IsGrabbing():
# Retrieve the latest image from the cameragrab_result=self.camera.RetrieveResult(5000, pylon.TimeoutHandling_ThrowException)
ifgrab_result.GrabSucceeded():
try:
# Decompress the imagedecompressed_image=self.decompressor.DecompressImage(grab_result)
# Convert the decompressed Pylon image to a numpy array (OpenCV format)img_array=decompressed_image.GetArray()
# Check the number of channels in the imageiflen(img_array.shape) ==2orimg_array.shape[2] ==1:
# Image is single channel (grayscale), convert to BGR formatimg_array=cv2.cvtColor(img_array, cv2.COLOR_GRAY2BGR)
encoding="bgr8"else:
# Image is already in BGR formatencoding="bgr8"# Convert the numpy array (OpenCV image) to a ROS Image messageimage_msg=self.bridge.cv2_to_imgmsg(img_array, encoding=encoding)
# Publish the decompressed image to the ROS topicself.image_pub.publish(image_msg)
self.get_logger().info("Published decompressed image.")
# Release resourcesdecompressed_image.Release()
grab_result.Release()
exceptExceptionase:
self.get_logger().error(f"Error decompressing image: {e}")
else:
self.get_logger().warn(f"Image grab failed: {grab_result.GetErrorDescription()}")
defdestroy_node(self):
# Stop the camera grabbing when the node is destroyedifself.camera.IsGrabbing():
self.camera.StopGrabbing()
self.camera.Close()
super().destroy_node()
defmain(args=None):
rclpy.init(args=args)
node=PylonImageDecompressorNode()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
if__name__=='__main__':
main()
Issue Encountered
I could not find a way to retrieve all the required data for the pylon decompressor (like Descriptor) considering the camera is already working using the ROS2 Driver and I can not open the camera or
currently, I encountered the following error:
[INFO] [1725900784.144116477] [pylon_image_decompressor]: Received a compressed image wrapped in an Image message.
[ERROR] [1725900784.144999987] [pylon_image_decompressor]: Error decompressing image: Wrong number or type of arguments for overloaded function 'ImageDecompressor_DecompressImage'.
Possible C/C++ prototypes are:
Pylon::CImageDecompressor::DecompressImage(Pylon::CGrabResultPtr const &)
Pylon::CImageDecompressor::DecompressImage(void const *,size_t)
This is the ros2 topic echo for /image_raw for the compressed images:
Host system infos:
CPU architecture: x86_64
Kernel type: linux
Kernel version: 6.8.0-40-generic
OS type: ubuntu
OS version: 22.04
Render Backend: OpenGL
Hello @ibr5456s
Thank you for your reporting.
You write: "they are actually compressed and appear as static noise when visualized in RVIZ2". I don't have your camera model but it should be possible to visualize the images in rviz and rqt. Did you try rqt?
I can't help you here with the Pylon decompressor, you should contact the Basler support to get some help from them.
Do your program work with images acquired from the pylon viewer and stored on your computer?
Hello,
I am currently working on a project where I need to decompress images coming from a Basler camera in a ROS2 environment using the Pylon SDK in Python (or any other method that can achieve this goal) to visualize them in RVIZ2. The images are published to a ROS2 topic as
sensor_msgs/Image
messages, but they are actually compressed and appear as static noise when visualized in RVIZ2. My objective is to decompress these images and publish them again in a decompressed format that can be visualized correctly in RVIZ2.Issue and Steps to Reproduce
I am using the following Python code to attempt to decompress the images using the Pylon SDK (still experminting):
I have also used this to successfully decompress images directly from a connected camera (will not work with pylon_ros2_driver):
Issue Encountered
I could not find a way to retrieve all the required data for the pylon decompressor (like Descriptor) considering the camera is already working using the ROS2 Driver and I can not open the camera or
currently, I encountered the following error:
This is the ros2 topic echo for /image_raw for the compressed images:
image_data.txt
Hardware setup description
Runtime information
pylon info: 8.0.0.10 64-Bit
pylon Setup info: 7.5.0.15658
pylon Application info: 3.3.0.15479 64-Bit
pylon Viewer info: 7.5.0.15479 64-Bit
Host system infos:
CPU architecture: x86_64
Kernel type: linux
Kernel version: 6.8.0-40-generic
OS type: ubuntu
OS version: 22.04
Render Backend: OpenGL
Screen(s):
Screen 0 scale factor: 1
Screen 0 resolution: 2880x1620
Window(s):
pylon Viewer 64-Bit" on screen 0
Host network infos:
Host network adapter enp45s0:
Name: enp45s0
MAC address: 58:11:22:89:3B:E1
Host network adapter docker0:
Name: docker0
MAC address: 02:42:9C:42:4B:72
IP address: 172.17.0.1
Subnet mask: 255.255.0.0
Host network adapter br-a296f01552f4:
Name: br-a296f01552f4
MAC address: 02:42:36:9B:A9:47
IP address: 172.18.0.1
Subnet mask: 255.255.0.0
Host network adapter wlp46s0:
Name: wlp46s0
MAC address: 14:13:33:88:A3:99
IP address: 192.168.0.212
Subnet mask: 255.255.255.0
The text was updated successfully, but these errors were encountered: