LBP纹理特征研究
网上代码研究:
//****************************
//人脸特征提取(图像的基于Uniform模式的LBP纹理图的空间增强直方图)
//LBP纹理图像采用(8,1)邻域,即以每个像素周边的8个像素作为周边像素
//pImg: 输入的图像
//****************************
CvMat* KRRFace::calcLBPH(IplImage *pImg)
{
int i, j;
IplImage* pLBP; //LBP纹理图像
int weight[] = {0, 2, 4, 8, 16, 32, 64, 128}; //八个周边像素的权值
int iBiStrLen = 8; //LBP编码的长度
if(pImg->width != 96 || pImg->height != 96)
{
AfxMessageBox("image width and iamge height must be 96!");
return 0;
}
if(pImg->nChannels != 1)
{
AfxMessageBox("The channels of images must be 1!");
return 0;
}
pLBP = cvCreateImage( cvSize(pImg->width, pImg->height), IPL_DEPTH_8U, 1);
//LBP图像像素灰度值清零
for(i=0; i<pLBP->height; i++)
{
for(j=0; j<pLBP->width; j++)
{
pLBP->imageData[i * pImg->widthStep + j] = 0;
// cvmSet(pLBP, i, j, 0);
}
}
//为每个像素计算LBP编码
int height = pImg->height;
int width = pImg->width;
for(i=0; i<height; i++)
{
for(j=0; j<width; j++)
{
if( getPixel(pImg, i, (j+1)%width) > getPixel(pImg, i, j) )
{
setPixel( pLBP, i, j, getPixel(pLBP, i, j) + weight[3] );
}
else
{
setPixel( pLBP, i, (j+1)%width, getPixel( pLBP, i, (j+1)%width ) + weight[7] );
}
if( getPixel( pImg, (i+1)%height, (j+1)%width ) > getPixel(pImg, i, j) )
{
setPixel( pLBP, i, j, getPixel(pLBP, i, j) + weight[4] );
}
else
{
setPixel( pLBP, (i+1)%height, (j+1)%width, getPixel(pLBP, (i+1)%height, (j+1)%width) + weight[0] );
}
if( getPixel( pImg, (i+1)%height, j ) > getPixel(pImg, i, j) )
{
setPixel( pLBP, i, j, getPixel(pLBP, i, j) + weight[5] );
}
else
{
setPixel( pLBP, (i+1)%height, j, getPixel(pLBP, (i+1)%height, j) + weight[1] );
}
if( getPixel( pImg, (i+1)%height, j==0 ? (width-1) : (j-1) ) > getPixel(pImg, i, j) )
{
setPixel( pLBP, i, j, getPixel( pLBP, i, j) + weight[6] );
}
else
{
setPixel( pLBP, (i+1)%height, j==0 ? (width-1) : (j-1), getPixel( pLBP, (i+1)%height, j==0 ? (width-1) : (j-1) ) + weight[2] );
}
}
}
int iBNum; //图像像素的LBP编码
CString strBNum; //图像LBP编码的字符串形式
bool bUnifPat; //是否为uniform模式
int iBitTransNum; //LBP编码中1,0(或者0,1)变换次数
int iUnifPat; //基于uniform模式的LBP编码
int k;
for(i=0; i<height; i++)
{
for(j=0; j<width; j++)
{
iUnifPat = 0;
iBitTransNum = 0;
iBNum = getPixel(pLBP, i, j);
strBNum.Format("%d", iBNum);
for(; strBNum.GetLength()<iBiStrLen; ) //把LBP值的字符串形式用0补全,长度为iBitStrLen==8
{
strBNum = "0" + strBNum;
}
if(strBNum.GetAt(0) != strBNum.GetAt(iBiStrLen-1)) //计算二值字符串中10(或01)变化的次数
{
iBitTransNum++;
}
if(strBNum.GetAt(0) == '1') //计算字符串中1的个数
{
iUnifPat++;
}
for(k=1; k<iBiStrLen; k++)
{
if( strBNum.GetAt(k) != strBNum.GetAt(k-1) ) //计算二值字符串中10(或01)变化的次数
{
iBitTransNum++;
}
if( strBNum.GetAt(k) == '1') //计算字符串中1的个数
{
iUnifPat++;
}
}
if(iBitTransNum > 2) //判断是否为uniform模式,当iBitTransNum大于2时为uniform模式
{
iUnifPat = iBiStrLen+1; //非uniform模式,赋值为iBiStrLen+1
}
CvScalar sc;
sc.val[0] = iUnifPat;
cvSet2D(pLBP, i, j, sc);
}
}
CvScalar scal;
CvMat *pLBPH = cvCreateMat(160, 1, CV_32FC1); //基于uniform模式的LBP图像的空间增强直方图
//空间增强直方图清零
for(i=0; i<160; i++)
{
cvmSet(pLBPH, i, 0, 0);
}
k=0;
int ii, jj;
//计算空间增强直方图
for(i=0; i<=72; i+=24)
{
for(j=0; j<=72; j+=24)
{
for(ii=0; ii<24; ii++)
{
for(jj=0; jj<24; jj++)
{
scal = cvGet2D(pLBP, i+ii, j+jj);
int temp = cvmGet(pLBPH, k+scal.val[0], 0);
cvmSet( pLBPH, k+scal.val[0], 0, temp+1);
}
}
k+=10;
}
}
cvReleaseImage(&pLBP);
return pLBPH;
}