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;x max_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]; }