forked from wanglimin/dense_flow
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/py_denseflow'
Conflicts: CMakeLists.txt
- Loading branch information
Showing
12 changed files
with
280 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
[submodule "include/easylogging++"] | ||
path = include/easylogging++ | ||
url = https://github.com/easylogging/easyloggingpp | ||
[submodule "include/CLUE"] | ||
path = include/CLUE | ||
url = https://github.com/lindahua/CLUE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
#include <iostream> | ||
#include <boost/python.hpp> | ||
#include <Python.h> | ||
#include <vector> | ||
|
||
|
||
#include "common.h" | ||
#include "opencv2/gpu/gpu.hpp" | ||
using namespace cv::gpu; | ||
using namespace cv; | ||
|
||
namespace bp = boost::python; | ||
|
||
class TVL1FlowExtractor{ | ||
public: | ||
|
||
TVL1FlowExtractor(int bound){ | ||
bound_ = bound; | ||
} | ||
|
||
static void set_device(int dev_id){ | ||
setDevice(dev_id); | ||
} | ||
|
||
bp::list extract_flow(bp::list frames, int img_width, int img_height){ | ||
bp::list output; | ||
Mat input_frame, prev_frame, next_frame, prev_gray, next_gray; | ||
Mat flow_x, flow_y; | ||
|
||
|
||
|
||
|
||
// initialize the first frame | ||
const char* first_data = ((const char*)bp::extract<const char*>(frames[0])); | ||
input_frame = Mat(img_height, img_width, CV_8UC3); | ||
initializeMats(input_frame, prev_frame, prev_gray, next_frame, next_gray); | ||
|
||
memcpy(prev_frame.data, first_data, bp::len(frames[0])); | ||
cvtColor(prev_frame, prev_gray, CV_BGR2GRAY); | ||
for (int idx = 1; idx < bp::len(frames); idx++){ | ||
const char* this_data = ((const char*)bp::extract<const char*>(frames[idx])); | ||
memcpy(next_frame.data, this_data, bp::len(frames[0])); | ||
cvtColor(next_frame, next_gray, CV_BGR2GRAY); | ||
|
||
d_frame_0.upload(prev_gray); | ||
d_frame_1.upload(next_gray); | ||
|
||
alg_tvl1(d_frame_0, d_frame_1, d_flow_x, d_flow_y); | ||
|
||
d_flow_x.download(flow_x); | ||
d_flow_y.download(flow_y); | ||
|
||
vector<uchar> str_x, str_y; | ||
|
||
encodeFlowMap(flow_x, flow_y, str_x, str_y, bound_, false); | ||
output.append( | ||
bp::make_tuple( | ||
bp::str((const char*) str_x.data(), str_x.size()), | ||
bp::str((const char*) str_y.data(), str_y.size()) | ||
) | ||
); | ||
|
||
std::swap(prev_gray, next_gray); | ||
} | ||
return output; | ||
}; | ||
private: | ||
int bound_; | ||
GpuMat d_frame_0, d_frame_1; | ||
GpuMat d_flow_x, d_flow_y; | ||
OpticalFlowDual_TVL1_GPU alg_tvl1; | ||
}; | ||
|
||
|
||
//// Boost Python Related Decl | ||
BOOST_PYTHON_MODULE(libpydenseflow){ | ||
bp::class_<TVL1FlowExtractor>("TVL1FlowExtractor", bp::init<int>()) | ||
.def("extract_flow", &TVL1FlowExtractor::extract_flow) | ||
.def("set_device", &TVL1FlowExtractor::set_device) | ||
.staticmethod("set_device"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
// | ||
// Created by alex on 16-3-27. | ||
// | ||
|
||
#include "dense_flow.h" | ||
#include "utils.h" | ||
#include <clue/timing.hpp> | ||
#include <clue/textio.hpp> | ||
#include <random> | ||
#include "easylogging++.h" | ||
|
||
INITIALIZE_EASYLOGGINGPP | ||
|
||
using namespace cv::gpu; | ||
|
||
void OpenVideoOnly(string video_path){ | ||
VideoCapture video_stream(video_path); | ||
CHECK(video_stream.isOpened())<<"Cannot open video stream \"" | ||
<<video_path<<"\""; | ||
video_stream.release(); | ||
} | ||
|
||
std::pair<double, double> SeekByFrame(string video_path, vector<float> ratio, int read_num, double& first_seek_time){ | ||
VideoCapture video_stream(video_path); | ||
|
||
double seeking_time = 0, reading_time = 0; | ||
int cnt = 0; | ||
for (float r : ratio) { | ||
CHECK(video_stream.isOpened())<<"Cannot open video stream \"" | ||
<<video_path<<"\""; | ||
int frame_cnt = (int) video_stream.get(CV_CAP_PROP_FRAME_COUNT); | ||
int frame_idx = (int) (frame_cnt * r); | ||
|
||
auto sw = clue::stop_watch(true); | ||
video_stream.set(CV_CAP_PROP_POS_FRAMES, frame_idx); | ||
|
||
double seek = sw.elapsed().msecs(); | ||
seeking_time += seek; | ||
|
||
sw.reset(); | ||
sw.start(); | ||
Mat capture_frame; | ||
|
||
for (int i = 0; i < read_num; ++i) { | ||
video_stream >> capture_frame; | ||
} | ||
reading_time += sw.elapsed().msecs(); | ||
|
||
if (cnt == 0){ | ||
first_seek_time = seeking_time; | ||
LOG(INFO)<<"first seek "<<seek; | ||
}else { | ||
LOG(INFO)<<"consequtive seek "<<seek; | ||
} | ||
cnt ++; | ||
} | ||
video_stream.release(); | ||
|
||
return std::make_pair(seeking_time, reading_time); | ||
} | ||
|
||
void SeekByMSEC(string video_path, float ratio, int read_num){ | ||
VideoCapture video_stream(video_path); | ||
CHECK(video_stream.isOpened())<<"Cannot open video stream \"" | ||
<<video_path<<"\""; | ||
int frame_cnt = (int)video_stream.get(CV_CAP_PROP_FRAME_COUNT); | ||
int fps = (int)video_stream.get(CV_CAP_PROP_FPS); | ||
float time_msec = 1000 * frame_cnt / fps * ratio; | ||
|
||
video_stream.set(CV_CAP_PROP_POS_MSEC, time_msec); | ||
Mat capture_frame; | ||
|
||
for(int i = 0; i < read_num; ++i){ | ||
video_stream>>capture_frame; | ||
} | ||
video_stream.release(); | ||
} | ||
|
||
void SeekByRATIO(string video_path, float ratio, int read_num){ | ||
VideoCapture video_stream(video_path); | ||
CHECK(video_stream.isOpened())<<"Cannot open video stream \"" | ||
<<video_path<<"\""; | ||
|
||
video_stream.set(CV_CAP_PROP_POS_AVI_RATIO, ratio); | ||
Mat capture_frame; | ||
|
||
for(int i = 0; i < read_num; ++i){ | ||
video_stream>>capture_frame; | ||
} | ||
video_stream.release(); | ||
} | ||
|
||
int main(int argc, char** argv){ | ||
|
||
CHECK(argc==6)<<"Need a input video list to test"; | ||
|
||
//read video list | ||
vector<string> video_list; | ||
std::ifstream list_file(argv[1]); | ||
CHECK(list_file.is_open()); | ||
|
||
int read_num; | ||
clue::try_parse(argv[2], read_num); | ||
|
||
string vid_path = string(argv[3]); | ||
|
||
while(list_file.good()){ | ||
string name; | ||
list_file>>name; | ||
video_list.push_back(name); | ||
} | ||
list_file.close(); | ||
|
||
int test_limit; | ||
clue::try_parse(argv[4], test_limit); | ||
|
||
int seek_num; | ||
clue::try_parse(argv[5], seek_num); | ||
|
||
LOG(INFO)<<"Video list loaded, "<<video_list.size()<<" video in total."; | ||
|
||
std::random_device rd; | ||
std::mt19937 gen(rd()); | ||
std::uniform_real_distribution<float> dist(0.01, 0.99); | ||
|
||
std::shuffle(video_list.begin(), video_list.end(), gen); | ||
|
||
// time seeking by frame number | ||
LOG(INFO)<<"Timing started. Reading "<<read_num<<" frame(s) per video. Seeking "<<seek_num<<" times "; | ||
auto aw = clue::stop_watch(true); | ||
|
||
int cnt = 0; | ||
double accum_seeking_time=0, accum_reading_time=0, accum_first_seeking_time=0; | ||
for(auto video_id : video_list){ | ||
string video_full_path = vid_path + video_id; | ||
vector<float> ratios; | ||
for (int i = 0; i < seek_num; i++){ | ||
ratios.push_back(dist(gen)); | ||
} | ||
double fs; | ||
auto pair = SeekByFrame(video_full_path, ratios, read_num, fs); | ||
accum_seeking_time += pair.first; | ||
accum_reading_time += pair.second; | ||
accum_first_seeking_time += fs; | ||
cnt ++; | ||
if (cnt >= test_limit){ | ||
break; | ||
} | ||
} | ||
|
||
double elapsed = aw.elapsed().msecs(); | ||
double avg_time = elapsed / cnt; | ||
|
||
LOG(INFO)<<"Seeking by Frame Finished. Total time "<<elapsed<<" ms. Average "<<avg_time<<" msec/video." | ||
<<" seeking time "<<accum_seeking_time/cnt<<" msec/video"<<". reading time "<<accum_reading_time/cnt<<" msec/video" | ||
<<". \n first seeking time "<<accum_first_seeking_time/cnt; | ||
return 0; | ||
} |