Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Vertical distortion of an image to a datum (=seismic horizon flattening of an image)
#1
Hi, a rookie to this forum, I would be very interested to know if it is possible for GIMP to distort/flatten an image along a horizon by pure vertical shifting of pixel columns, in a way that would make the thick red horizon in the lower half of this image https://img.aapg.org/Portals/0/PackFlash...lor=5cadb8 flat (horizontal), and all other parts of the image moved up or down accordingly, keeping all vertical distances equal?

In other words, is it possible to e.g. draw a curved path along the thick red horizon in the linked image, affix it to the image; then make the path horizontal (without stretching it horizontally) and have the image vertically flattened along/adjusted to such a datum accordingly? The resulting image would, obviously, have curved or jagged top and bottom edges..

Kind regards,
Tor
Reply
#2
There is the Curve bend tool, but you cannot draw on the image and I don't think you could be accurate enough.

Your problem is defining the 955 points of your hypothetical path.

Another method is to shred the image into 955 1px-wide layers, and shift the layers on by one to line the up. About as much work as defining the hypothetical path, but you get a visual feedback as you work. If you are lazy, use 2px or 3px strips. Of course you can only shift by an integer count of pixels.

Here I lined up the red line in the middle of the blue strip, around 495px down where it starts:

   
Reply
#3
From the image title, 'machine-learning' looking for something developed from ?
https://www.gimp-forum.net/Thread-Some-p...g-for-Gimp

I was hoping someone might come up with a procedure since the only (poor) solution I came up with is very hands-on and does not use a path. The gmic interactive warp filter.

With some swopping images, a displacement map. https://i.imgur.com/4qoKvUv.jpg
Then applied to the image. https://i.imgur.com/EEiq1xW.jpg
gmic can retain the filter parameters in a file. Possibly grab values from path and write the correct parameters.
Maybe ask the gmic developer, either the gmic site or https://discuss.pixls.us/
Reply
#4
I wonder if that can be done with a morphing plugin : morphing the image to one (or more parallel lines) , just a tought....
Reply
#5
(05-07-2020, 09:30 AM)denzjos Wrote: I wonder if that can be done with a morphing plugin : morphing the image to one (or more parallel lines) , just a thought....

No, morphing doesn't work

But it is always difficult to find the right software to straighten pictures. As in this case, it is different to straighten horizons where one have to calculate new pixels, here one just have to shift columns of pixels up or down. Let's suppose one keep a reference line in mind on the middle of the drawing. In this picture there is a yellow line that one can isolate. Then one can get the x- and y-coordinates from the pixels from that line. If one compares this coordinates with the horizontal line, one get positive, negative and zero values. It can't be such a job to shift the columns up/down/let them to transform the picture to straight lines. It's just a pixel shift job in a loop. Maybe this can be done with the help of layers as Ofnuts mentioned. Such a script / plugin would also be very useful to straighten distorted scanned pages from books, even correct horizons on photos,  etc..
In my younger days far away a would program this in compiled quick basic, but in this days that's antique. I think, as I see gimp developing, there will be such a kind of plugin / script in the future.  So Tor, no solution from my side.
Reply
#6
Mathematically you can compute the cross-correlation between adjacent strips of pixels, and deduce the shift to apply to align them (and this would find a best fit over the whole height, not locally for a specific feature). A question could be how to avoid drifts.
Reply
#7
If one could import the different values, that can be calculated from of the curved lines on the image to a horizontal line (maybe by using a path), into the 'Filter / Distorts / GE Shift' to shift the different rows up and down, it would be possible to do the job. Now the filter generate different values in the X- or Y direction to move columns or rows, so if one can replace the generated values (reading out one by one out of the calculated values in memory / file) this can work. Just a suggestion.
Reply
#8
(05-07-2020, 09:14 PM)Ofnuts Wrote: Mathematically you can compute the cross-correlation between adjacent strips of pixels, and deduce the shift to apply to align them (and this would find a best fit over the whole height, not locally for a specific feature). A question could be how to avoid drifts.

For the specific problem in the original post would the cross-correlation not have to be done only on the area of the thicker red stripe (or possibly the thin lighter line above it)? If you work on the complete columns of pixels the thicker red line would probably bot end up horizontal.

One problem is that in one area the lower edge of the thicker red stripe becomes rather blurred - hence suggesting using the lighter stripe immediately above it.

If writing a script for this Python should be used - Script-fu gets painfully slow when pixel peeping is required as here.

The original poster talks of drawing a path - that would be fine if this was an infrequent need. The easiest way then, from the point of view of writing a script, would be to add a transparent layer over the origianl image and draw a line of single pixel thickness on this second layer. The script dialog could specify the vertical coordinate at which the new 'horizon' should be placed. Its then a relatively simple matter for the script to determine the necessary vertical adjustment for each column of the original image based on the vertical positions of the pixels in the upper layer and shift the pixels in that column of the lower layer.

I wonder duplicating the original layer, applying one of the edge detection algorithms on this duplicated layer and then erase everything but the required line.

It would of course be possible to have the script operate only with the single layer of the original image and determine shifts required to make the thicker red band (or possibly the thinner light band above it) horizontal but I would be concerned about having a line with edges that were clear enough to follow.

Hope this makes some sort of sense.
Reply
#9
(05-09-2020, 10:45 AM)programmer_ceds Wrote:
(05-07-2020, 09:14 PM)Ofnuts Wrote: Mathematically you can compute the cross-correlation between adjacent strips of pixels, and deduce the shift to apply to align them (and this would find a best fit over the whole height, not locally for a specific feature). A question could be how to avoid drifts.

For the specific problem in the original post would the cross-correlation not have to be done only on the area of the thicker red stripe (or possibly the thin lighter line above it)? If you work on the complete columns of pixels the thicker red line would probably bot end up horizontal.

One problem is that in one area the lower edge of the thicker red stripe becomes rather blurred - hence suggesting using the lighter stripe immediately above it.

If writing a script for this Python should be used - Script-fu gets painfully slow when pixel peeping is required as here.

The original poster talks of drawing a path - that would be fine if this was an infrequent need. The easiest way then, from the point of view of writing a script, would be to add a transparent layer over the origianl image and draw a line of single pixel thickness on this second layer. The script dialog could specify the vertical coordinate at which the new 'horizon' should be placed. Its then a relatively simple matter for the script to determine the necessary vertical adjustment for each column of the original image based on the vertical positions of the pixels in the upper layer and shift the pixels in that column of the lower layer.

I wonder duplicating the original layer, applying one of the edge detection algorithms on this duplicated layer and then erase everything but the required line.

It would of course be possible to have the script operate only with the single layer of the original image and determine shifts required to make the thicker red band (or possibly the thinner light band above it) horizontal but I would be concerned about having a line with edges that were clear enough to follow.

Hope this makes some sort of sense.

Possibly a XY problem, so I wouldn't stick too much on the initial requirements.

Python would be OK if using numpy and/or some signal processing library, otherwise the amount of computation requires a compiled language.
Reply


Forum Jump: