/*************************************************************************
*
* 函数名称:
*   TemplateMatchDIB()
*
* 参数:
*   LPSTR lpDIBBits    - 指向源DIB图像指针
*   LPSTR lpDIBBitsBK  - 指向背景DIB图像指针
*   LONG  lWidth       - 源图像宽度(象素数)
*   LONG  lHeight      - 源图像高度(象素数)
*   LONG  lTemplateWidth       - 模板图像宽度(象素数)
*   LONG  lTemplateHeight      - 模板图像高度(象素数)
*
* 返回值:
*   BOOL               - 运算成功返回TRUE,否则返回FALSE。
*
* 说明:
* 该函数用于对图像进行模板匹配运算。
*
* 要求目标图像为255个灰度值的灰度图像。
************************************************************************/

BOOL WINAPI TemplateMatchDIB (LPSTR lpDIBBits, LPSTR lpTemplateDIBBits, LONG lWidth, LONG lHeight,
                                            LONG lTemplateWidth,LONG lTemplateHeight)
{      
      // 指向源图像的指针
      LPSTR      lpSrc,lpTemplateSrc;
      
      // 指向缓存图像的指针
      LPSTR      lpDst;
      
      // 指向缓存DIB图像的指针
      LPSTR      lpNewDIBBits;
      HLOCAL      hNewDIBBits;

      //循环变量
      long i;
      long j;
      long m;
      long n;

      //中间结果
      double dSigmaST;
      double dSigmaS;
      double dSigmaT;

      //相似性测度
      double R;

      //最大相似性测度
      double MaxR;

      //最大相似性出现位置
      long lMaxWidth;
      long lMaxHeight;

      //像素值
      unsigned char pixel;
      unsigned char templatepixel;

      // 图像每行的字节数
      LONG lLineBytes,lTemplateLineBytes;

      // 暂时分配内存,以保存新图像
      hNewDIBBits = LocalAlloc(LHND, lWidth * lHeight);

      if (hNewDIBBits == NULL)
      {
            // 分配内存失败
            return FALSE;
      }
      
      // 锁定内存
      lpNewDIBBits = (char * )LocalLock(hNewDIBBits);

      // 初始化新分配的内存,设定初始值为255
      lpDst = (char *)lpNewDIBBits;
      memset(lpDst, (BYTE)255, lWidth * lHeight);

      // 计算图像每行的字节数
      lLineBytes = WIDTHBYTES(lWidth * 8);
      lTemplateLineBytes = WIDTHBYTES(lTemplateWidth * 8);

      //计算dSigmaT
      dSigmaT = 0;
      for (n = 0;n < lTemplateHeight ;n++)
      {
            for(m = 0;m < lTemplateWidth ;m++)
            {
                  // 指向模板图像倒数第j行,第i个象素的指针                  
                  lpTemplateSrc = (char *)lpTemplateDIBBits + lTemplateLineBytes * n + m;
                  templatepixel = (unsigned char)*lpTemplateSrc;
                  dSigmaT += (double)templatepixel*templatepixel;
            }
      }

      //找到图像中最大相似性的出现位置
      MaxR = 0.0;
      for (j = 0;j < lHeight - lTemplateHeight +1 ;j++)
      {
            for(i = 0;i < lWidth - lTemplateWidth + 1;i++)
            {
                  dSigmaST = 0;
                  dSigmaS = 0;
      
                  for (n = 0;n < lTemplateHeight ;n++)
                  {
                        for(m = 0;m < lTemplateWidth ;m++)
                        {
                              // 指向源图像倒数第j+n行,第i+m个象素的指针                  
                              lpSrc  = (char *)lpDIBBits + lLineBytes * (j+n) + (i+m);
                  
                              // 指向模板图像倒数第n行,第m个象素的指针                  
                              lpTemplateSrc  = (char *)lpTemplateDIBBits + lTemplateLineBytes * n + m;

                              pixel = (unsigned char)*lpSrc;
                              templatepixel = (unsigned char)*lpTemplateSrc;

                              dSigmaS += (double)pixel*pixel;
                              dSigmaST += (double)pixel*templatepixel;
                        }
                  }
                  //计算相似性
                  R = dSigmaST / ( sqrt(dSigmaS)*sqrt(dSigmaT));
                  //与最大相似性比较
                  if (R > MaxR)
                  {
                        MaxR = R;
                        lMaxWidth = i;
                        lMaxHeight = j;
                  }
            }
      }

      //将最大相似性出现区域部分复制到目标图像
      for (n = 0;n < lTemplateHeight ;n++)
      {
            for(m = 0;m < lTemplateWidth ;m++)
            {
                  lpTemplateSrc = (char *)lpTemplateDIBBits + lTemplateLineBytes * n + m;
                  lpDst = (char *)lpNewDIBBits + lLineBytes * (n+lMaxHeight) + (m+lMaxWidth);
                  *lpDst = *lpTemplateSrc;
            }
      }
      
      // 复制图像
      memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight);

      // 释放内存
      LocalUnlock(hNewDIBBits);
      LocalFree(hNewDIBBits);

      // 返回
      return TRUE;
}
Posted on 2005-03-19 10:33  domini  阅读(965)  评论(1编辑  收藏  举报