局部二值模式LBP由于其简单、高效在目标检测、目标识别、图像检索等领域得到了广泛的应用。现如今,LBP的变体不下上十种,如VLBP、SILBP等。要了解更多关于LBP的知识可以参考:纹理分类-全局特征LBP及相关文献。
2)带有容忍银子的LBP算子
3)带有乘性因子的LBP算子
欲了解更多参考论文
:Modeling Pixel Process with Scale Invariant Local Patterns for Background Subtraction in Complex Scenes。
下面介绍的三种LBP算子的区别见下图:
本文不介绍LBP的理论知识,只是简单的说说LBP及其变体的实现:
1)最原始的LBP算子的实现代码
- void lbp( Mat& _src, Mat& _dst)
- {
- if ( -_dst.empty())
- _dst.create(_src.rows, _src.cols, CV_8UC1);
- _dst = cv::Scalar::all(0);
- // calculate patterns
- for(int i=1;i<_src.rows-1;i++)
- {
- for(int j=1;j<_src.cols-1;j++)
- {
- uchar center = _src.at<uchar>(i,j);
- unsigned char code = 0;
- code |= (_src.at<uchar>(i-1,j-1) >= center) << 7;
- code |= (_src.at<uchar>(i-1,j) >= center) << 6;
- code |= (_src.at<uchar>(i-1,j+1) >= center) << 5;
- code |= (_src.at<uchar>(i,j+1) >= center) << 4;
- code |= (_src.at<uchar>(i+1,j+1) >= center) << 3;
- code |= (_src.at<uchar>(i+1,j) >= center) << 2;
- code |= (_src.at<uchar>(i+1,j-1) >= center) << 1;
- code |= (_src.at<uchar>(i,j-1) >= center) << 0;
- _dst.at<unsigned char>(i,j) = code;
- }
- }
- }
- void lbp_with_factor( Mat& _src, Mat& _dst, uchar factor) // factor default 3
- {
- if ( -_dst.empty())
- _dst.create(_src.rows, _src.cols, CV_8UC1);
- _dst = cv::Scalar::all(0);
- // calculate patterns
- for(int i=1;i<_src.rows-1;i++)
- {
- for(int j=1;j<_src.cols-1;j++)
- {
- uchar center = _src.at<uchar>(i,j)+factor;
- unsigned char code = 0;
- code |= (_src.at<uchar>(i-1,j-1) >= center) << 7;
- code |= (_src.at<uchar>(i-1,j) >= center) << 6;
- code |= (_src.at<uchar>(i-1,j+1) >= center) << 5;
- code |= (_src.at<uchar>(i,j+1) >= center) << 4;
- code |= (_src.at<uchar>(i+1,j+1) >= center) << 3;
- code |= (_src.at<uchar>(i+1,j) >= center) << 2;
- code |= (_src.at<uchar>(i+1,j-1) >= center) << 1;
- code |= (_src.at<uchar>(i,j-1) >= center) << 0;
- _dst.at<unsigned char>(i,j) = code;
- }
- }
- }
- // 这里需要采用2个字符来编码,如00、01、10、11
- void lbp_with_factor( Mat& _src, Mat& _dst, float factor) // facotr default 0.1
- {
- if ( -_dst.empty())
- _dst.create(_src.rows, _src.cols, CV_8UC1);
- _dst = cv::Scalar::all(0);
- // calculate patterns
- for(int i=1;i<_src.rows-1;i++)
- {
- for(int j=1;j<_src.cols-1;j++)
- {
- uchar center = _src.at<uchar>(i,j);
- int up = center*(1.0+factor);
- int down = center*(1.0+factor);
- unsigned char code = 0;
- /*code |= (_src.at<uchar>(i-1,j-1) >= center ) << 7;
- code |= (_src.at<uchar>(i-1,j) >= center) << 6;
- code |= (_src.at<uchar>(i-1,j+1) >= center) << 5;
- code |= (_src.at<uchar>(i,j+1) >= center) << 4;
- code |= (_src.at<uchar>(i+1,j+1) >= center) << 3;
- code |= (_src.at<uchar>(i+1,j) >= center) << 2;
- code |= (_src.at<uchar>(i+1,j-1) >= center) << 1;
- code |= (_src.at<uchar>(i,j-1) >= center) << 0;
- _dst.at<unsigned char>(i,j) = code;*/
- }
- }
- }