48 ReconstructUpdateCallback(
50 void* callback_customdata) {
51 progress_update_callback_ = progress_update_callback;
52 callback_customdata_ = callback_customdata;
55 void invoke(
double progress,
const char* message) {
56 if (progress_update_callback_) {
57 progress_update_callback_(callback_customdata_, progress, message);
63 void* callback_customdata_;
66 void libmv_solveRefineIntrinsics(
68 const int refine_intrinsics,
69 const int bundle_constraints,
71 void* callback_customdata,
75 int bundle_intrinsics = 0;
84 #define SET_DISTORTION_FLAG_CHECKED(type, coefficient) \
86 if (refine_intrinsics & LIBMV_REFINE_##type##_DISTORTION_##coefficient) { \
87 bundle_intrinsics |= libmv::BUNDLE_##type##_##coefficient; \
99 #undef SET_DISTORTION_FLAG_CHECKED
101 progress_update_callback(callback_customdata, 1.0,
"Refining solution");
110 void finishReconstruction(
115 void* callback_customdata) {
120 progress_update_callback(callback_customdata, 1.0,
"Finishing solution");
122 libmv_reconstruction->
error =
126 bool selectTwoKeyframesBasedOnGRICAndVariance(
128 Tracks& normalized_tracks,
136 normalized_tracks, camera_intrinsics, keyframes);
138 if (keyframes.size() < 2) {
139 LG <<
"Not enough keyframes detected by GRIC";
141 }
else if (keyframes.size() == 2) {
142 keyframe1 = keyframes[0];
143 keyframe2 = keyframes[1];
155 int previous_keyframe = keyframes[0];
157 for (
int i = 1; i < keyframes.size(); i++) {
159 int current_keyframe = keyframes[i];
164 Tracks keyframe_tracks(keyframe_markers);
171 double current_error =
174 LG <<
"Error between " << previous_keyframe <<
" and " << current_keyframe
175 <<
": " << current_error;
177 if (current_error < best_error) {
178 best_error = current_error;
179 keyframe1 = previous_keyframe;
180 keyframe2 = current_keyframe;
183 previous_keyframe = current_keyframe;
193 projected /= projected(2);
197 projected(0), projected(1), &reprojected_marker.
x, &reprojected_marker.
y);
201 return reprojected_marker;
206 Tracks* normalized_tracks) {
208 for (
int i = 0; i <
markers.size(); ++i) {
211 marker.
x, marker.
y, &marker.
x, &marker.
y);
212 normalized_tracks->
Insert(
224 void* callback_customdata) {
232 ReconstructUpdateCallback update_callback =
233 ReconstructUpdateCallback(progress_update_callback, callback_customdata);
237 camera_intrinsics = libmv_reconstruction->
intrinsics =
242 libmv_getNormalizedTracks(
tracks, *camera_intrinsics, &normalized_tracks);
245 int keyframe1 = libmv_reconstruction_options->
keyframe1,
246 keyframe2 = libmv_reconstruction_options->
keyframe2;
249 LG <<
"Using automatic keyframe selection";
251 update_callback.invoke(0,
"Selecting keyframes");
253 if (selectTwoKeyframesBasedOnGRICAndVariance(
tracks,
259 libmv_reconstruction_options->
keyframe1 = keyframe1;
260 libmv_reconstruction_options->
keyframe2 = keyframe2;
265 LG <<
"frames to init from: " << keyframe1 <<
" " << keyframe2;
270 LG <<
"number of markers for init: " << keyframe_markers.size();
272 if (keyframe_markers.size() < 16) {
273 LG <<
"No enough markers to initialize from";
274 libmv_reconstruction->
is_valid =
false;
275 return libmv_reconstruction;
278 update_callback.invoke(0,
"Initial reconstruction");
281 LG <<
"Failed to initialize reconstruction";
282 libmv_reconstruction->
is_valid =
false;
283 return libmv_reconstruction;
292 libmv_solveRefineIntrinsics(
tracks,
295 progress_update_callback,
305 finishReconstruction(
tracks,
307 libmv_reconstruction,
308 progress_update_callback,
309 callback_customdata);
311 libmv_reconstruction->
is_valid =
true;
320 void* callback_customdata) {
328 ReconstructUpdateCallback update_callback =
329 ReconstructUpdateCallback(progress_update_callback, callback_customdata);
333 camera_intrinsics = libmv_reconstruction->
intrinsics =
338 libmv_getNormalizedTracks(
tracks, *camera_intrinsics, &normalized_tracks);
352 libmv_solveRefineIntrinsics(
tracks,
355 progress_update_callback,
362 finishReconstruction(
tracks,
364 libmv_reconstruction,
365 progress_update_callback,
366 callback_customdata);
368 libmv_reconstruction->
is_valid =
true;
373 return libmv_reconstruction->
is_valid;
405 int num_reprojected = 0;
406 double total_error = 0.0;
408 for (
int i = 0; i <
markers.size(); ++i) {
409 double weight =
markers[i].weight;
421 Marker reprojected_marker =
423 double ex = (reprojected_marker.
x -
markers[i].x) * weight;
424 double ey = (reprojected_marker.
y -
markers[i].y) * weight;
426 total_error +=
sqrt(ex * ex + ey * ey);
429 return total_error / num_reprojected;
440 int num_reprojected = 0;
441 double total_error = 0.0;
447 for (
int i = 0; i <
markers.size(); ++i) {
457 Marker reprojected_marker =
462 total_error +=
sqrt(ex * ex + ey * ey);
465 return total_error / num_reprojected;
477 for (
int j = 0; j < 3; ++j) {
478 for (
int k = 0; k < 3; ++k) {
498 mat[3][0] = optical_center(0);
499 mat[3][1] = optical_center(2);
500 mat[3][2] = optical_center(1);
512 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 Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise 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
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 Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise 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
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
virtual void invoke(double progress, const char *message)=0
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.
depth_tx normal_tx diffuse_light_tx specular_light_tx volume_light_tx environment_tx ambient_occlusion_tx aov_value_tx in_weight_img image(1, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D_ARRAY, "out_weight_img") .image(3
const vector< Marker > & markers
CameraIntrinsics * libmv_cameraIntrinsicsCreateFromOptions(const libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
struct libmv_CameraIntrinsics libmv_CameraIntrinsics
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)
double libmv_reprojectionErrorForImage(const libmv_Reconstruction *libmv_reconstruction, int image)
libmv_CameraIntrinsics * libmv_reconstructionExtractIntrinsics(libmv_Reconstruction *libmv_reconstruction)
double libmv_reprojectionError(const libmv_Reconstruction *libmv_reconstruction)
void libmv_reconstructionDestroy(libmv_Reconstruction *libmv_reconstruction)
int libmv_reconstructionIsValid(libmv_Reconstruction *libmv_reconstruction)
int libmv_reprojectionCameraForImage(const libmv_Reconstruction *libmv_reconstruction, int image, double mat[4][4])
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)
int libmv_reprojectionPointForTrack(const libmv_Reconstruction *libmv_reconstruction, int track, double pos[3])
#define SET_DISTORTION_FLAG_CHECKED(type, coefficient)
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
const ProjectiveReconstruction & reconstruction
std::vector< ElementType, Eigen::aligned_allocator< ElementType > > vector
void ModalSolver(const Tracks &tracks, EuclideanReconstruction *reconstruction, ProgressUpdateCallback *update_callback)
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)
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)