spectrum_to_spectrogram.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 import cv2
4 from cv_bridge import CvBridge
5 import numpy as np
6 import rospy
7 
8 from jsk_recognition_msgs.msg import Spectrum
9 from sensor_msgs.msg import Image
10 
11 
12 # This node publish spectrogram (sensor_msgs/Image)
13 # from spectrum (jsk_recognition_msgs/Spectrum)
14 
15 class SpectrumToSpectrogram(object):
16 
17  def __init__(self):
18  super(SpectrumToSpectrogram, self).__init__()
19  # Set spectrogram shape
20  self.image_height = rospy.get_param('~image_height', 300)
21  self.image_width = rospy.get_param('~image_width', 300)
22  # Get spectrum length
23  spectrum_msg = rospy.wait_for_message('~spectrum', Spectrum)
24  spectrum_len = len(spectrum_msg.amplitude)
25  # Buffer for spectrum topic
26  self.spectrogram = np.zeros((0, spectrum_len), dtype=np.float32)
27  self.spectrum_stamp = []
28  # Period[s] to store audio data to create one spectrogram topic
29  self.spectrogram_period = rospy.get_param('~spectrogram_period', 5)
30  # ROS subscriber and publisher
31  rospy.Subscriber(
32  '~spectrum', Spectrum, self.audio_cb)
33  self.pub_spectrogram = rospy.Publisher(
34  '~spectrogram', Image, queue_size=1)
35  publish_rate = rospy.get_param(
36  '~publish_rate', float(self.image_width / self.spectrogram_period))
37  rospy.Timer(
38  rospy.Duration(
39  1.0 / publish_rate),
40  self.timer_cb)
41  self.bridge = CvBridge()
42 
43  def audio_cb(self, msg):
44  # Add spectrum msg to buffer
45  spectrum = np.array(msg.amplitude, dtype=np.float32)
46  self.spectrogram = np.concatenate(
47  [self.spectrogram, spectrum[None]])
48  self.spectrum_stamp.append(msg.header.stamp)
49  # Extract spectrogram of last (self.spectrogram_period) seconds
50  time_now = rospy.Time.now()
51  for i, stamp in enumerate(self.spectrum_stamp):
52  if (time_now - stamp).to_sec() < self.spectrogram_period:
53  self.spectrogram = self.spectrogram[i:]
54  self.spectrum_stamp = self.spectrum_stamp[i:]
55  break
56 
57  def timer_cb(self, timer):
58  if self.spectrogram.shape[0] == 0:
59  return
60  # Reshape spectrogram
61  spectrogram = self.spectrogram.transpose(1, 0)[::-1, :]
62  spectrogram = cv2.resize(
63  spectrogram, (self.image_width, self.image_height))
64  # Publish spectrogram
65  spectrogram_msg = self.bridge.cv2_to_imgmsg(spectrogram, '32FC1')
66  spectrogram_msg.header.stamp = self.spectrum_stamp[-1]
67  self.pub_spectrogram.publish(spectrogram_msg)
68 
69 
70 if __name__ == '__main__':
71  rospy.init_node('audio_to_spectrogram')
73  rospy.spin()


audio_to_spectrogram
Author(s):
autogenerated on Mon May 3 2021 03:02:58