Camera tracking integration

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

- Merge Movie Distort and Movie Undistort nodes into one node
  called Movie Distortion where action (distort/undistort is specified).
- Implemented more proper distortion/undistortion for scaled images.

NOTE: Please, delete distortion nodes with current blender first
      before opening files with blender versions from this commit/
This commit is contained in:
Sergey Sharybin
2011-09-28 13:31:32 +00:00
parent 3323a36861
commit a36dd050ed
20 changed files with 465 additions and 334 deletions

View File

@@ -546,13 +546,14 @@ 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)
double k1, double k2, double k3, int width, int height)
{
libmv::CameraIntrinsics *intrinsics= new libmv::CameraIntrinsics();
intrinsics->SetFocalLength(focal_length, focal_length);
intrinsics->SetPrincipalPoint(principal_x, principal_y);
intrinsics->SetRadialDistortion(k1, k2, k3);
intrinsics->SetImageSize(width, height);
return (struct libmv_CameraIntrinsics *) intrinsics;
}
@@ -565,7 +566,7 @@ void libmv_CameraIntrinsicsDestroy(struct libmv_CameraIntrinsics *libmvIntrinsic
}
void libmv_CameraIntrinsicsUpdate(struct libmv_CameraIntrinsics *libmvIntrinsics, double focal_length,
double principal_x, double principal_y, double k1, double k2, double k3)
double principal_x, double principal_y, double k1, double k2, double k3, int width, int height)
{
libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
@@ -577,6 +578,9 @@ void libmv_CameraIntrinsicsUpdate(struct libmv_CameraIntrinsics *libmvIntrinsics
if (intrinsics->k1() != k1 || intrinsics->k2() != k2 || intrinsics->k3() != k3)
intrinsics->SetRadialDistortion(k1, k2, k3);
if (intrinsics->image_width() != width || intrinsics->image_height() != height)
intrinsics->SetImageSize(width, height);
}
void libmv_CameraIntrinsicsUndistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics,
@@ -584,9 +588,6 @@ void libmv_CameraIntrinsicsUndistortByte(struct libmv_CameraIntrinsics *libmvInt
{
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);
}
@@ -595,9 +596,6 @@ void libmv_CameraIntrinsicsUndistortFloat(struct libmv_CameraIntrinsics *libmvIn
{
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);
}
@@ -605,10 +603,6 @@ void libmv_CameraIntrinsicsDistortByte(struct libmv_CameraIntrinsics *libmvIntri
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);
}
@@ -617,9 +611,6 @@ void libmv_CameraIntrinsicsDistortFloat(struct libmv_CameraIntrinsics *libmvIntr
{
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);
}

View File

@@ -80,12 +80,12 @@ 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);
double k1, double k2, double k3, int width, int height);
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);
double principal_x, double principal_y, double k1, double k2, double k3, int width, int height);
void libmv_CameraIntrinsicsUndistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics,
unsigned char *src, unsigned char *dst, int width, int height, int channels);

View File

@@ -24,6 +24,7 @@
namespace libmv {
struct Offset { signed char ix,iy; unsigned char fx,fy; };
struct Grid { struct Offset *offset; int width, height; };
CameraIntrinsics::CameraIntrinsics()
: K_(Mat3::Identity()),
@@ -38,8 +39,7 @@ CameraIntrinsics::CameraIntrinsics()
undistort_(0) {}
CameraIntrinsics::~CameraIntrinsics() {
if(distort_) delete[] distort_;
if(undistort_) delete[] undistort_;
FreeLookupGrid();
}
/// Set the entire calibration matrix at once.
@@ -146,11 +146,17 @@ void CameraIntrinsics::InvertIntrinsics(double image_x,
// TODO(MatthiasF): downsample lookup
template<typename WarpFunction>
void CameraIntrinsics::ComputeLookupGrid(Offset* grid, int width, int height) {
void CameraIntrinsics::ComputeLookupGrid(Grid* grid, int width, int height) {
double aspx = (double)width / image_width_;
double aspy = (double)height / image_height_;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
double src_x = x / aspx, src_y = y / aspy;
double warp_x, warp_y;
WarpFunction(this,x,y,&warp_x,&warp_y);
WarpFunction(this,src_x,src_y,&warp_x,&warp_y);
warp_x *= aspx;
warp_y *= aspy;
int ix = int(warp_x), iy = int(warp_y);
int fx = round((warp_x-ix)*256), fy = round((warp_y-iy)*256);
if(fx == 256) { fx=0; ix++; }
@@ -162,10 +168,10 @@ void CameraIntrinsics::ComputeLookupGrid(Offset* grid, int width, int height) {
if( iy >= height-2 ) iy = height-2;
if ( ix-x > -128 && ix-x < 128 && iy-y > -128 && iy-y < 128 ) {
Offset offset = { ix-x, iy-y, fx, fy };
grid[y*width+x] = offset;
grid->offset[y*width+x] = offset;
} else {
Offset offset = { 0, 0, 0, 0 };
grid[y*width+x] = offset;
grid->offset[y*width+x] = offset;
}
}
}
@@ -173,11 +179,11 @@ void CameraIntrinsics::ComputeLookupGrid(Offset* grid, int width, int height) {
// TODO(MatthiasF): cubic B-Spline image sampling, bilinear lookup
template<typename T,int N>
static void Warp(const Offset* grid, const T* src, T* dst,
static void Warp(const Grid* grid, const T* src, T* dst,
int width, int height) {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Offset offset = grid[y*width+x];
Offset offset = grid->offset[y*width+x];
const T* s = &src[((y+offset.iy)*width+(x+offset.ix))*N];
for (int i = 0; i < N; i++) {
dst[(y*width+x)*N+i] = ((s[ i] * (256-offset.fx) + s[ N+i] * offset.fx) * (256-offset.fy)
@@ -188,8 +194,17 @@ static void Warp(const Offset* grid, const T* src, T* dst,
}
void CameraIntrinsics::FreeLookupGrid() {
if(distort_) delete distort_, distort_=0;
if(undistort_) delete undistort_, undistort_=0;
if(distort_) {
delete distort_;
delete distort_->offset;
distort_ = NULL;
}
if(undistort_) {
delete undistort_;
delete undistort_->offset;
undistort_ = NULL;
}
}
// FIXME: C++ templates limitations makes thing complicated, but maybe there is a simpler method.
@@ -211,11 +226,50 @@ struct InvertIntrinsicsFunction {
}
};
void CameraIntrinsics::Distort(const float* src, float* dst, int width, int height, int channels) {
if(!distort_) {
distort_ = new Offset[width*height];
ComputeLookupGrid<InvertIntrinsicsFunction>(distort_,width,height);
void CameraIntrinsics::CheckDistortLookupGrid(int width, int height)
{
if(distort_) {
if(distort_->width != width || distort_->height != height) {
delete [] distort_->offset;
distort_->offset = NULL;
}
} else {
distort_ = new Grid;
distort_->offset = NULL;
}
if(!distort_->offset) {
distort_->offset = new Offset[width*height];
ComputeLookupGrid<InvertIntrinsicsFunction>(distort_,width,height);
}
distort_->width = width;
distort_->height = height;
}
void CameraIntrinsics::CheckUndistortLookupGrid(int width, int height)
{
if(undistort_) {
if(undistort_->width != width || undistort_->height != height) {
delete [] undistort_->offset;
undistort_->offset = NULL;
}
} else {
undistort_ = new Grid;
undistort_->offset = NULL;
}
if(!undistort_->offset) {
undistort_->offset = new Offset[width*height];
ComputeLookupGrid<ApplyIntrinsicsFunction>(undistort_,width,height);
}
undistort_->width = width;
undistort_->height = height;
}
void CameraIntrinsics::Distort(const float* src, float* dst, int width, int height, int channels) {
CheckDistortLookupGrid(width, height);
if(channels==1) Warp<float,1>(distort_,src,dst,width,height);
else if(channels==2) Warp<float,2>(distort_,src,dst,width,height);
else if(channels==3) Warp<float,3>(distort_,src,dst,width,height);
@@ -224,10 +278,7 @@ void CameraIntrinsics::Distort(const float* src, float* dst, int width, int heig
}
void CameraIntrinsics::Distort(const unsigned char* src, unsigned char* dst, int width, int height, int channels) {
if(!distort_) {
distort_ = new Offset[width*height];
ComputeLookupGrid<InvertIntrinsicsFunction>(distort_,width,height);
}
CheckDistortLookupGrid(width, height);
if(channels==1) Warp<unsigned char,1>(distort_,src,dst,width,height);
else if(channels==2) Warp<unsigned char,2>(distort_,src,dst,width,height);
else if(channels==3) Warp<unsigned char,3>(distort_,src,dst,width,height);
@@ -236,10 +287,7 @@ void CameraIntrinsics::Distort(const unsigned char* src, unsigned char* dst, int
}
void CameraIntrinsics::Undistort(const float* src, float* dst, int width, int height, int channels) {
if(!undistort_) {
undistort_ = new Offset[width*height];
ComputeLookupGrid<ApplyIntrinsicsFunction>(undistort_,width,height);
}
CheckUndistortLookupGrid(width, height);
if(channels==1) Warp<float,1>(undistort_,src,dst,width,height);
else if(channels==2) Warp<float,2>(undistort_,src,dst,width,height);
else if(channels==3) Warp<float,3>(undistort_,src,dst,width,height);
@@ -248,10 +296,7 @@ void CameraIntrinsics::Undistort(const float* src, float* dst, int width, int he
}
void CameraIntrinsics::Undistort(const unsigned char* src, unsigned char* dst, int width, int height, int channels) {
if(!undistort_) {
undistort_ = new Offset[width*height];
ComputeLookupGrid<ApplyIntrinsicsFunction>(undistort_,width,height);
}
CheckUndistortLookupGrid(width, height);
if(channels==1) Warp<unsigned char,1>(undistort_,src,dst,width,height);
else if(channels==2) Warp<unsigned char,2>(undistort_,src,dst,width,height);
else if(channels==3) Warp<unsigned char,3>(undistort_,src,dst,width,height);

View File

@@ -26,8 +26,6 @@ typedef Eigen::Matrix<double, 3, 3> Mat3;
namespace libmv {
struct Offset;
class CameraIntrinsics {
public:
CameraIntrinsics();
@@ -123,7 +121,9 @@ class CameraIntrinsics {
int width, int height, int channels);
private:
template<typename WarpFunction> void ComputeLookupGrid(Offset* grid, int width, int height);
template<typename WarpFunction> void ComputeLookupGrid(struct Grid* grid, int width, int height);
void CheckUndistortLookupGrid(int width, int height);
void CheckDistortLookupGrid(int width, int height);
void FreeLookupGrid();
// The traditional intrinsics matrix from x = K[R|t]X.
@@ -140,8 +140,8 @@ class CameraIntrinsics {
// independent of image size.
double k1_, k2_, k3_, p1_, p2_;
Offset* distort_;
Offset* undistort_;
struct Grid *distort_;
struct Grid *undistort_;
};
} // namespace libmv

View File

@@ -0,0 +1,215 @@
diff --git a/src/libmv/simple_pipeline/camera_intrinsics.cc b/src/libmv/simple_pipeline/camera_intrinsics.cc
index f9888ff..e1e6117 100644
--- a/src/libmv/simple_pipeline/camera_intrinsics.cc
+++ b/src/libmv/simple_pipeline/camera_intrinsics.cc
@@ -24,6 +24,7 @@
namespace libmv {
struct Offset { signed char ix,iy; unsigned char fx,fy; };
+struct Grid { struct Offset *offset; int width, height; };
CameraIntrinsics::CameraIntrinsics()
: K_(Mat3::Identity()),
@@ -38,8 +39,7 @@ CameraIntrinsics::CameraIntrinsics()
undistort_(0) {}
CameraIntrinsics::~CameraIntrinsics() {
- if(distort_) delete[] distort_;
- if(undistort_) delete[] undistort_;
+ FreeLookupGrid();
}
/// Set the entire calibration matrix at once.
@@ -146,11 +146,17 @@ void CameraIntrinsics::InvertIntrinsics(double image_x,
// TODO(MatthiasF): downsample lookup
template<typename WarpFunction>
-void CameraIntrinsics::ComputeLookupGrid(Offset* grid, int width, int height) {
+void CameraIntrinsics::ComputeLookupGrid(Grid* grid, int width, int height) {
+ double aspx = (double)width / image_width_;
+ double aspy = (double)height / image_height_;
+
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
+ double src_x = x / aspx, src_y = y / aspy;
double warp_x, warp_y;
- WarpFunction(this,x,y,&warp_x,&warp_y);
+ WarpFunction(this,src_x,src_y,&warp_x,&warp_y);
+ warp_x *= aspx;
+ warp_y *= aspy;
int ix = int(warp_x), iy = int(warp_y);
int fx = round((warp_x-ix)*256), fy = round((warp_y-iy)*256);
if(fx == 256) { fx=0; ix++; }
@@ -162,10 +168,10 @@ void CameraIntrinsics::ComputeLookupGrid(Offset* grid, int width, int height) {
if( iy >= height-2 ) iy = height-2;
if ( ix-x > -128 && ix-x < 128 && iy-y > -128 && iy-y < 128 ) {
Offset offset = { ix-x, iy-y, fx, fy };
- grid[y*width+x] = offset;
+ grid->offset[y*width+x] = offset;
} else {
Offset offset = { 0, 0, 0, 0 };
- grid[y*width+x] = offset;
+ grid->offset[y*width+x] = offset;
}
}
}
@@ -173,11 +179,11 @@ void CameraIntrinsics::ComputeLookupGrid(Offset* grid, int width, int height) {
// TODO(MatthiasF): cubic B-Spline image sampling, bilinear lookup
template<typename T,int N>
-static void Warp(const Offset* grid, const T* src, T* dst,
+static void Warp(const Grid* grid, const T* src, T* dst,
int width, int height) {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
- Offset offset = grid[y*width+x];
+ Offset offset = grid->offset[y*width+x];
const T* s = &src[((y+offset.iy)*width+(x+offset.ix))*N];
for (int i = 0; i < N; i++) {
dst[(y*width+x)*N+i] = ((s[ i] * (256-offset.fx) + s[ N+i] * offset.fx) * (256-offset.fy)
@@ -188,8 +194,17 @@ static void Warp(const Offset* grid, const T* src, T* dst,
}
void CameraIntrinsics::FreeLookupGrid() {
- if(distort_) delete distort_, distort_=0;
- if(undistort_) delete undistort_, undistort_=0;
+ if(distort_) {
+ delete distort_;
+ delete distort_->offset;
+ distort_ = NULL;
+ }
+
+ if(undistort_) {
+ delete undistort_;
+ delete undistort_->offset;
+ undistort_ = NULL;
+ }
}
// FIXME: C++ templates limitations makes thing complicated, but maybe there is a simpler method.
@@ -211,11 +226,50 @@ struct InvertIntrinsicsFunction {
}
};
-void CameraIntrinsics::Distort(const float* src, float* dst, int width, int height, int channels) {
- if(!distort_) {
- distort_ = new Offset[width*height];
- ComputeLookupGrid<InvertIntrinsicsFunction>(distort_,width,height);
+void CameraIntrinsics::CheckDistortLookupGrid(int width, int height)
+{
+ if(distort_) {
+ if(distort_->width != width || distort_->height != height) {
+ delete [] distort_->offset;
+ distort_->offset = NULL;
+ }
+ } else {
+ distort_ = new Grid;
+ distort_->offset = NULL;
+ }
+
+ if(!distort_->offset) {
+ distort_->offset = new Offset[width*height];
+ ComputeLookupGrid<InvertIntrinsicsFunction>(distort_,width,height);
}
+
+ distort_->width = width;
+ distort_->height = height;
+}
+
+void CameraIntrinsics::CheckUndistortLookupGrid(int width, int height)
+{
+ if(undistort_) {
+ if(undistort_->width != width || undistort_->height != height) {
+ delete [] undistort_->offset;
+ undistort_->offset = NULL;
+ }
+ } else {
+ undistort_ = new Grid;
+ undistort_->offset = NULL;
+ }
+
+ if(!undistort_->offset) {
+ undistort_->offset = new Offset[width*height];
+ ComputeLookupGrid<ApplyIntrinsicsFunction>(undistort_,width,height);
+ }
+
+ undistort_->width = width;
+ undistort_->height = height;
+}
+
+void CameraIntrinsics::Distort(const float* src, float* dst, int width, int height, int channels) {
+ CheckDistortLookupGrid(width, height);
if(channels==1) Warp<float,1>(distort_,src,dst,width,height);
else if(channels==2) Warp<float,2>(distort_,src,dst,width,height);
else if(channels==3) Warp<float,3>(distort_,src,dst,width,height);
@@ -224,10 +278,7 @@ void CameraIntrinsics::Distort(const float* src, float* dst, int width, int heig
}
void CameraIntrinsics::Distort(const unsigned char* src, unsigned char* dst, int width, int height, int channels) {
- if(!distort_) {
- distort_ = new Offset[width*height];
- ComputeLookupGrid<InvertIntrinsicsFunction>(distort_,width,height);
- }
+ CheckDistortLookupGrid(width, height);
if(channels==1) Warp<unsigned char,1>(distort_,src,dst,width,height);
else if(channels==2) Warp<unsigned char,2>(distort_,src,dst,width,height);
else if(channels==3) Warp<unsigned char,3>(distort_,src,dst,width,height);
@@ -236,10 +287,7 @@ void CameraIntrinsics::Distort(const unsigned char* src, unsigned char* dst, int
}
void CameraIntrinsics::Undistort(const float* src, float* dst, int width, int height, int channels) {
- if(!undistort_) {
- undistort_ = new Offset[width*height];
- ComputeLookupGrid<ApplyIntrinsicsFunction>(undistort_,width,height);
- }
+ CheckUndistortLookupGrid(width, height);
if(channels==1) Warp<float,1>(undistort_,src,dst,width,height);
else if(channels==2) Warp<float,2>(undistort_,src,dst,width,height);
else if(channels==3) Warp<float,3>(undistort_,src,dst,width,height);
@@ -248,10 +296,7 @@ void CameraIntrinsics::Undistort(const float* src, float* dst, int width, int he
}
void CameraIntrinsics::Undistort(const unsigned char* src, unsigned char* dst, int width, int height, int channels) {
- if(!undistort_) {
- undistort_ = new Offset[width*height];
- ComputeLookupGrid<ApplyIntrinsicsFunction>(undistort_,width,height);
- }
+ CheckUndistortLookupGrid(width, height);
if(channels==1) Warp<unsigned char,1>(undistort_,src,dst,width,height);
else if(channels==2) Warp<unsigned char,2>(undistort_,src,dst,width,height);
else if(channels==3) Warp<unsigned char,3>(undistort_,src,dst,width,height);
diff --git a/src/libmv/simple_pipeline/camera_intrinsics.h b/src/libmv/simple_pipeline/camera_intrinsics.h
index 29bc8a1..99141c6 100644
--- a/src/libmv/simple_pipeline/camera_intrinsics.h
+++ b/src/libmv/simple_pipeline/camera_intrinsics.h
@@ -26,8 +26,6 @@ typedef Eigen::Matrix<double, 3, 3> Mat3;
namespace libmv {
-struct Offset;
-
class CameraIntrinsics {
public:
CameraIntrinsics();
@@ -123,7 +121,9 @@ class CameraIntrinsics {
int width, int height, int channels);
private:
- template<typename WarpFunction> void ComputeLookupGrid(Offset* grid, int width, int height);
+ template<typename WarpFunction> void ComputeLookupGrid(struct Grid* grid, int width, int height);
+ void CheckUndistortLookupGrid(int width, int height);
+ void CheckDistortLookupGrid(int width, int height);
void FreeLookupGrid();
// The traditional intrinsics matrix from x = K[R|t]X.
@@ -140,8 +140,8 @@ class CameraIntrinsics {
// independent of image size.
double k1_, k2_, k3_, p1_, p2_;
- Offset* distort_;
- Offset* undistort_;
+ struct Grid *distort_;
+ struct Grid *undistort_;
};
} // namespace libmv

View File

@@ -8,3 +8,4 @@ function_derivative.patch
high_distortion_crash_fix.patch
mingw.patch
msvc2010.patch
scaled_distortion.patch

View File

@@ -567,8 +567,7 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat);
#define CMP_NODE_MOVIECLIP 262
#define CMP_NODE_STABILIZE2D 263
#define CMP_NODE_TRANSFORM 264
#define CMP_NODE_MOVIEUNDISTORT 265
#define CMP_NODE_MOVIEDISTORT 266
#define CMP_NODE_MOVIEDISTORTION 265
#define CMP_NODE_GLARE 301
#define CMP_NODE_TONEMAP 302

View File

@@ -94,8 +94,8 @@ void BKE_tracking_stabilization_data(struct MovieTracking *tracking, int framenr
struct ImBuf *BKE_tracking_stabilize(struct MovieTracking *tracking, int framenr, struct ImBuf *ibuf, float loc[2], float *scale, float *angle);
void BKE_tracking_stabdata_to_mat4(int width, int height, float loc[2], float scale, float angle, float mat[4][4]);
struct ImBuf *BKE_tracking_undistort(struct MovieTracking *tracking, struct ImBuf *ibuf);
struct ImBuf *BKE_tracking_distort(struct MovieTracking *tracking, struct ImBuf *ibuf);
struct ImBuf *BKE_tracking_undistort(struct MovieTracking *tracking, struct ImBuf *ibuf, int width, int height);
struct ImBuf *BKE_tracking_distort(struct MovieTracking *tracking, struct ImBuf *ibuf, int width, int height);
#define TRACK_SELECTED(track) ((((track)->flag&TRACK_HIDDEN)==0) && ((track)->flag&SELECT || (track)->pat_flag&SELECT || (track)->search_flag&SELECT))
#define TRACK_AREA_SELECTED(track, area) ((((track)->flag&TRACK_HIDDEN)==0) && ((area)==TRACK_AREA_POINT?(track)->flag&SELECT : ((area)==TRACK_AREA_PAT?(track)->pat_flag&SELECT:(track)->search_flag&SELECT)))

View File

@@ -525,20 +525,13 @@ static ImBuf *get_undistorted_cache(MovieClip *clip, MovieClipUser *user)
static ImBuf *get_undistorted_ibuf(MovieClip *clip, ImBuf *ibuf)
{
ImBuf *aspectibuf= ibuf, *undistibuf;
float aspy= 1.f/clip->tracking.camera.pixel_aspect;
if(aspectibuf->y*aspy!=aspectibuf->y) {
/* XXX: not nice, but distortion coefficients were adjusted exactly for such aspect ratio */
aspectibuf= IMB_dupImBuf(aspectibuf);
IMB_scaleImBuf(aspectibuf, aspectibuf->x, aspectibuf->y*aspy);
}
ImBuf *undistibuf;
/* XXX: because of #27997 do not use float buffers to undistort,
otherwise, undistorted proxy can be darker than it should */
imb_freerectfloatImBuf(aspectibuf);
imb_freerectfloatImBuf(ibuf);
undistibuf= BKE_tracking_undistort(&clip->tracking, aspectibuf);
undistibuf= BKE_tracking_undistort(&clip->tracking, ibuf, ibuf->x, ibuf->y);
if(undistibuf->userflags|= IB_RECT_INVALID) {
ibuf->userflags&= ~IB_RECT_INVALID;
@@ -547,9 +540,6 @@ static ImBuf *get_undistorted_ibuf(MovieClip *clip, ImBuf *ibuf)
IMB_scaleImBuf(undistibuf, ibuf->x, ibuf->y);
if(aspectibuf!=ibuf)
IMB_freeImBuf(aspectibuf);
return undistibuf;
}

View File

@@ -1849,8 +1849,7 @@ static void registerCompositNodes(ListBase *ntypelist)
register_node_type_cmp_lensdist(ntypelist);
register_node_type_cmp_transform(ntypelist);
register_node_type_cmp_stabilize2d(ntypelist);
register_node_type_cmp_moviedistort(ntypelist);
register_node_type_cmp_movieundistort(ntypelist);
register_node_type_cmp_moviedistortion(ntypelist);
}
static void registerShaderNodes(ListBase *ntypelist)

View File

@@ -1897,7 +1897,7 @@ void BKE_tracking_stabdata_to_mat4(int width, int height, float loc[2], float sc
mul_serie_m4(mat, lmat, smat, cmat, rmat, icmat, NULL, NULL, NULL);
}
ImBuf *BKE_tracking_undistort(MovieTracking *tracking, ImBuf *ibuf)
ImBuf *BKE_tracking_undistort(MovieTracking *tracking, ImBuf *ibuf, int width, int height)
{
ImBuf *resibuf;
MovieTrackingCamera *camera= &tracking->camera;
@@ -1909,11 +1909,11 @@ ImBuf *BKE_tracking_undistort(MovieTracking *tracking, ImBuf *ibuf)
if(camera->intrinsics == NULL) {
camera->intrinsics= libmv_CameraIntrinsicsNew(camera->focal,
camera->principal[0], camera->principal[1] * aspy,
camera->k1, camera->k2, camera->k3);
camera->k1, camera->k2, camera->k3, width, height * aspy);
} else {
libmv_CameraIntrinsicsUpdate(camera->intrinsics, camera->focal,
camera->principal[0], camera->principal[1] * aspy,
camera->k1, camera->k2, camera->k3);
camera->k1, camera->k2, camera->k3, width, height * aspy);
}
#endif
@@ -1936,7 +1936,7 @@ ImBuf *BKE_tracking_undistort(MovieTracking *tracking, ImBuf *ibuf)
return resibuf;
}
ImBuf *BKE_tracking_distort(MovieTracking *tracking, ImBuf *ibuf)
ImBuf *BKE_tracking_distort(MovieTracking *tracking, ImBuf *ibuf, int width, int height)
{
ImBuf *resibuf;
MovieTrackingCamera *camera= &tracking->camera;
@@ -1948,11 +1948,11 @@ ImBuf *BKE_tracking_distort(MovieTracking *tracking, ImBuf *ibuf)
if(camera->intrinsics == NULL) {
camera->intrinsics= libmv_CameraIntrinsicsNew(camera->focal,
camera->principal[0], camera->principal[1] * aspy,
camera->k1, camera->k2, camera->k3);
camera->k1, camera->k2, camera->k3, width, height * aspy);
} else {
libmv_CameraIntrinsicsUpdate(camera->intrinsics, camera->focal,
camera->principal[0], camera->principal[1] * aspy,
camera->k1, camera->k2, camera->k3);
camera->k1, camera->k2, camera->k3, width, height * aspy);
}
#endif

View File

@@ -1697,15 +1697,16 @@ static void node_composit_buts_transform(uiLayout *layout, bContext *UNUSED(C),
uiItemR(layout, ptr, "filter_type", 0, "", 0);
}
static void node_composit_buts_movieundistort(uiLayout *layout, bContext *C, PointerRNA *ptr)
static void node_composit_buts_moviedistortion(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
bNode *node= ptr->data;
uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL);
}
if(!node->id)
return;
static void node_composit_buts_moviedistort(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL);
uiItemR(layout, ptr, "distortion_type", 0, "", 0);
}
/* only once called */
@@ -1867,11 +1868,8 @@ static void node_composit_set_butfunc(bNodeType *ntype)
case CMP_NODE_TRANSFORM:
ntype->uifunc= node_composit_buts_transform;
break;
case CMP_NODE_MOVIEUNDISTORT:
ntype->uifunc= node_composit_buts_movieundistort;
break;
case CMP_NODE_MOVIEDISTORT:
ntype->uifunc= node_composit_buts_moviedistort;
case CMP_NODE_MOVIEDISTORTION:
ntype->uifunc= node_composit_buts_moviedistortion;
break;
default:
ntype->uifunc= NULL;

View File

@@ -2447,27 +2447,26 @@ static void def_cmp_stabilize2d(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
}
static void def_cmp_movieundistort(StructRNA *srna)
static void def_cmp_moviedistortion(StructRNA *srna)
{
PropertyRNA *prop;
static EnumPropertyItem distortion_type_items[] = {
{0, "UNDISTORT", 0, "Undistort", ""},
{1, "DISTORT", 0, "Distort", ""},
{0, NULL, 0, NULL, NULL}};
prop = RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "id");
RNA_def_property_struct_type(prop, "MovieClip");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Movie Clip", "");
RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
}
static void def_cmp_moviedistort(StructRNA *srna)
{
PropertyRNA *prop;
prop = RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "id");
RNA_def_property_struct_type(prop, "MovieClip");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Movie Clip", "");
prop = RNA_def_property(srna, "distortion_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, distortion_type_items);
RNA_def_property_ui_text(prop, "Distortion", "Distoriton to use to filter image");
RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
}

View File

@@ -122,8 +122,7 @@ DefNode( CompositorNode, CMP_NODE_HUECORRECT, def_cmp_huecorrect, "HUECO
DefNode( CompositorNode, CMP_NODE_MOVIECLIP, def_cmp_movieclip, "MOVIECLIP", MovieClip, "MovieClip", "" )
DefNode( CompositorNode, CMP_NODE_TRANSFORM, dev_cmd_transform, "TRANSFORM", Transform, "Transform", "" )
DefNode( CompositorNode, CMP_NODE_STABILIZE2D, def_cmp_stabilize2d, "STABILIZE2D", Stabilize, "Stabelize 2D", "" )
DefNode( CompositorNode, CMP_NODE_MOVIEDISTORT, def_cmp_moviedistort, "MOVIEDISTORT", MovieDistort, "Movie Distort", "" )
DefNode( CompositorNode, CMP_NODE_MOVIEUNDISTORT, def_cmp_movieundistort, "MOVIEUNDISTORT", MovieUndistort, "Movie Undistort", "" )
DefNode( CompositorNode, CMP_NODE_MOVIEDISTORTION,def_cmp_moviedistortion,"MOVIEDISTORTION",MovieDistortion, "Movie Distortion", "" )
DefNode( TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" )
DefNode( TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" )

View File

@@ -81,8 +81,7 @@ set(SRC
composite/nodes/node_composite_math.c
composite/nodes/node_composite_mixrgb.c
composite/nodes/node_composite_movieclip.c
composite/nodes/node_composite_moviedistort.c
composite/nodes/node_composite_movieundistort.c
composite/nodes/node_composite_moviedistortion.c
composite/nodes/node_composite_normal.c
composite/nodes/node_composite_normalize.c
composite/nodes/node_composite_outputFile.c

View File

@@ -118,8 +118,7 @@ void register_node_type_cmp_displace(ListBase *lb);
void register_node_type_cmp_mapuv(ListBase *lb);
void register_node_type_cmp_transform(ListBase *lb);
void register_node_type_cmp_stabilize2d(ListBase *lb);
void register_node_type_cmp_moviedistort(ListBase *lb);
void register_node_type_cmp_movieundistort(ListBase *lb);
void register_node_type_cmp_moviedistortion(ListBase *lb);
void register_node_type_cmp_glare(ListBase *lb);
void register_node_type_cmp_tonemap(ListBase *lb);

View File

@@ -158,8 +158,13 @@ static void node_composit_exec_movieclip(void *data, bNode *node, bNodeStack **U
static void init(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
MovieClipUser *user= MEM_callocN(sizeof(MovieClipUser), "node movie clip user");
node->storage= user;
user->framenr= 1;
if(G.main->movieclip.first == G.main->movieclip.last) {
node->id= G.main->movieclip.first;
}
}
void register_node_type_cmp_movieclip(ListBase *lb)

View File

@@ -1,117 +0,0 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2006 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Blender Foundation,
* Sergey Sharybin
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/nodes/composite/nodes/node_composite_moviedistort.c
* \ingroup cmpnodes
*/
#include "node_composite_util.h"
/* **************** Translate ******************** */
static bNodeSocketTemplate cmp_node_moviedistort_in[]= {
{ SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
static bNodeSocketTemplate cmp_node_moviedistort_out[]= {
{ SOCK_RGBA, 0, "Image"},
{ -1, 0, "" }
};
static void node_composit_exec_moviedistort(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
if(in[0]->data && node->id) {
MovieClip *clip= (MovieClip *)node->id;
CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 0);
ImBuf *ibuf;
ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
if(ibuf) {
ImBuf *obuf;
MovieClipUser *user= (MovieClipUser *)node->storage;
float aspy= 1.f/clip->tracking.camera.pixel_aspect;
int scaled= 0, width, height;
ibuf->rect_float= cbuf->rect;
BKE_movieclip_acquire_size(clip, user, &width, &height);
height*= aspy;
if(ibuf->x!=width || ibuf->y!=height) {
/* TODO: not sure this is really needed, but distortion coefficients are
calculated using camera resolution, so if image with other resolution
is passed to distortion node, it'll be distorted correct (but quality can hurt)
This is also needed to deal when camera pixel aspect isn't 1. Problems in this case
are caused because of how aspect x/y are calculating. Currently. projeciton
matrices and reconstruction stuff are supposing that aspect x is always 1 and
aspect y is less than 1 (if x resolution is larger than y resolution) */
IMB_scaleImBuf(ibuf, width, height);
scaled= 1;
}
obuf= BKE_tracking_distort(&clip->tracking, ibuf);
if(scaled)
IMB_scaleImBuf(obuf, cbuf->x, cbuf->y);
stackbuf->rect= obuf->rect_float;
stackbuf->malloc= 1;
obuf->mall&= ~IB_rectfloat;
obuf->rect_float= NULL;
IMB_freeImBuf(ibuf);
IMB_freeImBuf(obuf);
}
/* pass on output and free */
out[0]->data= stackbuf;
if(cbuf!=in[0]->data)
free_compbuf(cbuf);
}
}
void register_node_type_cmp_moviedistort(ListBase *lb)
{
static bNodeType ntype;
node_type_base(&ntype, CMP_NODE_MOVIEDISTORT, "Movie Distort", NODE_CLASS_DISTORT, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_moviedistort_in, cmp_node_moviedistort_out);
node_type_size(&ntype, 140, 100, 320);
node_type_exec(&ntype, node_composit_exec_moviedistort);
nodeRegisterType(lb, &ntype);
}

View File

@@ -0,0 +1,126 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2006 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Blender Foundation,
* Sergey Sharybin
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/nodes/composite/nodes/node_composite_moviedistortion.c
* \ingroup cmpnodes
*/
#include "node_composite_util.h"
/* **************** Translate ******************** */
static bNodeSocketTemplate cmp_node_moviedistortion_in[]= {
{ SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
static bNodeSocketTemplate cmp_node_moviedistortion_out[]= {
{ SOCK_RGBA, 0, "Image"},
{ -1, 0, "" }
};
static void exec(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
if(in[0]->data) {
if(node->id) {
MovieClip *clip= (MovieClip *)node->id;
CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 0);
ImBuf *ibuf;
ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
if(ibuf) {
ImBuf *obuf;
MovieClipUser *user= (MovieClipUser *)node->storage;
int width, height;
ibuf->rect_float= cbuf->rect;
BKE_movieclip_acquire_size(clip, user, &width, &height);
if(node->custom1==0)
obuf= BKE_tracking_undistort(&clip->tracking, ibuf, width, height);
else
obuf= BKE_tracking_distort(&clip->tracking, ibuf, width, height);
stackbuf->rect= obuf->rect_float;
stackbuf->malloc= 1;
obuf->mall&= ~IB_rectfloat;
obuf->rect_float= NULL;
IMB_freeImBuf(ibuf);
IMB_freeImBuf(obuf);
}
/* pass on output and free */
out[0]->data= stackbuf;
if(cbuf!=in[0]->data)
free_compbuf(cbuf);
} else {
CompBuf *cbuf= in[0]->data;
CompBuf *stackbuf= pass_on_compbuf(cbuf);
out[0]->data= stackbuf;
}
}
}
static void init(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
if(G.main->movieclip.first == G.main->movieclip.last) {
node->id= G.main->movieclip.first;
}
}
static const char *label(bNode *node)
{
if(node->custom1==0)
return "Undistortion";
else
return "Distortion";
}
void register_node_type_cmp_moviedistortion(ListBase *lb)
{
static bNodeType ntype;
node_type_base(&ntype, CMP_NODE_MOVIEDISTORTION, "Movie Distortion", NODE_CLASS_DISTORT, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_moviedistortion_in, cmp_node_moviedistortion_out);
node_type_size(&ntype, 140, 100, 320);
node_type_init(&ntype, init);
node_type_label(&ntype, label);
node_type_exec(&ntype, exec);
nodeRegisterType(lb, &ntype);
}

View File

@@ -1,117 +0,0 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2006 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Blender Foundation,
* Sergey Sharybin
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/nodes/composite/nodes/node_composite_movieundistort.c
* \ingroup cmpnodes
*/
#include "node_composite_util.h"
/* **************** Translate ******************** */
static bNodeSocketTemplate cmp_node_movieundistort_in[]= {
{ SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
static bNodeSocketTemplate cmp_node_movieundistort_out[]= {
{ SOCK_RGBA, 0, "Image"},
{ -1, 0, "" }
};
static void node_composit_exec_movieundistort(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
if(in[0]->data && node->id) {
MovieClip *clip= (MovieClip *)node->id;
CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 0);
ImBuf *ibuf;
ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
if(ibuf) {
ImBuf *obuf;
MovieClipUser *user= (MovieClipUser *)node->storage;
float aspy= 1.f/clip->tracking.camera.pixel_aspect;
int scaled= 0, width, height;
ibuf->rect_float= cbuf->rect;
BKE_movieclip_acquire_size(clip, user, &width, &height);
height*= aspy;
if(ibuf->x!=width || ibuf->y!=height) {
/* TODO: not sure this is really needed, but distortion coefficients are
calculated using camera resolution, so if image with other resolution
is passed to undistortion node, it'll be undistorted correct (but quality can hurt)
This is also needed to deal when camera pixel aspect isn't 1. Problems in this case
are caused because of how aspect x/y are calculating. Currently. projeciton
matrices and reconstruction stuff are supposing that aspect x is always 1 and
aspect y is less than 1 (if x resolution is larger than y resolution) */
IMB_scaleImBuf(ibuf, width, height);
scaled= 1;
}
obuf= BKE_tracking_undistort(&clip->tracking, ibuf);
if(scaled)
IMB_scaleImBuf(obuf, cbuf->x, cbuf->y);
stackbuf->rect= obuf->rect_float;
stackbuf->malloc= 1;
obuf->mall&= ~IB_rectfloat;
obuf->rect_float= NULL;
IMB_freeImBuf(ibuf);
IMB_freeImBuf(obuf);
}
/* pass on output and free */
out[0]->data= stackbuf;
if(cbuf!=in[0]->data)
free_compbuf(cbuf);
}
}
void register_node_type_cmp_movieundistort(ListBase *lb)
{
static bNodeType ntype;
node_type_base(&ntype, CMP_NODE_MOVIEUNDISTORT, "Movie Undistort", NODE_CLASS_DISTORT, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_movieundistort_in, cmp_node_movieundistort_out);
node_type_size(&ntype, 140, 100, 320);
node_type_exec(&ntype, node_composit_exec_movieundistort);
nodeRegisterType(lb, &ntype);
}