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

動態影像估算(白色)面積與重心,面積及重心有錯誤

答題得分者是:taishyang
monkey0710
一般會員


發表:2
回覆:1
積分:0
註冊:2008-04-24

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-07-02 21:32:13 IP:140.125.xxx.xxx 訂閱
是這樣的,我用攝影機從不定高度去拍攝地面上一個目標板,打算利用估算面積的方式來換算高度,並且求出目標版在畫面中的重心位置。
將來是要應用到直升機上面去做landing的動作。

我抓取影像擷取卡的元件是使用taishyang副站長所發表的EzCapCamera,然後我的程式在下方。
我目前面臨到的問題是: 1、面積估算出來會變成正確面積的3/4;重心的位置也不對。 2、運算速度會被面積拖垮,假如目標物(白色)面積太大,計算的速度會相當慢。

另外我timer的interval是設200。影像擷取卡每秒鐘抓取的張數是30張。影像擷取卡用的是UPMOST_UPG304。

目前懷疑會不會是電腦RAM不夠(DDR 512Mb)以及使用主機板本身的顯示卡,所以拖垮運算速度。
所以想請教各位先進能否幫我看看程式的部份是哪邊有錯,造成計算出來的面積及重心有誤。
另外除了從硬體上來提升速度,不知有什麼好方法可以從程式上下手來提升速度。


[code cpp]
//---------------------------------------------------------------------------
#include
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "EzCapCamera"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{

}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button1Click(TObject *Sender)
{
EzCapCamera1->CameraDisplay(); //開啟攝影機攝影機畫面
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
EzCapCamera1->CameraClose();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
Timer1->Enabled=false;
}
//---------------------------------------------------------------------------


void __fastcall TForm1::ScrollBar1Change(TObject *Sender)
{
Graphics::TBitmap *Bitmap1= new Graphics::TBitmap();
Bitmap1->PixelFormat=pf24bit;
Bitmap1->Assign(Image1->Picture);
int Threshold;
Threshold = (int)ScrollBar1->Position;
Byte *ptr;
Byte gray;
for (int y=0; yHeight;y )
{
ptr=(Byte *)Bitmap1->ScanLine[y];
for(int x=0;xWidth*3;x =3)
{
gray=( ptr[x] ptr[x 1] ptr[x 2])/3;
if(gray>Threshold)
{
ptr[x]=255;
ptr[x 1]=255;
ptr[x 2]=255;
}
else
{
ptr[x]=0;
ptr[x 1]=0;
ptr[x 2]=0;
}
}
}
Repaint();
Form1->Image1->Picture->Assign(Bitmap1);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button7Click(TObject *Sender)
{
Timer1->Enabled=true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
//----抓取bmp檔並存為1.bmp-----------
Graphics::TBitmap *Bitmap1 = new Graphics::TBitmap();
EzCapCamera1->CapBitmapFrame(Bitmap1);
EzCapCamera1->CapBmpPic("1.bmp");
Image1->Picture->LoadFromFile("1.bmp");
//---- 抓取ScrollBar的position設為Threshold,並以此值做二值化
Bitmap1->PixelFormat=pf24bit;
Bitmap1->Assign(Image1->Picture);
int Threshold;
Threshold = (int)ScrollBar1->Position;
Edit1->Text=ScrollBar1->Position;
Byte *ptr;
Byte gray;
for (int y=0; yHeight;y )
{
ptr=(Byte *)Bitmap1->ScanLine[y];
for(int x=0;xWidth*3;x =3)
{
gray=( ptr[x] ptr[x 1] ptr[x 2])/3;
if(gray>Threshold)
{
ptr[x]=255;
ptr[x 1]=255;
ptr[x 2]=255;
}
else
{
ptr[x]=0;
ptr[x 1]=0;
ptr[x 2]=0;
}
}
}
Form1->Image1->Picture->Assign(Bitmap1);
//------計算面積以及重心---------
Byte *tptr;
int r,g,b;
int i,j,XX,YY;
int sum=0, X=0, Y=0;
Bitmap1->Assign(Image1->Picture->Bitmap);
Bitmap1->PixelFormat=pf24bit;
for (int i=0;iHeight;i )
{
tptr=(Byte*)Bitmap1->ScanLine[i];
for (int j=0;jWidth;j )
{
b=tptr[i*3];
g=tptr[i*3 1];
r=tptr[j*3 2];
if(r==255&&g==255&&b==255&&iHeight&&jHeight)
{
sum=sum 1;
X=X i;
Y=Y i;
XX=X/sum;
YY=Y/sum;
Form1->Edit2->Text=sum;
Form1->Edit3->Text=XX;
Form1->Edit4->Text=YY;
}
}
}

}
[/code]
taishyang
站務副站長


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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-07-03 10:05:01 IP:118.169.xxx.xxx 訂閱
可以拆成兩部分來看
1.計算的問題,假如用單張圖片計算會不會有問題?
先用攝影機拍下數張照片,看看這幾張照片計算的結果是否正確

2.截取速度的問題,你可以計算你在timer裡花了多少時間處理,來不來得及你的frame rate
程式碼裡看到你
1.把照片存成檔案
2.用TImgae讀檔
3.Assign給TBitmap處理
這三項就很花時間了,可以合併成一項,直接將攝影機畫面assign給TBitmap,怎麼做站上已經很多參考文章 ^_^
monkey0710
一般會員


發表:2
回覆:1
積分:0
註冊:2008-04-24

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-07-03 15:22:33 IP:140.125.xxx.xxx 訂閱
首先先感謝副站長 taishyang的回覆;昨天晚上檢查了一整晚的程式,跟學弟討論後發現是自己腦殘程式有寫錯的地方,
所以造成面積以及重心計算錯誤。 我鈀修改後的程式碼放在下面。
另外計算速度慢後來是發現我在原本的if回圈裏面計算太多東西了,其實重心可以在迴圈外作計算就會變快了,
修改後的內容一樣在下方。

另外想請教一下 taishyang副站長,因為我用的這三個步驟也是參考站上的其他前輩們的作法,關於您所說的
"直接將攝影機畫面assign給TBitmap"這個做法可以幫小弟解釋一下嘛,因為我找了一下不太知道從何下手。

謝謝,感謝您百忙之中撥空回答。


[code cpp]
//---------------------------------------------------------------------------
#include
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "EzCapCamera"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{

}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button1Click(TObject *Sender)
{
EzCapCamera1->CameraDisplay(); //開啟攝影機攝影機畫面
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
EzCapCamera1->CameraClose();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
Timer1->Enabled=false;
}
//---------------------------------------------------------------------------


void __fastcall TForm1::ScrollBar1Change(TObject *Sender)
{
Graphics::TBitmap *Bitmap1= new Graphics::TBitmap();
Bitmap1->PixelFormat=pf24bit;
Bitmap1->Assign(Image1->Picture);
int Threshold;
Threshold = (int)ScrollBar1->Position;
Byte *ptr;
Byte gray;
for (int y=0; yHeight;y )
{
ptr=(Byte *)Bitmap1->ScanLine[y];
for(int x=0;xWidth*3;x =3)
{
gray=( ptr[x] ptr[x 1] ptr[x 2])/3;
if(gray>Threshold)
{
ptr[x]=255;
ptr[x 1]=255;
ptr[x 2]=255;
}
else
{
ptr[x]=0;
ptr[x 1]=0;
ptr[x 2]=0;
}
}
}
Repaint();
Form1->Image1->Picture->Assign(Bitmap1);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button7Click(TObject *Sender)
{
Timer1->Enabled=true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
//----抓取bmp檔並存為1.bmp-----------
Graphics::TBitmap *Bitmap1 = new Graphics::TBitmap();
EzCapCamera1->CapBitmapFrame(Bitmap1);
EzCapCamera1->CapBmpPic("1.bmp");
Image1->Picture->LoadFromFile("1.bmp");
//---- 抓取ScrollBar的position設為Threshold,並以此值做二值化
Bitmap1->PixelFormat=pf24bit;
Bitmap1->Assign(Image1->Picture);
int Threshold;
Threshold = (int)ScrollBar1->Position;
Edit1->Text=ScrollBar1->Position;
Byte *ptr;
Byte gray;
for (int y=0; yHeight;y )
{
ptr=(Byte *)Bitmap1->ScanLine[y];
for(int x=0;xWidth*3;x =3)
{
gray=( ptr[x] ptr[x 1] ptr[x 2])/3;
if(gray>Threshold)
{
ptr[x]=255;
ptr[x 1]=255;
ptr[x 2]=255;
}
else
{
ptr[x]=0;
ptr[x 1]=0;
ptr[x 2]=0;
}
}
}
Form1->Image1->Picture->Assign(Bitmap1);
//------計算面積以及重心---------
Byte *tptr;
int r,g,b;
int i,j,XX,YY;
int sum=0, X=0, Y=0;
Bitmap1->Assign(Image1->Picture->Bitmap);
Bitmap1->PixelFormat=pf24bit;
for (int i=0;iHeight;i )
{
tptr=(Byte*)Bitmap1->ScanLine[i];
for (int j=0;jWidth;j )
{
b=tptr[j*3];
g=tptr[j*3 1];
r=tptr[j*3 2];
if(r==255&&g==255&&b==255&&iHeight&&jWidth)
{
sum=sum 1;
X=X j;
Y=Y i;
}
}
}
XX=X/sum;
YY=Y/sum;
Form1->Edit2->Text=sum;
Form1->Edit3->Text=XX;
Form1->Edit4->Text=YY;
delete Bitmap1;
}
[/code]
taishyang
站務副站長


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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-07-03 15:30:01 IP:118.169.xxx.xxx 訂閱
我記得元件裡面有CapBitmapFrame function可以用
可以將畫面assign 給TBitmap

===================引 用 monkey0710 文 章===================
另外想請教一下 taishyang副站長,因為我用的這三個步驟也是參考站上的其他前輩們的作法,關於您所說的
"直接將攝影機畫面assign給TBitmap"這個做法可以幫小弟解釋一下嘛,因為我找了一下不太知道從何下手。

系統時間:2024-04-28 21:06:35
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!