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

關於USB CCD影像處理的一些問題...

尚未結案
Fusheng
一般會員


發表:4
回覆:6
積分:2
註冊:2005-08-03

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-08-06 01:36:23 IP:59.115.xxx.xxx 未訂閱
問題一: 我使用的USB CCD 規格表上說最快每秒可擷取30張 我處理後每秒只有十張左右(計算畫面上四種顏色的平均座標) 以各位大大的經驗來看,我寫的程式是否還有改進的空間呢? 問題二: 若使用一般的CCD Camera 影像擷取卡....速度是否會改進呢? 問題三: 使用USB CCD 與 CCD 影像擷取卡 , 哪個佔較少的CPU資源呢? == 因手邊沒影像擷取卡,所以才考慮要不要改成這個 ^^" 感謝各位的幫忙 ~~ 發表人 - Fusheng 於 2005/08/06 01:37:25
arisaka_matsuri
高階會員


發表:25
回覆:205
積分:231
註冊:2003-10-19

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-08-06 09:30:13 IP:220.135.xxx.xxx 未訂閱
答一: 很難說,但一般來看,只是計算四種顏色的平均座標,不會花那麼多時間。    答二: 如果你的程式沒變,我想速度不會差太多。但是,由於省掉USB消耗的資源,「感覺上」應該會快一點。    答三: 同答二,多花一點錢總是好辦事
Fusheng
一般會員


發表:4
回覆:6
積分:2
註冊:2005-08-03

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-08-07 00:24:49 IP:59.115.xxx.xxx 未訂閱
每秒30張我想是指320*240的情況下... 我是把設定調成640*480...不過速度應該不會掉太多... 想想....還是我自己寫的有問題 貼一下我寫的程式 麻煩各位一下,要怎麼改,每秒的張數才會增加呢? (順便問一下,我跑這個程式的時候,佔了CPU40%的資源耶...這樣算正常嗎?) === 以下是程式碼...參考精華區中多位大大的寫法... //---------------------------------------------------------------------------
#include 
#include 
#pragma hdrstop
#include "vfw.h"
#include <math.h>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;    BYTE* Line;
Graphics::TBitmap *bmp = new Graphics::TBitmap();
LPVIDEOHDR VideoStr;
LRESULT CALLBACK FrameCallBack( HWND, Longint );
int  IndexX=320,IndexY=240;
int  p_x1,p_y1,p_x2,p_y2,p_x3,p_y3,p_x4,p_y4;
int  th_x1,th_y1,th_x2,th_y2;
int  th_r1,th_r2,th_g1,th_g2,th_b1,th_b2;
int  o1th_r1,o1th_r2,o1th_g1,o1th_g2,o1th_b1,o1th_b2;
int  o2th_r1,o2th_r2,o2th_g1,o2th_g2,o2th_b1,o2th_b2;
int  o3th_r1,o3th_r2,o3th_g1,o3th_g2,o3th_b1,o3th_b2;
int  o4th_r1,o4th_r2,o4th_g1,o4th_g2,o4th_b1,o4th_b2;
int count_mouse_down=0;
int run_obj1=0,run_obj2=0,run_obj3=0,run_obj4=0;
int clear=0;
float starttime,endtime,totaltime;    //---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{    }
//---------------------------------------------------------------------------    HWND ghCapWnd;
LRESULT CALLBACK FrameCallBack( HWND hwnd, Longint lpvhdr );
//---------------------------------------------------------------------------
LRESULT CALLBACK FrameCallBack( HWND hwnd, Longint lpvhdr )
{     LPVIDEOHDR VideoStr;
 static BITMAPINFOHEADER BitmapHead;
 static BITMAPINFO BitmapInfo;
 static BITMAPFILEHEADER BitmapFileHead;
 CAPSTATUS status;
 int BIHsize, byte;
 Byte *ptr;
 TMemoryStream *stream = new TMemoryStream;
 VideoStr=LPVIDEOHDR(lpvhdr);                        // 取得圖片資料
 capGetStatus( ghCapWnd, &status, sizeof(status) ) ; // 取得CAP訊息
 BIHsize=capGetVideoFormatSize( ghCapWnd );          // 取得圖片格式容量大小
 capGetVideoFormat( ghCapWnd, &BitmapHead, BIHsize); // 取得圖片格式 代入 bitmapinfohead 內
 BitmapInfo.bmiHeader=BitmapHead;                    // 設定 BITMAPINFO
 stream->Size=sizeof(BitmapFileHead)   sizeof(BitmapHead)   BitmapHead.biSizeImage; // 取得圖檔總容量
 // 設定 BITMAPFILEHEAD
 BitmapFileHead.bfType=0x4D42; //總是 BM
 BitmapFileHead.bfSize=stream->Size; //該圖檔總大小
 BitmapFileHead.bfOffBits=sizeof(BitmapFileHead)   sizeof(BitmapHead); // 偏移至imagedata大小
 // 將資料存入 memorystream
 stream->Position=0;
 stream->WriteBuffer( &BitmapFileHead, sizeof(BitmapFileHead) );
 stream->WriteBuffer( &BitmapInfo, sizeof(BitmapInfo) );
 (void*)ptr=stream->Memory;
 ptr  = BitmapFileHead.bfOffBits;
 Move( VideoStr->lpData, ptr, BitmapHead.biSizeImage);
 // 存入完成     stream->Position=0;    //Form1->Image1->Picture->Bitmap->LoadFromStream(stream);
bmp->LoadFromStream(stream);     delete stream ;
 capSetCallbackOnFrame (ghCapWnd, NULL); //停止callbackonframe     int i,j;
 int cx1=0,cy1=0,c1=0,cx2=0,cy2=0,c2=0,cx3=0,cy3=0,c3=0,cx4=0,cy4=0,c4=0;
 int B,G,R;     for(j=0;jScanLine[IndexY-1-j];
        for(i=0;i=o1th_r1 && R<=o1th_r2 && G>=o1th_g1 && G<=o1th_g2 && B>=o1th_b1 && B<=o1th_b2)
         //     if(sqrt(tr*tr tg*tg tb*tb)<150)
              {
                  cx1=cx1 i;
                  cy1=cy1 j;
                  c1=c1 1;
              }              }
 }             if(c1>5)
         {
         p_x1=cx1/c1;
         p_y1=cy1/c1;
         }
         else
         {
         p_x1=0;
         p_y1=0;
         }
         }    Form1->Image1->Picture->Bitmap->Assign(bmp);    //顯示畫面在Bitmap上,可刪    endtime=clock()-starttime;
totaltime=endtime/1000;
starttime=clock();     return(0);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
 Form1->DoubleBuffered=true;
 ghCapWnd = capCreateCaptureWindow ( "Capture Window",
 WS_CHILD | WS_VISIBLE ,0,0,/*Panel1->Width,Panel1->Height,Panel1->Handle*/1,1,Handle, 0);  //設定視窗大小
 bool a = false;
 for(int i=0;i<10;i  )
 {
  a=capDriverConnect(ghCapWnd,i);
        if( a )
          {
          break;}
 }      if( !a )
   ShowMessage("攝影機連接失敗..");
// if (!capOverlay(ghCapWnd,true))
// {
    capDlgVideoFormat(ghCapWnd);        //設定解析度or影像格式
    capPreviewRate(ghCapWnd,66);
//    capPreview(ghCapWnd,true);    // }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
 capSetCallbackOnFrame (ghCapWnd, &FrameCallBack);
}
//-------------------------------------------------------
void __fastcall TForm1::Timer2Timer(TObject *Sender)
{    if(totaltime!=0)
{totaltime=1/totaltime;
Edit9->Text=totaltime;}
}
發表人 - Fusheng 於 2005/08/07 00:32:54
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-08-07 00:35:33 IP:219.84.xxx.xxx 未訂閱
Fusheng你好:     你的做法是把圖片讀入MemoryStream,之後又讀進Bitmap,最後又用Scanline,花的時間當然會多不少。我的做法是直接讀影像至一個記憶體空間,之後直接處理。以下是我的做法的片段....,我想速度應該會差不少。     
 
LRESULT CALLBACK TCCDPanel::capVideoStreamCallback(HWND hWnd,LPVIDEOHDR lpVHdr)
{
    TCCDPanel* Panel = (TCCDPanel*)GetWindowLong(hWnd,GWL_USERDATA);
    if(Panel)
        {
        size_t size = lpVHdr->dwBufferLength;
        unsigned char* pr = Panel->r.begin();
        unsigned char* pg = Panel->g.begin();
        unsigned char* pb = Panel->b.begin();
        unsigned char* pi = (unsigned char*)lpVHdr->lpData;
        unsigned char* pi_end = pi   size;
        while(pi < pi_end)
            {
            *pr = *pi;
              pi;
              pr;
            *pg = *pi;
              pi;
              pg;
            *pb = *pi;
              pi;
              pb;
            }
        Panel->updated = true;
        }
    return true;
}
發表人 - pwipwi 於 2005/08/07 00:38:32
Fusheng
一般會員


發表:4
回覆:6
積分:2
註冊:2005-08-03

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-08-07 03:02:16 IP:59.115.xxx.xxx 未訂閱
pwipwi你好: 您寫的方法我有點看不懂耶..(while內的東西除外) 可以稍微解釋一下嗎? 另, 其實我是只會處理Bitmap....所以才會這麼作,沒想到卻拖慢了速度... 可否說明一下讀到記憶體空間後要怎麼處理嗎?? 非常的感謝你~
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-08-07 12:33:06 IP:219.84.xxx.xxx 未訂閱
其實重點只在取得lpVHdr內的影像資料(while內在做的事),pr,pg,pb這三個指標是指向三個預先配置好空間的記憶體,然後在while內把ccd的影像重接寫入。之後我處理的時候就直接處理這三個記憶體的資料即可。 其他像TCCDPanel只是我自已設計的一個元件,拿來處理預先配置記憶體和ccd視窗的相關處理(就像你在FormCreast時做的一樣),應該不是重點所在。
Fusheng
一般會員


發表:4
回覆:6
積分:2
註冊:2005-08-03

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-08-10 20:42:56 IP:163.28.xxx.xxx 未訂閱
pwipwi你好:    我使用了你說的方法,讀入記憶體直接處理 速度果然從每秒10張提升至15張左右,真是非常的感謝你~< > 現在又有個問題了...< > 我把LRESULT CALLBACK 內的code全刪了 只放一個計數的功能(count ;) 直接測出來每秒也是16張左右耶... 什麼code都沒有,怎麼會那麼慢呢? 這樣一來,我不管再怎麼改code,速度也改變不了了
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-08-10 22:56:05 IP:219.84.xxx.xxx 未訂閱
你的Callback呼叫和大家的做法都不太一樣,可以先參考一下站上一些相關文章作修改。 我想應該是Callback的問題。
系統時間:2024-04-30 0:45:53
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!