forked from bartvdbraak/blender
262 lines
9.0 KiB
Diff
262 lines
9.0 KiB
Diff
|
diff --git a/src/libmv/simple_pipeline/camera_intrinsics.cc b/src/libmv/simple_pipeline/camera_intrinsics.cc
|
||
|
index f9888ff..110a16d 100644
|
||
|
--- a/src/libmv/simple_pipeline/camera_intrinsics.cc
|
||
|
+++ b/src/libmv/simple_pipeline/camera_intrinsics.cc
|
||
|
@@ -23,7 +23,32 @@
|
||
|
|
||
|
namespace libmv {
|
||
|
|
||
|
-struct Offset { signed char ix,iy; unsigned char fx,fy; };
|
||
|
+struct Offset {
|
||
|
+ signed char ix, iy;
|
||
|
+ unsigned char fx,fy;
|
||
|
+};
|
||
|
+
|
||
|
+struct Grid {
|
||
|
+ struct Offset *offset;
|
||
|
+ int width, height;
|
||
|
+};
|
||
|
+
|
||
|
+static struct Grid *copyGrid(struct Grid *from)
|
||
|
+{
|
||
|
+ struct Grid *to = NULL;
|
||
|
+
|
||
|
+ if (from) {
|
||
|
+ to = new Grid;
|
||
|
+
|
||
|
+ to->width = from->width;
|
||
|
+ to->height = from->height;
|
||
|
+
|
||
|
+ to->offset = new Offset[to->width*to->height];
|
||
|
+ memcpy(to->offset, from->offset, sizeof(struct Offset)*to->width*to->height);
|
||
|
+ }
|
||
|
+
|
||
|
+ return to;
|
||
|
+}
|
||
|
|
||
|
CameraIntrinsics::CameraIntrinsics()
|
||
|
: K_(Mat3::Identity()),
|
||
|
@@ -37,9 +62,22 @@ CameraIntrinsics::CameraIntrinsics()
|
||
|
distort_(0),
|
||
|
undistort_(0) {}
|
||
|
|
||
|
+CameraIntrinsics::CameraIntrinsics(const CameraIntrinsics &from)
|
||
|
+ : K_(from.K_),
|
||
|
+ image_width_(from.image_width_),
|
||
|
+ image_height_(from.image_height_),
|
||
|
+ k1_(from.k1_),
|
||
|
+ k2_(from.k2_),
|
||
|
+ k3_(from.k3_),
|
||
|
+ p1_(from.p1_),
|
||
|
+ p2_(from.p2_)
|
||
|
+{
|
||
|
+ distort_ = copyGrid(from.distort_);
|
||
|
+ undistort_ = copyGrid(from.undistort_);
|
||
|
+}
|
||
|
+
|
||
|
CameraIntrinsics::~CameraIntrinsics() {
|
||
|
- if(distort_) delete[] distort_;
|
||
|
- if(undistort_) delete[] undistort_;
|
||
|
+ FreeLookupGrid();
|
||
|
}
|
||
|
|
||
|
/// Set the entire calibration matrix at once.
|
||
|
@@ -146,11 +184,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 = warp_x*aspx;
|
||
|
+ warp_y = 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 +206,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 +217,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 +232,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_->offset;
|
||
|
+ delete distort_;
|
||
|
+ distort_ = NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ if(undistort_) {
|
||
|
+ delete undistort_->offset;
|
||
|
+ delete undistort_;
|
||
|
+ undistort_ = NULL;
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
// FIXME: C++ templates limitations makes thing complicated, but maybe there is a simpler method.
|
||
|
@@ -211,11 +264,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 +316,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 +325,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 +334,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..f525571 100644
|
||
|
--- a/src/libmv/simple_pipeline/camera_intrinsics.h
|
||
|
+++ b/src/libmv/simple_pipeline/camera_intrinsics.h
|
||
|
@@ -26,11 +26,12 @@ typedef Eigen::Matrix<double, 3, 3> Mat3;
|
||
|
|
||
|
namespace libmv {
|
||
|
|
||
|
-struct Offset;
|
||
|
+struct Grid;
|
||
|
|
||
|
class CameraIntrinsics {
|
||
|
public:
|
||
|
CameraIntrinsics();
|
||
|
+ CameraIntrinsics(const CameraIntrinsics &from);
|
||
|
~CameraIntrinsics();
|
||
|
|
||
|
const Mat3 &K() const { return K_; }
|
||
|
@@ -123,7 +124,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 +143,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
|