Camera tracking integration

===========================

Lookup grids used for image distortion/undistortion are now
caching and re-building if distortion settings are changing.

This speedups compositor node for cases distortion model isn't
changing, but first run and runs after changing distortion
coefficients is still slow.
This commit is contained in:
Sergey Sharybin 2011-09-26 19:00:12 +00:00
parent bb46df03ac
commit 4bd96adbcf
5 changed files with 160 additions and 16 deletions

@ -543,6 +543,86 @@ void libmv_destroyFeatures(struct libmv_Features *libmv_features)
delete (libmv::Feature *)libmv_features;
}
/* ************ camera intrinsics ************ */
struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsNew(double focal_length, double principal_x, double principal_y,
double k1, double k2, double k3)
{
libmv::CameraIntrinsics *intrinsics= new libmv::CameraIntrinsics();
intrinsics->SetFocalLength(focal_length, focal_length);
intrinsics->SetPrincipalPoint(principal_x, principal_y);
intrinsics->SetRadialDistortion(k1, k2, k3);
return (struct libmv_CameraIntrinsics *) intrinsics;
}
void libmv_CameraIntrinsicsDestroy(struct libmv_CameraIntrinsics *libmvIntrinsics)
{
libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
delete intrinsics;
}
void libmv_CameraIntrinsicsUpdate(struct libmv_CameraIntrinsics *libmvIntrinsics, double focal_length,
double principal_x, double principal_y, double k1, double k2, double k3)
{
libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
if (intrinsics->focal_length() != focal_length)
intrinsics->SetFocalLength(focal_length, focal_length);
if (intrinsics->principal_point_x() != principal_x || intrinsics->principal_point_y() != principal_y)
intrinsics->SetFocalLength(focal_length, focal_length);
if (intrinsics->k1() != k1 || intrinsics->k2() != k2 || intrinsics->k3() != k3)
intrinsics->SetRadialDistortion(k1, k2, k3);
}
void libmv_CameraIntrinsicsUndistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics,
unsigned char *src, unsigned char *dst, int width, int height, int channels)
{
libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
if (intrinsics->image_width() != width || intrinsics->image_height() != height)
intrinsics->SetImageSize(width, height);
intrinsics->Undistort(src, dst, width, height, channels);
}
void libmv_CameraIntrinsicsUndistortFloat(struct libmv_CameraIntrinsics *libmvIntrinsics,
float *src, float *dst, int width, int height, int channels)
{
libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
if (intrinsics->image_width() != width || intrinsics->image_height() != height)
intrinsics->SetImageSize(width, height);
intrinsics->Undistort(src, dst, width, height, channels);
}
void libmv_CameraIntrinsicsDistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics,
unsigned char *src, unsigned char *dst, int width, int height, int channels)
{
libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
if (intrinsics->image_width() != width || intrinsics->image_height() != height)
intrinsics->SetImageSize(width, height);
intrinsics->Distort(src, dst, width, height, channels);
}
void libmv_CameraIntrinsicsDistortFloat(struct libmv_CameraIntrinsics *libmvIntrinsics,
float *src, float *dst, int width, int height, int channels)
{
libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
if (intrinsics->image_width() != width || intrinsics->image_height() != height)
intrinsics->SetImageSize(width, height);
intrinsics->Distort(src, dst, width, height, channels);
}
/* ************ distortion ************ */
void libmv_undistortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,

@ -37,6 +37,7 @@ struct libmv_RegionTracker;
struct libmv_Tracks;
struct libmv_Reconstruction;
struct libmv_Features;
struct libmv_CameraIntrinsics;
/* Logging */
void libmv_initLogging(const char *argv0);
@ -77,6 +78,27 @@ int libmv_countFeatures(struct libmv_Features *libmv_features);
void libmv_getFeature(struct libmv_Features *libmv_features, int number, double *x, double *y, double *score, double *size);
void libmv_destroyFeatures(struct libmv_Features *libmv_features);
/* camera intrinsics */
struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsNew(double focal_length, double principal_x, double principal_y,
double k1, double k2, double k3);
void libmv_CameraIntrinsicsDestroy(struct libmv_CameraIntrinsics *libmvIntrinsics);
void libmv_CameraIntrinsicsUpdate(struct libmv_CameraIntrinsics *libmvIntrinsics, double focal_length,
double principal_x, double principal_y, double k1, double k2, double k3);
void libmv_CameraIntrinsicsUndistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics,
unsigned char *src, unsigned char *dst, int width, int height, int channels);
void libmv_CameraIntrinsicsUndistortFloat(struct libmv_CameraIntrinsics *libmvIntrinsics,
float *src, float *dst, int width, int height, int channels);
void libmv_CameraIntrinsicsDistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics,
unsigned char *src, unsigned char *dst, int width, int height, int channels);
void libmv_CameraIntrinsicsDistortFloat(struct libmv_CameraIntrinsics *libmvIntrinsics,
float *src, float *dst, int width, int height, int channels);
/* dsitortion */
void libmv_undistortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
unsigned char *src, unsigned char *dst, int width, int height, int channels);

@ -463,6 +463,11 @@ void BKE_tracking_free(MovieTracking *tracking)
if(tracking->stabilization.scaleibuf)
IMB_freeImBuf(tracking->stabilization.scaleibuf);
#ifdef WITH_LIBMV
if(tracking->camera.intrinsics)
libmv_CameraIntrinsicsDestroy(tracking->camera.intrinsics);
#endif
}
/*********************** tracking *************************/
@ -1898,18 +1903,32 @@ ImBuf *BKE_tracking_undistort(MovieTracking *tracking, ImBuf *ibuf)
resibuf= IMB_dupImBuf(ibuf);
#ifdef WITH_LIBMV
if(camera->intrinsics == NULL) {
camera->intrinsics= libmv_CameraIntrinsicsNew(camera->focal,
camera->principal[0], camera->principal[1] * aspy,
camera->k1, camera->k2, camera->k3);
} else {
libmv_CameraIntrinsicsUpdate(camera->intrinsics, camera->focal,
camera->principal[0], camera->principal[1] * aspy,
camera->k1, camera->k2, camera->k3);
}
#endif
if(ibuf->rect_float) {
libmv_undistortFloat(camera->focal,
camera->principal[0], camera->principal[1] * aspy,
camera->k1, camera->k2, camera->k3,
ibuf->rect_float, resibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels);
#ifdef WITH_LIBMV
libmv_CameraIntrinsicsUndistortFloat(camera->intrinsics,
ibuf->rect_float, resibuf->rect_float,
ibuf->x, ibuf->y, ibuf->channels);
#endif
ibuf->userflags|= IB_RECT_INVALID;
} else {
libmv_undistortByte(camera->focal,
camera->principal[0], camera->principal[1] * aspy,
camera->k1, camera->k2, camera->k3,
(unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect, ibuf->x, ibuf->y, ibuf->channels);
#ifdef WITH_LIBMV
libmv_CameraIntrinsicsUndistortByte(camera->intrinsics,
(unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect,
ibuf->x, ibuf->y, ibuf->channels);
#endif
}
return resibuf;
@ -1923,18 +1942,32 @@ ImBuf *BKE_tracking_distort(MovieTracking *tracking, ImBuf *ibuf)
resibuf= IMB_dupImBuf(ibuf);
#ifdef WITH_LIBMV
if(camera->intrinsics == NULL) {
camera->intrinsics= libmv_CameraIntrinsicsNew(camera->focal,
camera->principal[0], camera->principal[1] * aspy,
camera->k1, camera->k2, camera->k3);
} else {
libmv_CameraIntrinsicsUpdate(camera->intrinsics, camera->focal,
camera->principal[0], camera->principal[1] * aspy,
camera->k1, camera->k2, camera->k3);
}
#endif
if(ibuf->rect_float) {
libmv_distortFloat(camera->focal,
camera->principal[0], camera->principal[1] * aspy,
camera->k1, camera->k2, camera->k3,
ibuf->rect_float, resibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels);
#ifdef WITH_LIBMV
libmv_CameraIntrinsicsDistortFloat(camera->intrinsics,
ibuf->rect_float, resibuf->rect_float,
ibuf->x, ibuf->y, ibuf->channels);
#endif
ibuf->userflags|= IB_RECT_INVALID;
} else {
libmv_distortByte(camera->focal,
camera->principal[0], camera->principal[1] * aspy,
camera->k1, camera->k2, camera->k3,
(unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect, ibuf->x, ibuf->y, ibuf->channels);
#ifdef WITH_LIBMV
libmv_CameraIntrinsicsDistortByte(camera->intrinsics,
(unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect,
ibuf->x, ibuf->y, ibuf->channels);
#endif
}
return resibuf;

@ -1259,6 +1259,9 @@ void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain)
for(;clip; clip= clip->id.next) {
if(clip->cache)
oldnewmap_insert(fd->movieclipmap, clip->cache, clip->cache, 0);
if(clip->tracking.camera.intrinsics)
oldnewmap_insert(fd->movieclipmap, clip->tracking.camera.intrinsics, clip->tracking.camera.intrinsics, 0);
}
}
@ -1278,6 +1281,7 @@ void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain)
for(;clip; clip= clip->id.next) {
clip->cache= newmclipadr(fd, clip->cache);
clip->tracking.camera.intrinsics= newmclipadr(fd, clip->tracking.camera.intrinsics);
}
}
@ -5803,6 +5807,9 @@ static void direct_link_movieclip(FileData *fd, MovieClip *clip)
if(fd->movieclipmap) clip->cache= newmclipadr(fd, clip->cache);
else clip->cache= NULL;
if(fd->movieclipmap) clip->tracking.camera.intrinsics= newmclipadr(fd, clip->tracking.camera.intrinsics);
else clip->tracking.camera.intrinsics= NULL;
tracking->reconstruction.cameras= newdataadr(fd, tracking->reconstruction.cameras);
link_list(fd, &tracking->tracks);

@ -55,6 +55,8 @@ typedef struct MovieReconstructedCamera {
} MovieReconstructedCamera;
typedef struct MovieTrackingCamera {
void *intrinsics; /* intrinsics handle */
float sensor_width; /* width of CCD sensor */
float pixel_aspect; /* pixel aspect ratio */
float pad2;