link: no
#define RESIZED_SAMPLE_X_SIZE 64
#define RESIZED_SAMPLE_Y_SIZE 128
#define CELL_SIZE 8
#define BLOCK_SIZE 2
#define ORIENTATION_NUM 9
#define FEAT_DIM (BLOCK_SIZE*BLOCK_SIZE*ORIENTATION_NUM)*(BLOCK_NUM_IN_X)*(BLOCK_NUM_IN_Y)
#define CELL_NUM_IN_X (RESIZED_SAMPLE_X_SIZE/CELL_SIZE)
#define CELL_NUM_IN_Y (RESIZED_SAMPLE_Y_SIZE/CELL_SIZE)
#define BLOCK_NUM_IN_X (CELL_NUM_IN_X-BLOCK_SIZE+1)
#define BLOCK_NUM_IN_Y (CELL_NUM_IN_Y-BLOCK_SIZE+1)
#define PI 3.14f
#define LN_E 1.0f
#define LUT_SIZE 511
float MAGNITUDE_LUT[LUT_SIZE][LUT_SIZE] = {0, };
int GRADIENT_LUT[LUT_SIZE][LUT_SIZE] = {0, };
float INTEGRAL_IMAGE[ORIENTATION_NUM][RESIZED_SAMPLE_Y_SIZE][RESIZED_SAMPLE_X_SIZE] = {0, };
float CELL_HISTOGRAM[CELL_NUM_IN_X][CELL_NUM_IN_Y][ORIENTATION_NUM] = {0, };
void ExtractIntegralHOGFeature(unsigned char *image, int imageWidth, int imageHeight)
{
int width = imageWidth;
int height = imageHeight;
assert(width == RESIZED_SAMPLE_X_SIZE);
assert(height == RESIZED_SAMPLE_Y_SIZE);
float HOG_FEATURE[FEAT_DIM] = {0, };
CreateGradientLUT();
InitIntegralImage();
CreateIntegralHOG(image, width, height);
GetIntegralHOGFeature(HOG_FEATURE, 0, 0, width, height);
}
void CreateGradientLUT()
{
memset(MAGNITUDE_LUT, 0, sizeof(MAGNITUDE_LUT));
memset(GRADIENT_LUT, 0, sizeof(GRADIENT_LUT));
register int i, j;
int x, y;
float gradient;
float degreeFactor = 180/PI;
for(j=0; j<LUT_SIZE; j++)
{
y = j-255;
for(i=0; i<LUT_SIZE; i++)
{
x = i-255;
MAGNITUDE_LUT[j][i] = sqrt((float)(x*x + y*y));
gradient = atan2((float)y, (float)x);
gradient = gradient*degreeFactor;
gradient -= 1.0;
if(gradient < 0.0)
{
gradient += 360.0f;
}
if(gradient > 180.0)
{
gradient = gradient-180.0f;
}
GRADIENT_LUT[j][i] = (int)gradient/20.0f;
}
}
}
void InitIntegralImage()
{
memset(INTEGRAL_IMAGE, 0, sizeof(INTEGRAL_IMAGE));
}
void CreateIntegralHOG(unsigned char *image, int width, int height)
{
register int x, y;
int xGradient, yGradient, gradient;
for(y=0; y<height; y++)
{
for(x=0; x<width; x++)
{
if(x == 0)
{
xGradient = image[y*width+x] - image[y*width+(x+1)];
}
else if(x == width-1)
{
xGradient = image[y*width+(x-1)] - image[y*width+x];
}
else
{
xGradient = image[y*width+(x-1)] - image[y*width+(x+1)];
}
if(y == 0)
{
yGradient = image[y*width+x] - image[(y+1)*width+x];
}
else if(y == height-1)
{
yGradient = image[(y-1)*width+x] - image[y*width+x];
}
else
{
yGradient = image[(y-1)*width+x] - image[(y+1)*width+x];
}
xGradient = xGradient+255;
yGradient = yGradient+255;
gradient = GRADIENT_LUT[yGradient][xGradient];
INTEGRAL_IMAGE[gradient][y][x] = MAGNITUDE_LUT[yGradient][xGradient];
}
}
ComputeIntegralImage(width, height);
}
void ComputeIntegralImage(int width, int height)
{
register int i, j, k;
for(k=0; k<ORIENTATION_NUM; k++)
{
for(j=1; j<height; j++)
{
for(i=0; i<width; i++)
{
INTEGRAL_IMAGE[k][j][i] = INTEGRAL_IMAGE[k][j-1][i] + INTEGRAL_IMAGE[k][j][i];
}
}
for(j=0; j<height; j++)
{
for(i=1; i<width; i++)
{
INTEGRAL_IMAGE[k][j][i] = INTEGRAL_IMAGE[k][j][i-1] + INTEGRAL_IMAGE[k][j][i];
}
}
}
}
void GetIntegralHOGFeature(float feature[], int x, int y, int sizeW, int sizeH)
{
memset(feature, 0, sizeof(feature));
memset(CELL_HISTOGRAM, 0, sizeof(CELL_HISTOGRAM));
register int p, q, k;
int x1, x2, y1, y2;
int iW = sizeW/CELL_NUM_IN_X;
int iH = sizeH/CELL_NUM_IN_Y;
for(q=0; q<CELL_NUM_IN_Y; q++)
{
y1 = y + iH * q;
y2 = y1 + iH - 1;
for(p=0; p<CELL_NUM_IN_X; p++)
{
x1 = x + iW * p;
x2 = x1 + iW - 1;
if(x1 == 0)
{
if(y1 == 0)
{
for(k=0; k<ORIENTATION_NUM; k++)
{
CELL_HISTOGRAM[p][q][k] = INTEGRAL_IMAGE[k][y2][x2];
}
}
else
{
for(k=0; k<ORIENTATION_NUM; k++)
{
CELL_HISTOGRAM[p][q][k] = INTEGRAL_IMAGE[k][y2][x2] - INTEGRAL_IMAGE[k][y1-1][x2];
}
}
}
else
{
if(y1 == 0)
{
for(k=0; k<ORIENTATION_NUM; k++)
{
CELL_HISTOGRAM[p][q][k] = INTEGRAL_IMAGE[k][y2][x2] - INTEGRAL_IMAGE[k][y2][x1-1];
}
}
else
{
for(k=0; k<ORIENTATION_NUM; k++)
{
CELL_HISTOGRAM[p][q][k] = (INTEGRAL_IMAGE[k][y1-1][x1-1] + INTEGRAL_IMAGE[k][y2][x2]) -
(INTEGRAL_IMAGE[k][y2][x1-1] + INTEGRAL_IMAGE[k][y1-1][x2]);
}
}
}
}
}
Normalize(feature);
}
void Normalize(float feature[])
{
register int i, j, p, q, k;
int c = 0;
float sumMagnitude = 0.0f;
float e = LN_E;
float divRegular;
for(q=0; q<BLOCK_NUM_IN_Y; q++)
{
for(p=0; p<BLOCK_NUM_IN_X; p++)
{
sumMagnitude = 0.0f;
for(j=0; j<BLOCK_SIZE; j++)
{
for(i=0; i<BLOCK_SIZE; i++)
{
for(k=0; k<ORIENTATION_NUM; k++)
{
sumMagnitude += CELL_HISTOGRAM[p+i][q+j][k] * CELL_HISTOGRAM[p+i][q+j][k];
}
}
}
divRegular = 1.0f/sqrt(sumMagnitude+e);
for(j=0; j<BLOCK_SIZE; j++)
{
for(i=0; i<BLOCK_SIZE; i++)
{
for(k=0; k<ORIENTATION_NUM; k++)
{
feature[c] = CELL_HISTOGRAM[p+i][q+j][k] * divRegular;
c++;
}
}
}
sumMagnitude = 0.0f;
}
}
}
'Image Processing > Feature Extraction' 카테고리의 다른 글
[논문 읽기/2004] A Linear-Time Component-Labeling Algorithm Using Contour Tracing Technique (0) | 2020.05.29 |
---|