- /********************************************************************************************************
- 文件说明:
- 改进的圆形LBP的C++代码实现
- 开发环境:
- Win7 + OpenCv2.4.8 + VS2012
- 时间地点:
- 陕西师范大学 2017.3.16
- 作 者:
- 九 月
- *********************************************************************************************************/
- #include <iostream>
- #include <opencv2/core/core.hpp>
- #include <opencv2/highgui/highgui.hpp>
- #include <opencv2/imgproc/imgproc.hpp>
- #include <opencv2/contrib/contrib.hpp>
-
- using namespace std;
- using namespace cv;
-
- /********************************************************************************************************
- 函数说明:
- 改进的圆形局部二值模式特征LBP的C++代码实现
- 参数说明:
- 1)Mat img-----------输入图像说明
- 2)int radius--------圆形窗口的半径
- 3)int neighbours----圆形窗口邻域的采样点数
- *********************************************************************************************************/
- //圆形LBP
- cv::Mat ELBP(Mat img, int radius, int neighbors)
- {
- cv::Mat result;
- //【1】创建一个结果矩阵,这个矩阵包含矩阵头和矩阵体
- result.create(img.rows-radius*2, img.cols-radius*2, img.type());
- //【2】初始化这个矩阵的矩阵体
- result.setTo(0);
- //【3】计算圆形邻域内的局部二值模式的LBP特征
- for(int n=0; n<neighbors; n++)
- {
- //【1】2.0*CV_PI/neighbors相当于把一个圆周的弧度值按照采样点的个数进行等分
- float x = static_cast<float>(radius * cos(2.0*CV_PI*n/static_cast<float>(neighbors)));
- float y = static_cast<float>(-radius * sin(2.0*CV_PI*n/static_cast<float>(neighbors)));
-
- int fx = static_cast<int>(floor(x)); //【2】floor的函数是向下取整
- int fy = static_cast<int>(floor(y)); //【3】之所以向下取整,是因为我们以R为半径,以一个点为窗口中心,进行采样,
- // 这样得到的笛卡尔坐标有可能不是整数
- int cx = static_cast<int>(ceil(x)); //【4】向上取整函数,返回一个大于等于X的数
- int cy = static_cast<int>(ceil(y));
- // fractional part
- float ty = y - fy; //【5】计算坐标点的小数部分
- float tx = x - fx;
- // set interpolation weights
- float w1 = (1 - tx) * (1 - ty); //【6】设置插值权重
- float w2 = tx * (1 - ty);
- float w3 = (1 - tx) * ty;
- float w4 = tx * ty;
- // iterate through your data
- for(int i=radius; i < img.rows-radius;i++)
- {
- for(int j=radius;j < img.cols-radius;j++)
- {
- // calculate interpolated value
- 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));
- // floating point precision, so check some machine-dependent epsilon
- 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;
- }
- }
- }
- return result;
- }
-
- int main()
- {
- cv::Mat srcImg = cv::imread(".\\images\\crack.jpeg",0);
- if(srcImg.empty())
- {
- std::cout<<"【NOTICE】NO valid inout image was given,please check the inoput image!"<<std::endl;
- std::system("pause");
- return -1;
- }
- cv::Mat resultMat = ELBP(srcImg,1,8);
- cv::imshow("srcImg",srcImg);
- cv::imshow("imgLBP",resultMat);
- cv::waitKey(0);
- return 0;
- }
- /********************************************************************************************************
- 文件说明:
- 改进的具有灰度不变性的局部二值模式的LBP特征-----代码稍微有点问题
- 开发环境:
- Win7 + OpenCv2.4.8 + VS2012
- 时间地点:
- 陕西师范大学 2017.3.16
- 作 者:
- 九 月
- *********************************************************************************************************/
- #include <iostream>
- #include <opencv2/core/core.hpp>
- #include <opencv2/highgui/highgui.hpp>
- #include <opencv2/imgproc/imgproc.hpp>
- #include <opencv2/contrib/contrib.hpp>
-
- using namespace std;
- using namespace cv;
-
- /********************************************************************************************************
- 函数说明:
- 改进的x旋转不变性局部二值模式特征LBP的C++代码实现
- 参数说明:
- Mat img-----------输入图像说明
- *********************************************************************************************************/
- cv::Mat RILBP(Mat img)
- {
- uchar RITable[256];
- int temp = 0;
- int val = 0;
- cv::Mat result;
- result.create(img.rows - 2, img.cols -2 , img.type());
- result.setTo(0);
- /******************************************************************************************************
- 核心模块:
- 下面这个模块是:旋转不变性局部二值模式LBP特征的核心思想
- 旋转不变:
- 我们把[0,255]这256个值当作256中LBP特征编码值,然后,对每一种特征编码值,先将这种特征编码值当作
- 一个八位的二进制数,并且这八位的二进制数组成了一个圆形;然后不断的对着八位二进制数按位右移,找
- 到这个过程中LBP特征编码所对应的最小的值,然后将这个值保存起来。
- 这块代码的作用,其实就相当于计算出了这256种LBP特征值编码所对应的旋转不变性的LBP特征编码值
- ******************************************************************************************************/
- for(int i = 0; i<256; i++)
- {
- val = i;
- for(int j =0; j<7; j++)
- {
- temp = i>>1;
- if(val>temp)
- {
- val = temp;
- }
- }
- RITable[i] = val;
- }
-
- for(int j=0;j<256;j++)
- {
- std::cout<<j<<"Value = "<<(int)RITable[j]<<std::endl;
- }
- for(int i = 1; i<img.rows - 1; i++)
- {
- for(int j = 1;j<img.cols -1; j++)
- {
- uchar center = img.at<uchar>(i, j);
- uchar code = 0;
-
- code |= (img.at<uchar>(i-1, j-1) >= center)<<7; //按位或
- code |= (img.at<uchar>(i-1, j) >= center)<<6;
- code |= (img.at<uchar>(i-1, j+1) >= center)<<5;
- code |= (img.at<uchar>(i, j+1) >= center)<<4;
- code |= (img.at<uchar>(i+1, j+1) >= center)<<3;
- code |= (img.at<uchar>(i+1, j) >= center)<<2;
- code |= (img.at<uchar>(i+1, j-1) >= center)<<1;
- code |= (img.at<uchar>(i, j-1) >= center)<<0;
-
- result.at<uchar>(i -1, j -1) = RITable[code];
- }
- }
- return result;
- }
-
- int main()
- {
- cv::Mat srcImg = cv::imread(".\\images\\crack.jpeg",0);
- if(srcImg.empty())
- {
- std::cout<<"【NOTICE】NO valid inout image was given,please check the inoput image!"<<std::endl;
- std::system("pause");
- return -1;
- }
-
- cv::Mat resultMat = RILBP(srcImg);
- cv::imshow("srcImg",srcImg);
- cv::imshow("imgLBP",resultMat);
- cv::waitKey(0);
- return 0;
- }
|