最近需要将.avi格式的视频转换成rosbag,方便跑包。
#include <iostream>
#include <ros/ros.h>
#include <rosbag/bag.h>
#include <opencv2/highgui/highgui.hpp>
#include"cv_bridge/cv_bridge.h"
using namespace std;
using namespace cv;
int main(int argc,char **argv)
{
ros::init(argc, argv, "rosbag_recode_node");
ros::NodeHandle nh;
rosbag::Bag bag;
bag.open("/home/xxx/视频/raw.bag", rosbag::bagmode::Write);
cv::VideoCapture cap("/home/xxx/视频/abc.avi");
long totalFrameNum = cap.get(CV_CAP_PROP_FRAME_COUNT);
long FrameCount = 0;
cout << "total frame" << totalFrameNum << endl;
while (ros::ok())
{
cv::Mat frame;
cap >> frame;
if (frame.empty()) {
std::cout << "error, no image" << std::endl;
return -1;
}
cv::imshow("image", frame);
cv::waitKey(25);//此处的waitKey很重要,影响了录制长度
std_msgs::Header header;
header.frame_id = "image_frame";
header.stamp = ros::Time::now();
sensor_msgs::ImagePtr image_msg = cv_bridge::CvImage(header, "bgr8", frame).toImageMsg();
// sensor_msgs::CompressedImagePtr compressed_image_msg = cv_bridge::CvImage(header, "bgr8", frame).toCompressedImageMsg();
if(FrameCount % 2 == 0)
bag.write("/camera/image_raw", ros::Time::now(), image_msg);
// bag.write("image_raw/compressed", ros::Time::now(), compressed_image_msg);
//ros::Time time;
//time.fromNSec(timestamp); // 从图像数据集生成bag时,timestamp一般为图像名
//bag.write("image_topic", time, msg);
++FrameCount;
}
bag.close();
cap.release();
return 0;
}
CMakeLists:
cmake_minimum_required(VERSION 3.2)
project(videobag)
set(CMAKE_CXX_STANDARD 11)
set( EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin )
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
find_package(catkin REQUIRED COMPONENTS
roscpp
rosbag
cv_bridge
)
include_directories(
${catkin_INCLUDE_DIRS}
)
add_executable(videobag src/main.cpp)
target_link_libraries(videobag
${catkin_LIBRARIES}
${OpenCV_LIBS})
已解决的问题:
1.当cv::waitKey(10)时,录制的rosbag会存在卡顿现象,并且整体速率也不太对。调整这里的时长就行。
2.降低录制帧率,具体见代码。