www.pudn.com > facedetectDLL_expressions.zip > classimage.cpp
/***************************************************************************
classimage.cpp
Base class for all images
begin : Sat Nov 23 2002
copyright : (C) 2002 by Bob Mottram
email : fuzzgun@btinternet.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include
#include
#include
#include
#include "classimage.h"
//---------------------------------------------------------------------------------------------
// constructor
//---------------------------------------------------------------------------------------------
classimage::classimage()
{
initialised=0;
reductionFactor_x=1;
reductionFactor_y=1;
image=NULL;
width=0;
height=0;
rotationLookup=NULL;
}
//---------------------------------------------------------------------------------------------
// destructor
//---------------------------------------------------------------------------------------------
classimage::~classimage()
{
int x,y;
if (image!=NULL)
{
for (x=0;x 0) v2 = image[x - 1][y][0]; else v2 = 0;
tVal = abs(v1 - v2);
if (y > 0) v2 = image[x][y - 1][0]; else v2 = 0;
tVal += abs(v1 - v2);
textureVal += tVal;
p += image[x][y][0];
p2 += tVal;
if (y > 0)
{
Integral[x][y][0] = p + Integral[x][y - 1][0];
Integral[x][y][1] = p2 + Integral[x][y - 1][1];
}
else
{
Integral[x][y][0] = p;
Integral[x][y][1] = p2;
}
}
}
Texture = textureVal / (width * height);
}
//------------------------------------------------------------------------------------------------------------------------
// get the total pixel value for the given area
//------------------------------------------------------------------------------------------------------------------------
long classimage::getIntegral(int tx, int ty, int bx, int by, int index)
{
return(Integral[bx][by][index] + Integral[tx][ty][index] - (Integral[tx][by][index] + Integral[bx][ty][index]));
}
//------------------------------------------------------------------------------------------------------------------------
// detect different types of feature
//------------------------------------------------------------------------------------------------------------------------
long classimage::detectFeature(int x, int y, int wdth, int hght, int featureType)
{
long area[4];
long v=0;
switch(featureType)
{
case 0: //A
{
area[0] = getIntegral(x, y, x + wdth, y + hght + hght, 0);
area[1] = getIntegral(x + wdth, y, x + wdth + wdth, y + hght + hght, 0);
v = abs(area[0] - area[1]);
break;
}
case 1: //B
{
area[0] = getIntegral(x, y, x + wdth, y + hght, 0);
area[1] = getIntegral(x, y + hght, x + wdth, y + hght + hght, 0);
v = abs(area[0] - area[1]);
break;
}
case 2: //C
{
area[0] = getIntegral(x, y, x + wdth, y + hght, 0);
area[1] = getIntegral(x + wdth, y, x + wdth + wdth, y + hght, 0);
area[2] = getIntegral(x + wdth + wdth, y, x + wdth + wdth + wdth, y + hght, 0);
v = abs((area[1] * 2) - (area[0] + area[2]));
break;
}
case 3: //D
{
area[0] = getIntegral(x, y, x + wdth, y + hght, 0);
area[1] = getIntegral(x + wdth, y, x + wdth + wdth, y + hght, 0);
area[2] = getIntegral(x, y + hght, x + wdth, y + hght + hght, 0);
area[3] = getIntegral(x + wdth, y + hght, x + wdth + wdth, y + hght + hght, 0);
v = abs((area[1] + area[2]) - (area[0] + area[3]));
break;
}
case 4: //A
{
area[0] = getIntegral(x, y, x + wdth, y + hght + hght, 1);
area[1] = getIntegral(x + wdth, y, x + wdth + wdth, y + hght + hght, 1);
v = abs(area[0] - area[1]);
break;
}
case 5: //B
{
area[0] = getIntegral(x, y, x + wdth, y + hght, 1);
area[1] = getIntegral(x, y + hght, x + wdth, y + hght + hght, 1);
v = abs(area[0] - area[1]);
break;
}
case 6: //C
{
area[0] = getIntegral(x, y, x + wdth, y + hght, 1);
area[1] = getIntegral(x + wdth, y, x + wdth + wdth, y + hght, 1);
area[2] = getIntegral(x + wdth + wdth, y, x + wdth + wdth + wdth, y + hght, 1);
v = abs((area[1] * 2) - (area[0] + area[2]));
break;
}
case 7: //D
{
area[0] = getIntegral(x, y, x + wdth, y + hght, 1);
area[1] = getIntegral(x + wdth, y, x + wdth + wdth, y + hght, 1);
area[2] = getIntegral(x, y + hght, x + wdth, y + hght + hght, 1);
area[3] = getIntegral(x + wdth, y + hght, x + wdth + wdth, y + hght + hght, 1);
v = abs((area[1] + area[2]) - (area[0] + area[3]));
break;
}
case 8:
{
v = getIntegral(x, y, x + wdth + wdth, y + hght + hght, 0);
break;
}
case 9:
{
v = getIntegral(x, y, x + wdth + wdth, y + hght + hght, 1);
break;
}
}
return(v);
}
//------------------------------------------------------------------------------------------------------------------------
// sample the given image within the given bounding box
//------------------------------------------------------------------------------------------------------------------------
void classimage::sampleFromImage(classimage *example_img, int tx, int ty, int bx, int by)
{
int x,y,xx,yy,dx,dy,c;
dx = bx - tx;
dy = by - ty;
for (x = 0;ximage[xx][yy][c];
}
}
updateIntegralImage();
}
//------------------------------------------------------------------------------------------------------------------------
// get image from a bitmap
//------------------------------------------------------------------------------------------------------------------------
void classimage::updateFromBitmap(BYTE *bmp, int RGBformat, int wdth, int hght)
{
int x,y,xx,yy;
unsigned char r,g,b;
int p;
//create a new image array if necessary
if (width==0) createImage(wdth/reductionFactor_x,hght/reductionFactor_y);
//populate the image array from the bitmap
p=0;
for (y=0;ywidth-1) xx = width-1;
if (yy>height-1) yy = height-1;
r = image[xx][yy][0];
g = image[xx][yy][1];
b = image[xx][yy][2];
if (RGBformat==0) //pixels in RGB order
{
bmp[p] = (BYTE)r; p++;
bmp[p] = (BYTE)g; p++;
bmp[p] = (BYTE)b; p++;
}
else
{ //pixels in BGR order
bmp[p] = (BYTE)b; p++;
bmp[p] = (BYTE)g; p++;
bmp[p] = (BYTE)r; p++;
}
}
}
//test pattern
/*
int pixels = width*height;
int p2;
for (p=0;p100) p2=0;
}
*/
}
//------------------------------------------------------------------------------------------------------------------------
//random number generator
//------------------------------------------------------------------------------------------------------------------------
float classimage::Rnd()
{
return(rand()/(float)RAND_MAX);
}
//------------------------------------------------------------------------------------------------------------------------
// update from another image object
//------------------------------------------------------------------------------------------------------------------------
void classimage::updateFromImage(classimage *img)
{
int x,y,xx,yy,c;
if (!initialised)
{
createImage(img->width/reductionFactor_x,img->height/reductionFactor_y);
initialised=true;
}
xx=0;
for (x=0;xwidth;x+=reductionFactor_x)
{
yy=0;
for (y=0;yheight;y+=reductionFactor_y)
{
for (c=0;c<3;c++) image[xx][yy][c] = img->image[x][y][c];
yy++;
}
xx++;
}
updateIntegralImage();
}
//------------------------------------------------------------------------------------------------------------------------
//rotate the image
//------------------------------------------------------------------------------------------------------------------------
void classimage::Rotate90()
{
int x,y,c;
unsigned char temp;
for (x=0;x-1) && (x-1) && (ywidth/2;
cy = sourceImage->height/2;
for (x=0;xwidth;x++)
{
for (y=0;yheight;y++)
{
hyp = (float)sqrt(((x-cx)*(x-cx))+((y-cy)*(y-cy)));
if (hyp>0)
{
ang = (float)acos((y-cy)/hyp);
if (x-cx>0) ang = (float)((2*3.1415927)-ang);
xx = cx + (int)(hyp * sin(rot-ang));
yy = cy + (int)(hyp * cos(rot-ang));
}
else
{
xx=x;
yy=y;
}
if ((xx>=0) && (xx=0) && (yyimage[xx][yy][c];
}
}
}
//recalculate the integral image
updateIntegralImage();
}
}
//------------------------------------------------------------------------------------------------------------------------
//returns the 'centre of gravity' for the given region relative to the given colour
//------------------------------------------------------------------------------------------------------------------------
void classimage::CG(int tx, int ty, int bx, int by, unsigned char targ_r, unsigned char targ_g, unsigned char targ_b, int &cx, int &cy, int maxval)
{
int x,y,p[3],c;
long tot,tot_x,tot_y,dp;
tot = 1;
tot_x = 0;
tot_y = 0;
for (x=tx;xminrowhits)
{
totrowhits+=rowhits;
NoOfRows++;
}
}
totrowhits /= NoOfRows;
averageWidth = (((by-ty) - NoOfRows) + totrowhits)/2;
return((hits * 100) / pixels);
}