Implemented a video reader and writer with OpenCV.

The program now works as a video cat or converter :
./prpa -c MP42 -o /tmp/bar.avi /tmp/foo.flv
-c specify a 4-letter codec to be used for the output file and follow a strict
code defined on this page : http://www.fourcc.org/codecs.php
The file output extension *does* matter and must match the selected output
codec.
This commit is contained in:
Delalande Ivan 2012-07-12 10:42:38 +02:00
parent 6a89d1f5df
commit cbc9a7a686
10 changed files with 145 additions and 2 deletions

View File

@ -27,4 +27,7 @@ prpa_SOURCES = src/main.cc
prpa_LDFLAGS = \
$(BOOST_LDFLAGS) \
$(BOOST_PROGRAM_OPTIONS_LIB)
$(BOOST_PROGRAM_OPTIONS_LIB) \
-ltbb \
$(DEPS_CFLAGS) \
$(DEPS_LIBS)

View File

@ -42,6 +42,11 @@ m4_include([m4/ax_boost_program_options.m4])
AX_BOOST_BASE([1.33.1])
AX_BOOST_PROGRAM_OPTIONS
#
# Check for OpenCV
#
PKG_CHECK_MODULES([DEPS], [opencv])
#
# Check for TBB
#

View File

@ -6,4 +6,4 @@ AM_CXXFLAGS = \
$(BOOST_CPPFLAGS) \
$(DEBUG_CXXFLAGS)
______lib_libencoder_a_SOURCES =
______lib_libencoder_a_SOURCES = video.cc video_writer.cc video_reader.cc

7
src/encoder/video.cc Normal file
View File

@ -0,0 +1,7 @@
#include "video.hh"
void Video::copy(Video& v)
{
for (auto it = v.images_.begin(); it != v.images_.end(); ++it)
this->images_.push_back(new cv::Mat(**it));
}

17
src/encoder/video.hh Normal file
View File

@ -0,0 +1,17 @@
#ifndef VIDEO_HH_
# define VIDEO_HH_
# include <string>
# include "tbb/concurrent_vector.h"
# include "opencv2/opencv.hpp"
class Video
{
public:
void close();
void copy(Video& v);
protected:
tbb::concurrent_vector<cv::Mat*> images_;
};
#endif /* !VIDEO_HH_ */

View File

@ -0,0 +1,42 @@
#include "video_reader.hh"
VideoReader::VideoReader(std::string filename)
: capture_(filename)
{
if (this->capture_.isOpened())
{
while (this->capture_.grab())
{
cv::Mat retrieved;
cv::Mat* mat = new cv::Mat();
this->capture_.retrieve(retrieved);
*mat = retrieved.clone();
this->images_.push_back(mat);
}
}
}
int VideoReader::fps_get()
{
if (this->capture_.isOpened())
return (int)this->capture_.get(CV_CAP_PROP_FPS);
else
return -1;
}
int VideoReader::width_get()
{
if (this->capture_.isOpened())
return (int)this->capture_.get(CV_CAP_PROP_FRAME_WIDTH);
else
return -1;
}
int VideoReader::height_get()
{
if (this->capture_.isOpened())
return (int)this->capture_.get(CV_CAP_PROP_FRAME_HEIGHT);
else
return -1;
}

View File

@ -0,0 +1,18 @@
#ifndef VIDEO_READER_HH_
# define VIDEO_READER_HH_
# include <string>
# include "video.hh"
class VideoReader: public Video
{
public:
VideoReader(std::string filename);
int fps_get();
int width_get();
int height_get();
private:
cv::VideoCapture capture_;
};
#endif /* !VIDEO_READER_HH_ */

View File

@ -0,0 +1,20 @@
#include "video_writer.hh"
bool VideoWriter::open(std::string filename, std::string enc,
int fps, int width, int height)
{
if (enc.length() != 4)
return false;
return this->writer_.open(filename,
CV_FOURCC(enc[0], enc[1], enc[2], enc[3]), fps, { width, height } );
}
void VideoWriter::write()
{
if (this->writer_.isOpened())
{
for (auto it = this->images_.begin(); it != this->images_.end(); ++it)
this->writer_.write(**it);
}
}

View File

@ -0,0 +1,17 @@
#ifndef VIDEO_WRITER_HH_
# define VIDEO_WRITER_HH_
# include <string>
# include "video.hh"
class VideoWriter: public Video
{
public:
void write();
bool open(std::string filename, std::string enc,
int fps, int width, int height);
private:
cv::VideoWriter writer_;
};
#endif /* !VIDEO_WRITER_HH_ */

View File

@ -1,6 +1,10 @@
#include <iostream>
#include <boost/program_options.hpp>
#include "encoder/video.hh"
#include "encoder/video_reader.hh"
#include "encoder/video_writer.hh"
int
main (int argc, char** argv)
{
@ -12,6 +16,8 @@ main (int argc, char** argv)
("help,h", "produce help message")
("filter,f", po::value<std::vector<std::string> > (), "apply a filter")
("input-file,i", po::value<std::vector<std::string> > (), "file to treat")
("output,o", po::value<std::vector<std::string> > (), "output file")
("codec,c", po::value<std::vector<std::string> > (), "output codec")
;
// Handle ./prpa file.avi instead of ./prpa --input-file=file.avi
@ -54,5 +60,13 @@ main (int argc, char** argv)
else
std::cout << 0 << std::endl;
VideoReader vr(vm["input-file"].as<std::vector<std::string> >()[0]);
VideoWriter vw = VideoWriter();
vw.open(vm["output"].as<std::vector<std::string> >()[0],
vm["codec"].as<std::vector<std::string> >()[0],
vr.fps_get(), vr.width_get(), vr.height_get());
vw.copy(vr);
vw.write();
return 0;
}