LBP是一种描述图像局部纹理的特征算子,该算子具有旋转不变性与灰度不变性等显著优点。 以窗口中心像素为阈值,将其相邻8淋雨像素灰度与中心像素值比较,若周围像素值大于中心像素值,则该中心像素位置被标记为1,否则为0,通过计算得到的窗口中心像素点LBP码可以用来反映该窗口的区域纹理特征特征信息,经典LBP的数学表达式如下:
L
B
P
(
x
c
,
y
c
)
=
∑
n
=
0
n
−
1
2
n
ψ
(
i
n
−
i
c
)
LBP(x_c,y_c)=\sum_{n=0}^{n-1}2^n \psi(i_n-i_c)
LBP(xc,yc)=n=0∑n−12nψ(in−ic)
其中,
ψ
(
x
)
=
{
1
x
>
0
0
x
<
0
\psi(x)=\begin{cases}1&x>0\\0&x<0\end{cases}
ψ(x)={10x>0x<0,为了区分中心点等于还是大于邻域像素点,引入LBP+和LBP-因子。
圆形LBP的基本思想是将局部纹理分布作为当前像素灰度的联合概率分布,将正方形窗口扩展到任意圆形邻域,满足半径为R采样到N个像素点,对于非整数坐标像素,采用近邻域插值或双线性插值。
cv::Mat OLBP(cv::Mat srcImage)
{
const int nRows = srcImage.rows;
const int nCols = srcImage.cols;
cv::Mat resultMat(srcImage.size(), srcImage.type());
for (int y = 1; y < nCols - 1; y++)
{
for (int x = 1; x < nRows - 1; x++)
{
uchar neighbor[8] = { 0 };
neighbor[0] = srcImage.at<uchar>(x - 1, y - 1);
neighbor[1] = srcImage.at<uchar>(x , y - 1);
neighbor[2] = srcImage.at<uchar>(x + 1, y - 1);
neighbor[3] = srcImage.at<uchar>(x + 1, y );
neighbor[4] = srcImage.at<uchar>(x + 1, y + 1);
neighbor[5] = srcImage.at<uchar>(x, y + 1);
neighbor[6] = srcImage.at<uchar>(x - 1, y + 1);
neighbor[7] = srcImage.at<uchar>(x - 1, y);
uchar center = srcImage.at<uchar>(x, y);
uchar temp = 0;
for (int k = 0; k < 8; k++)
{
temp += (neighbor[k] >= center) * (1 << k);
}
resultMat.at<uchar>(x, y) = temp;
}
}
return resultMat;
}