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

WEBCAM即時影像處理上迴圈的問題

答題得分者是:bugmans
esju0000
一般會員


發表:7
回覆:9
積分:3
註冊:2007-09-01

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-01-28 12:40:53 IP:140.121.xxx.xxx 訂閱
我寫了一個即時影像擷取處理的程式
但在迴圈上遇到了問題
我是用WHILE LOOP不斷將PENAL上的影像資料抓取並處理
但是如果迴圈內不加上 " Application->ProcessMessages() " 程式會死當
如果加上去 每次處理的時間又會爆增
若是在前面加上 " if(count0==0) " 減少其使用的次數
程式的畫面又會很遲緩
想請問各位大大有無良方能救小弟脫出苦海
先在此拜謝
以下為我程式碼~

[code cpp]
void __fastcall TForm1::Button1Click(TObject *Sender)
{
kkk=-1*kkk;
while(kkk==1)
{
Button1->Caption="暫停";
QueryPerformanceFrequency(&litmp);//獲得計時器計時頻率
dfFreq=(double)litmp.QuadPart;
QueryPerformanceCounter(&litmp); //獲得初始值
QPart1=litmp.QuadPart;
HDC hDC=GetDC(Panel1->Handle);
csBuf->Handle=hDC;
bmp2->Width=Panel1->Width;
bmp2->Height=Panel1->Height;
bmp2->PixelFormat= pf24bit;
bmp2->Canvas->CopyRect(Rect(0, 0, bmp2->Width, bmp2->Height),
csBuf, Rect(0, 0, Panel1->Width, Panel1->Height));

DynamicArray Xr;
DynamicArray Yr;
DynamicArray xr;
DynamicArray yr;
Xr.Length = 1;
Yr.Length = 1;
xr.Length = 1;
yr.Length = 1;
//影像前處理
for( int j=ScrollBar5 -> Position ; j Position; j )
{
ptr2 = (Byte *)bmp2->ScanLine[j];
for( int i=ScrollBar2 -> Position ; i Position; i )
{
b2=ptr2[i*3];
r2=ptr2[i*3 2];

//濾光鏡(濾除藍紅兩色)
if (r2>ScrollBar1 ->Position || b2>ScrollBar1 ->Position)
{Gray2=255;}
else
{Gray2=0;}
if (Gray2 == 0) //存取圖面黑點座標至矩陣
{
Xr[Xr.Length-1]=i;
Yr[Yr.Length-1]=j;
Xr.Length ;
Yr.Length ;
}
ptr2[i*3]=ptr2[i*3 1]=ptr2[i*3 2]=Gray2;
}
}
//中值法
for(int k=0;k {
int n=0;
for(int j=Yr[k]-1;j {
ptr2 = (Byte *)bmp2->ScanLine[j];
for(int i=Xr[k]-1;i {
Gray2=ptr2[i*3];
if (Gray2 == 0)
{n ;}
}
}
if (n <= ScrollBar6 -> Position)
{
for(int j=Yr[k]-1;j {
ptr2 = (Byte *)bmp2->ScanLine[j];
for(int i=Xr[k]-1;i {
ptr2[i*3]=ptr2[i*3 1]=ptr2[i*3 2]=255;
}
}
Xr[k]=0;
Yr[k]=0;
}
}
ReleaseDC(0,hDC);
Image1->Picture->Assign(bmp2);
//取球所有座標的矩陣
for(int k=0;k {
if(Xr[k]!=0 || Yr[k]!=0)
{
xr[xr.Length-1]=Xr[k];
yr[yr.Length-1]=Yr[k];
xr.Length ;
yr.Length ;
}
}

//計算質心座標
int Xb=0,Yb=0;
if(xr.Length-1==0)
{
Xb=ScrollBar2 -> Position;
Yb=ScrollBar5 -> Position;
}
else
{
for(int i=0;i {
Xb=Xb xr[i];
Yb=Yb yr[i];
}
Xb=Xb/(xr.Length-1);
Yb=Yb/(yr.Length-1);
}
//定義局部影像處理區域大小
SQP1[0]=Point(ScrollBar2 -> Position,ScrollBar5 -> Position);
SQP1[1]=Point(ScrollBar3 -> Position,ScrollBar5 -> Position);
SQP1[2]=Point(ScrollBar3 -> Position,ScrollBar4 -> Position);
SQP1[3]=Point(ScrollBar2 -> Position,ScrollBar4 -> Position);
SQP1[4]=Point(ScrollBar2 -> Position,ScrollBar5 -> Position);
Image1->Canvas->Pen->Color = clBlue;
Image1->Canvas->Polyline(SQP1,4);
//劃定輸入區
Image1->Canvas->Pen->Color = clRed;
Image1->Canvas->MoveTo((ScrollBar2 -> Position) 75,ScrollBar4 -> Position);
Image1->Canvas->LineTo((ScrollBar2 -> Position) 75,ScrollBar5 -> Position);
//劃定輸出區
Image1->Canvas->Brush->Style = bsClear;
Image1->Canvas->Pen->Color = clRed;
Image1->Canvas->Ellipse(305,73,385,169);
//繪製質心位置
SQP2[0]=Point(Xb-2,Yb-2);
SQP2[1]=Point(Xb 2,Yb-2);
SQP2[2]=Point(Xb 2,Yb 2);
SQP2[3]=Point(Xb-2,Yb 2);
Image1->Canvas->Pen->Color = clRed;
Image1->Canvas->Brush->Color = clRed;
Image1->Canvas->Polygon(SQP2,3);
if(mmm==1) //擷取資料判定
{
if (Xb>50&&count1==0)//輸入值
{
Xin[count]=Xb;
Yin[count]=Yb;
count ;
}
if (Xb>265)//輸出值
{
count1=1;
}

if(Xb<40)
{
count1=0;
}
}

Label23 -> Caption= "(" IntToStr(Xb) "," IntToStr(Yb) ")";
Label27 -> Caption= count;
//if(count0==0)
Application->ProcessMessages();//釋放CPU資源

QueryPerformanceCounter(&litmp);// 獲得終止值
QPart2 = litmp.QuadPart;
dfMinus = (double)(QPart2 - QPart1);
dfTim = dfMinus / dfFreq;// 獲得對應的時間值
int T = 1000*dfTim;
Label1-> Caption= T;
}
Button1->Caption="繼續擷取";
}
[/code]
yy680511
一般會員


發表:5
回覆:10
積分:13
註冊:2007-08-08

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-01-28 13:28:00 IP:61.64.xxx.xxx 訂閱
你可以建立一個timer
固定一個時間將Image 的資料copy 到另一個buffery再作處理...
這樣顯示部分與處理的部分就分開也不會占用loading
esju0000
一般會員


發表:7
回覆:9
積分:3
註冊:2007-09-01

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-01-28 14:24:32 IP:140.121.xxx.xxx 訂閱
我原本是用bcb內建的Timer 
但是其時間間距無法降到50mS以下
(也許100mS以下可能都不行QQ)
所以才會想使用while loop
還是大大能提供小弟 其他的Timer
間距能越短越好
萬分感謝
===================引 用 yy680511 文 章===================
你可以建立一個timer
固定一個時間將Image 的資料copy 到另一個buffery再作處理...
這樣顯示部分與處理的部分就分開也不會占用loading
lu
高階會員


發表:11
回覆:189
積分:195
註冊:2003-11-19

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-01-28 18:02:02 IP:203.73.xxx.xxx 訂閱
看了一下你的程式碼,你這種作法一定效能不好~~
因為你是先把WEBCAM的影像顯示在TImage 上面,然後再抓回來處理,處理完在丟回去,一來一往,當然會耗用很多不必要的時間

建議改寫 DirectShow 的 Filter,寫FILTER有個好處
1. 可以一個 Frame、一個 Frame 處理資料,無所謂的間隔
2. 寫 Filter 可在顯示前就先把資料處理好,無時間浪費

當然~~凡事都有好、壞兩面,DirectShow 的 Filter 必須使用 Microsoft 的VC撰寫....不能用BCB來寫(至少我沒找到怎樣用 BCB 寫Filter)

esju0000
一般會員


發表:7
回覆:9
積分:3
註冊:2007-09-01

發送簡訊給我
#5 引用回覆 回覆 發表時間:2008-01-28 21:10:08 IP:140.121.xxx.xxx 訂閱
感謝Lu大大的建議 但是老闆釘我甚緊 
能否我現行的架構下做修改呢?
如果我跟老闆說 現在得改用VC
我可能要跑路(淚奔~)
===================引 用 lu 文 章===================
看了一下你的程式碼,你這種作法一定效能不好~~
因為你是先把WEBCAM的影像顯示在TImage 上面,然後再抓回來處理,處理完在丟回去,一來一往,當然會耗用很多不必要的時間

建議改寫 DirectShow 的 Filter,寫FILTER有個好處
1. 可以一個 Frame、一個 Frame 處理資料,無所謂的間隔
2. 寫 Filter 可在顯示前就先把資料處理好,無時間浪費

當然~~凡事都有好、壞兩面,DirectShow 的 Filter 必須使用 Microsoft 的VC撰寫....不能用BCB來寫(至少我沒找到怎樣用 BCB 寫Filter)
?
lu
高階會員


發表:11
回覆:189
積分:195
註冊:2003-11-19

發送簡訊給我
#6 引用回覆 回覆 發表時間:2008-01-29 08:49:24 IP:203.73.xxx.xxx 訂閱
那建議你用 Timer 來作吧,個人經驗類似這樣的作法,一秒能有超過10個 Frame 就算很好了

真的還是不行的話....用快一點的CPU來補足吧

如果用快一點的CPU也不行,因為現在CPU大多為雙核心,所以把資料拆成2半,用THREAD分開同時計算,時間大概可以縮短1.5倍左右吧
但是,請注意~~如果要用THREAD,請先爬完站內相關文章,不可直接套用你所寫的程式碼~~必當



===================引 用 esju0000 文 章===================
感謝Lu大大的建議 但是老闆釘我甚緊
能否我現行的架構下做修改呢?
如果我跟老闆說 現在得改用VC
我可能要跑路(淚奔~)
bugmans
高階會員


發表:95
回覆:322
積分:188
註冊:2003-04-12

發送簡訊給我
#7 引用回覆 回覆 發表時間:2008-01-29 20:31:40 IP:125.225.xxx.xxx 未訂閱
在BCB和Delphi應該是用Dspack,ICaptureGraphBuilder2,RenderStream都是DirectX的東西吧
http://delphi.ktop.com.tw/board.php?cid=168&fid=921&tid=83094
===================引 用 lu 文 章===================
當然~~凡事都有好、壞兩面,DirectShow 的 Filter 必須使用 Microsoft 的VC撰寫....不能用BCB來寫(至少我沒找到怎樣用 BCB 寫Filter)
esju0000
一般會員


發表:7
回覆:9
積分:3
註冊:2007-09-01

發送簡訊給我
#8 引用回覆 回覆 發表時間:2008-01-31 06:05:12 IP:140.121.xxx.xxx 訂閱
感謝大大的幫忙 雖然還沒完成
但是小弟正往Dspack的路上努力
希望將來在遇到問題大大們也能不吝指教^^
===================引 用 bugmans 文 章===================
在BCB和Delphi應該是用Dspack,ICaptureGraphBuilder2,RenderStream都是DirectX的東西吧
http://delphi.ktop.com.tw/board.php?cid=168&fid=921&tid=83094
===================引 用 lu 文 章===================
當然~~凡事都有好、壞兩面,DirectShow 的 Filter 必須使用 Microsoft 的VC撰寫....不能用BCB來寫(至少我沒找到怎樣用 BCB 寫Filter)
系統時間:2024-04-27 4:20:53
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!