1 | initial version |
This is a supplementary answer in addition to R.Saracchini's answer.
As usual, there are benefits and drawbacks for using OpenCV for a certain task. This comment is trivially true for basically any tool at your disposal. If ImageMagick is a much easier route for your purpose, then by all means use the best handy tool you have.
Step 1. Generate two matrices which contain just the coordinates of each pixel. This is same as the MATLAB command meshgrid
(link). The equivalent steps in OpenCV are found in this answer.
Step 2. Using the matrices of x and y values, convert them into a matrix of "r", which is the distance from each pixel to the center of the image.
Step 3. Likewise, compute the value of "theta" from x and y. This "theta" is necessary for Step 6.
Step 2 and 3 together forms the basics of "Cartesian to Polar coordinate conversion".
Step 4. Computer the matrices of "r" raised to the second and third power.
Step 5. Apply the formula seen in the ImageMagick documentation on the polynomial of "r". Let the new result to be "r prime".
Step 6. With the "r prime" from Step 5, and the "theta" from Step 3, convert the polar coordinates back to Cartesian coordinates, "x prime" and "y prime"
Step 7. "x prime" and "y prime" can be used with remap
to generate the final result.
When applying the steps above, it is very important to distinguish whether one is performing the "forward mapping" or the "inverse mapping". Inverse mapping is closer to the everyday programming concept of "array lookup" - given the output array index, look up the output's value from the input at the input array index.
I will happily let any OpenCV user more capable than I am to provide a working sample of source code. If so, I welcome anyone to copy-and-paste the description (or better yet, rewrite it in a more understandable way) and include it in their answers. No attributions needed.
2 | warning about numerical stability of 32F in polynomial evaluation |
This is a supplementary answer in addition to R.Saracchini's answer.
As usual, there are benefits and drawbacks for using OpenCV for a certain task. This comment is trivially true for basically any tool at your disposal. If ImageMagick is a much easier route for your purpose, then by all means use the best handy tool you have.
Step 1. Generate two matrices which contain just the coordinates of each pixel. This is same as the MATLAB command meshgrid
(link). The equivalent steps in OpenCV are found in this answer.
Step 2. Using the matrices of x and y values, convert them into a matrix of "r", which is the distance from each pixel to the center of the image.
Step 3. Likewise, compute the value of "theta" from x and y. This "theta" is necessary for Step 6.
Step 2 and 3 together forms the basics of "Cartesian to Polar coordinate conversion".
Step 4. Computer the matrices of "r" raised to the second and third power.
Step 5. Apply the formula seen in the ImageMagick documentation on the polynomial of "r". Let the new result to be "r prime".
Step 6. With the "r prime" from Step 5, and the "theta" from Step 3, convert the polar coordinates back to Cartesian coordinates, "x prime" and "y prime"
Step 7. "x prime" and "y prime" can be used with remap
to generate the final result.
Caveat 1.
When applying the steps above, it is very important to distinguish whether one is performing the "forward mapping" or the "inverse mapping". Inverse mapping is closer to the everyday programming concept of "array lookup" - given the output array index, look up the output's value from the input at the input array index.
Caveat 2.
For typical sizes of photographic images (about several thousand pixels across in each dimension), the value of "r" will be roughly similar. When such values are evaluated in a cubic polynomial, if the signs of some polynomial coefficients are opposite, it is possible that catastrophic cancellation can occur, if the 32-bit floating point (CV_32F
) is used. MATLAB users might pay less attention from this problem because MATLAB defaults to using 64-bit floating point always. Working around this issue is beyond the scope of this question. I encourage any advanced OpenCV users to share your opinions on this issue.
(My memory is too weak to recall whether Horner's polynomial evaluation can mitigate this issue.)
Caveat 3.
The approach above will use lots of memory, as one might suspect. C or C++ programmers would tend to write a two-level for-loop, and calculate the "x prime" and "y prime" from the equations given the loop variables "x" and "y". That way only two coordinate matrices would ever be allocated. Users of Python would probably look for something like numpy.fromfunction
(documentation), such as this example. (Disclaimer: since I do not use Python, I do not know the performance or memory characteristics of this function.)
I will happily let any OpenCV user more capable than I am to provide a working sample of source code. If so, I welcome anyone to copy-and-paste the description (or better yet, rewrite it in a more understandable way) and include it in their answers. No attributions needed.