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

奇怪的錯誤......

尚未結案
NICK0401
一般會員


發表:10
回覆:17
積分:5
註冊:2003-10-08

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-10-08 21:48:01 IP:61.230.xxx.xxx 未訂閱
請教各位先進幾個問題 1.YIQ模型中的I,Q分量其範圍包跨"正""負",處理時用原來的正負範圍來處理較好還是將其正規化到只有"正"比較好? 2.我有一段副程式將RGB轉成YIQ,圖案大小為60x80.R,G,B,Y,I,Q都為配置60x80記憶體空間的指標。程式中有個迴圈多次呼叫這個副程式,每次呼叫時的R,G,B內容都不一樣,執行的時候有時很順利,有時會在迴圈經過多次候出現錯誤停在Y[i]=0.114*B[i]+0.587*G[i]+0.299*R[i]這一行,然後出現Invalid floating point operating。我實在找不出也搞不懂為何會這樣,請教各位高手為什麼?? Thans!
 
void YIQ(byte *Y,byte *I,byte *Q,byte *R,byte *G,byte *B)
{
if (I!=null)
for(int i=0;i<4800;i  )
{
Y[i]=0.114*B[i] 0.587*G[i] 0.299*R[i];
I[i]=-0.321*B[i]-0.275*G[i] 0.596*R[i];
Q[i]=0.311*B[i]-0.523*G[i]  0.212*R[i];
}
else
for(int i=0;i<4800;i  )
Y[i]=0.114*B[i] 0.587*G[i] 0.299*R[i];    }  
發表人 - NICK0401 於 2003/10/08 22:04:10
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-10-08 22:00:01 IP:140.135.xxx.xxx 未訂閱
NICK0401您好:   請參考下面連結做適當的修正   http://delphi.ktop.com.tw/topic.php?TOPIC_ID=37787 謝謝您的配合 請問一下您做 > <>~我也是在學習的階段,回答的不好請您多多見諒與指教~ 發表人 -
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-10-08 23:30:53 IP:140.135.xxx.xxx 未訂閱
NICK0401您好: 我測試後沒有像您一樣的錯誤訊息耶 下面是我測試的code,您參考看看
void YIQ(byte *Y,byte *I,byte *Q,byte *R,byte *G,byte *B)
{
 if (I!=NULL)
 for(int i=0;i<4800;i  )
{
 Y[i]=0.114*B[i] 0.587*G[i] 0.299*R[i];
 I[i]=-0.321*B[i]-0.275*G[i] 0.596*R[i];
 Q[i]=0.311*B[i]-0.523*G[i]  0.212*R[i];
}
 else
 for(int i=0;i<4800;i  )
 Y[i]=0.114*B[i] 0.587*G[i] 0.299*R[i];
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 //---取出圖片的RGB值並存入R[],G[],B[]中
 byte Y[4800],I[4800],Q[4800],R[4800],G[4800],B[4800],*ptr;
 Graphics::TBitmap* BMP=new Graphics::TBitmap();
 BMP->LoadFromFile("1.bmp");
 for (int y=0; yHeight; y  )
 {
  ptr=(Byte*)BMP->ScanLine[y];
  for (int x=0; xWidth; x  )
  {
   B[x 80*y]=ptr[x*3];         
   G[x 80*y]=ptr[x*3 1];
   R[x 80*y]=ptr[x*3 2];
  }
 }
 delete BMP;
//-----RGB2YIQ----
 YIQ(Y,I,Q,R,G,B);
//-----秀出轉換後的效果
 Graphics::TBitmap* BMP1=new Graphics::TBitmap();
 BMP1->Height=60;
 BMP1->Width=80;
 for (int y=0;yHeight ;y  )
 {
  for (int x=0;xWidth ;x  )
  {
   BMP1->Canvas->Pixels[x][y]=TColor(RGB(Y[x 80*y],Y[x 80*y],Y[x 80*y]));
  }
 }
 Image1->Picture->Assign(BMP1);
 delete BMP1;
}
順心 <>~我也是在學習的階段,回答的不好請您多多見諒與指教~
NICK0401
一般會員


發表:10
回覆:17
積分:5
註冊:2003-10-08

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-10-09 00:03:09 IP:61.230.xxx.xxx 未訂閱
我是要作影像追蹤,轉成YIQ後以特定大小區塊對Y,I,Q分別計算其平均值和變異數。 我的程式是將CCD的影像擷取進來不斷的轉換,作判斷。為何說是奇怪的錯誤,怪就怪在有時執行很順利有時執行到一半會出錯。是不是有什麼特殊的情況下會導致Invalid floating point operation??
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-10-09 00:06:56 IP:140.135.xxx.xxx 未訂閱
NICK0401您好: 方不方便將完整的程式碼貼上,好讓有經驗的人可以幫您呢? 說不定是其他地方的問題導致錯誤也說不一定< > 順心< > ~我也是在學習的階段,回答的不好請您多多見諒與指教~
NICK0401
一般會員


發表:10
回覆:17
積分:5
註冊:2003-10-08

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-10-09 00:21:25 IP:61.230.xxx.xxx 未訂閱
是..方便啦!不過完整的程式碼很多要全貼嗎?
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-10-09 00:28:07 IP:140.135.xxx.xxx 未訂閱
NICK0401您好: 那..只好看看其他有經驗的人看完這些討論串後是否能判斷出哪裡有問題了 我用我之前寫的程式是確定可以 > 若可以的話也可以將整個 href="http://delphi.ktop.com.tw/forum.asp?FORUM_ID=97">http://delphi.ktop.com.tw/forum.asp?FORUM_ID=97 順心 GoodLuck <>~我也是在學習的階段,回答的不好請您多多見諒與指教~ 發表人 -
mkbobo
一般會員


發表:4
回覆:68
積分:19
註冊:2003-04-10

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-10-09 01:24:56 IP:61.216.xxx.xxx 未訂閱
引言:
 
void YIQ(byte *Y,byte *I,byte *Q,byte *R,byte *G,byte *B)
{
if (I!=null)  //<<為啥只判斷I 而且如果只判斷I這樣有點危險
 for(int i=0;i<4800;i  )
 {
  Y[i]=0.114*B[i] 0.587*G[i] 0.299*R[i];
  I[i]=-0.321*B[i]-0.275*G[i] 0.596*R[i];
  Q[i]=0.311*B[i]-0.523*G[i]  0.212*R[i];
 }
 else
  for(int i=0;i<4800;i  )
   Y[i]=0.114*B[i] 0.587*G[i] 0.299*R[i];//當I等於NULL時 只改變Y 哪是不是其他永遠不變    }      
我認為你的問題出在I 因為你只判斷I存不存在 如果當I存在 而I的陣列大小卻沒有超過4800那會發生啥事 一個不存在的數值去做運算應該就是你錯誤的訊息導致的原因 >> Invalid floating point operating 建議 一 你應該在進入這函式之前將陣列大小定義完整至少要超過4800 二 如果你在某些狀況下用到這些函式是不需要I和Q的 如果你是用 new 的 你應該在delete 後 再加上 I = NULL 及 Q = NULL
NICK0401
一般會員


發表:10
回覆:17
積分:5
註冊:2003-10-08

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-10-09 12:14:42 IP:163.21.xxx.xxx 未訂閱
因為有時只需Y的值所以我呼叫的方式為:
 
YIQ(Y,NULL,NULL,R,G,B);
有時則YIQ都需轉換:
 
YIQ(Y,I,Q,R,G,B);
Y,I,Q,R,G,B這些引數在程式中宣告他們為byte指標,且都用malloc()函式配置4800大小的記憶體位置.
mkbobo
一般會員


發表:4
回覆:68
積分:19
註冊:2003-04-10

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-10-09 12:47:40 IP:61.216.xxx.xxx 未訂閱
既然是這樣哪就不是我說發生的原因了    接下來就要看你的型態了 你設定的型態是 byte 是 unsinged char ?? 如果是這個 我們把你的程式片斷拆解下來看   0.114*B[i] = (float) * (unsinged char) 你可以試看看用下面的方法  byte(0.114*(float)B[i]+0.587*(float)G[i]+0.299*(float)R[i] ) 先將你的byte轉型為float 做完運算後 在將他轉為byte 其實最後這個步驟應該是編譯器就會幫你做掉ㄌ只是這樣寫比較好  順便再提到一點一般我們再做運算時 如果該型態不是浮點數 而我們的計算是會用到浮點運算 便會習慣將他乘上 class="code"> int a=10; int b=21; float c= a/b ; float d= 1.0*a/b ; 觀察c和d
JerryKuo
版主


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

發送簡訊給我
#11 引用回覆 回覆 發表時間:2003-10-09 13:48:15 IP:210.68.xxx.xxx 未訂閱
引言: 請教各位先進幾個問題 1.YIQ模型中的I,Q分量其範圍包跨"正""負",處理時用原來的正負範圍來處理較好還是將其正規化到只有"正"比較好? 2.我有一段副程式將RGB轉成YIQ,圖案大小為60x80.R,G,B,Y,I,Q都為配置60x80記憶體空間的指標。程式中有個迴圈多次呼叫這個副程式,每次呼叫時的R,G,B內容都不一樣,執行的時候有時很順利,有時會在迴圈經過多次候出現錯誤停在Y[i]=0.114*B[i] 0.587*G[i] 0.299*R[i]這一行,然後出現Invalid floating point operating。我實在找不出也搞不懂為何會這樣,請教各位高手為什麼?? Thans!
 
void YIQ(byte *Y,byte *I,byte *Q,byte *R,byte *G,byte *B)
{
if (I!=null)
for(int i=0;i<4800;i  )
{
Y[i]=0.114*B[i] 0.587*G[i] 0.299*R[i];
I[i]=-0.321*B[i]-0.275*G[i] 0.596*R[i];
Q[i]=0.311*B[i]-0.523*G[i]  0.212*R[i];
}
else
for(int i=0;i<4800;i  )
Y[i]=0.114*B[i] 0.587*G[i] 0.299*R[i];    }  
你好: 以下有幾點,你可以加到程式確認一下。 1.)如果是做浮點運算時,運算變數最好也是浮點,尤其變數是byte(0~255)時 由於必須是正整數,且數值範圍又很小(0~255),運算時很容易溢位。建議你增 加變數轉型的宣告。如: Y[i] = (byte)(0.114*(double)B[i] 0.587*(double)G[i] 0.299*(double)R[i]); 2.)基本上byte這種變數型態,bcb不允許做乘除的運算的,因為很容易超出數值 範圍,所以要做乘除運算時,先轉成整數型態或浮點型態,最後再把值轉回自己想要 的變數型態,以上面的式子為例,RGB先轉為double運算,運算後再轉為byte。 3.)因為沒實際做過RGB->YIQ,所以並不曉得,YIQ的值範圍是多少,依照你的宣告 是byte,所以值是落在0~255,如果運算出的值大於255,或是小於0,很容易造成 結果錯誤失真。建議YIQ宣告為浮點數(double),得到所有運算結果時,再利用影 像正規化(normalization)或是去頭去尾的方式輸出,如此才不會莫名其妙的產生 失真。 發表人 - jerrykuo 於 2003/10/09 13:58:06
Royce520
高階會員


發表:18
回覆:157
積分:100
註冊:2002-09-13

發送簡訊給我
#12 引用回覆 回覆 發表時間:2003-10-09 20:29:06 IP:61.59.xxx.xxx 未訂閱
NICK0401 你好,   我也用以下程式碼幫你試過了, 也是不會碰到你說的哪的問題   我想這是別的地方引起 你的好好找一下了
void YIQ(byte *Y,byte *I,byte *Q,byte *R,byte *G,byte *B)
{
if (I!=NULL)
for(int i=0;i<1;i  )
{
//Y[i]=0.114*B[i] 0.587*G[i] 0.299*R[i];
Y[i]=(29*B[i] 150*G[i] 76*R[i])>>8; // 你可以改寫成這樣子,
// 好處是快不少... 下面的式子都可以用
I[i]=-0.321*B[i]-0.275*G[i] 0.596*R[i];
Q[i]=0.311*B[i]-0.523*G[i]  0.212*R[i];
}
else
for(int i=0;i<1;i  )
Y[i]=0.114*B[i] 0.587*G[i] 0.299*R[i];
}    ......
   for ( int a = 0; a < 256;   a)
   for ( int b = 0; b < 256;   b)
   for ( int c = 0; c < 256;   c)
   {
      R[0] = a;
      G[0] = b;
      B[0] = b;
      YIQ(Y, I, Q, R, G, B);
   }
以你的例子來說, YIQ 的範圍大約在 Y = [0, 255], I = [-152, 152] Q = [-133, 133] *真實的事物最美, 簡單的道理最好, 我能體會的 太少*
------
不要忘記呼吸,不要忘記編程! ∩__∩
NICK0401
一般會員


發表:10
回覆:17
積分:5
註冊:2003-10-08

發送簡訊給我
#13 引用回覆 回覆 發表時間:2003-10-10 00:27:40 IP:61.230.xxx.xxx 未訂閱
首先感謝taishyang,mkbobo,JerryKuo及Royce520。 真是奇怪,今天在學校實驗室run我的程式,沒問題 但回來後在家裡的電腦 > 我程式的主體為: >>>>>
NICK0401
一般會員


發表:10
回覆:17
積分:5
註冊:2003-10-08

發送簡訊給我
#14 引用回覆 回覆 發表時間:2003-10-19 16:01:59 IP:163.21.xxx.xxx 未訂閱
找了好久還是沒找到錯誤發生原因,我已將我的Project上傳道會員求助區了,希望有控的大大們能幫幫我,非常感謝....
mkbobo
一般會員


發表:4
回覆:68
積分:19
註冊:2003-04-10

發送簡訊給我
#15 引用回覆 回覆 發表時間:2003-10-20 10:00:21 IP:202.168.xxx.xxx 未訂閱
NICK0401您好 我看了你的上傳檔案了  我的問題是 你說出現問題的地方 為和跟上面所討論的地方不一樣阿
JerryKuo
版主


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

發送簡訊給我
#16 引用回覆 回覆 發表時間:2003-10-20 10:47:19 IP:61.220.xxx.xxx 未訂閱
引言: 找了好久還是沒找到錯誤發生原因,我已將我的Project上傳道會員求助區了,希 望有控的大大們能幫幫我,非常感謝....
NICK0401你好:
void WaveletYIQ(byte *Y,short *I,short *Q,byte *R,byte *G,byte *B)
{
 if (I!=NULL)
  for(int i=0;i<4800;i  )
  {
   Y[i]=(B[i]*29 G[i]*150 R[i]*76)/255;
   I[i]=(-82*B[i]-70*G[i] R[i]*152)/255;
   Q[i]=(79*B[i]-133*G[i] 54*R[i])/255;
  }
 else
  for(int i=0;i<4800;i  )
   Y[i]=(B[i]*29 G[i]*150 R[i]*76)/255;
}
我還是覺得這個函數這樣寫會有問題。建議改成 < class="code"> void WaveletYIQ(byte *Y,short *I,short *Q,byte *R,byte *G,byte *B) { if (I!=NULL) for(int i=0;i<4800;i ) { Y[i]=(byte)(( 29*(int)B[i] 150*(int)G[i] 76*(int)R[i])/255); I[i]= (-82*(int)B[i]- 70*(int)G[i] 152*(int)R[i])/255; Q[i]= ( 79*(int)B[i]-133*(int)G[i] 54*(int)R[i])/255; } else for(int i=0;i<4800;i ) Y[i]=(byte)(( 29*(int)B[i] 150*(int)G[i] 76*(int)R[i])/255); } ~就只會這一招了^^~ 發表人 - jerrykuo 於 2003/10/20 10:49:02
NICK0401
一般會員


發表:10
回覆:17
積分:5
註冊:2003-10-08

發送簡訊給我
#17 引用回覆 回覆 發表時間:2003-10-20 11:10:39 IP:163.21.xxx.xxx 未訂閱
mkbobo您好! 抱歉我有點混亂了! 原本出錯的地方我沒改什麼,但現在在學校實驗室的電腦 >搞不懂什麼原因,難道跟
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#18 引用回覆 回覆 發表時間:2003-10-20 17:48:54 IP:140.135.xxx.xxx 未訂閱
NICK0401您好: 能否將您的專案編譯成獨立執行檔呢? 不然連測試都沒有辦法測試說
NICK0401
一般會員


發表:10
回覆:17
積分:5
註冊:2003-10-08

發送簡訊給我
#19 引用回覆 回覆 發表時間:2003-10-20 20:32:38 IP:61.230.xxx.xxx 未訂閱
什麼意思? Packages中Build with run time packages不要勾選是嗎?
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#20 引用回覆 回覆 發表時間:2003-10-20 21:36:54 IP:140.135.xxx.xxx 未訂閱
NICK0401您好: 還有RTL也不要勾選,但是想想,您的程式似乎是針對羅技某台攝影機 要測試似乎也不是那麼容易
NICK0401
一般會員


發表:10
回覆:17
積分:5
註冊:2003-10-08

發送簡訊給我
#21 引用回覆 回覆 發表時間:2003-10-21 12:39:04 IP:61.230.xxx.xxx 未訂閱
我的程式擷取影像部分是用Bitblt函式,我把他寫成副程式
 void Get_Picture(Graphics TBitmap *Bitmap,HWND Source)
Source是擷取來源的Handle 如果各位高手有空,手邊也有影像輸入裝置, 我想應該只要把Button1Click(顯示影像)事件中改成可以驅動該輸入裝置的程式,將他顯示在如Panel上,如此只要把Source傳入Panel->Handle即可
系統時間:2024-04-30 18:45:43
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!