全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:3880
推到 Plurk!
推到 Facebook!

關於yuv的問題.....

答題得分者是:JerryKuo
even
一般會員


發表:12
回覆:17
積分:5
註冊:2003-07-18

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-08-12 11:59:16 IP:210.70.xxx.xxx 未訂閱
input檔為一qcif.yuv(4,1,1)176*144的檔案.... frame數為450張...現在想由pBitmap來秀出每一張frame... 程式碼如下..
y =Yraw2array(FileName.c_str(),w, h, frame_no);//取出Y的raw data
u =Uraw2array(FileName.c_str(),w, h, frmae_no);//取出U的raw data
v =Vraw2array(FileName.c_str(),w, h, frame_no);//取出V的raw data
array2bmp(y,u,v,w,h,pBitmap);
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
void array2bmp(int *y,int *u,int *v,int w,int h,Graphics::TBitmap *bmp)
{
 Byte *ptr;
 float R,G,B;
 bmp->Height=h;
 bmp->Width=w;
 for(int y=0;yScanLine[y];
   for(int x=0;xPicture->Assign(bmp);
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
int* Yraw2array(char* FileName, int w, int h, int frame_no)
{
  int* temp1 = new int[w*h];
  unsigned char* temp2 =new unsigned char[w*h];
  FILE* p;
  p=fopen(FileName,"rb");
  fseek(p,frame_no*w*h,SEEK_SET);
  fread(temp2,w*h,1,p);
  for(int a=0;a
不知是那出了問題....
麻煩大大們指點一下囉.....         
        
JerryKuo
版主


發表:42
回覆:571
積分:322
註冊:2003-03-10

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-08-12 12:36:48 IP:61.230.xxx.xxx 未訂閱
你好: 請問問題在哪? 有錯嗎? 錯誤訊息是什麼?
even
一般會員


發表:12
回覆:17
積分:5
註冊:2003-07-18

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-08-12 12:49:51 IP:210.70.xxx.xxx 未訂閱
呈現出來的圖像是錯誤地.. 我想可能是我在捉u、v的raw data時出了錯吧... 不過...我不知道如修改它....
brook
資深會員


發表:57
回覆:323
積分:371
註冊:2002-07-12

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-08-12 13:20:40 IP:218.160.xxx.xxx 未訂閱
之前曾用過ScanLine,但在不同的電腦會有不同的結果,不知你的問題是不是也是如此. 你要轉換成Byte, 那先把PixelFormat先轉成8bit試看看. bmp->PixelFormat = pf8bit; ptr=(Byte *)bmp->ScanLine[y];
even
一般會員


發表:12
回覆:17
積分:5
註冊:2003-07-18

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-08-12 13:34:36 IP:210.70.xxx.xxx 未訂閱
謝謝brook的回應... 之前我是設24bit.... 現在修改過後還是不行....
JerryKuo
版主


發表:42
回覆:571
積分:322
註冊:2003-03-10

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-08-12 13:41:39 IP:61.230.xxx.xxx 未訂閱
你好:    我有幾個問題,你先試試改看看 1.在array2bmp()函數裡,輸入值y,u,v。結果y被拿來當index,反而是出現g這個 陣列,這compiler會過嗎?.. 2.來源檔案是176x144raw_data,YUV比例是4:1:1,所以Y檔的像素應為176x144 U和V分別是44x36。讀檔時要注意 3.假設讀檔成功,在使用上,是4個Y搭配一對UV,舉個例,也就是(0,0),(1,0), (0,1),(1,1)四個點的Y值,搭配(0,0)的U和V值。在你的程式好像沒有用到這 幾個設定。    試試看吧    
引言: input檔為一qcif.yuv(4,1,1)176*144的檔案.... frame數為450張...現在想由pBitmap來秀出每一張frame... 程式碼如下..
y =Yraw2array(FileName.c_str(),w, h, frame_no);//取出Y的raw data
u =Uraw2array(FileName.c_str(),w, h, frmae_no);//取出U的raw data
v =Vraw2array(FileName.c_str(),w, h, frame_no);//取出V的raw data
array2bmp(y,u,v,w,h,pBitmap);
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
void array2bmp(int *y,int *u,int *v,int w,int h,Graphics::TBitmap *bmp)
{
 Byte *ptr;
 float R,G,B;
 bmp->Height=h;
 bmp->Width=w;
 for(int y=0;yScanLine[y];
   for(int x=0;xPicture->Assign(bmp);
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
int* Yraw2array(char* FileName, int w, int h, int frame_no)
{
  int* temp1 = new int[w*h];
  unsigned char* temp2 =new unsigned char[w*h];
  FILE* p;
  p=fopen(FileName,"rb");
  fseek(p,frame_no*w*h,SEEK_SET);
  fread(temp2,w*h,1,p);
  for(int a=0;a
不知是那出了問題....
麻煩大大們指點一下囉.....         
even
一般會員


發表:12
回覆:17
積分:5
註冊:2003-07-18

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-08-12 14:26:57 IP:210.70.xxx.xxx 未訂閱
謝謝JerryKuo的回應.... 關於3點.. 第一點---哈..是我地筆誤啦....所以這點ok 第二點---嗯嗯...修改過了.....讀檔不會有問題..... 第三點---嘿嘿..小女子笨笨....不知如何下手... 是將各別讀到的值在全部放於另一個array裡嗎???還是.... 能否再給予指導呢...^^
JerryKuo
版主


發表:42
回覆:571
積分:322
註冊:2003-03-10

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-08-12 14:44:55 IP:61.230.xxx.xxx 未訂閱
引言: 謝謝JerryKuo的回應.... 關於3點.. 第一點---哈..是我地筆誤啦....所以這點ok 第二點---嗯嗯...修改過了.....讀檔不會有問題..... 第三點---嘿嘿..小女子笨笨....不知如何下手... 是將各別讀到的值在全部放於另一個array裡嗎???還是.... 能否再給予指導呢...^^
你原本的做法就行得通,只是不知道你讀出來的檔是否正確,試著把 y,u,v三個陣例show出來,你應該會看到三張圖是否正確。然後再合 成為RGB。
brook
資深會員


發表:57
回覆:323
積分:371
註冊:2002-07-12

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-08-12 16:55:17 IP:218.160.xxx.xxx 未訂閱
引言: 3.假設讀檔成功,在使用上,是4個Y搭配一對UV,舉個例,也就是(0,0),(1,0), (0,1),(1,1)四個點的Y值,搭配(0,0)的U和V值。在你的程式好像沒有用到這 幾個設定。
int* Yraw2array(char* FileName, int w, int h, int frame_no)
{
  int* temp1 = new int[w*h];    // 假如是4份的話應該多乘4
  unsigned char* temp2 =new unsigned char[w*h*4];       FILE* p;
  p=fopen(FileName,"rb");
  fseek(p,frame_no*w*h,SEEK_SET);
  
// 假如是4份的話
  fread(temp2,w*h,4,p);      for(int a=0;a        發表人 - brook 於 2003/08/12  17:04:42
        
even
一般會員


發表:12
回覆:17
積分:5
註冊:2003-07-18

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-08-12 21:33:05 IP:210.70.xxx.xxx 未訂閱
修改了下... 程式如下...
f =Yraw2array(FileName.c_str(),w, h, frame_no);
u =Uraw2array(FileName.c_str(),w, h, frame_no);
v =Vraw2array(FileName.c_str(),w, h, frame_no);
array2bmp(f,u,v,w,h,pBitmap);
bmp_disp(pBitmap,Image1);
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
int* Yraw2array(char* FileName, int w, int h, int frame_no)
{
  int* temp1 = new int[w*h];
  unsigned char* temp2 =new unsigned char[w*h];
  FILE* p;
  p=fopen(FileName,"rb");
  fseek(p,frame_no*w*h*1.5,SEEK_SET);
  fread(temp2,w*h,1,p);
  for(int a=0;a(0,0)
    for(int i=0;i<2;i  ){    //不知有沒有錯....
     for(int j=0;j<2;j  ){
     temp1[2*a i j*w]=temp2[a];
     }
    }
  }
  fclose(p);
  return temp1;
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
int* Vraw2array(char* FileName, int w, int h, int frame_no)
{
  int* temp1 = new int[w*h];
  unsigned char* temp2 =new unsigned char[w*h];
  FILE* p;
  p=fopen(FileName,"rb");
  fseek(p,frame_no*w*h*1.5 w*h*5/4,SEEK_SET);
  fread(temp2,w*h/4,1,p);
  for(int a=0;aHeight=h;
bmp->Width=w;
 for(int y=0;yPixelFormat =pf24bit;
   ptr=(Byte *)bmp->ScanLine[y];
   for(int x=0;xPicture->Assign(bmp);
}
麻煩各位大大幫幫忙...... 看看是那寫錯了.. 謝謝....
brook
資深會員


發表:57
回覆:323
積分:371
註冊:2002-07-12

發送簡訊給我
#11 引用回覆 回覆 發表時間:2003-08-13 09:10:17 IP:218.160.xxx.xxx 未訂閱
引言: input檔為一qcif.yuv(4,1,1)176*144的檔案....
一般存在檔案的資料我都會用一個一個struct來存, 如此讀寫資料比較方便 如: typedef struct { char y[4]; \\or long y; char u; char v; } YUV; 不知你的資料是不是這樣的存法?
JerryKuo
版主


發表:42
回覆:571
積分:322
註冊:2003-03-10

發送簡訊給我
#12 引用回覆 回覆 發表時間:2003-08-13 10:04:51 IP:210.68.xxx.xxx 未訂閱
even你好    可以請你寄一個你的測試圖給我嗎?...我發現你的YUV->RGB公式 好像有些誤差,我用的公式如下,至少正確度90%,呵呵
B = Y + 2.032*(U - 128)
G = Y - 0.395*(U - 128) - 0.581*(V - 128)
R = Y + 1.140*(V - 128)
不過我這個公式開出來的圖有10%暇庇,如圖左上角 我查了一下網路的YUV->RGB公式,大部分都是RGB->YUV 所以當要做YUV->RGB時,就要根據RGB->YUV是如何轉換的 才能用反矩陣將YUV轉換RGB。 我用的是視訊壓縮標準的參考圖,原始圖就是YUV,並不是 RGB轉換而來的,我的轉換式是試過數種YUV->RGB公式,得 到結果最好的一個式子,我想MPEG應該有標準的YUV->RGB 我會再查看看H.263有沒有這個式子(但書再遙遠的家鄉) 參考看看吧
even
一般會員


發表:12
回覆:17
積分:5
註冊:2003-07-18

發送簡訊給我
#13 引用回覆 回覆 發表時間:2003-08-13 21:33:37 IP:210.70.xxx.xxx 未訂閱
謝謝各位大大的熱情的幫忙.... 問題已經解決了...^^ 嘿嘿... 果然是公式的運算有問題..... 還有y檔與u、v檔的對應問題....... 程式碼如下.....
int* Yrawarray(char* FileName, int w, int h, int frame_no)
{
  int* temp1 = new int[w*h];
  unsigned char* temp2 =new unsigned char[w*h];
  FILE* p;
  p=fopen(FileName,"rb");
  fseek(p,frame_no*w*h*1.5,SEEK_SET);
  fread(temp2,w*h,1,p);
  for(int a=0;aHeight=h;
bmp->Width=w;
 for(int y=0;yPixelFormat =pf24bit;
   ptr=(Byte *)bmp->ScanLine[y];
   for(int x=0;xPicture->Assign(bmp);
}
再次謝謝JerryKuo大大及brook的幫忙囉.........
JerryKuo
版主


發表:42
回覆:571
積分:322
註冊:2003-03-10

發送簡訊給我
#14 引用回覆 回覆 發表時間:2003-08-18 17:19:17 IP:61.230.xxx.xxx 未訂閱
小弟找到10%錯誤的原因啦~ 原因是YUV轉RGB公式,RGB會出現負值或是大於255。 所以RGB數值要做一次調整 大於255取255 小於0取0
hclnsmsimsmsim
一般會員


發表:0
回覆:1
積分:0
註冊:2006-12-04

發送簡訊給我
#15 引用回覆 回覆 發表時間:2006-12-06 14:39:35 IP:134.208.xxx.xxx 未訂閱
請問 如果資料是4:2:0該如何抓資料呢? 測試過此程式 會發生色差問題!
系統時間:2024-05-08 18:06:46
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!