#include "stdafx.h"
#include "texturefeature.h"
BOOL Clr2Gray(HXLBMPFILE *hbf, HXLBMPFILE *bf)
{
bf->imagew = hbf->imagew;
bf->imageh = hbf->imageh;
bf->iRGBnum = 1;
if (!bf->AllocateMem())
return FALSE;
if (hbf->iRGBnum != 3)
{
int total = hbf->imagew*hbf->imageh;
memmove(bf->pDataAt(0, 0), hbf->pDataAt(0, 0), total);
return TRUE;
}
float g;
int j, k;
for (j = 0; j < bf->imageh; j++)
for (k = 0; k < bf->imagew;k++)
{
g = (float)*(hbf->pDataAt(j, 0) + k)*0.229 +
(float)*(hbf->pDataAt(j, 1) + k)*0.587+
(float)*(hbf->pDataAt(j, 2) + k)*0.114;
*(bf->pDataAt(j) + k) = (BYTE)g;
}
return TRUE;
}
BOOL SmoothArray(HXLBMPFILE *imagedata, HXLBMPFILE *Smoothdata)
{
int i, j, t;
int height = imagedata->imageh;
int width = imagedata->imagew;
BYTE*s, *g, *gal, *gnl;
int jal, jnl;
for (i = 0; i < height; i++)
{
s = Smoothdata->pDataAt(i);
g = imagedata->pDataAt(i);
t = i - 1;
if (t < 0) t = height - 1;
gnl = imagedata->pDataAt(t);
t = t + 1;
if (t >= height) t = 0;
gal = imagedata->pDataAt(t);
for (j = 0; j < width; j++)
{
jnl = j - 1;
if (jnl < 0) jnl = width - 1;
jal = j + 1;
if (jal > width - 1) jal = 0;
*(s + j) = (BYTE)(int)(gnl[jnl] + gnl[j] + gnl[jal] + g[jnl] + g[j] + g[jal] + gal[jnl] + gal[j] + gal[jal]) / 9;
}
}
return 1;
}
BOOL GainMeanandVar(float** grayCoocurrData, Coocurrmeanandvar &meanandvar)
{
int i, j;
float temp1[16];
float temp2[16];
//遍历纵坐标
for (i = 0; i < 16; i++)
{
temp1[i] = 0.0f;
//遍历横坐标(列)
for (j = 0; j < 16; j++)
//第i行发生概率
temp1[i] += grayCoocurrData[i][j];
//计算均值
meanandvar.meanx += i*temp1[i];
}
//遍历列
for (i = 0; i < 16;i++)
{
temp2[i] = 0.0f;
//遍历行
for (j = 0; j < 16; j++)
//第i列发生的概率
temp2[i] += grayCoocurrData[j][i];
//计算第i列均值
meanandvar.meany += i*temp2[i];
}
//计算每一行和列的方差
for (i = 0; i < 16;i++)
{
meanandvar.varx += (float)((i - meanandvar.meanx)*(i - meanandvar.meanx)*temp1[i]);
meanandvar.vary += (float)((i - meanandvar.meany)*(i - meanandvar.meany)*temp2[i]);
}
//标准差
meanandvar.varx = (float)sqrt(meanandvar.varx);
meanandvar.vary = (float)sqrt(meanandvar.vary);
return 1;
}
BOOL GetGrayArray(HXLBMPFILE *hbf, float **pGrayCoocurrData)
{
HXLBMPFILE bmpf;
if (!Clr2Gray(hbf, &bmpf)) return FALSE;
int i, j;
for (i = 0; i < hbf->imageh; i++)
{
BYTE* p = bmpf.pDataAt(i);
for (j = 0; j < hbf->imagew; j++)
{
*(p + j) = (BYTE)((int)*(p + j) * 15 / 255);
}
}
//为平滑矩阵分配内存
HXLBMPFILE Smoothdata;
Smoothdata.imagew = bmpf.imagew;
Smoothdata.imageh = bmpf.imageh;
Smoothdata.iRGBnum = 1;
if (!Smoothdata.AllocateMem()) return FALSE;
//平滑滤波
if (!SmoothArray(&bmpf, &Smoothdata)) return FALSE;
//得到平滑矩阵
for (i = 0; i < hbf->imageh; i++)
for (j = 0; j < hbf->imagew; j++)
pGrayCoocurrData[bmpf.pDataAt(i)[j]][Smoothdata.pDataAt(i)[j]]++;
//归一化,消除图片大小影响
for (i = 0; i < 16; i++)
for (j = 0; j < 16; j++)
pGrayCoocurrData[i][j] = pGrayCoocurrData[i][j] / (hbf->imageh*hbf->imagew);
return 1;
}
BOOL GetGraCoocurrFea(HXLBMPFILE *hbf, float* pGraCooFeature)
{
//为平滑矩阵分配内存
int i, j;
float **GrayCoocurrData = new float*[16];
if (!GrayCoocurrData) return FALSE;
for (i = 0; i < 16; i++)
{
GrayCoocurrData[i] = new float[16];
if (GrayCoocurrData[i] == NULL)
{
for (j = 0; j < i; j++)
if (GrayCoocurrData[j]) delete[] GrayCoocurrData[j];
delete[]GrayCoocurrData;
return 1;
}
memset(GrayCoocurrData[i], 0, sizeof(float) * 16);
}
//得到平滑矩阵
if (!GetGrayArray(hbf, GrayCoocurrData))
{
for (i = 0; i < 16; i++)
if (GrayCoocurrData[i]) delete[] GrayCoocurrData[i];
if (GrayCoocurrData) delete[] GrayCoocurrData;
return false;
}
//为均值和方差赋初值
Coocurrmeanandvar meanandvar;
meanandvar.meanx = 0.0f;
meanandvar.meany = 0.0f;
meanandvar.varx = 0.0f;
meanandvar.vary = 0.0f;
//计算均值和方差
if (!GainMeanandVar(GrayCoocurrData, meanandvar))
return FALSE;
//计算特征值
for (i = 0; i < 16; i++)
for (j = 0; j < 16;j++)
{
//1.反差 2.熵 3.逆差距 4.灰度相关 5.能量 6.集群荫 7.集群突出
pGraCooFeature[0] += abs(i - j)*GrayCoocurrData[i][j];
if (GrayCoocurrData[i][j] != 0)
pGraCooFeature[1] -= (float)(GrayCoocurrData[i][j] * log(GrayCoocurrData[i][j]));
pGraCooFeature[2] += (float)GrayCoocurrData[i][j] / (1 + abs(i - j));
pGraCooFeature[3] += (i - meanandvar.meanx)*(j - meanandvar.meany)*GrayCoocurrData[i][j];
pGraCooFeature[4] += GrayCoocurrData[i][j] * GrayCoocurrData[i][j];
pGraCooFeature[5] += (float)pow((i - meanandvar.meanx) + (j - meanandvar.meany), 3)*GrayCoocurrData[i][j];
pGraCooFeature[6] += (float)pow((i - meanandvar.meanx) + (j - meanandvar.meany), 4)*GrayCoocurrData[i][j];
}
pGraCooFeature[3] /= meanandvar.varx*meanandvar.vary;
for (i = 0; i < 16; i++)
if (GrayCoocurrData[i]) delete[] GrayCoocurrData[i];
if (GrayCoocurrData) delete[] GrayCoocurrData;
return 1;
}
BOOL GetMeansAndVars(PathandFeature *RetrivaledBMP, PathandFeature *pDataLibrary, int ImageNum)
{
int i,j,k;
float sumFea[4][7];
float varsFea[4][7];
float meansFea[4][7];
memset(sumFea, 0, sizeof(float[4][7] ));
for (i = 0; i < ImageNum; i++)
{
for (k = 0; k < 4; k++)
for (j = 0; j < 7; j++)
{
sumFea[k][j] += pDataLibrary[i].GraCoocurrFea[k][j];
}
}
memset(meansFea, 0, sizeof(float[4][7]));
for (k = 0; k < 4; k++)
for (j = 0; j < 7; j++)
{
meansFea[k][j] = sumFea[k][j] / ImageNum;
}
memset(sumFea, 0, sizeof(float[4][7]));
for (i = 0; i < ImageNum; i++)
{
for (k = 0; k < 4; k++)
for (j = 0; j < 7; j++)
{
sumFea[k][j] += pow(pDataLibrary[i].GraCoocurrFea[k][j] - meansFea[k][j], 2);
}
}
memset(varsFea, 0, sizeof(float[4][7]));
for (k = 0; k < 4; k++)
for (j = 0; j < 7; j++)
{
varsFea[k][j] = sqrt(sumFea[k][j] / ImageNum);
}
for (k = 0; k < 4; k++)
for (j = 0; j < 7;j++)
{
RetrivaledBMP->GraCoocurrFea[k][j] = (RetrivaledBMP->GraCoocurrFea[k][j] - meansFea[k][j]) / (3 * varsFea[k][j]);
if (RetrivaledBMP->GraCoocurrFea[k][j]>1)
RetrivaledBMP->GraCoocurrFea[k][j] = 1;
if (RetrivaledBMP->GraCoocurrFea[k][j] < -1)
RetrivaledBMP->GraCoocurrFea[k][j] = -1;
//归一化到[0,1]
RetrivaledBMP->GraCoocurrFea[k][j] = (RetrivaledBMP->GraCoocurrFea[k][j] + 1) / 2;
}
for (i = 0; i < ImageNum; i++)
{
for (k = 0; k < 4; k++)
for (j = 0; j < 7; j++)
{
pDataLibrary[i].GraCoocurrFea[k][j] = (pDataLibrary[i].GraCoocurrFea[k][j] - meansFea[k][j]) / (3 * varsFea[k][j]);
if (pDataLibrary[i].GraCoocurrFea[k][j]>1)
pDataLibrary[i].GraCoocurrFea[k][j] = 1;
if (pDataLibrary[i].GraCoocurrFea[k][j]< -1)
pDataLibrary[i].GraCoocurrFea[k][j] = -1;
//归一化到[0,1]
pDataLibrary[i].GraCoocurrFea[k][j] = (pDataLibrary[i].GraCoocurrFea[k][j] + 1) / 2;
}
}
return 1;
}