我使用 ffmpeg 转换的图像和视频的宽高比错误

我使用 ffmpeg 转换的图像和视频的宽高比错误

我正在尝试将一些旧电影文件转换为图像(然后重新编码为 h.264)。问题是生成的图像在垂直方向上被拉伸了。

这是 ffmpeg 命令:

ffmpeg -i preview.mpg -filter_complex "[0:v]fps=fps=1[onepersec]; [onepersec]scale=min(200\, iw):-2[rescaled]" -map "[rescaled]" -f image2 image%4d.jpg

我有一个猜测:scale我使用的滤镜会忽略显示宽高比DAR,而只是缩放像素值。我希望图像的宽度最多为 200 像素,高度可以是任意大小,只要看起来正确即可,即不拉伸。

我应该如何转换电影文件以获得看起来不拉伸的图像(和重新编码的视频)?

有关视频文件的其他信息:

在 VLC 中播放效果不错。它看起来像是正常的 4:3 宽高比。VLC 在Current media information>中显示以下内容Codec

Stream 0
Type: Video
Codec: MPEG-1/2 Video (mpgv)
Resolution: 352x576
Frame rate: 25
Decoded format: Planar 4:2:0 YUV

以下是运行上述命令的输出ffmpeg

ffmpeg version git-2014-07-24-f753956 Copyright (c) 2000-2014 the FFmpeg developers
  built on Jul 24 2014 13:39:56 with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-4)
  configuration: --prefix=/home/somename/ffmpeg_build --extra-cflags=-I/home/somename/ffmpeg_build/include --extra-ldflags=-L/home/somename/ffmpeg_build/lib --bindir=/home/somename/bin --extra-libs=-ldl --enable-gpl --enable-nonfree --enable-libfdk_aac --enable-libmp3la
me --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libfreetype --enable-libspeex --enable-libtheora
  libavutil      52. 92.101 / 52. 92.101
  libavcodec     55. 69.100 / 55. 69.100
  libavformat    55. 49.100 / 55. 49.100
  libavdevice    55. 13.102 / 55. 13.102
  libavfilter     4. 11.102 /  4. 11.102
  libswscale      2.  6.100 /  2.  6.100
  libswresample   0. 19.100 /  0. 19.100
  libpostproc    52.  3.100 / 52.  3.100
Input #0, mpeg, from 'preview.mpg':
  Duration: 00:14:23.59, start: 1.646067, bitrate: 2244 kb/s
    Stream #0:0[0x1bf]: Data: dvd_nav_packet
    Stream #0:1[0x1e0]: Video: mpeg2video (Main), yuv420p(tv), 352x576 [SAR 24:11 DAR 4:3], max. 2500 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc
    Stream #0:2[0x80]: Audio: ac3, 48000 Hz, stereo, fltp, 256 kb/s
[swscaler @ 0x3f6fae0] deprecated pixel format used, make sure you did set range correctly
Output #0, image2, to 'image%4d.jpg':
  Metadata:
    encoder         : Lavf55.49.100
    Stream #0:0: Video: mjpeg, yuvj420p, 200x328 [SAR 164:75 DAR 4:3], q=2-31, 200 kb/s, 1 fps, 1 tbn, 1 tbc
    Metadata:
      encoder         : Lavc55.69.100 mjpeg
Stream mapping:
  Stream #0:1 (mpeg2video) -> fps
  scale -> Stream #0:0 (mjpeg)
Press [q] to stop, [?] for help
frame=   41 fps=0.0 q=1.6 size=N/A time=00:00:41.00 bitrate=N/A    ^Mframe=   80 fps= 79 q=1.6 size=N/A time=00:01:20.00 bitrate=N/A    ^Mframe=  125 fps= 71 q=1.6 size=N/A time=00:02:05.00 bitrate=N/A    ^Mframe=  156 fps= 69 q=1.6 size=N/A time=00:02:36.00 bitrate=N/A    ^Mframe=  203 fps= 74 q=1.6 size=N/A time=00:03:23.00 bitrate=N/A    ^Mframe=  248 fps= 76 q=1.6 size=N/A time=00:04:08.00 bitrate=N/A    ^Mframe=  295 fps= 79 q=1.6 size=N/A time=00:04:55.00 bitrate=N/A    ^Mframe=  336 fps= 79 q=1.6 size=N/A time=00:05:36.00 bitrate=N/A    ^Mframe=  377 fps= 79 q=1.6 size=N/A time=00:06:17.00 bitrate=N/A    ^Mframe=  424 fps= 81 q=1.6 size=N/A time=00:07:04.00 bitrate=N/A    ^Mframe=  465 fps= 81 q=1.6 size=N/A time=00:07:45.00 bitrate=N/A    ^Mframe=  508 fps= 81 q=1.6 size=N/A time=00:08:28.00 bitrate=N/A    ^Mframe=  547 fps= 79 q=1.6 size=N/A time=00:09:07.00 bitrate=N/A    ^Mframe=  580 fps= 78 q=1.6 size=N/A time=00:09:40.00 bitrate=N/A    ^Mframe=  621 fps= 79 q=1.6 size=N/A time=00:10:21.00 bitrate=N/A    ^Mframe=  665 fps= 79 q=1.6 size=N/A time=00:11:05.00 bitrate=N/A    ^Mframe=  709 fps= 80 q=1.6 size=N/A time=00:11:49.00 bitrate=N/A    ^Mframe=  746 fps= 79 q=1.6 size=N/A time=00:12:26.00 bitrate=N/A    ^Mframe=  794 fps= 80 q=1.6 size=N/A time=00:13:14.00 bitrate=N/A
^Mframe=  833 fps= 80 q=1.6 size=N/A time=00:13:53.00 bitrate=N/A    ^Mframe=  865 fps= 81 q=1.6 Lsize=N/A time=00:14:25.00 bitrate=N/A
video:11118kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown

也许我需要做点什么[swscaler @ 0x3f6fae0] 使用了弃用的像素格式,请确保正确设置了范围

以下是输出mediainfo

$ mediainfo preview.mpg
General
Complete name                            : /[...]/preview.mpg
Format                                   : MPEG-PS
File size                                : 231 MiB
Duration                                 : 14mn 23s
Overall bit rate mode                    : Variable
Overall bit rate                         : 2 244 Kbps

Video
ID                                       : 224 (0xE0)
Format                                   : MPEG Video
Format version                           : Version 2
Format profile                           : Main@Main
Format settings, BVOP                    : Yes
Format settings, Matrix                  : Custom
Format settings, GOP                     : M=2, N=12
Duration                                 : 14mn 23s
Bit rate mode                            : Variable
Bit rate                                 : 1 943 Kbps
Maximum bit rate                         : 2 500 Kbps
Width                                    : 352 pixels
Height                                   : 576 pixels
Display aspect ratio                     : 4:3
Frame rate                               : 25.000 fps
Standard                                 : PAL
Color space                              : YUV
Chroma subsampling                       : 4:2:0
Bit depth                                : 8 bits
Scan type                                : Interlaced
Scan order                               : Top Field First
Compression mode                         : Lossy
Bits/(Pixel*Frame)                       : 0.383
Time code of first frame                 : 00:00:00:12
Time code source                         : Group of pictures header
Stream size                              : 200 MiB (87%)

Audio
ID                                       : 189 (0xBD)-128 (0x80)
Format                                   : AC-3
Format/Info                              : Audio Coding 3
Mode extension                           : CM (complete main)
Format settings, Endianness              : Big
Muxing mode                              : DVD-Video
Duration                                 : 14mn 23s
Bit rate mode                            : Constant
Bit rate                                 : 256 Kbps
Channel(s)                               : 2 channels
Channel positions                        : Front: L R
Sampling rate                            : 48.0 KHz
Bit depth                                : 16 bits
Compression mode                         : Lossy
Delay relative to video                  : -31ms
Stream size                              : 26.3 MiB (11%)

Menu

以下是输出ffprobe

$ ffprobe preview.mpg
ffprobe version git-2014-07-24-f753956 Copyright (c) 2007-2014 the FFmpeg developers
  built on Jul 24 2014 13:39:56 with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-4)
  configuration: --prefix=/home/sadmin/ffmpeg_build --extra-cflags=-I/home/somename/ffmpeg_build/include --extra-ldflags=-L/home/somename/ffmpeg_build/lib --bindir=/home/somename/bin --extra-libs=-ldl --enable-gpl --enable-nonfree --enable-libfdk_aac --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libfreetype --enable-libspeex --enable-libtheora
  libavutil      52. 92.101 / 52. 92.101
  libavcodec     55. 69.100 / 55. 69.100
  libavformat    55. 49.100 / 55. 49.100
  libavdevice    55. 13.102 / 55. 13.102
  libavfilter     4. 11.102 /  4. 11.102
  libswscale      2.  6.100 /  2.  6.100
  libswresample   0. 19.100 /  0. 19.100
  libpostproc    52.  3.100 / 52.  3.100
Input #0, mpeg, from 'preview.mpg':
  Duration: 00:14:23.59, start: 1.646067, bitrate: 2244 kb/s
    Stream #0:0[0x1bf]: Data: dvd_nav_packet
    Stream #0:1[0x1e0]: Video: mpeg2video (Main), yuv420p(tv), 352x576 [SAR 24:11 DAR 4:3], max. 2500 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc
    Stream #0:2[0x80]: Audio: ac3, 48000 Hz, stereo, fltp, 256 kb/s
Unsupported codec with id 1145979222 for input stream 0
$

此处为文本输入流 0 不支持 ID 为 1145979222 的编解码器已突出显示。我猜是关于Stream #0.0(?)的,我不需要它。

以下是我得到其中一张图片的结果:

$ ffprobe image0001.jpg
ffprobe version git-2014-07-24-f753956 Copyright (c) 2007-2014 the FFmpeg developers
  built on Jul 24 2014 13:39:56 with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-4)
  configuration: --prefix=/home/somename/ffmpeg_build --extra-cflags=-I/home/somename/ffmpeg_build/include --extra-ldflags=-L/home/somename/ffmpeg_build/lib --bindir=/home/somename/bin --extra-libs=-ldl --enable-gpl --enable-nonfree --enable-libfdk_aac --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libfreetype --enable-libspeex --enable-libtheora
  libavutil      52. 92.101 / 52. 92.101
  libavcodec     55. 69.100 / 55. 69.100
  libavformat    55. 49.100 / 55. 49.100
  libavdevice    55. 13.102 / 55. 13.102
  libavfilter     4. 11.102 /  4. 11.102
  libswscale      2.  6.100 /  2.  6.100
  libswresample   0. 19.100 /  0. 19.100
  libpostproc    52.  3.100 / 52.  3.100
[mjpeg @ 0x24c7e40] ignoring invalid SAR: 164/75
Input #0, image2, from 'mov0001.jpg':
  Duration: 00:00:00.04, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: mjpeg, yuvj420p(pc, bt470bg), 200x328, 25 tbr, 25 tbn, 25 tbc

有趣的是[mjpeg @ 0x24c7e40] 忽略无效 SAR:164/75 但是,这是什么意思?

答案1

7 年后,我又面临类似的问题,将在这里为未来 7 年来访的人们提供解决方案。

首先尝试更好地理解 SAR/PAR 和 DAR 值的含义。关于这个主题的 YouTube 视频很棒。

这样,在转换 SAR 值不为 1 的视频时,它就有意义了。首先要对视频进行标准化(即将像素平方)以符合 SAR 1/1。

图像被拉伸的根本原因显然是大多数图像查看软件不关心读取/理解 SAR 值。它们期望 SAR 为 1/1。

实现此目的的一种方法是通过比例过滤器:

scale=iw*sar:ih

通用的 ffmpeg 示例:

ffmpeg -i somefile.avi -vf 'scale=iw*sar:ih' someoutput%04d.jpg

这会在保持高度的同时缩放宽度以确保 SAR 现在为 1/1。

然后您可以添加另一个比例步骤来获得所需的尺寸:

scale=iw*sar:ih,scale=200:-2

或者使用问题中所示的旧过滤器符号:

-filter_complex "[0:v]fps=fps=1[onepersec]; [onepersec]scale=iw*sar:ih[onepersecondnorm]; [onepersecnorm]scale=min(200\, iw):-2[rescaled]"

希望这对某人有帮助。

答案2

@QuickPrototype- 我觉得你的回答有点令人沮丧,因为理解解决方案以便将其应用于类似情况通常需要理解问题本身,而你的帖子并没有很好地描述 SAR/PAR/DAR 问题。它只是简单地告诉我们在 Youtube 上研究它。

由于没有找到任何有用的 YouTube 视频,我发现以下维基百科文章非常有启发性:像素长宽比

形象的观念像素(即图像数据的最小点)及其宽高比(即图像/像素/屏幕尺寸的比率为'宽度/高度有时表达为宽度:高度') 源于制作模拟视频录像的数字版本。模拟视频录像有 '线' 和 '中心点' 这与当时使用的 4:3 宽高比的老式阴极射线管电视配合得很好。模拟视频记录中没有像素,模拟视频记录旨在引导扫描光子束穿过屏幕,点亮屏幕上的荧光粉,从左到右扫描,然后向下扫描一行到下一行,直到 NTSC(美国)电视上的所有 525 行(或欧洲 PAL 或 SECAM 的 635 行)都绘制完毕,然后重新开始该过程,每秒产生一系列 25 或 30 个闪烁图像,从而给人眼运动的错觉。相反,数字记录使用网格 '像素'将模拟图像映射到液晶屏幕技术或其他现代电视平板技术。

转码问题当使用 4:3 宽度乘以高度 (DAR) 的旧电视阴极射线管屏幕进行模拟视频录制时,会发生这种情况'显示宽高比' 被数字化,然后显示在 16:9 的平板电视上 '显示宽高比'。生成的图像可能会在左右两侧出现黑带,以补偿不同的 DAR 比率(4:3 与 16:9),或者 4:3 图像可能会被拉伸以填充整个宽度,这意味着要么裁剪图像的顶部和底部,要么可能挤压图像的高度。人们指的是挤压图像的高度还是拉伸图像的宽度并不重要,因为结果在实践中基本相同;但是,产生的结果可能是 4:3 图像看起来被奇怪地拉伸以适应 16:9 DAR 屏幕,这通常不是推荐的解决方案。黑带或最小限度的裁剪看起来更好,因为人们的脸没有被挤压或拉伸。

从技术角度来看,数字“伸展' 或者 '挤压' 是由于没有 '正方形' 每个像素为 1x1 单位正方形;相反,假设像素可以被拉伸或压缩为矩形“1.33 x 1 单位”或“1 x 0.75 单位”像素。任何时候 (PAR) '像素长宽比' 不是正方形,而是矩形,则生成的图像看起来会被拉伸或挤压。

从数学上来说这可以用以下公式来表达:

SAR x PAR = DAR' .. 和 .. 'PAR = DAR/SAR' (即,如果 PAR = 1,则 SAR = DAR)其中:

SAR = '存储纵横比' 是图像的宽度和高度(以像素为单位),通常以数字文件格式存储。

PAR = '像素长宽比' 是像素的宽度和高度之比,通常应为 1:1(即平方),否则'伸展' 和 '挤压' 效果发生

DAR = '显示宽高比' 是屏幕的宽度和高度之比,它是硬连线到屏幕硬件本身的。

现在来描述一下我遇到的问题:'延展性' 或其反义词 '挤压' 是我在数字视频转码过程中遇到的一个问题。在尝试“标准化”笔记本电脑屏幕录制中出现的非标准分辨率时,分辨率为 1197x989 等奇数分辨率,然后我尝试使用 ffmpeg 过滤器将其缩放到更“标准”的宽高比 '-vf 比例=960:720' 或者 '-vf 比例=1440:1080' 例如,我会找到高度缩放后的输出文件(即'挤压' 至 720 像素或 '拉伸' 到 1080 像素)正确,但宽度不正确 '挤压' 改为 871 像素而不是 960 像素或不正确 '拉伸' 仅为 1307 像素,而不是 1440 像素,这没有达到所需的 4:3 DAR 显示纵横比。实际上,ffmpeg 不是应用 4:3 DAR,而是使用旧的 SAR 1197:989 来定义 DAR,并且 -vf scale=value:value 过滤器只会将图像正确地缩放到所需的高度,而不是宽度。

沮丧之余,我进行了更多的研究,发现ffmpeg 常见问题解答页,3.18 我的视频被拉伸了,为什么缩放无法修复?这里我介绍了 ffmpeg 过滤器:'-方面 4:3' 或者 '-宽高比 16:9' 这会影响输出图像的宽度,但不会影响高度。应用此滤镜时,高度仍为 989 像素,但宽度将分别变为 1318 或 1758 像素。这看起来更糟,因为宽度 '伸展' 就更加引人注目了。

我的解决方案在没有找到特定的 ffmpeg PAR 过滤器的情况下,将上述两个过滤器组合起来(即'ffmpeg -i <输入文件> -vf scale=960:720 -aspect 4:3 <输出文件>' ... 和 ... 'ffmpeg -i <输入文件> -vf scale=1440:1080 -aspect 4:3 <输出文件>' ) 分别生成所需的 960x720 和 1440x1080 像素的视频文件。'-vf 比例=值:值' 有效地设置输出文件所需的高度(以像素为单位),而 '-方面值:值' 过滤器以像素为单位设置输出文件的所需宽度。

免责声明:当然,将非标准宽高比转换为标准尺寸时,必须有一些'伸展‘和/或’挤压' 不使用时的图像裁剪或者创可贴有时人们会这样称呼黑色条纹。关键是要确保生成的图像看起来不会异常怪异,这取决于每个观看者的欣赏能力。如果非标准尺寸与标准尺寸相当接近,那么我发现的结果是可以接受的。

我希望这个关于问题和解决方案的冗长的描述能够帮助其他正在努力解决形象问题的人。延展性

相关内容