需求
需要編寫一個Python程序,訂閱電腦外接的深度相機發出的視頻消息,錄制視頻并逐幀保存為圖片到本地,用于采集制作數據集的圖片信息
運行環境
Ubuntu18.04 + ROS Melodic + Python2.7
Python程序
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rospy
import cv2
from sensor_msgs.msg import Image
from cv_bridge import CvBridgeclass VideoRecorder:def __init__(self):self.bridge = CvBridge()self.image_sub = rospy.Subscriber('/camera/color/image_raw', Image, self.image_callback)self.frames = []self.recording = Falsedef image_callback(self, msg):try:cv_image = self.bridge.imgmsg_to_cv2(msg, "bgr8")if self.recording:self.frames.append(cv_image)except Exception as e:print(e)def start_recording(self):self.frames = []self.recording = Truedef stop_recording(self):self.recording = Falseif self.frames:self.save_frames()def save_frames(self):for i, frame in enumerate(self.frames):filename = 'frame_{:04d}.jpg'.format(i)cv2.imwrite(filename, frame)print('Saved {} frames.'.format(len(self.frames)))if __name__ == '__main__':rospy.init_node('video_recorder_node', anonymous=True)recorder = VideoRecorder()try:while not rospy.is_shutdown():cmd = raw_input("Enter 'start' to begin recording or 'stop' to stop recording: ")if cmd == 'start':recorder.start_recording()elif cmd == 'stop':recorder.stop_recording()except rospy.ROSInterruptException:pass
程序解釋
這段代碼是一個用于ROS(Robot Operating System)環境下的Python程序,用于訂閱相機圖像消息并將圖像保存為視頻幀。
1. 首先,代碼聲明了使用Python解釋器,并設置了文件的編碼格式為utf-8。
2. 導入了所需的庫和模塊:
? ?- `rospy`:ROS的Python客戶端庫,用于創建ROS節點、發布和訂閱消息等。
? ?- `cv2`:OpenCV庫,用于圖像處理和計算機視覺任務。
? ?- `Image`:來自`sensor_msgs.msg`模塊的消息類型,用于傳輸圖像數據。
? ?- `CvBridge`:用于在ROS消息和OpenCV圖像之間進行轉換的工具類。
3. 定義了一個名為`VideoRecorder`的類,其中包含以下方法:
? ?- `__init__(self)`:類的初始化方法,在其中進行一些必要的設置。創建了一個`CvBridge`實例,用于ROS圖像和OpenCV圖像的轉換;訂閱了名為`/camera/color/image_raw`的相機圖像消息,并將回調函數設置為`image_callback`;初始化了用于存儲幀的列表`frames`,以及一個表示是否正在錄制的標志`recording`。
? ?- `image_callback(self, msg)`:圖像消息的回調函數。將ROS圖像消息轉換為OpenCV格式,如果正在錄制,則將幀添加到`frames`列表中。
? ?- `start_recording(self)`:開始錄制方法。清空`frames`列表,并將`recording`標志設置為True。
? ?- `stop_recording(self)`:停止錄制方法。將`recording`標志設置為False,并調用`save_frames`方法保存已錄制的幀。
? ?- `save_frames(self)`:保存幀方法。遍歷`frames`列表,將每幀圖像保存為JPEG文件,并在控制臺輸出保存的幀數。
4. 在`if __name__ == '__main__':`語句塊中:
? ?- 初始化了ROS節點,節點名為`video_recorder_node`,設置為匿名節點。
? ?- 創建了`VideoRecorder`類的實例`recorder`。
? ?- 在一個無限循環中,等待用戶輸入命令。如果輸入為`start`,則調用`start_recording`方法開始錄制;如果輸入為`stop`,則調用`stop_recording`方法停止錄制。
? ?- 通過捕獲`rospy.ROSInterruptException`異常來保證程序在收到終止信號時能夠正常退出。
總之,這段代碼通過ROS接收相機圖像消息,并根據用戶輸入的命令開始或停止錄制圖像幀,然后將錄制的幀保存為JPEG文件。