49 ReconstructUpdateCallback(
51 void* callback_customdata) {
52 progress_update_callback_ = progress_update_callback;
53 callback_customdata_ = callback_customdata;
56 void invoke(
double progress,
const char* message) {
57 if (progress_update_callback_) {
58 progress_update_callback_(callback_customdata_, progress, message);
64 void* callback_customdata_;
67void libmv_solveRefineIntrinsics(
69 const int refine_intrinsics,
70 const int bundle_constraints,
72 void* callback_customdata,
76 int bundle_intrinsics = 0;
85#define SET_DISTORTION_FLAG_CHECKED(type, coefficient) \
87 if (refine_intrinsics & LIBMV_REFINE_##type##_DISTORTION_##coefficient) { \
88 bundle_intrinsics |= libmv::BUNDLE_##type##_##coefficient; \
100#undef SET_DISTORTION_FLAG_CHECKED
102 progress_update_callback(callback_customdata, 1.0,
"Refining solution");
111void finishReconstruction(
116 void* callback_customdata) {
121 progress_update_callback(callback_customdata, 1.0,
"Finishing solution");
123 libmv_reconstruction->
error =
127bool selectTwoKeyframesBasedOnGRICAndVariance(
129 Tracks& normalized_tracks,
137 normalized_tracks, camera_intrinsics, keyframes);
139 if (keyframes.size() < 2) {
140 LG <<
"Not enough keyframes detected by GRIC";
142 }
else if (keyframes.size() == 2) {
143 keyframe1 = keyframes[0];
144 keyframe2 = keyframes[1];
156 int previous_keyframe = keyframes[0];
157 double best_error = std::numeric_limits<double>::max();
158 for (
int i = 1; i < keyframes.size(); i++) {
160 int current_keyframe = keyframes[i];
165 Tracks keyframe_tracks(keyframe_markers);
172 double current_error =
175 LG <<
"Error between " << previous_keyframe <<
" and " << current_keyframe
176 <<
": " << current_error;
178 if (current_error < best_error) {
179 best_error = current_error;
180 keyframe1 = previous_keyframe;
181 keyframe2 = current_keyframe;
184 previous_keyframe = current_keyframe;
194 projected /= projected(2);
198 projected(0), projected(1), &reprojected_marker.
x, &reprojected_marker.
y);
202 return reprojected_marker;
207 Tracks* normalized_tracks) {
209 for (
int i = 0; i < markers.size(); ++i) {
210 Marker& marker = markers[i];
212 marker.
x, marker.
y, &marker.
x, &marker.
y);
213 normalized_tracks->
Insert(
225 void* callback_customdata) {
233 ReconstructUpdateCallback update_callback =
234 ReconstructUpdateCallback(progress_update_callback, callback_customdata);
238 camera_intrinsics = libmv_reconstruction->
intrinsics =
243 libmv_getNormalizedTracks(
tracks, *camera_intrinsics, &normalized_tracks);
246 int keyframe1 = libmv_reconstruction_options->
keyframe1,
247 keyframe2 = libmv_reconstruction_options->
keyframe2;
250 LG <<
"Using automatic keyframe selection";
252 update_callback.invoke(0,
"Selecting keyframes");
254 if (selectTwoKeyframesBasedOnGRICAndVariance(
tracks,
260 libmv_reconstruction_options->
keyframe1 = keyframe1;
261 libmv_reconstruction_options->
keyframe2 = keyframe2;
266 LG <<
"frames to init from: " << keyframe1 <<
" " << keyframe2;
271 LG <<
"number of markers for init: " << keyframe_markers.size();
273 if (keyframe_markers.size() < 16) {
274 LG <<
"No enough markers to initialize from";
275 libmv_reconstruction->
is_valid =
false;
276 return libmv_reconstruction;
279 update_callback.invoke(0,
"Initial reconstruction");
282 LG <<
"Failed to initialize reconstruction";
283 libmv_reconstruction->
is_valid =
false;
284 return libmv_reconstruction;
289 normalized_tracks, &reconstruction, &update_callback);
293 libmv_solveRefineIntrinsics(
tracks,
296 progress_update_callback,
306 finishReconstruction(
tracks,
308 libmv_reconstruction,
309 progress_update_callback,
310 callback_customdata);
312 libmv_reconstruction->
is_valid =
true;
321 void* callback_customdata) {
329 ReconstructUpdateCallback update_callback =
330 ReconstructUpdateCallback(progress_update_callback, callback_customdata);
334 camera_intrinsics = libmv_reconstruction->
intrinsics =
339 libmv_getNormalizedTracks(
tracks, *camera_intrinsics, &normalized_tracks);
342 ModalSolver(normalized_tracks, &reconstruction, &update_callback);
345 EuclideanBundleCommonIntrinsics(normalized_tracks,
353 libmv_solveRefineIntrinsics(
tracks,
356 progress_update_callback,
363 finishReconstruction(
tracks,
365 libmv_reconstruction,
366 progress_update_callback,
367 callback_customdata);
369 libmv_reconstruction->
is_valid =
true;
374 return libmv_reconstruction->
is_valid;
406 int num_reprojected = 0;
407 double total_error = 0.0;
409 for (
int i = 0; i < markers.size(); ++i) {
410 double weight = markers[i].weight;
422 Marker reprojected_marker =
424 double ex = (reprojected_marker.
x - markers[i].x) * weight;
425 double ey = (reprojected_marker.
y - markers[i].y) * weight;
427 total_error +=
sqrt(ex * ex + ey * ey);
430 return total_error / num_reprojected;
441 int num_reprojected = 0;
442 double total_error = 0.0;
448 for (
int i = 0; i < markers.size(); ++i) {
458 Marker reprojected_marker =
460 double ex = (reprojected_marker.
x - markers[i].x) * markers[i].weight;
461 double ey = (reprojected_marker.
y - markers[i].y) * markers[i].weight;
463 total_error +=
sqrt(ex * ex + ey * ey);
466 return total_error / num_reprojected;
478 for (
int j = 0; j < 3; ++j) {
479 for (
int k = 0; k < 3; ++k) {
499 mat[3][0] = optical_center(0);
500 mat[3][1] = optical_center(2);
501 mat[3][2] = optical_center(1);
513 return libmv_reconstruction->
error;
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between camera
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
ATTR_WARN_UNUSED_RESULT const BMLoop * l
virtual void ApplyIntrinsics(double normalized_x, double normalized_y, double *image_x, double *image_y) const =0
virtual void InvertIntrinsics(double image_x, double image_y, double *normalized_x, double *normalized_y) const =0
EuclideanPoint * PointForTrack(int track)
Returns a pointer to the point corresponding to track.
EuclideanCamera * CameraForImage(int image)
Returns a pointer to the camera corresponding to image.
vector< Marker > MarkersInImage(int image) const
Returns all the markers visible in image.
vector< Marker > MarkersForTracksInBothImages(int image1, int image2) const
void Insert(int image, int track, double x, double y, double weight=1.0)
vector< Marker > MarkersForTrack(int track) const
Returns all the markers belonging to a track.
input_tx image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "preview_img") .compute_source("compositor_compute_preview.glsl") .do_static_compilation(true)
CameraIntrinsics * libmv_cameraIntrinsicsCreateFromOptions(const libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
struct libmv_CameraIntrinsics libmv_CameraIntrinsics
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)
double libmv_reprojectionErrorForImage(const libmv_Reconstruction *libmv_reconstruction, int image)
double libmv_reprojectionError(const libmv_Reconstruction *libmv_reconstruction)
void libmv_reconstructionDestroy(libmv_Reconstruction *libmv_reconstruction)
bool EuclideanReconstructTwoFrames(const vector< Marker > &markers, EuclideanReconstruction *reconstruction)
void EuclideanScaleToUnity(EuclideanReconstruction *reconstruction)
void EuclideanBundle(const Tracks &tracks, EuclideanReconstruction *reconstruction)
void EuclideanCompleteReconstruction(const Tracks &tracks, EuclideanReconstruction *reconstruction, ProgressUpdateCallback *update_callback)
int libmv_reconstructionIsValid(libmv_Reconstruction *libmv_reconstruction)
int libmv_reprojectionCameraForImage(const libmv_Reconstruction *libmv_reconstruction, int image, double mat[4][4])
libmv_CameraIntrinsics * libmv_reconstructionExtractIntrinsics(libmv_Reconstruction *libmv_reconstruction)
int libmv_reprojectionPointForTrack(const libmv_Reconstruction *libmv_reconstruction, int track, double pos[3])
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)
#define SET_DISTORTION_FLAG_CHECKED(type, coefficient)
double EuclideanReprojectionError(const Tracks &image_tracks, const EuclideanReconstruction &reconstruction, const CameraIntrinsics &intrinsics)
double libmv_reprojectionErrorForTrack(const libmv_Reconstruction *libmv_reconstruction, int track)
void(* reconstruct_progress_update_cb)(void *customdata, double progress, const char *message)
@ LIBMV_REFINE_FOCAL_LENGTH
@ LIBMV_REFINE_PRINCIPAL_POINT
struct libmv_Tracks libmv_Tracks
void SelectKeyframesBasedOnGRICAndVariance(const Tracks &_tracks, const CameraIntrinsics &intrinsics, vector< int > &keyframes)
bool EuclideanReconstructTwoFrames(const vector< Marker > &markers, EuclideanReconstruction *reconstruction)
void EuclideanScaleToUnity(EuclideanReconstruction *reconstruction)
void EuclideanBundle(const Tracks &tracks, EuclideanReconstruction *reconstruction)
void EuclideanCompleteReconstruction(const Tracks &tracks, EuclideanReconstruction *reconstruction, ProgressUpdateCallback *update_callback)
std::vector< ElementType, Eigen::aligned_allocator< ElementType > > vector
void EuclideanBundleCommonIntrinsics(const Tracks &tracks, const int bundle_intrinsics, const int bundle_constraints, EuclideanReconstruction *reconstruction, CameraIntrinsics *intrinsics, BundleEvaluation *evaluation)
double EuclideanReprojectionError(const Tracks &image_tracks, const EuclideanReconstruction &reconstruction, const CameraIntrinsics &intrinsics)
CameraIntrinsics * intrinsics
EuclideanReconstruction reconstruction
#define LIBMV_OBJECT_NEW(type,...)
#define LIBMV_OBJECT_DELETE(what, type)