使用多線程的圖像模板比較算法.
(2008-04-06 14:50:46)
下一個
把一幅大圖分成兩部分,一個線程處理1/2幅圖,以列(Height)或者行(Width)劃分圖.第一幅圖的Column從0到width/2, 第二幅圖的列從width/2到width. 創建兩個線程單獨處理一部分,等待線程結束,再合並結果,即在兩個結果中再取相似度較高者(correlation最小).
class DIBSecion{... void NormalizedCross();
int correlate(DIBSection& db2, int x, int y);
int RunCorrelate(DIBSection& db2, int startx, int starty);
virtual int RunThread(PVOID data);
void CreateThread(PVOID pdata);};
typedef int ( DIBSection::*Proc)(PVOID data);
typedef struct { DIBSection* pBaseClass; DIBSection* image2; int startx, endx; int minc; int minx,miny; void *pThreadData; Proc pfun; HANDLE mHandle; DWORD mThreadId;}_DIVDATA;
int DIBSection::correlate(DIBSection& db2, int x0, int y0){ int c = 0; for (int x = 0; x < db2.Width(); x++) for (int y = 0; y < db2.Height(); y++) { c += GetData(y + y0, x + x0).r * db2.GetData(y, x).r; } return c;}
void DIBSection::NormalizedCross(){ int ReadBMPFile(const char * filename, DIBSection& dib); DIBSection temp; char *file = "c:tempstretchtemplate.bmp"; ReadBMPFile(file, temp); temp.ConvertToGray();
_DIVDATA data; data.endx = (Width() - temp.Width() ) / 2 ; data.startx = 0; data.image2 = &temp; CreateThread(&data);
_DIVDATA data2; data2.startx = (Width() - temp.Width() ) / 2 +1; data2.endx = Width() - temp.Width() ; data2.image2 = &temp; CreateThread(&data2);
WaitForSingleObject(data.mHandle, INFINITE ); WaitForSingleObject(data2.mHandle, INFINITE );
DWORD ret = 0; GetExitCodeThread(data.mHandle, &ret); DWORD ret2 = 0; GetExitCodeThread(data2.mHandle, &ret2); int minx, miny; if (data.minc < data2.minc) { minx = data.minx; miny = data.miny; } else { minx = data2.minx; miny = data2.miny; } ; return;}
int DIBSection::RunThread(PVOID data){ _DIVDATA *pdata =(_DIVDATA*)data; int min = INT_MAX, minx, miny;
for (int x = pdata->startx; x < pdata->endx; x++) for (int y = 0; y < Height() - pdata->image2->Width(); y++) { int c = correlate(*pdata->image2, x, y); if (min > c) { min = c; minx = x; miny = y; } } pdata->minc = min; pdata->minx = minx; pdata->miny = miny; return 1;}
DWORD WINAPI RunThreadTool(LPVOID p){ _DIVDATA *pdata = (_DIVDATA *)p; try {
return (pdata->pBaseClass->*(pdata->pfun))(p); } catch(...) { return 0; } return 1;//return 0 if cancelled}
void DIBSection::CreateThread(PVOID pdata){ _DIVDATA *data = (_DIVDATA *)pdata;
data->pfun = &DIBSection::RunThread; data->pBaseClass = this; data->mHandle = NULL; data->minc = 0; data->minx = 0; data->pThreadData = NULL; data->mThreadId = 0; data->miny = 0;
HANDLE t1 = ::CreateThread (0, 0, RunThreadTool, pdata, 0, &((_DIVDATA*)pdata)->mThreadId); ((_DIVDATA*)pdata)->mHandle = t1;}