kirsch算子实现

kirsch原理:

Kirsch算子是R.Kirsch提出来一种边缘检测新算法,它采用8个模板对图像上的每一个像素点进行卷积求导数,这8个模板代表8个方向,对图像上的8个特定边缘方向作出最大响应,运算中取最大值作为图像的边缘输出(上述算法中用到的8个模板在下面的实现代码中给出)。为了便于读者理解该算法的实现,这里我们给出实现该算法的函数代码,读者可以稍加改动应用到自己的项目中去。 [1]  
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个模版来计算每个边缘方向的最大响应值作为边缘特征值-边缘强度。
c++代码实现:

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   {
  for (j=0; 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   {
  pImage[j+1] = pbBits[effwdt + j];
  pImage[(biHeight-1)*dwEffWidth+j+1] = pbBits[(ds.biHeight-2)*effwdt + j];
  }
  for (i=0; 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   {
  for (j=0; 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   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   {
  for (j=0; 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   {
  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   {
  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   {
  for (j=0; 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   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;
  }

你可能感兴趣的:(kirsch算子实现)