Added a few other filters, including filters that merge two files.

This commit is contained in:
Delalande Ivan 2012-07-13 18:03:45 +02:00
parent 875745cf22
commit 590bb48500
16 changed files with 202 additions and 30 deletions

View File

@ -23,7 +23,8 @@ prpa_LDADD = \
lib/libfilterSample.a \ lib/libfilterSample.a \
lib/libencoder.a lib/libencoder.a
prpa_SOURCES = src/main.cc src/configuration.cc src/pipeline.cc prpa_SOURCES = src/main.cc src/configuration.cc src/pipeline.cc \
src/compose.cc
prpa_LDFLAGS = \ prpa_LDFLAGS = \
$(BOOST_LDFLAGS) \ $(BOOST_LDFLAGS) \

View File

@ -14,7 +14,7 @@ AC_CONFIG_MACRO_DIR([m4])
# Look for a C++ compiler.CXXFLAGS_save="$CXXFLAGS" # Look for a C++ compiler.CXXFLAGS_save="$CXXFLAGS"
AC_PROG_CXX AC_PROG_CXX
AC_PROG_RANLIB AC_PROG_RANLIB
CXXFLAGS="$CXXFLAGS_save -std=c++11 -g" CXXFLAGS="$CXXFLAGS_save -std=c++11 -g -O0"
AC_ARG_ENABLE(debug, AC_ARG_ENABLE(debug,
[ --enable-debug compile with debugging support], [ --enable-debug compile with debugging support],

16
src/compose.cc Normal file
View File

@ -0,0 +1,16 @@
#include <utility>
#include <assert.h>
#include "compose.hh"
#include "opencv2/opencv.hpp"
void* Compose::operator()(void* para)
{
cv::Mat* mat = (cv::Mat*)para;
std::pair<cv::Mat*, cv::Mat*>* res = new std::pair<cv::Mat*, cv::Mat*>();
res->first = mat;
res->second = (cv::Mat*)this->vr_(nullptr);
return res;
}

16
src/compose.hh Normal file
View File

@ -0,0 +1,16 @@
#ifndef COMPOSE_HH_
# define COMPOSE_HH_
# include "tbb/pipeline.h"
# include "encoder/video_reader.hh"
class Compose: public tbb::filter
{
public:
Compose(VideoReader vr): filter(tbb::filter::serial_in_order), vr_(vr) {}
void* operator()(void*);
private:
VideoReader vr_;
};
#endif /* COMPOSE_HH_ */

View File

@ -1,36 +1,34 @@
#include "opencv2/opencv.hpp" #include "opencv2/opencv.hpp"
#include "video_reader.hh" #include "video_reader.hh"
VideoReader::VideoReader(std::string filename)
: filter(tbb::filter::serial_in_order), capture_(filename)
{
this->remaining_ = framecount_get();
}
VideoReader::VideoReader(const VideoReader& vr) VideoReader::VideoReader(const VideoReader& vr)
: filter(tbb::filter::serial_in_order) : filter(tbb::filter::serial_in_order)
{ {
this->capture_ = vr.capture_; this->capture_ = vr.capture_;
this->maxframe_ = vr.maxframe_; this->remaining_ = framecount_get();
this->current_ = vr.current_;
} }
void* VideoReader::operator()(void* ign) void* VideoReader::operator()(void* ign)
{ {
(void)ign; (void)ign;
if (this->capture_.grab() && this->current_ < this->maxframe_)
{
this->current_++;
cv::Mat retrieved; cv::Mat retrieved;
if (this->remaining_ > 0)
{
this->capture_.read(retrieved);
cv::Mat* res = new cv::Mat; cv::Mat* res = new cv::Mat;
this->capture_.retrieve(retrieved);
*res = retrieved.clone(); *res = retrieved.clone();
this->remaining_--;
return res; return res;
} }
else else
{
return nullptr; return nullptr;
}
}
void VideoReader::maxframe_set(int limit)
{
this->maxframe_ = limit;
} }
int VideoReader::framecount_get() int VideoReader::framecount_get()

View File

@ -3,23 +3,21 @@
# include <string> # include <string>
# include "tbb/pipeline.h" # include "tbb/pipeline.h"
# include "opencv2/opencv.hpp"
class VideoReader: public tbb::filter class VideoReader: public tbb::filter
{ {
public: public:
VideoReader(const VideoReader& vr); VideoReader(const VideoReader& vr);
VideoReader(std::string filename) : filter(tbb::filter::serial_in_order), VideoReader(std::string filename);
capture_(filename), current_(0) {}
int framecount_get(); int framecount_get();
int fps_get(); int fps_get();
int width_get(); int width_get();
int height_get(); int height_get();
void maxframe_set(int limit);
void* operator()(void*); void* operator()(void*);
private: private:
cv::VideoCapture capture_; cv::VideoCapture capture_;
int maxframe_; int remaining_;
int current_;
}; };
#endif /* !VIDEO_READER_HH_ */ #endif /* !VIDEO_READER_HH_ */

View File

@ -6,4 +6,4 @@ AM_CXXFLAGS = \
$(BOOST_CPPFLAGS) \ $(BOOST_CPPFLAGS) \
$(DEBUG_CXXFLAGS) $(DEBUG_CXXFLAGS)
______lib_libfilterSample_a_SOURCES = grey.cc ______lib_libfilterSample_a_SOURCES = grey.cc reverse.cc merge.cc interlace.cc

View File

@ -0,0 +1,32 @@
#include <utility>
#include <iostream>
#include "interlace.hh"
#include "opencv2/opencv.hpp"
void* Interlace::operator()(void* para)
{
std::pair<cv::Mat*, cv::Mat*>* pair = (std::pair<cv::Mat*, cv::Mat*>*)para;
cv::Mat* mat = pair->first;
if (mat == nullptr)
return nullptr;
if (pair->second != nullptr)
{
for (size_t i = 0; i < mat->rows; ++i)
for (size_t j = 0; j < mat->cols; ++j)
if (i < pair->second->rows && j < pair->second->cols
&& (i + j) % 2 == 0)
{
mat->at<cv::Vec3b>(i, j)[0] = pair->second->at<cv::Vec3b>(i, j)[0];
mat->at<cv::Vec3b>(i, j)[1] = pair->second->at<cv::Vec3b>(i, j)[1];
mat->at<cv::Vec3b>(i, j)[2] = pair->second->at<cv::Vec3b>(i, j)[2];
}
delete pair->second;
}
delete pair;
return mat;
}

View File

@ -0,0 +1,13 @@
#ifndef INTERLACE_HH_
# define INTERLACE_HH_
# include "tbb/pipeline.h"
class Interlace: public tbb::filter
{
public:
Interlace(): filter(tbb::filter::parallel) {}
void* operator()(void*);
};
#endif /* !INTERLACE_HH_ */

33
src/filterSample/merge.cc Normal file
View File

@ -0,0 +1,33 @@
#include <utility>
#include <iostream>
#include "merge.hh"
#include "opencv2/opencv.hpp"
void* Merge::operator()(void* para)
{
std::pair<cv::Mat*, cv::Mat*>* pair = (std::pair<cv::Mat*, cv::Mat*>*)para;
cv::Mat* mat = pair->first;
if (mat == nullptr)
return nullptr;
if (pair->second != nullptr)
{
for (size_t i = 0; i < mat->rows; ++i)
for (size_t j = 0; j < mat->cols; ++j)
if (i < pair->second->rows && j < pair->second->cols)
{
mat->at<cv::Vec3b>(i, j)[0] = (mat->at<cv::Vec3b>(i, j)[0]
+ pair->second->at<cv::Vec3b>(i, j)[0]) / 2;
mat->at<cv::Vec3b>(i, j)[1] = (mat->at<cv::Vec3b>(i, j)[1]
+ pair->second->at<cv::Vec3b>(i, j)[1]) / 2;
mat->at<cv::Vec3b>(i, j)[2] = (mat->at<cv::Vec3b>(i, j)[2]
+ pair->second->at<cv::Vec3b>(i, j)[2]) / 2;
}
}
delete pair->second;
delete pair;
return mat;
}

13
src/filterSample/merge.hh Normal file
View File

@ -0,0 +1,13 @@
#ifndef MERGE_HH_
# define MERGE_HH_
# include "tbb/pipeline.h"
class Merge: public tbb::filter
{
public:
Merge(): filter(tbb::filter::parallel) {}
void* operator()(void*);
};
#endif /* !MERGE_HH_ */

View File

@ -0,0 +1,20 @@
#include "reverse.hh"
#include "opencv2/opencv.hpp"
void* Reverse::operator()(void* para)
{
cv::Mat* mat = (cv::Mat*)para;
if (mat == nullptr)
return nullptr;
for (auto it = mat->begin<cv::Vec3b>(); it != mat->end<cv::Vec3b>(); ++it)
{
(*it)[0] = ~(*it)[0];
(*it)[1] = ~(*it)[1];
(*it)[2] = ~(*it)[2];
}
return mat;
}

View File

@ -0,0 +1,13 @@
#ifndef REVERSE_HH_
# define REVERSE_HH_
# include "tbb/pipeline.h"
class Reverse: public tbb::filter
{
public:
Reverse(): filter(tbb::filter::parallel) {}
void* operator()(void*);
};
#endif /* !REVERSE_HH_ */

View File

@ -95,12 +95,17 @@ int main (int argc, char** argv)
return 1; return 1;
VideoReader vr(conf.input.front()); VideoReader vr(conf.input.front());
auto it = conf.input.begin();
it++;
VideoWriter vw = VideoWriter(); VideoWriter vw = VideoWriter();
vw.open(conf.output, conf.codec, vr.fps_get(), vr.width_get(), vr.height_get()); vw.open(conf.output, conf.codec, vr.fps_get(), vr.width_get(), vr.height_get());
Pipeline pipe(std::list<VideoReader> { vr }, vw); Pipeline pipe(std::list<VideoReader> { vr, VideoReader(*it) }, vw);
// add filters here // add filters here
pipe.add_filter("grey"); //pipe.add_filter("grey");
//pipe.add_filter("reverse");
//pipe.add_filter("interlace");
//pipe.add_filter("merge");
pipe.run(); pipe.run();
return 0; return 0;

View File

@ -1,18 +1,38 @@
#include "tbb/pipeline.h" #include "tbb/pipeline.h"
#include "pipeline.hh" #include "pipeline.hh"
#include "compose.hh"
#include "filterSample/grey.hh" #include "filterSample/grey.hh"
#include "filterSample/reverse.hh"
#include "filterSample/merge.hh"
#include "filterSample/interlace.hh"
Pipeline::Pipeline(std::list<VideoReader> input, VideoWriter output) Pipeline::Pipeline(std::list<VideoReader> input, VideoWriter output)
: input_(input), output_(output) : input_(input), output_(output)
{ {
this->input_it_ = this->input_.begin();
this->pipeline_.add_filter(this->input_.front()); this->pipeline_.add_filter(this->input_.front());
this->input_it_++;
} }
bool Pipeline::add_filter(std::string filter) bool Pipeline::add_filter(std::string filter)
{ {
if (filter == "grey" || filter == "gray") if (filter == "grey" || filter == "gray")
this->pipeline_.add_filter(*(new Grey())); this->pipeline_.add_filter(*(new Grey()));
else if (filter == "reverse" || filter == "inverse")
this->pipeline_.add_filter(*(new Reverse()));
else if (filter == "merge" && this->input_it_ != this->input_.end())
{
this->pipeline_.add_filter(*(new Compose(*this->input_it_)));
this->input_it_++;
this->pipeline_.add_filter(*(new Merge()));
}
else if (filter == "interlace" && this->input_it_ != this->input_.end())
{
this->pipeline_.add_filter(*(new Compose(*this->input_it_)));
this->input_it_++;
this->pipeline_.add_filter(*(new Interlace()));
}
else else
return false; return false;
@ -21,13 +41,6 @@ bool Pipeline::add_filter(std::string filter)
void Pipeline::run() void Pipeline::run()
{ {
int minframe = this->input_.front().framecount_get();
for (auto it = this->input_.begin(); it != this->input_.end(); ++it)
if (minframe > it->framecount_get())
minframe = it->framecount_get();
for (auto it = this->input_.begin(); it != this->input_.end(); ++it)
it->maxframe_set(minframe);
this->pipeline_.add_filter(this->output_); this->pipeline_.add_filter(this->output_);
this->pipeline_.run(CHUNK_SIZE); this->pipeline_.run(CHUNK_SIZE);
} }

View File

@ -20,6 +20,7 @@ class Pipeline
private: private:
std::list<tbb::filter_t<cv::Mat*, cv::Mat*>> filters_; std::list<tbb::filter_t<cv::Mat*, cv::Mat*>> filters_;
std::list<VideoReader> input_; std::list<VideoReader> input_;
std::list<VideoReader>::const_iterator input_it_;
VideoWriter output_; VideoWriter output_;
tbb::pipeline pipeline_; tbb::pipeline pipeline_;
}; };