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

想請問程式執行十分慢...可能的問題??

尚未結案
vinbaby
一般會員


發表:10
回覆:5
積分:3
註冊:2005-07-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-09-02 22:59:04 IP:61.230.xxx.xxx 未訂閱
我現在正在撰寫一個簡單的圖型配對的程式~~程式已經寫好了~~ 不過發現ㄌㄧ些問題~~想麻煩厲害的大大~~教教我~~ 為什麼它執行的很慢阿~~~配對會找到不過要花約30秒ㄟ~~以下我大約說明一下我程式的過程!!    我有一張大的影像A~~和一張小的影像B~~~而B是從A中切割出來的~~ 所以一定會配對成功~~不過就是執行的很慢~~~我不太清楚為什麼?? 以下我附上我所寫的程式碼~~~
//----------------------------------------------    #include 
#pragma hdrstop
#include "Math.h"
#include "Unit1.h"
//---------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//----------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------
unsigned char img1[200][320*3],img2[40][40*3];
void __fastcall TForm1::Button1Click(TObject *Sender)
{      bool flag = false;
  int i,j,x,y,sum,
      img1_h = Image1->Picture->Bitmap->Height,
      img1_w = Image1->Picture->Bitmap->Width,
      img2_h = Image2->Picture->Bitmap->Height,
      img2_w = Image2->Picture->Bitmap->Width;
  unsigned char *ptr1, *ptr2;      for(i=0; iPicture->Bitmap->ScanLine[i];
    for(j=0; jPicture->Bitmap->ScanLine[i];
     for(j=0; jPicture->Bitmap->ScanLine[i];
     for(j=0; jRefresh();    }
//-------------------------------------------------------------    void __fastcall TForm1::Button2Click(TObject *Sender)
{
   if(OpenPictureDialog1->Execute() ) 
   {
      Image1->Picture->Bitmap->LoadFromFile
         (OpenPictureDialog1->FileName);
      Image1->Height =  Image1->Picture->Bitmap->Height;
      Image1->Width  =  Image1->Picture->Bitmap->Width;
   }
}
//-------------------------------------------------------------    void __fastcall TForm1::Button3Click(TObject *Sender)
{
   if(OpenPictureDialog1->Execute() ) 
   {
      Image2->Picture->Bitmap->LoadFromFile
          (OpenPictureDialog1->FileName);
      Image2->Height =  Image2->Picture->Bitmap->Height;
      Image2->Width  =  Image2->Picture->Bitmap->Width;
   }
}
//---------------------------------------------------------------
 
麻煩可以有大大幫我解答一下~~~>< 以下我附上我的執行介面~~!!
pony0385
一般會員


發表:1
回覆:1
積分:0
註冊:2005-01-23

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-09-03 01:01:55 IP:218.168.xxx.xxx 未訂閱
可能的原因 在 bitmap->ScanLine 在VCl source code 的原型是去 用到 setpixel , getpixel 所以會很慢 若能一次把圖檔load 到memory .. 粉大唷 再和來源的小圖做比對 就可以改善這的問題 haha
------
haha
richtop
資深會員


發表:122
回覆:646
積分:468
註冊:2003-06-10

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-09-03 01:26:32 IP:211.76.xxx.xxx 未訂閱
vinbaby 您好:    有個耍賴的方法可以增進比對的速度,提供您參考一下! 那就是:先對左上角那一點,如果一樣,再進行區塊的比對!  程式增加的部分,以紅色表示:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  .....      for(i=0; isum = abs(img1[i][j]-img2[0][0]);
       if ( sum!=0 ) continue;
       sum = 0;          
       for(x=0; x0 ) break;  // 靈感來自於RedSnow 
       }
       if(sum == 0){
         flag = true;
         for(x=0; x
RichTop 敬上 =====***** 把數學當工具,可以解決問題;將數學變能力,能夠發現並解決問題! =====##### 發表人 - richtop 於 2005/09/03 10:35:55
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-09-03 01:47:00 IP:61.230.xxx.xxx 未訂閱
vinbaby 妳好:    妳這個比對動作是逐點比對,所以會慢是正常的,妳看看程式內用了幾層迴圈就知道了,當然啦~程式還是可以設法做些處理,讓它稍微快一些,我剛才玩了一下,將妳設定的 img1 & img2 由 unsigned char 陣列改成使用 TBitmap,這樣子比較靈活一些,同時也可以用到 ScanLine,讓處理處度能稍快一些,修改的程式碼如下:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    // 下列這兩行是拿來計算執行時間之用的,正式使用時可以刪除掉
    DWORD StartTime, EndTime;
    StartTime = GetTickCount();        Screen->Cursor = crHourGlass;  // 滑鼠指標換成沙漏圖案,表示在處理中        bool flag = false;
    int i, j, x, y, sum;        // 改用 TBitmap 來代替原先的 unsigned char 陣列
    Graphics::TBitmap *img1 = new Graphics::TBitmap();
    Graphics::TBitmap *img2 = new Graphics::TBitmap();
    img1->Assign(Image1->Picture->Bitmap);
    img2->Assign(Image2->Picture->Bitmap);        TRGBTriple *ptr1, *ptr2;  // 使用 TRGBTriple 以提高程式碼的易讀性        for (i=0; iHeight-img2->Height;   i) {
        for (j=0; j<(img1->Width-img2->Width);   j) {
            sum = 0;
            for (x=0; xHeight; x  ) {
                ptr1 = (TRGBTriple *)img1->ScanLine[i x];  // 使用 ScanLine 來擷取比對資料
                ptr2 = (TRGBTriple *)img2->ScanLine[x];
                for (y=0; yWidth; y  ) {
                    sum  = abs(ptr1[j y].rgbtRed   - ptr2[y].rgbtRed);
                    sum  = abs(ptr1[j y].rgbtGreen - ptr2[y].rgbtGreen);
                    sum  = abs(ptr1[j y].rgbtBlue  - ptr2[y].rgbtBlue);
                }
                if(sum != 0) break;  // 若有任一點不相同,則跳出迴圈以節省時間
            }
            if (sum == 0) {
                flag = true;
                // 將找到的位置填成灰色
                for (x=0; xHeight; x  ) {
                    ptr1 = (TRGBTriple *)Image1->Picture->Bitmap->ScanLine[i x];
                    for (y=0; yWidth; y  ) {
                        ptr1[j y].rgbtRed   = 100;
                        ptr1[j y].rgbtGreen = 100;
                        ptr1[j y].rgbtBlue  = 100;
                    }
                }                    break;  // 後邊的資料無需比對了,跳出迴圈以節省時間
            }
        }
                if (flag) break;  // 後邊的資料無需比對了,跳出迴圈以節省時間
    }        Screen->Cursor = crDefault;  // 滑鼠指標恢復成預設圖案        // 下列這一段是拿來計算執行時間之用的,正式使用時可以刪除掉
    EndTime = GetTickCount();
    AnsiString szStr, spStr;
    double clock = (EndTime - StartTime);
    if (clock > 1000.0) {
        clock = clock / 1000.0;
        spStr = FloatToStrF(clock, ffNumber, 3, 3) " 秒";
    }else{
        spStr = FloatToStrF(clock, ffNumber, 3, 0) " 微秒";
    }
    spStr = "使用時間:" spStr;        if (flag) {
        ShowMessage("找到相同的影像\r\n" spStr);
    } else {
        ShowMessage("沒有找到相同的影像\r\n" spStr);
    }        delete img1;
    img1 = NULL;
    delete img2;
    img2 = NULL;        Image1->Refresh();
}
或許還有其它更快速的方式或技巧,但是目前我僅玩到這邊,妳先參考一下吧。 7 天天敲鍵盤 v 時時按滑鼠 8 發表人 - RedSnow 於 2005/09/03 01:52:32
vinbaby
一般會員


發表:10
回覆:5
積分:3
註冊:2005-07-13

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-09-06 14:06:01 IP:220.228.xxx.xxx 未訂閱
謝謝各位大大的熱心教導~~    richtop大大謝謝你ㄉ教導~~不過我這堤結案還是會給RedSnow大大~~ 因為他教ㄌ我不一樣得寫法~~讓我多學到ㄌㄧ些我以前不知道ㄉ東西~~ 希望你別介意~~ >
系統時間:2024-05-03 12:42:19
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!