Add Chromium-only Blender WebEngine parity work
This commit is contained in:
87
blender-5.2.0/intern/libmv/intern/autotrack.cc
Normal file
87
blender-5.2.0/intern/libmv/intern/autotrack.cc
Normal file
@@ -0,0 +1,87 @@
|
||||
/* SPDX-FileCopyrightText: 2014 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "intern/autotrack.h"
|
||||
#include "intern/tracksN.h"
|
||||
#include "intern/utildefines.h"
|
||||
#include "libmv/autotrack/autotrack.h"
|
||||
|
||||
using libmv::TrackRegionOptions;
|
||||
using libmv::TrackRegionResult;
|
||||
using mv::AutoTrack;
|
||||
using mv::FrameAccessor;
|
||||
using mv::Marker;
|
||||
|
||||
libmv_AutoTrack* libmv_autoTrackNew(libmv_FrameAccessor* frame_accessor) {
|
||||
return (libmv_AutoTrack*)LIBMV_OBJECT_NEW(AutoTrack,
|
||||
(FrameAccessor*)frame_accessor);
|
||||
}
|
||||
|
||||
void libmv_autoTrackDestroy(libmv_AutoTrack* libmv_autotrack) {
|
||||
LIBMV_OBJECT_DELETE(libmv_autotrack, AutoTrack);
|
||||
}
|
||||
|
||||
void libmv_autoTrackSetOptions(libmv_AutoTrack* libmv_autotrack,
|
||||
const libmv_AutoTrackOptions* options) {
|
||||
AutoTrack* autotrack = ((AutoTrack*)libmv_autotrack);
|
||||
libmv_configureTrackRegionOptions(options->track_region,
|
||||
&autotrack->options.track_region);
|
||||
|
||||
autotrack->options.search_region.min(0) = options->search_region.min[0];
|
||||
autotrack->options.search_region.min(1) = options->search_region.min[1];
|
||||
autotrack->options.search_region.max(0) = options->search_region.max[0];
|
||||
autotrack->options.search_region.max(1) = options->search_region.max[1];
|
||||
}
|
||||
|
||||
int libmv_autoTrackMarker(libmv_AutoTrack* libmv_autotrack,
|
||||
const libmv_TrackRegionOptions* libmv_options,
|
||||
libmv_Marker* libmv_tracked_marker,
|
||||
libmv_TrackRegionResult* libmv_result) {
|
||||
Marker tracked_marker;
|
||||
TrackRegionOptions options;
|
||||
TrackRegionResult result;
|
||||
libmv_apiMarkerToMarker(*libmv_tracked_marker, &tracked_marker);
|
||||
libmv_configureTrackRegionOptions(*libmv_options, &options);
|
||||
bool ok = (((AutoTrack*)libmv_autotrack)
|
||||
->TrackMarker(&tracked_marker, &result, &options));
|
||||
libmv_markerToApiMarker(tracked_marker, libmv_tracked_marker);
|
||||
libmv_regionTrackergetResult(result, libmv_result);
|
||||
return ok && result.is_usable();
|
||||
}
|
||||
|
||||
void libmv_autoTrackAddMarker(libmv_AutoTrack* libmv_autotrack,
|
||||
const libmv_Marker* libmv_marker) {
|
||||
Marker marker;
|
||||
libmv_apiMarkerToMarker(*libmv_marker, &marker);
|
||||
((AutoTrack*)libmv_autotrack)->AddMarker(marker);
|
||||
}
|
||||
|
||||
void libmv_autoTrackSetMarkers(libmv_AutoTrack* libmv_autotrack,
|
||||
const libmv_Marker* libmv_marker,
|
||||
size_t num_markers) {
|
||||
if (num_markers == 0) {
|
||||
// Early output.
|
||||
return;
|
||||
}
|
||||
libmv::vector<Marker> markers;
|
||||
markers.resize(num_markers);
|
||||
for (size_t i = 0; i < num_markers; ++i) {
|
||||
libmv_apiMarkerToMarker(libmv_marker[i], &markers[i]);
|
||||
}
|
||||
((AutoTrack*)libmv_autotrack)->SetMarkers(&markers);
|
||||
}
|
||||
|
||||
int libmv_autoTrackGetMarker(libmv_AutoTrack* libmv_autotrack,
|
||||
int clip,
|
||||
int frame,
|
||||
int track,
|
||||
libmv_Marker* libmv_marker) {
|
||||
Marker marker;
|
||||
int ok =
|
||||
((AutoTrack*)libmv_autotrack)->GetMarker(clip, frame, track, &marker);
|
||||
if (ok) {
|
||||
libmv_markerToApiMarker(marker, libmv_marker);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
53
blender-5.2.0/intern/libmv/intern/autotrack.h
Normal file
53
blender-5.2.0/intern/libmv/intern/autotrack.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* SPDX-FileCopyrightText: 2014 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifndef LIBMV_C_API_AUTOTRACK_H_
|
||||
#define LIBMV_C_API_AUTOTRACK_H_
|
||||
|
||||
#include "intern/frame_accessor.h"
|
||||
#include "intern/region.h"
|
||||
#include "intern/track_region.h"
|
||||
#include "intern/tracksN.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct libmv_AutoTrack libmv_AutoTrack;
|
||||
|
||||
typedef struct libmv_AutoTrackOptions {
|
||||
libmv_TrackRegionOptions track_region;
|
||||
libmv_Region search_region;
|
||||
} libmv_AutoTrackOptions;
|
||||
|
||||
libmv_AutoTrack* libmv_autoTrackNew(libmv_FrameAccessor* frame_accessor);
|
||||
|
||||
void libmv_autoTrackDestroy(libmv_AutoTrack* libmv_autotrack);
|
||||
|
||||
void libmv_autoTrackSetOptions(libmv_AutoTrack* libmv_autotrack,
|
||||
const libmv_AutoTrackOptions* options);
|
||||
|
||||
int libmv_autoTrackMarker(libmv_AutoTrack* libmv_autotrack,
|
||||
const libmv_TrackRegionOptions* libmv_options,
|
||||
libmv_Marker* libmv_tracker_marker,
|
||||
libmv_TrackRegionResult* libmv_result);
|
||||
|
||||
void libmv_autoTrackAddMarker(libmv_AutoTrack* libmv_autotrack,
|
||||
const libmv_Marker* libmv_marker);
|
||||
|
||||
void libmv_autoTrackSetMarkers(libmv_AutoTrack* libmv_autotrack,
|
||||
const libmv_Marker* libmv_marker,
|
||||
size_t num_markers);
|
||||
|
||||
int libmv_autoTrackGetMarker(libmv_AutoTrack* libmv_autotrack,
|
||||
int clip,
|
||||
int frame,
|
||||
int track,
|
||||
libmv_Marker* libmv_marker);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // LIBMV_C_API_TRACKS_H_
|
||||
413
blender-5.2.0/intern/libmv/intern/camera_intrinsics.cc
Normal file
413
blender-5.2.0/intern/libmv/intern/camera_intrinsics.cc
Normal file
@@ -0,0 +1,413 @@
|
||||
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "intern/camera_intrinsics.h"
|
||||
#include "intern/utildefines.h"
|
||||
#include "libmv/simple_pipeline/camera_intrinsics.h"
|
||||
|
||||
using libmv::BrownCameraIntrinsics;
|
||||
using libmv::CameraIntrinsics;
|
||||
using libmv::DivisionCameraIntrinsics;
|
||||
using libmv::NukeCameraIntrinsics;
|
||||
using libmv::PolynomialCameraIntrinsics;
|
||||
|
||||
libmv_CameraIntrinsics* libmv_cameraIntrinsicsNew(
|
||||
const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options) {
|
||||
CameraIntrinsics* camera_intrinsics =
|
||||
libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
|
||||
return (libmv_CameraIntrinsics*)camera_intrinsics;
|
||||
}
|
||||
|
||||
libmv_CameraIntrinsics* libmv_cameraIntrinsicsCopy(
|
||||
const libmv_CameraIntrinsics* libmv_intrinsics) {
|
||||
const CameraIntrinsics* orig_intrinsics =
|
||||
(const CameraIntrinsics*)libmv_intrinsics;
|
||||
|
||||
CameraIntrinsics* new_intrinsics = NULL;
|
||||
switch (orig_intrinsics->GetDistortionModelType()) {
|
||||
case libmv::DISTORTION_MODEL_POLYNOMIAL: {
|
||||
const PolynomialCameraIntrinsics* polynomial_intrinsics =
|
||||
static_cast<const PolynomialCameraIntrinsics*>(orig_intrinsics);
|
||||
new_intrinsics =
|
||||
LIBMV_OBJECT_NEW(PolynomialCameraIntrinsics, *polynomial_intrinsics);
|
||||
break;
|
||||
}
|
||||
case libmv::DISTORTION_MODEL_DIVISION: {
|
||||
const DivisionCameraIntrinsics* division_intrinsics =
|
||||
static_cast<const DivisionCameraIntrinsics*>(orig_intrinsics);
|
||||
new_intrinsics =
|
||||
LIBMV_OBJECT_NEW(DivisionCameraIntrinsics, *division_intrinsics);
|
||||
break;
|
||||
}
|
||||
case libmv::DISTORTION_MODEL_NUKE: {
|
||||
const NukeCameraIntrinsics* nuke_intrinsics =
|
||||
static_cast<const NukeCameraIntrinsics*>(orig_intrinsics);
|
||||
new_intrinsics = LIBMV_OBJECT_NEW(NukeCameraIntrinsics, *nuke_intrinsics);
|
||||
break;
|
||||
}
|
||||
case libmv::DISTORTION_MODEL_BROWN: {
|
||||
const BrownCameraIntrinsics* brown_intrinsics =
|
||||
static_cast<const BrownCameraIntrinsics*>(orig_intrinsics);
|
||||
new_intrinsics =
|
||||
LIBMV_OBJECT_NEW(BrownCameraIntrinsics, *brown_intrinsics);
|
||||
break;
|
||||
}
|
||||
default: assert(!"Unknown distortion model");
|
||||
}
|
||||
return (libmv_CameraIntrinsics*)new_intrinsics;
|
||||
}
|
||||
|
||||
void libmv_cameraIntrinsicsDestroy(libmv_CameraIntrinsics* libmv_intrinsics) {
|
||||
LIBMV_OBJECT_DELETE(libmv_intrinsics, CameraIntrinsics);
|
||||
}
|
||||
|
||||
void libmv_cameraIntrinsicsUpdate(
|
||||
const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
|
||||
libmv_CameraIntrinsics* libmv_intrinsics) {
|
||||
CameraIntrinsics* camera_intrinsics = (CameraIntrinsics*)libmv_intrinsics;
|
||||
|
||||
double focal_length = libmv_camera_intrinsics_options->focal_length;
|
||||
double principal_x = libmv_camera_intrinsics_options->principal_point_x;
|
||||
double principal_y = libmv_camera_intrinsics_options->principal_point_y;
|
||||
int image_width = libmv_camera_intrinsics_options->image_width;
|
||||
int image_height = libmv_camera_intrinsics_options->image_height;
|
||||
|
||||
/* Try avoid unnecessary updates, so pre-computed distortion grids
|
||||
* are not freed. */
|
||||
|
||||
if (camera_intrinsics->focal_length() != focal_length) {
|
||||
camera_intrinsics->SetFocalLength(focal_length, focal_length);
|
||||
}
|
||||
|
||||
if (camera_intrinsics->principal_point_x() != principal_x ||
|
||||
camera_intrinsics->principal_point_y() != principal_y) {
|
||||
camera_intrinsics->SetPrincipalPoint(principal_x, principal_y);
|
||||
}
|
||||
|
||||
if (camera_intrinsics->image_width() != image_width ||
|
||||
camera_intrinsics->image_height() != image_height) {
|
||||
camera_intrinsics->SetImageSize(image_width, image_height);
|
||||
}
|
||||
|
||||
switch (libmv_camera_intrinsics_options->distortion_model) {
|
||||
case LIBMV_DISTORTION_MODEL_POLYNOMIAL: {
|
||||
assert(camera_intrinsics->GetDistortionModelType() ==
|
||||
libmv::DISTORTION_MODEL_POLYNOMIAL);
|
||||
|
||||
PolynomialCameraIntrinsics* polynomial_intrinsics =
|
||||
(PolynomialCameraIntrinsics*)camera_intrinsics;
|
||||
|
||||
double k1 = libmv_camera_intrinsics_options->polynomial_k1;
|
||||
double k2 = libmv_camera_intrinsics_options->polynomial_k2;
|
||||
double k3 = libmv_camera_intrinsics_options->polynomial_k3;
|
||||
|
||||
if (polynomial_intrinsics->k1() != k1 ||
|
||||
polynomial_intrinsics->k2() != k2 ||
|
||||
polynomial_intrinsics->k3() != k3) {
|
||||
polynomial_intrinsics->SetRadialDistortion(k1, k2, k3);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case LIBMV_DISTORTION_MODEL_DIVISION: {
|
||||
assert(camera_intrinsics->GetDistortionModelType() ==
|
||||
libmv::DISTORTION_MODEL_DIVISION);
|
||||
|
||||
DivisionCameraIntrinsics* division_intrinsics =
|
||||
(DivisionCameraIntrinsics*)camera_intrinsics;
|
||||
|
||||
double k1 = libmv_camera_intrinsics_options->division_k1;
|
||||
double k2 = libmv_camera_intrinsics_options->division_k2;
|
||||
|
||||
if (division_intrinsics->k1() != k1 || division_intrinsics->k2() != k2) {
|
||||
division_intrinsics->SetDistortion(k1, k2);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LIBMV_DISTORTION_MODEL_NUKE: {
|
||||
assert(camera_intrinsics->GetDistortionModelType() ==
|
||||
libmv::DISTORTION_MODEL_NUKE);
|
||||
|
||||
NukeCameraIntrinsics* nuke_intrinsics =
|
||||
(NukeCameraIntrinsics*)camera_intrinsics;
|
||||
|
||||
double k1 = libmv_camera_intrinsics_options->nuke_k1;
|
||||
double k2 = libmv_camera_intrinsics_options->nuke_k2;
|
||||
|
||||
if (nuke_intrinsics->k1() != k1 || nuke_intrinsics->k2() != k2) {
|
||||
nuke_intrinsics->SetRadialDistortion(k1, k2);
|
||||
}
|
||||
|
||||
double p1 = libmv_camera_intrinsics_options->nuke_p1;
|
||||
double p2 = libmv_camera_intrinsics_options->nuke_p2;
|
||||
|
||||
if (nuke_intrinsics->p1() != p1 || nuke_intrinsics->p2() != p2) {
|
||||
nuke_intrinsics->SetTangentialDistortion(p1, p2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case LIBMV_DISTORTION_MODEL_BROWN: {
|
||||
assert(camera_intrinsics->GetDistortionModelType() ==
|
||||
libmv::DISTORTION_MODEL_BROWN);
|
||||
|
||||
BrownCameraIntrinsics* brown_intrinsics =
|
||||
(BrownCameraIntrinsics*)camera_intrinsics;
|
||||
|
||||
double k1 = libmv_camera_intrinsics_options->brown_k1;
|
||||
double k2 = libmv_camera_intrinsics_options->brown_k2;
|
||||
double k3 = libmv_camera_intrinsics_options->brown_k3;
|
||||
double k4 = libmv_camera_intrinsics_options->brown_k4;
|
||||
|
||||
if (brown_intrinsics->k1() != k1 || brown_intrinsics->k2() != k2 ||
|
||||
brown_intrinsics->k3() != k3 || brown_intrinsics->k4() != k4) {
|
||||
brown_intrinsics->SetRadialDistortion(k1, k2, k3, k4);
|
||||
}
|
||||
|
||||
double p1 = libmv_camera_intrinsics_options->brown_p1;
|
||||
double p2 = libmv_camera_intrinsics_options->brown_p2;
|
||||
|
||||
if (brown_intrinsics->p1() != p1 || brown_intrinsics->p2() != p2) {
|
||||
brown_intrinsics->SetTangentialDistortion(p1, p2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: assert(!"Unknown distortion model");
|
||||
}
|
||||
}
|
||||
|
||||
void libmv_cameraIntrinsicsExtractOptions(
|
||||
const libmv_CameraIntrinsics* libmv_intrinsics,
|
||||
libmv_CameraIntrinsicsOptions* camera_intrinsics_options) {
|
||||
const CameraIntrinsics* camera_intrinsics =
|
||||
(const CameraIntrinsics*)libmv_intrinsics;
|
||||
|
||||
// Fill in options which are common for all distortion models.
|
||||
camera_intrinsics_options->focal_length = camera_intrinsics->focal_length();
|
||||
camera_intrinsics_options->principal_point_x =
|
||||
camera_intrinsics->principal_point_x();
|
||||
camera_intrinsics_options->principal_point_y =
|
||||
camera_intrinsics->principal_point_y();
|
||||
|
||||
camera_intrinsics_options->image_width = camera_intrinsics->image_width();
|
||||
camera_intrinsics_options->image_height = camera_intrinsics->image_height();
|
||||
|
||||
switch (camera_intrinsics->GetDistortionModelType()) {
|
||||
case libmv::DISTORTION_MODEL_POLYNOMIAL: {
|
||||
const PolynomialCameraIntrinsics* polynomial_intrinsics =
|
||||
static_cast<const PolynomialCameraIntrinsics*>(camera_intrinsics);
|
||||
camera_intrinsics_options->distortion_model =
|
||||
LIBMV_DISTORTION_MODEL_POLYNOMIAL;
|
||||
camera_intrinsics_options->polynomial_k1 = polynomial_intrinsics->k1();
|
||||
camera_intrinsics_options->polynomial_k2 = polynomial_intrinsics->k2();
|
||||
camera_intrinsics_options->polynomial_k3 = polynomial_intrinsics->k3();
|
||||
camera_intrinsics_options->polynomial_p1 = polynomial_intrinsics->p1();
|
||||
camera_intrinsics_options->polynomial_p2 = polynomial_intrinsics->p2();
|
||||
break;
|
||||
}
|
||||
|
||||
case libmv::DISTORTION_MODEL_DIVISION: {
|
||||
const DivisionCameraIntrinsics* division_intrinsics =
|
||||
static_cast<const DivisionCameraIntrinsics*>(camera_intrinsics);
|
||||
camera_intrinsics_options->distortion_model =
|
||||
LIBMV_DISTORTION_MODEL_DIVISION;
|
||||
camera_intrinsics_options->division_k1 = division_intrinsics->k1();
|
||||
camera_intrinsics_options->division_k2 = division_intrinsics->k2();
|
||||
break;
|
||||
}
|
||||
|
||||
case libmv::DISTORTION_MODEL_NUKE: {
|
||||
const NukeCameraIntrinsics* nuke_intrinsics =
|
||||
static_cast<const NukeCameraIntrinsics*>(camera_intrinsics);
|
||||
camera_intrinsics_options->distortion_model = LIBMV_DISTORTION_MODEL_NUKE;
|
||||
camera_intrinsics_options->nuke_k1 = nuke_intrinsics->k1();
|
||||
camera_intrinsics_options->nuke_k2 = nuke_intrinsics->k2();
|
||||
camera_intrinsics_options->nuke_p1 = nuke_intrinsics->p1();
|
||||
camera_intrinsics_options->nuke_p2 = nuke_intrinsics->p2();
|
||||
break;
|
||||
}
|
||||
|
||||
case libmv::DISTORTION_MODEL_BROWN: {
|
||||
const BrownCameraIntrinsics* brown_intrinsics =
|
||||
static_cast<const BrownCameraIntrinsics*>(camera_intrinsics);
|
||||
camera_intrinsics_options->distortion_model =
|
||||
LIBMV_DISTORTION_MODEL_BROWN;
|
||||
camera_intrinsics_options->brown_k1 = brown_intrinsics->k1();
|
||||
camera_intrinsics_options->brown_k2 = brown_intrinsics->k2();
|
||||
camera_intrinsics_options->brown_k3 = brown_intrinsics->k3();
|
||||
camera_intrinsics_options->brown_k4 = brown_intrinsics->k4();
|
||||
camera_intrinsics_options->brown_p1 = brown_intrinsics->p1();
|
||||
camera_intrinsics_options->brown_p2 = brown_intrinsics->p2();
|
||||
break;
|
||||
}
|
||||
|
||||
default: assert(!"Unknown distortion model");
|
||||
}
|
||||
}
|
||||
|
||||
void libmv_cameraIntrinsicsUndistortByte(
|
||||
const libmv_CameraIntrinsics* libmv_intrinsics,
|
||||
const unsigned char* source_image,
|
||||
int width,
|
||||
int height,
|
||||
float overscan,
|
||||
int channels,
|
||||
unsigned char* destination_image) {
|
||||
CameraIntrinsics* camera_intrinsics = (CameraIntrinsics*)libmv_intrinsics;
|
||||
camera_intrinsics->UndistortBuffer(
|
||||
source_image, width, height, overscan, channels, destination_image);
|
||||
}
|
||||
|
||||
void libmv_cameraIntrinsicsUndistortFloat(
|
||||
const libmv_CameraIntrinsics* libmv_intrinsics,
|
||||
const float* source_image,
|
||||
int width,
|
||||
int height,
|
||||
float overscan,
|
||||
int channels,
|
||||
float* destination_image) {
|
||||
CameraIntrinsics* intrinsics = (CameraIntrinsics*)libmv_intrinsics;
|
||||
intrinsics->UndistortBuffer(
|
||||
source_image, width, height, overscan, channels, destination_image);
|
||||
}
|
||||
|
||||
void libmv_cameraIntrinsicsDistortByte(
|
||||
const struct libmv_CameraIntrinsics* libmv_intrinsics,
|
||||
const unsigned char* source_image,
|
||||
int width,
|
||||
int height,
|
||||
float overscan,
|
||||
int channels,
|
||||
unsigned char* destination_image) {
|
||||
CameraIntrinsics* intrinsics = (CameraIntrinsics*)libmv_intrinsics;
|
||||
intrinsics->DistortBuffer(
|
||||
source_image, width, height, overscan, channels, destination_image);
|
||||
}
|
||||
|
||||
void libmv_cameraIntrinsicsDistortFloat(
|
||||
const libmv_CameraIntrinsics* libmv_intrinsics,
|
||||
float* source_image,
|
||||
int width,
|
||||
int height,
|
||||
float overscan,
|
||||
int channels,
|
||||
float* destination_image) {
|
||||
CameraIntrinsics* intrinsics = (CameraIntrinsics*)libmv_intrinsics;
|
||||
intrinsics->DistortBuffer(
|
||||
source_image, width, height, overscan, channels, destination_image);
|
||||
}
|
||||
|
||||
void libmv_cameraIntrinsicsApply(
|
||||
const struct libmv_CameraIntrinsics* libmv_intrinsics,
|
||||
double x,
|
||||
double y,
|
||||
double* x1,
|
||||
double* y1) {
|
||||
CameraIntrinsics* intrinsics = (CameraIntrinsics*)libmv_intrinsics;
|
||||
intrinsics->ApplyIntrinsics(x, y, x1, y1);
|
||||
}
|
||||
|
||||
void libmv_cameraIntrinsicsInvert(
|
||||
const struct libmv_CameraIntrinsics* libmv_intrinsics,
|
||||
double x,
|
||||
double y,
|
||||
double* x1,
|
||||
double* y1) {
|
||||
CameraIntrinsics* intrinsics = (CameraIntrinsics*)libmv_intrinsics;
|
||||
intrinsics->InvertIntrinsics(x, y, x1, y1);
|
||||
}
|
||||
|
||||
static void libmv_cameraIntrinsicsFillFromOptions(
|
||||
const libmv_CameraIntrinsicsOptions* camera_intrinsics_options,
|
||||
CameraIntrinsics* camera_intrinsics) {
|
||||
camera_intrinsics->SetFocalLength(camera_intrinsics_options->focal_length,
|
||||
camera_intrinsics_options->focal_length);
|
||||
|
||||
camera_intrinsics->SetPrincipalPoint(
|
||||
camera_intrinsics_options->principal_point_x,
|
||||
camera_intrinsics_options->principal_point_y);
|
||||
|
||||
camera_intrinsics->SetImageSize(camera_intrinsics_options->image_width,
|
||||
camera_intrinsics_options->image_height);
|
||||
|
||||
switch (camera_intrinsics_options->distortion_model) {
|
||||
case LIBMV_DISTORTION_MODEL_POLYNOMIAL: {
|
||||
PolynomialCameraIntrinsics* polynomial_intrinsics =
|
||||
static_cast<PolynomialCameraIntrinsics*>(camera_intrinsics);
|
||||
|
||||
polynomial_intrinsics->SetRadialDistortion(
|
||||
camera_intrinsics_options->polynomial_k1,
|
||||
camera_intrinsics_options->polynomial_k2,
|
||||
camera_intrinsics_options->polynomial_k3);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LIBMV_DISTORTION_MODEL_DIVISION: {
|
||||
DivisionCameraIntrinsics* division_intrinsics =
|
||||
static_cast<DivisionCameraIntrinsics*>(camera_intrinsics);
|
||||
|
||||
division_intrinsics->SetDistortion(
|
||||
camera_intrinsics_options->division_k1,
|
||||
camera_intrinsics_options->division_k2);
|
||||
break;
|
||||
}
|
||||
|
||||
case LIBMV_DISTORTION_MODEL_NUKE: {
|
||||
NukeCameraIntrinsics* nuke_intrinsics =
|
||||
static_cast<NukeCameraIntrinsics*>(camera_intrinsics);
|
||||
|
||||
nuke_intrinsics->SetRadialDistortion(camera_intrinsics_options->nuke_k1,
|
||||
camera_intrinsics_options->nuke_k2);
|
||||
nuke_intrinsics->SetTangentialDistortion(
|
||||
camera_intrinsics_options->nuke_p1,
|
||||
camera_intrinsics_options->nuke_p2);
|
||||
break;
|
||||
}
|
||||
|
||||
case LIBMV_DISTORTION_MODEL_BROWN: {
|
||||
BrownCameraIntrinsics* brown_intrinsics =
|
||||
static_cast<BrownCameraIntrinsics*>(camera_intrinsics);
|
||||
|
||||
brown_intrinsics->SetRadialDistortion(
|
||||
camera_intrinsics_options->brown_k1,
|
||||
camera_intrinsics_options->brown_k2,
|
||||
camera_intrinsics_options->brown_k3,
|
||||
camera_intrinsics_options->brown_k4);
|
||||
brown_intrinsics->SetTangentialDistortion(
|
||||
camera_intrinsics_options->brown_p1,
|
||||
camera_intrinsics_options->brown_p2);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: assert(!"Unknown distortion model");
|
||||
}
|
||||
}
|
||||
|
||||
CameraIntrinsics* libmv_cameraIntrinsicsCreateFromOptions(
|
||||
const libmv_CameraIntrinsicsOptions* camera_intrinsics_options) {
|
||||
CameraIntrinsics* camera_intrinsics = NULL;
|
||||
switch (camera_intrinsics_options->distortion_model) {
|
||||
case LIBMV_DISTORTION_MODEL_POLYNOMIAL:
|
||||
camera_intrinsics = LIBMV_OBJECT_NEW(PolynomialCameraIntrinsics);
|
||||
break;
|
||||
case LIBMV_DISTORTION_MODEL_DIVISION:
|
||||
camera_intrinsics = LIBMV_OBJECT_NEW(DivisionCameraIntrinsics);
|
||||
break;
|
||||
case LIBMV_DISTORTION_MODEL_NUKE:
|
||||
camera_intrinsics = LIBMV_OBJECT_NEW(NukeCameraIntrinsics);
|
||||
break;
|
||||
case LIBMV_DISTORTION_MODEL_BROWN:
|
||||
camera_intrinsics = LIBMV_OBJECT_NEW(BrownCameraIntrinsics);
|
||||
break;
|
||||
default: assert(!"Unknown distortion model");
|
||||
}
|
||||
libmv_cameraIntrinsicsFillFromOptions(camera_intrinsics_options,
|
||||
camera_intrinsics);
|
||||
return camera_intrinsics;
|
||||
}
|
||||
123
blender-5.2.0/intern/libmv/intern/camera_intrinsics.h
Normal file
123
blender-5.2.0/intern/libmv/intern/camera_intrinsics.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifndef LIBMV_C_API_CAMERA_INTRINSICS_H_
|
||||
#define LIBMV_C_API_CAMERA_INTRINSICS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct libmv_CameraIntrinsics libmv_CameraIntrinsics;
|
||||
|
||||
enum {
|
||||
LIBMV_DISTORTION_MODEL_POLYNOMIAL = 0,
|
||||
LIBMV_DISTORTION_MODEL_DIVISION = 1,
|
||||
LIBMV_DISTORTION_MODEL_NUKE = 2,
|
||||
LIBMV_DISTORTION_MODEL_BROWN = 3,
|
||||
};
|
||||
|
||||
typedef struct libmv_CameraIntrinsicsOptions {
|
||||
// Common settings of all distortion models.
|
||||
int distortion_model;
|
||||
int image_width, image_height;
|
||||
double focal_length;
|
||||
double principal_point_x, principal_point_y;
|
||||
|
||||
// Radial distortion model.
|
||||
double polynomial_k1, polynomial_k2, polynomial_k3;
|
||||
double polynomial_p1, polynomial_p2;
|
||||
|
||||
// Division distortion model.
|
||||
double division_k1, division_k2;
|
||||
|
||||
// Nuke distortion model.
|
||||
double nuke_k1, nuke_k2;
|
||||
double nuke_p1, nuke_p2;
|
||||
|
||||
// Brown-Conrady distortion model.
|
||||
double brown_k1, brown_k2, brown_k3, brown_k4;
|
||||
double brown_p1, brown_p2;
|
||||
} libmv_CameraIntrinsicsOptions;
|
||||
|
||||
libmv_CameraIntrinsics* libmv_cameraIntrinsicsNew(
|
||||
const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options);
|
||||
|
||||
libmv_CameraIntrinsics* libmv_cameraIntrinsicsCopy(
|
||||
const libmv_CameraIntrinsics* libmv_intrinsics);
|
||||
|
||||
void libmv_cameraIntrinsicsDestroy(libmv_CameraIntrinsics* libmv_intrinsics);
|
||||
void libmv_cameraIntrinsicsUpdate(
|
||||
const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
|
||||
libmv_CameraIntrinsics* libmv_intrinsics);
|
||||
|
||||
void libmv_cameraIntrinsicsExtractOptions(
|
||||
const libmv_CameraIntrinsics* libmv_intrinsics,
|
||||
libmv_CameraIntrinsicsOptions* camera_intrinsics_options);
|
||||
|
||||
void libmv_cameraIntrinsicsUndistortByte(
|
||||
const libmv_CameraIntrinsics* libmv_intrinsics,
|
||||
const unsigned char* source_image,
|
||||
int width,
|
||||
int height,
|
||||
float overscan,
|
||||
int channels,
|
||||
unsigned char* destination_image);
|
||||
|
||||
void libmv_cameraIntrinsicsUndistortFloat(
|
||||
const libmv_CameraIntrinsics* libmv_intrinsics,
|
||||
const float* source_image,
|
||||
int width,
|
||||
int height,
|
||||
float overscan,
|
||||
int channels,
|
||||
float* destination_image);
|
||||
|
||||
void libmv_cameraIntrinsicsDistortByte(
|
||||
const struct libmv_CameraIntrinsics* libmv_intrinsics,
|
||||
const unsigned char* source_image,
|
||||
int width,
|
||||
int height,
|
||||
float overscan,
|
||||
int channels,
|
||||
unsigned char* destination_image);
|
||||
|
||||
void libmv_cameraIntrinsicsDistortFloat(
|
||||
const libmv_CameraIntrinsics* libmv_intrinsics,
|
||||
float* source_image,
|
||||
int width,
|
||||
int height,
|
||||
float overscan,
|
||||
int channels,
|
||||
float* destination_image);
|
||||
|
||||
void libmv_cameraIntrinsicsApply(
|
||||
const struct libmv_CameraIntrinsics* libmv_intrinsics,
|
||||
double x,
|
||||
double y,
|
||||
double* x1,
|
||||
double* y1);
|
||||
|
||||
void libmv_cameraIntrinsicsInvert(
|
||||
const struct libmv_CameraIntrinsics* libmv_intrinsics,
|
||||
double x,
|
||||
double y,
|
||||
double* x1,
|
||||
double* y1);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace libmv {
|
||||
class CameraIntrinsics;
|
||||
}
|
||||
|
||||
libmv::CameraIntrinsics* libmv_cameraIntrinsicsCreateFromOptions(
|
||||
const libmv_CameraIntrinsicsOptions* camera_intrinsics_options);
|
||||
#endif
|
||||
|
||||
#endif // LIBMV_C_API_CAMERA_INTRINSICS_H_
|
||||
126
blender-5.2.0/intern/libmv/intern/detector.cc
Normal file
126
blender-5.2.0/intern/libmv/intern/detector.cc
Normal file
@@ -0,0 +1,126 @@
|
||||
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "intern/detector.h"
|
||||
#include "intern/image.h"
|
||||
#include "intern/utildefines.h"
|
||||
#include "libmv/simple_pipeline/detect.h"
|
||||
|
||||
using libmv::Detect;
|
||||
using libmv::DetectOptions;
|
||||
using libmv::Feature;
|
||||
using libmv::FloatImage;
|
||||
|
||||
struct libmv_Features {
|
||||
int count;
|
||||
Feature* features;
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
libmv_Features* libmv_featuresFromVector(
|
||||
const libmv::vector<Feature>& features) {
|
||||
libmv_Features* libmv_features = LIBMV_STRUCT_NEW(libmv_Features, 1);
|
||||
int count = features.size();
|
||||
if (count) {
|
||||
libmv_features->features = LIBMV_STRUCT_NEW(Feature, count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
libmv_features->features[i] = features.at(i);
|
||||
}
|
||||
} else {
|
||||
libmv_features->features = NULL;
|
||||
}
|
||||
libmv_features->count = count;
|
||||
return libmv_features;
|
||||
}
|
||||
|
||||
void libmv_convertDetectorOptions(libmv_DetectOptions* options,
|
||||
DetectOptions* detector_options) {
|
||||
switch (options->detector) {
|
||||
#define LIBMV_CONVERT(the_detector) \
|
||||
case LIBMV_DETECTOR_##the_detector: \
|
||||
detector_options->type = DetectOptions::the_detector; \
|
||||
break;
|
||||
LIBMV_CONVERT(FAST)
|
||||
LIBMV_CONVERT(MORAVEC)
|
||||
LIBMV_CONVERT(HARRIS)
|
||||
#undef LIBMV_CONVERT
|
||||
}
|
||||
detector_options->margin = options->margin;
|
||||
detector_options->min_distance = options->min_distance;
|
||||
detector_options->fast_min_trackness = options->fast_min_trackness;
|
||||
detector_options->moravec_max_count = options->moravec_max_count;
|
||||
detector_options->moravec_pattern = options->moravec_pattern;
|
||||
detector_options->harris_threshold = options->harris_threshold;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
libmv_Features* libmv_detectFeaturesByte(const unsigned char* image_buffer,
|
||||
int width,
|
||||
int height,
|
||||
int channels,
|
||||
libmv_DetectOptions* options) {
|
||||
// Prepare the image.
|
||||
FloatImage image;
|
||||
libmv_byteBufferToFloatImage(image_buffer, width, height, channels, &image);
|
||||
|
||||
// Configure detector.
|
||||
DetectOptions detector_options;
|
||||
libmv_convertDetectorOptions(options, &detector_options);
|
||||
|
||||
// Run the detector.
|
||||
libmv::vector<Feature> detected_features;
|
||||
Detect(image, detector_options, &detected_features);
|
||||
|
||||
// Convert result to C-API.
|
||||
libmv_Features* result = libmv_featuresFromVector(detected_features);
|
||||
return result;
|
||||
}
|
||||
|
||||
libmv_Features* libmv_detectFeaturesFloat(const float* image_buffer,
|
||||
int width,
|
||||
int height,
|
||||
int channels,
|
||||
libmv_DetectOptions* options) {
|
||||
// Prepare the image.
|
||||
FloatImage image;
|
||||
libmv_floatBufferToFloatImage(image_buffer, width, height, channels, &image);
|
||||
|
||||
// Configure detector.
|
||||
DetectOptions detector_options;
|
||||
libmv_convertDetectorOptions(options, &detector_options);
|
||||
|
||||
// Run the detector.
|
||||
libmv::vector<Feature> detected_features;
|
||||
Detect(image, detector_options, &detected_features);
|
||||
|
||||
// Convert result to C-API.
|
||||
libmv_Features* result = libmv_featuresFromVector(detected_features);
|
||||
return result;
|
||||
}
|
||||
|
||||
void libmv_featuresDestroy(libmv_Features* libmv_features) {
|
||||
if (libmv_features->features) {
|
||||
LIBMV_STRUCT_DELETE(libmv_features->features);
|
||||
}
|
||||
LIBMV_STRUCT_DELETE(libmv_features);
|
||||
}
|
||||
|
||||
int libmv_countFeatures(const libmv_Features* libmv_features) {
|
||||
return libmv_features->count;
|
||||
}
|
||||
|
||||
void libmv_getFeature(const libmv_Features* libmv_features,
|
||||
int number,
|
||||
double* x,
|
||||
double* y,
|
||||
double* score,
|
||||
double* size) {
|
||||
Feature& feature = libmv_features->features[number];
|
||||
*x = feature.x;
|
||||
*y = feature.y;
|
||||
*score = feature.score;
|
||||
*size = feature.size;
|
||||
}
|
||||
55
blender-5.2.0/intern/libmv/intern/detector.h
Normal file
55
blender-5.2.0/intern/libmv/intern/detector.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifndef LIBMV_C_API_DETECTOR_H_
|
||||
#define LIBMV_C_API_DETECTOR_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct libmv_Features libmv_Features;
|
||||
|
||||
enum {
|
||||
LIBMV_DETECTOR_FAST,
|
||||
LIBMV_DETECTOR_MORAVEC,
|
||||
LIBMV_DETECTOR_HARRIS,
|
||||
};
|
||||
|
||||
typedef struct libmv_DetectOptions {
|
||||
int detector;
|
||||
int margin;
|
||||
int min_distance;
|
||||
int fast_min_trackness;
|
||||
int moravec_max_count;
|
||||
unsigned char* moravec_pattern;
|
||||
double harris_threshold;
|
||||
} libmv_DetectOptions;
|
||||
|
||||
libmv_Features* libmv_detectFeaturesByte(const unsigned char* image_buffer,
|
||||
int width,
|
||||
int height,
|
||||
int channels,
|
||||
libmv_DetectOptions* options);
|
||||
|
||||
libmv_Features* libmv_detectFeaturesFloat(const float* image_buffer,
|
||||
int width,
|
||||
int height,
|
||||
int channels,
|
||||
libmv_DetectOptions* options);
|
||||
|
||||
void libmv_featuresDestroy(libmv_Features* libmv_features);
|
||||
int libmv_countFeatures(const libmv_Features* libmv_features);
|
||||
void libmv_getFeature(const libmv_Features* libmv_features,
|
||||
int number,
|
||||
double* x,
|
||||
double* y,
|
||||
double* score,
|
||||
double* size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // LIBMV_C_API_DETECTOR_H_
|
||||
178
blender-5.2.0/intern/libmv/intern/frame_accessor.cc
Normal file
178
blender-5.2.0/intern/libmv/intern/frame_accessor.cc
Normal file
@@ -0,0 +1,178 @@
|
||||
/* SPDX-FileCopyrightText: 2014 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "intern/frame_accessor.h"
|
||||
#include "intern/image.h"
|
||||
#include "intern/utildefines.h"
|
||||
#include "libmv/autotrack/frame_accessor.h"
|
||||
#include "libmv/autotrack/region.h"
|
||||
#include "libmv/image/image.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using libmv::FloatImage;
|
||||
using mv::FrameAccessor;
|
||||
using mv::Region;
|
||||
|
||||
struct LibmvFrameAccessor : public FrameAccessor {
|
||||
LibmvFrameAccessor(libmv_FrameAccessorUserData* user_data,
|
||||
libmv_GetImageCallback get_image_callback,
|
||||
libmv_ReleaseImageCallback release_image_callback,
|
||||
libmv_GetMaskForTrackCallback get_mask_for_track_callback,
|
||||
libmv_ReleaseMaskCallback release_mask_callback)
|
||||
: user_data_(user_data),
|
||||
get_image_callback_(get_image_callback),
|
||||
release_image_callback_(release_image_callback),
|
||||
get_mask_for_track_callback_(get_mask_for_track_callback),
|
||||
release_mask_callback_(release_mask_callback) {}
|
||||
|
||||
virtual ~LibmvFrameAccessor() {}
|
||||
|
||||
libmv_InputMode get_libmv_input_mode(InputMode input_mode) {
|
||||
switch (input_mode) {
|
||||
#define CHECK_INPUT_MODE(mode) \
|
||||
case mode: return LIBMV_IMAGE_MODE_##mode;
|
||||
CHECK_INPUT_MODE(MONO)
|
||||
CHECK_INPUT_MODE(RGBA)
|
||||
#undef CHECK_INPUT_MODE
|
||||
}
|
||||
assert(!"unknown input mode passed from Libmv.");
|
||||
// TODO(sergey): Proper error handling here in the future.
|
||||
return LIBMV_IMAGE_MODE_MONO;
|
||||
}
|
||||
|
||||
void get_libmv_region(const Region& region, libmv_Region* libmv_region) {
|
||||
libmv_region->min[0] = region.min(0);
|
||||
libmv_region->min[1] = region.min(1);
|
||||
libmv_region->max[0] = region.max(0);
|
||||
libmv_region->max[1] = region.max(1);
|
||||
}
|
||||
|
||||
Key GetImage(int clip,
|
||||
int frame,
|
||||
InputMode input_mode,
|
||||
int downscale,
|
||||
const Region* region,
|
||||
const Transform* transform,
|
||||
FloatImage* destination) {
|
||||
float* float_buffer;
|
||||
int width, height, channels;
|
||||
libmv_Region libmv_region;
|
||||
if (region) {
|
||||
get_libmv_region(*region, &libmv_region);
|
||||
}
|
||||
Key cache_key = get_image_callback_(user_data_,
|
||||
clip,
|
||||
frame,
|
||||
get_libmv_input_mode(input_mode),
|
||||
downscale,
|
||||
region != NULL ? &libmv_region : NULL,
|
||||
(libmv_FrameTransform*)transform,
|
||||
&float_buffer,
|
||||
&width,
|
||||
&height,
|
||||
&channels);
|
||||
|
||||
// TODO(sergey): Dumb code for until we can set data directly.
|
||||
FloatImage temp_image(float_buffer, height, width, channels);
|
||||
destination->CopyFrom(temp_image);
|
||||
|
||||
return cache_key;
|
||||
}
|
||||
|
||||
void ReleaseImage(Key cache_key) { release_image_callback_(cache_key); }
|
||||
|
||||
Key GetMaskForTrack(int clip,
|
||||
int frame,
|
||||
int track,
|
||||
const Region* region,
|
||||
FloatImage* destination) {
|
||||
float* float_buffer;
|
||||
int width, height;
|
||||
libmv_Region libmv_region;
|
||||
if (region) {
|
||||
get_libmv_region(*region, &libmv_region);
|
||||
}
|
||||
Key cache_key =
|
||||
get_mask_for_track_callback_(user_data_,
|
||||
clip,
|
||||
frame,
|
||||
track,
|
||||
region != NULL ? &libmv_region : NULL,
|
||||
&float_buffer,
|
||||
&width,
|
||||
&height);
|
||||
|
||||
if (cache_key == NULL) {
|
||||
// No mask for the given track.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// TODO(sergey): Dumb code for until we can set data directly.
|
||||
FloatImage temp_image(float_buffer, height, width, 1);
|
||||
destination->CopyFrom(temp_image);
|
||||
|
||||
return cache_key;
|
||||
}
|
||||
|
||||
void ReleaseMask(Key key) { release_mask_callback_(key); }
|
||||
|
||||
bool GetClipDimensions(int /*clip*/, int* /*width*/, int* /*height*/) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int NumClips() { return 1; }
|
||||
|
||||
int NumFrames(int /*clip*/) { return 0; }
|
||||
|
||||
libmv_FrameAccessorUserData* user_data_;
|
||||
libmv_GetImageCallback get_image_callback_;
|
||||
libmv_ReleaseImageCallback release_image_callback_;
|
||||
libmv_GetMaskForTrackCallback get_mask_for_track_callback_;
|
||||
libmv_ReleaseMaskCallback release_mask_callback_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
libmv_FrameAccessor* libmv_FrameAccessorNew(
|
||||
libmv_FrameAccessorUserData* user_data,
|
||||
libmv_GetImageCallback get_image_callback,
|
||||
libmv_ReleaseImageCallback release_image_callback,
|
||||
libmv_GetMaskForTrackCallback get_mask_for_track_callback,
|
||||
libmv_ReleaseMaskCallback release_mask_callback) {
|
||||
return (libmv_FrameAccessor*)LIBMV_OBJECT_NEW(LibmvFrameAccessor,
|
||||
user_data,
|
||||
get_image_callback,
|
||||
release_image_callback,
|
||||
get_mask_for_track_callback,
|
||||
release_mask_callback);
|
||||
}
|
||||
|
||||
void libmv_FrameAccessorDestroy(libmv_FrameAccessor* frame_accessor) {
|
||||
LIBMV_OBJECT_DELETE(frame_accessor, LibmvFrameAccessor);
|
||||
}
|
||||
|
||||
int64_t libmv_frameAccessorgetTransformKey(
|
||||
const libmv_FrameTransform* transform) {
|
||||
return ((FrameAccessor::Transform*)transform)->key();
|
||||
}
|
||||
|
||||
void libmv_frameAccessorgetTransformRun(const libmv_FrameTransform* transform,
|
||||
const libmv_FloatImage* input_image,
|
||||
libmv_FloatImage* output_image) {
|
||||
const FloatImage input(input_image->buffer,
|
||||
input_image->height,
|
||||
input_image->width,
|
||||
input_image->channels);
|
||||
|
||||
FloatImage output;
|
||||
((FrameAccessor::Transform*)transform)->run(input, &output);
|
||||
|
||||
int num_pixels = output.Width() * output.Height() * output.Depth();
|
||||
output_image->buffer = new float[num_pixels];
|
||||
memcpy(output_image->buffer, output.Data(), num_pixels * sizeof(float));
|
||||
output_image->width = output.Width();
|
||||
output_image->height = output.Height();
|
||||
output_image->channels = output.Depth();
|
||||
}
|
||||
71
blender-5.2.0/intern/libmv/intern/frame_accessor.h
Normal file
71
blender-5.2.0/intern/libmv/intern/frame_accessor.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/* SPDX-FileCopyrightText: 2014 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifndef LIBMV_C_API_FRAME_ACCESSOR_H_
|
||||
#define LIBMV_C_API_FRAME_ACCESSOR_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "intern/image.h"
|
||||
#include "intern/region.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct libmv_FrameAccessor libmv_FrameAccessor;
|
||||
typedef struct libmv_FrameTransform libmv_FrameTransform;
|
||||
typedef struct libmv_FrameAccessorUserData libmv_FrameAccessorUserData;
|
||||
typedef void* libmv_CacheKey;
|
||||
|
||||
typedef enum {
|
||||
LIBMV_IMAGE_MODE_MONO,
|
||||
LIBMV_IMAGE_MODE_RGBA,
|
||||
} libmv_InputMode;
|
||||
|
||||
typedef libmv_CacheKey (*libmv_GetImageCallback)(
|
||||
libmv_FrameAccessorUserData* user_data,
|
||||
int clip,
|
||||
int frame,
|
||||
libmv_InputMode input_mode,
|
||||
int downscale,
|
||||
const libmv_Region* region,
|
||||
const libmv_FrameTransform* transform,
|
||||
float** destination,
|
||||
int* width,
|
||||
int* height,
|
||||
int* channels);
|
||||
|
||||
typedef void (*libmv_ReleaseImageCallback)(libmv_CacheKey cache_key);
|
||||
|
||||
typedef libmv_CacheKey (*libmv_GetMaskForTrackCallback)(
|
||||
libmv_FrameAccessorUserData* user_data,
|
||||
int clip,
|
||||
int frame,
|
||||
int track,
|
||||
const libmv_Region* region,
|
||||
float** destination,
|
||||
int* width,
|
||||
int* height);
|
||||
typedef void (*libmv_ReleaseMaskCallback)(libmv_CacheKey cache_key);
|
||||
|
||||
libmv_FrameAccessor* libmv_FrameAccessorNew(
|
||||
libmv_FrameAccessorUserData* user_data,
|
||||
libmv_GetImageCallback get_image_callback,
|
||||
libmv_ReleaseImageCallback release_image_callback,
|
||||
libmv_GetMaskForTrackCallback get_mask_for_track_callback,
|
||||
libmv_ReleaseMaskCallback release_mask_callback);
|
||||
void libmv_FrameAccessorDestroy(libmv_FrameAccessor* frame_accessor);
|
||||
|
||||
int64_t libmv_frameAccessorgetTransformKey(
|
||||
const libmv_FrameTransform* transform);
|
||||
|
||||
void libmv_frameAccessorgetTransformRun(const libmv_FrameTransform* transform,
|
||||
const libmv_FloatImage* input_image,
|
||||
libmv_FloatImage* output_image);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // LIBMV_C_API_FRAME_ACCESSOR_H_
|
||||
35
blender-5.2.0/intern/libmv/intern/homography.cc
Normal file
35
blender-5.2.0/intern/libmv/intern/homography.cc
Normal file
@@ -0,0 +1,35 @@
|
||||
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "intern/homography.h"
|
||||
#include "intern/utildefines.h"
|
||||
#include "libmv/logging/logging.h"
|
||||
#include "libmv/multiview/homography.h"
|
||||
|
||||
void libmv_homography2DFromCorrespondencesEuc(/* const */ double (*x1)[2],
|
||||
/* const */ double (*x2)[2],
|
||||
int num_points,
|
||||
double H[3][3]) {
|
||||
libmv::Mat x1_mat, x2_mat;
|
||||
libmv::Mat3 H_mat;
|
||||
|
||||
x1_mat.resize(2, num_points);
|
||||
x2_mat.resize(2, num_points);
|
||||
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
x1_mat.col(i) = libmv::Vec2(x1[i][0], x1[i][1]);
|
||||
x2_mat.col(i) = libmv::Vec2(x2[i][0], x2[i][1]);
|
||||
}
|
||||
|
||||
LG << "x1: " << x1_mat;
|
||||
LG << "x2: " << x2_mat;
|
||||
|
||||
libmv::EstimateHomographyOptions options;
|
||||
libmv::EstimateHomography2DFromCorrespondences(
|
||||
x1_mat, x2_mat, options, &H_mat);
|
||||
|
||||
LG << "H: " << H_mat;
|
||||
|
||||
memcpy(H, H_mat.data(), 9 * sizeof(double));
|
||||
}
|
||||
21
blender-5.2.0/intern/libmv/intern/homography.h
Normal file
21
blender-5.2.0/intern/libmv/intern/homography.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifndef LIBMV_C_API_HOMOGRAPHY_H_
|
||||
#define LIBMV_C_API_HOMOGRAPHY_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void libmv_homography2DFromCorrespondencesEuc(/* const */ double (*x1)[2],
|
||||
/* const */ double (*x2)[2],
|
||||
int num_points,
|
||||
double H[3][3]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // LIBMV_C_API_HOMOGRAPHY_H_
|
||||
252
blender-5.2.0/intern/libmv/intern/image.cc
Normal file
252
blender-5.2.0/intern/libmv/intern/image.cc
Normal file
@@ -0,0 +1,252 @@
|
||||
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "intern/image.h"
|
||||
#include "intern/utildefines.h"
|
||||
#include "libmv/tracking/track_region.h"
|
||||
|
||||
#include <png.h>
|
||||
#include <cassert>
|
||||
|
||||
using libmv::FloatImage;
|
||||
using libmv::SamplePlanarPatch;
|
||||
|
||||
void libmv_floatImageDestroy(libmv_FloatImage* image) {
|
||||
delete[] image->buffer;
|
||||
}
|
||||
|
||||
/* Image <-> buffers conversion */
|
||||
|
||||
void libmv_byteBufferToFloatImage(const unsigned char* buffer,
|
||||
int width,
|
||||
int height,
|
||||
int channels,
|
||||
FloatImage* image) {
|
||||
image->Resize(height, width, channels);
|
||||
for (int y = 0, a = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int k = 0; k < channels; k++) {
|
||||
(*image)(y, x, k) = (float)buffer[a++] / 255.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void libmv_floatBufferToFloatImage(const float* buffer,
|
||||
int width,
|
||||
int height,
|
||||
int channels,
|
||||
FloatImage* image) {
|
||||
image->Resize(height, width, channels);
|
||||
for (int y = 0, a = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int k = 0; k < channels; k++) {
|
||||
(*image)(y, x, k) = buffer[a++];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void libmv_floatImageToFloatBuffer(const FloatImage& image, float* buffer) {
|
||||
for (int y = 0, a = 0; y < image.Height(); y++) {
|
||||
for (int x = 0; x < image.Width(); x++) {
|
||||
for (int k = 0; k < image.Depth(); k++) {
|
||||
buffer[a++] = image(y, x, k);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void libmv_floatImageToByteBuffer(const libmv::FloatImage& image,
|
||||
unsigned char* buffer) {
|
||||
for (int y = 0, a = 0; y < image.Height(); y++) {
|
||||
for (int x = 0; x < image.Width(); x++) {
|
||||
for (int k = 0; k < image.Depth(); k++) {
|
||||
buffer[a++] = image(y, x, k) * 255.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool savePNGImage(png_bytep* row_pointers,
|
||||
int width,
|
||||
int height,
|
||||
int depth,
|
||||
int color_type,
|
||||
const char* file_name) {
|
||||
png_infop info_ptr;
|
||||
png_structp png_ptr;
|
||||
FILE* fp = fopen(file_name, "wb");
|
||||
|
||||
if (fp == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Initialize stuff */
|
||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
png_init_io(png_ptr, fp);
|
||||
|
||||
/* Write PNG header. */
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
png_set_IHDR(png_ptr,
|
||||
info_ptr,
|
||||
width,
|
||||
height,
|
||||
depth,
|
||||
color_type,
|
||||
PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_BASE,
|
||||
PNG_FILTER_TYPE_BASE);
|
||||
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
|
||||
/* Write bytes/ */
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
png_write_image(png_ptr, row_pointers);
|
||||
|
||||
/* End write/ */
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
png_write_end(png_ptr, NULL);
|
||||
fclose(fp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool libmv_saveImage(const FloatImage& image,
|
||||
const char* prefix,
|
||||
int x0,
|
||||
int y0) {
|
||||
int x, y;
|
||||
png_bytep* row_pointers;
|
||||
|
||||
assert(image.Depth() == 1);
|
||||
|
||||
row_pointers = new png_bytep[image.Height()];
|
||||
|
||||
for (y = 0; y < image.Height(); y++) {
|
||||
row_pointers[y] = new png_byte[4 * image.Width()];
|
||||
|
||||
for (x = 0; x < image.Width(); x++) {
|
||||
if (x0 == x && image.Height() - y0 - 1 == y) {
|
||||
row_pointers[y][x * 4 + 0] = 255;
|
||||
row_pointers[y][x * 4 + 1] = 0;
|
||||
row_pointers[y][x * 4 + 2] = 0;
|
||||
row_pointers[y][x * 4 + 3] = 255;
|
||||
} else {
|
||||
float pixel = image(image.Height() - y - 1, x, 0);
|
||||
row_pointers[y][x * 4 + 0] = pixel * 255;
|
||||
row_pointers[y][x * 4 + 1] = pixel * 255;
|
||||
row_pointers[y][x * 4 + 2] = pixel * 255;
|
||||
row_pointers[y][x * 4 + 3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int image_counter = 0;
|
||||
char file_name[128];
|
||||
snprintf(
|
||||
file_name, sizeof(file_name), "%s_%02d.png", prefix, ++image_counter);
|
||||
bool result = savePNGImage(row_pointers,
|
||||
image.Width(),
|
||||
image.Height(),
|
||||
8,
|
||||
PNG_COLOR_TYPE_RGBA,
|
||||
file_name);
|
||||
|
||||
for (y = 0; y < image.Height(); y++) {
|
||||
delete[] row_pointers[y];
|
||||
}
|
||||
delete[] row_pointers;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void libmv_samplePlanarPatchFloat(const float* image,
|
||||
int width,
|
||||
int height,
|
||||
int channels,
|
||||
const double* xs,
|
||||
const double* ys,
|
||||
int num_samples_x,
|
||||
int num_samples_y,
|
||||
const float* mask,
|
||||
float* patch,
|
||||
double* warped_position_x,
|
||||
double* warped_position_y) {
|
||||
FloatImage libmv_image, libmv_patch, libmv_mask;
|
||||
FloatImage* libmv_mask_for_sample = NULL;
|
||||
|
||||
libmv_floatBufferToFloatImage(image, width, height, channels, &libmv_image);
|
||||
|
||||
if (mask) {
|
||||
libmv_floatBufferToFloatImage(mask, width, height, 1, &libmv_mask);
|
||||
libmv_mask_for_sample = &libmv_mask;
|
||||
}
|
||||
|
||||
SamplePlanarPatch(libmv_image,
|
||||
xs,
|
||||
ys,
|
||||
num_samples_x,
|
||||
num_samples_y,
|
||||
libmv_mask_for_sample,
|
||||
&libmv_patch,
|
||||
warped_position_x,
|
||||
warped_position_y);
|
||||
|
||||
libmv_floatImageToFloatBuffer(libmv_patch, patch);
|
||||
}
|
||||
|
||||
void libmv_samplePlanarPatchByte(const unsigned char* image,
|
||||
int width,
|
||||
int height,
|
||||
int channels,
|
||||
const double* xs,
|
||||
const double* ys,
|
||||
int num_samples_x,
|
||||
int num_samples_y,
|
||||
const float* mask,
|
||||
unsigned char* patch,
|
||||
double* warped_position_x,
|
||||
double* warped_position_y) {
|
||||
libmv::FloatImage libmv_image, libmv_patch, libmv_mask;
|
||||
libmv::FloatImage* libmv_mask_for_sample = NULL;
|
||||
|
||||
libmv_byteBufferToFloatImage(image, width, height, channels, &libmv_image);
|
||||
|
||||
if (mask) {
|
||||
libmv_floatBufferToFloatImage(mask, width, height, 1, &libmv_mask);
|
||||
libmv_mask_for_sample = &libmv_mask;
|
||||
}
|
||||
|
||||
libmv::SamplePlanarPatch(libmv_image,
|
||||
xs,
|
||||
ys,
|
||||
num_samples_x,
|
||||
num_samples_y,
|
||||
libmv_mask_for_sample,
|
||||
&libmv_patch,
|
||||
warped_position_x,
|
||||
warped_position_y);
|
||||
|
||||
libmv_floatImageToByteBuffer(libmv_patch, patch);
|
||||
}
|
||||
77
blender-5.2.0/intern/libmv/intern/image.h
Normal file
77
blender-5.2.0/intern/libmv/intern/image.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifndef LIBMV_IMAGE_H_
|
||||
#define LIBMV_IMAGE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
# include "libmv/image/image.h"
|
||||
void libmv_byteBufferToFloatImage(const unsigned char* buffer,
|
||||
int width,
|
||||
int height,
|
||||
int channels,
|
||||
libmv::FloatImage* image);
|
||||
|
||||
void libmv_floatBufferToFloatImage(const float* buffer,
|
||||
int width,
|
||||
int height,
|
||||
int channels,
|
||||
libmv::FloatImage* image);
|
||||
|
||||
void libmv_floatImageToFloatBuffer(const libmv::FloatImage& image,
|
||||
float* buffer);
|
||||
|
||||
void libmv_floatImageToByteBuffer(const libmv::FloatImage& image,
|
||||
unsigned char* buffer);
|
||||
|
||||
bool libmv_saveImage(const libmv::FloatImage& image,
|
||||
const char* prefix,
|
||||
int x0,
|
||||
int y0);
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct libmv_FloatImage {
|
||||
float* buffer;
|
||||
int width;
|
||||
int height;
|
||||
int channels;
|
||||
} libmv_FloatImage;
|
||||
|
||||
void libmv_floatImageDestroy(libmv_FloatImage* image);
|
||||
|
||||
void libmv_samplePlanarPatchFloat(const float* image,
|
||||
int width,
|
||||
int height,
|
||||
int channels,
|
||||
const double* xs,
|
||||
const double* ys,
|
||||
int num_samples_x,
|
||||
int num_samples_y,
|
||||
const float* mask,
|
||||
float* patch,
|
||||
double* warped_position_x,
|
||||
double* warped_position_y);
|
||||
|
||||
void libmv_samplePlanarPatchByte(const unsigned char* image,
|
||||
int width,
|
||||
int height,
|
||||
int channels,
|
||||
const double* xs,
|
||||
const double* ys,
|
||||
int num_samples_x,
|
||||
int num_samples_y,
|
||||
const float* mask,
|
||||
unsigned char* patch,
|
||||
double* warped_position_x,
|
||||
double* warped_position_y);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // LIBMV_IMAGE_H_
|
||||
47
blender-5.2.0/intern/libmv/intern/logging.cc
Normal file
47
blender-5.2.0/intern/libmv/intern/logging.cc
Normal file
@@ -0,0 +1,47 @@
|
||||
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
#include "intern/logging.h"
|
||||
#include "intern/utildefines.h"
|
||||
#include "libmv/logging/logging.h"
|
||||
|
||||
static bool is_verbosity_set() {
|
||||
using LIBMV_GFLAGS_NAMESPACE::GetCommandLineOption;
|
||||
|
||||
std::string verbosity;
|
||||
if (!GetCommandLineOption("v", &verbosity)) {
|
||||
return false;
|
||||
}
|
||||
return verbosity != "0";
|
||||
}
|
||||
|
||||
void libmv_initLogging(const char* argv0) {
|
||||
using LIBMV_GFLAGS_NAMESPACE::SetCommandLineOption;
|
||||
google::InitGoogleLogging(argv0);
|
||||
SetCommandLineOption("logtostderr", "1");
|
||||
if (!is_verbosity_set()) {
|
||||
SetCommandLineOption("v", "0");
|
||||
}
|
||||
SetCommandLineOption("stderrthreshold", "0");
|
||||
SetCommandLineOption("minloglevel", "0");
|
||||
}
|
||||
|
||||
void libmv_startDebugLogging(void) {
|
||||
using LIBMV_GFLAGS_NAMESPACE::SetCommandLineOption;
|
||||
SetCommandLineOption("logtostderr", "1");
|
||||
if (!is_verbosity_set()) {
|
||||
SetCommandLineOption("v", "2");
|
||||
}
|
||||
SetCommandLineOption("stderrthreshold", "0");
|
||||
SetCommandLineOption("minloglevel", "0");
|
||||
}
|
||||
|
||||
void libmv_setLoggingVerbosity(int verbosity) {
|
||||
using LIBMV_GFLAGS_NAMESPACE::SetCommandLineOption;
|
||||
char val[10];
|
||||
snprintf(val, sizeof(val), "%d", verbosity);
|
||||
SetCommandLineOption("v", val);
|
||||
}
|
||||
25
blender-5.2.0/intern/libmv/intern/logging.h
Normal file
25
blender-5.2.0/intern/libmv/intern/logging.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifndef LIBMV_C_API_LOGGING_H_
|
||||
#define LIBMV_C_API_LOGGING_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Initialize GLog logging.
|
||||
void libmv_initLogging(const char* argv0);
|
||||
|
||||
// Switch Glog to debug logging level.
|
||||
void libmv_startDebugLogging(void);
|
||||
|
||||
// Set GLog logging verbosity level.
|
||||
void libmv_setLoggingVerbosity(int verbosity);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // LIBMV_C_API_LOGGING_H_
|
||||
519
blender-5.2.0/intern/libmv/intern/reconstruction.cc
Normal file
519
blender-5.2.0/intern/libmv/intern/reconstruction.cc
Normal file
@@ -0,0 +1,519 @@
|
||||
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "intern/reconstruction.h"
|
||||
#include "intern/camera_intrinsics.h"
|
||||
#include "intern/tracks.h"
|
||||
#include "intern/utildefines.h"
|
||||
|
||||
#include "libmv/logging/logging.h"
|
||||
#include "libmv/simple_pipeline/bundle.h"
|
||||
#include "libmv/simple_pipeline/initialize_reconstruction.h"
|
||||
#include "libmv/simple_pipeline/keyframe_selection.h"
|
||||
#include "libmv/simple_pipeline/modal_solver.h"
|
||||
#include "libmv/simple_pipeline/pipeline.h"
|
||||
#include "libmv/simple_pipeline/reconstruction_scale.h"
|
||||
#include "libmv/simple_pipeline/tracks.h"
|
||||
|
||||
using libmv::CameraIntrinsics;
|
||||
using libmv::EuclideanCamera;
|
||||
using libmv::EuclideanPoint;
|
||||
using libmv::EuclideanReconstruction;
|
||||
using libmv::EuclideanScaleToUnity;
|
||||
using libmv::Marker;
|
||||
using libmv::ProgressUpdateCallback;
|
||||
|
||||
using libmv::EuclideanBundle;
|
||||
using libmv::EuclideanCompleteReconstruction;
|
||||
using libmv::EuclideanReconstructTwoFrames;
|
||||
using libmv::EuclideanReprojectionError;
|
||||
using libmv::PolynomialCameraIntrinsics;
|
||||
using libmv::Tracks;
|
||||
|
||||
struct libmv_Reconstruction {
|
||||
EuclideanReconstruction reconstruction;
|
||||
|
||||
/* Used for per-track average error calculation after reconstruction */
|
||||
Tracks tracks;
|
||||
CameraIntrinsics* intrinsics;
|
||||
|
||||
double error;
|
||||
bool is_valid;
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
class ReconstructUpdateCallback : public ProgressUpdateCallback {
|
||||
public:
|
||||
ReconstructUpdateCallback(
|
||||
reconstruct_progress_update_cb progress_update_callback,
|
||||
void* callback_customdata) {
|
||||
progress_update_callback_ = progress_update_callback;
|
||||
callback_customdata_ = callback_customdata;
|
||||
}
|
||||
|
||||
void invoke(double progress, const char* message) {
|
||||
if (progress_update_callback_) {
|
||||
progress_update_callback_(callback_customdata_, progress, message);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
reconstruct_progress_update_cb progress_update_callback_;
|
||||
void* callback_customdata_;
|
||||
};
|
||||
|
||||
void libmv_solveRefineIntrinsics(
|
||||
const Tracks& tracks,
|
||||
const int refine_intrinsics,
|
||||
const int bundle_constraints,
|
||||
reconstruct_progress_update_cb progress_update_callback,
|
||||
void* callback_customdata,
|
||||
EuclideanReconstruction* reconstruction,
|
||||
CameraIntrinsics* intrinsics) {
|
||||
/* only a few combinations are supported but trust the caller/ */
|
||||
int bundle_intrinsics = 0;
|
||||
|
||||
if (refine_intrinsics & LIBMV_REFINE_FOCAL_LENGTH) {
|
||||
bundle_intrinsics |= libmv::BUNDLE_FOCAL_LENGTH;
|
||||
}
|
||||
if (refine_intrinsics & LIBMV_REFINE_PRINCIPAL_POINT) {
|
||||
bundle_intrinsics |= libmv::BUNDLE_PRINCIPAL_POINT;
|
||||
}
|
||||
|
||||
#define SET_DISTORTION_FLAG_CHECKED(type, coefficient) \
|
||||
do { \
|
||||
if (refine_intrinsics & LIBMV_REFINE_##type##_DISTORTION_##coefficient) { \
|
||||
bundle_intrinsics |= libmv::BUNDLE_##type##_##coefficient; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
SET_DISTORTION_FLAG_CHECKED(RADIAL, K1);
|
||||
SET_DISTORTION_FLAG_CHECKED(RADIAL, K2);
|
||||
SET_DISTORTION_FLAG_CHECKED(RADIAL, K3);
|
||||
SET_DISTORTION_FLAG_CHECKED(RADIAL, K4);
|
||||
|
||||
SET_DISTORTION_FLAG_CHECKED(TANGENTIAL, P1);
|
||||
SET_DISTORTION_FLAG_CHECKED(TANGENTIAL, P2);
|
||||
|
||||
#undef SET_DISTORTION_FLAG_CHECKED
|
||||
|
||||
progress_update_callback(callback_customdata, 1.0, "Refining solution");
|
||||
|
||||
EuclideanBundleCommonIntrinsics(tracks,
|
||||
bundle_intrinsics,
|
||||
bundle_constraints,
|
||||
reconstruction,
|
||||
intrinsics);
|
||||
}
|
||||
|
||||
void finishReconstruction(
|
||||
const Tracks& tracks,
|
||||
const CameraIntrinsics& camera_intrinsics,
|
||||
libmv_Reconstruction* libmv_reconstruction,
|
||||
reconstruct_progress_update_cb progress_update_callback,
|
||||
void* callback_customdata) {
|
||||
EuclideanReconstruction& reconstruction =
|
||||
libmv_reconstruction->reconstruction;
|
||||
|
||||
/* Reprojection error calculation. */
|
||||
progress_update_callback(callback_customdata, 1.0, "Finishing solution");
|
||||
libmv_reconstruction->tracks = tracks;
|
||||
libmv_reconstruction->error =
|
||||
EuclideanReprojectionError(tracks, reconstruction, camera_intrinsics);
|
||||
}
|
||||
|
||||
bool selectTwoKeyframesBasedOnGRICAndVariance(
|
||||
Tracks& tracks,
|
||||
Tracks& normalized_tracks,
|
||||
CameraIntrinsics& camera_intrinsics,
|
||||
int& keyframe1,
|
||||
int& keyframe2) {
|
||||
libmv::vector<int> keyframes;
|
||||
|
||||
/* Get list of all keyframe candidates first. */
|
||||
SelectKeyframesBasedOnGRICAndVariance(
|
||||
normalized_tracks, camera_intrinsics, keyframes);
|
||||
|
||||
if (keyframes.size() < 2) {
|
||||
LG << "Not enough keyframes detected by GRIC";
|
||||
return false;
|
||||
} else if (keyframes.size() == 2) {
|
||||
keyframe1 = keyframes[0];
|
||||
keyframe2 = keyframes[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Now choose two keyframes with minimal reprojection error after initial
|
||||
* reconstruction choose keyframes with the least reprojection error after
|
||||
* solving from two candidate keyframes.
|
||||
*
|
||||
* In fact, currently libmv returns single pair only, so this code will
|
||||
* not actually run. But in the future this could change, so let's stay
|
||||
* prepared.
|
||||
*/
|
||||
int previous_keyframe = keyframes[0];
|
||||
double best_error = std::numeric_limits<double>::max();
|
||||
for (int i = 1; i < keyframes.size(); i++) {
|
||||
EuclideanReconstruction reconstruction;
|
||||
int current_keyframe = keyframes[i];
|
||||
libmv::vector<Marker> keyframe_markers =
|
||||
normalized_tracks.MarkersForTracksInBothImages(previous_keyframe,
|
||||
current_keyframe);
|
||||
|
||||
Tracks keyframe_tracks(keyframe_markers);
|
||||
|
||||
/* get a solution from two keyframes only */
|
||||
EuclideanReconstructTwoFrames(keyframe_markers, &reconstruction);
|
||||
EuclideanBundle(keyframe_tracks, &reconstruction);
|
||||
EuclideanCompleteReconstruction(keyframe_tracks, &reconstruction, NULL);
|
||||
|
||||
double current_error =
|
||||
EuclideanReprojectionError(tracks, reconstruction, camera_intrinsics);
|
||||
|
||||
LG << "Error between " << previous_keyframe << " and " << current_keyframe
|
||||
<< ": " << current_error;
|
||||
|
||||
if (current_error < best_error) {
|
||||
best_error = current_error;
|
||||
keyframe1 = previous_keyframe;
|
||||
keyframe2 = current_keyframe;
|
||||
}
|
||||
|
||||
previous_keyframe = current_keyframe;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Marker libmv_projectMarker(const EuclideanPoint& point,
|
||||
const EuclideanCamera& camera,
|
||||
const CameraIntrinsics& intrinsics) {
|
||||
libmv::Vec3 projected = camera.R * point.X + camera.t;
|
||||
projected /= projected(2);
|
||||
|
||||
libmv::Marker reprojected_marker;
|
||||
intrinsics.ApplyIntrinsics(
|
||||
projected(0), projected(1), &reprojected_marker.x, &reprojected_marker.y);
|
||||
|
||||
reprojected_marker.image = camera.image;
|
||||
reprojected_marker.track = point.track;
|
||||
return reprojected_marker;
|
||||
}
|
||||
|
||||
void libmv_getNormalizedTracks(const Tracks& tracks,
|
||||
const CameraIntrinsics& camera_intrinsics,
|
||||
Tracks* normalized_tracks) {
|
||||
libmv::vector<Marker> markers = tracks.AllMarkers();
|
||||
for (int i = 0; i < markers.size(); ++i) {
|
||||
Marker& marker = markers[i];
|
||||
camera_intrinsics.InvertIntrinsics(
|
||||
marker.x, marker.y, &marker.x, &marker.y);
|
||||
normalized_tracks->Insert(
|
||||
marker.image, marker.track, marker.x, marker.y, marker.weight);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
libmv_Reconstruction* libmv_solveReconstruction(
|
||||
const libmv_Tracks* libmv_tracks,
|
||||
const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
|
||||
libmv_ReconstructionOptions* libmv_reconstruction_options,
|
||||
reconstruct_progress_update_cb progress_update_callback,
|
||||
void* callback_customdata) {
|
||||
libmv_Reconstruction* libmv_reconstruction =
|
||||
LIBMV_OBJECT_NEW(libmv_Reconstruction);
|
||||
|
||||
Tracks& tracks = *((Tracks*)libmv_tracks);
|
||||
EuclideanReconstruction& reconstruction =
|
||||
libmv_reconstruction->reconstruction;
|
||||
|
||||
ReconstructUpdateCallback update_callback =
|
||||
ReconstructUpdateCallback(progress_update_callback, callback_customdata);
|
||||
|
||||
/* Retrieve reconstruction options from C-API to libmv API. */
|
||||
CameraIntrinsics* camera_intrinsics;
|
||||
camera_intrinsics = libmv_reconstruction->intrinsics =
|
||||
libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
|
||||
|
||||
/* Invert the camera intrinsics/ */
|
||||
Tracks normalized_tracks;
|
||||
libmv_getNormalizedTracks(tracks, *camera_intrinsics, &normalized_tracks);
|
||||
|
||||
/* keyframe selection. */
|
||||
int keyframe1 = libmv_reconstruction_options->keyframe1,
|
||||
keyframe2 = libmv_reconstruction_options->keyframe2;
|
||||
|
||||
if (libmv_reconstruction_options->select_keyframes) {
|
||||
LG << "Using automatic keyframe selection";
|
||||
|
||||
update_callback.invoke(0, "Selecting keyframes");
|
||||
|
||||
if (selectTwoKeyframesBasedOnGRICAndVariance(tracks,
|
||||
normalized_tracks,
|
||||
*camera_intrinsics,
|
||||
keyframe1,
|
||||
keyframe2)) {
|
||||
/* so keyframes in the interface would be updated */
|
||||
libmv_reconstruction_options->keyframe1 = keyframe1;
|
||||
libmv_reconstruction_options->keyframe2 = keyframe2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Actual reconstruction. */
|
||||
LG << "frames to init from: " << keyframe1 << " " << keyframe2;
|
||||
|
||||
libmv::vector<Marker> keyframe_markers =
|
||||
normalized_tracks.MarkersForTracksInBothImages(keyframe1, keyframe2);
|
||||
|
||||
LG << "number of markers for init: " << keyframe_markers.size();
|
||||
|
||||
if (keyframe_markers.size() < 16) {
|
||||
LG << "No enough markers to initialize from";
|
||||
libmv_reconstruction->is_valid = false;
|
||||
return libmv_reconstruction;
|
||||
}
|
||||
|
||||
update_callback.invoke(0, "Initial reconstruction");
|
||||
|
||||
if (!EuclideanReconstructTwoFrames(keyframe_markers, &reconstruction)) {
|
||||
LG << "Failed to initialize reconstruction";
|
||||
libmv_reconstruction->is_valid = false;
|
||||
return libmv_reconstruction;
|
||||
}
|
||||
|
||||
EuclideanBundle(normalized_tracks, &reconstruction);
|
||||
EuclideanCompleteReconstruction(
|
||||
normalized_tracks, &reconstruction, &update_callback);
|
||||
|
||||
/* Refinement. */
|
||||
if (libmv_reconstruction_options->refine_intrinsics) {
|
||||
libmv_solveRefineIntrinsics(tracks,
|
||||
libmv_reconstruction_options->refine_intrinsics,
|
||||
libmv::BUNDLE_NO_CONSTRAINTS,
|
||||
progress_update_callback,
|
||||
callback_customdata,
|
||||
&reconstruction,
|
||||
camera_intrinsics);
|
||||
}
|
||||
|
||||
/* Set reconstruction scale to unity. */
|
||||
EuclideanScaleToUnity(&reconstruction);
|
||||
|
||||
/* Finish reconstruction. */
|
||||
finishReconstruction(tracks,
|
||||
*camera_intrinsics,
|
||||
libmv_reconstruction,
|
||||
progress_update_callback,
|
||||
callback_customdata);
|
||||
|
||||
libmv_reconstruction->is_valid = true;
|
||||
return (libmv_Reconstruction*)libmv_reconstruction;
|
||||
}
|
||||
|
||||
libmv_Reconstruction* libmv_solveModal(
|
||||
const libmv_Tracks* libmv_tracks,
|
||||
const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
|
||||
const libmv_ReconstructionOptions* libmv_reconstruction_options,
|
||||
reconstruct_progress_update_cb progress_update_callback,
|
||||
void* callback_customdata) {
|
||||
libmv_Reconstruction* libmv_reconstruction =
|
||||
LIBMV_OBJECT_NEW(libmv_Reconstruction);
|
||||
|
||||
Tracks& tracks = *((Tracks*)libmv_tracks);
|
||||
EuclideanReconstruction& reconstruction =
|
||||
libmv_reconstruction->reconstruction;
|
||||
|
||||
ReconstructUpdateCallback update_callback =
|
||||
ReconstructUpdateCallback(progress_update_callback, callback_customdata);
|
||||
|
||||
/* Retrieve reconstruction options from C-API to libmv API. */
|
||||
CameraIntrinsics* camera_intrinsics;
|
||||
camera_intrinsics = libmv_reconstruction->intrinsics =
|
||||
libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
|
||||
|
||||
/* Invert the camera intrinsics. */
|
||||
Tracks normalized_tracks;
|
||||
libmv_getNormalizedTracks(tracks, *camera_intrinsics, &normalized_tracks);
|
||||
|
||||
/* Actual reconstruction. */
|
||||
ModalSolver(normalized_tracks, &reconstruction, &update_callback);
|
||||
|
||||
PolynomialCameraIntrinsics empty_intrinsics;
|
||||
EuclideanBundleCommonIntrinsics(normalized_tracks,
|
||||
libmv::BUNDLE_NO_INTRINSICS,
|
||||
libmv::BUNDLE_NO_TRANSLATION,
|
||||
&reconstruction,
|
||||
&empty_intrinsics);
|
||||
|
||||
/* Refinement. */
|
||||
if (libmv_reconstruction_options->refine_intrinsics) {
|
||||
libmv_solveRefineIntrinsics(tracks,
|
||||
libmv_reconstruction_options->refine_intrinsics,
|
||||
libmv::BUNDLE_NO_TRANSLATION,
|
||||
progress_update_callback,
|
||||
callback_customdata,
|
||||
&reconstruction,
|
||||
camera_intrinsics);
|
||||
}
|
||||
|
||||
/* Finish reconstruction. */
|
||||
finishReconstruction(tracks,
|
||||
*camera_intrinsics,
|
||||
libmv_reconstruction,
|
||||
progress_update_callback,
|
||||
callback_customdata);
|
||||
|
||||
libmv_reconstruction->is_valid = true;
|
||||
return (libmv_Reconstruction*)libmv_reconstruction;
|
||||
}
|
||||
|
||||
int libmv_reconstructionIsValid(libmv_Reconstruction* libmv_reconstruction) {
|
||||
return libmv_reconstruction->is_valid;
|
||||
}
|
||||
|
||||
void libmv_reconstructionDestroy(libmv_Reconstruction* libmv_reconstruction) {
|
||||
LIBMV_OBJECT_DELETE(libmv_reconstruction->intrinsics, CameraIntrinsics);
|
||||
LIBMV_OBJECT_DELETE(libmv_reconstruction, libmv_Reconstruction);
|
||||
}
|
||||
|
||||
int libmv_reprojectionPointForTrack(
|
||||
const libmv_Reconstruction* libmv_reconstruction,
|
||||
int track,
|
||||
double pos[3]) {
|
||||
const EuclideanReconstruction* reconstruction =
|
||||
&libmv_reconstruction->reconstruction;
|
||||
const EuclideanPoint* point = reconstruction->PointForTrack(track);
|
||||
if (point) {
|
||||
pos[0] = point->X[0];
|
||||
pos[1] = point->X[2];
|
||||
pos[2] = point->X[1];
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
double libmv_reprojectionErrorForTrack(
|
||||
const libmv_Reconstruction* libmv_reconstruction, int track) {
|
||||
const EuclideanReconstruction* reconstruction =
|
||||
&libmv_reconstruction->reconstruction;
|
||||
const CameraIntrinsics* intrinsics = libmv_reconstruction->intrinsics;
|
||||
libmv::vector<Marker> markers =
|
||||
libmv_reconstruction->tracks.MarkersForTrack(track);
|
||||
|
||||
int num_reprojected = 0;
|
||||
double total_error = 0.0;
|
||||
|
||||
for (int i = 0; i < markers.size(); ++i) {
|
||||
double weight = markers[i].weight;
|
||||
const EuclideanCamera* camera =
|
||||
reconstruction->CameraForImage(markers[i].image);
|
||||
const EuclideanPoint* point =
|
||||
reconstruction->PointForTrack(markers[i].track);
|
||||
|
||||
if (!camera || !point || weight == 0.0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
num_reprojected++;
|
||||
|
||||
Marker reprojected_marker =
|
||||
libmv_projectMarker(*point, *camera, *intrinsics);
|
||||
double ex = (reprojected_marker.x - markers[i].x) * weight;
|
||||
double ey = (reprojected_marker.y - markers[i].y) * weight;
|
||||
|
||||
total_error += sqrt(ex * ex + ey * ey);
|
||||
}
|
||||
|
||||
return total_error / num_reprojected;
|
||||
}
|
||||
|
||||
double libmv_reprojectionErrorForImage(
|
||||
const libmv_Reconstruction* libmv_reconstruction, int image) {
|
||||
const EuclideanReconstruction* reconstruction =
|
||||
&libmv_reconstruction->reconstruction;
|
||||
const CameraIntrinsics* intrinsics = libmv_reconstruction->intrinsics;
|
||||
libmv::vector<Marker> markers =
|
||||
libmv_reconstruction->tracks.MarkersInImage(image);
|
||||
const EuclideanCamera* camera = reconstruction->CameraForImage(image);
|
||||
int num_reprojected = 0;
|
||||
double total_error = 0.0;
|
||||
|
||||
if (!camera) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < markers.size(); ++i) {
|
||||
const EuclideanPoint* point =
|
||||
reconstruction->PointForTrack(markers[i].track);
|
||||
|
||||
if (!point) {
|
||||
continue;
|
||||
}
|
||||
|
||||
num_reprojected++;
|
||||
|
||||
Marker reprojected_marker =
|
||||
libmv_projectMarker(*point, *camera, *intrinsics);
|
||||
double ex = (reprojected_marker.x - markers[i].x) * markers[i].weight;
|
||||
double ey = (reprojected_marker.y - markers[i].y) * markers[i].weight;
|
||||
|
||||
total_error += sqrt(ex * ex + ey * ey);
|
||||
}
|
||||
|
||||
return total_error / num_reprojected;
|
||||
}
|
||||
|
||||
int libmv_reprojectionCameraForImage(
|
||||
const libmv_Reconstruction* libmv_reconstruction,
|
||||
int image,
|
||||
double mat[4][4]) {
|
||||
const EuclideanReconstruction* reconstruction =
|
||||
&libmv_reconstruction->reconstruction;
|
||||
const EuclideanCamera* camera = reconstruction->CameraForImage(image);
|
||||
|
||||
if (camera) {
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
for (int k = 0; k < 3; ++k) {
|
||||
int l = k;
|
||||
|
||||
if (k == 1) {
|
||||
l = 2;
|
||||
} else if (k == 2) {
|
||||
l = 1;
|
||||
}
|
||||
|
||||
if (j == 2) {
|
||||
mat[j][l] = -camera->R(j, k);
|
||||
} else {
|
||||
mat[j][l] = camera->R(j, k);
|
||||
}
|
||||
}
|
||||
mat[j][3] = 0.0;
|
||||
}
|
||||
|
||||
libmv::Vec3 optical_center = -camera->R.transpose() * camera->t;
|
||||
|
||||
mat[3][0] = optical_center(0);
|
||||
mat[3][1] = optical_center(2);
|
||||
mat[3][2] = optical_center(1);
|
||||
|
||||
mat[3][3] = 1.0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
double libmv_reprojectionError(
|
||||
const libmv_Reconstruction* libmv_reconstruction) {
|
||||
return libmv_reconstruction->error;
|
||||
}
|
||||
|
||||
libmv_CameraIntrinsics* libmv_reconstructionExtractIntrinsics(
|
||||
libmv_Reconstruction* libmv_reconstruction) {
|
||||
return (libmv_CameraIntrinsics*)libmv_reconstruction->intrinsics;
|
||||
}
|
||||
88
blender-5.2.0/intern/libmv/intern/reconstruction.h
Normal file
88
blender-5.2.0/intern/libmv/intern/reconstruction.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifndef LIBMV_C_API_RECONSTRUCTION_H_
|
||||
#define LIBMV_C_API_RECONSTRUCTION_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct libmv_Tracks;
|
||||
struct libmv_CameraIntrinsics;
|
||||
struct libmv_CameraIntrinsicsOptions;
|
||||
|
||||
typedef struct libmv_Reconstruction libmv_Reconstruction;
|
||||
|
||||
enum {
|
||||
LIBMV_REFINE_FOCAL_LENGTH = (1 << 0),
|
||||
LIBMV_REFINE_PRINCIPAL_POINT = (1 << 1),
|
||||
|
||||
LIBMV_REFINE_RADIAL_DISTORTION_K1 = (1 << 2),
|
||||
LIBMV_REFINE_RADIAL_DISTORTION_K2 = (1 << 3),
|
||||
LIBMV_REFINE_RADIAL_DISTORTION_K3 = (1 << 4),
|
||||
LIBMV_REFINE_RADIAL_DISTORTION_K4 = (1 << 5),
|
||||
LIBMV_REFINE_RADIAL_DISTORTION =
|
||||
(LIBMV_REFINE_RADIAL_DISTORTION_K1 | LIBMV_REFINE_RADIAL_DISTORTION_K2 |
|
||||
LIBMV_REFINE_RADIAL_DISTORTION_K3 | LIBMV_REFINE_RADIAL_DISTORTION_K4),
|
||||
|
||||
LIBMV_REFINE_TANGENTIAL_DISTORTION_P1 = (1 << 6),
|
||||
LIBMV_REFINE_TANGENTIAL_DISTORTION_P2 = (1 << 7),
|
||||
LIBMV_REFINE_TANGENTIAL_DISTORTION = (LIBMV_REFINE_TANGENTIAL_DISTORTION_P1 |
|
||||
LIBMV_REFINE_TANGENTIAL_DISTORTION_P2),
|
||||
};
|
||||
|
||||
typedef struct libmv_ReconstructionOptions {
|
||||
int select_keyframes;
|
||||
int keyframe1, keyframe2;
|
||||
int refine_intrinsics;
|
||||
} libmv_ReconstructionOptions;
|
||||
|
||||
typedef void (*reconstruct_progress_update_cb)(void* customdata,
|
||||
double progress,
|
||||
const char* message);
|
||||
|
||||
libmv_Reconstruction* libmv_solveReconstruction(
|
||||
const struct libmv_Tracks* libmv_tracks,
|
||||
const struct libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
|
||||
libmv_ReconstructionOptions* libmv_reconstruction_options,
|
||||
reconstruct_progress_update_cb progress_update_callback,
|
||||
void* callback_customdata);
|
||||
|
||||
libmv_Reconstruction* libmv_solveModal(
|
||||
const struct libmv_Tracks* libmv_tracks,
|
||||
const struct libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
|
||||
const libmv_ReconstructionOptions* libmv_reconstruction_options,
|
||||
reconstruct_progress_update_cb progress_update_callback,
|
||||
void* callback_customdata);
|
||||
|
||||
int libmv_reconstructionIsValid(libmv_Reconstruction* libmv_reconstruction);
|
||||
|
||||
void libmv_reconstructionDestroy(libmv_Reconstruction* libmv_reconstruction);
|
||||
|
||||
int libmv_reprojectionPointForTrack(
|
||||
const libmv_Reconstruction* libmv_reconstruction, int track, double pos[3]);
|
||||
|
||||
double libmv_reprojectionErrorForTrack(
|
||||
const libmv_Reconstruction* libmv_reconstruction, int track);
|
||||
|
||||
double libmv_reprojectionErrorForImage(
|
||||
const libmv_Reconstruction* libmv_reconstruction, int image);
|
||||
|
||||
int libmv_reprojectionCameraForImage(
|
||||
const libmv_Reconstruction* libmv_reconstruction,
|
||||
int image,
|
||||
double mat[4][4]);
|
||||
|
||||
double libmv_reprojectionError(
|
||||
const libmv_Reconstruction* libmv_reconstruction);
|
||||
|
||||
struct libmv_CameraIntrinsics* libmv_reconstructionExtractIntrinsics(
|
||||
libmv_Reconstruction* libmv_Reconstruction);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // LIBMV_C_API_RECONSTRUCTION_H_
|
||||
21
blender-5.2.0/intern/libmv/intern/region.h
Normal file
21
blender-5.2.0/intern/libmv/intern/region.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/* SPDX-FileCopyrightText: 2014 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifndef LIBMV_C_API_REGION_H_
|
||||
#define LIBMV_C_API_REGION_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct libmv_Region {
|
||||
float min[2];
|
||||
float max[2];
|
||||
} libmv_Region;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // LIBMV_C_API_REGION_H_
|
||||
372
blender-5.2.0/intern/libmv/intern/stub.cc
Normal file
372
blender-5.2.0/intern/libmv/intern/stub.cc
Normal file
@@ -0,0 +1,372 @@
|
||||
/* SPDX-FileCopyrightText: 2013 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "libmv-capi.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
/* ************ Logging ************ */
|
||||
|
||||
void libmv_initLogging(const char* /*argv0*/) {
|
||||
}
|
||||
|
||||
void libmv_startDebugLogging(void) {
|
||||
}
|
||||
|
||||
void libmv_setLoggingVerbosity(int /*verbosity*/) {
|
||||
}
|
||||
|
||||
/* ************ Planar tracker ************ */
|
||||
|
||||
/* TrackRegion (new planar tracker) */
|
||||
int libmv_trackRegion(const libmv_TrackRegionOptions* /*options*/,
|
||||
const float* /*image1*/,
|
||||
int /*image1_width*/,
|
||||
int /*image1_height*/,
|
||||
const float* /*image2*/,
|
||||
int /*image2_width*/,
|
||||
int /*image2_height*/,
|
||||
const double* x1,
|
||||
const double* y1,
|
||||
libmv_TrackRegionResult* result,
|
||||
double* x2,
|
||||
double* y2) {
|
||||
/* Convert to doubles for the libmv API. The four corners and the center. */
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
x2[i] = x1[i];
|
||||
y2[i] = y1[i];
|
||||
}
|
||||
|
||||
result->termination = -1;
|
||||
result->termination_reason = "Built without libmv support";
|
||||
result->correlation = 0.0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void libmv_samplePlanarPatchFloat(const float* /*image*/,
|
||||
int /*width*/,
|
||||
int /*height*/,
|
||||
int /*channels*/,
|
||||
const double* /*xs*/,
|
||||
const double* /*ys*/,
|
||||
int /*num_samples_x*/,
|
||||
int /*num_samples_y*/,
|
||||
const float* /*mask*/,
|
||||
float* /*patch*/,
|
||||
double* /*warped_position_x*/,
|
||||
double* /*warped_position_y*/) {
|
||||
/* TODO(sergey): implement */
|
||||
}
|
||||
|
||||
void libmv_samplePlanarPatchByte(const unsigned char* /*image*/,
|
||||
int /*width*/,
|
||||
int /*height*/,
|
||||
int /*channels*/,
|
||||
const double* /*xs*/,
|
||||
const double* /*ys*/,
|
||||
int /*num_samples_x*/,
|
||||
int /*num_samples_y*/,
|
||||
const float* /*mask*/,
|
||||
unsigned char* /*patch*/,
|
||||
double* /*warped_position_x*/,
|
||||
double* /*warped_position_y*/) {
|
||||
/* TODO(sergey): implement */
|
||||
}
|
||||
|
||||
void libmv_floatImageDestroy(libmv_FloatImage* /*image*/) {
|
||||
}
|
||||
|
||||
/* ************ Tracks ************ */
|
||||
|
||||
libmv_Tracks* libmv_tracksNew(void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void libmv_tracksInsert(libmv_Tracks* /*libmv_tracks*/,
|
||||
int /*image*/,
|
||||
int /*track*/,
|
||||
double /*x*/,
|
||||
double /*y*/,
|
||||
double /*weight*/) {
|
||||
}
|
||||
|
||||
void libmv_tracksDestroy(libmv_Tracks* /*libmv_tracks*/) {
|
||||
}
|
||||
|
||||
/* ************ Reconstruction solver ************ */
|
||||
|
||||
libmv_Reconstruction* libmv_solveReconstruction(
|
||||
const libmv_Tracks* /*libmv_tracks*/,
|
||||
const libmv_CameraIntrinsicsOptions* /*libmv_camera_intrinsics_options*/,
|
||||
libmv_ReconstructionOptions* /*libmv_reconstruction_options*/,
|
||||
reconstruct_progress_update_cb /*progress_update_callback*/,
|
||||
void* /*callback_customdata*/) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
libmv_Reconstruction* libmv_solveModal(
|
||||
const libmv_Tracks* /*libmv_tracks*/,
|
||||
const libmv_CameraIntrinsicsOptions* /*libmv_camera_intrinsics_options*/,
|
||||
const libmv_ReconstructionOptions* /*libmv_reconstruction_options*/,
|
||||
reconstruct_progress_update_cb /*progress_update_callback*/,
|
||||
void* /*callback_customdata*/) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int libmv_reconstructionIsValid(
|
||||
libmv_Reconstruction* /*libmv_reconstruction*/) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libmv_reprojectionPointForTrack(
|
||||
const libmv_Reconstruction* /*libmv_reconstruction*/,
|
||||
int /*track*/,
|
||||
double /*pos*/[3]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
double libmv_reprojectionErrorForTrack(
|
||||
const libmv_Reconstruction* /*libmv_reconstruction*/, int /*track*/) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double libmv_reprojectionErrorForImage(
|
||||
const libmv_Reconstruction* /*libmv_reconstruction*/, int /*image*/) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
int libmv_reprojectionCameraForImage(
|
||||
const libmv_Reconstruction* /*libmv_reconstruction*/,
|
||||
int /*image*/,
|
||||
double /*mat*/[4][4]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
double libmv_reprojectionError(
|
||||
const libmv_Reconstruction* /*libmv_reconstruction*/) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
void libmv_reconstructionDestroy(
|
||||
struct libmv_Reconstruction* /*libmv_reconstruction*/) {
|
||||
}
|
||||
|
||||
/* ************ Feature detector ************ */
|
||||
|
||||
libmv_Features* libmv_detectFeaturesByte(const unsigned char* /*image_buffer*/,
|
||||
int /*width*/,
|
||||
int /*height*/,
|
||||
int /*channels*/,
|
||||
libmv_DetectOptions* /*options*/) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct libmv_Features* libmv_detectFeaturesFloat(
|
||||
const float* /*image_buffer*/,
|
||||
int /*width*/,
|
||||
int /*height*/,
|
||||
int /*channels*/,
|
||||
libmv_DetectOptions* /*options*/) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int libmv_countFeatures(const libmv_Features* /*libmv_features*/) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void libmv_getFeature(const libmv_Features* /*libmv_features*/,
|
||||
int /*number*/,
|
||||
double* x,
|
||||
double* y,
|
||||
double* score,
|
||||
double* size) {
|
||||
*x = 0.0;
|
||||
*y = 0.0;
|
||||
*score = 0.0;
|
||||
*size = 0.0;
|
||||
}
|
||||
|
||||
void libmv_featuresDestroy(struct libmv_Features* /*libmv_features*/) {
|
||||
}
|
||||
|
||||
/* ************ Camera intrinsics ************ */
|
||||
|
||||
libmv_CameraIntrinsics* libmv_reconstructionExtractIntrinsics(
|
||||
libmv_Reconstruction* /*libmv_reconstruction*/) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
libmv_CameraIntrinsics* libmv_cameraIntrinsicsNew(
|
||||
const libmv_CameraIntrinsicsOptions* /*libmv_camera_intrinsics_options*/) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
libmv_CameraIntrinsics* libmv_cameraIntrinsicsCopy(
|
||||
const libmv_CameraIntrinsics* /*libmvIntrinsics*/) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void libmv_cameraIntrinsicsDestroy(
|
||||
libmv_CameraIntrinsics* /*libmvIntrinsics*/) {
|
||||
}
|
||||
|
||||
void libmv_cameraIntrinsicsUpdate(
|
||||
const libmv_CameraIntrinsicsOptions* /*libmv_camera_intrinsics_options*/,
|
||||
libmv_CameraIntrinsics* /*libmv_intrinsics*/) {
|
||||
}
|
||||
|
||||
void libmv_cameraIntrinsicsExtractOptions(
|
||||
const libmv_CameraIntrinsics* /*libmv_intrinsics*/,
|
||||
libmv_CameraIntrinsicsOptions* camera_intrinsics_options) {
|
||||
memset(camera_intrinsics_options, 0, sizeof(libmv_CameraIntrinsicsOptions));
|
||||
camera_intrinsics_options->focal_length = 1.0;
|
||||
}
|
||||
|
||||
void libmv_cameraIntrinsicsUndistortByte(
|
||||
const libmv_CameraIntrinsics* /*libmv_intrinsics*/,
|
||||
const unsigned char* source_image,
|
||||
int width,
|
||||
int height,
|
||||
float /*overscan*/,
|
||||
int channels,
|
||||
unsigned char* destination_image) {
|
||||
memcpy(destination_image,
|
||||
source_image,
|
||||
channels * width * height * sizeof(unsigned char));
|
||||
}
|
||||
|
||||
void libmv_cameraIntrinsicsUndistortFloat(
|
||||
const libmv_CameraIntrinsics* /*libmv_intrinsics*/,
|
||||
const float* source_image,
|
||||
int width,
|
||||
int height,
|
||||
float /*overscan*/,
|
||||
int channels,
|
||||
float* destination_image) {
|
||||
memcpy(destination_image,
|
||||
source_image,
|
||||
channels * width * height * sizeof(float));
|
||||
}
|
||||
|
||||
void libmv_cameraIntrinsicsDistortByte(
|
||||
const struct libmv_CameraIntrinsics* /*libmv_intrinsics*/,
|
||||
const unsigned char* source_image,
|
||||
int width,
|
||||
int height,
|
||||
float /*overscan*/,
|
||||
int channels,
|
||||
unsigned char* destination_image) {
|
||||
memcpy(destination_image,
|
||||
source_image,
|
||||
channels * width * height * sizeof(unsigned char));
|
||||
}
|
||||
|
||||
void libmv_cameraIntrinsicsDistortFloat(
|
||||
const libmv_CameraIntrinsics* /*libmv_intrinsics*/,
|
||||
float* source_image,
|
||||
int width,
|
||||
int height,
|
||||
float /*overscan*/,
|
||||
int channels,
|
||||
float* destination_image) {
|
||||
memcpy(destination_image,
|
||||
source_image,
|
||||
channels * width * height * sizeof(float));
|
||||
}
|
||||
|
||||
/* ************ utils ************ */
|
||||
|
||||
void libmv_cameraIntrinsicsApply(
|
||||
const struct libmv_CameraIntrinsics* /*libmv_intrinsics*/,
|
||||
double /*x*/,
|
||||
double /*y*/,
|
||||
double* x1,
|
||||
double* y1) {
|
||||
*x1 = 0.0;
|
||||
*y1 = 0.0;
|
||||
}
|
||||
|
||||
void libmv_cameraIntrinsicsInvert(
|
||||
const struct libmv_CameraIntrinsics* /*libmv_intrinsics*/,
|
||||
double /*x*/,
|
||||
double /*y*/,
|
||||
double* x1,
|
||||
double* y1) {
|
||||
*x1 = 0.0;
|
||||
*y1 = 0.0;
|
||||
}
|
||||
|
||||
void libmv_homography2DFromCorrespondencesEuc(/* const */ double (* /*x1*/)[2],
|
||||
/* const */ double (* /*x2*/)[2],
|
||||
int /*num_points*/,
|
||||
double H[3][3]) {
|
||||
memset(H, 0, sizeof(double[3][3]));
|
||||
H[0][0] = 1.0f;
|
||||
H[1][1] = 1.0f;
|
||||
H[2][2] = 1.0f;
|
||||
}
|
||||
|
||||
/* ************ autotrack ************ */
|
||||
|
||||
libmv_AutoTrack* libmv_autoTrackNew(libmv_FrameAccessor* /*frame_accessor*/) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void libmv_autoTrackDestroy(libmv_AutoTrack* /*libmv_autotrack*/) {
|
||||
}
|
||||
|
||||
void libmv_autoTrackSetOptions(libmv_AutoTrack* /*libmv_autotrack*/,
|
||||
const libmv_AutoTrackOptions* /*options*/) {
|
||||
}
|
||||
|
||||
int libmv_autoTrackMarker(libmv_AutoTrack* /*libmv_autotrack*/,
|
||||
const libmv_TrackRegionOptions* /*libmv_options*/,
|
||||
libmv_Marker* /*libmv_tracker_marker*/,
|
||||
libmv_TrackRegionResult* /*libmv_result*/) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void libmv_autoTrackAddMarker(libmv_AutoTrack* /*libmv_autotrack*/,
|
||||
const libmv_Marker* /*libmv_marker*/) {
|
||||
}
|
||||
|
||||
void libmv_autoTrackSetMarkers(libmv_AutoTrack* /*libmv_autotrack*/,
|
||||
const libmv_Marker* /*libmv_marker-*/,
|
||||
size_t /*num_markers*/) {
|
||||
}
|
||||
|
||||
int libmv_autoTrackGetMarker(libmv_AutoTrack* /*libmv_autotrack*/,
|
||||
int /*clip*/,
|
||||
int /*frame*/,
|
||||
int /*track*/,
|
||||
libmv_Marker* /*libmv_marker*/) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ************ frame accessor ************ */
|
||||
|
||||
libmv_FrameAccessor* libmv_FrameAccessorNew(
|
||||
libmv_FrameAccessorUserData* /*user_data**/,
|
||||
libmv_GetImageCallback /*get_image_callback*/,
|
||||
libmv_ReleaseImageCallback /*release_image_callback*/,
|
||||
libmv_GetMaskForTrackCallback /*get_mask_for_track_callback*/,
|
||||
libmv_ReleaseMaskCallback /*release_mask_callback*/) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void libmv_FrameAccessorDestroy(libmv_FrameAccessor* /*frame_accessor*/) {
|
||||
}
|
||||
|
||||
int64_t libmv_frameAccessorgetTransformKey(
|
||||
const libmv_FrameTransform* /*transform*/) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void libmv_frameAccessorgetTransformRun(
|
||||
const libmv_FrameTransform* /*transform*/,
|
||||
const libmv_FloatImage* /*input_image*/,
|
||||
libmv_FloatImage* /*output_image*/) {
|
||||
}
|
||||
177
blender-5.2.0/intern/libmv/intern/track_region.cc
Normal file
177
blender-5.2.0/intern/libmv/intern/track_region.cc
Normal file
@@ -0,0 +1,177 @@
|
||||
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "intern/track_region.h"
|
||||
#include "intern/image.h"
|
||||
#include "intern/utildefines.h"
|
||||
#include "libmv/image/image.h"
|
||||
#include "libmv/logging/logging.h"
|
||||
#include "libmv/tracking/track_region.h"
|
||||
|
||||
/* define this to generate PNG images with content of search areas
|
||||
tracking between which failed */
|
||||
#undef DUMP_FAILURE
|
||||
|
||||
/* define this to generate PNG images with content of search areas
|
||||
on every iteration of tracking */
|
||||
#undef DUMP_ALWAYS
|
||||
|
||||
using libmv::FloatImage;
|
||||
using libmv::TrackRegion;
|
||||
using libmv::TrackRegionOptions;
|
||||
using libmv::TrackRegionResult;
|
||||
|
||||
namespace {
|
||||
|
||||
TrackRegionOptions::Direction convertDirection(
|
||||
libmv_TrackRegionDirection direction) {
|
||||
switch (direction) {
|
||||
case LIBMV_TRACK_REGION_FORWARD: return TrackRegionOptions::FORWARD;
|
||||
case LIBMV_TRACK_REGION_BACKWARD: return TrackRegionOptions::BACKWARD;
|
||||
}
|
||||
|
||||
LOG(FATAL) << "Unhandled tracking direction " << direction
|
||||
<< ", should never happen.";
|
||||
|
||||
return TrackRegionOptions::FORWARD;
|
||||
}
|
||||
|
||||
TrackRegionOptions::Mode convertMotionModelToMode(int motion_model) {
|
||||
switch (motion_model) {
|
||||
#define LIBMV_CONVERT(the_model) \
|
||||
case TrackRegionOptions::the_model: return TrackRegionOptions::the_model;
|
||||
|
||||
LIBMV_CONVERT(TRANSLATION)
|
||||
LIBMV_CONVERT(TRANSLATION_ROTATION)
|
||||
LIBMV_CONVERT(TRANSLATION_SCALE)
|
||||
LIBMV_CONVERT(TRANSLATION_ROTATION_SCALE)
|
||||
LIBMV_CONVERT(AFFINE)
|
||||
LIBMV_CONVERT(HOMOGRAPHY)
|
||||
|
||||
#undef LIBMV_CONVERT
|
||||
}
|
||||
|
||||
LOG(FATAL) << "Unhandled motion model " << motion_model
|
||||
<< ", should never happen.";
|
||||
|
||||
return TrackRegionOptions::TRANSLATION;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void libmv_configureTrackRegionOptions(
|
||||
const libmv_TrackRegionOptions& options,
|
||||
TrackRegionOptions* track_region_options) {
|
||||
track_region_options->direction = convertDirection(options.direction);
|
||||
track_region_options->mode = convertMotionModelToMode(options.motion_model);
|
||||
track_region_options->minimum_correlation = options.minimum_correlation;
|
||||
track_region_options->max_iterations = options.num_iterations;
|
||||
track_region_options->sigma = options.sigma;
|
||||
track_region_options->num_extra_points = 1;
|
||||
track_region_options->image1_mask = NULL;
|
||||
track_region_options->use_brute_initialization = options.use_brute;
|
||||
/* TODO(keir): This will make some cases better, but may be a regression until
|
||||
* the motion model is in. Since this is on trunk, enable it for now.
|
||||
*
|
||||
* TODO(sergey): This gives much worse results on mango footage (see 04_2e)
|
||||
* so disabling for now for until proper prediction model is landed.
|
||||
*
|
||||
* The thing is, currently blender sends input coordinates as the guess to
|
||||
* region tracker and in case of fast motion such an early out ruins the
|
||||
* track.
|
||||
*/
|
||||
track_region_options->attempt_refine_before_brute = false;
|
||||
track_region_options->use_normalized_intensities = options.use_normalization;
|
||||
}
|
||||
|
||||
void libmv_regionTrackergetResult(const TrackRegionResult& track_region_result,
|
||||
libmv_TrackRegionResult* result) {
|
||||
result->termination = (int)track_region_result.termination;
|
||||
result->termination_reason = "";
|
||||
result->correlation = track_region_result.correlation;
|
||||
}
|
||||
|
||||
int libmv_trackRegion(const libmv_TrackRegionOptions* options,
|
||||
const float* image1,
|
||||
int image1_width,
|
||||
int image1_height,
|
||||
const float* image2,
|
||||
int image2_width,
|
||||
int image2_height,
|
||||
const double* x1,
|
||||
const double* y1,
|
||||
libmv_TrackRegionResult* /*result*/,
|
||||
double* x2,
|
||||
double* y2) {
|
||||
double xx1[5], yy1[5];
|
||||
double xx2[5], yy2[5];
|
||||
bool tracking_result = false;
|
||||
|
||||
// Convert to doubles for the libmv api. The four corners and the center.
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
xx1[i] = x1[i];
|
||||
yy1[i] = y1[i];
|
||||
xx2[i] = x2[i];
|
||||
yy2[i] = y2[i];
|
||||
}
|
||||
|
||||
TrackRegionOptions track_region_options;
|
||||
FloatImage image1_mask;
|
||||
|
||||
libmv_configureTrackRegionOptions(*options, &track_region_options);
|
||||
if (options->image1_mask) {
|
||||
libmv_floatBufferToFloatImage(
|
||||
options->image1_mask, image1_width, image1_height, 1, &image1_mask);
|
||||
|
||||
track_region_options.image1_mask = &image1_mask;
|
||||
}
|
||||
|
||||
// Convert from raw float buffers to libmv's FloatImage.
|
||||
FloatImage old_patch, new_patch;
|
||||
libmv_floatBufferToFloatImage(
|
||||
image1, image1_width, image1_height, 1, &old_patch);
|
||||
libmv_floatBufferToFloatImage(
|
||||
image2, image2_width, image2_height, 1, &new_patch);
|
||||
|
||||
TrackRegionResult track_region_result;
|
||||
TrackRegion(old_patch,
|
||||
new_patch,
|
||||
xx1,
|
||||
yy1,
|
||||
track_region_options,
|
||||
xx2,
|
||||
yy2,
|
||||
&track_region_result);
|
||||
|
||||
// Convert to floats for the blender api.
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
x2[i] = xx2[i];
|
||||
y2[i] = yy2[i];
|
||||
}
|
||||
|
||||
// TODO(keir): Update the termination string with failure details.
|
||||
if (track_region_result.termination == TrackRegionResult::CONVERGENCE ||
|
||||
track_region_result.termination == TrackRegionResult::NO_CONVERGENCE) {
|
||||
tracking_result = true;
|
||||
}
|
||||
|
||||
// Debug dump of patches.
|
||||
#if defined(DUMP_FAILURE) || defined(DUMP_ALWAYS)
|
||||
bool need_dump = !tracking_result;
|
||||
|
||||
# ifdef DUMP_ALWAYS
|
||||
need_dump = true;
|
||||
# endif
|
||||
|
||||
if (need_dump) {
|
||||
libmv_saveImage(old_patch, "old_patch", x1[4], y1[4]);
|
||||
libmv_saveImage(new_patch, "new_patch", x2[4], y2[4]);
|
||||
if (options->image1_mask) {
|
||||
libmv_saveImage(image1_mask, "mask", x2[4], y2[4]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return tracking_result;
|
||||
}
|
||||
65
blender-5.2.0/intern/libmv/intern/track_region.h
Normal file
65
blender-5.2.0/intern/libmv/intern/track_region.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifndef LIBMV_C_API_TRACK_REGION_H_
|
||||
#define LIBMV_C_API_TRACK_REGION_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum libmv_TrackRegionDirection {
|
||||
LIBMV_TRACK_REGION_FORWARD,
|
||||
LIBMV_TRACK_REGION_BACKWARD,
|
||||
} libmv_TrackRegionDirection;
|
||||
|
||||
typedef struct libmv_TrackRegionOptions {
|
||||
libmv_TrackRegionDirection direction;
|
||||
int motion_model;
|
||||
int num_iterations;
|
||||
int use_brute;
|
||||
int use_normalization;
|
||||
double minimum_correlation;
|
||||
double sigma;
|
||||
float* image1_mask;
|
||||
} libmv_TrackRegionOptions;
|
||||
|
||||
typedef struct libmv_TrackRegionResult {
|
||||
int termination;
|
||||
const char* termination_reason;
|
||||
double correlation;
|
||||
} libmv_TrackRegionResult;
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace libmv {
|
||||
struct TrackRegionOptions;
|
||||
struct TrackRegionResult;
|
||||
} // namespace libmv
|
||||
void libmv_configureTrackRegionOptions(
|
||||
const libmv_TrackRegionOptions& options,
|
||||
libmv::TrackRegionOptions* track_region_options);
|
||||
|
||||
void libmv_regionTrackergetResult(
|
||||
const libmv::TrackRegionResult& track_region_result,
|
||||
libmv_TrackRegionResult* result);
|
||||
#endif
|
||||
|
||||
int libmv_trackRegion(const libmv_TrackRegionOptions* options,
|
||||
const float* image1,
|
||||
int image1_width,
|
||||
int image1_height,
|
||||
const float* image2,
|
||||
int image2_width,
|
||||
int image2_height,
|
||||
const double* x1,
|
||||
const double* y1,
|
||||
libmv_TrackRegionResult* result,
|
||||
double* x2,
|
||||
double* y2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // LIBMV_C_API_PLANAR_TRACKER_H_
|
||||
30
blender-5.2.0/intern/libmv/intern/tracks.cc
Normal file
30
blender-5.2.0/intern/libmv/intern/tracks.cc
Normal file
@@ -0,0 +1,30 @@
|
||||
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "intern/tracks.h"
|
||||
#include "intern/utildefines.h"
|
||||
|
||||
#include "libmv/simple_pipeline/tracks.h"
|
||||
|
||||
using libmv::Marker;
|
||||
using libmv::Tracks;
|
||||
|
||||
libmv_Tracks* libmv_tracksNew(void) {
|
||||
Tracks* tracks = LIBMV_OBJECT_NEW(Tracks);
|
||||
|
||||
return (libmv_Tracks*)tracks;
|
||||
}
|
||||
|
||||
void libmv_tracksDestroy(libmv_Tracks* libmv_tracks) {
|
||||
LIBMV_OBJECT_DELETE(libmv_tracks, Tracks);
|
||||
}
|
||||
|
||||
void libmv_tracksInsert(libmv_Tracks* libmv_tracks,
|
||||
int image,
|
||||
int track,
|
||||
double x,
|
||||
double y,
|
||||
double weight) {
|
||||
((Tracks*)libmv_tracks)->Insert(image, track, x, y, weight);
|
||||
}
|
||||
29
blender-5.2.0/intern/libmv/intern/tracks.h
Normal file
29
blender-5.2.0/intern/libmv/intern/tracks.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifndef LIBMV_C_API_TRACKS_H_
|
||||
#define LIBMV_C_API_TRACKS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct libmv_Tracks libmv_Tracks;
|
||||
|
||||
libmv_Tracks* libmv_tracksNew(void);
|
||||
|
||||
void libmv_tracksDestroy(libmv_Tracks* libmv_tracks);
|
||||
|
||||
void libmv_tracksInsert(libmv_Tracks* libmv_tracks,
|
||||
int image,
|
||||
int track,
|
||||
double x,
|
||||
double y,
|
||||
double weight);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // LIBMV_C_API_TRACKS_H_
|
||||
113
blender-5.2.0/intern/libmv/intern/tracksN.cc
Normal file
113
blender-5.2.0/intern/libmv/intern/tracksN.cc
Normal file
@@ -0,0 +1,113 @@
|
||||
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "intern/tracksN.h"
|
||||
#include "intern/utildefines.h"
|
||||
#include "libmv/autotrack/marker.h"
|
||||
#include "libmv/autotrack/tracks.h"
|
||||
|
||||
using mv::Marker;
|
||||
using mv::Tracks;
|
||||
|
||||
void libmv_apiMarkerToMarker(const libmv_Marker& libmv_marker, Marker* marker) {
|
||||
marker->clip = libmv_marker.clip;
|
||||
marker->frame = libmv_marker.frame;
|
||||
marker->track = libmv_marker.track;
|
||||
marker->center(0) = libmv_marker.center[0];
|
||||
marker->center(1) = libmv_marker.center[1];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
marker->patch.coordinates(i, 0) = libmv_marker.patch[i][0];
|
||||
marker->patch.coordinates(i, 1) = libmv_marker.patch[i][1];
|
||||
}
|
||||
marker->search_region.min(0) = libmv_marker.search_region_min[0];
|
||||
marker->search_region.min(1) = libmv_marker.search_region_min[1];
|
||||
marker->search_region.max(0) = libmv_marker.search_region_max[0];
|
||||
marker->search_region.max(1) = libmv_marker.search_region_max[1];
|
||||
marker->weight = libmv_marker.weight;
|
||||
marker->source = (Marker::Source)libmv_marker.source;
|
||||
marker->status = (Marker::Status)libmv_marker.status;
|
||||
marker->reference_clip = libmv_marker.reference_clip;
|
||||
marker->reference_frame = libmv_marker.reference_frame;
|
||||
marker->model_type = (Marker::ModelType)libmv_marker.model_type;
|
||||
marker->model_id = libmv_marker.model_id;
|
||||
marker->disabled_channels = libmv_marker.disabled_channels;
|
||||
}
|
||||
|
||||
void libmv_markerToApiMarker(const Marker& marker, libmv_Marker* libmv_marker) {
|
||||
libmv_marker->clip = marker.clip;
|
||||
libmv_marker->frame = marker.frame;
|
||||
libmv_marker->track = marker.track;
|
||||
libmv_marker->center[0] = marker.center(0);
|
||||
libmv_marker->center[1] = marker.center(1);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
libmv_marker->patch[i][0] = marker.patch.coordinates(i, 0);
|
||||
libmv_marker->patch[i][1] = marker.patch.coordinates(i, 1);
|
||||
}
|
||||
libmv_marker->search_region_min[0] = marker.search_region.min(0);
|
||||
libmv_marker->search_region_min[1] = marker.search_region.min(1);
|
||||
libmv_marker->search_region_max[0] = marker.search_region.max(0);
|
||||
libmv_marker->search_region_max[1] = marker.search_region.max(1);
|
||||
libmv_marker->weight = marker.weight;
|
||||
libmv_marker->source = (libmv_MarkerSource)marker.source;
|
||||
libmv_marker->status = (libmv_MarkerStatus)marker.status;
|
||||
libmv_marker->reference_clip = marker.reference_clip;
|
||||
libmv_marker->reference_frame = marker.reference_frame;
|
||||
libmv_marker->model_type = (libmv_MarkerModelType)marker.model_type;
|
||||
libmv_marker->model_id = marker.model_id;
|
||||
libmv_marker->disabled_channels = marker.disabled_channels;
|
||||
}
|
||||
|
||||
libmv_TracksN* libmv_tracksNewN(void) {
|
||||
Tracks* tracks = LIBMV_OBJECT_NEW(Tracks);
|
||||
|
||||
return (libmv_TracksN*)tracks;
|
||||
}
|
||||
|
||||
void libmv_tracksDestroyN(libmv_TracksN* libmv_tracks) {
|
||||
LIBMV_OBJECT_DELETE(libmv_tracks, Tracks);
|
||||
}
|
||||
|
||||
void libmv_tracksAddMarkerN(libmv_TracksN* libmv_tracks,
|
||||
const libmv_Marker* libmv_marker) {
|
||||
Marker marker;
|
||||
libmv_apiMarkerToMarker(*libmv_marker, &marker);
|
||||
((Tracks*)libmv_tracks)->AddMarker(marker);
|
||||
}
|
||||
|
||||
void libmv_tracksGetMarkerN(libmv_TracksN* libmv_tracks,
|
||||
int clip,
|
||||
int frame,
|
||||
int track,
|
||||
libmv_Marker* libmv_marker) {
|
||||
Marker marker;
|
||||
((Tracks*)libmv_tracks)->GetMarker(clip, frame, track, &marker);
|
||||
libmv_markerToApiMarker(marker, libmv_marker);
|
||||
}
|
||||
|
||||
void libmv_tracksRemoveMarkerN(libmv_TracksN* libmv_tracks,
|
||||
int clip,
|
||||
int frame,
|
||||
int track) {
|
||||
((Tracks*)libmv_tracks)->RemoveMarker(clip, frame, track);
|
||||
}
|
||||
|
||||
void libmv_tracksRemoveMarkersForTrack(libmv_TracksN* libmv_tracks, int track) {
|
||||
((Tracks*)libmv_tracks)->RemoveMarkersForTrack(track);
|
||||
}
|
||||
|
||||
int libmv_tracksMaxClipN(libmv_TracksN* libmv_tracks) {
|
||||
return ((Tracks*)libmv_tracks)->MaxClip();
|
||||
}
|
||||
|
||||
int libmv_tracksMaxFrameN(libmv_TracksN* libmv_tracks, int clip) {
|
||||
return ((Tracks*)libmv_tracks)->MaxFrame(clip);
|
||||
}
|
||||
|
||||
int libmv_tracksMaxTrackN(libmv_TracksN* libmv_tracks) {
|
||||
return ((Tracks*)libmv_tracks)->MaxTrack();
|
||||
}
|
||||
|
||||
int libmv_tracksNumMarkersN(libmv_TracksN* libmv_tracks) {
|
||||
return ((Tracks*)libmv_tracks)->NumMarkers();
|
||||
}
|
||||
105
blender-5.2.0/intern/libmv/intern/tracksN.h
Normal file
105
blender-5.2.0/intern/libmv/intern/tracksN.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
// TODO(serrgey): For the time being we're converting simple pipeline
|
||||
// to an autotrack pipeline we call it tracks.
|
||||
// Once we've done with porting we remove N.
|
||||
|
||||
#ifndef LIBMV_C_API_TRACKSN_H_
|
||||
#define LIBMV_C_API_TRACKSN_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct libmv_TracksN libmv_TracksN;
|
||||
|
||||
// Keep order in this enums exactly the same as in mv::Marker.
|
||||
// Otherwise API wouldn't convert the values properly.
|
||||
typedef enum libmv_MarkerSource {
|
||||
LIBMV_MARKER_SOURCE_MANUAL,
|
||||
LIBMV_MARKER_SOURCE_DETECTED,
|
||||
LIBMV_MARKER_SOURCE_TRACKED,
|
||||
LIBMV_MARKER_SOURCE_MATCHED,
|
||||
LIBMV_MARKER_SOURCE_PREDICTED,
|
||||
} libmv_MarkerSource;
|
||||
|
||||
typedef enum libmv_MarkerStatus {
|
||||
LIBMV_MARKER_STATUS_UNKNOWN,
|
||||
LIBMV_MARKER_STATUS_INLIER,
|
||||
LIBMV_MARKER_STATUS_OUTLIER,
|
||||
} libmv_MarkerStatus;
|
||||
|
||||
typedef enum libmv_MarkerModelType {
|
||||
LIBMV_MARKER_MODEL_TYPE_POINT,
|
||||
LIBMV_MARKER_MODEL_TYPE_PLANE,
|
||||
LIBMV_MARKER_MODEL_TYPE_LINE,
|
||||
LIBMV_MARKER_MODEL_TYPE_CUBE,
|
||||
} libmv_MarkerModelType;
|
||||
|
||||
enum libmv_MarkerChannel {
|
||||
LIBMV_MARKER_CHANNEL_R = (1 << 0),
|
||||
LIBMV_MARKER_CHANNEL_G = (1 << 1),
|
||||
LIBMV_MARKER_CHANNEL_B = (1 << 2),
|
||||
};
|
||||
|
||||
typedef struct libmv_Marker {
|
||||
int clip;
|
||||
int frame;
|
||||
int track;
|
||||
float center[2];
|
||||
float patch[4][2];
|
||||
float search_region_min[2];
|
||||
float search_region_max[2];
|
||||
float weight;
|
||||
libmv_MarkerSource source;
|
||||
libmv_MarkerStatus status;
|
||||
int reference_clip;
|
||||
int reference_frame;
|
||||
libmv_MarkerModelType model_type;
|
||||
int model_id;
|
||||
int disabled_channels;
|
||||
} libmv_Marker;
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace mv {
|
||||
struct Marker;
|
||||
}
|
||||
void libmv_apiMarkerToMarker(const libmv_Marker& libmv_marker,
|
||||
mv::Marker* marker);
|
||||
|
||||
void libmv_markerToApiMarker(const mv::Marker& marker,
|
||||
libmv_Marker* libmv_marker);
|
||||
#endif
|
||||
|
||||
libmv_TracksN* libmv_tracksNewN(void);
|
||||
|
||||
void libmv_tracksDestroyN(libmv_TracksN* libmv_tracks);
|
||||
|
||||
void libmv_tracksAddMarkerN(libmv_TracksN* libmv_tracks,
|
||||
const libmv_Marker* libmv_marker);
|
||||
|
||||
void libmv_tracksGetMarkerN(libmv_TracksN* libmv_tracks,
|
||||
int clip,
|
||||
int frame,
|
||||
int track,
|
||||
libmv_Marker* libmv_marker);
|
||||
|
||||
void libmv_tracksRemoveMarkerN(libmv_TracksN* libmv_tracks,
|
||||
int clip,
|
||||
int frame,
|
||||
int track);
|
||||
|
||||
void libmv_tracksRemoveMarkersForTrack(libmv_TracksN* libmv_tracks, int track);
|
||||
|
||||
int libmv_tracksMaxClipN(libmv_TracksN* libmv_tracks);
|
||||
int libmv_tracksMaxFrameN(libmv_TracksN* libmv_tracks, int clip);
|
||||
int libmv_tracksMaxTrackN(libmv_TracksN* libmv_tracks);
|
||||
int libmv_tracksNumMarkersN(libmv_TracksN* libmv_tracks);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // LIBMV_C_API_TRACKS_H_
|
||||
60
blender-5.2.0/intern/libmv/intern/utildefines.h
Normal file
60
blender-5.2.0/intern/libmv/intern/utildefines.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* SPDX-FileCopyrightText: 2013 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifndef LIBMV_C_API_UTILDEFINES_H_
|
||||
#define LIBMV_C_API_UTILDEFINES_H_
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
# define __func__ __FUNCTION__
|
||||
# define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
#ifdef WITH_LIBMV_GUARDED_ALLOC
|
||||
# include "MEM_guardedalloc.h"
|
||||
# if defined __GNUC__
|
||||
# define LIBMV_OBJECT_NEW(type, args...) \
|
||||
new (MEM_new_uninitialized(sizeof(type), __func__)) type(args)
|
||||
# else
|
||||
# define LIBMV_OBJECT_NEW(type, ...) \
|
||||
new (MEM_new_uninitialized(sizeof(type), __FUNCTION__)) type(__VA_ARGS__)
|
||||
# endif
|
||||
# define LIBMV_OBJECT_DELETE(what, type) \
|
||||
{ \
|
||||
if (what) { \
|
||||
((type*)what)->~type(); \
|
||||
MEM_delete_void(const_cast<void*>(static_cast<const void*>(what))); \
|
||||
} \
|
||||
} \
|
||||
(void)0
|
||||
# define LIBMV_STRUCT_NEW(type, count) \
|
||||
(type*)MEM_new_uninitialized(sizeof(type) * count, __func__)
|
||||
# define LIBMV_STRUCT_DELETE(what) \
|
||||
MEM_delete_void(const_cast<void*>(static_cast<const void*>(what)))
|
||||
#else
|
||||
// Need this to keep libmv-capi potentially standalone.
|
||||
# if defined __GNUC__ || defined __sun
|
||||
# define LIBMV_OBJECT_NEW(type, args...) \
|
||||
new (malloc(sizeof(type))) type(args)
|
||||
# else
|
||||
# define LIBMV_OBJECT_NEW(type, ...) \
|
||||
new (malloc(sizeof(type))) type(__VA_ARGS__)
|
||||
# endif
|
||||
# define LIBMV_OBJECT_DELETE(what, type) \
|
||||
{ \
|
||||
if (what) { \
|
||||
((type*)(what))->~type(); \
|
||||
free(what); \
|
||||
} \
|
||||
} \
|
||||
(void)0
|
||||
# define LIBMV_STRUCT_NEW(type, count) (type*)malloc(sizeof(type) * count)
|
||||
# define LIBMV_STRUCT_DELETE(what) \
|
||||
{ \
|
||||
if (what) \
|
||||
free(what); \
|
||||
} \
|
||||
(void)0
|
||||
#endif
|
||||
|
||||
#endif // LIBMV_C_API_UTILDEFINES_H_
|
||||
Reference in New Issue
Block a user