dkogan / mrcal

Next-generation camera-modeling toolkit
http://mrcal.secretsauce.net
Apache License 2.0
179 stars 14 forks source link

I have a question about cv.undistPoints and cv.remap. #5

Closed VasilevIvanVladimirovich closed 1 year ago

VasilevIvanVladimirovich commented 1 year ago

Hi @dkogan I'm interested in doing an experiment with the camera model: LENSMODEL_SPLINED_STEREOGRAPHIC. I want to see how this model will show itself during the operation of my device.

My application uses the undistPoints function, thanks to which I get the opportunity to create a map of a new undistorted position for each pixel. This allows me to quickly transform at arbitrary points without affecting the entire image.

Using this code, I get an analog of the cv.initUndistortRectifeMap function, and then to get the undistortImage, the cv.remap function is used, which performs the inverse transformation + interpolation. m = mrcal.cameramodel('imgPath') model_pinhole = mrcal.pinhole_model_for_reprojection(m,fit="corners") mapxy = mral.image_transformation_map(m,model_pinhole )

I need to get a transformation map for each pixel so that I can quickly know the new location of the undistorted pixel by index. Blue color - cv.UndistPoint() (opencvModel) Green - mrcal.image_transformation_map() (slined model)

2022-12-15_11-58-55

How can i do this ?

dkogan commented 1 year ago

Hi. I don't understand what you're asking. I think you used the code snippet above to visualize

Or you just want a function to map pixel(s) from one model to the other? Assuming extrinsics are identical:

p    = mrcal.unproject(q_from, *model_from.intrinsics())
q_to = mrcal.project(p, *model_to.intrinsics())

If the two models came from two different calibrations, then you have an implied extrinsics difference to take care of. You need this function: http://mrcal.secretsauce.net/mrcal-python-api-reference.html#-implied_Rt10__from_unprojections

VasilevIvanVladimirovich commented 1 year ago

Hello @dkogan I apologize for the poorly worded question.

When the mrcal.image_transformation_map() function is used, I get a reverse map. I can use this map further in the cv.remap() function to get an undistorted image. I need to get a undistorted for the point (cv.remap() works on the whole image). When I display the map mrcal.image_transformation_map(), there is a reverse distortion, different from cv.undistortPoint(). I demonstrated this in the color picture above, where green is cv.undistPoint, blue is mrcal.image_transformation_map()

When I try to translate the coordinate of a point using the map mrcatl.image_transformation_map(), I get even more distortion (Example of translating all points):

UndistReverse

My question is, is there an analogue of the function see cv.undistortPoint(), or is there some other way to get a undistort for a point ?

dkogan commented 1 year ago

Hi. These functions all map projections from one model to the other. The snippet from the previous message is what you want to do:

p    = mrcal.unproject(q_from, *model_from.intrinsics())
q_to = mrcal.project(p, *model_to.intrinsics())

This tells you the pixel q_to corresponding to the pixel q_from in the original model. Set the to/from to whatever models you need. These functions all broadcast, so you can handle many q_from at the same time. You can also use the mrcal-reproject-points commandline tool if you don't want to write any code.

VasilevIvanVladimirovich commented 1 year ago

Hi! Thanks for the reply. 👍 I applied the code above and really got the points I needed :D

I have a question, why do I get negative coordinates of points in cv.undistortPoint() and in the case of mrcal-reproject-point I got all positive coordinates?

Wow

dkogan commented 1 year ago

If you're giving them the same models and the same data, you should get the same result. Show me the data and code, if you want me to look at it. ALSO, FYI if you're reprojecting images instead of discrete points, the mrcal-reproject-image tool will do all that for you.

VasilevIvanVladimirovich commented 1 year ago

I was a little confused when I didn't see any negative coordinates. Having tried to do the same, but with a different model, I found the presence of negative coordinates.

Thank you for your help in my question.