├── README.md ├── src └── main.cpp ├── CMakeLists.txt ├── include └── extract_patches.hpp └── LICENSE /README.md: -------------------------------------------------------------------------------- 1 | ## Extract patches 2 | 3 | 4 | C++ Header-only library for the local patch extraction. 5 | Simplified C++ version of the [extract_patches](https://github.com/ducha-aiki/extract_patches) 6 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | #include "extract_patches.hpp" 10 | 11 | 12 | 13 | #ifdef _OPENMP 14 | #include 15 | #endif 16 | 17 | 18 | int main(int argc, char **argv) 19 | { 20 | cv::Mat image = cv::imread("kpi.png", 0); 21 | std::vector keypoints1; 22 | cv::Ptr detector = cv::AKAZE::create(); 23 | detector->detect(image, keypoints1); 24 | 25 | std::vector patches; 26 | extract_patches(image, 27 | keypoints1, 28 | patches, 64, 12.0); 29 | 30 | for (int i=0; i<10; i++){ 31 | cv::imwrite(std::to_string(i) + ".png", patches[i]); 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12) 2 | project(extract_patches) 3 | 4 | add_definitions(-fPIC) 5 | add_definitions(-DA64) 6 | add_definitions(-std=c++14) 7 | 8 | SET(CMAKE_BUILD_TYPE "RELEASE") 9 | 10 | IF(CMAKE_COMPILER_IS_GNUCXX) 11 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-strict-aliasing") 12 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra -Wno-write-strings") 13 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated -ansi") 14 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -ftree-vectorize -funroll-loops") 15 | ENDIF(CMAKE_COMPILER_IS_GNUCXX) 16 | 17 | FIND_PACKAGE(OpenMP) 18 | if (USE_OPENMP) 19 | if(NOT OPENMP_FOUND) 20 | message(FATAL_ERROR "OPENMP not found.") 21 | endif() 22 | add_definitions(-DUSE_OPENMP) 23 | endif (USE_OPENMP) 24 | 25 | # ============================================================================== 26 | # Find OpenCV 27 | # ============================================================================== 28 | find_package(OpenCV) 29 | if (OPENCV_FOUND) 30 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenCV_CXX_FLAGS}") 31 | endif (OPENCV_FOUND) 32 | 33 | ####### sources 34 | include_directories(include/) 35 | 36 | #find_package(Torch REQUIRED) 37 | #include_directories(/home/old-ufo/dev/libtorch/libtorch/include/) 38 | 39 | add_executable(extract_patches_example 40 | src/main.cpp) 41 | 42 | target_link_libraries(extract_patches_example ${OpenCV_LIBS}) 43 | -------------------------------------------------------------------------------- /include/extract_patches.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | //#include 6 | 7 | void convertKeypoints(std::vector &kpts, 8 | std::vector &M, 9 | std::vector &out_pyr_idx, 10 | int PS = 32, 11 | float mag_factor = 12.0){ 12 | M.clear(); 13 | out_pyr_idx.clear(); 14 | const double half_PS = double(PS) / 2.0; 15 | for (size_t i=0; i(0,0) = s_pyr*cos_a; 25 | M_cur.at(0,1) = -s_pyr*sin_a; 26 | M_cur.at(0,2) = (-s_pyr*cos_a + s_pyr*sin_a) * half_PS + kp.pt.x / d_factor; 27 | 28 | M_cur.at(1,0) = s_pyr*sin_a; 29 | M_cur.at(1,1) = s_pyr*cos_a; 30 | M_cur.at(1,2) = (-s_pyr*sin_a - s_pyr*cos_a) * half_PS + kp.pt.y / d_factor; 31 | M.push_back(M_cur); 32 | out_pyr_idx.push_back(int(pyr_idx)); 33 | } 34 | } 35 | 36 | std::vector build_image_pyramid(cv::Mat &img, int min_size = 16){ 37 | std::vector out; 38 | cv::Mat cur_img = img.clone(); 39 | out.push_back(img.clone()); 40 | while (std::min(cur_img.cols, cur_img.rows) > min_size) { 41 | cv::pyrDown(cur_img.clone(), cur_img); 42 | out.push_back(cur_img); 43 | } 44 | return out; 45 | } 46 | 47 | 48 | void extract_patches(cv::Mat &img, 49 | std::vector &kpts, 50 | std::vector &patches, 51 | int PS = 32, 52 | float mag_factor = 12.0){ 53 | std::vector img_pyr = build_image_pyramid(img, int(float(PS)/2)); 54 | size_t max_pyr_idx = img_pyr.size() - 1; 55 | 56 | std::vector M; 57 | std::vector pyr_idxs; 58 | convertKeypoints(kpts, M, pyr_idxs, PS, mag_factor); 59 | patches.clear(); 60 | patches.resize(kpts.size()); 61 | #ifdef _OPENMP 62 | omp_set_nested(1); 63 | #endif 64 | #pragma omp parallel for schedule (dynamic,1) 65 | for (size_t i=0; i &kpts, 79 | torch::Tensor& patches, 80 | int PS = 32, 81 | float mag_factor = 10.0){ 82 | cv::Mat grayImg; 83 | if (img.channels() > 1){ 84 | cv::cvtColor(img, grayImg, cv::COLOR_BGR2GRAY); 85 | } 86 | else { 87 | grayImg = img; 88 | } 89 | std::vector img_pyr = build_image_pyramid(grayImg, int(float(PS)/2)); 90 | size_t max_pyr_idx = img_pyr.size() - 1; 91 | std::vector patches_list; 92 | std::vector M; 93 | std::vector pyr_idxs; 94 | convertKeypoints(kpts, M, pyr_idxs, PS, mag_factor); 95 | for (size_t i=0; i