georgmartius / vid.stab

Video stabilization library
http://public.hronopik.de/vid.stab/
Other
842 stars 108 forks source link

feature request: crop=cut without zoom #78

Closed mviereck closed 4 years ago

mviereck commented 4 years ago

First, much thanks for libvidstab! It does an impressive work.

I currently try to use it for aligning an image stack of microscopic captures. So far the results look promising, I am still fiddling with the options to get the best possible results.

However, I have one problem: I need to cut off the black edges without any tricks of zooming or mirroring or copying from other frames. I must not use zoom because it would tamper microscopic measurement. I do not want to use parts of other frames because it would tamper the real image.

I tried with crop=black. An overlay of all images shows all black borders:

align_crop min tif trim_hard

I tried to automatically remove all black borders with color code #000000, but a bit is left as you can see in the red rectangle. This little rest is not entirely black.

Feature request: I would like a crop=cut option that results in smaller frames without black edges.

Alternatively, if I can somehow extract the crop coordinates from transforms.trf and you can give me a hint where to find them, I could do the crop myself. Edit: I just found global_motions.trf that somehow might tell me what I need. But I have no idea how to interpret the floating values.

georgmartius commented 4 years ago

I understand, a) due to interpolation the pixels will not be black at the border between image and padded black values b) I did not want to bother with changing the resolution, so I guess the best option would be to crop them afterwards. The problem is that the amount of movement of the camera is only calculated in the second pass and the transform file does only contain the optical flow data. Without changing the code you can do the following: Run the second pass with optzoom = 1 and parse the computed fixed zoom value that is printed. (You might be able to tell ffmpeg to only take 1 sec of video, and dump it to /dev/null). Anyway this value should be a good guideline for cropping. It is computed to keep 99% of all translations inside (no black borders), but it ignores rotation. (No sure you want rotation anyway, if not, then put max_angle = 0). So I would add a few percent to the opt-zoom value. BTW: it is given in percent, so zoom factor should be 1+zoom/100 (100 percent means factor 2, meaning that you have to chop half of the pixels away).

Hope that was not too cryptic.

mviereck commented 4 years ago

Thanks for your reply!

Hope that was not too cryptic.

It is entirely understandable. :-) Just need to read more than twice. I did some attempts, but could not solve the core issues.

parse the computed fixed zoom value that is printed

I can calculate a crop size from the zoom factor. But that does not tell me where to crop the frames, i.e. I am missing an X,Y offset.

No sure you want rotation anyway

I need rotation, too.

due to interpolation the pixels will not be black at the border between image and padded black values

I tried with interpol=0. That improved my crop result (removing black border) a lot, but still leaves some artefacts. A bit black != #000000 is left. Furthermore, gray areas appear on some frames: preview_0049

I think, the best way for me would be to find out the distorting values (rotation and offset) and apply them with imagemagick myself. With debug=1 in vidstabtransform I get a file global_motions.trf. Can I somehow calculate rotation and offset with this file? This entry should match the sample frame below:

0 0.386790 -0.285255 0.001211 -0.293168 0
#                    10.921363 3

out

georgmartius commented 4 years ago

There is no offset for global cropping. You would crop around the center.

The gray areas are very weird. One problem is typically the pixel format: YUV has different resolution for color and greyscale. Neverthess this should only result in 1 pixel gray values or so. This gray border is not in the original image already?

The global_motions.trf contains the following information: x y alpha zoom extra # some comments where x and y is the translation in pixels, alpha is the rotation in rad, zoom is the factor: 1+zoom (I hope) and extra = 1 for frames that have been badly matched.

mviereck commented 4 years ago

There is no offset for global cropping. You would crop around the center.

Of course, I could have thought that myself. Now I crop around the center and get a fairly well result if rotation is close to zero. But this attempt fails entirely for heavily rotated images.

This gray border is not in the original image already?

No, the original images only have those brownish colors. I've opened a new ticket for this: #79

The global_motions.trf contains the following information: x y alpha zoom extra # some comments where x and y is the translation in pixels, alpha is the rotation in rad, zoom is the factor: 1+zoom (I hope) and extra = 1 for frames that have been badly matched.

Finally I succeeded! I found that I have to sum up the given x, y and alpha values. They are always relative to the previous image. I've been confused before because the values did not make sense if seen as absolute.

Thank you! I want to note that vidstab does an impressive accurate and fast work in aligning image focus stacks. Other tools like align_image_stack and the hugin tools give similar results, but are way slower than vidstab.