2

Here is my question: My optical system is made of a camera plus a circular plexiglass "lens" that changes its curvature depending on pressure (radial bending).

This curvature induces a deformation of the image captured by the camera. To correct this deformation, images need to be calibrated. Calibration can be made with a grid (chessboard, dots, lines), pressure range has to be discretized with a certain step. For each pressure step, an image of the grid has to be taken. Then each image has to be compared to the reference one (P=0), and a transformation matrix has to be computed and stored. Finally, each image taken during the experiment for a specific pressure has to be corrected by the transformation matrix.

The deformation is non-linear (not only a combination of rotations and translations), but most likely Barrel distortion. (again not induced by the camera) Which looks like that: http://en.wikipedia.org/wiki/Distortion_%28optics%29#mediaviewer/File:Barrel_distortion.svg

I found a plugin in ImageJ called BunwarpJ, http://biocomp.cnb.csic.es/~iarganda/bUnwarpJ/

and I basically want to know if there is an equivalent way to produce the same result in Opencv. (CalibrateCamera won't do the trick)

mugenop
  • 23
  • 6

2 Answers2

2

OpenCv has an undistort function that can take a current image, a matrix of camera coefficients, distorsion coeffs. and produces a new image corrected for sent camera coeffs. and a new set of camera coeffs. (if you need to do other transformations on the new image).

I have not used it before, so I can't say what exactly are camera or distorsion coefficients are but as manual describes:

The function transforms an image to compensate radial and tangential lens distortion. The function is simply a combination of initUndistortRectifyMap() (with unity R ) and remap() (with bilinear interpolation).

So checking those two funcs. out are a good way to find out.

I believe you misunderstood the manual perhaps because you seem to think that CalibrateCamera does this for you. Instead CalibrateCamera actually returns the camera and distorsion coeffs. which you need to undistort your image.

Each lens has its own constant coeffs. which in your case means that you'll have to calibrateCamera for a range of pressures (I assume you control that experimentally?) and then call different undistort func. with different parameters which you'll get out of your experiments.

ljetibo
  • 3,048
  • 19
  • 25
  • thank you @ljetibo for your answer, I understood perfectly how cameracalibrate and undistort work. but in terms of time, it's a huge investment (taking several images for each pressure step), since I already have an alternative solution (bUnwarp) on imageJ which works as pixel based registration approach (combined with feature based approach), I will be using it. – mugenop Feb 28 '15 at 22:02
  • @MugenOp It's sometimes hard to guess the knowledge of OP especially when user is still new. Sorry if that made you uncomfortable. Programing in computer vision usually does take a lot of time, and can be very hard. But if you want results to **exactly** behave by your rules is still the only option to go. However I'd probably also use BUnwrapJ. ImageJ is open source and has an [API](http://imagej.nih.gov/ij/plugins/jython/index.html), it might perhaps pay off to dig around there to gain access to the unwrap functionality? – ljetibo Feb 28 '15 at 22:10
0

A matrix can only capture a linear transformation (or possibly a linear transformation in homogeneous space), not a general distortion.

In my experience any attempt to use a single global transformation formula wouldn't be very accurate (it's not trivial to get just 99.9% accuracy). Even just correcting camera lens distortion this way is difficult if you want high accuracy.

In the past I got good enough results using a sparse global RBF interpolation, but later I moved to an interpolating 2d spline approach; if you can choose your calibration points to be on a regular grid this is the solution I would suggest.

In the end the mapping could be a 2-valued 3d interpolating spline on a regular grid (XY for the image, Z for the pressure; values UV are the pixel coordinates).

Straightening the image once pressure is known is just texture mapping.

6502
  • 112,025
  • 15
  • 165
  • 265