維持影像比例不失真調整解析度計算方法

維持顯示比例調整解析度計算方法

名詞介紹

Width: 寬度,即橫軸像素數量
Height: 高度,即縱軸像素數量
Display Aspect Ratio (DAR) : 顯示比例
Pixel Aspect Ratio (PAR): 像素比例
Sample Aspect Ratio (SAR): 取樣比例 等同 PAR
Source Aspect Ratio (SAR): 原始比例 即 Width/Height

DAR = Width / Height * PAR

請注意: 一般說的 "Aspect (比例)" 指的是 "DAR (顯示比例)"
DAR 才是 播放時正確的比例

Wiki: https://en.wikipedia.org/wiki/Pixel_aspect_ratio



DAR = 8 / 8 * 1 / 1 = 1:1



DAR = 4 / 8 * 2 / 1 = 1:1

--------------------------------

常見標準比例為 4:3, 16:9, 2.39:1 (近代電影)
2.35:1 是舊的電影標準比例,目前稱呼為 2.35:1 的電影實際上是 2.39:1
或是 Resize 後的誤差使之接近 2.35:1
而影片的 PAR 通常為 1:1 (正方形像素)

記住: 部分影片的 並不是正方形像素
例如 解析度為 1440x1080 [PAR 4:3, DAR 16:9]
(某些 HDTV 就是使用此規格)

非正方形象素可以節省大量資料量,以及降低播放端需求
‧ 影片1: 1920x1080 [PAR 1:1, DAR 16:9] 像素數量 (畫素): 2073600
‧ 影片2: 1440x1080 [PAR 4:3, DAR 16:9] 像素數量 (畫素): 1555200

播放影片時,如果顯示器是1920x1080, PAR 1:1 (正方形像素,PC 標準)
因為螢幕是正方形像素,則影片 2 會被 Resize 至 1920x1080 輸出
如果直接輸出為 1440x1080, 會得到錯誤 DAR = 1440 / 1080 * 1 / 1 = 4:3,
原因可能是設定錯誤,或是播放器不認得 PAR 4:3

--------------------------------

常見的影片標準解析度與顯示比例:
規格 - 名稱 
‧ 3840x2160 [PAR 1:1, DAR 16:9] - UHD, 4K
‧ 1920x1080 [PAR 1:1, DAR 16:9] - Full HD, HD 1080
‧ 1440x1080 [PAR 4:3, DAR 16:9] - HD 1080
‧ 1280x720 [PAR 1:1, DAR 16:9] - HD 720
‧ 720x480 [PAR 40:33, DAR 20:11] - Full D1 NTSC 16:9
‧ 720x480 [PAR 10:11, DAR 45:33] - Full D1 NTSC 4:3
‧ 720x576 [PAR 16:11, DAR 20:11] - Full D1 PAL 16:9
‧ 720x576 [PAR 12:11, DAR 45:33] - Full D1 PAL 4:3
‧ 704x480 [PAR 40:33, DAR 16:9] - D1 NTSC 16:9
‧ 704x480 [PAR 10:11, DAR 4:3] - D1 NTSC 4:3
‧ 704x576 [PAR 16:11, DAR 16:9] - D1 PAL 16:9
‧ 704x576 [PAR 12:11, DAR 4:3] - D1 PAL 4:3

由以上可得知,處理 Full D1 片源時
必須左右各裁切8像素寬度,才可以得到正確的 16:9 或 4:3
(720 - 8 * 2) / 480 * 40 / 33 = 16:9

--------------------------------



維持顯示比例不變或接近,基本上誤差不要太大即可

令 InDAR ~= ScaleDAR = ScaleWidth * ScaleHeight * OutPAR

ScaleWidth = CustomScaleHeight / CustomPAR * InDAR
ScaleHeight = CustomScaleWidth * CustomPAR / InDAR

※ 此處InDAR 指的是縮放之前的 DAR,不是片源的 DAR。

片源若為 1440x1080 [PAR 4:3, DAR 16:9],上下裁切各 140 像素高度再進行縮放的話...

裁切後的 DAR:
CutDAR = 1440 / (1080 - 140 * 2) * 4 / 3 = 2.4

若要將解析度寬縮放到 1280 (正方形像素):
ScaleHeight = 1280 / 2.4 = 533.333... 取最接近的偶數 534

所以輸出設定為 1280x534 (PAR 1:1)


某些輸入影片其實本身顯示比例就有誤差或是錯誤
這時你可以代入你認為正確的顯示比例來計算
例如 常見的將 16:9 片源 被轉成 848x480 (PAR 1:1), DAR = 848/480*1/1 ~= 1.76666:1
如果你為了相容較低階設備,需要再降解析度到 640x480 (PAR 1:1)以下,
計算時把它的 DAR 當作 16/9 即可

ScaleHeight = 640 * 9 / 16 = 360

所以輸出設定為 640x360 (PAR 1:1)

--------------------------------

mod16, mod8, mod4, mod2

NewNum = Fix(Num / Modulus + 0.5) * Modulus

函數 Fix 功能為取整數(直接捨棄小數)
Fix(1.6) = 1
所以 Fix(Num + 0.5) 為 Num 的小數第一位四捨五入
Fix(1.6 + 0.5) = Fix(2.1) = 2

寬與高並非只要是正整數都可以
通常為 mod16 x mod8

Ex. 1280x533 修正為 mod16 x mod8

Width = Fix(1280 / 16 + 0.5) * 16 ~= Fix(80.5) * 16 = 80 * 16 = 1280

Height = Fix(533 / 8 + 0.5) * 8 ~= Fix(67.125) * 8 = 67 * 8 = 536

--------------------------------

誤差計算方式

DAR_Error = (InDAR - OutDAR) / InDAR * 100%

所以縮放後造成的顯示比例誤差為

DAR_Error = (InDAR - ScaleDAR) / InDAR * 100%

誤差控制在 -1% ~ +1% 內即可

※ 計算縮放後造成的顯示比例誤差 InDAR 帶入縮放之前的 DAR,不是片源的 DAR。

Ex.

片源: DAR 16:9
→ 裁黑邊後: DAR 2.39:1

輸出: 1280x536, PAR 1:1

OutDAR = 1280 / 536 * 1 / 1 ~= 2.338

DAR_Error ~= (2.39 - 2.338) / 2.39 * 100% ~= 0.08%
2014-08-17 15:50 #1
伸展(Stretch)

自訂目標寬與高度,調整像素寬高比以維持顯示比例。

OutPAR = CustomScaleHeight / CustomScaleWidth * InDAR


Ex.
片源: 1920x1080 PAR 1:1 (DAR 16:9)
輸出目標: 1440x1080

OutPAR = 1080 / 1440 * (16 / 9) = 4 / 3

DAR_Error = (16 / 9 - (1440 / 1080 * 4 / 3)) / (16 / 9) * 100% = 0%


符合寬度(Fit to Width)

自訂目標寬度,調整高度以維持顯示比例。

ScaleHeight = Fix((CustomScaleWidth * CustomPAR / InDAR) / Modulus + 0.5) * Modulus


Ex.
片源: 1440x1080 PAR 4:3 (DAR 16:9)
→ 上下裁切各 140 像素
輸出目標: 寬度1280、正方形像素 (PAR 1:1) 並維持顯示比例、高度取 8 的倍數。。

CutDAR = 1440 / (1080 - 140 * 2) * 4 / 3 = 2.4

ScaleHeight = Fix((1280 * 1 / 2.4) / 8 + 0.5) * 8 = 67 * 8 = 536

DAR_Error = (2.4 - (1280 / 536 * 1)) / 2.4 * 100% ~= 0.4975%

微調像素寬高比令 DAR_Error 為 0
承上,若播放器支援非正方形像素可以微調 PAR 使播放時顯示比例最接近 2.4:1

CustomPAR = 536 / 1280 * 2.4 = 1.005


符合高度(Fit to Height)

自訂目標高度,調整寬度以維持顯示比例。

ScaleWidth = Fix((CustomScaleHeight / CustomPAR * InDAR) / Modulus + 0.5) * Modulus


Ex.
片源: 1920x1080 PAR 1:1 (DAR 16:9)
輸出目標: 高度 480、正方形像素 (PAR 1:1) 並維持顯示比例、寬度取 16 的倍數。

ScaleWidth = Fix((480 / 1 * (16 / 9)) / 16 + 0.5) * 16 = 848

DAR_Error = ((848 / 480) - (16 / 9)) / (16 / 9) * 100% ~= -0.625%

微調像素寬高比令 DAR_Error 為 0
承上,若播放器支援非正方形像素可以微調 PAR 使播放時顯示比例最接近 16:9

CustomPAR = 480 / 848 * (16 / 9) = 30 / 53 * (16 / 9) = 480 / 477


符合寬與高度(Fit to Both)

符合寬或高度與像素寬高比,調整寬或高度以維持顯示比例。

ScaleWidth = Min(Width, Fix((Height / CustomPAR * InDAR) / 2 + 0.5) * 2)
ScaleHeight = Min(Height, Fix((Width * CustomPAR / InDAR) / 2 + 0.5) * 2)


Ex. 1.
片源: 1920x1080 PAR 1:1 (DAR 16:9)
→ 上下裁切各 140 像素
輸出目標: 縮小到 704x480 以下,且 PAR 40:33 並維持顯示比例。

CutDAR = 1920 / (1080 - 140 * 2) * 1 = 2.4

ScaleWidth = Min(704, Fix((480 * 2.4 / (40 / 33)) / 2 + 0.5) * 2) = Min(704, 950) = 704

ScaleHeight = Min(480, Fix((704 / 2.4 * (40 / 33)) / 2 + 0.5) * 2)= Min(480, 356) = 356

所以解析度縮放為 704x356 即小於 704x480 且 PAR 40:33 並維持顯示比例。

OutDAR = 704 / 356 * 40 / 33 ~= 2.397

DAR_Error = (2.4 - 2.397) / 2.4 * 100% = 0.125%

若再將上下各補上 62 高度的黑邊 (356+62*2=480):
則可以得到 D1 NTSC 16:9 - 704x480 [PAR 40:33, DAR 16:9]

若再將左右各補上 8 寬度的黑邊 (704+8*2=720):
則可以得到 Full D1 NTSC 16:9 - 720x480 [PAR 40:33, DAR 16:9]


Ex. 2.
片源: 1920x1080 PAR 1:1 (DAR 16:9)
→ 上下裁切各 140 像素
輸出目標: 縮小到 1280x720 以下取 mod16 x mod8、正方形像素 (PAR 1:1) 並維持顯示比例、。

CutDAR = 1920 / (1080 - 140 * 2) * 1 = 2.4

ScaleWidth = Min(1280, Fix((720 / 1 * 2.4) / 16 + 0.5) * 16) = Min(1280, 1728) = 1280

ScaleHeight = Min(720, Fix((1280 * 1 / 2.4) / 8 + 0.5) * 8)= Min(720, 536) = 536

DAR_Error = (2.4 - (1280 / 536)) / 2.4 * 100% ~= 0.4975%

微調像素寬高比令 DAR_Error 為 0
承上,若播放器支援非正方形像素可以微調 PAR 使播放時顯示比例最接近 2.4:1

CustomPAR = 536 / 1280 * 2.4 = 1.005
Letterbox

說明:
輸出某一解析度與像素寬高比,以填充黑邊方式維持比例不失真。



http://zh.wikipedia.org/wiki/%E9%BB%91%E9%82%8A


公式 1: 先 縮放解析度 再 填充黑邊

ScaleWidth = Min(CustomWidth, Fix((CustomHeight / CustomPAR * InDAR) / 2 + 0.5) * 2)

ScaleHeight = Min(CustomHeight, Fix((CustomWidth * CustomPAR / InDAR) / 2 + 0.5) * 2)

OutPAR = CustomPAR

PadWidth = CustomWidth

PadHeight = CustomHeight


公式 2: 先 填充黑邊 再 縮放解析度

PadWidth = Max(InWidth, Fix((InHeight / InPAR * OutDAR) / 2 + 0.5) *2 )

PadHeight = Max(InHeight, Fix((InWidth * InPAR / OutDAR) /2 + 0.5) *2 )

ScaleWidth = CustomScaleWidth

ScaleHeight = CustomScaleHeight

OutPAR = CustomPAR

※ 函數 Max 功能為取較大的數值


公式: 平均分配黑邊

X = (PadWidth - InWidth) / 2

Y = (PadHeight - InHeight) / 2

X1 = PadWidth - X

Y1 = PadHeight - Y
我有一個VOB檔(從DVD COPY出來的)
檔案訊息如下
Stream #0:1[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, bt470bg/smpte170m/smpte170m), 352x480 [SAR 20:11 DAR 4:3], max. 2982 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc


這個VOB我用POTPLAYER撥放時,"比例"
自動長寬比(推薦) 時,寬跟長分別是 312 跟 480
原始比例 時,寬跟長分別是 352 跟 480


這個312不太知道怎麼來的
我用352:480 20:11 4:3
怎麼湊就是算不出這個寬度


我想把影片透過ffmpeg轉成
檔案內容還是352x480
但用POTPLAYER播放時會變成640X480

PS
以前沒玩過轉檔時
有發現有些影片原始數據是窄的
但用POTPLAYER播放時會變成正常比例

我試了以下組合(數字是亂填的,只是想看有沒有效果)
-vf setdar=dar=11/15
-vf setdar=dar=4/3
-vf setdar=dar=20/11

-vf setsar=sar=11/15
-vf setsar=sar=4/3
-vf setsar=sar=20/11

-vf setdar=ratio=11/15
-vf setdar=ratio=4/3
-vf setdar=ratio=20/11

以上九個轉出來的檔案
用POTPLAYER播放時,"比例"
選 自動長寬比(推薦)或原始比例時時,寬跟長分別都是 352 跟 480

難道我只能用scale強制把352x480轉成640X480嗎?
謝謝
I love Vancouver!
我後來用scale達到我的目的了
可是我之前用scale是真的把影片像素變多欸
這次反而影片總像素沒變
難道跟input output 的container或是codec有關?


ffmpeg -i 1.MOV -filter:v scale=1920:1080 2.MOV
影片像素播放像素
轉檔前 1.MOV1792x1008 [SAR 1:1 DAR 16:9]1792X1008
轉檔後 2.MOV1920x1080 [SAR 1:1 DAR 16:9]1920X1080



ffmpeg -i VTS_01_1.VOB -vf scale=640:480 -vf unsharp=7:7:1.5:7:7:1.5 -c:v libx264 -x264-params crf=18 -an VTS_01_1.mp4
影片像素播放像素
轉檔前 VTS_01_1.VOB352x480 [SAR 20:11 DAR 4:3]352x480
轉檔後 VTS_01_1.mp4352x480 [SAR 20:11 DAR 4:3]640X480



PS
播放像素是指
用POTPLAYER撥放時
"比例"選自動長寬比(推薦)
I love Vancouver!
kobenein wrote:
352x480 [SAR 20:11 DAR 4:3]

這邊要注意一點
FFmpeg 的 SAR 指的是 Sample Aspect Ratio (取樣比例)
等同 Pixel Aspect Ratio (PAR, 像素比例)
不是 Source Aspect Ratio (SAR, 原始比例)
為了避免混淆以下皆用 PAR 稱呼

kobenein wrote:
這個VOB我用POTPLAYER撥放時,"比例"
選 自動長寬比(推薦) 時,寬跟長分別是 312 跟 480
選 原始比例 時,寬跟長分別是 352 跟 480


應該是 PotPlayer 誤認此 VOB 影片的 PAR、DAR
FFmpeg 告訴你的 DAR、SAR 才是正確的
DAR = Width / Height * PAR = 352 / 480 * 20 / 11 = 4 / 3

正常而言顯示器的 PAR 是 1:1,所以輸出應該是 640x480 才對
DAR = Width / Height * PAR = 640 / 480 * 1 / 1 = 4 / 3

kobenein wrote:
我想把影片透過ffmpeg轉成
檔案內容還是352x480
但用POTPLAYER播放時會變成640X480

FFmpeg 預設是維持輸出 DAR 與輸入相同
如果你改變了解析度,FFmpeg 會修改輸出的 PAR 使輸出 DAR 與輸入相同

FFmpeg 要是你沒指定輸出解析度與 PAR 或 DAR 的話
正常言要與原檔相同,也就是 352x480 [SAR 20:11 DAR 4:3]
只是這次 PotPlayer 播放此 FFmpeg 輸出的 MP4 影片並沒有誤判 PAR 或 DAR
所以輸出是正確的 640x480 (DAR 4:3)

kobenein wrote:
難道我只能用scale強制把352x480轉成640X480嗎?

像素數量變多你必須給更高 bitrate 才能達到目標品質
我是建議轉成視訊 H.264 編碼格式
但畫面維持與原檔相同的 352x480 [SAR 20:11 DAR 4:3]
應該不會有撥放器認錯 H.264 的 PAR,就算認錯也可手動強制播放比例為 4:3

如果你非得要輸出 PAR 1:1 與 DAR 4:3,可以考慮以下解析度
1. 640x480, 2. 352x264, 3. 320x240
提高解析度會浪費大量 bitrate,而降解析度會損失細節,通常都是選後者

----------------

最後補充一點
Resize 直接如同上面那樣 丟個 方程式 讓 ffmpeg 自己去計算即可
省得一堆麻煩

kingdragon wrote:
影片 Resize 維持顯示比例計算方式

寫的不錯.
☆ 私人訊息直接刪除不再回覆 ☆ 願望 : bovuhPPjMnEfkyhggnsJdABaLFPuhXT4
限制級
您即將進入之討論頁 需滿18歲 方可瀏覽。
提醒:內容可能因過於寫實、驚悚而令人感到不舒服,是否繼續觀看?

根據「電腦網路內容分級處理辦法」修正條文第六條第三款規定,已於該限制級網頁,依台灣網站分級推廣基金會規定作標示。
評分
複製連結