分享

【图像特征提取4】改进的圆形局部二值模式LBP特征描述符C++代码的实现

 mscdj 2017-12-27
  1. /******************************************************************************************************** 
  2. 文件说明: 
  3.         改进的圆形LBP的C++代码实现 
  4. 开发环境: 
  5.         Win7 + OpenCv2.4.8 + VS2012 
  6. 时间地点: 
  7.         陕西师范大学 2017.3.16 
  8. 作    者: 
  9.         九 月 
  10. *********************************************************************************************************/  
  11. #include <iostream>  
  12. #include <opencv2/core/core.hpp>  
  13. #include <opencv2/highgui/highgui.hpp>  
  14. #include <opencv2/imgproc/imgproc.hpp>  
  15. #include <opencv2/contrib/contrib.hpp>  
  16.   
  17. using namespace std;  
  18. using namespace cv;  
  19.   
  20. /******************************************************************************************************** 
  21. 函数说明: 
  22.         改进的圆形局部二值模式特征LBP的C++代码实现 
  23. 参数说明: 
  24.         1)Mat img-----------输入图像说明 
  25.         2)int radius--------圆形窗口的半径 
  26.         3)int neighbours----圆形窗口邻域的采样点数 
  27. *********************************************************************************************************/  
  28. //圆形LBP  
  29. cv::Mat ELBP(Mat img, int radius, int neighbors)  
  30. {  
  31.    cv::Mat result;  
  32.    //【1】创建一个结果矩阵,这个矩阵包含矩阵头和矩阵体  
  33.    result.create(img.rows-radius*2, img.cols-radius*2, img.type());  
  34.    //【2】初始化这个矩阵的矩阵体  
  35.    result.setTo(0);  
  36.    //【3】计算圆形邻域内的局部二值模式的LBP特征  
  37.    for(int n=0; n<neighbors; n++)  
  38.      {  
  39.                                                             //【1】2.0*CV_PI/neighbors相当于把一个圆周的弧度值按照采样点的个数进行等分  
  40.         float x = static_cast<float>(radius  * cos(2.0*CV_PI*n/static_cast<float>(neighbors)));          
  41.         float y = static_cast<float>(-radius * sin(2.0*CV_PI*n/static_cast<float>(neighbors)));  
  42.           
  43.         int fx = static_cast<int>(floor(x));              //【2】floor的函数是向下取整  
  44.         int fy = static_cast<int>(floor(y));              //【3】之所以向下取整,是因为我们以R为半径,以一个点为窗口中心,进行采样,  
  45.                                                             //     这样得到的笛卡尔坐标有可能不是整数     
  46.         int cx = static_cast<int>(ceil(x));               //【4】向上取整函数,返回一个大于等于X的数  
  47.         int cy = static_cast<int>(ceil(y));  
  48.         // fractional part  
  49.         float ty = y - fy;                                  //【5】计算坐标点的小数部分  
  50.         float tx = x - fx;  
  51.         // set interpolation weights  
  52.         float w1 = (1 - tx) * (1 - ty);                     //【6】设置插值权重  
  53.         float w2 =      tx  * (1 - ty);  
  54.         float w3 = (1 - tx) *      ty;  
  55.         float w4 =      tx  *      ty;  
  56.         // iterate through your data  
  57.         for(int i=radius; i < img.rows-radius;i++)   
  58.         {  
  59.             for(int j=radius;j < img.cols-radius;j++)   
  60.             {  
  61.                 // calculate interpolated value  
  62.                 float t = static_cast<float>(w1*img.at<uchar>(i+fy,j+fx) + w2*img.at<uchar>(i+fy,j+cx) + w3*img.at<uchar>(i+cy,j+fx) + w4*img.at<uchar>(i+cy,j+cx));  
  63.                 // floating point precision, so check some machine-dependent epsilon  
  64.                 result.at<uchar>(i-radius,j-radius) += ((t > img.at<uchar>(i,j)) || (std::abs(t-img.at<uchar>(i,j)) < std::numeric_limits<float>::epsilon())) << n;  
  65.             }  
  66.         }  
  67.    }  
  68.    return result;  
  69. }  
  70.   
  71. int main()  
  72. {  
  73.     cv::Mat srcImg = cv::imread(".\\images\\crack.jpeg",0);  
  74.     if(srcImg.empty())  
  75.     {  
  76.         std::cout<<"【NOTICE】NO valid inout image was given,please check the inoput image!"<<std::endl;  
  77.         std::system("pause");  
  78.         return -1;  
  79.     }  
  80.     cv::Mat resultMat = ELBP(srcImg,1,8);  
  81.     cv::imshow("srcImg",srcImg);  
  82.     cv::imshow("imgLBP",resultMat);  
  83.     cv::waitKey(0);  
  84.     return 0;  
  85. }  

  1. /******************************************************************************************************** 
  2. 文件说明: 
  3.         改进的具有灰度不变性的局部二值模式的LBP特征-----代码稍微有点问题 
  4. 开发环境: 
  5.         Win7 + OpenCv2.4.8 + VS2012 
  6. 时间地点: 
  7.         陕西师范大学 2017.3.16 
  8. 作    者: 
  9.         九 月 
  10. *********************************************************************************************************/  
  11. #include <iostream>  
  12. #include <opencv2/core/core.hpp>  
  13. #include <opencv2/highgui/highgui.hpp>  
  14. #include <opencv2/imgproc/imgproc.hpp>  
  15. #include <opencv2/contrib/contrib.hpp>  
  16.   
  17. using namespace std;  
  18. using namespace cv;  
  19.   
  20. /******************************************************************************************************** 
  21. 函数说明: 
  22.         改进的x旋转不变性局部二值模式特征LBP的C++代码实现 
  23. 参数说明: 
  24.         Mat img-----------输入图像说明 
  25. *********************************************************************************************************/  
  26. cv::Mat RILBP(Mat img)  
  27. {  
  28.     uchar   RITable[256];  
  29.    int     temp = 0;  
  30.    int     val  = 0;  
  31.    cv::Mat result;  
  32.    result.create(img.rows - 2, img.cols -2 , img.type());  
  33.    result.setTo(0);  
  34.    /****************************************************************************************************** 
  35.    核心模块: 
  36.             下面这个模块是:旋转不变性局部二值模式LBP特征的核心思想 
  37.    旋转不变: 
  38.             我们把[0,255]这256个值当作256中LBP特征编码值,然后,对每一种特征编码值,先将这种特征编码值当作 
  39.             一个八位的二进制数,并且这八位的二进制数组成了一个圆形;然后不断的对着八位二进制数按位右移,找 
  40.             到这个过程中LBP特征编码所对应的最小的值,然后将这个值保存起来。 
  41.                 这块代码的作用,其实就相当于计算出了这256种LBP特征值编码所对应的旋转不变性的LBP特征编码值 
  42.    ******************************************************************************************************/  
  43.    for(int i = 0; i<256; i++)  
  44.    {  
  45.       val = i;  
  46.       for(int j =0; j<7; j++)  
  47.       {  
  48.          temp = i>>1;  
  49.          if(val>temp)  
  50.          {  
  51.            val = temp;  
  52.          }  
  53.        }  
  54.       RITable[i] = val;  
  55.    }  
  56.   
  57.    for(int j=0;j<256;j++)  
  58.    {  
  59.        std::cout<<j<<"Value = "<<(int)RITable[j]<<std::endl;  
  60.    }  
  61.    for(int i = 1; i<img.rows - 1; i++)  
  62.    {  
  63.       for(int j = 1;j<img.cols -1; j++)  
  64.       {  
  65.          uchar center = img.at<uchar>(i, j);  
  66.          uchar code = 0;  
  67.   
  68.          code |= (img.at<uchar>(i-1, j-1) >= center)<<7;               //按位或  
  69.          code |= (img.at<uchar>(i-1, j)   >= center)<<6;  
  70.          code |= (img.at<uchar>(i-1, j+1) >= center)<<5;  
  71.          code |= (img.at<uchar>(i,   j+1) >= center)<<4;  
  72.          code |= (img.at<uchar>(i+1, j+1) >= center)<<3;  
  73.          code |= (img.at<uchar>(i+1, j)   >= center)<<2;  
  74.          code |= (img.at<uchar>(i+1, j-1) >= center)<<1;  
  75.          code |= (img.at<uchar>(i,   j-1) >= center)<<0;  
  76.   
  77.          result.at<uchar>(i -1, j -1) = RITable[code];         
  78.       }  
  79.    }  
  80.    return result;  
  81. }  
  82.   
  83. int main()  
  84. {  
  85.     cv::Mat srcImg = cv::imread(".\\images\\crack.jpeg",0);  
  86.     if(srcImg.empty())  
  87.     {  
  88.         std::cout<<"【NOTICE】NO valid inout image was given,please check the inoput image!"<<std::endl;  
  89.         std::system("pause");  
  90.         return -1;  
  91.     }  
  92.   
  93.     cv::Mat resultMat = RILBP(srcImg);  
  94.     cv::imshow("srcImg",srcImg);  
  95.     cv::imshow("imgLBP",resultMat);  
  96.     cv::waitKey(0);  
  97.     return 0;  
  98. }  


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多