#include <highgui.h>
#include <stdio.h>
#include <stdlib.h>
#include <cv.h>
#include<math.h>
class EdgeHistogram
{
public:
static const int BIN_COUNT = 80;
double **grey_level;
IplImage *image;
//double **this->grey_level;//灰度图像矩阵
EdgeHistogram(IplImage *image)
{//获得图像的基本信息
this->image = image;
double QuantTable[5][8] = {0.010867, 0.057915, 0.099526, 0.144849, 0.195573, 0.260504, 0.358031, 0.530128 ,0.012266, 0.069934, 0.125879, 0.182307, 0.243396, 0.314563, 0.411728, 0.564319,0.004193, 0.025852, 0.04686, 0.068519, 0.09328599999999999, 0.12349, 0.161505, 0.22896,0.004174, 0.025924, 0.046232, 0.067163, 0.089655, 0.115391, 0.151904, 0.217745,0.006778, 0.051667, 0.10865, 0.166257, 0.224226, 0.285691, 0.356375, 0.450972};
blockSize = -1;
Local_Edge_Histogram = new double[80];
for(int i = 0; i < 80; i ++)
Local_Edge_Histogram[i] = 0;
bins = new int[80];
for(int i = 0; i < 80; i ++)
bins[i] = 0;
this->treshold = 11;//阈值
num_block = 1100;
//IplImage *image = cvLoadImage(name,1);
/////////////////////////////////////////////////////////////////////////
//image = paramBufferedImage;//图像
width = image->width;//宽度
height = image->height;//长度
this->grey_level = new double*[width];
for(int i = 0; i < width; i ++)
this->grey_level[i] = new double[height];
init(image);
extractFeature();//提取特征
edgeHistogram = setEdgeHistogram(QuantTable);//边缘直方图
}
void init(IplImage *image)
{
for(int i = 0; i < (int)width; i++)
{
for(int j = 0; j < (int)height; j++)
{
int b = ((uchar *)(image->imageData+j*image->widthStep))[i*image->nChannels+0];
int g = ((uchar *)(image->imageData+j*image->widthStep))[i*image->nChannels+1];
int r = ((uchar *)(image->imageData+j*image->widthStep))[i*image->nChannels+2];
double d = (0.299 * r + 0.587 * g + 0.114 * b) / 256.0;
this->grey_level[i][j] = (int)(219.0 * d + 16.5);
}
//printf("\n");
}
}
void setThreshold()
{
this->treshold = 11;
}
int getThreshold()
{
return this->treshold;
}
void extractFeature()
{
int i, j;
int k = 0;
int *arrayOfInt = new int[16];
for (k = 0; k < 16; ++k)
arrayOfInt[k] = 0;
k = 0;
while (k <= height - getblockSize())
{
int l = 0;
while (l <= width - getblockSize())
{
i = (int)((l << 2) / width) + ((int)((k << 2) / height) << 2);// 高+长的比例 乘了4 到边缘部分可能会有小数
//printf("%d ",i);
arrayOfInt[i] += 1;
j = getEdgeFeature(l, k);//计算后得到特征属性
if(k == 4 && l == 6)
printf("%d ",j);
switch (j)//定义Local_Edge_Histogram
{
case 0:
break;
case 1:
this->Local_Edge_Histogram[(i * 5)] += 1.0;
break;
case 2:
this->Local_Edge_Histogram[(i * 5 + 1)] += 1.0;
break;
case 4:
this->Local_Edge_Histogram[(i * 5 + 2)] += 1.0;
break;
case 5:
this->Local_Edge_Histogram[(i * 5 + 3)] += 1.0;
break;
case 3:
this->Local_Edge_Histogram[(i * 5 + 4)] += 1.0;
}
l += getblockSize();
}
//printf("\n");
k += getblockSize();
}
//for(int i = 0; i < 80; i ++)
//{
// printf("%f ",Local_Edge_Histogram[i]);
// if(i+1%10 == 0)
// printf("\n");
//}
for (k = 0; k < 80; ++k)
Local_Edge_Histogram[k] /= arrayOfInt[(k / 5)];//每5个数值都是相同的
//for(int i = 0; i < 16; i ++)
//{
// printf("%d ",arrayOfInt[i]);
//}
delete[] arrayOfInt;
}
int *setEdgeHistogram(double QuantTable[][8])
{
//for(int i = 0; i < 5; i ++)
//{
// for(int j = 0; j < 8; j ++)
// {
// printf("%f ",QuantTable[i][j]);
// }
// printf("\n");
//}
//int *arrayOfInt = new int[80];
double d = 0.0;
//double *arrayOfDouble = this->Local_Edge_Histogram;//已经得到的边缘直方图信息
for (int i = 0; i < 80; ++i)
for (int j = 0; j < 8; ++j)
{
this->bins[i] = j;
//printf("arrayOfDouble[i] = %f",this->Local_Edge_Histogram[i]);
//printf("d = %f\n",d);
if (j < 7)
d = (QuantTable[(i % 5)][j] + QuantTable[(i % 5)][(j + 1)]) / 2.0;//QuantTable是定义好的二维double数组
else
d = 1.0;
if (this->Local_Edge_Histogram[i] <= d)
break;
}
/* for(int i = 0 ; i < 80; i ++)
{
printf("%d ",this->bins[i]);
if((i+1)%10 == 0)
printf("\n");
}*/
return this->bins;
}
/*static float calculateDistance(int *paramArrayOfInt1, int *paramArrayOfInt2)
{
if (paramArrayOfInt1 == null)
printf("Input edgeHistogram a is null!\n");
if (paramArrayOfInt2 == null)
printf("Input edgeHistogram b is null!\n");
float f = 0.0F;
int i = 0;
for (i = 0; i < paramArrayOfInt1.length; ++i)
f += Math.abs((float)QuantTable[(i % 5)][paramArrayOfInt1[i]] - (float)QuantTable[(i % 5)][paramArrayOfInt2[i]]);
for (i = 0; i <= 4; ++i)
f += 5.0F * Math.abs(paramArrayOfInt1[i] - paramArrayOfInt2[i]);
for (i = 5; i < 80; ++i)
f += Math.abs(paramArrayOfInt1[i] - paramArrayOfInt2[i]);
return f;
}*/
//void makeGreyLevel()
//{
// int i = 0, j = 0;
// this->grey_level = new double*[height];
// for(i = 0; i < height; i++)
//this->grey_level[i] = new double[width];
// for (i = 0; i < height; ++i)
// for (j = 0; j < width; ++j)
// this->grey_level[i][j] = getYfromRGB(i, j);//获得转化后的灰度图像矩阵
//}
void getStringRepresentation()
{
printf("edgehistogram:\n");
for(int i = 0; i < 80; i ++)
{
printf("%d ",this->edgeHistogram[i]);
if((i+1) %10 == 0)
printf("\n");
}
printf("\n");
//localStringBuilder.append(this->edgeHistogram[0]);
//for (int i = 1; i < this.edgeHistogram.length; ++i)
//{
// localStringBuilder.append(' ');
// localStringBuilder.append(this.edgeHistogram[i]);
//}
//return localStringBuilder.toString();
}
~EdgeHistogram()
{
for(int i=0;i<this->image->width;++i)
{
delete []this->grey_level[i];
this->grey_level[i]=NULL;
}
delete []this->grey_level;
this->grey_level=NULL;
delete []this->Local_Edge_Histogram;
this->Local_Edge_Histogram = NULL;
//delete []this->Local_Edge_Histogram;
delete []this->bins;
this->bins = NULL;
}
private:
int *bins;
int treshold;//阈值
double width;
double height;
int num_block;
static const int NoEdge = 0;
static const int vertical_edge = 1;
static const int horizontal_edge = 2;
static const int non_directional_edge = 3;
static const int diagonal_45_degree_edge = 4;
static const int diagonal_135_degree_edge = 5;
double *Local_Edge_Histogram;
int blockSize;//小块的边长 初始化为0
double getFirstBlockAVG(int paramInt1, int paramInt2)
{
double d1 = 0.0;
if (this->grey_level[paramInt1][paramInt2] != 0.0)//灰度图像中这个块起点的像素值
for (int i = 0; i <= (getblockSize() >> 1) - 1; ++i)
for (int j = 0; j <= (getblockSize() >> 1) - 1; ++j)
d1 += this->grey_level[(paramInt1 + i)][(paramInt2 + j)];
else
printf("Grey level not initialized.\n");
double d2 = getblockSize() * getblockSize();
double d3 = 4.0 / d2;
d1 *= d3;
return d1;
}
/*void setBinCounts(int *paramArrayOfInt)
throws Exception
{
for (int i = 0; i <= 79; ++i)
bins[i] = paramArrayOfInt[i];
}
*/
int getblockSize()
{
double d = 0;
if (blockSize < 0)
{
d = (int)sqrt(width * height / num_block);//分块后的小块边长
blockSize = (int)(((int)(d / 2.0)) * 2.0);//Math.floor取小数的整数部分,这里获得块的整数边长
if (blockSize == 0)//如果分块失败就取