kirsch運算元

Kirsch運算元介紹

Kirsch運算元是R.Kirsch提出來一種邊緣檢測新算法,它採用8個模板對圖像上的每一個像素點進行卷積求導數,這8個模板代表8個方向,對圖像上的8個特定邊緣方向作出最大回響,運算中取最大值作為圖像的邊緣輸出(上述算法中用到的8個模板在下面的實現代碼中給出)。為了便於讀者理解該算法的實現,這裡我們給出實現該算法的函式代碼,讀者可以稍加改動套用到自己的項目中去。

int ntemplate[8][9]={{5,5,5,-3,0,-3,-3,-3,-3},
{-3,5,5,-3,0,5,-3,-3,-3},
{-3,-3,5,-3,0,5,-3,-3,5},
{-3,-3,-3,-3,0,5,-3,5,5},
{-3,-3,-3,-3,0,-3,5,5,5},
{-3,-3,-3,5,0,-3,5,5,-3},
{5,-3,-3,5,0,-3,5,-3,-3},
{5,5,-3,5,0,-3,-3,-3,-3}};//3×3

用這個8個模版來計算每個邊緣方向的最大回響值作為邊緣特徵值-邊緣強度。

相關代碼

//
BOOL CWMSpatialDomain::Kirsch(HANDLE hImage)
{
int Nn=9;
int ntemplate[8][9]={{5,5,5,-3,0,-3,-3,-3,-3},
{-3,5,5,-3,0,5,-3,-3,-3},
{-3,-3,5,-3,0,5,-3,-3,5},
{-3,-3,-3,-3,0,5,-3,5,5},
{-3,-3,-3,-3,0,-3,5,5,5},
{-3,-3,-3,5,0,-3,5,5,-3},
{5,-3,-3,5,0,-3,5,-3,-3},
{5,5,-3,5,0,-3,-3,-3,-3}};//3×3
int nSum[8];

if(hImage==NULL)
{
WriteLog(TRA_LEVEL_WARN,_T("CImageWaterMarkTest::Kirsch, Image is null"));
return FALSE;
}

int i, j, k, l;
int bThre = 5;

BITMAPINFOHEADER ds;
memcpy(&ds,hImage, sizeof(ds));
int effwdt = ((((ds.biBitCount * ds.biWidth ) + 31) / 32) * 4);

BYTE* pbBits = (BYTE*)hImage + *(DWORD*)hImage + ds.biClrUsed * sizeof(RGBQUAD);
WriteLog(TRA_LEVEL_DEBUG,_T("CImageWaterMarkTest::Kirsch, Pic's width=%d, height=%d"),ds.biWidth,ds.biHeight);
switch (ds.biBitCount)
{
case 1: // 1-bit DIB
case 4: // 4-bit DIB
break;
case 8: // 8-bit DIB
{
int biWidth=ds.biWidth+2;
int biHeight=ds.biHeight+2;
long dwEffWidth = ((((ds.biBitCount * biWidth) + 31) / 32) * 4);
BYTE* pImage = new BYTE[dwEffWidth * biHeight];// copy the hImage to new pImage
memset(pImage,0,dwEffWidth * biHeight);
for (i=0; i<ds.biHeight; i++)
{
for (j=0; j<ds.biWidth; j++)
{
pImage[(i+1)*dwEffWidth+j+1] = pbBits[i*effwdt + j];
}
}
pImage[0]=pbBits[effwdt+1];
pImage[biWidth-1]=pbBits[effwdt+ds.biWidth-2];
pImage[dwEffWidth*(biHeight-1)]=pbBits[(ds.biHeight-2)*effwdt+1];
pImage[(dwEffWidth)*(biHeight)-1]=pbBits[(ds.biHeight-2)*effwdt+ds.biWidth-2];
for (j=0; j<ds.biWidth; j++)
{
pImage[j+1] = pbBits[effwdt + j];
pImage[(biHeight-1)*dwEffWidth+j+1] = pbBits[(ds.biHeight-2)*effwdt + j];
}
for (i=0; i<ds.biHeight; i++)
{
pImage[(i+1)*dwEffWidth] = pbBits[i*effwdt + 1];
pImage[(i+1)*dwEffWidth+biWidth-1] = pbBits[i*effwdt + ds.biWidth-2];
}
//SaveAsBmpFileEx(_T("Testfort.bmp"),8,dwEffWidth,biHeight,pImage);

m_ipFramework->ShowProgressCtrl();
for (i=0; i<ds.biHeight; i++)
{
for (j=0; j<ds.biWidth; j++)
{
int nIndex=0;
nSum[0]=nSum[1]=nSum[2]=nSum[3]=nSum[4]=nSum[5]=nSum[6]=nSum[7]=0;
for (k=i;k<=i+2;k++)
{
for (l=j;l<=j+2;l++)
{
nSum[0] += pImage[k*dwEffWidth+l] * ntemplate[0][nIndex];
nSum[1] += pImage[k*dwEffWidth+l] * ntemplate[1][nIndex];
nSum[2] += pImage[k*dwEffWidth+l] * ntemplate[2][nIndex];
nSum[3] += pImage[k*dwEffWidth+l] * ntemplate[3][nIndex];
nSum[4] += pImage[k*dwEffWidth+l] * ntemplate[4][nIndex];
nSum[5] += pImage[k*dwEffWidth+l] * ntemplate[5][nIndex];
nSum[6] += pImage[k*dwEffWidth+l] * ntemplate[6][nIndex];
nSum[7] += pImage[k*dwEffWidth+l] * ntemplate[7][nIndex];
nIndex++;
}
}
int nMax=0;
//取最大方向的導數;
for(k=0;k<8;k++)
{
if(nMax<nSum[k])
nMax=nSum[k];
}
if(nMax<0)
nMax=0;
if(nMax>255)
nMax=255;

if(nMax<255)
{
if(nMax>=bThre)
{
pbBits[i*effwdt + j]=nMax;
}
else
{
pbBits[i*effwdt + j]=0;
}
}
else
{
pbBits[i*effwdt + j]=255;
}
}
m_ipFramework->SetPosProgressCtrl(int((i+1)*100/ds.biHeight));
}
m_ipFramework->SetPosProgressCtrl(100);
m_ipFramework->HideProgressCtrl();
delete[] pImage;
}
break;
case 24: // 24-bit DIB
{
int biWidth=ds.biWidth+2;
int biHeight=ds.biHeight+2;
long dwEffWidth = ((((ds.biBitCount * biWidth) + 31) / 32) * 4);
BYTE* pImage = new BYTE[dwEffWidth * biHeight];// copy the hImage to new pImage
memset(pImage,0,dwEffWidth * biHeight);
int cb = 0;
int cg = 0;
int cr = 0;
for (i=0; i<ds.biHeight; i++)
{
for (j=0; j<ds.biWidth; j++)
{
BYTE *p1 = &pbBits[i*effwdt + j*3];
cb = *p1;cg = *(p1+1);cr = *(p1+2);
pImage[(i+1)*dwEffWidth+j+1] = RGB2GRAY(cr,cg,cb);
}
}
pImage[0]=RGB2GRAY(pbBits[effwdt+5],pbBits[effwdt+4],pbBits[effwdt+3]);
pImage[biWidth-1]=RGB2GRAY(pbBits[effwdt+(ds.biWidth-2)*3+2],pbBits[effwdt+(ds.biWidth-2)*3+1],pbBits[effwdt+(ds.biWidth-2)*3]);
pImage[dwEffWidth*(biHeight-1)]=RGB2GRAY(pbBits[(ds.biHeight-2)*effwdt+5],pbBits[(ds.biHeight-2)*effwdt+4],pbBits[(ds.biHeight-2)*effwdt+3]);
pImage[(dwEffWidth)*(biHeight)-1]=RGB2GRAY(pbBits[(ds.biHeight-2)*effwdt+(ds.biWidth-2)*3+2],pbBits[(ds.biHeight-2)*effwdt+(ds.biWidth-2)*3+1],pbBits[(ds.biHeight-2)*effwdt+(ds.biWidth-2)*3]);
for (j=0; j<ds.biWidth; j++)
{
pImage[j+1] = RGB2GRAY(pbBits[effwdt + j*3+2],pbBits[effwdt + j*3+1],pbBits[effwdt + j*3]);
pImage[(biHeight-1)*dwEffWidth+j+1] = RGB2GRAY(pbBits[(ds.biHeight-2)*effwdt + j*3+2],pbBits[(ds.biHeight-2)*effwdt + j*3+1],pbBits[(ds.biHeight-2)*effwdt + j*3]);
}
for (i=0; i<ds.biHeight; i++)
{
pImage[(i+1)*dwEffWidth] = RGB2GRAY(pbBits[i*effwdt + 5],pbBits[i*effwdt + 4],pbBits[i*effwdt + 3]);
pImage[(i+1)*dwEffWidth+biWidth-1] = RGB2GRAY(pbBits[i*effwdt + (ds.biWidth-2)*3+2],pbBits[i*effwdt + (ds.biWidth-2)*3+1],pbBits[i*effwdt + (ds.biWidth-2)*3]);
}
//SaveAsBmpFileEx(_T("Testfort.bmp"),8,dwEffWidth,biHeight,pImage);

m_ipFramework->ShowProgressCtrl();
for (i=0; i<ds.biHeight; i++)
{
for (j=0; j<ds.biWidth; j++)
{
int nIndex=0;
nSum[0]=nSum[1]=nSum[2]=nSum[3]=nSum[4]=nSum[5]=nSum[6]=nSum[7]=0;
for (k=i;k<=i+2;k++)
{
for (l=j;l<=j+2;l++)
{
nSum[0] += pImage[k*dwEffWidth+l] * ntemplate[0][nIndex];
nSum[1] += pImage[k*dwEffWidth+l] * ntemplate[1][nIndex];
nSum[2] += pImage[k*dwEffWidth+l] * ntemplate[2][nIndex];
nSum[3] += pImage[k*dwEffWidth+l] * ntemplate[3][nIndex];
nSum[4] += pImage[k*dwEffWidth+l] * ntemplate[4][nIndex];
nSum[5] += pImage[k*dwEffWidth+l] * ntemplate[5][nIndex];
nSum[6] += pImage[k*dwEffWidth+l] * ntemplate[6][nIndex];
nSum[7] += pImage[k*dwEffWidth+l] * ntemplate[7][nIndex];
nIndex++;
}
}
int nMax=0;
//取最大方向的導數;
for(k=0;k<8;k++)
{
nSum[k] = fabs(nSum[k]);
if(nMax<nSum[k])
nMax=nSum[k];
}
if(nMax<0)
nMax=0;
if(nMax>255)
nMax=255;
if(nMax<255)
{
if(nMax>=bThre)
{
pbBits[i*effwdt + j*3]=nMax;
pbBits[i*effwdt + j*3+1]=nMax;
pbBits[i*effwdt + j*3+2]=nMax;
}
else
{
pbBits[i*effwdt + j*3]=0;
pbBits[i*effwdt + j*3+1]=0;
pbBits[i*effwdt + j*3+2]=0;
}
}
else
{
pbBits[i*effwdt + j*3]=255;
pbBits[i*effwdt + j*3+1]=255;
pbBits[i*effwdt + j*3+2]=255;
}
}
m_ipFramework->SetPosProgressCtrl(int((i+1)*100/ds.biHeight));
}
m_ipFramework->SetPosProgressCtrl(100);
m_ipFramework->HideProgressCtrl();
delete[] pImage;
}
break;

default: // Unrecognized color format
WriteLog(TRA_LEVEL_WARN,_T("CImageWaterMarkTest::Kirsch, Unrecognized color format"));
return FALSE;
}
return TRUE;
}

Note:如有不對或者不明的地方,請指出,謝謝!

相關詞條

相關搜尋

熱門詞條

聯絡我們