# Correct image for distortion by external lens

**URL:** <https://forum.opencv.org/t/correct-image-for-distortion-by-external-lens/5301>\
**Category:** Python\
**Tags:** calib3d, practical, cg, optics\
**Created:** [September 21, 2021, 12:11am UTC](https://forum.opencv.org/t/correct-image-for-distortion-by-external-lens/5301 "2021-09-21T00:11:51Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Oryx](https://avatars.discourse-cdn.com/v4/letter/o/ee59a6/32.png) [@Oryx](https://forum.opencv.org/u/Oryx)\
**Post date:** [September 21, 2021, 12:11am UTC](https://forum.opencv.org/t/correct-image-for-distortion-by-external-lens/5301/1 "2021-09-21T00:11:51Z")

</div>

Hi All

I am capturing images of an object inside an acrylic cylinder filled with oil (simple plan view sketch below). Due to the refractive index mismatch the cylinder acts as a lens and distorts my images horizontally.

 ![Picture1](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/b/b7472674e7a3c4b407ab1089c7beedaa20d15ece.png)

My setup is in a controlled environment so I can define the position of the camera, cylinder and object fairly accurately. Consequently, I can calculate the distorted (_a_) and undistorted (_a’_) image point for a given point _A_ on the object using ray tracing. Currently I am using [findHomography](https://docs.opencv.org/master/d9/d0c/group__calib3d.html#ga4abc2ece9fab9398f2e560d53c8c9780) to calculate a homography matrix from the distorted (_a_) and undistorted (_a’_) points. I then use this matrix and [warpPerspective](https://docs.opencv.org/master/da/d54/group__imgproc__transform.html#gaf73673a7e8e18ec6963e3774e6a94b87) to correct for the distortion.

Is this the most efficient way to do it? Or should I be looking at something in the line of `calibrateCamera`? If so, how should I go about it as I only have one set of points on the image and object planes.

Thanks!

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [September 21, 2021, 12:59am UTC](https://forum.opencv.org/t/correct-image-for-distortion-by-external-lens/5301/2 "2021-09-21T00:59:19Z")

</div>

I doubt homographies can model this type of distortion. homographies are for plane-to-plane projections. this however involves all kinds of trigonometry.

something like `calibrateCamera` might be needed. ordinarily, distortion for lenses is modeled as a polynomial over the radius, and then used to correct the picture (“undistortion”, maybe using `cv::remap`). you might need something along those lines.

you said you can raytrace this. that’s good for exploring the situation.

I’ll assume that you care about the _surface_ of the solid black cylinder.

assuming you have enough control over the ray tracing, remove all lighting and media effects, and apply to the cylinder a dummy “texture” with given (u,v) coordinates (or equivalent mechanism), and have that mapped to your image plane.

you might need the inverse of that, i.e. given coordinates on the cylinder, where on the image plane that point is mapped to, so you can map an actual image back to the cylinder.

thanks to the lens effect of the oil cylinder, I guess this will introduce blur… or not, if you stick with _simple_ raytracing. I don’t have a good grasp of the situation.

---

<div class="post-metadata">

**Author:** ![Oryx](https://avatars.discourse-cdn.com/v4/letter/o/ee59a6/32.png) [@Oryx](https://forum.opencv.org/u/Oryx)\
**Post date:** [September 26, 2021, 4:24am UTC](https://forum.opencv.org/t/correct-image-for-distortion-by-external-lens/5301/3 "2021-09-26T04:24:02Z")

</div>

Thanks for the suggestions! As a check I used the homography matrix to back-calculate the calibration points, and the error was quite significant.

I made a mistake in the sketch, I am actually taking a photo of a section through the cylinder. This section is perpendicular to the camera. It seems that the best solution for me is to use the simple (analytical) raytracing to find the distorted and undistorted image points for a grid over the section. Then I will fit a polynomial to these points and use the fitted surface to populate `cv::remap` as you suggested.
