Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/py_denseflow'
Browse files Browse the repository at this point in the history
Conflicts:
	CMakeLists.txt
  • Loading branch information
yjxiong committed Apr 28, 2016
2 parents f64d0d0 + 0563a3f commit 8306a66
Show file tree
Hide file tree
Showing 12 changed files with 280 additions and 11 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
@@ -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
16 changes: 14 additions & 2 deletions CMakeLists.txt
Expand Up @@ -7,26 +7,38 @@ include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()


find_package( OpenCV REQUIRED )
find_package( LibZip REQUIRED )

# BOOST
FIND_PACKAGE(Boost REQUIRED python)
FIND_PACKAGE(PythonLibs REQUIRED)

if(LIBZIP_VERSION VERSION_LESS 0.11)
#old version LibZip
add_definitions(-DUSE_OBSEL_LIBZIP)
endif()

include_directories( ${OpenCV_INCLUDE_DIRS} ${LIBZIP_INCLUDE_DIR_ZIP} ${LIBZIP_INCLUDE_DIR_ZIPCONF} include/ include/easylogging++/src)
include_directories( ${OpenCV_INCLUDE_DIRS} ${LIBZIP_INCLUDE_DIR_ZIP} ${LIBZIP_INCLUDE_DIR_ZIPCONF} include/ include/easylogging++/src include/CLUE/include)
include_directories(SYSTEM ${Boost_INCLUDE_DIR} ${PYTHON_INCLUDE_DIR})

add_library(denseflow src/common.cpp src/dense_flow.cpp src/dense_flow_gpu.cpp src/dense_warp_flow_gpu.cpp src/zip_utils.cpp)
target_link_libraries( denseflow ${OpenCV_LIBS} ${LIBZIP_LIBRARY})

add_library(pydenseflow SHARED src/py_denseflow.cpp)
target_link_libraries(pydenseflow
denseflow
${Boost_LIBRARIES} ${PYTHON_LIBRARIES} ${OpenCV_LIBS}
)

add_executable( extract_cpu tools/extract_flow.cpp)
target_link_libraries( extract_cpu ${OpenCV_LIBS} ${LIBZIP_LIBRARY} denseflow)

Expand Down
10 changes: 7 additions & 3 deletions build_of.py
Expand Up @@ -45,19 +45,23 @@ def run_optical_flow(vid_item, dev_id=0):
flow_y_path = '{}/flow_y'.format(out_full_path)

cmd = './build/extract_gpu -f {} -x {} -y {} -i {} -b 20 -t 1 -d {} -s 1 -o zip'.format(vid_path, flow_x_path, flow_y_path, image_path, dev_id)
#cmd = './build/extract_gpu -f {} -x {} -y {} -b 20 -t 1 -d {} -s 1 -o zip'.format(vid_path, flow_x_path, flow_y_path, dev_id)

os.system(cmd)
print '{} {} done'.format(vid_id, vid_name)
return True


if __name__ == '__main__':
out_path = '/data1/alex/anet/flow_tvl1'
out_path = '/data2/alex/anet_v1.2_testing_flow_tvl1'
import glob
vid_list = glob.glob('/home/alex/clips/*avi')
#vid_list = glob.glob('/data1/alex/anet_clips_v1.2/*avi')
vid_list = glob.glob('/data1/alex/ActivityNet/testing_videos_v1.2/*.mp4')
#vid_list = ['/data1/alex/anet_clips_v1.2/{}.avi'.format(x.strip()) for x in open('/data2/alex/prob_clip_list.txt')]
print len(vid_list)
pool = Pool(4)
pool = Pool(16)
pool.map(run_optical_flow, zip(vid_list, xrange(len(vid_list))))
#map(run_optical_flow, zip(vid_list, xrange(len(vid_list))))
#file_list = pool.map(dump_frames, vid_list)
#all_file_list = [f for x in file_list for f in x]
#open('anet_image_list_nov_17.txt','w').writelines('\n'.join(all_file_list))
Expand Down
1 change: 1 addition & 0 deletions include/CLUE
Submodule CLUE added at 1d8199
4 changes: 2 additions & 2 deletions include/common.h
Expand Up @@ -5,7 +5,7 @@
#ifndef DENSEFLOW_COMMON_H_H
#define DENSEFLOW_COMMON_H_H

#include "easylogging++.h"


#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc/imgproc.hpp"
Expand All @@ -21,7 +21,7 @@ void drawOptFlowMap(const Mat& flow, Mat& cflowmap, int step,double, const Scala

void encodeFlowMap(const Mat& flow_map_x, const Mat& flow_map_y,
vector<uchar>& encoded_x, vector<uchar>& encoded_y,
int bound);
int bound, bool to_jpg=true);

inline void initializeMats(const Mat& frame,
Mat& capture_image, Mat& capture_gray,
Expand Down
1 change: 1 addition & 0 deletions include/dense_flow.h
Expand Up @@ -6,6 +6,7 @@
#define DENSEFLOW_DENSE_FLOW_H

#include "common.h"
#include "easylogging++.h"

void calcDenseFlow(string file_name, int bound, int type, int step,
vector<vector<uchar> >& output_x,
Expand Down
13 changes: 10 additions & 3 deletions src/common.cpp
Expand Up @@ -31,15 +31,22 @@ void drawOptFlowMap(const Mat& flow, Mat& cflowmap, int step,double, const Scala

void encodeFlowMap(const Mat& flow_map_x, const Mat& flow_map_y,
vector<uchar>& encoded_x, vector<uchar>& encoded_y,
int bound){
int bound, bool to_jpg){
Mat flow_img_x(flow_map_x.size(), CV_8UC1);
Mat flow_img_y(flow_map_y.size(), CV_8UC1);

convertFlowToImage(flow_map_x, flow_map_y, flow_img_x, flow_img_y,
-bound, bound);

imencode(".jpg", flow_img_x, encoded_x);
imencode(".jpg", flow_img_y, encoded_y);
if (to_jpg) {
imencode(".jpg", flow_img_x, encoded_x);
imencode(".jpg", flow_img_y, encoded_y);
}else {
encoded_x.resize(flow_img_x.total());
encoded_y.resize(flow_img_y.total());
memcpy(encoded_x.data(), flow_img_x.data, flow_img_x.total());
memcpy(encoded_y.data(), flow_img_y.data, flow_img_y.total());
}
}

void writeImages(vector<vector<uchar>> images, string name_temp){
Expand Down
1 change: 1 addition & 0 deletions src/dense_flow.cpp
Expand Up @@ -2,6 +2,7 @@
// Created by yjxiong on 11/18/15.
//
#include "common.h"
#include "dense_flow.h"

void calcDenseFlow(string file_name, int bound, int type, int step,
vector<vector<uchar> >& output_x,
Expand Down
2 changes: 1 addition & 1 deletion src/dense_flow_gpu.cpp
@@ -1,7 +1,7 @@
//
// Created by yjxiong on 11/18/15.
//
#include "common.h"
#include "dense_flow.h"
#include "opencv2/gpu/gpu.hpp"
using namespace cv::gpu;

Expand Down
81 changes: 81 additions & 0 deletions src/py_denseflow.cpp
@@ -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");
}
1 change: 1 addition & 0 deletions src/zip_utils.cpp
Expand Up @@ -4,6 +4,7 @@

#include "utils.h"
#include "zip.h"
#include "easylogging++.h"

void writeZipFile(vector<vector<uchar> >& data, string name_temp, string archive_name){
int err=0;
Expand Down
158 changes: 158 additions & 0 deletions tools/benchmark_video_io.cpp
@@ -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;
}

0 comments on commit 8306a66

Please sign in to comment.