• 1.摘要
  • 2.基本信息
  • 3.Kirsch算子介绍
  • 4.相关代码

kirsch算子

Kirsch算子是R.Kirsch提出来一种边缘检测新算法,它采用8个模板对图像上的每一个像素点进行卷积求导数,这8个模板代表8个方向,对图像上的8个特定边缘方向作出最大响应,运算中取最大值作为图像的边缘输出。

基本信息

  • 中文名

    kirsch算子

  • 外文名

    kirsch operator

  • 学术范围

    学术

  • 所求目标

    边缘特征值-边缘强度

  • 本质

    边缘检测新算法

  • 辅助工具

    8个模板

Kirsch算子介绍

为了便于读者理解该算法的实现,这里我们给出实现该算法的函数代码,读者可以稍加改动应用到自己的项目中去。

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×3int 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 DIBcase 4: // 4-bit DIBbreak;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 pImagememset(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 pImagememset(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 formatWriteLog(TRA_LEVEL_WARN,_T("CImageWaterMarkTest::Kirsch, Unrecognized color format"));return FALSE;}return TRUE;}

Note:如有不对或者不明的地方,请指出,谢谢!