Search code examples
pythonopencvimage-processingimagej

Image registration b-spline opencv


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)


Solution

  • 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.