use main image describer as reference.

This commit is contained in:
Jordan 2024-04-03 07:39:37 -07:00
parent 301fc2ca75
commit e1137844ac
4 changed files with 184 additions and 25 deletions

View File

@ -39,6 +39,7 @@ set (LIBDART_OPENMVG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/src)
find_package(JPEG REQUIRED) find_package(JPEG REQUIRED)
find_package(TIFF REQUIRED) find_package(TIFF REQUIRED)
find_package(OpenCV REQUIRED)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/extlib/cwalk) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/extlib/cwalk)
@ -59,6 +60,7 @@ set(SKIP_INSTALL_ALL OFF CACHE BOOL "" FORCE) # we only want lib
add_definitions(${PNG_DEFINITIONS}) add_definitions(${PNG_DEFINITIONS})
add_library(${LIBDART_OPENMVG} SHARED add_library(${LIBDART_OPENMVG} SHARED
"mvg_override/describer/akaze.hpp"
"frame.cxx" "frame.cxx"
"streamingview.cxx" "streamingview.cxx"
"image.cxx" "image.cxx"
@ -67,6 +69,8 @@ add_library(${LIBDART_OPENMVG} SHARED
set(CEREAL_INCLUDE_DIR ${OpenMVG_DIR}/../../../include/openMVG_dependencies/cereal/include/cereal/) set(CEREAL_INCLUDE_DIR ${OpenMVG_DIR}/../../../include/openMVG_dependencies/cereal/include/cereal/)
dump_cmake_variables("^opencv")
target_include_directories( target_include_directories(
${LIBDART_OPENMVG} ${LIBDART_OPENMVG}
PRIVATE PRIVATE
@ -74,6 +78,7 @@ target_include_directories(
${PNG_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS}
${ARCHIMEDES_INCLUDE_DIRS} ${ARCHIMEDES_INCLUDE_DIRS}
${CEREAL_INCLUDE_DIR} ${CEREAL_INCLUDE_DIR}
${OpenCV_INCLUDE_DIRS}
) )
target_link_libraries( target_link_libraries(
@ -82,6 +87,7 @@ target_link_libraries(
jpeg jpeg
tiff tiff
png png
${OpenCV_LIBS}
OpenMVG::openMVG_image OpenMVG::openMVG_image
OpenMVG::openMVG_numeric OpenMVG::openMVG_numeric
OpenMVG::openMVG_features OpenMVG::openMVG_features

View File

@ -72,16 +72,18 @@ Frame *new_frame_from_handle(FILE *stream, int w, int h, int depth)
return f; return f;
} }
void clean_frame(Frame *f) { void clean_frame(Frame *f)
{
fclose(f->stream); fclose(f->stream);
free(f); free(f);
} }
#ifdef __cplusplus #ifdef __cplusplus
DartOpenMvg::Frame::Frame(const DartOpenMvg::Frame &frame) { DartOpenMvg::Frame::Frame(const DartOpenMvg::Frame &frame)
{
cFrame = frame.cFrame; cFrame = frame.cFrame;
mRegions = std::unique_ptr<openMVG::features::Regions>(frame.mRegions.get()); // mRegions = std::unique_ptr<openMVG::features::Regions>(frame.mRegions.get());
} }
openMVG::image::Image<u_char> DartOpenMvg::imageFromFrame(const CFrame *frame) openMVG::image::Image<u_char> DartOpenMvg::imageFromFrame(const CFrame *frame)
@ -107,20 +109,15 @@ DartOpenMvg::Frames::Frames(openMVG::sfm::Bundle_Adjustment_Ceres::BA_Ceres_opti
mAdjustment = openMVG::sfm::Bundle_Adjustment_Ceres(options); mAdjustment = openMVG::sfm::Bundle_Adjustment_Ceres(options);
} }
void DartOpenMvg::Frames::add_frame(FILE *handle, int w, int h, int depth) { void DartOpenMvg::Frames::add_frame(FILE *handle, int w, int h, int depth)
{
CFrame *f = new_frame_from_handle(handle, w, h, depth); CFrame *f = new_frame_from_handle(handle, w, h, depth);
mFrames.push_back( mFrames.push_back(
Frame(f) Frame(f));
);
} }
void DartOpenMvg::Frames::computeMatches() void DartOpenMvg::Frames::computeMatches()
{ {
#ifdef OPENMVG_USE_OPENMP
OPENMVG_LOG_INFO << "Using the OPENMP thread interface";
const bool b_multithreaded_pair_search = (eMatcherType_ == CASCADE_HASHING_L2);
// -> set to true for CASCADE_HASHING_L2, since OpenMP instructions are not used in this matcher
#endif
// Match the pairs as a sequence // Match the pairs as a sequence
// Within openMvg::matching_image_collection::Matcher // Within openMvg::matching_image_collection::Matcher
@ -129,16 +126,17 @@ void DartOpenMvg::Frames::computeMatches()
for (size_t i = 0; i < mFrames.size() - 1; ++i) for (size_t i = 0; i < mFrames.size() - 1; ++i)
{ {
const Frame &frame1 = mFrames[i]; const Frame &frame1 = mFrames[i];
const Frame &frame2 = mFrames[i+1]; const Frame &frame2 = mFrames[i + 1];
auto *regions1 = frame1.mRegions.get(); auto regions1 = frame1.mRegions.get();
auto *regions2 = frame2.mRegions.get(); auto regions2 = frame2.mRegions.get();
if (!regions1) { if (!regions1)
{
std::string msg = std::string("Did you remember to calculate regions for frame ") + std::to_string(i) + "?"; std::string msg = std::string("Did you remember to calculate regions for frame ") + std::to_string(i) + "?";
throw std::out_of_range(msg); throw std::out_of_range(msg);
} }
regions1->Load(); // regions1->Load();
std::cerr << "Loading " << std::to_string(regions1->RegionCount()) << " regions" << endl; std::cerr << "Loading " << std::to_string(regions1->RegionCount()) << " regions" << std::endl;
auto is_binary = regions1->IsBinary(); auto is_binary = regions1->IsBinary();
@ -147,10 +145,6 @@ void DartOpenMvg::Frames::computeMatches()
openMVG::matching::RegionMatcherFactory(openMVG::matching::EMatcherType::HNSW_L2, *regions1); openMVG::matching::RegionMatcherFactory(openMVG::matching::EMatcherType::HNSW_L2, *regions1);
if (!matcher) if (!matcher)
continue; continue;
#ifdef OPENMVG_USE_OPENMP
#pragma omp parallel for schedule(dynamic) if (b_multithreaded_pair_search)
#endif
openMVG::matching::IndMatches vec_putative_matches; openMVG::matching::IndMatches vec_putative_matches;
matcher->MatchDistanceRatio(0.5, *regions2, vec_putative_matches); matcher->MatchDistanceRatio(0.5, *regions2, vec_putative_matches);
if (vec_putative_matches.empty()) if (vec_putative_matches.empty())
@ -186,12 +180,17 @@ void DartOpenMvg::Frame::calculateFeatures()
{ {
using namespace openMVG::image; using namespace openMVG::image;
using namespace openMVG::features; using namespace openMVG::features;
auto desc = SIFT_Anatomy_Image_describer(SIFT_Anatomy_Image_describer::Params()); MvgOverride::AKAZE_OCV_Image_describer desc;
auto image = imageFromFrame(cFrame); auto im = imageFromFrame(cFrame);
mRegions = desc.Describe(image); mRegions = std::make_shared<Regions>(std::move(desc.Describe(im)));
if (!mRegions.get()) {
throw std::range_error("Could not set regions member.");
}
} }
void DartOpenMvg::Frames::resection() { void DartOpenMvg::Frames::resection()
{
// openMVG::tracks::TracksUtilsMap::GetFeatIndexPerViewAndTrackId( // openMVG::tracks::TracksUtilsMap::GetFeatIndexPerViewAndTrackId(
// mTracks; // mTracks;
// ) // )

View File

@ -20,6 +20,7 @@
#include <openMVG/image/image_io.hpp> #include <openMVG/image/image_io.hpp>
#include <openMVG/numeric/numeric.h> #include <openMVG/numeric/numeric.h>
#include <openMVG/tracks/tracks.hpp> #include <openMVG/tracks/tracks.hpp>
#include <opencv2/opencv.hpp>
#include <string> #include <string>
#include <vector> #include <vector>
#include <memory> #include <memory>
@ -36,6 +37,7 @@
#include <map> #include <map>
#include <utility> #include <utility>
#include "./base.hpp" #include "./base.hpp"
#include "./mvg_override/describer/akaze.hpp"
#ifndef __FRAME_H #ifndef __FRAME_H
#define __FRAME_H #define __FRAME_H

View File

@ -0,0 +1,152 @@
// This file is part of OpenMVG, an Open Multiple View Geometry C++ library.
// Copyright (c) 2012, 2013 Pierre MOULON.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// The <cereal/archives> headers are special and must be included first.
#include <cereal/archives/json.hpp>
#include "openMVG/image/image_io.hpp"
#include "openMVG/features/regions_factory_io.hpp"
#include "openMVG/sfm/sfm.hpp"
#include "openMVG/system/timer.hpp"
/// OpenCV Includes
#include <opencv2/opencv.hpp>
#include <opencv2/core/eigen.hpp>
#include <cstdlib>
#include <fstream>
#ifndef __MVG_OVERRIDE_DESCRIBER_AKAZE_H
#define __MVG_OVERRIDE_DESCRIBER_AKAZE_H
namespace MvgOverride
{
using namespace openMVG;
using namespace openMVG::image;
using namespace openMVG::features;
using namespace openMVG::sfm;
enum eGeometricModel
{
FUNDAMENTAL_MATRIX = 0,
ESSENTIAL_MATRIX = 1,
HOMOGRAPHY_MATRIX = 2
};
enum ePairMode
{
PAIR_EXHAUSTIVE = 0,
PAIR_CONTIGUOUS = 1,
PAIR_FROM_FILE = 2
};
///
//- Create an Image_describer interface that use an OpenCV feature extraction method
// i.e. with the AKAZE detector+descriptor
//--/!\ If you use a new Regions type you define and register it in
// "openMVG/features/regions_factory.hpp" file.
///
// Reuse the existing AKAZE floating point Keypoint.
typedef features::AKAZE_Float_Regions AKAZE_OpenCV_Regions;
// Define the Interface
class AKAZE_OCV_Image_describer : public Image_describer
{
public:
using Regions_type = AKAZE_OpenCV_Regions;
cv::Ptr<cv::Feature2D> extractor;
AKAZE_OCV_Image_describer() : Image_describer()
{
extractor = cv::AKAZE::create(cv::AKAZE::DESCRIPTOR_KAZE);
}
bool Set_configuration_preset(EDESCRIBER_PRESET preset) override
{
return false;
}
/**
@brief Detect regions on the image and compute their attributes (description)
@param image Image.
@param mask 8-bit gray image for keypoint filtering (optional).
Non-zero values depict the region of interest.
@return regions The detected regions and attributes (the caller must delete the allocated data)
*/
std::unique_ptr<Regions> Describe(
const Image<unsigned char> &image,
const Image<unsigned char> *mask = nullptr) override
{
return Describe_AKAZE_OCV(image, mask);
}
/**
@brief Detect regions on the image and compute their attributes (description)
@param image Image.
@param mask 8-bit gray image for keypoint filtering (optional).
Non-zero values depict the region of interest.
@return regions The detected regions and attributes (the caller must delete the allocated data)
*/
std::unique_ptr<Regions_type> Describe_AKAZE_OCV(
const Image<unsigned char> &image,
const Image<unsigned char> *mask = nullptr)
{
auto regions = std::unique_ptr<Regions_type>(new Regions_type);
cv::Mat img;
cv::eigen2cv(image.GetMat(), img);
cv::Mat m_mask;
if (mask != nullptr)
{
cv::eigen2cv(mask->GetMat(), m_mask);
}
std::vector<cv::KeyPoint> vec_keypoints;
cv::Mat m_desc;
extractor->detectAndCompute(img, m_mask, vec_keypoints, m_desc);
if (!vec_keypoints.empty())
{
// reserve some memory for faster keypoint saving
regions->Features().reserve(vec_keypoints.size());
regions->Descriptors().reserve(vec_keypoints.size());
using DescriptorT = Descriptor<float, 64>;
DescriptorT descriptor;
int cpt = 0;
for (auto i_keypoint = vec_keypoints.begin(); i_keypoint != vec_keypoints.end(); ++i_keypoint, ++cpt)
{
const SIOPointFeature feat((*i_keypoint).pt.x, (*i_keypoint).pt.y, (*i_keypoint).size, (*i_keypoint).angle);
regions->Features().push_back(feat);
memcpy(descriptor.data(),
m_desc.ptr<typename DescriptorT::bin_type>(cpt),
DescriptorT::static_size * sizeof(DescriptorT::bin_type));
regions->Descriptors().push_back(descriptor);
}
}
return regions;
};
/// Allocate Regions type depending of the Image_describer
std::unique_ptr<Regions> Allocate() const override
{
return std::unique_ptr<Regions_type>(new Regions_type);
}
template <class Archive>
void serialize(Archive &ar)
{
}
};
}
#endif // __MVG_OVERRIDE_DESCRIBER_AKAZE_H