Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2011-09-28 17:31:32 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2011-09-28 17:31:32 +0400
commita36dd050ede226dea2e0960d09228ad5bb0c2f49 (patch)
treedaacf9898342ca1dc0f5be7788e9213de98c28d1 /extern/libmv
parent3323a368619f29c0c5ab554e56d96530088d83b2 (diff)
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/
Diffstat (limited to 'extern/libmv')
-rw-r--r--extern/libmv/libmv-capi.cpp21
-rw-r--r--extern/libmv/libmv-capi.h4
-rw-r--r--extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc97
-rw-r--r--extern/libmv/libmv/simple_pipeline/camera_intrinsics.h10
-rw-r--r--extern/libmv/patches/scaled_distortion.patch215
-rw-r--r--extern/libmv/patches/series1
6 files changed, 300 insertions, 48 deletions
diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp
index 4c6c8824c31..11c77deceba 100644
--- a/extern/libmv/libmv-capi.cpp
+++ b/extern/libmv/libmv-capi.cpp
@@ -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);
}
diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h
index 39e1a986dcf..137759bc347 100644
--- a/extern/libmv/libmv-capi.h
+++ b/extern/libmv/libmv-capi.h
@@ -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);
diff --git a/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc
index f9888ff3ae6..e1e6117e2e2 100644
--- a/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc
+++ b/extern/libmv/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/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h
index 29bc8a1cea4..99141c61bfc 100644
--- a/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h
+++ b/extern/libmv/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
diff --git a/extern/libmv/patches/scaled_distortion.patch b/extern/libmv/patches/scaled_distortion.patch
new file mode 100644
index 00000000000..5088c6725c9
--- /dev/null
+++ b/extern/libmv/patches/scaled_distortion.patch
@@ -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
diff --git a/extern/libmv/patches/series b/extern/libmv/patches/series
index 9e4f8c15bd5..8f785a659cf 100644
--- a/extern/libmv/patches/series
+++ b/extern/libmv/patches/series
@@ -8,3 +8,4 @@ function_derivative.patch
high_distortion_crash_fix.patch
mingw.patch
msvc2010.patch
+scaled_distortion.patch