Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
fix distorted round
Is there a way to fix images with distorted round objects to perfect round objects? I think of a plugin / script where one can place a few points on the distorted circle or use a path / selection. Playing with the different gimp tools is time consuming to get a good result. An example to correct :
Maybe not possible with standard Gimp scriptable to create a plugin, I am sure someone will advise if it is.

There has to be some degree of evaluation, in the example, the numbers 9 and 3 the same size, 12 and 6 the same. 12 and 6 vertical and the hands central.  Is that possible without user intervention?

What tools do you use at present ?  Best I came up with for speed is 3D transform followed by handle transform. Even then, obviously concentrating on the clock face, that is not quite aligned. Must do better.


A quick demo, to fit in the imgur 60 second time limit, already setup with center line and a circular path guides + some idea of the values required
Thank you rich for the answer. I've used the same tools (drew a circle and used 3D transform) but I could'n fix the same horizontal distance between the centers to the 3 and the 9. I've seen on the demo how to use the cage transform to solve this. There are many ways to use tools (also gimp tools), but life is a way of learning. Thanks.
Not that hard manually, at least for such a dial where you have markings at 90° angles.
  1. Start the perspective tool (Clipping: Adjust)
  2. Adjust the handles so that the 4 lines are tangent to the dial circle at 90° angles (ie, 3,6,9,12 hours).
  3. Apply, this gives you a rectangle
  4. Image>Scale image, unlink the dimensions, set one of the dimensions equal to the other
  5. Apply. Now you clock is round
  6. To recover the rest f the image: Image>Fit canvas to layers and crop what you don't need.
In your image, the axis of the hands is quite long and the perspective won"t fix his, so the perceived center of the dial (where handles intersect) isn't the center of the circle (but the bottom of the axis is indeed in the center of the dial). Not mentioning that the dial is recessed in the bezel...

Ofnuts, thank you for the solution. It is still tricky to make good tangents and get a perfect result, but I am also satisfied with this method.  I know that the center is on the dial, but that is no issue for me. I only want the dial to have the right dimensions, the rest is cloning and healing. I also want to correct round stained glas windows en parts (with round items) of photographed technical drawings. For this last item, that is concerning a distorted flat image, and if there are no axes in the circles, it is important to get a perfect circle (not to be confused with the supergroup). Thanks
Gven four points that are supposed tn be in a circle, t It could be possible to determine the unique Perspective transform that puts them on a circle (unless there are 4 possible such transforms, depending one which point you pick). Three points are not enough because three points are always in a circle. But all this is outside my current math abilities. Maybe ask our resident mathematician, Ottia Tuota.
Thank you Ofnuts that you also have some interest in this issue. I found an article that is concerning this problem : Maybe someone can use this information for writing a script.........
Since I was mentioned: I know how to get a Python function for the desired plane transformation. But I have no idea how to apply it to transform an image.

When I wrote my plugins on path transformations, I implemented also general projective transformations. But I never published it as a plugin since I felt that it was too laborious to use. But some code is embedded in the file Specifically, there is a Python function that creates projective plane transformations. I copy here the comment describing the function:

# -------------------
# make_projective_map
# -------------------
# Given four points A,B,C,D (base) in a general position (no three collinear),
# another four points P,Q,R,S (target) in a general position,
# make plane transformation which sends
#    A -> P
#    B -> Q
#    C -> R
#    D -> S
# Return also
# - coefficients [g,h,k] such that the pre-image of the ideal line has
#   the equation gx+hy+k=0; or None if the pre-image equals the ideal line;
# - the same info for the image of the ideal line.
# Args:
# - base:   [A,B,C,D]: [ControlPoint,ControlPoint,ControlPoint,ControlPoint]
# - target: [P,Q,R,S]: [ControlPoint,ControlPoint,ControlPoint,ControlPoint]
# Returns:
# - PlaneTransformation
# - [float,float,float] or None (coefficients g,h,k for the pre-image of ideal line)
# - [float,float,float] or None (coefficients g,h,k for the image of ideal line)
# Exceptions:
# - MakeProjectiveMapError
def make_projective_map(base,target):
.....  For the code see  .....

The plane is viewed as the complex number plane. (Names 'ControlPoint' and 'RowVector' are synonymous to 'complex'). What the function does, is that it takes (almost) arbitrary four points A,B,C,D in the plane and another four points P,Q,R,S, and it creates the projective transformation which sends A,B,C,D to P,Q,R,S. The transformation will be an object in the class PlaneTransformation (my own creation, also included in the file

So, for example if you choose some four points A,B,C,D from the circumference of your clock face, and corresponding four points P,Q,R,S from a circle, the created transformation should be the one needed.

But the problem is, how to make it to a usable plugin, for instance. That is, how to use the transformation to transform an image. That is too difficult for me. In fact, I have no idea how such image transforms are made. My hobby was to transform paths, and I designed the class PlaneTransformation for that purpose.

Any object pt in the class PlaneTransformation has attributes pt.point_map and pt.jacobian. Here pt.point_map is a function C->C (the C being the complex number plane). So, if z is some point in the plane (as a complex number), then pt.point_map(z) is the transformed point (as a complex number). The other attribute pt.jacobian gives the Jacobian matrix of the mapping: pt.jacobian(z) is the Jacobian matrix at point z.

I imagine that the Jacobian matrix is not needed for image transformations (it was crucial for path transformations). So, having chosen such points A,B,C,D and P,Q,R,S, one calls the Python function 'make_projective_map' as follows:

pt = make_projective_map([A,B,C,D],[P,Q,R,S])[0]

Then pt is an instance of PlaneTransformation, and

F = pt.point_map

is a Python function implementing the desired mapping C->C. The problem is, even given this F,  how to transform an image with it? Here is the limit of my skills. Perhaps somebody who knows how to make such image transformations gets some idea and wants to take over.

But I doubt it would be worth the trouble. It is easiest just to use Gimp's ready-made transform tools since they seem quite adequate for the job (post #4 by Ofnuts). And the result would be no better even if it were done by some fancy plugin.

By the way, here seems to be two traditions in terminology. I believe that what I, as a mathematician, call a "projective transformation", is the same thing as the tool Perspective transform in Gimp.
Thanks Ottia Tuota for the extended explanation. I thought it could be possible to make a link to some points on a circle path and on the image and then send the values to the the gimp 3D Tranform and the gimp Cage Transform to let them do the job. But anyway, thanks for the reply.
(10-26-2020, 07:02 AM)Ottia Tuota Wrote: So, for example if you choose some four points A,B,C,D from the circumference of your clock face, and corresponding four points P,Q,R,S from a circle, the created transformation should be the one needed.

The problem is that its difficult to figure out the 4 points that should correspond to 4 known points on the final correct circle. It is however possible to indicate 4 points on the distorted circle, but nothing more. So the question is, given 4 points, is there a way to compute the Projective transform (is this transform unique? additional constraints are possible to make it unique, such as keeping the distance between two points identical, or keepin the orientation between two given points, or both)) than puts them on a circle? If I have this transform, I can figure out a way to use it with gimp_item_transform_perspective().

Forum Jump: