[Search for users]
[Overall Top Noters]
[List of all Conferences]
[Download this site]
Title: | The New Neural Networks Conference |
|
Moderator: | LGP30::FLEISCHER |
|
Created: | Fri May 25 1990 |
Last Modified: | Sun May 04 1997 |
Last Successful Update: | Fri Jun 06 1997 |
Number of topics: | 82 |
Total number of notes: | 276 |
82.0. "Source code for Windows 95 Application, Neural networks for image recognition" by SUBSYS::POIRIER () Sun May 04 1997 18:36
This program only runs on Windows95 do to some of the keyboard interrupts
I am monitoring. To compile I used Microsoft Visual C++ v 4.1.
You need to include the video for Windows libraries in order to compile.
These are available from the MSDN site.
The header file follows this..
If anybody wants just the executable, E-Mail me at [email protected]
Questions or comments, I will gladly answer..
-Jamey
/* 1/28/97 JP Neural Net
Feedforward multilayer representation of a Neural Network which
uses supervised learning through back propagation.
Uses three layers, input - hidden - output.
The activation of a node is computed by:
1. For each incoming connection compute activion*weight.
2. Sum up all the values of step 1 to get total input.
3. Perform sigmoid function 1/1+exp(-x) on total input.
Training is done by repeatedly running a training set, taking the
resulting error function of the output nodes and adjusting the weights
backward through the net to get as close to the desired output as
possible. */
#include "ICU.H"
//Global variables
NET Net; //The network
double ITERATIONS; //Count number of epochs needed to train net.
/* FLAGWIN is a global window which when opened must be acknowledged
(closed) by the user before it will allow you to continue. */
HWND FLAGWIN;
char INPUTSTRING[10]; //Temp String to store user keyboard input as needed.
/* INIT flag which is set to true once a network has been set up
in memory and initialized. */
BOOLEAN NET_INIT=FALSE;
long NUM_INPUT; //Size of Input layer, how many nodes
long NUM_OUTPUT;
long NUM_HIDDEN;
long INPUT_SET; //Number of training sets..
double ACCEPTABLE_ERROR=0.00009;
float **DESIRED_OUTPUT; //[SET][DESIRED_NETWORK_ACTIVATION]
BOOLEAN AllocSpace()
/* Allocates space within the heap for the neural net and
associated weights. By using pointers can allow the
user to change the size of the network dynamically.
Returns true if network is set up correctly.
!!! WARNING: I am not checking all these calls to malloc !!! */
{
long i;
int set;
Net.input=(Unit **)malloc(sizeof(Unit *)*INPUT_SET);
Net.hidden=(Unit *)malloc(sizeof(Unit)*NUM_HIDDEN);
Net.output=(Unit *)malloc(sizeof(Unit)*NUM_OUTPUT);
Net.error=(double *)malloc(sizeof(double)*INPUT_SET);
Net.i2h=(double **)malloc(sizeof(double *)*NUM_INPUT);
Net.h2o=(double **)malloc(sizeof(double *)*NUM_HIDDEN);
DESIRED_OUTPUT=(float **)malloc(sizeof(float *)*INPUT_SET);
for (i=0; i<INPUT_SET; i++)
{
Net.input[i]=(Unit *)malloc(sizeof(Unit)*NUM_INPUT);
DESIRED_OUTPUT[i]=(float *)malloc(sizeof(float)*NUM_OUTPUT);
}
for (i=0; i<NUM_INPUT; i++)
{
Net.i2h[i]=(double *)malloc(sizeof(double)*NUM_HIDDEN);
if (Net.i2h[i]==NULL)
{
MessageBox(NULL,"Insufficient Memory","Allocate
Memory",MB_ICONSTOP);
FreeSpace();
PostQuitMessage(0); //Exit Program
}
}
for (i=0; i<NUM_HIDDEN; i++)
{
Net.h2o[i]=(double *)malloc(sizeof(double)*NUM_OUTPUT);
if (Net.h2o[i]==NULL)
{
MessageBox(NULL,"Insufficient Memory","Allocate
Memory",MB_ICONSTOP);
FreeSpace();
PostQuitMessage(0); //Exit Program
}
}
//Clear Input layer and set all desired outputs to zero initially.
for (set=0; set<INPUT_SET; set++)
{
for (i=0; i<NUM_INPUT; i++)
Net.input[set][i].activation=(float)0;
for (i=0; i<NUM_OUTPUT; i++)
DESIRED_OUTPUT[set][i]=(float)0;
}
//Clear Hidden Layer
for (i=0; i<NUM_HIDDEN; i++)
Net.hidden[i].activation=0;
//Finally, Clear Output Layer
for (i=0; i<NUM_OUTPUT; i++)
Net.output[i].activation=0;
return TRUE;
} //End of Alloc Space
void FreeSpace()
/* Frees up heap memory being used for the network. Note
that if it ran out of memory while trying to allocate space
then the first NULL parameter we hit should be as far as we need
to go since every other memory request after that point is also
NULL. */
{
long i;
if (Net.hidden==NULL)
return;
else
free(Net.hidden);
if (Net.output==NULL)
return;
else
free(Net.output);
if (Net.error==NULL)
return;
else
free(Net.error);
for (i=0; i<INPUT_SET; i++)
{
if (Net.input[i]==NULL)
return;
else
free(Net.input[i]);
if (DESIRED_OUTPUT[i]==NULL)
return;
else
free(DESIRED_OUTPUT[i]);
}
if (Net.input==NULL)
return;
else
free(Net.input);
if (DESIRED_OUTPUT==NULL)
return;
else
free(DESIRED_OUTPUT);
for (i=0; i<NUM_INPUT; i++)
if (Net.i2h[i]==NULL)
return;
else
free(Net.i2h[i]);
if (Net.i2h==NULL)
return;
else
free(Net.i2h);
for (i=0; i<NUM_HIDDEN; i++)
if (Net.h2o[i]==NULL)
return;
else
free(Net.h2o[i]);
if (Net.h2o==NULL)
return;
else
free(Net.h2o);
//Reset env params
NET_INIT=FALSE;
NUM_INPUT=0;
NUM_HIDDEN=0;
NUM_OUTPUT=0;
ACCEPTABLE_ERROR=0;
INPUT_SET=0;
} //End of FreeSpace
void SavNet(HWND hwnd)
/* This function will save a network's connection weights
in a file. These can be loaded later and you don't have
to re-train the network. */
{
FILE *file;
char filename[80]="";
OPENFILENAME ofn; // common dialog box structure
int i,j;
if (!NET_INIT)
{
MessageBox(hwnd,"Network Not Initialized!","Save Network",
MB_ICONHAND);
return;
}
//First get filename
// Initialize OPENFILENAME
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hInstance=NULL;
ofn.hwndOwner = hwnd;
ofn.lpstrFile = filename;
ofn.nMaxFile = sizeof(filename);
ofn.lpstrFilter = "All\0*.*\0Neural Network\0*.NET\0";
ofn.lpstrCustomFilter=NULL;
ofn.nFilterIndex = 2;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle="Save Neural Network";
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
// Display the Open dialog box.
if (GetSaveFileName(&ofn)!=TRUE)
{
MessageBox(hwnd,"Invalid Filename.","Save Network",MB_ICONWARNING);
return;
}
//Open file with write privs
if ((file=fopen(filename,"w"))==NULL)
{
MessageBox(hwnd,"Error: Unable to open file for write!","Save
Network",MB_ICONWARNING);
return;
}
//Write Environment to file
fprintf(file,"%d\n",NUM_INPUT);
fprintf(file,"%d\n",NUM_HIDDEN);
fprintf(file,"%d\n",NUM_OUTPUT);
fprintf(file,"%d\n",INPUT_SET);
fprintf(file,"%f\n",ACCEPTABLE_ERROR);
fprintf(file,"\n\n"); //Two Seperator lines in file
//Write weights to file..
for (i=0; i<NUM_INPUT; i++)
for (j=0; j<NUM_HIDDEN; j++)
fprintf(file,"%f\n",Net.i2h[i][j]);
fprintf(file,"\n\n"); //Two seperator lines in file..
for (i=0; i<NUM_HIDDEN; i++)
for (j=0; j<NUM_OUTPUT; j++)
fprintf(file,"%f\n",Net.h2o[i][j]);
if (fclose(file))
{
MessageBox(hwnd,"Unable to close file!","Save
Network",MB_ICONWARNING);
return;
}
MessageBox(hwnd,"Network successfully saved.","Save Network",MB_OK);
return;
} //End of SavNet
void ViewParams(HWND parent)
/* Allows the user to view the current environment
parameter settings. */
{
HWND child;
HDC hdc;
char temp[100],tempb[50];
char number[20];
//Check to make certain network has been initialized
if (!NET_INIT)
{
MessageBox(parent,"Network has not been initialized!",
"View Environment Parameters",MB_ICONSTOP);
return;
}
child=CreateWindow(
"ChildClass", //name of Window Class
"Current Environment Parameters", //You supply the title
WS_DLGFRAME, //window_style dialog box
CW_USEDEFAULT, //X coordinate - let Windows decide
CW_USEDEFAULT, //Y coordinate - let Windows decide
300, //Width
200, //Height
parent, //Handle to Parent window
NULL, //No menu
NULL, //handle of this instance of the program
NULL, //No additional arguments
);
//display the window
ShowWindow(child,1);
//display env params
hdc=GetDC(child);
//INPUT NODES
strcpy(temp,"NUM_INPUT nodes: ");
ltoa(NUM_INPUT,number,10); strcat(temp,number);
TextOut(hdc,1,1,temp,strlen(temp));
//HIDDEN NODES
strcpy(temp,"NUM_HIDDEN nodes: ");
ltoa(NUM_HIDDEN,number,10); strcat(temp,number);
TextOut(hdc,1,20,temp,strlen(temp));
//OUTPUT NODES
strcpy(temp,"NUM_OUTPUT nodes: ");
ltoa(NUM_OUTPUT,number,10); strcat(temp,number);
TextOut(hdc,1,40,temp,strlen(temp));
//INPUT SET
strcpy(temp,"Number of input sets: ");
ltoa(INPUT_SET,number,10); strcat(temp,number);
TextOut(hdc,1,60,temp,strlen(temp));
//ACCEPTABLE ERROR
ConvertFloat(tempb,ACCEPTABLE_ERROR,8);
strcpy(temp,"Acceptable Error: "); strcat(temp,tempb);
TextOut(hdc,1,80,temp,strlen(temp));
ReleaseDC(hdc,child);
}
void LoadNet(HWND hwnd)
/* Loads a network from a previously saved file. All we
are concerned with here are the weights i2h and h2o. */
{
FILE *file;
char filename[80]="";
OPENFILENAME ofn; // common dialog box structure
char line[100];
int i,j;
//First get filename
// Initialize OPENFILENAME
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hInstance=NULL;
ofn.hwndOwner = hwnd;
ofn.lpstrFile = filename;
ofn.nMaxFile = sizeof(filename);
ofn.lpstrFilter = "All\0*.*\0Neural Network\0*.NET\0";
ofn.lpstrCustomFilter=NULL;
ofn.nFilterIndex = 2;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle="Open Neural Network";
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
// Display the Open dialog box.
if (GetOpenFileName(&ofn)!=TRUE)
{
MessageBox(hwnd,"Invalid Filename.","Load Neural Net",MB_ICONWARNING);
return;
}
//Open file with read privs
if ((file=fopen(filename,"r"))==NULL)
{
MessageBox(hwnd,"Unable to open for read.","Load Neural
Net",MB_ICONWARNING);
return;
}
//If Network has been initialized clear it..
if (NET_INIT)
FreeSpace();
//Get Environment data from file
fgets(line,100,file); NUM_INPUT=atol(line);
fgets(line,100,file); NUM_HIDDEN=atol(line);
fgets(line,100,file); NUM_OUTPUT=atol(line);
fgets(line,100,file); INPUT_SET=atol(line);
fgets(line,100,file); ACCEPTABLE_ERROR=atof(line);
NET_INIT=AllocSpace();
if (!NET_INIT)
{
MessageBox(hwnd,"Network parameters incorrectly defined in input
file!",
"Load Network",MB_ICONSTOP);
fclose(file);
return;
}
//Skip two lines
fgets(line,100,file);
fgets(line,100,file);
//Load input to hidden..
for (i=0; i<NUM_INPUT; i++)
for (j=0; j<NUM_HIDDEN; j++)
{
if(feof(file))
{
MessageBox(hwnd,"Not enough input data for input to
hidden weights!","Load Neural Net",MB_ICONWARNING);
return;
}
fgets(line,100,file);
Net.i2h[i][j]=atof(line);
}
//Expect two blank lines between data sets..
fgets(line,100,file);
fgets(line,100,file);
//Ok now load hidden to output..
for (i=0; i<NUM_HIDDEN; i++)
for (j=0; j<NUM_OUTPUT; j++)
{
if(feof(file))
{
MessageBox(hwnd,"Not enough input data for hidden to
output weights!","Load Neural Net",MB_ICONWARNING);
fclose(file);
return;
}
fgets(line,100,file);
Net.h2o[i][j]=atof(line);
}
fclose(file);
strcpy(line,"Loaded "); strcat(line,filename);
strcat(line," Successfully.");
MessageBox(hwnd,line,"Load Neural Net",MB_OK);
return;
} //End of LoadNet
void LoadDSRD(HWND hwnd)
/* Loads desired activations for the output nodes from a file.
This is easier than setting them all manually when you have a lot
of input sets. */
{
FILE *file;
int count,set;
char filename[80];
char line[100];
OPENFILENAME ofn; // common dialog box structure
if (!NET_INIT)
{
MessageBox(hwnd,"Network Not Initialized!","Load Desired Activations",
MB_ICONHAND);
return;
}
//First get filename
// Initialize OPENFILENAME
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hInstance=NULL;
ofn.hwndOwner = hwnd;
ofn.lpstrFile = filename;
ofn.nMaxFile = sizeof(filename);
ofn.lpstrFilter = "All\0*.*\0Desired Data\0*.DAT\0";
ofn.lpstrCustomFilter=NULL;
ofn.nFilterIndex = 2;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle="Open Desired Activation File";
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
// Display the Open dialog box.
if (GetOpenFileName(&ofn)!=TRUE)
{
MessageBox(hwnd,"Invalid Filename.","Load Desired
Activations",MB_ICONWARNING);
return;
}
/* Starts filling at input set 0 and continues until
it has no more data. */
//Open the file, read only
if ((file=fopen(filename,"r"))==NULL)
{
MessageBox(hwnd,"Unable to open file for read!","Load Desired
Activations",MB_ICONHAND);
return;
}
set=0;
do
{
for (count=0; count<NUM_OUTPUT; count++)
{
if(feof(file))
{
MessageBox(hwnd,"End of Data Reached","Load Desired
Activations",MB_OK);
fclose(file);
return;
}
strcpy(line,"0.000000");
fgets(line,100,file);
DESIRED_OUTPUT[set][count]=(float)atof(line);
}
set++;
} while (set<INPUT_SET);
fclose(file);
strcpy(line,"Data loaded from: ");
strcat(line,filename);
MessageBox(hwnd,line,"Load Desired Activations",MB_OK);
return;
} //End of LoadDSRD
void NetInit(HWND hwnd)
/* Clears all the activation states of the units
and assigns random values from 0-1 for the connection
weights. */
{
int i,j;
MSG msg;
double NegPos;
/* If network has already been initialized then
free up memory before re-initializing. Size may change.. */
if (NET_INIT)
FreeSpace();
//Get Number of Input Nodes
ZeroMemory(INPUTSTRING,strlen(INPUTSTRING)); //Reset Input String
UserInput("Number of Input Nodes: ",300,100,hwnd);
while (FLAGWIN!=NULL)
{
GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg);
DispatchMessage(&msg); //return control to Windows
}
NUM_INPUT=atol(INPUTSTRING);
if (NUM_INPUT<1 | NUM_INPUT>19200)
{
MessageBox(hwnd,"Invalid number of input units!","Initialize
Network",MB_ICONHAND);
NET_INIT=FALSE;
return;
}
//Get Number of Hidden Nodes
ZeroMemory(INPUTSTRING,strlen(INPUTSTRING)); //Reset Input String
UserInput("Number of Hidden Nodes: ",300,100,hwnd);
while (FLAGWIN!=NULL)
{
GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg);
DispatchMessage(&msg); //return control to Windows
}
NUM_HIDDEN=atol(INPUTSTRING);
if (NUM_HIDDEN<1)
{
MessageBox(hwnd,"Invalid number of hidden units!","Initialize
Network",MB_ICONHAND);
NET_INIT=FALSE;
return;
}
//Get Number of Output Nodes
ZeroMemory(INPUTSTRING,strlen(INPUTSTRING)); //Reset Input String
UserInput("Number of Output Nodes: ",300,100,hwnd);
while (FLAGWIN!=NULL)
{
GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg);
DispatchMessage(&msg); //return control to Windows
}
NUM_OUTPUT=atol(INPUTSTRING);
if (NUM_OUTPUT<1)
{
MessageBox(hwnd,"Invalid number of output units!","Initialize
Network",MB_ICONHAND);
NET_INIT=FALSE;
return;
}
//Get Number of Input sets
ZeroMemory(INPUTSTRING,strlen(INPUTSTRING)); //Reset Input String
UserInput("Number of Input Sets: ",300,100,hwnd);
while (FLAGWIN!=NULL)
{
GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg);
DispatchMessage(&msg); //return control to Windows
}
INPUT_SET=atol(INPUTSTRING);
if (INPUT_SET<1)
{
MessageBox(hwnd,"Invalid number of input sets!","Initialize
Network",MB_ICONHAND);
NET_INIT=FALSE;
return;
}
//Get Acceptable error level
ZeroMemory(INPUTSTRING,strlen(INPUTSTRING)); //Reset Input String
UserInput("Acceptable Error Level: ",300,100,hwnd);
while (FLAGWIN!=NULL)
{
GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg);
DispatchMessage(&msg); //return control to Windows
}
ACCEPTABLE_ERROR=atof(INPUTSTRING);
if (INPUT_SET<0)
{
MessageBox(hwnd,"Invalid error level!","Initialize
Network",MB_ICONHAND);
NET_INIT=FALSE;
return;
}
//Allocate space for network
if (!(NET_INIT=AllocSpace()))
{
MessageBox(hwnd,"Unable to allocate space for network!","Initialize
Network",
MB_ICONHAND);
return;
}
srand( (unsigned)time( NULL ) ); //Seed off timer
//Assign Random weights for input to hidden connections
for (i=0; i<NUM_INPUT; i++)
for (j=0; j<NUM_HIDDEN; j++)
{
NegPos=RANDOM;
if (NegPos<0.5)
Net.i2h[i][j]=RANDOM*-1; //random 0 to -1
else
Net.i2h[i][j]=RANDOM; //random 0 to 1
}
//Clear Hidden Layer
for (i=0; i<NUM_HIDDEN; i++)
{
Net.hidden[i].activation=0;
//Assign Random weights for hidden to output connections
for (j=0; j<NUM_OUTPUT; j++)
{
NegPos=RANDOM;
if (NegPos<0.5)
Net.h2o[i][j]=RANDOM*-1;
else
Net.h2o[i][j]=RANDOM;
}
}
return;
} //end NetInit
void ViewInputActivations(HWND parent)
{
HWND win;
if (!NET_INIT)
{
MessageBox(parent,"Network not initialized!","View Input Activations",
MB_ICONSTOP);
return;
}
win=CreateWindow("InputClass","Input Layer Activations",WS_VSCROLL,
CW_USEDEFAULT,CW_USEDEFAULT,400,200,parent,NULL,NULL,NULL);
ShowWindow(win,1);
}
void ViewHiddenActivations(HWND parent)
{
HWND win;
if (!NET_INIT)
{
MessageBox(parent,"Network not initialized!","View Hidden
Activations",
MB_ICONSTOP);
return;
}
win=CreateWindow("HiddenClass","Hidden Layer Activations",WS_VSCROLL,
CW_USEDEFAULT,CW_USEDEFAULT,400,200,parent,NULL,NULL,NULL);
ShowWindow(win,1);
}
void ViewOutputActivations(HWND parent)
{
HWND win;
if (!NET_INIT)
{
MessageBox(parent,"Network not initialized!","View Output
Activations",
MB_ICONSTOP);
return;
}
win=CreateWindow("OutputClass","Output Layer Activations",WS_VSCROLL,
CW_USEDEFAULT,CW_USEDEFAULT,400,200,parent,NULL,NULL,NULL);
ShowWindow(win,1);
}
void ViewI2H(HWND parent)
{
HWND win;
if (!NET_INIT)
{
MessageBox(parent,"Network not initialized!","View Input to Hidden
Weights",
MB_ICONSTOP);
return;
}
win=CreateWindow("I2HClass","Input to Hidden Weights",WS_VSCROLL,
CW_USEDEFAULT,CW_USEDEFAULT,400,200,parent,NULL,NULL,NULL);
ShowWindow(win,1);
}
void ViewH2O(HWND parent)
{
HWND win;
if (!NET_INIT)
{
MessageBox(parent,"Network not initialized!","View Hidden to Output
Weights",
MB_ICONSTOP);
return;
}
win=CreateWindow("H2OClass","Hidden to Output Weights",WS_VSCROLL,
CW_USEDEFAULT,CW_USEDEFAULT,400,200,parent,NULL,NULL,NULL);
ShowWindow(win,1);
}
void ViewDesiredOutput(HWND parent)
{
HWND win;
if (!NET_INIT)
{
MessageBox(parent,"Network not initialized!","View Desired Output
Activations",
MB_ICONSTOP);
return;
}
win=CreateWindow("DesiredClass","Desired Output Activations",WS_VSCROLL,
CW_USEDEFAULT,CW_USEDEFAULT,500,200,parent,NULL,NULL,NULL);
ShowWindow(win,1);
}
void GetInput(HWND hwnd)
/* This will read incoming DATA from a file into
the input nodes. The first line in the input file should be
the input set you want to load data into. */
{
FILE *file;
int count,set;
int DataType;
char filename[80];
char line[100];
OPENFILENAME ofn; // common dialog box structure
if (!NET_INIT)
{
MessageBox(hwnd,"Network Not Initialized!","Load Input File",
MB_ICONHAND);
return;
}
//First get filename
// Initialize OPENFILENAME
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hInstance=NULL;
ofn.hwndOwner = hwnd;
ofn.lpstrFile = filename;
ofn.nMaxFile = sizeof(filename);
ofn.lpstrFilter = "All\0*.*\0Network Data\0*.DAT\0";
ofn.lpstrCustomFilter=NULL;
ofn.nFilterIndex = 2;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle="Open Network Data File";
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
// Display the Open dialog box.
if (GetOpenFileName(&ofn)!=TRUE)
{
MessageBox(hwnd,"Invalid Filename.","Load Data File",MB_ICONWARNING);
return;
}
//Open the file, read only
if ((file=fopen(filename,"r"))==NULL)
{
MessageBox(hwnd,"Unable to open file for read!","Load Data
File",MB_ICONHAND);
return;
}
//Do you want to load this as serial or optimized? 1=optimized 0=serial
DataType=MessageBox(hwnd,"Load optimized?","Load Data File",MB_YESNO);
/* The first line in the file should contain the input set you
want to begin loading the data into. From that point it will
continue to load data until it hits the end of file. */
fgets(line,100,file);
set=atoi(line);
if (set<0 | set>INPUT_SET)
{
MessageBox(hwnd,"Error: First line in file should contain number of
the input set to start loading into."
,"Load Data File",MB_ICONWARNING);
fclose(file);
return;
}
if (DataType!=IDYES) //then load Serial
do
{
for (count=0; count<NUM_INPUT; count++)
{
if(feof(file))
{
MessageBox(hwnd,"End of Data Reached","Load Data
File",MB_OK);
fclose(file);
return;
}
strcpy(line,"0.000000");
fgets(line,100,file);
Net.input[set][count].activation=atof(line);
}
set++;
} while (set<INPUT_SET);
else //optimized
{
do
{
if(feof(file))
{
MessageBox(hwnd,"End of Data Reached","Load
Data File",MB_OK);
fclose(file);
return;
}
ZeroMemory(&line[0],strlen(line));
fgets(line,50,file);
for (count=0; count<NUM_INPUT; count++)
Net.input[set][count].activation=line[count]-'0';
for (count=0; count<NUM_OUTPUT; count++)
{
if (line[count+NUM_INPUT+1]=='0')
DESIRED_OUTPUT[set][count]=(float)0.00;
else
DESIRED_OUTPUT[set][count]=(float)1.00;
}
set++;
} while (set<INPUT_SET);
} //End of else
fclose(file);
strcpy(line,"Data loaded from: ");
strcat(line,filename);
MessageBox(hwnd,line,"Load Data File",MB_OK);
return;
} //End of GetInput
void Epoch(HWND hwnd)
/* Computes output of network and adjusts using error function
until net is trained. */
{
int SetCount; //Counter to keep track of what input set we are on.
int total; //Total number of input sets which flag accetable error rates.
unsigned long keyval;
int i;
long *Flags=(long *)malloc(sizeof(long)*INPUT_SET);
/* If a particular input pattern has an acceptable output
error with these weights I will set this input patterns flag
to true. This allows me to know when all the input patterns
are trained. */
if (!NET_INIT)
{
MessageBox(hwnd,"Network Not Initialized!","Train Network",
MB_ICONHAND);
return;
}
MessageBox(hwnd,"Beginning Network Training!","Train Network",MB_OK);
ITERATIONS=0;
do
{
for (SetCount=0; SetCount<INPUT_SET; SetCount++)
{
//Monitor keyboard interrupt for keypress 'break'
keyval=_inp(0x60);
if (keyval==70) //on press of CTRL-BREAK abort training.
{
/* This is nice since you can stop the network at
any time and look to see how close it is, and restart
it training from where it left off. */
SetForegroundWindow(hwnd);
if (MessageBox(hwnd,"Abort Training???","Train
Network",
MB_YESNO)==IDYES)
return;
}
Compute(SetCount);
if (Good(SetCount))
{
/* This particular input pattern is within the
acceptable
error rate. */
Flags[SetCount]=1;
total=0;
for (i=0; i<INPUT_SET; i++)
if (Flags[i]==1) total+=1;
if (total==INPUT_SET)
{
SetForegroundWindow(hwnd);
MessageBox(hwnd,"Network successfully
Trained!","Train Network",MB_OK);
free(Flags);
return; //Network trained
}
}
else
{
BackProp(SetCount); //Adjust weights
ITERATIONS++;
Flags[SetCount]=0;
}
} //End of for SetCount
} while (1);
} //End of Epoch
int Good(int SetCount)
/* Computes overall network error, returns
1 if pattern is trained, else 0 */
{
int i;
/* Compute overall network error:
(sum(square(actual output of node i-desired output of node i)))/NUM_OUTPUT */
Net.error[SetCount]=0;
for (i=0; i<NUM_OUTPUT; i++)
Net.error[SetCount]=Net.error[SetCount]+(square((Net.output[i].activation-DESIRED_OUT
PUT[SetCount][i])));
Net.error[SetCount]=Net.error[SetCount]/NUM_OUTPUT; //Divide by the total
number of output units.
if (Net.error[SetCount]<=ACCEPTABLE_ERROR)
return 1;
else
return 0;
}
void BackProp(int SetCount)
/* Computes error value of output activation and adjusts
weights backward through the net. */
{
int i,j;
double *EAo=(double *)malloc(sizeof(double)*NUM_OUTPUT); //Output node
activation error
double *EAh=(double *)malloc(sizeof(double)*NUM_HIDDEN); //Hidden node
activation error
/* Compute EA for output nodes (difference between actual
and desired activation output) */
for (i=0; i<NUM_OUTPUT; i++)
EAo[i]=Net.output[i].activation-DESIRED_OUTPUT[SetCount][i];
//Compute EA for hidden nodes
for (i=0; i<NUM_HIDDEN; i++)
{
EAh[i]=0;
for (j=0; j<NUM_OUTPUT; j++)
EAh[i]+=(Net.h2o[i][j]*(Net.output[j].activation)*(1-Net.output[j].activation)*EAo[j]
);
}
//Adjust weights accordingly
for (i=0; i<NUM_HIDDEN; i++)
for (j=0; j<NUM_OUTPUT; j++)
Net.h2o[i][j]+=((-1)*Net.hidden[i].activation*Net.output[j].activation*(1-Net.output[
j].activation)*EAo[j]);
for (i=0; i<NUM_INPUT; i++)
for (j=0; j<NUM_HIDDEN; j++)
Net.i2h[i][j]+=((-1)*Net.input[SetCount][i].activation*Net.hidden[j].activation*(1-Ne
t.hidden[j].activation)*EAh[j]);
free(EAo);
free(EAh);
} //Yes! End of backprop.
void Compute(int SetCount)
/* Pushes input values through the net and gives output activiation */
{
int i,h,o;
//Sum up Input to Hidden inputs
for (h=0; h<NUM_HIDDEN; h++)
{
Net.hidden[h].input=0; //Reset total input
for (i=0; i<NUM_INPUT; i++)
Net.hidden[h].input+=(Net.input[SetCount][i].activation*Net.i2h[i][h]);
}
//Peform Sigmoid on total inputs of hidden layer
for (h=0; h<NUM_HIDDEN; h++)
Net.hidden[h].activation=SIGMOID(Net.hidden[h].input);
//Sum up Hidden to Output inputs
for (o=0; o<NUM_OUTPUT; o++)
{
Net.output[o].input=0; //Reset total input
for (h=0; h<NUM_HIDDEN; h++)
Net.output[o].input+=(Net.hidden[h].activation*Net.h2o[h][o]);
}
//Perform Sigmoid on total inputs of output layer
for (o=0; o<NUM_OUTPUT; o++)
Net.output[o].activation=SIGMOID(Net.output[o].input);
return;
} //End of Compute
void SetDOutput(HWND hwnd)
/* Allows the user to manually set the desired
output for a particular input pattern. */
{
MSG msg;
int i,set;
char line[100];
if (!NET_INIT)
{
MessageBox(hwnd,"Network Not Initialized","Set Desired Output
Activation",
MB_ICONHAND);
return;
}
//What input set to run..
INPUTSTRING[0]=0; set=-1; //Reset Input string and image set
UserInput("Enter INPUT SET",300,100,hwnd);
while (FLAGWIN!=NULL)
{
GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg);
DispatchMessage(&msg); //return control to Windows
}
set=atoi(INPUTSTRING);
if (strlen(INPUTSTRING)<1)
set=-1;
if (set<0 | set>INPUT_SET-1)
{
MessageBox(hwnd,"Invalid Input Set","Set Desired Output",MB_ICONHAND);
return;
}
for (i=0; i<NUM_OUTPUT; i++)
{
do
{
INPUTSTRING[0]=0; //Reset Input string
itoa(i, line, 10);
strcat(line," nodes output");
UserInput(line,300,100,hwnd);
while (FLAGWIN!=NULL)
{
GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg);
DispatchMessage(&msg); //return control to Windows
}
DESIRED_OUTPUT[set][i]=(float)atof(INPUTSTRING);
} while (DESIRED_OUTPUT[set][i]<0 | DESIRED_OUTPUT[set][i]>1);
}
MessageBox(hwnd,"Desired Output set.","Set Desired Output",MB_OK);
return;
}
int PASCAL WinMain(HANDLE hThisInst, HANDLE hPrevInst,
LPSTR lpszArgs, int nWinMode)
{
HWND hwnd;
MSG msg;
WNDCLASS wcl,kid,input,hidden,output,i2h,h2o,desired;
/* If this is the first instance of the program, then I need
to register several window classes for different window types. */
if (!hPrevInst) //Like school in the summertime, no CLASS
{
//Register a Main Window Class
wcl.hInstance=hThisInst; //handle to this instance
wcl.lpszClassName="MyWin"; //Window Class name
wcl.lpfnWndProc=WindowFunc; //Window function
wcl.style=CS_DBLCLKS; //Support double click of mouse
wcl.hIcon=LoadIcon(NULL,IDI_APPLICATION); //Icon style
wcl.hCursor=LoadCursor(NULL,IDC_ARROW); //Cursor style
wcl.lpszMenuName=NULL; //no Menu
wcl.cbClsExtra=0; //no extra
wcl.cbWndExtra=0; //Information needed
wcl.hbrBackground=GetStockObject(WHITE_BRUSH);
//Register Generic Child Class
kid.hInstance=hThisInst; //handle to this instance
kid.lpszClassName="ChildClass"; //Window Class name
kid.lpfnWndProc=ChildFunc; //Window function
kid.style=CS_NOCLOSE; //Disable close option.
kid.hIcon=LoadIcon(NULL,IDI_APPLICATION); //Icon style
kid.hCursor=LoadCursor(NULL,IDC_ARROW); //Cursor style
kid.lpszMenuName=NULL; //no Menu
kid.cbClsExtra=0; //no extra
kid.cbWndExtra=0; //Information needed
kid.hbrBackground=GetStockObject(WHITE_BRUSH);
//Register DisplayInputClass (supports scroll bars)
input.hInstance=hThisInst; //handle to this instance
input.lpszClassName="InputClass"; //Window Class name
input.lpfnWndProc=DisplayInputNodes; //Window function
input.style=CS_NOCLOSE; //Disable close option.
input.hIcon=LoadIcon(NULL,IDI_APPLICATION); //Icon style
input.hCursor=LoadCursor(NULL,IDC_ARROW); //Cursor style
input.lpszMenuName=NULL; //no Menu
input.cbClsExtra=0; //no extra
input.cbWndExtra=0; //Information needed
input.hbrBackground=GetStockObject(WHITE_BRUSH);
//Register DisplayHiddenClass
hidden.hInstance=hThisInst; //handle to this instance
hidden.lpszClassName="HiddenClass"; //Window Class name
hidden.lpfnWndProc=DisplayHiddenNodes; //Window function
hidden.style=CS_NOCLOSE; //Disable close option.
hidden.hIcon=LoadIcon(NULL,IDI_APPLICATION); //Icon style
hidden.hCursor=LoadCursor(NULL,IDC_ARROW); //Cursor style
hidden.lpszMenuName=NULL; //no Menu
hidden.cbClsExtra=0; //no extra
hidden.cbWndExtra=0; //Information needed
hidden.hbrBackground=GetStockObject(WHITE_BRUSH);
//Register DisplayOutputClass
output.hInstance=hThisInst; //handle to this instance
output.lpszClassName="OutputClass"; //Window Class name
output.lpfnWndProc=DisplayOutputNodes; //Window function
output.style=CS_NOCLOSE; //Disable close option.
output.hIcon=LoadIcon(NULL,IDI_APPLICATION); //Icon style
output.hCursor=LoadCursor(NULL,IDC_ARROW); //Cursor style
output.lpszMenuName=NULL; //no Menu
output.cbClsExtra=0; //no extra
output.cbWndExtra=0; //Information needed
output.hbrBackground=GetStockObject(WHITE_BRUSH);
//Register DisplayI2HClass
i2h.hInstance=hThisInst; //handle to this instance
i2h.lpszClassName="i2hClass"; //Window Class name
i2h.lpfnWndProc=DisplayI2H; //Window function
i2h.style=CS_NOCLOSE; //Disable close option.
i2h.hIcon=LoadIcon(NULL,IDI_APPLICATION); //Icon style
i2h.hCursor=LoadCursor(NULL,IDC_ARROW); //Cursor style
i2h.lpszMenuName=NULL; //no Menu
i2h.cbClsExtra=0; //no extra
i2h.cbWndExtra=0; //Information needed
i2h.hbrBackground=GetStockObject(WHITE_BRUSH);
//Register DisplayH2OClass
h2o.hInstance=hThisInst; //handle to this instance
h2o.lpszClassName="h2oClass"; //Window Class name
h2o.lpfnWndProc=DisplayH2O; //Window function
h2o.style=CS_NOCLOSE; //Disable close option.
h2o.hIcon=LoadIcon(NULL,IDI_APPLICATION); //Icon style
h2o.hCursor=LoadCursor(NULL,IDC_ARROW); //Cursor style
h2o.lpszMenuName=NULL; //no Menu
h2o.cbClsExtra=0; //no extra
h2o.cbWndExtra=0; //Information needed
h2o.hbrBackground=GetStockObject(WHITE_BRUSH);
//Register DisplayDesiredClass
desired.hInstance=hThisInst; //handle to this instance
desired.lpszClassName="DesiredClass"; //Window Class name
desired.lpfnWndProc=DisplayDesired; //Window function
desired.style=CS_NOCLOSE; //Disable close option.
desired.hIcon=LoadIcon(NULL,IDI_APPLICATION); //Icon style
desired.hCursor=LoadCursor(NULL,IDC_ARROW); //Cursor style
desired.lpszMenuName=NULL; //no Menu
desired.cbClsExtra=0; //no extra
desired.cbWndExtra=0; //Information needed
desired.hbrBackground=GetStockObject(WHITE_BRUSH);
if (!RegisterClass(&wcl)) return 0;
if (!RegisterClass(&kid)) return 0;
if (!RegisterClass(&input)) return 0;
if (!RegisterClass(&hidden)) return 0;
if (!RegisterClass(&output)) return 0;
if (!RegisterClass(&i2h)) return 0;
if (!RegisterClass(&h2o)) return 0;
if (!RegisterClass(&desired)) return 0;
}
/* Now that a window class has been registered, a Window can
be created. */
hwnd=CreateWindow(
"MyWin", //name of Window Class
"Neural Net - J.P. 97", //Title
WS_OVERLAPPEDWINDOW, //window_style normal
CW_USEDEFAULT, //X coordinate - let Windows decide
CW_USEDEFAULT, //Y coordinate - let Windows decide
350, //Width
350, //Height
NULL, //Parent window, there isn't one
NULL, //No menu
hThisInst, //handle of this instance of the program
NULL, //No additional arguments
);
//Now display the window
ShowWindow(hwnd,nWinMode);
//Display main Menu
Menu(hwnd);
//Create message loop
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg); //allow use of keyboard
DispatchMessage(&msg); //return control to Windows
}
return msg.wParam;
}
/* This function is called by Windows and is passed messages from the
message queue. */
LONG FAR PASCAL WindowFunc(HWND hwnd, unsigned int message,
unsigned int
wParam, LONG lParam)
{
int xcount,ycount;
switch (message)
{
case WM_CHAR: //Process keystroke
Beep(1,1);
break;
case WM_LBUTTONDBLCLK: //Process left mouse button
if (FLAGWIN)
//Cannot perform operation
Beep(1,20);
else
{
xcount=(int)LOWORD(lParam); //horizontal position of cursor
ycount=(int)HIWORD(lParam); //vertical position of cursor
ProcessSelection(xcount,ycount,hwnd);
}
break;
case WM_PAINT: //Redraw the screen
Menu(hwnd);
break;
case WM_DESTROY: //terminate program
PostQuitMessage(0);
break;
}
/* let Windows process any messages not specified in the
preceding switch statement. */
return DefWindowProc(hwnd,message,wParam,lParam);
}
void clrscr(HWND hwnd)
/* Clears the screen */
{
HDC hdc;
int i;
hdc=GetDC(hwnd);
//Clear the screen
for (i=0; i<400; i++)
TextOut(hdc,1,i,
" ",54);
ReleaseDC(hwnd,hdc);
}
void Menu(HWND hwnd)
/* This function draws the main menu on the screen. */
{
HDC hdc;
char Temp[50],Temp2[10];
hdc=GetDC(hwnd);
//Main Menu
TextOut(hdc,1,1 ,"Main Menu ",20);
TextOut(hdc,20,20 ,"Initialize Network ",20);
TextOut(hdc,20,40 ,"Load Input File ",20);
TextOut(hdc,20,60 ,"Train Network ",20);
TextOut(hdc,20,80 ,"Save Network ",20);
TextOut(hdc,20,100 ,"Load Network ",20);
TextOut(hdc,20,120 ,"Camera Viewpoint ",20);
TextOut(hdc,20,140 ,"Run Image ",20);
TextOut(hdc,20,160 ,"Set Desired Output ",20);
TextOut(hdc,20,180 ,"View ENV Params ",20);
TextOut(hdc,20,200 ,"Quit ",20);
TextOut(hdc,200,20 ,"View Dsrd Outputs ",20);
TextOut(hdc,200,40 ,"Input Activations ",20);
TextOut(hdc,200,60 ,"Hidden Activations ",20);
TextOut(hdc,200,80 ,"Output Activations ",20);
TextOut(hdc,200,100,"I2H Weights ",20);
TextOut(hdc,200,120,"H2O Weights ",20);
TextOut(hdc,200,140,"Recognize Image ",20);
TextOut(hdc,200,160,"Load DSRD from file ",20);
TextOut(hdc,200,180,"Run All input sets ",20);
//Display Time to Train
strcpy(Temp,"Training Revolutions: ");
strcpy(Temp2,"0.00000");
ltoa((long)ITERATIONS,Temp2,10);
strcat(Temp,Temp2);
TextOut(hdc,100,300,Temp,strlen(Temp));
ReleaseDC(hwnd,hdc);
} //End of Menu
void ProcessSelection(int xcount, int ycount, HWND hwnd)
/* This checks for a user selection from the main menu and
responds accordingly. */
{
HDC hdc;
MSG msg;
int i,set;
hdc=GetDC(hwnd);
//Clear the line where status remarks are being printed.
for (i=0; i<200; i++)
TextOut(hdc,i,280," ",1);
if (xcount>20 & xcount<150) //Left menu items
{
if (ycount>20 & ycount<40) //Initialize Network
{
TextOut(hdc,1,280,"Initializing Network...",23);
NetInit(hwnd);
TextOut(hdc,1,280,"Network Initialized. ",24);
ReleaseDC(hwnd,hdc);
return;
}
if (ycount>40 & ycount<60) //Load Input File
{
TextOut(hdc,1,280,"Load Input File",15);
GetInput(hwnd);
ReleaseDC(hwnd,hdc);
return;
}
if (ycount>60 & ycount<80) //Train Network
{
TextOut(hdc,1,280,"Training in Progress!!",22);
Epoch(hwnd);
TextOut(hdc,1,280,"Training Complete ",23);
ReleaseDC(hwnd,hdc);
return;
}
if (ycount>80 & ycount<100) //Save Network
{
TextOut(hdc,1,280,"Save Network",13);
SavNet(hwnd);
ReleaseDC(hwnd,hdc);
return;
}
if (ycount>100 & ycount<120) //Load Network
{
TextOut(hdc,1,280,"Load Network",12);
LoadNet(hwnd);
ReleaseDC(hwnd,hdc);
return;
}
if (ycount>120 & ycount<140) //Get single Camera Image
{
WhatISee(hwnd);
ReleaseDC(hwnd,hdc);
return;
}
if (ycount>140 & ycount<160) //Run Image
{
TextOut(hdc,1,280,"Run Image",9);
//Check if Network is initialized
if (!NET_INIT)
{
MessageBox(hwnd,"Network Not Initialized!","Run
Image",
MB_ICONHAND);
return;
}
//What input set to run..
INPUTSTRING[0]=0; set=-1; //Reset Input string and image set
UserInput("Enter Input Set to run",300,100,hwnd);
while (FLAGWIN!=NULL)
{
GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg);
DispatchMessage(&msg); //return control to Windows
}
set=atoi(INPUTSTRING);
if (strlen(INPUTSTRING)<1)
set=-1;
if (set<0 | set>INPUT_SET-1)
{
MessageBox(hwnd,"Invalid Input Set","Run
Image",MB_ICONHAND);
ReleaseDC(hwnd,hdc);
return;
}
Compute(set);
MessageBox(hwnd,"Image run, View Output Activations to see
results.","Run Image Set",MB_OK);
ReleaseDC(hwnd,hdc);
return;
} //end of Run Image
if (ycount>160 & ycount<180) //Set Desired Output
{
TextOut(hdc,1,280,"Set Desired Output",18);
SetDOutput(hwnd);
ReleaseDC(hwnd,hdc);
return;
}
if (ycount>180 & ycount<200) //View Env Params
{
TextOut(hdc,1,280,"View Environment Parameters",27);
ViewParams(hwnd);
ReleaseDC(hwnd,hdc);
return;
}
if (ycount>200 & ycount<220) //Quit
{
if (MessageBox(hwnd,"You wish to
quit?","Quit",MB_YESNO)==IDYES)
{
if (NET_INIT)
FreeSpace(); //Free up environment!
PostQuitMessage(0); //Exit Program
}
}
} //end of if (xcount>20 & xcount<150)
if (xcount<350 & xcount>150) //Right Menu Items
{
if (ycount>20 & ycount<40) //View Desired Output
{
TextOut(hdc,1,280,"View Desired Output",19);
ViewDesiredOutput(hwnd);
ReleaseDC(hwnd,hdc);
return;
}
if (ycount>40 & ycount<60) //View Input Activations
{
TextOut(hdc,1,280,"View Input Activations",22);
ViewInputActivations(hwnd);
ReleaseDC(hwnd,hdc);
return;
}
if (ycount>60 & ycount<80) //View Hidden Activations
{
TextOut(hdc,1,280,"View Hidden Activations",23);
ViewHiddenActivations(hwnd);
ReleaseDC(hwnd,hdc);
return;
}
if (ycount>80 & ycount<100) //View Output Activations
{
TextOut(hdc,1,280,"View Output Activations",23);
ViewOutputActivations(hwnd);
ReleaseDC(hwnd,hdc);
return;
}
if (ycount>100 & ycount<120) //View I2H Weights
{
TextOut(hdc,1,280,"View Input to Hidden",20);
ViewI2H(hwnd);
ReleaseDC(hwnd,hdc);
return;
}
if (ycount>120 & ycount<140) //View H2O Weights
{
TextOut(hdc,1,280,"View Hidden to Output",21);
ViewH2O(hwnd);
ReleaseDC(hwnd,hdc);
return;
}
if (ycount>140 & ycount<160) //Recognize Image
{
Capture(hwnd);
ReleaseDC(hwnd,hdc);
return;
}
if (ycount>160 & ycount<180) //Load desired output from file
{
TextOut(hdc,1,280,"Load Desired Output File",24);
LoadDSRD(hwnd);
ReleaseDC(hwnd,hdc);
return;
}
if (ycount>180 & ycount<200) //Run All input Sets
{
TextOut(hdc,1,280,"Run all input Sets",18);
RunAllSets(hwnd);
ReleaseDC(hwnd,hdc);
return;
}
} // end of if (xcount<350 & xcount>150)
ReleaseDC(hwnd,hdc);
} //End of ProcessSelection
void DisplayText(char title[50],char output[100],HWND parent,int priority)
/* This function will create a dialog box which will
display the output to the user. If priority is set to 1 then the
dialog must be CLOSED before the user can continue. */
{
HWND child;
HDC hdc;
switch (priority)
{
case 1:
FLAGWIN=CreateWindow(
"ChildClass", //name of Window Class
title, //You supply the title
WS_DLGFRAME, //window_style dialog box
CW_USEDEFAULT, //X coordinate - let Windows decide
CW_USEDEFAULT, //Y coordinate - let Windows decide
300, //Width
100, //Height
parent, //Handle to Parent window
NULL, //No menu
NULL, //handle of this instance of the program
NULL, //No additional arguments
);
//display the window
ShowWindow(FLAGWIN,1);
//display the message
hdc=GetDC(FLAGWIN);
SetTextColor(hdc,0x0000FF); //Red
TextOut(hdc,1,1,output,strlen(output));
ReleaseDC(hdc,child);
break;
default:
child=CreateWindow(
"ChildClass", //name of Window Class
title, //You supply the title
WS_DLGFRAME, //window_style dialog box
CW_USEDEFAULT, //X coordinate - let Windows decide
CW_USEDEFAULT, //Y coordinate - let Windows decide
300, //Width
100, //Height
parent, //Handle to Parent window
NULL, //No menu
NULL, //handle of this instance of the program
NULL, //No additional arguments
);
//display the window
ShowWindow(child,1);
//display the message
hdc=GetDC(child);
SetTextColor(hdc,0x0);
TextOut(hdc,1,1,output,strlen(output));
ReleaseDC(hdc,child);
break;
}
} //End of DisplayText
void UserInput(char *title,int width, int height,HWND parent)
{
HDC hdc;
FLAGWIN=CreateWindow(
"ChildClass", //name of Window Class
title, //You supply the title
WS_DLGFRAME, //edit style dialog box
CW_USEDEFAULT, //X coordinate - let Windows decide
CW_USEDEFAULT, //Y coordinate - let Windows decide
width, //Width
height, //Height
parent, //Handle to Parent window
NULL, //No menu
NULL, //handle of this instance of the program
NULL, //No additional arguments
);
//display the window
ShowWindow(FLAGWIN,1);
//display the message
hdc=GetDC(FLAGWIN);
TextOut(hdc,1,1," ",1);
ReleaseDC(hdc,FLAGWIN);
}
LONG FAR PASCAL ChildFunc(HWND child, unsigned int message,
unsigned int
wParam, LONG lParam)
/* This function handles incoming messages from the child window
class. */
{
HDC hdc;
switch (message)
{
case WM_LBUTTONDOWN:
//User presses mouse get rid of window
if (FLAGWIN==child)
FLAGWIN=NULL;
DestroyWindow(child);
break;
case WM_CHAR:
switch(wParam)
{
case 13: //return
if (FLAGWIN==child)
FLAGWIN=NULL;
DestroyWindow(child);
break;
default:
hdc=GetDC(child);
strcat(INPUTSTRING,(char *)&wParam);
TextOut(hdc,1,1,INPUTSTRING,strlen(INPUTSTRING));
ReleaseDC(hdc,child);
break;
} //End switch wParam
break;
}
/* let Windows process any messages not specified in the
preceding switch statement. */
return DefWindowProc(child,message,wParam,lParam);
} //End of ChildFunc
LONG FAR PASCAL DisplayInputNodes(HWND scroll, unsigned int message,
unsigned int wParam, LONG lParam)
/* Handles incoming messages for the scrolling window displaying
Input nodes and their activations. */
{
HDC hdc;
PAINTSTRUCT ps;
TEXTMETRIC tm;
SCROLLINFO si;
/* These variables are required to display text. */
static int xClient; /* width of client area */
static int yClient; /* height of client area */
static int xClientMax; /* maximum width of client area */
static int xChar; /* horizontal scrolling unit */
static int yChar; /* vertical scrolling unit */
static int xUpper; /* average width of uppercase letters */
static int xPos; /* current horizontal scrolling position */
static int yPos; /* current vertical scrolling position */
static int xMax; /* maximum horiz. scrolling position */
static int yMax; /* maximum vert. scrolling position */
int yInc; /* vertical scrolling increment */
long i; /* loop counter */
int x, y; /* horiz. and vert. printing coords */
long FirstLine; /* first line in the invalidated area */
long LastLine; /* last line in the invalidated area */
char tempa[100],tempb[20]; /* Used to parse output lines */
div_t div_result; /* Division result structure */
long SetCount; /* Keep track of what input set */
long NodeCount; /* Keep track of what node in the input set */
/* This is the number of maximum number of lines that need
to be displayed. */
long LINES=NUM_INPUT*INPUT_SET;
switch (message)
{
case WM_LBUTTONDOWN:
//User presses mouse get rid of window
DestroyWindow(scroll);
break;
case WM_CREATE :
/* Get the handle of the client area's device context. */
hdc = GetDC (scroll);
/* Extract font dimensions from the text metrics. */
GetTextMetrics (hdc, &tm);
xChar = tm.tmAveCharWidth;
xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2;
yChar = tm.tmHeight + tm.tmExternalLeading;
/* Free the device context. */
ReleaseDC (scroll, hdc);
/*
* Set an arbitrary maximum width for client area.
* (xClientMax is the sum of the widths of 48 average
* lowercase letters and 12 uppercase letters.)
*/
xClientMax = 48 * xChar + 12 * xUpper;
return 0;
case WM_SIZE:
/* Retrieve the dimensions of the client area. */
yClient = HIWORD (lParam);
xClient = LOWORD (lParam);
/*
* Determine the maximum vertical scrolling position.
* The two is added for extra space below the lines
* of text.
*/
yMax = max (0, LINES + 2 - yClient/yChar);
/*
* Make sure the current vertical scrolling position
* does not exceed the maximum.
*/
yPos = min (yPos, yMax);
/*
* Adjust the vertical scrolling range and scroll box
* position to reflect the new yMax and yPos values.
*/
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = 0;
si.nMax = yMax;
si.nPage = yClient / yChar;
si.nPos = yPos;
SetScrollInfo(scroll, SB_VERT, &si, TRUE);
/*
* Determine the maximum horizontal scrolling position.
* The two is added for extra space to the right of the
* lines of text.
*/
xMax = max (0, 2 + (xClientMax - xClient)/xChar);
/*
* Make sure the current horizontal scrolling position
* does not exceed the maximum.
*/
xPos = min (xPos, xMax);
/*
* Adjust the horizontal scrolling range and scroll box
* position to reflect the new xMax and xPos values.
*/
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = 0;
si.nMax = xMax;
si.nPage = xClient / xChar;
si.nPos = xPos;
SetScrollInfo(scroll, SB_HORZ, &si, TRUE);
return 0;
case WM_PAINT:
/* Prepare the window for painting. */
hdc = BeginPaint(scroll, &ps);
/*
* Use the current vertical scrolling position and
* coordinates of the invalid rectangle to determine
* the range of new lines that should be drawn in the
* client area.
*/
FirstLine = max (0, yPos + ps.rcPaint.top/yChar - 1);
LastLine = min (LINES, yPos + ps.rcPaint.bottom/yChar);
/* Display these lines. */
for (i = FirstLine;i < LastLine;i++)
{
div_result = div( i, NUM_INPUT);
SetCount=div_result.quot;
NodeCount=div_result.rem;
x = xChar * (1 - xPos);
y = yChar * (1 - yPos + i);
strcpy(tempa,"Input Set: "); ltoa(div_result.quot,tempb,10);
strcat(tempa,tempb);
strcat(tempa," Node: "); ltoa(NodeCount,tempb,10);
strcat(tempa,tempb);
strcat(tempa," Activation: ");
ConvertFloat(tempb,Net.input[SetCount][NodeCount].activation,8);
strcat(tempa,tempb);
//Clear line
TextOut(hdc,x,y,"
",52);
TextOut(hdc,x+50,y,"
",52);
TextOut(hdc, x, y, tempa, strlen(tempa));
}
/* Indicate that painting is finished. */
EndPaint(scroll, &ps);
break;
case WM_VSCROLL:
switch(LOWORD (wParam)) {
/* User clicked the shaft above the scroll box. */
case SB_PAGEUP:
yInc = min(-1, -yClient / yChar);
break;
/* User clicked the shaft below the scroll box. */
case SB_PAGEDOWN:
yInc = max(1, yClient / yChar);
break;
/* User clicked the top arrow. */
case SB_LINEUP:
yInc = -1;
break;
/* User clicked the bottom arrow. */
case SB_LINEDOWN:
yInc = 1;
break;
/* User dragged the scroll box. */
case SB_THUMBTRACK:
yInc = HIWORD(wParam) - yPos;
break;
default:
yInc = 0;
}
/*
* If applying the vertical scrolling increment does not
* take the scrolling position out of the scrolling range,
* increment the scrolling position, adjust the position
* of the scroll box, and update the window. UpdateWindow
* sends the WM_PAINT message.
*/
if (yInc = max(-yPos, min(yInc, yMax - yPos))) {
yPos += yInc;
ScrollWindowEx(scroll, 0, -yChar * yInc,
(CONST RECT *) NULL, (CONST RECT *) NULL,
(HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE);
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = yPos;
SetScrollInfo(scroll, SB_VERT, &si, TRUE);
UpdateWindow (scroll);
}
} //End of switch(message)
//Let Windows handle it..
return DefWindowProc(scroll,message,wParam,lParam);
} //End of DisplayInputNodes
LONG FAR PASCAL DisplayHiddenNodes(HWND scroll, unsigned int message,
unsigned int wParam, LONG lParam)
/* Handles incoming messages for the scrolling window displaying
Hidden nodes and their activations. */
{
HDC hdc;
PAINTSTRUCT ps;
TEXTMETRIC tm;
SCROLLINFO si;
/* These variables are required to display text. */
static int xClient; /* width of client area */
static int yClient; /* height of client area */
static int xClientMax; /* maximum width of client area */
static int xChar; /* horizontal scrolling unit */
static int yChar; /* vertical scrolling unit */
static int xUpper; /* average width of uppercase letters */
static int xPos; /* current horizontal scrolling position */
static int yPos; /* current vertical scrolling position */
static int xMax; /* maximum horiz. scrolling position */
static int yMax; /* maximum vert. scrolling position */
int yInc; /* vertical scrolling increment */
long i; /* loop counter */
int x, y; /* horiz. and vert. printing coords */
long FirstLine; /* first line in the invalidated area */
long LastLine; /* last line in the invalidated area */
char tempa[100],tempb[20]; /* Used to parse output lines */
/* This is the number of maximum number of lines that need
to be displayed. */
long LINES=NUM_HIDDEN;
switch (message)
{
case WM_LBUTTONDOWN:
//User presses mouse get rid of window
DestroyWindow(scroll);
break;
case WM_CREATE :
/* Get the handle of the client area's device context. */
hdc = GetDC (scroll);
/* Extract font dimensions from the text metrics. */
GetTextMetrics (hdc, &tm);
xChar = tm.tmAveCharWidth;
xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2;
yChar = tm.tmHeight + tm.tmExternalLeading;
/* Free the device context. */
ReleaseDC (scroll, hdc);
/*
* Set an arbitrary maximum width for client area.
* (xClientMax is the sum of the widths of 48 average
* lowercase letters and 12 uppercase letters.)
*/
xClientMax = 48 * xChar + 12 * xUpper;
return 0;
case WM_SIZE:
/* Retrieve the dimensions of the client area. */
yClient = HIWORD (lParam);
xClient = LOWORD (lParam);
/*
* Determine the maximum vertical scrolling position.
* The two is added for extra space below the lines
* of text.
*/
yMax = max (0, LINES + 2 - yClient/yChar);
/*
* Make sure the current vertical scrolling position
* does not exceed the maximum.
*/
yPos = min (yPos, yMax);
/*
* Adjust the vertical scrolling range and scroll box
* position to reflect the new yMax and yPos values.
*/
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = 0;
si.nMax = yMax;
si.nPage = yClient / yChar;
si.nPos = yPos;
SetScrollInfo(scroll, SB_VERT, &si, TRUE);
/*
* Determine the maximum horizontal scrolling position.
* The two is added for extra space to the right of the
* lines of text.
*/
xMax = max (0, 2 + (xClientMax - xClient)/xChar);
/*
* Make sure the current horizontal scrolling position
* does not exceed the maximum.
*/
xPos = min (xPos, xMax);
/*
* Adjust the horizontal scrolling range and scroll box
* position to reflect the new xMax and xPos values.
*/
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = 0;
si.nMax = xMax;
si.nPage = xClient / xChar;
si.nPos = xPos;
SetScrollInfo(scroll, SB_HORZ, &si, TRUE);
return 0;
case WM_PAINT:
/* Prepare the window for painting. */
hdc = BeginPaint(scroll, &ps);
/*
* Use the current vertical scrolling position and
* coordinates of the invalid rectangle to determine
* the range of new lines that should be drawn in the
* client area.
*/
FirstLine = max (0, yPos + ps.rcPaint.top/yChar - 1);
LastLine = min (LINES, yPos + ps.rcPaint.bottom/yChar);
/* Display these lines. */
for (i = FirstLine;i < LastLine;i++)
{
x = xChar * (1 - xPos);
y = yChar * (1 - yPos + i);
strcpy(tempa,"Hidden Node: "); ltoa(i,tempb,10);
strcat(tempa,tempb);
strcat(tempa," Activation: ");
ConvertFloat(tempb,Net.hidden[i].activation,8);
strcat(tempa,tempb);
//Clear line
TextOut(hdc,x,y,"
",52);
TextOut(hdc,x+50,y,"
",52);
TextOut(hdc, x, y, tempa, strlen(tempa));
}
/* Indicate that painting is finished. */
EndPaint(scroll, &ps);
break;
case WM_VSCROLL:
switch(LOWORD (wParam)) {
/* User clicked the shaft above the scroll box. */
case SB_PAGEUP:
yInc = min(-1, -yClient / yChar);
break;
/* User clicked the shaft below the scroll box. */
case SB_PAGEDOWN:
yInc = max(1, yClient / yChar);
break;
/* User clicked the top arrow. */
case SB_LINEUP:
yInc = -1;
break;
/* User clicked the bottom arrow. */
case SB_LINEDOWN:
yInc = 1;
break;
/* User dragged the scroll box. */
case SB_THUMBTRACK:
yInc = HIWORD(wParam) - yPos;
break;
default:
yInc = 0;
}
/*
* If applying the vertical scrolling increment does not
* take the scrolling position out of the scrolling range,
* increment the scrolling position, adjust the position
* of the scroll box, and update the window. UpdateWindow
* sends the WM_PAINT message.
*/
if (yInc = max(-yPos, min(yInc, yMax - yPos))) {
yPos += yInc;
ScrollWindowEx(scroll, 0, -yChar * yInc,
(CONST RECT *) NULL, (CONST RECT *) NULL,
(HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE);
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = yPos;
SetScrollInfo(scroll, SB_VERT, &si, TRUE);
UpdateWindow (scroll);
}
} //End of switch(message)
//Let Windows handle it..
return DefWindowProc(scroll,message,wParam,lParam);
} //End of DisplayHiddenNodes
LONG FAR PASCAL DisplayOutputNodes(HWND scroll, unsigned int message,
unsigned int wParam, LONG lParam)
/* Handles incoming messages for the scrolling window displaying
Output nodes and their activations. */
{
HDC hdc;
PAINTSTRUCT ps;
TEXTMETRIC tm;
SCROLLINFO si;
/* These variables are required to display text. */
static int xClient; /* width of client area */
static int yClient; /* height of client area */
static int xClientMax; /* maximum width of client area */
static int xChar; /* horizontal scrolling unit */
static int yChar; /* vertical scrolling unit */
static int xUpper; /* average width of uppercase letters */
static int xPos; /* current horizontal scrolling position */
static int yPos; /* current vertical scrolling position */
static int xMax; /* maximum horiz. scrolling position */
static int yMax; /* maximum vert. scrolling position */
int yInc; /* vertical scrolling increment */
long i; /* loop counter */
int x, y; /* horiz. and vert. printing coords */
long FirstLine; /* first line in the invalidated area */
long LastLine; /* last line in the invalidated area */
char tempa[100],tempb[20]; /* Used to parse output lines */
/* This is the number of maximum number of lines that need
to be displayed. */
long LINES=NUM_OUTPUT;
switch (message)
{
case WM_LBUTTONDOWN:
//User presses mouse get rid of window
DestroyWindow(scroll);
break;
case WM_CREATE :
/* Get the handle of the client area's device context. */
hdc = GetDC (scroll);
/* Extract font dimensions from the text metrics. */
GetTextMetrics (hdc, &tm);
xChar = tm.tmAveCharWidth;
xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2;
yChar = tm.tmHeight + tm.tmExternalLeading;
/* Free the device context. */
ReleaseDC (scroll, hdc);
/*
* Set an arbitrary maximum width for client area.
* (xClientMax is the sum of the widths of 48 average
* lowercase letters and 12 uppercase letters.)
*/
xClientMax = 48 * xChar + 12 * xUpper;
return 0;
case WM_SIZE:
/* Retrieve the dimensions of the client area. */
yClient = HIWORD (lParam);
xClient = LOWORD (lParam);
/*
* Determine the maximum vertical scrolling position.
* The two is added for extra space below the lines
* of text.
*/
yMax = max (0, LINES + 2 - yClient/yChar);
/*
* Make sure the current vertical scrolling position
* does not exceed the maximum.
*/
yPos = min (yPos, yMax);
/*
* Adjust the vertical scrolling range and scroll box
* position to reflect the new yMax and yPos values.
*/
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = 0;
si.nMax = yMax;
si.nPage = yClient / yChar;
si.nPos = yPos;
SetScrollInfo(scroll, SB_VERT, &si, TRUE);
/*
* Determine the maximum horizontal scrolling position.
* The two is added for extra space to the right of the
* lines of text.
*/
xMax = max (0, 2 + (xClientMax - xClient)/xChar);
/*
* Make sure the current horizontal scrolling position
* does not exceed the maximum.
*/
xPos = min (xPos, xMax);
/*
* Adjust the horizontal scrolling range and scroll box
* position to reflect the new xMax and xPos values.
*/
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = 0;
si.nMax = xMax;
si.nPage = xClient / xChar;
si.nPos = xPos;
SetScrollInfo(scroll, SB_HORZ, &si, TRUE);
return 0;
case WM_PAINT:
/* Prepare the window for painting. */
hdc = BeginPaint(scroll, &ps);
/*
* Use the current vertical scrolling position and
* coordinates of the invalid rectangle to determine
* the range of new lines that should be drawn in the
* client area.
*/
FirstLine = max (0, yPos + ps.rcPaint.top/yChar - 1);
LastLine = min (LINES, yPos + ps.rcPaint.bottom/yChar);
/* Display these lines. */
for (i = FirstLine;i < LastLine;i++)
{
x = xChar * (1 - xPos);
y = yChar * (1 - yPos + i);
strcpy(tempa,"Output Node : "); ltoa(i,tempb,10);
strcat(tempa,tempb);
strcat(tempa," Activation: ");
ConvertFloat(tempb,Net.output[i].activation,8);
strcat(tempa,tempb);
//Clear line
TextOut(hdc,x,y,"
",52);
TextOut(hdc,x+50,y,"
",52);
TextOut(hdc, x, y, tempa, strlen(tempa));
}
/* Indicate that painting is finished. */
EndPaint(scroll, &ps);
break;
case WM_VSCROLL:
switch(LOWORD (wParam)) {
/* User clicked the shaft above the scroll box. */
case SB_PAGEUP:
yInc = min(-1, -yClient / yChar);
break;
/* User clicked the shaft below the scroll box. */
case SB_PAGEDOWN:
yInc = max(1, yClient / yChar);
break;
/* User clicked the top arrow. */
case SB_LINEUP:
yInc = -1;
break;
/* User clicked the bottom arrow. */
case SB_LINEDOWN:
yInc = 1;
break;
/* User dragged the scroll box. */
case SB_THUMBTRACK:
yInc = HIWORD(wParam) - yPos;
break;
default:
yInc = 0;
}
/*
* If applying the vertical scrolling increment does not
* take the scrolling position out of the scrolling range,
* increment the scrolling position, adjust the position
* of the scroll box, and update the window. UpdateWindow
* sends the WM_PAINT message.
*/
if (yInc = max(-yPos, min(yInc, yMax - yPos))) {
yPos += yInc;
ScrollWindowEx(scroll, 0, -yChar * yInc,
(CONST RECT *) NULL, (CONST RECT *) NULL,
(HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE);
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = yPos;
SetScrollInfo(scroll, SB_VERT, &si, TRUE);
UpdateWindow (scroll);
}
} //End of switch(message)
//Let Windows handle it..
return DefWindowProc(scroll,message,wParam,lParam);
} //End of DisplayOutputNodes
LONG FAR PASCAL DisplayI2H(HWND scroll, unsigned int message,
unsigned int wParam, LONG lParam)
/* Handles incoming messages for the scrolling window displaying
Input to Hidden Weights. */
{
HDC hdc;
PAINTSTRUCT ps;
TEXTMETRIC tm;
SCROLLINFO si;
/* These variables are required to display text. */
static int xClient; /* width of client area */
static int yClient; /* height of client area */
static int xClientMax; /* maximum width of client area */
static int xChar; /* horizontal scrolling unit */
static int yChar; /* vertical scrolling unit */
static int xUpper; /* average width of uppercase letters */
static int xPos; /* current horizontal scrolling position */
static int yPos; /* current vertical scrolling position */
static int xMax; /* maximum horiz. scrolling position */
static int yMax; /* maximum vert. scrolling position */
int yInc; /* vertical scrolling increment */
long i; /* loop counter */
int x, y; /* horiz. and vert. printing coords */
long FirstLine; /* first line in the invalidated area */
long LastLine; /* last line in the invalidated area */
char tempa[100],tempb[20]; /* Used to parse output lines */
div_t div_result; /* Division result structure */
long InputCount;
long HiddenCount;
/* This is the number of maximum number of lines that need
to be displayed. */
long LINES=NUM_INPUT*NUM_HIDDEN;
switch (message)
{
case WM_LBUTTONDOWN:
//User presses mouse get rid of window
DestroyWindow(scroll);
break;
case WM_CREATE :
/* Get the handle of the client area's device context. */
hdc = GetDC (scroll);
/* Extract font dimensions from the text metrics. */
GetTextMetrics (hdc, &tm);
xChar = tm.tmAveCharWidth;
xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2;
yChar = tm.tmHeight + tm.tmExternalLeading;
/* Free the device context. */
ReleaseDC (scroll, hdc);
/*
* Set an arbitrary maximum width for client area.
* (xClientMax is the sum of the widths of 48 average
* lowercase letters and 12 uppercase letters.)
*/
xClientMax = 48 * xChar + 12 * xUpper;
return 0;
case WM_SIZE:
/* Retrieve the dimensions of the client area. */
yClient = HIWORD (lParam);
xClient = LOWORD (lParam);
/*
* Determine the maximum vertical scrolling position.
* The two is added for extra space below the lines
* of text.
*/
yMax = max (0, LINES + 2 - yClient/yChar);
/*
* Make sure the current vertical scrolling position
* does not exceed the maximum.
*/
yPos = min (yPos, yMax);
/*
* Adjust the vertical scrolling range and scroll box
* position to reflect the new yMax and yPos values.
*/
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = 0;
si.nMax = yMax;
si.nPage = yClient / yChar;
si.nPos = yPos;
SetScrollInfo(scroll, SB_VERT, &si, TRUE);
/*
* Determine the maximum horizontal scrolling position.
* The two is added for extra space to the right of the
* lines of text.
*/
xMax = max (0, 2 + (xClientMax - xClient)/xChar);
/*
* Make sure the current horizontal scrolling position
* does not exceed the maximum.
*/
xPos = min (xPos, xMax);
/*
* Adjust the horizontal scrolling range and scroll box
* position to reflect the new xMax and xPos values.
*/
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = 0;
si.nMax = xMax;
si.nPage = xClient / xChar;
si.nPos = xPos;
SetScrollInfo(scroll, SB_HORZ, &si, TRUE);
return 0;
case WM_PAINT:
/* Prepare the window for painting. */
hdc = BeginPaint(scroll, &ps);
/*
* Use the current vertical scrolling position and
* coordinates of the invalid rectangle to determine
* the range of new lines that should be drawn in the
* client area.
*/
FirstLine = max (0, yPos + ps.rcPaint.top/yChar - 1);
LastLine = min (LINES, yPos + ps.rcPaint.bottom/yChar);
/* Display these lines. */
for (i = FirstLine;i < LastLine;i++)
{
div_result = div( i, NUM_HIDDEN);
InputCount=div_result.quot;
HiddenCount=div_result.rem;
x = xChar * (1 - xPos);
y = yChar * (1 - yPos + i);
strcpy(tempa,"Input Node: "); ltoa(InputCount,tempb,10);
strcat(tempa,tempb);
strcat(tempa," Hidden Node: "); ltoa(HiddenCount,tempb,10);
strcat(tempa,tempb);
strcat(tempa," Weight: ");
ConvertFloat(tempb,Net.i2h[InputCount][HiddenCount],8);
strcat(tempa,tempb);
//Clear line
TextOut(hdc,x,y,"
",52);
TextOut(hdc,x+50,y,"
",52);
TextOut(hdc, x, y, tempa, strlen(tempa));
}
/* Indicate that painting is finished. */
EndPaint(scroll, &ps);
break;
case WM_VSCROLL:
switch(LOWORD (wParam)) {
/* User clicked the shaft above the scroll box. */
case SB_PAGEUP:
yInc = min(-1, -yClient / yChar);
break;
/* User clicked the shaft below the scroll box. */
case SB_PAGEDOWN:
yInc = max(1, yClient / yChar);
break;
/* User clicked the top arrow. */
case SB_LINEUP:
yInc = -1;
break;
/* User clicked the bottom arrow. */
case SB_LINEDOWN:
yInc = 1;
break;
/* User dragged the scroll box. */
case SB_THUMBTRACK:
yInc = HIWORD(wParam) - yPos;
break;
default:
yInc = 0;
}
/*
* If applying the vertical scrolling increment does not
* take the scrolling position out of the scrolling range,
* increment the scrolling position, adjust the position
* of the scroll box, and update the window. UpdateWindow
* sends the WM_PAINT message.
*/
if (yInc = max(-yPos, min(yInc, yMax - yPos))) {
yPos += yInc;
ScrollWindowEx(scroll, 0, -yChar * yInc,
(CONST RECT *) NULL, (CONST RECT *) NULL,
(HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE);
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = yPos;
SetScrollInfo(scroll, SB_VERT, &si, TRUE);
UpdateWindow (scroll);
}
} //End of switch(message)
//Let Windows handle it..
return DefWindowProc(scroll,message,wParam,lParam);
} //End of DisplayI2H
LONG FAR PASCAL DisplayH2O(HWND scroll, unsigned int message,
unsigned int wParam, LONG lParam)
/* Handles incoming messages for the scrolling window displaying
Hidden to Output Weights. */
{
HDC hdc;
PAINTSTRUCT ps;
TEXTMETRIC tm;
SCROLLINFO si;
/* These variables are required to display text. */
static int xClient; /* width of client area */
static int yClient; /* height of client area */
static int xClientMax; /* maximum width of client area */
static int xChar; /* horizontal scrolling unit */
static int yChar; /* vertical scrolling unit */
static int xUpper; /* average width of uppercase letters */
static int xPos; /* current horizontal scrolling position */
static int yPos; /* current vertical scrolling position */
static int xMax; /* maximum horiz. scrolling position */
static int yMax; /* maximum vert. scrolling position */
int yInc; /* vertical scrolling increment */
long i; /* loop counter */
int x, y; /* horiz. and vert. printing coords */
long FirstLine; /* first line in the invalidated area */
long LastLine; /* last line in the invalidated area */
char tempa[100],tempb[20]; /* Used to parse output lines */
div_t div_result; /* Division result structure */
long HiddenCount;
long OutputCount;
/* This is the number of maximum number of lines that need
to be displayed. */
long LINES=NUM_HIDDEN*NUM_OUTPUT;
switch (message)
{
case WM_LBUTTONDOWN:
//User presses mouse get rid of window
DestroyWindow(scroll);
break;
case WM_CREATE :
/* Get the handle of the client area's device context. */
hdc = GetDC (scroll);
/* Extract font dimensions from the text metrics. */
GetTextMetrics (hdc, &tm);
xChar = tm.tmAveCharWidth;
xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2;
yChar = tm.tmHeight + tm.tmExternalLeading;
/* Free the device context. */
ReleaseDC (scroll, hdc);
/*
* Set an arbitrary maximum width for client area.
* (xClientMax is the sum of the widths of 48 average
* lowercase letters and 12 uppercase letters.)
*/
xClientMax = 48 * xChar + 12 * xUpper;
return 0;
case WM_SIZE:
/* Retrieve the dimensions of the client area. */
yClient = HIWORD (lParam);
xClient = LOWORD (lParam);
/*
* Determine the maximum vertical scrolling position.
* The two is added for extra space below the lines
* of text.
*/
yMax = max (0, LINES + 2 - yClient/yChar);
/*
* Make sure the current vertical scrolling position
* does not exceed the maximum.
*/
yPos = min (yPos, yMax);
/*
* Adjust the vertical scrolling range and scroll box
* position to reflect the new yMax and yPos values.
*/
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = 0;
si.nMax = yMax;
si.nPage = yClient / yChar;
si.nPos = yPos;
SetScrollInfo(scroll, SB_VERT, &si, TRUE);
/*
* Determine the maximum horizontal scrolling position.
* The two is added for extra space to the right of the
* lines of text.
*/
xMax = max (0, 2 + (xClientMax - xClient)/xChar);
/*
* Make sure the current horizontal scrolling position
* does not exceed the maximum.
*/
xPos = min (xPos, xMax);
/*
* Adjust the horizontal scrolling range and scroll box
* position to reflect the new xMax and xPos values.
*/
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = 0;
si.nMax = xMax;
si.nPage = xClient / xChar;
si.nPos = xPos;
SetScrollInfo(scroll, SB_HORZ, &si, TRUE);
return 0;
case WM_PAINT:
/* Prepare the window for painting. */
hdc = BeginPaint(scroll, &ps);
/*
* Use the current vertical scrolling position and
* coordinates of the invalid rectangle to determine
* the range of new lines that should be drawn in the
* client area.
*/
FirstLine = max (0, yPos + ps.rcPaint.top/yChar - 1);
LastLine = min (LINES, yPos + ps.rcPaint.bottom/yChar);
/* Display these lines. */
for (i = FirstLine;i < LastLine;i++)
{
div_result = div( i, NUM_OUTPUT);
HiddenCount=div_result.quot;
OutputCount=div_result.rem;
x = xChar * (1 - xPos);
y = yChar * (1 - yPos + i);
strcpy(tempa,"Hidden Node: "); ltoa(HiddenCount,tempb,10);
strcat(tempa,tempb);
strcat(tempa," Output Node: "); ltoa(OutputCount,tempb,10);
strcat(tempa,tempb);
strcat(tempa," Weight: ");
ConvertFloat(tempb,Net.h2o[HiddenCount][OutputCount],8);
strcat(tempa,tempb);
//Clear line
TextOut(hdc,x,y,"
",52);
TextOut(hdc,x+50,y,"
",52);
TextOut(hdc, x, y, tempa, strlen(tempa));
}
/* Indicate that painting is finished. */
EndPaint(scroll, &ps);
break;
case WM_VSCROLL:
switch(LOWORD (wParam)) {
/* User clicked the shaft above the scroll box. */
case SB_PAGEUP:
yInc = min(-1, -yClient / yChar);
break;
/* User clicked the shaft below the scroll box. */
case SB_PAGEDOWN:
yInc = max(1, yClient / yChar);
break;
/* User clicked the top arrow. */
case SB_LINEUP:
yInc = -1;
break;
/* User clicked the bottom arrow. */
case SB_LINEDOWN:
yInc = 1;
break;
/* User dragged the scroll box. */
case SB_THUMBTRACK:
yInc = HIWORD(wParam) - yPos;
break;
default:
yInc = 0;
}
/*
* If applying the vertical scrolling increment does not
* take the scrolling position out of the scrolling range,
* increment the scrolling position, adjust the position
* of the scroll box, and update the window. UpdateWindow
* sends the WM_PAINT message.
*/
if (yInc = max(-yPos, min(yInc, yMax - yPos))) {
yPos += yInc;
ScrollWindowEx(scroll, 0, -yChar * yInc,
(CONST RECT *) NULL, (CONST RECT *) NULL,
(HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE);
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = yPos;
SetScrollInfo(scroll, SB_VERT, &si, TRUE);
UpdateWindow (scroll);
}
} //End of switch(message)
//Let Windows handle it..
return DefWindowProc(scroll,message,wParam,lParam);
} //End of DisplayH2O
LONG FAR PASCAL DisplayDesired(HWND scroll, unsigned int message,
unsigned int wParam, LONG lParam)
/* Handles incoming messages for the scrolling window displaying
desired output of the network. */
{
HDC hdc;
PAINTSTRUCT ps;
TEXTMETRIC tm;
SCROLLINFO si;
/* These variables are required to display text. */
static int xClient; /* width of client area */
static int yClient; /* height of client area */
static int xClientMax; /* maximum width of client area */
static int xChar; /* horizontal scrolling unit */
static int yChar; /* vertical scrolling unit */
static int xUpper; /* average width of uppercase letters */
static int xPos; /* current horizontal scrolling position */
static int yPos; /* current vertical scrolling position */
static int xMax; /* maximum horiz. scrolling position */
static int yMax; /* maximum vert. scrolling position */
int yInc; /* vertical scrolling increment */
long i; /* loop counter */
int x, y; /* horiz. and vert. printing coords */
long FirstLine; /* first line in the invalidated area */
long LastLine; /* last line in the invalidated area */
char tempa[100],tempb[20]; /* Used to parse output lines */
div_t div_result; /* Division result structure */
long SetCount; /* Keep track of what input set */
long NodeCount; /* Keep track of what node in the input set */
/* This is the number of maximum number of lines that need
to be displayed. */
long LINES=NUM_OUTPUT*INPUT_SET;
switch (message)
{
case WM_LBUTTONDOWN:
//User presses mouse get rid of window
DestroyWindow(scroll);
break;
case WM_CREATE :
/* Get the handle of the client area's device context. */
hdc = GetDC (scroll);
/* Extract font dimensions from the text metrics. */
GetTextMetrics (hdc, &tm);
xChar = tm.tmAveCharWidth;
xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2;
yChar = tm.tmHeight + tm.tmExternalLeading;
/* Free the device context. */
ReleaseDC (scroll, hdc);
/*
* Set an arbitrary maximum width for client area.
* (xClientMax is the sum of the widths of 48 average
* lowercase letters and 12 uppercase letters.)
*/
xClientMax = 48 * xChar + 12 * xUpper;
return 0;
case WM_SIZE:
/* Retrieve the dimensions of the client area. */
yClient = HIWORD (lParam);
xClient = LOWORD (lParam);
/*
* Determine the maximum vertical scrolling position.
* The two is added for extra space below the lines
* of text.
*/
yMax = max (0, LINES + 2 - yClient/yChar);
/*
* Make sure the current vertical scrolling position
* does not exceed the maximum.
*/
yPos = min (yPos, yMax);
/*
* Adjust the vertical scrolling range and scroll box
* position to reflect the new yMax and yPos values.
*/
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = 0;
si.nMax = yMax;
si.nPage = yClient / yChar;
si.nPos = yPos;
SetScrollInfo(scroll, SB_VERT, &si, TRUE);
/*
* Determine the maximum horizontal scrolling position.
* The two is added for extra space to the right of the
* lines of text.
*/
xMax = max (0, 2 + (xClientMax - xClient)/xChar);
/*
* Make sure the current horizontal scrolling position
* does not exceed the maximum.
*/
xPos = min (xPos, xMax);
/*
* Adjust the horizontal scrolling range and scroll box
* position to reflect the new xMax and xPos values.
*/
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = 0;
si.nMax = xMax;
si.nPage = xClient / xChar;
si.nPos = xPos;
SetScrollInfo(scroll, SB_HORZ, &si, TRUE);
return 0;
case WM_PAINT:
/* Prepare the window for painting. */
hdc = BeginPaint(scroll, &ps);
/*
* Use the current vertical scrolling position and
* coordinates of the invalid rectangle to determine
* the range of new lines that should be drawn in the
* client area.
*/
FirstLine = max (0, yPos + ps.rcPaint.top/yChar - 1);
LastLine = min (LINES, yPos + ps.rcPaint.bottom/yChar);
/* Display these lines. */
for (i = FirstLine;i < LastLine;i++)
{
div_result = div( i, NUM_OUTPUT);
SetCount=div_result.quot;
NodeCount=div_result.rem;
x = xChar * (1 - xPos);
y = yChar * (1 - yPos + i);
strcpy(tempa,"Input Set: "); ltoa(SetCount,tempb,10);
strcat(tempa,tempb);
strcat(tempa," OutputNode: "); ltoa(NodeCount,tempb,10);
strcat(tempa,tempb);
strcat(tempa," DesiredActivation: ");
ConvertFloat(tempb,DESIRED_OUTPUT[SetCount][NodeCount],8);
strcat(tempa,tempb);
TextOut(hdc,x,y,"
",52);
TextOut(hdc,x+50,y,"
",52);
TextOut(hdc, x, y, tempa, strlen(tempa));
}
/* Indicate that painting is finished. */
EndPaint(scroll, &ps);
break;
case WM_VSCROLL:
switch(LOWORD (wParam)) {
/* User clicked the shaft above the scroll box. */
case SB_PAGEUP:
yInc = min(-1, -yClient / yChar);
break;
/* User clicked the shaft below the scroll box. */
case SB_PAGEDOWN:
yInc = max(1, yClient / yChar);
break;
/* User clicked the top arrow. */
case SB_LINEUP:
yInc = -1;
break;
/* User clicked the bottom arrow. */
case SB_LINEDOWN:
yInc = 1;
break;
/* User dragged the scroll box. */
case SB_THUMBTRACK:
yInc = HIWORD(wParam) - yPos;
break;
default:
yInc = 0;
}
/*
* If applying the vertical scrolling increment does not
* take the scrolling position out of the scrolling range,
* increment the scrolling position, adjust the position
* of the scroll box, and update the window. UpdateWindow
* sends the WM_PAINT message.
*/
if (yInc = max(-yPos, min(yInc, yMax - yPos))) {
yPos += yInc;
ScrollWindowEx(scroll, 0, -yChar * yInc,
(CONST RECT *) NULL, (CONST RECT *) NULL,
(HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE);
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = yPos;
SetScrollInfo(scroll, SB_VERT, &si, TRUE);
UpdateWindow (scroll);
}
} //End of switch(message)
//Let Windows handle it..
return DefWindowProc(scroll,message,wParam,lParam);
} //End of DisplayDesired
inline void ConvertFloat(char *string,double source,int precision)
/* Tiresome way of going about converting a float to
a string. */
{
int decimal, sign,i,len;
char *buffer;
char temp[100];
buffer = _fcvt( source, precision, &decimal, &sign );
if (sign)
strcpy(string,"-");
else
strcpy(string," ");
if (decimal<=0)
{
strcat(string,"0.");
len=strlen(buffer);
for (i=0; i<(precision-len); i++)
strcat(string,"0");
strcat(string,buffer);
}
else
{
strcpy(temp,buffer);
temp[decimal]='\0';
strcat(string,temp);
strcat(string,".");
strcat(string,&buffer[decimal]);
}
} //End of ConvertFloat
void Capture(HWND parent)
/* Takes input from VFW API (camera) and will convert
it to bitmap data. It will then run the image
through the network displaying network output.
>>NOTE: 8 bit greyscale!!!<< */
{
HWND win;
HWND ghWndCap ; //Handle to capture window
BOOL ok;
HBITMAP hbmp;
PBYTE lpvBits;
BITMAPINFO bi;
BITMAPINFO *pbi;
DWORD i;
HDC hdc;
HPALETTE hpal;
int xdim=160,ydim=120;
int a,b;
int NetCount;
MSG msg;
if (!NET_INIT)
{
MessageBox(parent,"Network Not Initialized!","Video Capture",
MB_ICONHAND);
return;
}
//Get width of area to recognize
ZeroMemory(INPUTSTRING,strlen(INPUTSTRING));
UserInput("Enter WIDTH of capture area:",300,100,parent);
while (FLAGWIN!=NULL)
{
GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
xdim=atoi(INPUTSTRING);
if (xdim>160)
{
MessageBox(parent,"X dimension must be 160 or less!",
"Video Capture",MB_ICONSTOP);
return;
}
//Get Height of area to recognize
ZeroMemory(INPUTSTRING,strlen(INPUTSTRING));
UserInput("Enter HEIGHT of capture area",300,100,parent);
while (FLAGWIN!=NULL)
{
GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
ydim=atoi(INPUTSTRING);
if (ydim>120)
{
MessageBox(parent,"Y dimension must be 120 or less!",
"Video Capture",MB_ICONSTOP);
return;
}
if (xdim*ydim>NUM_INPUT)
{
MessageBox(parent,"Image size larger than input layer of network!"
,"Video Capture",MB_ICONSTOP);
return;
}
win=CreateWindow("ChildClass","Video Capture Window",
WS_OVERLAPPEDWINDOW,0,0,320,
240,parent,NULL,NULL,NULL);
ghWndCap = capCreateCaptureWindow((LPTSTR)TEXT("Cap Win"),
WS_CHILD | WS_VISIBLE,
160-(xdim/2),120-(ydim/2), xdim, ydim,
(HWND) win, (int) 0) ;
/* Display the window before attaching it to camera since it may
take time to connect and the user wants to see something happen. */
ShowWindow(win,1);
/* Note that the QuickCam is driver 0 on my system.
This could change if I had another video driver installed.
--> Word of caution: If the program hangs or crashes while you
are connected to the capture driver you will need to reboot
the machine before you can reconnect again. why?? don't know.. */
ok=capDriverConnect(ghWndCap, 0);
if (!ok)
{
MessageBox(parent,"Unable to connect to QuickCam Driver!","Video
Capture",MB_ICONWARNING);
return;
}
//Set capture rate and start incoming stream
capPreviewRate(ghWndCap, 30);
capPreview(ghWndCap, TRUE);
//Create DC to parent Window
hdc=GetDC(ghWndCap);
//Now allocate space for bits
if ((lpvBits = (PBYTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,19200)) == NULL)
{
MessageBox(parent, "Failed in Memory Allocation for lpvBits!", "Video
Capture", MB_ICONWARNING);
return;
}
//Allocate space for bitmap header and palette
if ((pbi=(PBITMAPINFO)malloc(sizeof(BITMAPINFO)+(sizeof(RGBQUAD)*256)))==NULL)
{
MessageBox(parent,"Failed to allocate memory for bitmap!","Video
Capture",
MB_ICONWARNING);
return;
}
//Loop here continuosly grabbing frames
do
{
ZeroMemory(pbi,(sizeof(BITMAPINFO)+(sizeof(RGBQUAD)*256)));
ZeroMemory(lpvBits,sizeof(BYTE)*19200);
//Grab a frame from the video stream
if (!capGrabFrameNoStop(ghWndCap))
{
MessageBox(parent,"Unable to grab frame from input stream!",
"Video Capture",MB_ICONWARNING);
capDriverDisconnect(ghWndCap);
if (lpvBits!=NULL)
GlobalFree(lpvBits);
if (hbmp!=NULL)
DeleteObject(hbmp);
if (pbi!=NULL)
free(pbi);
EmptyClipboard();
CloseClipboard();
ReleaseDC(hdc,ghWndCap);
return;
}
//Copy the frame to the clipboard
if (!capEditCopy(ghWndCap))
{
MessageBox(parent,"Cannot copy bitmap to clipboard!","Video
Capture",
MB_ICONWARNING);
capDriverDisconnect(ghWndCap);
if (lpvBits!=NULL)
GlobalFree(lpvBits);
if (hbmp!=NULL)
DeleteObject(hbmp);
if (pbi!=NULL)
free(pbi);
EmptyClipboard();
CloseClipboard();
ReleaseDC(hdc,ghWndCap);
return;
}
//Open Clipboard and extract the frame and associated palette.
while (!OpenClipboard(NULL));
hbmp=GetClipboardData(CF_BITMAP);
hpal=GetClipboardData(CF_PALETTE);
if (hbmp==NULL | hpal==NULL)
{
MessageBox(parent,"Unable to Create Bitmap!","Video Capture"
,MB_ICONWARNING);
capDriverDisconnect(ghWndCap);
if (lpvBits!=NULL)
GlobalFree(lpvBits);
if (hbmp!=NULL)
DeleteObject(hbmp);
if (pbi!=NULL)
free(pbi);
EmptyClipboard();
CloseClipboard();
ReleaseDC(hdc,ghWndCap);
return;
}
/* Now we need to extract raw pixel data from Bitmap and put it into
input layer of network. */
//Select the palette into the device context.
SelectPalette(
hdc,
hpal,
FALSE //FALSE forces it into foreground mode
);
//This info must be filled in order to extract pixel data..
bi.bmiHeader.biSize=0x28;
bi.bmiHeader.biBitCount=0x0;
bi.bmiHeader.biClrImportant=0x0;
/* Call GetDIBits to return the raw data of the image since
we can't look inside the handle ourselves. If number of scan
lines is set to 0 DIBits returns the entire image. */
i=GetDIBits(
hdc, // handle of device context
hbmp, // handle of bitmap
0, // first scan line to set in destination bitmap
0, // number of scan lines to copy
NULL, // address of array for bitmap bits
&bi, // address of structure with bitmap data
DIB_RGB_COLORS // RGB or palette index
);
ZeroMemory(pbi,sizeof(BITMAPINFO)+(sizeof(RGBQUAD)*256));
memcpy(pbi,&bi,sizeof(BITMAPINFO));
i=GetDIBits(
hdc, // handle of device context
hbmp, // handle of bitmap
0, // first scan line to set in destination bitmap
120, // number of scan lines to copy
(LPVOID)lpvBits, // address of array for bitmap bits
pbi, // address of structure with bitmap data
DIB_RGB_COLORS // RGB or palette index
);
//Check to make sure input layer of net is large enough
if (xdim*ydim>NUM_INPUT)
{
MessageBox(parent,"Input Layer of Network too small!"
,"Recognize Image",MB_ICONSTOP);
capDriverDisconnect(ghWndCap);
if (lpvBits!=NULL)
GlobalFree(lpvBits);
if (hbmp!=NULL)
DeleteObject(hbmp);
if (pbi!=NULL)
free(pbi);
EmptyClipboard();
CloseClipboard();
ReleaseDC(hdc,ghWndCap);
return;
}
/* Copy the image into the neural network and compute the output. */
NetCount=0;
for (b=ydim; b>=1; b--)
for (a=0; a<xdim; a++)
{
Net.input[0][NetCount].activation=(pbi->bmiColors[lpvBits[(19200-(b*160))+a]].rgbBlue
/255.0);
NetCount++;
}
/* Here we go.. Compute calculates network output! */
Compute(0);
GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg);
DispatchMessage(&msg); //return control to Windows
//Display Output Activations
ViewInputActivations(parent);
ViewOutputActivations(parent);
//Clean up the clipboard
EmptyClipboard();
CloseClipboard();
} while (MessageBox(parent,"Continue?","Recognize Image",MB_YESNO)==IDYES);
//Disconnect from camera
capDriverDisconnect(ghWndCap);
if (lpvBits!=NULL)
GlobalFree(lpvBits);
if (hbmp!=NULL)
DeleteObject(hbmp);
if (pbi!=NULL)
free(pbi);
ReleaseDC(hdc,ghWndCap);
} //END OF CAPTURE!!
void WhatISee(HWND parent)
/* This function does almost the same thing as the capture function
except instead of feeding the image into the network it will instead
write the bits into a log file. In this way you can manually look
at what the camera "sees". */
{
HWND ghWndCap;
BOOL ok;
HBITMAP hbmp;
FILE *file;
PBYTE lpvBits;
BITMAPINFO bi;
PBITMAPINFO pbi;
DWORD i;
HDC hdc;
HPALETTE hpal;
OPENFILENAME ofn;
char filename[80]="";
int xdim=160,ydim=120;
int a,b;
MSG msg;
//Get width of area to capture
ZeroMemory(INPUTSTRING,strlen(INPUTSTRING));
UserInput("Enter WIDTH of capture area:",300,100,parent);
while (FLAGWIN!=NULL)
{
GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
xdim=atoi(INPUTSTRING);
if (xdim>160)
{
MessageBox(parent,"X dimension must be 160 or less!",
"Video Capture",MB_ICONSTOP);
return;
}
//Get Height of area to capture
ZeroMemory(INPUTSTRING,strlen(INPUTSTRING));
UserInput("Enter HEIGHT of capture area",300,100,parent);
while (FLAGWIN!=NULL)
{
GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
ydim=atoi(INPUTSTRING);
if (ydim>120)
{
MessageBox(parent,"Y dimension must be 120 or less!",
"Video Capture",MB_ICONSTOP);
return;
}
//Create a window to be connected with capture window
UserInput("Video Capture Window",320,240,parent);
ghWndCap = capCreateCaptureWindow((LPTSTR)TEXT("Cap Win"),
WS_CHILD | WS_VISIBLE,
160-(xdim/2), 120-(ydim/2), xdim, ydim,
(HWND) FLAGWIN, (int) 0);
/* Note that the QuickCam is driver 0 on my system.
This could change if I had another video driver installed.
--> Word of caution: If the program hangs or crashes while you
are connected to the capture driver you will need to reboot
the machine before you can reconnect again. why?? don't know.. */
ok=capDriverConnect(ghWndCap, 0);
if (!ok)
{
MessageBox(parent,"Unable to connect to QuickCam Driver!","Video
Capture",MB_ICONWARNING);
return;
}
//Create DC to capture window
hdc=GetDC(ghWndCap);
//Set capture rate and start incoming stream
capPreviewRate(ghWndCap, 90);
capPreview(ghWndCap, TRUE);
do
{ //Wait here until user closes window
GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg);
//Grab a frame from the video stream
capGrabFrameNoStop(ghWndCap);
//Copy the frame to the clipboard
capEditCopy(ghWndCap);
DispatchMessage(&msg);
} while (FLAGWIN!=NULL);
/* Disconnect from camera immediately, we don't really need
to be connected anymore and it's safer. */
capDriverDisconnect(ghWndCap);
//Open Clipboard and extract the frame and associated palette.
while (!OpenClipboard(NULL));
hbmp=GetClipboardData(CF_BITMAP);
hpal=GetClipboardData(CF_PALETTE);
if (hbmp==NULL)
{
MessageBox(parent,"Unable to Create Bitmap!","Video Capture"
,MB_ICONWARNING);
return;
}
if (hpal==NULL)
{
MessageBox(parent,"Unable to Create Bitmap Palette!","Video Capture",
MB_ICONWARNING);
return;
}
//Get filename
// Initialize OPENFILENAME
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hInstance=NULL;
ofn.hwndOwner = parent;
ofn.lpstrFile = filename;
ofn.nMaxFile = sizeof(filename);
ofn.lpstrFilter = "All\0*.*\0Image Log File\0*.LOG\0";
ofn.lpstrCustomFilter=NULL;
ofn.nFilterIndex = 2;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle="Save Image Log File";
ofn.Flags = OFN_PATHMUSTEXIST;
// Display the Open dialog box.
if (GetSaveFileName(&ofn)!=TRUE)
{
MessageBox(parent,"Invalid Filename.","Create Image
Log",MB_ICONWARNING);
return;
}
//Open log file
if (!(file=fopen(filename,"w")))
{
MessageBox(parent,"Unable to create file!","Create Image
Log",MB_ICONWARNING);
return;
}
//Select the palette into the device context.
SelectPalette(
hdc,
hpal,
FALSE //FALSE forces it into foreground mode
);
//This info must be filled in order to extract pixel data..
bi.bmiHeader.biSize=0x28;
bi.bmiHeader.biBitCount=0x0;
bi.bmiHeader.biClrImportant=0x0;
/* Call GetDIBits to return the raw data of the image since
we can't look inside the handle ourselves. If number of scan
lines is set to 0 DIBits returns the entire image. */
i=GetDIBits(
hdc, // handle of device context
hbmp, // handle of bitmap
0, // first scan line to set in destination bitmap
ydim, // number of scan lines to copy
NULL, // address of array for bitmap bits
&bi, // address of structure with bitmap data
DIB_RGB_COLORS // RGB or palette index
);
fprintf(file,"Number of bytes required: %x\n",sizeof(BITMAPINFOHEADER));
fprintf(file,"Bytes Returned: %d\n",i);
fprintf(file,"\nData Returned\n");
fprintf(file,"biSize: %02x\n",bi.bmiHeader.biSize);
fprintf(file,"biWidth: %02x\n",bi.bmiHeader.biWidth);
fprintf(file,"biHeight: %02x\n",bi.bmiHeader.biHeight);
fprintf(file,"biPlanes: %02x\n",bi.bmiHeader.biPlanes);
fprintf(file,"biBitCount: %02x\n",bi.bmiHeader.biBitCount);
fprintf(file,"biSizeImage: %02x\n",bi.bmiHeader.biSizeImage);
fprintf(file,"biCompression: %02x\n",bi.bmiHeader.biCompression);
fprintf(file,"biXPelsPerMeter: %02x\n",bi.bmiHeader.biXPelsPerMeter);
fprintf(file,"biYPelsPerMeter: %02x\n",bi.bmiHeader.biYPelsPerMeter);
fprintf(file,"biClrUsed: %02x\n",bi.bmiHeader.biClrUsed);
fprintf(file,"biClrImportant: %02x\n",bi.bmiHeader.biClrImportant);
//Now allocate space for bits
if ((lpvBits = (PBYTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,19200)) == NULL)
{
MessageBox(parent, "Failed in Memory Allocation for lpvBits!", "Video
Capture", MB_OK);
return;
}
ZeroMemory(lpvBits,sizeof(BYTE)*19200);
pbi=(PBITMAPINFO)malloc(sizeof(BITMAPINFO)+(sizeof(RGBQUAD)*256));
ZeroMemory(pbi,(sizeof(BITMAPINFO)+(sizeof(RGBQUAD)*256)));
memcpy(pbi,&bi,sizeof(BITMAPINFO));
i=GetDIBits(
hdc, // handle of device context
hbmp, // handle of bitmap
0, // first scan line to set in destination bitmap
120, // number of scan lines to copy
(LPVOID)lpvBits, // address of array for bitmap bits
pbi, // address of structure with bitmap data
DIB_RGB_COLORS // RGB or palette index
);
fprintf(file,"\nSecond Bytes Returned: %d\n",i);
fprintf(file,"biSize: %02x\n",pbi->bmiHeader.biSize);
fprintf(file,"biWidth: %02x\n",pbi->bmiHeader.biWidth);
fprintf(file,"biHeight: %02x\n",pbi->bmiHeader.biHeight);
fprintf(file,"biPlanes: %02x\n",pbi->bmiHeader.biPlanes);
fprintf(file,"biBitCount: %02x\n",pbi->bmiHeader.biBitCount);
fprintf(file,"biSizeImage: %02x\n",pbi->bmiHeader.biSizeImage);
fprintf(file,"biCompression: %02x\n",pbi->bmiHeader.biCompression);
fprintf(file,"biXPelsPerMeter: %02x\n",pbi->bmiHeader.biXPelsPerMeter);
fprintf(file,"biYPelsPerMeter: %02x\n",pbi->bmiHeader.biYPelsPerMeter);
fprintf(file,"biClrUsed: %02x\n",pbi->bmiHeader.biClrUsed);
fprintf(file,"biClrImportant: %02x\n",pbi->bmiHeader.biClrImportant);
fprintf(file,"\n\nColor Table\n\n");
for (i=0; i<256; i++)
{
fprintf(file,"Color Number: %d\n",i);
fprintf(file,"rgbBlue: %d\n",pbi->bmiColors[i].rgbBlue);
fprintf(file,"rgbGreen: %d\n",pbi->bmiColors[i].rgbGreen);
fprintf(file,"rgbRed: %d\n",pbi->bmiColors[i].rgbRed);
fputs("\n",file);
}
//Lets dump the bits
fprintf(file,"\nRaw Data\n");
for (b=ydim; b>=1; b--)
for (a=0; a<xdim; a++)
fprintf(file,"%f\n",(pbi->bmiColors[lpvBits[(19200-(b*160))+a]].rgbBlue/255.0));
fclose(file);
if (lpvBits!=NULL)
GlobalFree(lpvBits);
if (hbmp!=NULL)
DeleteObject(hbmp);
if (hpal!=NULL)
DeleteObject(hpal);
if (pbi!=NULL)
free(pbi);
EmptyClipboard();
CloseClipboard();
ReleaseDC(hdc,ghWndCap);
}
void RunAllSets(HWND parent)
/* This function will take all the input sets and compute
the network output one at a time. It puts the results into
a file specified as the output by the user. */
{
OPENFILENAME ofn;
char filename[100];
FILE *file;
int i,j;
//Check to make sure network is initialized...
if (!NET_INIT)
{
MessageBox(parent,"Network Not Initialized!","Run All Image Sets",
MB_ICONHAND);
return;
}
//First Get Filename
ZeroMemory(filename,strlen(filename));
// Initialize OPENFILENAME
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hInstance=NULL;
ofn.hwndOwner = parent;
ofn.lpstrFile = filename;
ofn.nMaxFile = sizeof(filename);
ofn.lpstrFilter = "All\0*.*\0Image Log File\0*.LOG\0";
ofn.lpstrCustomFilter=NULL;
ofn.nFilterIndex = 2;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle="Log File";
ofn.Flags = OFN_PATHMUSTEXIST;
// Display the Open dialog box.
if (GetSaveFileName(&ofn)!=TRUE)
{
MessageBox(parent,"Invalid Filename.","Run all Image
Sets",MB_ICONSTOP);
return;
}
//Open file for write
file=fopen(filename,"w");
for (i=0; i<INPUT_SET; i++)
{
Compute(i);
for (j=0; j<NUM_OUTPUT; j++)
fprintf(file,"%08f ",Net.output[j].activation);
fprintf(file,"\n");
}
fclose(file);
MessageBox(parent,"All Image Sets Run Successfully","Complete!",MB_OK);
}
---------------- Header File ICU.H ------------------------------------
/* 1/28/97 J. P. Neural Net */
#include <windows.h>
#include <strstrea.h>
#include <stddef.h>
#include <memory.h>
#include <winioctl.h>
#include <wingdi.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <windowsx.h>
#include <commdlg.h>
#include <mmreg.h>
#include <io.h>
#include <fcntl.h>
#include <vfw.h>
#include <math.h>
#include <time.h>
//Forward Declarations
int PASCAL WinMain(HANDLE hThisInst, HANDLE hPrevInst,
LPSTR lpszArgs, int nWinMode);
LONG FAR PASCAL WindowFunc(HWND hwnd, unsigned int message,
unsigned int wParam, LONG lParam);
LONG FAR PASCAL ChildFunc(HWND child, unsigned int message,
unsigned int wParam, LONG lParam);
LONG FAR PASCAL DisplayInputNodes(HWND scroll, unsigned int message,
unsigned int wParam, LONG lParam);
LONG FAR PASCAL DisplayHiddenNodes(HWND scroll, unsigned int message,
unsigned int wParam, LONG lParam);
LONG FAR PASCAL DisplayOutputNodes(HWND scroll, unsigned int message,
unsigned int wParam, LONG lParam);
LONG FAR PASCAL DisplayI2H(HWND scroll, unsigned int message,
unsigned int wParam, LONG lParam);
LONG FAR PASCAL DisplayH2O(HWND scroll, unsigned int message,
unsigned int wParam, LONG lParam);
LONG FAR PASCAL DisplayDesired(HWND scroll, unsigned int message,
unsigned int wParam, LONG lParam);
BOOLEAN AllocSpace(void);
void FreeSpace(void);
void NetInit(HWND hwnd);
void GetInput(HWND hwnd);
void Compute(int);
void BackProp(int);
int Good(int);
void Epoch(HWND hwnd);
void LoadNet(HWND hwnd);
void LoadDSRD(HWND hwnd);
void SavNet(HWND hwnd);
void SetDOutput(HWND hwnd);
void ViewParams(HWND parent);
void Menu(HWND);
void ProcessSelection(int xcount, int ycount, HWND hwnd);
void clrscr(HWND hwnd);
void DisplayText(char title[50],char output[100],HWND parent,int priority);
void UserInput(char *title,int width,int height,HWND parent);
inline void ConvertFloat(char *string,double source,int precision);
void ViewInputActivations(HWND parent);
void ViewHiddenActivations(HWND parent);
void ViewOutputActivations(HWND parent);
void ViewI2H(HWND parent);
void ViewH2O(HWND parent);
void ViewDesiredOutput(HWND parent);
void Capture(HWND parent);
void WhatISee(HWND parent);
void RunAllSets(HWND hwnd);
//Global Environment Parameters
#define SIGMOID(x) (1.0/(1.0+exp(-x)))
#define RANDOM ((double)rand()/(RAND_MAX))
#define square(x) ((x)*(x))
//Neural Network specific structures
typedef struct Unit
{
double input; //Total input
double activation; //Total output (input through sigmoid function)
} Unit;
typedef struct Net
{
Unit **input; //[INPUT_SET][NUM_INPUT]
Unit *hidden; //[NUM_HIDDEN]
Unit *output; //[NUM_OUTPUT]
double *error; //Overall network error [INPUT_SET]
//Connections between layers
double **i2h; //input to hidden [NUM_INPUT][NUM_HIDDEN]
double **h2o; //hidden to output [NUM_HIDDEN][NUM_OUTPUT]
} NET;
T.R | Title | User | Personal Name | Date | Lines
|
---|