加载中…
正文 字体大小:

Harris

(2012-11-05 20:11:11)
标签:

杂谈

关于harris算法的方法我就不描述了,非常简单,利用二维方向上的两个导数进行交叉求差,得到在两个方向平均最大的阶梯值,然后根据阈值可以选取感兴趣的角点。离图像方向越来越远了,越发地伤感。。。
   Harris

//Created by pritry

 inline void ImageTemplate(double* pOut, double* pData, int nDataWidth, int nDataHeight, double* pTemplate, int nTmpWidth, int nTmpHeight)
{
    ASSERT(pOut != NULL && pData != NULL);

    double* pTmp = new double[nDataWidth*nDataHeight];

    memset(pTmp , 0, sizeof(double)*nDataWidth*nDataHeight);

    int h = nTmpHeight / 2;
    int w = nTmpWidth / 2;

    for(int j = 0; j < nDataHeight; ++j)
    {
        for(int i = 0; i < nDataWidth; ++i)
        {
            for(int s = 0; s < nTmpHeight; ++s)
                for(int t = 0; t < nTmpWidth; ++t)
                {
                    if((j+s-h) >= 0 && (j+s-h) < nDataHeight && (i+t-w) >= 0 && (i+t-w) < nDataWidth)
                    {
                          pTmp[j*nDataWidth+i] += (pData[(j+s-h)*nDataWidth+(i+t-w)]

                            *pTemplate[s*nTmpWidth+t]);
                    }
                }
        }
    }

    memcpy(pOut, pTmp, sizeof(double)*nDataWidth*nDataHeight);
}

void Harris(unsigned char* pData, int nHeight, int nWidth)   //BGR格式
{
    std::vector<POINT> vecCornerPoint;   //存储角点,可做返回
    std::vector<POINT>* pCornerPoint = &vecCornerPoint;

    pCornerPoint->clear();

    int nGaussSize = 3;
    int nValueSize = 3;
    double sigma = 0.8;
    double thresh = 0.007;  
    double k = 0.06;

    int i, j;

    double* I = new double[nWidth*nHeight];
    double* Ix = new double[nWidth*nHeight];
    double* Ix2 = new double[nWidth*nHeight];
    double* Iy = new double[nWidth*nHeight];
    double* Iy2 = new double[nWidth*nHeight];
    double* Ixy = new double[nWidth*nHeight];
    double* Gauss = new double[nGaussSize*nGaussSize];

 

    for(j = 0; j < nHeight; ++j)
    {
        for(i = 0; i < nWidth; ++i)
        {
            color = m_pdoc->GetPixel(i, j);

            I[j*nWidth+i] = (pData[j*nWidth+i]*0.114f + 

                                      pData[j*nWidth+i+1]*0.587f + 

                                      pData[j*nWidth+i+2]*0.299f);
        }
    }

    double DisX[9] = { 
     -1, 0, 1,
     -1, 0, 1,
     -1, 0, 1
    };

    ImageTemplate(Ix, I, nWidth, nHeight, DisX, 3, 3);

    double DisY[9] = { 
     -1, -1, -1,
     0, 0, 0,
     1, 1, 1
    };

    ImageTemplate(Iy, I, nWidth, nHeight, DisY, 3, 3);

    for(j = 0; j < nHeight; ++j)
    {
        for(i = 0; i < nWidth; ++i)
        {
            Ix2[j*nWidth+i] = Ix[j*nWidth+i] * Ix[j*nWidth+i];
            Iy2[j*nWidth+i] = Iy[j*nWidth+i] * Iy[j*nWidth+i];
            Ixy[j*nWidth+i] = Ix[j*nWidth+i] * Iy[j*nWidth+i];
        }
    }

 //生成高斯模板
    for(j = 0; j < nGaussSize; ++j)
        for(i = 0; i < nGaussSize; ++i)
            Gauss[j*nGaussSize+i] = exp(-((j-nGaussSize/2)*(j-nGaussSize/2)+(i-nGaussSize/2)*(i-  

             nGaussSize/2)) / (2*sigma));

 

    double nTotal = 0;
    for(i = 0; i < nGaussSize*nGaussSize; ++i)
    {
        nTotal += Gauss[i];
    }

    for(j = 0; j < nGaussSize; ++j)
        for(i = 0; i < nGaussSize; ++i)
            Gauss[j*nGaussSize+i] /= nTotal;

    ImageTemplate(Ix2, Ix2, nWidth, nHeight, Gauss, nGaussSize, nGaussSize);
    ImageTemplate(Iy2, Iy2, nWidth, nHeight, Gauss, nGaussSize, nGaussSize);
    ImageTemplate(Ixy, Ixy, nWidth, nHeight, Gauss, nGaussSize, nGaussSize);

 

    double MaxI = -FLT_MAX;

    for(j = 0; j < nHeight; ++j)
    {
        for(i = 0; i < nWidth; ++i)
        {
            I[j*nWidth+i] = (Ix2[j*nWidth+i]*Iy2[j*nWidth+i] - Ixy[j*nWidth+i]*Ixy[j*nWidth+i])
             - k*((Ix2[j*nWidth+i] + Iy2[j*nWidth+i])*(Ix2[j*nWidth+i] + Iy2[j*nWidth+i]));

            if(MaxI < I[j*nWidth+i])
                MaxI = I[j*nWidth+i];
        }
    }

    for(j = 0; j < nHeight; ++j)
   {
       for(i = 0; i < nWidth; ++i)
      {
          double maxValue = I[j*nWidth+i];

          for(int s = 0; s < nValueSize; ++s)
         {
              for(int t = 0; t < nValueSize; ++t)
             {
                  if((j+s-nValueSize/2) >= 0 && (j+s-nValueSize/2) < nHeight && (i+t-nValueSize/2) >= 0

                  && (i+t-nValueSize/2) < nWidth)
                 {
                      if(I[(j+s-nValueSize/2)*nWidth+(i+t-nValueSize/2)] > maxValue)
                     {
                          maxValue = I[(j+s-nValueSize/2)*nWidth+(i+t-nValueSize/2)];
                     }
                }
            }
        }

        if(maxValue > thresh*MaxI && maxValue == I[j*nWidth+i])
        {
                POINT p;

                p.x = i;
                p.y = j;

                pCornerPoint->push_back(p);
        }
    }
     

    if(I) delete [] I;
    if(Ix) delete [] Ix;
    if(Iy) delete [] Iy;
    if(Ixy) delete [] Ixy;
    if(Ix2) delete [] Ix2;
    if(Iy2) delete [] Iy2;
    if(Gauss) delete [] Gauss;

 }


0

阅读 评论 收藏 转载 喜欢 打印举报
已投稿到:
  • 评论加载中,请稍候...
发评论

       

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 不良信息反馈 电话:4006900000 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有