began writing my own matching alg.
This commit is contained in:
parent
fe5ecdeec1
commit
d85c25b21e
@ -42,6 +42,28 @@ class LibDartOpenMVG {
|
|||||||
late final _make_buffer = _make_bufferPtr
|
late final _make_buffer = _make_bufferPtr
|
||||||
.asFunction<ffi.Pointer<FILE> Function(ffi.Pointer<ffi.Uint8>, int)>();
|
.asFunction<ffi.Pointer<FILE> Function(ffi.Pointer<ffi.Uint8>, int)>();
|
||||||
|
|
||||||
|
int read_buffer(
|
||||||
|
ffi.Pointer<FILE> arg0,
|
||||||
|
ffi.Pointer<ffi.Pointer<ffi.Uint8>> arg1,
|
||||||
|
ffi.Pointer<ffi.Size> arg2,
|
||||||
|
) {
|
||||||
|
return _read_buffer(
|
||||||
|
arg0,
|
||||||
|
arg1,
|
||||||
|
arg2,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
late final _read_bufferPtr = _lookup<
|
||||||
|
ffi.NativeFunction<
|
||||||
|
ffi.Int Function(
|
||||||
|
ffi.Pointer<FILE>,
|
||||||
|
ffi.Pointer<ffi.Pointer<ffi.Uint8>>,
|
||||||
|
ffi.Pointer<ffi.Size>)>>('read_buffer');
|
||||||
|
late final _read_buffer = _read_bufferPtr.asFunction<
|
||||||
|
int Function(ffi.Pointer<FILE>, ffi.Pointer<ffi.Pointer<ffi.Uint8>>,
|
||||||
|
ffi.Pointer<ffi.Size>)>();
|
||||||
|
|
||||||
ffi.Pointer<Frame> new_frame_from_handle(
|
ffi.Pointer<Frame> new_frame_from_handle(
|
||||||
ffi.Pointer<FILE> arg0,
|
ffi.Pointer<FILE> arg0,
|
||||||
int arg1,
|
int arg1,
|
||||||
|
@ -24,6 +24,4 @@ cmake \
|
|||||||
-DCMAKE_BUILD_TYPE=Debug
|
-DCMAKE_BUILD_TYPE=Debug
|
||||||
make
|
make
|
||||||
|
|
||||||
printf "\033c"
|
|
||||||
|
|
||||||
set +e
|
set +e
|
@ -1 +1 @@
|
|||||||
Subproject commit aff37dd005f85b3589aa50caca13b74ca7bd57e4
|
Subproject commit 7fd19fc22419a35481d39d2946f77e1dc00df37c
|
110
src/frame.cxx
110
src/frame.cxx
@ -1,5 +1,5 @@
|
|||||||
#include "frame.h"
|
#include "frame.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
FILE *make_buffer(const uint8_t *data, const size_t data_len)
|
FILE *make_buffer(const uint8_t *data, const size_t data_len)
|
||||||
{
|
{
|
||||||
@ -20,43 +20,46 @@ FILE *make_buffer(const uint8_t *data, const size_t data_len)
|
|||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_buffer(FILE *file, uint8_t **buffer, size_t *length) {
|
int read_buffer(FILE *file, uint8_t **buffer, size_t *length)
|
||||||
if (file != NULL) {
|
{
|
||||||
// Get the file size
|
if (file != NULL)
|
||||||
fseek(file, 0, SEEK_END);
|
{
|
||||||
(*length) = ftell(file);
|
// Get the file size
|
||||||
fseek(file, 0, SEEK_SET);
|
fseek(file, 0, SEEK_END);
|
||||||
|
(*length) = ftell(file);
|
||||||
|
fseek(file, 0, SEEK_SET);
|
||||||
|
|
||||||
// Allocate memory
|
// Allocate memory
|
||||||
*buffer = (uint8_t *) malloc((*length) * sizeof(char));
|
*buffer = (uint8_t *)malloc((*length) * sizeof(char));
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL)
|
||||||
printf("Error: Unable to allocate memory.\n");
|
{
|
||||||
return 1;
|
printf("Error: Unable to allocate memory.\n");
|
||||||
}
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Read file
|
// Read file
|
||||||
size_t newLen = fread(*buffer, sizeof(char), *length, file);
|
size_t newLen = fread(*buffer, sizeof(char), *length, file);
|
||||||
if (newLen == 0) {
|
if (newLen == 0)
|
||||||
if (feof(file)) {
|
{
|
||||||
printf("Error: End of file reached.\n");
|
if (feof(file))
|
||||||
return 2;
|
{
|
||||||
}
|
printf("Error: End of file reached.\n");
|
||||||
printf("Error: Reading file.\n");
|
return 2;
|
||||||
return 3;
|
|
||||||
}
|
}
|
||||||
return 4;
|
printf("Error: Reading file.\n");
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
return 4;
|
||||||
}
|
}
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Frame *new_frame_from_data(const uint8_t *data, const size_t data_len, int w, int h, int depth)
|
Frame *new_frame_from_data(const uint8_t *data, const size_t data_len, int w, int h, int depth)
|
||||||
{
|
{
|
||||||
FILE *buf = make_buffer(data, data_len);
|
FILE *buf = make_buffer(data, data_len);
|
||||||
return new_frame_from_handle(buf, w, h, depth);
|
return new_frame_from_handle(buf, w, h, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Frame *new_frame_from_handle(FILE *stream, int w, int h, int depth)
|
Frame *new_frame_from_handle(FILE *stream, int w, int h, int depth)
|
||||||
{
|
{
|
||||||
Frame *f = (Frame *)malloc(sizeof(Frame));
|
Frame *f = (Frame *)malloc(sizeof(Frame));
|
||||||
@ -66,3 +69,60 @@ Frame *new_frame_from_handle(FILE *stream, int w, int h, int depth)
|
|||||||
f->depth = depth;
|
f->depth = depth;
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
openMVG::image::Image<u_char> DartOpenMvg::imageFromFrame(const CFrame *frame)
|
||||||
|
{
|
||||||
|
rewind(frame->stream);
|
||||||
|
std::vector<unsigned char> imageData;
|
||||||
|
if (!openMVG::image::ReadPngStream(frame->stream, &imageData, (int *)&(frame->w), (int *)&(frame->h), (int *)&(frame->depth)))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Could not read stream");
|
||||||
|
};
|
||||||
|
int w = frame->w, h = frame->h;
|
||||||
|
Eigen::Matrix<u_char, Eigen::Dynamic, Eigen::Dynamic, 1> eigenMatrix(frame->w, frame->h);
|
||||||
|
for (int i = 0; i < w * h; ++i)
|
||||||
|
{
|
||||||
|
eigenMatrix(i / h, i % h) = imageData[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return openMVG::image::Image<uint8_t>(eigenMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DartOpenMvg::Frame::calculateFeatures()
|
||||||
|
{
|
||||||
|
using namespace openMVG::image;
|
||||||
|
using namespace openMVG::features;
|
||||||
|
auto desc = SIFT_Anatomy_Image_describer(SIFT_Anatomy_Image_describer::Params());
|
||||||
|
auto image = imageFromFrame(cFrame);
|
||||||
|
mRegions = desc.Describe(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
openMVG::image::Image<u_char> DartOpenMvg::Frame::getMvgImage() {
|
||||||
|
return imageFromFrame(this->cFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DartOpenMvg::Frames::computeMatches()
|
||||||
|
{
|
||||||
|
using namespace openMVG::matching;
|
||||||
|
using namespace openMVG::matching_image_collection;
|
||||||
|
using namespace openMVG::sfm;
|
||||||
|
using namespace openMVG::image;
|
||||||
|
Matcher *matcher = nullptr;
|
||||||
|
|
||||||
|
Regions_Provider provider = Regions_Provider();
|
||||||
|
|
||||||
|
matcher = new Matcher_Regions(0.8f, CASCADE_HASHING_L2);
|
||||||
|
|
||||||
|
openMVG::Pair_Set pairs = openMVG::Pair_Set();
|
||||||
|
Image im1 = this->at(0).getMvgImage();
|
||||||
|
Image im2 = this->at(1).getMvgImage();
|
||||||
|
auto pair = openMVG::Pair(0, 1);
|
||||||
|
pairs.insert(pair);
|
||||||
|
|
||||||
|
PairWiseMatches map_punitive_matches;
|
||||||
|
|
||||||
|
// matcher->Match(provider, pairs, map_punitive_matches, NULL);
|
||||||
|
|
||||||
|
#endif // __cplusplus
|
73
src/frame.h
73
src/frame.h
@ -1,12 +1,30 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
#include <openMVG/matching/cascade_hasher.hpp>
|
||||||
|
#include <openMVG/matching/regions_matcher.hpp>
|
||||||
|
#include <openMVG/matching_image_collection/Matcher.hpp>
|
||||||
|
#include <openMVG/matching_image_collection/Matcher_Regions.hpp>
|
||||||
|
#include <openMVG/matching_image_collection/Pair_Builder.hpp>
|
||||||
|
#include <openMVG/sfm/pipelines/sfm_regions_provider.hpp>
|
||||||
|
#include <openMVG/features/feature.hpp>
|
||||||
|
#include <openMVG/features/sift/octaver.hpp>
|
||||||
|
#include <openMVG/features/sift/SIFT_Anatomy_Image_Describer.hpp>
|
||||||
|
#include <openMVG/features/sift/sift_DescriptorExtractor.hpp>
|
||||||
|
#include <openMVG/features/sift/sift_KeypointExtractor.hpp>
|
||||||
|
#include <openMVG/features/akaze/AKAZE.hpp>
|
||||||
|
#include <openMVG/image/image_container.hpp>
|
||||||
|
#include <openMVG/image/image_io.hpp>
|
||||||
|
#include <openMVG/numeric/numeric.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <utility>
|
||||||
#include "./base.hpp"
|
#include "./base.hpp"
|
||||||
|
|
||||||
#ifndef __FRAME_H
|
#ifndef __FRAME_H
|
||||||
#define __FRAME_H
|
#define __FRAME_H
|
||||||
|
|
||||||
|
|
||||||
typedef struct _Frame
|
typedef struct _Frame
|
||||||
{
|
{
|
||||||
FILE *stream;
|
FILE *stream;
|
||||||
@ -16,9 +34,60 @@ typedef struct _Frame
|
|||||||
} Frame;
|
} Frame;
|
||||||
|
|
||||||
FILE *make_buffer(const uint8_t *, const size_t);
|
FILE *make_buffer(const uint8_t *, const size_t);
|
||||||
|
|
||||||
int read_buffer(FILE *, uint8_t **, size_t *);
|
int read_buffer(FILE *, uint8_t **, size_t *);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
typedef Frame CFrame;
|
||||||
|
|
||||||
|
namespace DartOpenMvg
|
||||||
|
{
|
||||||
|
openMVG::image::Image<uint8_t> imageFromFrame(const Frame *);
|
||||||
|
|
||||||
|
class InMemoryMatcherRegions : public openMVG::matching_image_collection::Matcher {
|
||||||
|
void Match(
|
||||||
|
const Pair_Set &,
|
||||||
|
PariWiseMatchesContainer &,
|
||||||
|
) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Frame
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
const CFrame *cFrame;
|
||||||
|
std::stringstream mStream;
|
||||||
|
int mW;
|
||||||
|
int mH;
|
||||||
|
int mDepth;
|
||||||
|
std::unique_ptr<openMVG::features::Regions> mRegions;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Frame(const _Frame *f) : mW(f->w), mH(f->h), mDepth(f->depth)
|
||||||
|
{
|
||||||
|
cFrame = f;
|
||||||
|
uint8_t *buffer_data = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
read_buffer(f->stream, &buffer_data, &len);
|
||||||
|
mStream = std::stringstream(std::string((char *)buffer_data));
|
||||||
|
}
|
||||||
|
openMVG::image::Image<u_char> DartOpenMvg::Frame::getMvgImage();
|
||||||
|
void calculateFeatures();
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::pair<Frame, Frame> FrameMatchKey;
|
||||||
|
typedef std::map<FrameMatchKey, openMVG::matching::IndMatches> FrameFeatureMatch;
|
||||||
|
|
||||||
|
class Frames : std::vector<Frame>
|
||||||
|
{
|
||||||
|
|
||||||
|
protected:
|
||||||
|
FrameFeatureMatch mFeatureMap;
|
||||||
|
public:
|
||||||
|
void computeMatches();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
_FFI_PLUGIN
|
_FFI_PLUGIN
|
||||||
Frame *new_frame_from_handle(FILE *, int, int, int);
|
Frame *new_frame_from_handle(FILE *, int, int, int);
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ void free_image_result(ImageResult *image_result)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<u_char> Archimedes::get_image_data_as_vector(const Frame *frame)
|
std::vector<u_char> DartOpenmvg::get_image_data_as_vector(const Frame *frame)
|
||||||
{
|
{
|
||||||
rewind(frame->stream);
|
rewind(frame->stream);
|
||||||
std::vector<unsigned char> imageData;
|
std::vector<unsigned char> imageData;
|
||||||
@ -51,7 +51,7 @@ std::vector<u_char> Archimedes::get_image_data_as_vector(const Frame *frame)
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
ImageResult *Archimedes::get_image_data(const Frame *frame)
|
ImageResult *DartOpenmvg::get_image_data(const Frame *frame)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
const std::vector<u_char> imageData = get_image_data_as_vector(frame);
|
const std::vector<u_char> imageData = get_image_data_as_vector(frame);
|
||||||
@ -69,58 +69,12 @@ ImageResult *Archimedes::get_image_data(const Frame *frame)
|
|||||||
_FFI_PLUGIN
|
_FFI_PLUGIN
|
||||||
ImageResult *archimedes_get_image_data(const Frame *frame)
|
ImageResult *archimedes_get_image_data(const Frame *frame)
|
||||||
{
|
{
|
||||||
return Archimedes::get_image_data(frame);
|
return DartOpenmvg::get_image_data(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Archimedes::images_to_sfm(const Frame **frames, size_t n_frames)
|
int DartOpenmvg::images_to_sfm(const Frame **frames, size_t n_frames)
|
||||||
{
|
{
|
||||||
// https://openmvg.readthedocs.io/en/latest/openMVG/sfm/sfm/#structure-computation-from-known-camera-poses
|
// TODO
|
||||||
using namespace openMVG::sfm;
|
|
||||||
|
|
||||||
const Frame *frame = frames[0];
|
|
||||||
const std::vector<u_char> imageData = get_image_data_as_vector(frame);
|
|
||||||
|
|
||||||
const size_t w = frame->w;
|
|
||||||
const size_t h = frame->h;
|
|
||||||
|
|
||||||
// Create the Eigen matrix and the image
|
|
||||||
|
|
||||||
Eigen::Matrix<u_char, Eigen::Dynamic, Eigen::Dynamic, 1> eigenMatrix(w, h);
|
|
||||||
for (int i = 0; i < w * h; ++i) {
|
|
||||||
eigenMatrix(i / h, i % h) = imageData[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
openMVG::image::Image bvgImage(eigenMatrix);
|
|
||||||
|
|
||||||
// Extract the features from the image
|
|
||||||
openMVG::features::SIFT_Anatomy_Image_describer desc;
|
|
||||||
std::unique_ptr<openMVG::features::SIFT_Anatomy_Image_describer::Regions_type> siftanatomy = desc.Describe_SIFT_Anatomy(bvgImage);
|
|
||||||
openMVG::features::SIOPointFeatures features = siftanatomy.get()->Features();
|
|
||||||
|
|
||||||
openMVG::features::SIOPointFeature feature = features.at(0);
|
|
||||||
|
|
||||||
Eigen::MatrixBase<Eigen::Vector2f> mat1 = feature.coords().matrix();
|
|
||||||
|
|
||||||
openMVG::TriangulateNView(mat1);
|
|
||||||
|
|
||||||
// SfM_Data sfmData {};
|
|
||||||
// sfmData.views = Views();
|
|
||||||
|
|
||||||
openMVG::sfm::GlobalSfM_Rotation_AveragingSolver rotSolver;
|
|
||||||
openMVG::sfm::GlobalSfM_Translation_AveragingSolver tranSolver;
|
|
||||||
|
|
||||||
openMVG::sfm::SfM_Data_Structure_Computation_Blind computation;
|
|
||||||
|
|
||||||
|
|
||||||
openMVG::rotation_averaging::RelativeRotation relRot;
|
|
||||||
openMVG::rotation_averaging::RelativeRotations relativeRot_in;
|
|
||||||
|
|
||||||
// rotSolver.Run(
|
|
||||||
// openMVG::sfm::ERotationAveragingMethod::ROTATION_AVERAGING_L1,
|
|
||||||
// openMVG::sfm::ERelativeRotationInferenceMethod::TRIPLET_ROTATION_INFERENCE_COMPOSITION_ERROR,
|
|
||||||
// relativeRot_in,
|
|
||||||
// map_globalR,
|
|
||||||
// );
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -129,5 +83,5 @@ int Archimedes::images_to_sfm(const Frame **frames, size_t n_frames)
|
|||||||
_FFI_PLUGIN
|
_FFI_PLUGIN
|
||||||
int archimedes_images_to_sfm(const Frame **frames, size_t n_frames)
|
int archimedes_images_to_sfm(const Frame **frames, size_t n_frames)
|
||||||
{
|
{
|
||||||
return Archimedes::images_to_sfm(frames, n_frames);
|
return DartOpenmvg::images_to_sfm(frames, n_frames);
|
||||||
}
|
}
|
@ -83,7 +83,7 @@ int image_result_free(ImageResult *);
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
namespace Archimedes
|
namespace DartOpenmvg
|
||||||
{
|
{
|
||||||
std::vector<u_char> get_image_data_as_vector(const Frame *frame);
|
std::vector<u_char> get_image_data_as_vector(const Frame *frame);
|
||||||
ImageResult *get_image_data(const Frame *);
|
ImageResult *get_image_data(const Frame *);
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
void libdart_openmvg::StreamingView::load(cereal::BinaryInputArchive &ar) const {
|
void libdart_openmvg::StreamingView::load(cereal::BinaryInputArchive &ar) const {
|
||||||
uint8_t *data = NULL;
|
uint8_t *data = NULL;
|
||||||
const size_t dLen1 = (mFrame->w * mFrame->h * mFrame->depth * sizeof(uint8_t));
|
const size_t dLen1 = (mFrame->w * mFrame->h * mFrame->depth * sizeof(uint8_t));
|
||||||
ar.loadBinary(data, sizeof(uint8_t) * dLen1);
|
size_t sz1 = sizeof(uint8_t) * dLen1;
|
||||||
|
ar.loadBinary(data, sz1);
|
||||||
const size_t dlen2 = sizeof(data) * sizeof(uint8_t);
|
const size_t dlen2 = sizeof(data) * sizeof(uint8_t);
|
||||||
mFrame->stream = make_buffer(data, dlen2);
|
mFrame->stream = make_buffer(data, dlen2);
|
||||||
rewind(mFrame->stream);
|
rewind(mFrame->stream);
|
||||||
|
Loading…
Reference in New Issue
Block a user