常用視頻像素格式NV12、NV21鳍烁、I420叨襟、YV12、YUYV

最近因為任務需要幔荒,遇到視頻像素格式的問題糊闽,學習了NV12和YV12,以及UYVY的具體存儲區(qū)別爹梁。

總結如下:

像素格式描述了像素數(shù)據(jù)存儲所用的格式右犹,定義了像素在內(nèi)存中的編碼方式,RGB和YUV是兩種經(jīng)常使用的像素格式姚垃。

RGB:較為熟悉念链,具有3個通道R G B,分別對應紅 綠 藍三個分量,由三個分量的值決定顏色掂墓;通常谦纱,會給RGB圖像加一個通道alpha,即透明度梆暮,于是共有四個分量共同控制顏色服协。(常用的opencv庫默認將圖片以BGR的方式進行存儲绍昂,只是通道順序不一樣而已)

YUV:(YCrCb)是指將亮度參量Y和色度參量U/V分開表示的像素格式啦粹,主要用于優(yōu)化彩色視頻信號的傳輸。

YUV像素格式來源于RGB像素格式窘游,通過公式運算唠椭,YUV三分量可以還原出RGB,YUV轉RGB的公式如下:

R = Y + 1.403V
G = Y - 0.344U - 0.714V
B = Y + 1.770U

一般忍饰,將RGB和YUV的范圍均限制在[0,255]間贪嫂,則有如下轉換公式:

R = Y + 1.403(V - 128)
G = Y - 0.344(U - 128) - 0.714(V - 128)
B = Y + 1.770(U - 128)

YUV采樣:YUV相比于RGB格式最大的好處是可以做到在保持圖像質量降低不明顯的前提下,減小文件大小艾蓝。YUV格式之所以能夠做到力崇,是因為進行了采樣操作。

YUV碼流的存儲格式與其采樣方式密切相關赢织,主流的采樣方式有3種:

YUV 4:4:4(YUV444), YUV 4:2:2(YUV422), YUV 4:2:0(YUV420)

若以以黑點表示采樣該像素點的Y分量亮靴,以空心圓圈表示采用該像素點的UV分量,則這三種采樣方式如下:

即:

YUV 4:4:4采樣于置,每一個Y對應一組UV分量茧吊。
YUV 4:2:2采樣,每兩個Y共用一組UV分量八毯。
YUV 4:2:0采樣搓侄,每四個Y共用一組UV分量。

YUV存儲格式

YUV存儲可以分為兩種:packed(打包)和planar(平面)话速;

packed:Y讶踪、U、V分量穿插著排列泊交,三個分量存在一個Byte型數(shù)組里乳讥;
planar:Y、U活合、V分量分別存在三個Byte型數(shù)組中雏婶;

常見的像素格式

1.YUV422:YUYV、YVYU白指、UYVY留晚、VYUY

這四種格式每一種又可以分為2類(packed和planar),以YUYV為例,一個6*4的圖像的存儲方式如下:

Y Y Y Y Y Y                   
Y Y Y Y Y Y                  
Y Y Y Y Y Y                   
Y Y Y Y Y Y                    
U U U U U U                  Y U Y V Y U Y V Y U Y V
U U U U U U                  Y U Y V Y U Y V Y U Y V
V V V V V V                  Y U Y V Y U Y V Y U Y V
V V V V V V                  Y U Y V Y U Y V Y U Y V
- Planar -                          - Packed:YUYV - 
 
Y Y Y Y Y Y                   
Y Y Y Y Y Y                  
Y Y Y Y Y Y                   
Y Y Y Y Y Y                    
U U U U U U                  U Y V Y U Y V Y U Y V Y
U U U U U U                  U Y V Y U Y V Y U Y V Y
V V V V V V                  U Y V Y U Y V Y U Y V Y
V V V V V V                  U Y V Y U Y V Y U Y V Y
- Planar -                          - Packed:UYVY - 

如果實際應用中错维,從camera那邊取到的數(shù)據(jù)流是UYVY的格式奖地,但是gl顯示或者圖像處理的相關接口又需要用到BGR或I420(YV12或NV12)的格式,那么就需要寫代碼進行轉換(下面給出一些示例代碼片段):

如果要用opencv的接口將UYVY格式轉成YV12格式(則需要先從UYVY轉成BGR或RGB,再將BGR或RGB轉成YV12):

//pSrcBuf的存儲格式是UYVY
cv::Mat yuv_img = cv::Mat(height, width, CV_8UC2, pSrcBuf);
cv::Mat bgr_img;
cv::cvtColor(yuv_img, bgr_img, CV_YUV2BGR_UYVY);
 
//pDstBuf的存儲格式是YV12
cv::Mat yv12_img = cv::Mat(height* 3/2, width, CV_8UC1, pDstBuf);
cv::cvtColor(bgr_img, yv12_img, CV_BGR2YUV_YV12);

所以下面直接手動轉換赋焕,而不調(diào)用opencv的cv::cvtColor接口來轉換参歹,也可以進一步熟悉存儲格式規(guī)范。

//從UYVY中獲取Y隆判,并存到一個數(shù)組
void UYVYToYRow(const char* src_uyvy, char* dst_y, int width) {
  // Output a row of Y values.
  for (int x = 0; x < width - 1; x += 2) {
    dst_y[x] = src_uyvy[1];
    dst_y[x + 1] = src_uyvy[3];
    src_uyvy += 4;
  }
 
}
//從UYVY中獲取UV犬庇,并分別存到2個數(shù)組
void UYVYToUVRow(const char* src_uyvy, int src_stride_uyvy,
                   char* dst_u, char* dst_v, int width) {
  // Output a row of UV values.
  for (int x = 0; x < width-1 ; x += 2) {
    dst_u[0] = src_uyvy[0];
    dst_v[0] = src_uyvy[2];
    src_uyvy += 4;
    dst_u += 1;
    dst_v += 1;
  }
}
int UYVYToI420(const char* src_uyvy, int src_stride_uyvy,
               char* dst_y, int dst_stride_y,
               char* dst_u, int dst_stride_u,
               char* dst_v, int dst_stride_v,
               int width, int height) {
 
 
  for (int y = 0; y < height - 1; y += 2) {
    UYVYToUVRow(src_uyvy, src_stride_uyvy, dst_u, dst_v, width);
    UYVYToYRow(src_uyvy, dst_y, width);
    UYVYToYRow(src_uyvy + src_stride_uyvy, dst_y + dst_stride_y, width);
    src_uyvy += src_stride_uyvy * 2;
    dst_y += dst_stride_y * 2;
    dst_u += dst_stride_u;
    dst_v += dst_stride_v;
 
  }
  
  return 0;
}
 
 
UYVYToI420( pSrcBuf, w*2,
            pDstBuf, w,
            pDstBuf + (w*h+w*h/4), w/2, // Put V channel first for YV12
            pDstBuf + (w*h), w/2,            
            w, h
          );

那么我如何驗證轉換前后的格式是否正確呢?可以分別用cv::cvtColor以及cv::imwrite將圖像dump到本地查看和對比:

//pSrcBuf的存儲格式是UYVY
cv::Mat yuv_img = cv::Mat(height, width, CV_8UC2, pSrcBuf);
cv::Mat bgr_img_src;
cv::cvtColor(yuv_img, bgr_img_src, CV_YUV2BGR_UYVY);
cv::imwrite("UYVY.png", bgr_img_src);
 
//pDstBuf的存儲格式是YV12
cv::Mat yv12_img = cv::Mat(height* 3/2, width, CV_8UC1, pDstBuf);
cv::Mat bgr_img_dst;
cv::cvtColor(picYV12, bgr_img_dst, CV_YUV2BGR_YV12);
cv::imwrite("YV12.png", bgr_img_dst);
  1. YUV420

    YUV420p: I420侨嘀、YV12
    YUV420sp: NV12臭挽、NV21

同樣,對于一個6*4的圖像咬腕,這四種像素格式的存儲方式如下:

Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y
Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y
Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y
Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y
U U U U U U      V V V V V V      U V U V U V      V U V U V U
V V V V V V      U U U U U U      U V U V U V      V U V U V U
 - I420 -          - YV12 -         - NV12 -         - NV21 -

注:

I420欢峰、YV12三個分量均為平面格式,即分別存在三個Byte型數(shù)組中涨共;
NV12纽帖、NV21的存儲格式為Y平面,UV打包举反,即Y信息存儲在一個數(shù)組中懊直,UV信息存儲在一個矩陣中。

原文鏈接:https://blog.csdn.net/Fan0920/article/details/103710014

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末照筑,一起剝皮案震驚了整個濱河市吹截,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌凝危,老刑警劉巖波俄,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蛾默,居然都是意外死亡懦铺,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門支鸡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來冬念,“玉大人,你說我怎么就攤上這事牧挣〖鼻埃” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵瀑构,是天一觀的道長裆针。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么世吨? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任澡刹,我火速辦了婚禮,結果婚禮上耘婚,老公的妹妹穿的比我還像新娘罢浇。我一直安慰自己,他們只是感情好沐祷,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布嚷闭。 她就那樣靜靜地躺著,像睡著了一般戈轿。 火紅的嫁衣襯著肌膚如雪凌受。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天思杯,我揣著相機與錄音,去河邊找鬼挠进。 笑死色乾,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的领突。 我是一名探鬼主播暖璧,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼君旦!你這毒婦竟也來了澎办?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤金砍,失蹤者是張志新(化名)和其女友劉穎局蚀,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恕稠,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡琅绅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鹅巍。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片千扶。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖骆捧,靈堂內(nèi)的尸體忽然破棺而出澎羞,到底是詐尸還是另有隱情,我是刑警寧澤敛苇,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布妆绞,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏摆碉。R本人自食惡果不足惜塘匣,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望巷帝。 院中可真熱鬧忌卤,春花似錦、人聲如沸楞泼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽堕阔。三九已至棍厂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間超陆,已是汗流浹背牺弹。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留时呀,地道東北人张漂。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像谨娜,于是被迫代替她去往敵國和親航攒。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345