線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3836
推到 Plurk!
推到 Facebook!

HSI 之 Hue圖顯示問題

尚未結案
IORIS
一般會員


發表:15
回覆:21
積分:7
註冊:2005-01-14

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-05-16 19:03:54 IP:210.244.xxx.xxx 未訂閱
請各位前輩能幫我看一下 RGB圖 轉HSI  我是用 rgb轉hsi 公式取出 Hue 值 公式如圖: 並用灰階圖來表示--------Hue(0~360)以灰階(0~255)表示 程式碼部分
 
void __fastcall TForm1::hsi_hClick(TObject *Sender)
{
  Graphics::TBitmap *Bmp = new Graphics::TBitmap();
  Bmp->Assign(Image1->Picture->Bitmap);
  Byte *ptr;
  Byte B,G,R,H ;
  float pi=3.14;
  for (int i=0;iHeight;i++)
   {
    ptr=(Byte *)Bmp->ScanLine[i];
    for(int j=0;jWidth;j++)
     {
      B=ptr[3*j];
      G=ptr[3*j+1];
      R=ptr[3*j+2];
      if(R==G && R==B && G==B)                   
        H=0;
      else
          {
           float fx=((R-G)+(R-B))/(2*sqrt(((R-G)*(R-G))+((R-B)*(G-B))));
           if(B>G)
              H=((2*pi-acos(fx))*180/pi) /360*255;       // 角度/360*255   Hue(0~360)以灰階(0~255)表示  //  
           else
              H =(acos(fx)*180/pi) /360*255;      
          }
      ptr[3*j]=ptr[3*j+1]=ptr[3*j+2]=H ;
     }
   }
 Image11->Picture->Assign(Bmp);
 delete Bmp;
}
測試圖檔 左圖 是原圖(200*200 24bit bmp) 右圖 Hue 的測試圖 ----總覺得顯示的很奇怪 但不知道哪裡出錯 麻煩各位前輩 能幫忙找出錯誤 謝謝 !!
m58610
初階會員


發表:22
回覆:83
積分:36
註冊:2003-09-07

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-05-17 06:14:01 IP:140.118.xxx.xxx 未訂閱
把pi精度用高一點看看 float pi = 3.1415926; 或是 double pi = asin(1) * 2;    然後如果有除的部份請用成浮點數 H=((2*pi-acos(fx))*180/pi) / 360.0 * 255; H =(acos(fx)*180/pi) / 360.0 * 255;
JerryKuo
版主


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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-05-17 10:02:01 IP:220.135.xxx.xxx 未訂閱
引言: 請各位前輩能幫我看一下 RGB圖 轉HSI 我是用 rgb轉hsi 公式取出 Hue 值 公式如圖: 並用灰階圖來表示--------Hue(0~360)以灰階(0~255)表示 程式碼部分
 
void __fastcall TForm1::hsi_hClick(TObject *Sender)
{
  Graphics::TBitmap *Bmp = new Graphics::TBitmap();
  Bmp->Assign(Image1->Picture->Bitmap);
  Byte *ptr;
  Byte B,G,R,H ;
  float pi=3.14;
  for (int i=0;iHeight;i  )
   {
    ptr=(Byte *)Bmp->ScanLine[i];
    for(int j=0;jWidth;j  )
     {
      B=ptr[3*j];
      G=ptr[3*j 1];
      R=ptr[3*j 2];
      if(R==G && R==B && G==B)                   
        H=0;
      else
          {
           float fx=((R-G) (R-B))/(2*sqrt(((R-G)*(R-G)) ((R-B)*(G-B))));
           if(B>G)
              H=(byte)((2*pi-acos(fx))*180/pi) /360.0*255.0;       // 角度/360*255   Hue(0~360)以灰階(0~255)表示  //  
           else
              H =(byte)(acos(fx)*180/pi) /360.0*255.0;      
          }
      ptr[3*j]=ptr[3*j 1]=ptr[3*j 2]=H ;
     }
   }
 Image11->Picture->Assign(Bmp);
 delete Bmp;
}
IORIS你好: 1.)因為整數相除的結果沒有小數點,所以如果值小於0,變成整數則為0。 所以請問360改為360.0較為恰當。 2.)另外H值為byte,所以浮點運算完記得將值轉為byte,否則值會亂跑,結果會亂掉。 3.)H(0~360)要轉RGB來顯示話,應該是H*(255/360),不曉得你是不是也是這樣寫。 檢查一下
IORIS
一般會員


發表:15
回覆:21
積分:7
註冊:2005-01-14

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-05-17 16:47:04 IP:59.104.xxx.xxx 未訂閱
多謝 兩位前輩的指正 還有個問題 想問說 這樣已經算是沒有錯誤了嗎 以下我用兩張圖分別去做比較 (卡通圖 & lenna) ------------------------------------------------------------------------  原始圖(圖一)------------------未修改程式(圖二)----------------------已修改程式(圖三) 由(卡通圖 & lenna)的 "圖三" 都可看出 在"圖二"中 白色的部分已經明顯變少(正常顯示??) 但在卡通圖中 仍可看出許多分散的白點 請問這樣算是正常顯示嗎? 如果 前輩們認為這樣算正常的話 那我就結案 謝謝 !! 附上 修改後的程式碼!
void __fastcall TForm1::hsi_hClick(TObject *Sender)
{
  Graphics::TBitmap *Bmp = new Graphics::TBitmap();
  Bmp->Assign(Image1->Picture->Bitmap);
  Byte *ptr;
  Byte B,G,R,H ;
  double  pi=3.1415926;
  for (int i=0;iHeight;i++)
   {
    ptr=(Byte *)Bmp->ScanLine[i];
    for(int j=0;jWidth;j++)
     {
      B=ptr[3*j];
      G=ptr[3*j+1];
      R=ptr[3*j+2];
      if(R==G && R==B && G==B)        
          H=0;
      else
          {
           double temp=((R-G)+(R-B))/(2*sqrt(((R-G)*(R-G))+((R-B)*(G-B))));   
           if(B>G)
              H=(Byte)((2*pi-acos(temp))*180.0/pi)*(255.0/360.0);                           
           else
              H=(Byte)(acos(temp)*180.0/pi) *(255.0/360.0);
          }
      ptr[3*j]=ptr[3*j+1]=ptr[3*j+2]=H ;
     }
   }
 Image11->Picture->Assign(Bmp);
 delete Bmp;
}
m58610
初階會員


發表:22
回覆:83
積分:36
註冊:2003-09-07

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-05-17 18:49:49 IP:140.118.xxx.xxx 未訂閱
感覺也是有點怪 不過我沒有跑程式我不知道 不然你先把H宣告成浮點數 float H; 然後後面給灰階值時再轉型 ptr[x*3] = (byte)H; 試試看搞不好會解決
m58610
初階會員


發表:22
回覆:83
積分:36
註冊:2003-09-07

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-05-17 20:40:45 IP:140.118.xxx.xxx 未訂閱
這是我剛剛寫的 我也不確定對不對 上圖是512*512的Lena 提供程式碼如下
 Graphics::TBitmap *TheBitmap,*TempBitmap;
Byte *ptr,*tptr;
float H,H1;
float pi = asin(1) * 2;
Byte r,g,b;
TheBitmap=raw_img->Picture->Bitmap;
TheBitmap->PixelFormat=pf24bit;
pro_img->Width=raw_img->Width;
pro_img->Height=raw_img->Height;
TempBitmap=pro_img->Picture->Bitmap;
TempBitmap->Assign(TheBitmap);
for(int y=0;yHeight;y++)
{
        ptr=(Byte*)TheBitmap->ScanLine[y];
        tptr=(Byte*)TempBitmap->ScanLine[y];
        for(int x=0;xWidth;x++)
        {
                r = ptr[x*3+2];
                g = ptr[x*3+1];
                b = ptr[x*3];
                if(r!=g || g!=b || b!=r)
                {
                        H1=acos((0.5*((r-g)+(r-b)))/(sqrt((r-g)*(r-g)+(r-b)*(g-b))))*180/pi;
                        if(b<=g)
                                H=H1 / 360.0 * 255;
                        else
                                H=255-H1 / 360.0 * 255;
                }
                else
                        H = 0;    ///如R=G=B時將色調設成0
                tptr[x*3]=(Byte)H;
                tptr[x*3+1]=tptr[x*3];
                tptr[x*3+2]=tptr[x*3];
        }
}
Repaint();
IORIS
一般會員


發表:15
回覆:21
積分:7
註冊:2005-01-14

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-05-17 20:49:44 IP:59.104.xxx.xxx 未訂閱
m58610 你好 :    你說的方法我試過了... 不過還是會跟原本的一樣...你秀出來的圖 感覺跟我的圖二 是一樣的 還是  很謝謝你的意見 !!    我是在懷疑說 1. 是那張卡通圖本身的RGB轉換成 Hue 之後用灰階表示 就是這樣的圖 2. 灰階跟角度的轉換有錯誤 例如: Hue =(acos(fx)*180.0/pi)---轉換成角度 (角度轉灰階表示) Hue *(256.0/360.0) ------(1) Hue *(255.0/360.0) ------(2) Hue *(256.0/359.0) ------(3) Hue *(255.0/359.0) ------(4) 這四個該選哪一個 灰階從0-255 共有256個單位 角度0-359 共有360度 這應該是"觀念問題" 我已經搞混了 >"< ps: 附上卡通圖檔--在圖檔區---鋼練bmp 如果各位前輩有空餘時間 能不能幫我測試看這張圖 是不是轉換後真的是那個樣子 謝謝!! 發表人 - ioris 於 2005/05/17 20:53:12 發表人 - ioris 於 2005/05/17 21:33:18
m58610
初階會員


發表:22
回覆:83
積分:36
註冊:2003-09-07

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-05-17 22:22:51 IP:140.118.xxx.xxx 未訂閱
你好這是我跑出來的結果 中間感覺有一些黑色的破洞 我發現是因為它的RGB都是255 所以按照程式跑是變成0沒錯 另外其他地方我也對過數字應該沒錯 再來就是關於要用255跟360這邊的問題 因為灰階顯示0~255,所以H=0時要變成0,H=360時要變成255 故應該是*255沒錯 色調H範圍應該是0~359.99999999999..... 因為是浮點數所以可以把它想成是無限多位 所以只能 / 360.0 將0變成0,359.99999999....變成0.99999999999.... 發表人 - m58610 於 2005/05/17 22:41:21
IORIS
一般會員


發表:15
回覆:21
積分:7
註冊:2005-01-14

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-05-18 20:07:57 IP:59.104.xxx.xxx 未訂閱
m58610 你好: 多謝你的講解那我有點觀念了 看來應該 是圖本身的經過轉換後 就會顯示成那個樣子吧! 還有你是第一個指出 (*255.0/360.0) 小數部分的錯誤 謝謝你! 那我就先結案了! 如果還有人發現其他的錯誤 請再告訴我 謝謝 在此多謝各位前輩的指導!
系統時間:2024-05-13 2:50:09
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!