www.pudn.com > hbp0.1.zip > classTopmap.cpp


/* 
Rodney robot - Topological map 
Copyright (C) 2002  Bob Mottram 
 
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. 
 
This program is distributed in the hope that it will be useful, 
but WITHOUT ANY WARRANTY; without even the implied warranty of 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
GNU General Public License for more details. 
 
You should have received a copy of the GNU General Public License 
along with this program; if not, write to the Free Software 
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 
 
Comments are included in machine readable XML format, for possible future  
production of program documentation 
*/ 
 
//------------------------------------------------------------------------------------------------------------------------ 
//  Video for windows stuff 
//------------------------------------------------------------------------------------------------------------------------ 
 
//#include                                                        //CB 
//#pragma hdrstop                                                        //CB 
 
#include  
#include  
#include  
#include "classTopmap.h" 
 
//------------------------------------------------------------------------------------------------------------------------ 
//#pragma package(smart_init)                                            //CB 
 
 
///  
/// Initialise the map with the desired dimensions.  It is assumed that the input to the classifier will be a two  
/// dimensional image, but if you wish to have only one dimensional input just set InputsHeight to 1. 
///  
/// Width of the input image to be classified 
/// Height of the input image to be classified 
/// Width of the topological map 
/// Height of the topological map 
Ttopmap::Ttopmap(int inputsWidth, int inputsHeight, int mapWidth, int mapHeight) 
{ 
  int x,y,xx,yy,i; 
 
  max_hits=0; 
  inputs_width = inputsWidth; 
  inputs_height = inputsHeight; 
  inputs = new unsigned char *[inputs_width]; 
  for (x=0;x 
/// Destructor 
///  
Ttopmap::~Ttopmap() 
{ 
} 
 
 
///  
/// Random number generator 
///  
/// A random number in the range 0.0 - 1.0 
float Ttopmap::Rnd() 
{ 
  return(rand()/(float)RAND_MAX); 
} 
 
 
///  
/// Sets a colour to be assigned to the given class index.  At present this function is not used within the facememory program 
///  
/// Index number or personID for the classification 
/// Red component of the desired colour 
/// Green component of the desired colour 
/// Blue component of the desired colour 
void Ttopmap::setClassificationColour(int classificationID, int Red, int Green, int Blue) 
{ 
  ClassificationColour[classificationID][0] = Red; 
  ClassificationColour[classificationID][1] = Green; 
  ClassificationColour[classificationID][2] = Blue; 
} 
 
 
///  
/// Returns a colour for the given class index.  At present this function is not used within the facememory program 
///  
/// Index number or personID for the classification 
/// A long integer value corresponding to the colour 
/// The returned red component of the desired colour 
/// The returned green component of the desired colour 
/// The returned blue component of the desired colour 
void Ttopmap::getClassificationColour(int classificationID, int &Red, int &Green, int &Blue) 
{ 
  Red = ClassificationColour[classificationID][0]; 
  Green = ClassificationColour[classificationID][1]; 
  Blue = ClassificationColour[classificationID][2]; 
} 
 
 
///  
/// Sets the value of an input in the range 0.0 - 1.0 
///  
/// X coordinate of the input unit 
/// Y coordinate of the input unit 
/// Value to be assigned to the input 
void Ttopmap::setInput(int x, int y, unsigned char value) 
{ 
  inputs[x][y] = value; 
} 
 
 
///  
/// Returns the value of an output 
///  
/// X coordinate on the topological map 
/// Y coordinate on the topological map 
/// Value of the output at the given topological map coordinates 
float Ttopmap::getOutput(int x, int y) 
{ 
  return(outputs[x][y]); 
} 
 
 
///  
/// Returns a value indicating how similar the topological map unit is to the current inputs.  
/// Smaller values indicate greater similarity 
///  
/// X coordinate on the topological map 
/// Y coordinate on the topological map 
/// Similarity value 
float Ttopmap::similarity(int x, int y) 
{ 
  int xx,yy; 
  float value; 
  float dv; 
 
  value = 0; 
  for (xx=0;xx 
/// Re-scale the hit scores if they get too big.  This function is presently not used 
///  
void Ttopmap::rescaleHits() 
{ 
  int x,y; 
  long h; 
 
  for (x=0;x 
/// Main update routine for the topological map.  This should be called after  
/// all current inputs have been assigned using the setInput method 
///  
void Ttopmap::update() 
{ 
  int x,y,least_hits; 
  long n=0; 
  float value; 
  float min; 
 
  WinnerX = -1; 
  WinnerY = -1; 
  min = 9999; 
  average_similarity=0; 
  for (x = 0;x-1) 
  { 
    hits[WinnerX][WinnerY]++; 
	if (hits[WinnerX][WinnerY] > max_hits) 
	{ 
	  max_hits = hits[WinnerX][WinnerY]; 
	  if (max_hits > 32000) rescaleHits(); 
	} 
  } 
  else 
  { 
	 
    //find the least used unit 
	least_hits = max_hits+1; 
    for (x = 0;x max_hits) 
	{ 
	  max_hits = hits[WinnerX][WinnerY]; 
	  if (max_hits > 32000) rescaleHits(); 
	} 
	 
  } 
} 
 
 
///  
/// Returns the squared two dimensional distance between the given topological map coordinate and the winning unit 
///  
/// X coordinate on the topological map 
/// Y coordinate on the topological map 
/// Distance 
float Ttopmap::Dist(int x, int y) 
{ 
  return((float)(((x - WinnerX) * (x - WinnerX)) + ((y - WinnerY) * (y - WinnerY)))); 
} 
 
 
///  
/// Takes a value and adds a little random noise to it 
///  
/// The value to be made noisy 
/// A noisy value 
float Ttopmap::randVal(float value) 
{ 
  return(((1 - randomness) * value) + (randomness * Rnd())); 
} 
 
 
///  
/// Adjusts weights of the unit in accordance with its value 
///  
/// X coordinate on the topological map 
/// Y coordinate on the topological map 
void Ttopmap::adjustWeights(int x, int y, float value) 
{ 
  int xx,yy; 
  float dw; 
  float w; 
 
  if (classification[x][y]==0) //if the unit is unclassified then adjust its weights 
  { 
    for (xx = 0;xx 
/// Perform learning (weight adjustments) for all units on the topological map 
///  
void Ttopmap::learn() 
{ 
  int x; 
  int y,i; 
  float d; 
  float value; 
  float max; 
 
 
  //store the current input image on the winning unit 
  if (WinnerX>-1) 
  { 
 
    max = (float)(RadiusExcite * RadiusExcite); 
    for (x = (WinnerX - RadiusExcite);x<=(WinnerX + RadiusExcite);x++) 
	{ 
      for (y = (WinnerY - RadiusExcite);y<=(WinnerY + RadiusExcite);y++) 
	  { 
        if ((x >= 0) && (x < map_width) && (y >= 0) && (y < map_height)) 
		{ 
          d = Dist(x, y) / (2 * max); 
          if (d < 1) 
		  { 
            value = randVal(d); 
            adjustWeights(x, y, value); 
 
            if (!((x == WinnerX) && (y == WinnerY))) 
			{ 
              for (i=0;i<10;i++) 
                classificationMulti[x][y][i] = classificationMulti[x][y][i] + (int)((classificationMulti[WinnerX][WinnerY][i] - classificationMulti[x][y][i]) * (1 - d) * learningRate); 
			} 
 
		  } 
		} 
	  } 
	} 
 
    for (x=0;x 
/// Create some initial random weights in the given range 
///  
/// Minimum weight value 
/// Maximum weight value 
void Ttopmap::initWeights(float minVal, float maxVal) 
{ 
  int x,y,xx,yy; 
 
  for (x=0;x 
/// Greates a random input image, used for testing purposes 
///  
void Ttopmap::randomInputs() 
{ 
  int x,y; 
 
  for (x = 0;x 
/// Sets the classification (personID) for the current winning unit on the topological map 
///  
/// Classification index or personID 
void Ttopmap::setClassification(int classificationID) 
{ 
  if (WinnerX > -1) classification[WinnerX][WinnerY] = classificationID; 
} 
 
 
 
///  
/// Returns the classification index (or personID) of the given topological map unit 
///  
/// X coordinate on the topological map 
/// Y coordinate on the topological map 
/// Classification index or personID 
int Ttopmap::getClassification(int x, int y) 
{ 
  return(classification[x][y]); 
} 
 
 
 
///  
/// Returns the geographically nearest classification (or personID) for the given topological map coordinates 
///  
/// X coordinate on the topological map 
/// Y coordinate on the topological map 
/// Classification index or personID 
int Ttopmap::getNearestClassification(int x, int y) 
{ 
  int xx,yy,classID=0,dx,dy; 
  float dist,minDist; 
 
  if (x>-1) 
  { 
    classID = classification[x][y]; 
 
    //if this unit is unclassified then return the nearest classification on the map 
    if (classID==0) 
	{ 
	  minDist=9999; 
      for (xx=0;xx0) 
		  { 
            dx = xx - x; 
		    dy = yy - y; 
		    dist = (float)sqrt((dx*dx)+(dy*dy)); 
		    if (dist 
/// Classify the given image using the given classification index (or personID) 
///  
/// The classification index or personID to be assigned to the winning unit 
void Ttopmap::classify(int classificationID) 
{ 
  update(); 
  setClassification(classificationID); 
  learn(); 
} 
 
 
///  
/// Sets the multi-dimensional classification value of the winning unit 
///  
/// Classification index or personID 
/// Value to be assigned 
void Ttopmap::setClassificationMulti(int classificationIndex, int value) 
{ 
  if (WinnerX > -1) 
    classificationMulti[WinnerX][WinnerY][classificationIndex] = value; 
} 
 
 
///  
/// Returns the multi-dimensional classification of the given topological map unit 
///  
/// X coordinate on the topological map 
/// Y coordinate on the topological map 
/// Dimension index for the classification 
/// Classification index or personID 
int Ttopmap::getClassificationMulti(int x, int y, int classificationIndex) 
{ 
  return(classificationMulti[x][y][classificationIndex]); 
} 
 
///  
/// Save the topological map data 
///  
/// Filename for the data 
void Ttopmap::save(char *filename) 
{ 
  int x,y,xx,yy,i,j; 
  FILE *fp; 
  
  fp = fopen(filename, "w"); 
 
  if (fp != NULL) 
  { 
	//save dimensions of the image 
    fprintf(fp,"%d\n",map_width); 
    fprintf(fp,"%d\n",map_height); 
    fprintf(fp,"%d\n",inputs_width); 
    fprintf(fp,"%d\n",inputs_height); 
 
     for (x=0;x 
/// Load the topological map data 
///  
/// Filename for the data 
void Ttopmap::load(char *filename) 
{ 
  int x,y,xx,yy,i,j,v; 
  float n; 
  char c; 
  FILE *fp; 
  
  fp = fopen(filename, "r"); 
 
  if (fp != NULL) 
  { 
	//save dimensions of the image 
    fscanf(fp,"%d\n",&map_width); 
    fscanf(fp,"%d\n",&map_height); 
    fscanf(fp,"%d\n",&inputs_width); 
    fscanf(fp,"%d\n",&inputs_height); 
 
     max_hits=0; 
     for (x=0;xmax_hits) max_hits = v; 
 
         fscanf(fp,"%d\n",&v); 
         classification[x][y]=v; 
         for (i=0;i<10;i++) 
		 { 
           fscanf(fp,"%d\n",&v); 
		   classificationMulti[x][y][i]=v; 
		 } 
	   } 
	 } 
	  
     for (i=0;i<20;i++) 
	 { 
       for (j=0;j<20;j++) 
	   { 
		 fscanf(fp,"%d\n",&c); 
	     classificationName[i][j] = c; 
	   } 
	 } 
 
 
     for (i=0;i<20;i++) 
	 { 
       for (j=0;j<150;j++) 
	   { 
		 fscanf(fp,"%d\n",&c); 
	     portrait[i][j] = c; 
	   } 
	 } 
 
	fclose(fp); 
  } 
 
} 
 
 
///  
/// Returns the name for the given classification ID 
///  
/// Classification index or personID 
/// Name of the class or person 
void Ttopmap::getClassificationName(int classID, char *className) 
{ 
  int i; 
   
  for (i = 0;i<17;i++) 
    className[i] = classificationName[classID][i]; 
} 
 
 
///  
/// Sets a name for the given classification ID 
///  
/// Classification index or personID 
/// Name of the class (person name) 
void Ttopmap::setClassificationName(int classID, char *className) 
{ 
  int i; 
   
  for (i = 0;i<17;i++) 
    classificationName[classID][i] = className[i]; 
} 
 
 
///  
/// Returns a filename associated with the given class index.  In this case the class index  
/// is the same as the personID - just a unique number corresponding to a particular classification. 
///  
/// Index number for the classification 
/// Returned filename of the image 
void Ttopmap::getPortrait(int classID, char *filename) 
{ 
  int i; 
   
  for (i = 0;i<150;i++) 
    filename[i] = portrait[classID][i]; 
} 
 
 
///  
/// Stores a filename associated with the given class index.  In this case the class index  
/// is the same as the personID - just a unique number corresponding to a particular classification. 
///  
/// Index number for the classification 
/// An image filename associated with the classification 
void Ttopmap::setPortrait(int classID, char *filename) 
{ 
  int i; 
   
  for (i = 0;i<150;i++) 
    portrait[classID][i] = filename[i]; 
}