Opencv: distort back

后端 未结 7 689
清歌不尽
清歌不尽 2021-02-02 02:53

I have the cameraMatrix and the distCoeff needed to undistort an image or a vector of points. Now I\'d like to distort them back.

Is it poss

7条回答
  •  余生分开走
    2021-02-02 03:00

    There is no analytical solution to this problem once you distort the coordinates there is no way going back at least analytically with this specific model. It is in nature of radial distortion model, the way it is defined allows to distort in simple analytical fashion but not vice versa. In order to do so one has to solve 7-th degree polynomial for which it is proven that there is no analytical solution.

    However the radial camera model is not special or sacred in any way it just simple rule that stretches the pixels outwards or inwards to optical center depending on lens you taken your picture with. The closer to optical center the less distortion pixel receives. There is multitude of other ways to define radial distortion model which could yield not only similar quality of distortion but also provide simple way to define the inverse of distortion. But going this way means that you would need to find optimal parameters for such model yourself.

    For instance in my specific case I've found that a simple sigmoid function (offset and scaled) is capable to approximating my existing radial model parameters with MSE integral error less than or equal to 1E-06 even though the comparison between model seems pointles. I don't think that native radial model yields better values and must not be treated as etalon one. Physical lens geometry may vary in a way that is not representable by both models and to better approximate lens geometry a mesh-like approach should be used. However I'm impressed by approximated model because it uses only one free parameter and provides notably accurate result which makes me think which model is actually better for the job.

    Here's the plot of original radial model (red) and it's sigmoid approximation (green) on top and also their derivatives (blue lines):

    So distortion / undistortion function in my case looked like this:

    distort = (r, alpha) -> 2/(1 + exp(-alpha*r)) - 1
    undistort = (d, alpha) -> -ln((d + 1)/(d - 1))/alpha
    

    (Please note that distortion is performed in polar coordinates around optical center and affects only distance from optical center (i.e. not the angle itself), r - distance from optical center, alpha is a free parameter that needs to be estimated):

    Here's how the distortion looked compared to native radial distortion (green is approximated, red is native radial distortion)

    And here's how the inverse mapping of pixels looks like if we were to take a regular pixel grid and try to undistort it:

提交回复
热议问题