YUV

在開(kāi)始學(xué)習(xí)YUV之前,先向大家介紹一款查看YUV圖像的查看工具---YUV Eye,這個(gè)工具會(huì)非常方便調(diào)試

1.YUV 概念

YUV 是一種表示顏色的模型,跟RGB是同一個(gè)級(jí)別的概念,通常用YCbCr這樣的形式表示,其中Y是指亮度分量,Cb指藍(lán)色色度分量,而Cr指紅色色度分量

2.YUV 和 RGB 比較

2.1 體積對(duì)比RGB更小
  • 如果使用RGB
比如RGB888 (R、G、B、每個(gè)分量都是8bit),那么
一個(gè)像素占用24bit
  • 如果使用YUV
1個(gè)像素可以減少至平均只占用12bit(1.5字節(jié))
2.2 組成
  • RGB 數(shù)據(jù)由R、G、B三個(gè)分量組成;
  • YUV數(shù)據(jù)由Y、U、V三個(gè)分量組成,現(xiàn)在通常說(shuō)的YUV指的是YCbCr
Y:表示亮度(Luminance、Luma),占8bit(1字節(jié))
Cb、Cr:表示色度(Chrominance、Chroma)
- Cb(U):藍(lán)色色度分量,占8bit(1字節(jié))
- Cr(V):紅色色度分量,占8bit(1字節(jié))

3.計(jì)算公式

3.1 計(jì)算公式1
Y = 0.257R + 0.504G + 0.098B + 16
U = -0.148R - 0.291G + 0.439B + 128
V = 0.439R - 0.368G - 0.071B + 128
 
R = 1.164(Y - 16) + 2.018(U - 128)
G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
B = 1.164(Y - 16) + 1.596(V - 128)
  • RGB的取值范圍是[0,255]
  • Y的取值范圍是[16,235]
  • UV的取值范圍是[16,239]
3.2 計(jì)算公式2
Y = 0.299R + 0.587G + 0.114B
U = 0.564(B - Y) = -0.169R - 0.331G + 0.500B
V = 0.713(R - Y) = 0.500R - 0.419G - 0.081B
 
R = Y + 1.403V
G = Y - 0.344U - 0.714V
B = Y + 1.770U
  • RGB的取值范圍是[0, 1]
  • Y的取值范圍是[0, 1]
  • UV的取值范圍是[-0.5, 0.5]
3.3 計(jì)算公式3
Y = 0.299R + 0.587G + 0.114B
U = -0.169R - 0.331G + 0.500B + 128
V = 0.500R - 0.419G - 0.081B + 128
 
R = Y + 1.403(V - 128)
G = Y - 0.343(U - 128) - 0.714(V - 128)
B = Y + 1.770(U - 128)
  • RGB的取值范圍是[0, 255]
  • YUV的取值范圍是[0, 255]

4.YUV 格式

YUV格式.png
5.分類(lèi)標(biāo)準(zhǔn)

我們可以將YUV格式按照數(shù)據(jù)大小分為三個(gè)格式,YUV420,YUV422,YUV444,另外因?yàn)槿搜壑杏猩蟽|個(gè)感光細(xì)胞,其中視桿細(xì)胞占了95%,而視錐細(xì)胞僅占5%。因此,人眼對(duì)亮度的敏感程度要高于對(duì)色度的敏感程度,人眼對(duì)于亮度的分辨要比對(duì)顏色的分辨精細(xì)一些。
如果把圖像的色度分量減少一些,人眼也絲毫感覺(jué)不到變化和差異

- 視桿細(xì)胞
感知光線的強(qiáng)弱
沒(méi)有色彩識(shí)別功能
負(fù)責(zé)夜間非彩色視覺(jué)

- 視錐細(xì)胞
感知顏色
負(fù)責(zé)白天彩色視覺(jué)
如果你的視錐細(xì)胞發(fā)育不正常,數(shù)量太少,那感知顏色就會(huì)受阻,可能會(huì)導(dǎo)致你色弱
5.1 采樣格式

采樣格式通常使用A:B:C的形式來(lái)表示,比如4:4:4、4:2:2、4:2:0 等

A:一塊A*2個(gè)像素的概念區(qū)域,一般都是4
B:第1行的色度采樣數(shù)目
C:第2行的色度采樣數(shù)目
- C的值一般要么等于B,要么等于0

前面已經(jīng)說(shuō)過(guò)人眼對(duì)Y的敏感度遠(yuǎn)超過(guò)于對(duì)U和V的敏感,所以有時(shí)候可以多個(gè)Y分量共用一種UV,這樣既可以極大得節(jié)省空間,又可以不太損失質(zhì)量。

  • YUV 420,由4個(gè)Y分量共用一套UV分量

  • YUV 422,由2個(gè)分量共用一套UV分量

  • YUV 444,不共用,一個(gè)Y分量使用一套UV分量
    下面進(jìn)行圖文解釋一下:?代表亮度,??代表色度

  • 4:4:4

  • 第一行采集4組CbCr分量,第二行采集4組CbCr分量

  • 第一個(gè)像素都有自己獨(dú)立的1組分量

    • Y分量與CbCr分量的水平方向比例是1:1(每1列都有1組CbCr分量)
    • Y分量與CbCr分量的垂直方向比例是1:1 (每1行都有1組CbCr分量)
    • Y分量與CbCr分量的總比例是1:1
  • 1個(gè)像素占用24bit(3字節(jié)),跟RGB888體積一樣

    • 24bpp(bits per pixel)


      YUV444.png
  • 4:2:2

  • 第一行采集2組CbCr分量,第二行采集2組CbCr分量

  • 水平方向相鄰的2個(gè)像素(1行2列)共用1組CbCr分量

    • Y分量與CbCr分量的水平方向比例是2:1(每2列就有1組CbCr分量)
    • Y分量與CbCr分量的垂直方向比例是1:1(每1行都有1組CbCr分量)
    • Y分量與CbCr分量的總比例是2:1
  • 1個(gè)像素平均占用16bit(2字節(jié))

    • 16bpp
    • 因?yàn)?個(gè)像素共占用32bit(4字節(jié) = 2個(gè)Y分量 + 1個(gè)Cb分量 + 1個(gè)Cr分量)


      YUV422.png
  • 4:2:0

  • 第一行采集2組CbCr分量,第二行共享第一行的CbCr分量

    • Y分量與CbCr分量的水平方向比例是2:1(每2列就有1組CbCr分量)
    • Y分量與CbCr分量的垂直方向比例是2:1(每2行就有1組CbCr分量)
    • Y分量與CbCr分量的總比例是4:1
  • 1個(gè)像素平均占用12bit(1.5 字節(jié))

    • 12bpp
    • 因?yàn)?個(gè)像素共占用48bit(6字節(jié) = 4個(gè)Y分量 + 1個(gè)Cb分量 + 1個(gè)Cr分量)


      YUV420.png
按照多個(gè)Y分量共用一個(gè)UV的方式,我們可以把YUV分為420,422,444 三種類(lèi)型,而在這三種類(lèi)型之下,我們又可以按照YUV的排列存儲(chǔ)順序,將其細(xì)分為好多種格式

6.存儲(chǔ)格式

存儲(chǔ)格式,決定了YUV數(shù)量是如何排列和存儲(chǔ)的


YUV格式.png
6.1 分類(lèi)
YUV的存儲(chǔ)格式可以分為3大類(lèi):
  • Plannar 平面
Y、U、V分量單獨(dú)存儲(chǔ)
名稱(chēng)通常以字母p結(jié)尾
  • Semi-Plannar(半平面)
Y分量單獨(dú)存儲(chǔ),U、V分量交錯(cuò)存儲(chǔ)
名稱(chēng)通常以字母sp結(jié)尾
  • Packed(緊湊)
或者叫Interleaved,YUV分量交錯(cuò)存儲(chǔ)
6.2 具體分類(lèi)

4:4:4

  • Plannar
  • I444
Y Y Y Y
Y Y Y Y
U U U U
U U U U
V V V V
V V V V
  • YV24
Y Y Y Y
Y Y Y Y
V V V V
V V V V
U U U U
U U U U
  • Semi-Plannar
  • NV24
Y Y Y Y
Y Y Y Y
U V U V U V U V
U V U V U V U V
  • NV42
Y Y Y Y
Y Y Y Y
V U V U V U V U
V U V U V U V U

4:2:2

  • Plannar
  • I422
Y Y Y Y
Y Y Y Y
U U
U U
V V
  • YV16
Y Y Y Y
Y Y Y Y
V V
V V
U U
U U
  • Semi-Plannar
  • NV16
Y Y Y Y
Y Y Y Y
U V U V
U V U V
  • NV61
Y Y Y Y
Y Y Y Y
V U V U
V U V U
  • Packed
  • UYVY
U Y V Y U Y V Y
U Y V Y U Y V Y
  • YUYV
Y U Y V Y U Y V
Y U Y V Y U Y V
  • YVYU
Y V Y U Y V Y U
Y V Y U Y V Y U

4:2:0

  • Plannar
  • I420 屬于YUV 420 Plannar 的一種,YUV分量分別存放,先是w * h 長(zhǎng)度的Y,后面跟著w * h * 0.25 長(zhǎng)度的U,最后是w * h * 0.25長(zhǎng)度的V,總長(zhǎng)度為w * h * 1.5;
Y Y Y Y
Y Y Y Y
U U
V V
  • YV12
Y Y Y Y
Y Y Y Y
V V
U U
  • Semi-Plannar
  • NV12
Y Y Y Y
Y Y Y Y
U V U V
  • NV21
Y Y Y Y
Y Y Y Y
V U V U

7 格式轉(zhuǎn)換

71.其他圖片格式轉(zhuǎn)YUV

ffmpeg -i in.png -s width*height -pix_fmt yuv420p out.yuv

 ? songlin@feng-sl  ~/audio/YUV   master ±  ffmpeg -i in.png -s 686x370 -pix_fmt yuv420p out.yuv
ffmpeg version 4.3.2 Copyright (c) 2000-2021 the FFmpeg developers
  built with Apple clang version 12.0.0 (clang-1200.0.32.29)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.3.2_4 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
Input #0, png_pipe, from 'in.png':
  Duration: N/A, bitrate: N/A
    Stream #0:0: Video: png, rgba(pc), 686x370, 25 tbr, 25 tbn, 25 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (png (native) -> rawvideo (native))
Press [q] to stop, [?] for help
Output #0, rawvideo, to 'out.yuv':
  Metadata:
    encoder         : Lavf58.45.100
    Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 686x370, q=2-31, 75480 kb/s, 25 fps, 25 tbn, 25 tbc
    Metadata:
      encoder         : Lavc58.91.100 rawvideo
frame=    1 fps=0.0 q=-0.0 Lsize=     369kB time=00:00:00.04 bitrate=75480.0kbits/s speed=5.16x
video:369kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%

上面命令生成的yuv文件大小是:imageSize = width * height = 686 * 370 * 1.5 = 380730 字節(jié)

  • - s
  • 設(shè)置圖片的尺寸
  • 可以使用一些固定字符串表示尺寸,比如hd720表示1280 * 720
  • 如果不設(shè)置此項(xiàng),默認(rèn)會(huì)跟隨輸入圖片的尺寸
  • -pix_fmt
  • 設(shè)置像素格式
  • 可以通過(guò)ffmpeg -pix_fmts 查看FFmpeg支持的像素格式
  • 如果不設(shè)置此選項(xiàng),默認(rèn)會(huì)跟隨輸入圖片的像素格式
    • 比如可能是rgb24,rgba8,pal8等
    • 可以通過(guò)ffprobe查看某圖片的像素格式,比如ffprobe in.png
7.2 YUV 轉(zhuǎn)其他圖片格式

ffmpeg -s 680x370 -pix_fmt yuv420p -i out.yuv out.jpg

songlin@feng-sl  ~/audio/YUV   master ±  ffmpeg -s 686x370 -pix_fmt yuv420p -i out.yuv out.jpg
ffmpeg version 4.3.2 Copyright (c) 2000-2021 the FFmpeg developers
  built with Apple clang version 12.0.0 (clang-1200.0.32.29)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.3.2_4 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
[rawvideo @ 0x7f924b809600] Estimating duration from bitrate, this may be inaccurate
Input #0, rawvideo, from 'out.yuv':
  Duration: 00:00:00.04, start: 0.000000, bitrate: 75480 kb/s
    Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 686x370, 75480 kb/s, 25 tbr, 25 tbn, 25 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> mjpeg (native))
Press [q] to stop, [?] for help
[swscaler @ 0x7f924b086000] deprecated pixel format used, make sure you did set range correctly
[swscaler @ 0x7f924b086000] Warning: data is not aligned! This can lead to a speed loss
Output #0, image2, to 'out.jpg':
  Metadata:
    encoder         : Lavf58.45.100
    Stream #0:0: Video: mjpeg, yuvj420p(pc), 680x370, q=2-31, 200 kb/s, 25 fps, 25 tbn, 25 tbc
    Metadata:
      encoder         : Lavc58.91.100 mjpeg
    Side data:
      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: N/A
frame=    1 fps=0.0 q=4.0 Lsize=N/A time=00:00:00.04 bitrate=N/A speed=8.71x
video:24kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown

8 顯示YUV

8.1 完整YUV

可以通過(guò)ffplay顯示YUV數(shù)據(jù)

  • YUV中直接存儲(chǔ)的是所有像素的顏色信息,可以理解為原始數(shù)據(jù)
  • 必須得設(shè)置YUV的尺寸(-s)、像素格式(-pix_fmt)才能正常顯示,和音頻pcm播放的時(shí)候需要設(shè)置采樣率(-ar)、聲道數(shù)(-ac)、采樣格式(-f)類(lèi)似
fplay -s 686x370 -pix_fmt yuv420p out.yuv
ffplay version 4.3.2 Copyright (c) 2003-2021 the FFmpeg developers
  built with Apple clang version 12.0.0 (clang-1200.0.32.29)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.3.2_4 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
Option -s is deprecated, use -video_size.
Option -pix_fmt is deprecated, use -pixel_format.
//可以看到我們上面輸入的兩個(gè)參數(shù)有一些已經(jīng)過(guò)期了,建議我們使用新參數(shù)
ffplay -video_size 686x370 -pixel_format yuv420p out.yuv
ffplay-yuv.png
8.2 單個(gè)分量

可以使用過(guò)濾器filter 顯示其中的單個(gè)分量(r、g、b、y、u、v)

  • 只顯示r分量
 ffplay -vf extractplanes=r in.png
ffplay-r.png
  • 只顯示g分量
ffplay -vf extractplanes=g in.png
ffplay-g.png
  • 只顯示b分量
ffplay -vf extractplanes=b in.png
ffplay-b.png
  • 只顯示y分量
ffplay -video_size 686x370 -pixel_format yuv420p -vf extractplanes=y out.yuv
ffplay-y.png
  • 只顯示u分量
ffplay -video_size 686x370 -pixel_format yuv420p -vf extractplanes=u out.yuv
ffplay-u.png
  • 只顯示v分量
ffplay -video_size 686x370 -pixel_format yuv420p -vf extractplanes=v out.yuv
ffplay-v.png

可以看到顯示U分量和V分量的時(shí)候,圖片的面積會(huì)變小,這個(gè)就是存儲(chǔ)格式導(dǎo)致的,4:2:0的存儲(chǔ)格式水平和垂直Y和UV分量比例都是2:1,所以整體就是4:1,所以面積會(huì)變小

好了YUV的介紹,到這里差不多了

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容