c++ - Fastest way to copy some rows from one matrix to another in OpenCV -
i have [32678 x 10] matrix (w2c
) , want copy 24700 rows of matrix(out
). have index of rows copied in vector(index
). doing in matlab do:
out = w2c(index_im,:);
it takes approximately 0.002622 seconds.
in opencv:
mat out(index.cols, w2c.cols, w2c.type()); (int = 0; < index.cols; ++i) { w2c.row(index.at<int>(i) - 1).copyto(out.row(i)); }
it takes approximately 0.015121 seconds.
as can see matlab 6 times faster. how can make opencv code efficient?
i using cmake-2.9, g++-4.8, opencv-2.4.9, ubuntu 14.04
update:
i ran code in release mode, here result ( still slower matlab )
release debug matlab 0.008183 0.010070 0.001604 0.009630 0.010050 0.001679 0.009120 0.009890 0.001566 0.007534 0.009567 0.001635 0.007886 0.009886 0.001840
based on our discussion in chat not compiling optimization enabled. if this, see notable performance increase. also, make sure linking against release build of opencv.
i measured execution time following example both without , optimization enabled:
main.cpp
#include <algorithm> #include <iostream> #include <iterator> #include <numeric> #include <random> #include <vector> #include <chrono> #include <opencv2/opencv.hpp> int main(int argc, char **argv) { const int num_rows = 32678; const int num_cols = 10; const int index_size = 24700; const int num_runs = 1000; const int seed = 42; std::vector<int> index_vec(num_rows); // fill index sequence std::iota (index_vec.begin(), index_vec.end(), 0); // randomize sequence std::random_device rd; std::mt19937 g(rd()); g.seed(seed); std::shuffle(index_vec.begin(), index_vec.end(), g); // trunkate index index_vec.resize(index_size); cv::mat w2c(num_rows, num_cols, cv_32f); // copy cv::mat out(index_size, w2c.cols, w2c.type()); auto start = std::chrono::high_resolution_clock::now(); (int k = 0; k<num_runs; ++k) { (int = 0; < index_size; ++i) { w2c.row(index_vec[i]).copyto(out.row(i)); } } auto end = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start); std::cout << duration.count()/num_runs << " microseconds" << std::endl; return 0; }
cmakelists.txt
project(copy) find_package(opencv required) add_executable(copy main.cpp) set(cmake_cxx_flags "${cmake_cxx_flags} -std=c++11") include_directories(${opencv_include_dirs}) target_link_libraries(copy ${opencv_libs})
compile , run without optimization
cmake . -dcmake_build_type=debug make ./copy 3924 microseconds
compile , run optimization
cmake . -dcmake_build_type=release make ./copy 2664 microseconds
i ran these tests on
- intel core i7-4600u cpu
- ubuntu 14.04 (x64)
- gcc 4.8.2
- opencv 3.0.0 (release build)
Comments
Post a Comment