How to crop and scale correctly with FFMPEG? - ffmpeg

I'm trying to remove the TOP AND BOTTOM black bars of a video.
Image sample from video
What i'm trying to achieve
The video itself is 1280x720 16:9, but the portion that's image information is at 4:3 since it's been captured from a VHS. I want to somehow stretch it until the top bars disappear without deforming the image. I don't care about the left and right bars.
I tried using crop and scale with no luck.
By using this code the top and bottom black bars disappeared on VLC when on normal screen but when going Full Screen the bars appeared again.
ffmpeg -i test.avi -filter:v "crop=1280:670" output_video.mp4
I thought it had something to do with the Scale of the video but honestly every scale code I tried to use deformed the image a lot.
I hope someone can help me, fairly new to FFMPEG but really enjoying it this far.

I got your image, resized it to 720p, made a 30 second video to test.
In my example I've also cropped the edges (left/right) because as #LordNeckbeard mentioned, when they hit the side of your screen, they may prevent the top/bottom of the video from reaching the top/bottom of the screen, which will again, look like black bars at the top/bottom, whether they are there or not.
This worked for me:
ffmpeg -y -hide_banner -i "test.avi" -filter:v "crop=iw-400:ih-40,scale=960:720" -pix_fmt yuv420p output_video.mp4
Quick explanation:
crop=iw-400:ih-40
Cropping 400 from the input width (iw) (2x200 left/right)
Cropping 40 from the input height (ih) (2x20 top/bottom)
You can cut a little more off if you want a 'crisper' edge.
scale=960:720
Scaling the video slightly to bring it back to your original 720p, the 960 is to keep it at a nice 4x3 ratio.
This scaling is not needed, your preference.
Let me know if it worked for you.

Related

FFMpeg to resize any video to fit 1080x1920 vertical, without cropping, instead by shrinking and adding blurred borders?

I found some posts explaining how to turn any video horizontal by adding blurred borders using FFMpeg, but I want to convert videos to vertical 1080x1920. I don't want it to enlarge the video, nor crop if a dimension is bigger than either 1080 or 1920 dimension. Instead, I want it to shrink the video until it fits fully inside 1080x1920, and then I want it to add blurred borders to the empty areas.
This is the snippet I found, but when I tried reversing the numbers, it actually cropped the video.
ffmpeg -I input.mp4 -lavfi "[0:v]scale=1920*2:1080*2,boxblur=luma_radius=min(h\,w)/20:luma_power=1:chroma_radius=min(cw\,ch)/20:chroma_power=1[bg];[0:v]scale=-1:1080[ov];[bg][ov]overlay=(W-w)/2:(H-h)/2,crop=w=1920:h=1080" output.mp4
Simple method:
ffmpeg -i input.mp4 -filter_complex "[0:v]boxblur=40,scale=1080x1920,setsar=1[bg];[0:v]scale=1080:1920:force_original_aspect_ratio=decrease[fg];[bg][fg]overlay=y=(H-h)/2" -c:a copy output.mp4
"Simple" because it forces the background to 1080x1920 and ignores aspect ratio. So the background it will looked stretched, but it is blurred so much nobody will care or notice.

perspective correction example

I have some videos taken of a display, with the camera not perfectly oriented, so that the result shows a strong trapezoidal effect.
I know that there is a perspective filter in ffmpeg https://ffmpeg.org/ffmpeg-filters.html#perspective, but I'm too dumb to understand how it works from the docs - and I cannot find a single example.
Somebody can show me how it works?
The following example extracts a trapezoidal perspective section from an input Matroska video to an output video.
An estimated coordinate had to be inserted to complete the trapezoidal pattern (out-of-frame coordinate x2=-60,y2=469).
Input video frame was 1280x720. Pixel interpolation was specified linear, however that is the default if not specified at all. Cubic interpolation bloats the output with NO apparent improvement in video quality. Output video frame size will be of the input video's frame size.
Video output was viewable but rough quality due to sampling error.
ffmpeg -hide_banner -i input.mkv -lavfi "perspective=x0=225:y0=0:x1=715:y1=385:x2=-60:y2=469:x3=615:y3=634:interpolation=linear" output.mkv
You can also make use of ffplay (or any player which lets you access ffmpeg filters, like mpv) to preview the effect, or if you want to keystone-correct a display surface.
For example, if you have your TV above your fireplace mantle and you're sitting on the floor looking up at it, this will un-distort the image to a large extent:
ffplay video.mkv -vf 'perspective=W*.1:0:W*.9:0:-W*.1:H:W*1.1:H'
The above expands the top by 20% and compresses the bottom by 20%, cropping the top and infilling the bottom with the edge pixels.
Also handy for playing back video of a building you're standing in front of with the camera pointed up around 30 degrees.

ffmpeg delogo works not good when delogo at boundary

I am trying using ffmpeg delogo filter to hide the logo, but I found when the logo is appears at boundary, delogo filter seems works not good. please check following images.
I also read a bit of source, seems the algorithm need subtract 1 pixel boundary. in the second image, the delogo result is looks strange, bottom is white. I want to make it invisible, is it possible?
thanks
Try
ffmpeg -i video
-filter_complex
"[0]split[m][b];
[b]crop=iw:144:0:174,vflip[a];
[m][a]vstack,delogo=794:689:134:40:1,crop=iw:720:0:0" out.mp4
The video is split in two. The 2nd feed is cropped to the bottom 20% but ending at a height just above the logo. This is then flipped and vertically stacked with the main stream. delogo is applied making sure that the height of the logo covers the whole logo. Then the excess portion at the bottom is cropped off.
Result:

Overlaying one video on another one, and making black pixels transparent

I'm trying to use FFMPEG to create a video with one video overlayed on top another.
I have 2 MP4s. I need to make all BLACK pixels in the overlay video transparent so that I can see the main video underneath it.
I found two ways to overlay one video on another:
First, the following positions the overlay in the center, and therefore, hides that portion of the main video beneath it:
ffmpeg -i 1.mp4 -vf "movie=2.mp4 [a]; [in][a] overlay=352:0 [b]" combined.mp4 -y
And, this one, places the overlay video on the left, but it's opacity is set to 50% so at least other one beneath it is visible:
ffmpeg -i 1.mp4 -i 2.mp4 -filter_complex "[0:v]setpts=PTS-STARTPTS[top]; [1:v]setpts=PTS-STARTPTS, format=yuva420p,colorchannelmixer=aa=0.5[bottom]; [top][bottom]overlay=shortest=0" -acodec libvo_aacenc -vcodec libx264 out.mp4 -y
My goal is simply to make all black pixels in the overlay (2.mp4) completely transparent. How can this be done.
The notional way to do this is to chroma-key the black out and then overlay, But as #MoDJ said, this likely won't produce satisfactory results. Neither will the method I suggest below, but it's worth a try.
ffmpeg -i 1.mp4 -i 2.mp4 -filter_complex
"[1]split[m][a];
[a]geq='if(gt(lum(X,Y),16),255,0)',hue=s=0[al];
[m][al]alphamerge[ovr];
[0][ovr]overlay"
output.mp4
Above, I duplicate the overlay video stream, then use the geq filter to manipulate the luma values so that any pixel with luma greater than 16 (i.e. not pure black) has its luma set to white, else zero. Since I haven't provided expressions for the two color channels, geq falls back on the luma expression. We don't want that, so I use the hue filter to nullify those channels. Then I use the alphamerge filter to merge this as an alpha channel with the first copy of the overlay video. Then, the overlay. Like I said, this may not produce satisfactory results. You can tweak the value 16 in the geq filter to change the black threshold. Suggested range is 16-24 for limited-range (Y: 16-235) video files.
You will not be able to get a "replace black pixels" approach to work properly. What you actually want is a foreground video with a real alpha channel that can be manipulated and tested before doing an overlay on a background. For an extended example that describes the problems, please take a look at my blog post on the subject. When using FFMPEG, an easy way to import alpha channel video is to use Quicktime with the Animation codec video at 32 BPP.

Resize to a specific width and height using ffmpeg

I need to generate thumbnails for videos, automatically. I cannot predict the format of the video, but I need the thumbnail to be 220x120 pixels, always. Using -s 220x120 produces a weird stretch, just like -vf "scale=220:120". I'd like the stretching to be uniform, either cutting away top and bottom if the video is too high or adding black borders.
This is an example using a picture, same filter can be applied to video:
ow=220
oh=120
ffmpeg -i foo.png \
-vf "scale=max($ow\,a*$oh):max($oh\,$ow/a),crop=$ow:$oh" bar.png
Regardless of aspect ratio, this will:
scale down until width or height fits "the box"
crop down the other until it fits as well
The commas inside needs to be escaped so they aren't interpreted as filter separators.
§ Crop
§ Scale

Resources