My goal is to take a series of night-sky photographs and stack them. To do this, I need to un-distort my images. I've located the stars in the image, so I need to run each star through
stars.forEach { star ->
val (realLocationX, realLocationY) = magicUnDistortFunction( star.x, star.y, magicDistortionConstant1,... )
}
Which means I'm searching for magicUnDistortFunction(), and then I can try a few million values for the magicDistortionConstant until things match, and then I will have my camera lens "calibrated" and re-use those constants next time. (Hopefully I can avoid needing magicDistortionConstant2, 3, 4, etc.)
I've found some code snippets to un-distort photographs, but all are quite complex, and I'm not sure why.
But... these all seem quite complex, and require knowing about how to factor a third-order polynomial to go from a regular captured photo to an undistorted model. I'll admit - I don't get why a simplified model doesn't work "close enough". Or maybe I haven't found the right code snippet yet.
For most distortion, the center of the image is "ok", then gets warped as you move towards the edge.
As you move from the center of the image to the right along the x axis:
x= your pixel's location
y= the actual star location
then
blue line is a perfect "your pixels = reality 1:1 correspondence, no distortion to be corrected"
red line is "your pixels = farther from reality as you move towards the edge"
![]()
And because it isn't a perfectly square camera, maybe a third line for moving along the Y axis, but it would be nice if it was a similar line, and even nicer if you could figure out the offset for any location using the same formula.
So... I think I need that formula.
rSrc = (a * rDest^3 + b * rDest^2 + c * rDest + d) * rDest
which is rSrc and rDest? rSrc is the source image... the reality version? Great, so I don't need to invert the function. But that has 4 constants.
Option 2: Rd = k1 * Ru^3 + (1 - k1) * Ru
I really hope Rd == rSrc, or else I have to invert the function...
And then I found that this only works if you "normalize" the coordinates, where radius = the biggest possible circle inside the photo along the shortest dimension. ack.