将序列图片保存成avi视频

举报
月照银海似蛟龙 发表于 2022/08/11 09:23:51 2022/08/11
【摘要】 Opencv是一个强大的计算机视觉库,它能将yuv图片转换为png/jpg等图片,同时它也能将一系列的png/jpg图片保存成avi格式的视频。注意:Opencv仅支持avi格式,且生成的视频文件不能大于2GB,且不能添加音频。如果想保存更多的视频格式或在视频文件中添加音频,需要使用更强大的多媒体开发工具FFmpeg。

Opencv是一个强大的计算机视觉库,它能将yuv图片转换为png/jpg等图片,同时它也能将一系列的png/jpg图片保存成avi格式的视频。注意:Opencv仅支持avi格式,且生成的视频文件不能大于2GB,且不能添加音频。如果想保存更多的视频格式或在视频文件中添加音频,需要使用更强大的多媒体开发工具FFmpeg。

核心函数分析

VideoWrite是写视频所用的类,其构造函数对应参数分析如下:

VideoWriter(const string& filename, int fourcc, double fps, Size frameSize, bool isColor=true)

函数参数:
filename:输出视频文件名
fourcc:四个字符用来表示压缩帧的编解码方式,对应编码方式主要有:
CV_FOURCC(‘P’, ‘I’, ‘M’, ‘1’) = MPEG-1 codec
CV_FOURCC(‘M’, ‘J’, ‘P’, ‘G’) = motion-jpeg codec
CV_FOURCC(‘M’, ‘P’, ‘4’, ‘2’) = MPEG-4.2 codec
CV_FOURCC(‘D’, ‘I’, ‘V’, ‘3’) = MPEG-4.3 codec
CV_FOURCC(‘D’, ‘I’, ‘V’, ‘X’) = MPEG-4 codec
CV_FOURCC(‘U’, ‘2’, ‘6’, ‘3’) = H263 codec
CV_FOURCC(‘I’, ‘2’, ‘6’, ‘3’) = H263I codec
CV_FOURCC(‘F’, ‘L’, ‘V’, ‘1’) = FLV1 codec
fps:帧率
frameSize:每帧图片大小
isColor:非0位彩色,0位黑白色

完整代码

将视频转换为图片这是大家都熟知的操作,本博文介绍一下将图片转换为视频。下面直接给出代码

#include <ros/ros.h>
#include <iostream> 
#include <opencv2/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <opencv2/opencv.hpp>
#include <sstream>
#include <stdlib.h>
#include <stdio.h>
#include <cv.h>
#include "std_msgs/String.h"
 
using namespace std;
using namespace cv;
 
cv::Mat img;
int i=0;
char image_name[30];
int isColor = 1;
int frame_fps =60;
int frame_width = 640;
int frame_height = 480;
string video_name = "out.avi";
cv::VideoWriter writer = VideoWriter(video_name, CV_FOURCC('X', 'V', 'I', 'D'),frame_fps,Size(frame_width,frame_height),isColor);
//cv::namedWindow("image to video", CV_WINDOW_AUTOSIZE);
 
class IMAGE_LISTENER_and_LOCATOR {
private:
    ros::NodeHandle nh_;  // 定义ROS句柄
    image_transport::ImageTransport it_;  // 定义一个image_transport实例
    image_transport::Subscriber image_sub_;  // 定义ROS图象接收器
 
public:
    IMAGE_LISTENER_and_LOCATOR()
    :it_(nh_) {   // 构造函数
        // 定义图象接受器,订阅话题是“camera/image”
        image_sub_ = it_.subscribe("camera/image", 1, &IMAGE_LISTENER_and_LOCATOR::convert_callback, this);
        // 初始化输入输出窗口
        // cv::namedWindow(INPUT);
        // cv::namedWindow(OUTPUT);
    }
    ~IMAGE_LISTENER_and_LOCATOR() {  // 析构函数
        // cv::destroyWindow(INPUT);
        // cv::destroyWindow(OUTPUT);
    }
 
    void convert_callback(const sensor_msgs::ImageConstPtr& msg)
    {  
      cv_bridge::CvImagePtr cv_ptr;  // 声明一个CvImage指针的实例
      try {
        // 将ROS消息中的图象信息提取,生成新cv类型的图象,复制给CvImage指针
        cv_ptr =  cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::MONO8);
      }
      catch(cv_bridge::Exception& e) {  // 异常处理
        ROS_ERROR("cv_bridge exception: %s", e.what());
        return;
      }
      img=cv_ptr->image;
      sprintf(image_name, "%s%d%s", "/home/song/img/image", ++i, ".jpg");
      //resize(img,img,Size(1536,2048));
      //imshow("image to video",img);
      if (!img.data)//判断图片调入是否成功
		  {
        cout<< "Could not load image file...\n" << endl;
		  }
      cv::imwrite(image_name,img);
      img = imread(image_name);
      //images.push_back(img);
      writer.write(img);
    }
    
};
 
int main(int argc, char **argv)
{
  ros::init(argc, argv, "Get_vedio");
  IMAGE_LISTENER_and_LOCATOR obj;
  ros::spin();
  return 0;
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。