Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgraded extract_images_sync script to ROS 2 #919

Merged
merged 9 commits into from
Jan 31, 2024
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
*pyc
.vscode/settings.json
2 changes: 2 additions & 0 deletions image_view/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<maintainer email="[email protected]">Joshua Whitley</maintainer>
<maintainer email="[email protected]">Jacob Perron</maintainer>
<maintainer email="[email protected]">Michael Ferguson</maintainer>
<maintainer email="[email protected]">Siddharth Vaghela</maintainer>
artineering marked this conversation as resolved.
Show resolved Hide resolved

<license>BSD</license>
<url type="website">https://index.ros.org/p/image_view/github-ros-perception-image_pipeline/</url>
Expand All @@ -25,6 +26,7 @@
<depend>cv_bridge</depend>
<depend>image_transport</depend>
<depend>message_filters</depend>
<depend>rclpy</depend>
artineering marked this conversation as resolved.
Show resolved Hide resolved
<depend>rclcpp</depend>
<depend>rclcpp_components</depend>
<depend>sensor_msgs</depend>
Expand Down
59 changes: 33 additions & 26 deletions image_view/scripts/extract_images_sync
Original file line number Diff line number Diff line change
Expand Up @@ -33,47 +33,51 @@
# POSSIBILITY OF SUCH DAMAGE.
"""Save images of multiple topics with timestamp synchronization.

Usage: rosrun image_view extract_images_sync _inputs:='[<topic_0>, <topic_1>]'
Usage: ros2 run image_view extract_images_sync _inputs:='[<topic_0>, <topic_1>]'
artineering marked this conversation as resolved.
Show resolved Hide resolved
"""

import sys

import cv2

import cv_bridge
import message_filters
import rospy
from sensor_msgs.msg import Image
import rclpy

from rclpy.node import Node
from sensor_msgs.msg import Image
from message_filters import ApproximateTimeSynchronizer, TimeSynchronizer, Subscriber

class ExtractImagesSync(object):
class ExtractImagesSync(Node):

def __init__(self):
super().__init__('extract_images_sync')
self.get_logger().info('Extract_Images_Sync Node has been started')
self.seq = 0
self.fname_fmt = rospy.get_param(
'~filename_format', 'frame%04i_%i.jpg')
self.do_dynamic_scaling = rospy.get_param(
'~do_dynamic_scaling', False)
img_topics = rospy.get_param('~inputs', None)
self.fname_fmt = self.declare_parameter(
'filename_format', 'frame%04i_%i.jpg').value
self.do_dynamic_scaling = self.declare_parameter(
'do_dynamic_scaling', False).value
img_topics = self.declare_parameter('_inputs', None).value
artineering marked this conversation as resolved.
Show resolved Hide resolved

if img_topics is None:
rospy.logwarn("""\
extract_images_sync: rosparam '~inputs' has not been specified! \
self.get_logger().warn("""\
extract_images_sync: Parameter '_inputs' has not been specified! \
Typical command-line usage:
\t$ rosrun image_view extract_images_sync _inputs:=<image_topic>
\t$ rosrun image_view extract_images_sync \
\t$ ros2 run image_view extract_images_sync _inputs:=<image_topic>
artineering marked this conversation as resolved.
Show resolved Hide resolved
\t$ ros2 run image_view extract_images_sync \
_inputs:='[<image_topic>, <image_topic>]'""")
sys.exit(1)

if not isinstance(img_topics, list):
img_topics = [img_topics]

subs = []
for t in img_topics:
subs.append(message_filters.Subscriber(t, Image))
if rospy.get_param('~approximate_sync', False):
sync = message_filters.ApproximateTimeSynchronizer(
subs, queue_size=100, slop=.1)
subs.append(Subscriber(self, Image, t))

self.approximate_sync = self.declare_parameter('approximate_sync', False).value;
if not self.approximate_sync:
artineering marked this conversation as resolved.
Show resolved Hide resolved
sync = ApproximateTimeSynchronizer(subs, 100, slop=0.1)
else:
sync = message_filters.TimeSynchronizer(
subs, queue_size=100)
sync = TimeSynchronizer(subs, 100)
sync.registerCallback(self.save)

def save(self, *imgmsgs):
Expand All @@ -84,16 +88,19 @@ _inputs:='[<image_topic>, <image_topic>]'""")
channels = img.shape[2] if img.ndim == 3 else 1
encoding_in = bridge.dtype_with_channels_to_cvtype2(
img.dtype, channels)
img = cv_bridge.cvtColorForDisplay(
img = cv_bridge.cvtColor_for_display(
img, encoding_in=encoding_in, encoding_out='',
do_dynamic_scaling=self.do_dynamic_scaling)
fname = self.fname_fmt % (seq, i)
print('Save image as {0}'.format(fname))
cv2.imwrite(fname, img)
self.seq = seq + 1

def main(args=None):
rclpy.init(args=args)
extractor = ExtractImagesSync()
rclpy.spin(extractor)
rclpy.shutdown()

if __name__ == '__main__':
rospy.init_node('extract_images_sync')
extractor = ExtractImagesSync()
rospy.spin()
main()