<u>Data Acquisition</u><br>
The first step in the experiment involved acquiring the data set to both train and test with. The ultimate goal is, of course, to determine whether a signature is authentic or not, requiring that more than one subject produce signatures. To ensure diversity, we acquired the signatures of five individuals, both male and female, who were instructed to produce their best forgeries and even given indirect hints on how to do this, creating similar sized signatures for example.<br><br>

<u>Preprocessing</u><br>
<i>Median Filter</i><br>
The signatures were produced on clean white sheets of paper with no printing on either side and scanned on a clean scanner, but nonetheless "salt and pepper" noise cannot be avoided, if caused by measurement error for no other reason. Any large blocks of noise would have been detected and removed when cropping the images.<br><br>

<i>Thinning and Pruning</i><br>
To account for ink bleeding, different pens, and other similar variations in writing conditions the signatures needed to be thinned. Non-smooth surfaces resulted in phantom lines appearing. A solution to the phantom line problem is pruning. From sampling several of the signatures, it appeared that line lengths shorter than 20 were probably merely phantom and could be removed. In some cases, the resulting signatures were marvelous, but in most cases some significant but not vital amounts of detail were lost, such as in the top of the "h" in "Mehler". One must realize that though the resulting signature may not visually appeal, as long as most of its identifying characteristics remain the preprocessing will have been a success.<br><br>

<i>Bounding Box</i><br>
Since the images were cropped by hand, they were not necessarily bottom-left oriented at the origin. To position all signatures similarly and reduce feature extraction time a bounding box for the signature is obtained and a new image produced.<br><br>

<table border=0 align=center>
<tr><td><a href=images/ra001.gif><img width=300 height=100 src=images/ra001.gif></a></td><td><a href=images/ra001.op.gif><img width=300 height=100 src=images/ra001.op.gif></a></td></tr>
<tr><td>Authentic Original</td><td>Authentic Preprocessed</td></tr>
<tr><td><a href=images/fa001.gif><img width=300 height=100 src=images/fa001.gif></a></td><td><a href=images/fa001.op.gif><img width=300 height=100 src=images/fa001.op.gif></a></td></tr>
<tr><td>Forged Original</td><td>Forged Preprocessed</td></tr>
<tr><td colspan=2 align=center><a href=images/ra001.np.gif><img width=500 height=100 src=images/ra001.np.gif></a></td></tr>
<tr><td colspan=2 align=center>Authentic Original w/o Pruning</td></tr>
<tr><td><a href=images/rb001.gif><img width=300 height=100 src=images/rb001.gif></a></td><td><a href=images/rb001.op.gif><img width=300 height=100 src=images/rb001.op.gif></a></td></tr>
<tr><td>Authentic Original</td><td>Authentic Preprocessed</td></tr>
<tr><td><a href=images/fb001.gif><img width=300 height=100 src=images/fb001.gif></a></td><td><a href=images/fb001.op.gif><img width=300 height=100 src=images/fb001.op.gif></a></td></tr>
<tr><td>Forged Original</td><td>Forged Preprocessed</td></tr>
</table><br><br>

<u>Feature Extraction</u><br>
<i>Global Features.</i><br>
Six global features were used in the feature vector.  They are signature height, width, area, center of mass (x,y), edge points, cross points, and closed loops.  These features proved to be a very accurate classifier.<br><br>

<i>Local Features</i><br>
Two methods of localized features were experimented with.  One was imposing a grid on the image area, and taking the area of all the pixels in the grid as the feature.  The other method was grouping the signature pixels into 'strokes'.  A stroke attempts to capture a continuous curve of the pen.  Strokes are found by scanning the image for an unmarked pixel, and extending this pixel in the up and down direction, only adding neighboring pixels to this stroke if they neighbor in the same direction (i.e. all successive neighbors are above each other).  Comparing the results of the two showed that using the grid is more sensitive to the particular signature.  Since strokes are based on the actual image data, they can adapt to difficult cases.  For each stroke, the top most and bottom most point is extracted, as well as the length and slope of the line connecting these two points.<br><br>

<table border=0 align=center>
<tr><td></td><td><a href=images/f1.gif><img width=300 height=100 src=images/f1.gif></a></td><td><a href=images/f2.gif><img width=300 height=100 src=images/f2.gif></a></td></tr>
<tr><td align=right>Height:</td><td align=center>161</td><td align=center>165</td></tr>
<tr><td align=right>Width:</td><td align=center>621</td><td align=center>924</td></tr>
<tr><td align=right>Area:</td><td align=center>2418</td><td align=center>2782</td></tr>
<tr><td align=right>Center of Mass:</td><td align=center>(307.320923, 61.564102)</td><td align=center>(458.598846, 63.445721)</td></tr>
<tr><td align=right>Edge Points:</td><td align=center>5</td><td align=center>8</td></tr>
<tr><td align=right>Cross Points:</td><td align=center>53</td><td align=center>28</td></tr>
<tr><td align=right>Closed Loops:</td><td align=center>25</td><td align=center>11</td></tr>
<tr><td align=right><br></td><td><br></td></tr>
<tr><td align=right><u>1st Stroke</u></td><td></td><td></td></tr>
<tr><td align=right>Top Point:</td><td align=center>(74,165)</td><td align=center>(38,164)</td></tr>
<tr><td align=right>Bottom Point:</td><td align=center>(5,21)</td><td align=center>(6,25)</td></tr>
<tr><td align=right>Length:</td><td align=center>159.677795</td><td align=center>142.635895</td></tr>
<tr><td align=right>Slope:</td><td align=center>2.086957</td><td align=center>4.343750</td></tr>
</table><br><br>

<u>Neural Network</u><br>
We used a Quasi-Newton training algorithm, with 1 Hidden Layer of 15 nodes, each with a logistic node function, and an output node with a tanh function.  The final result was the sign of the output.  This network was trained for 200 iterations.<br><br>

We also used an Ada Boost program.  Boosting lightly trains many very simple networks, and hopes by using a large number of them, the resulting vote will be accurate.  The program trained 1000 networks; each with 1 hidden layer of 3 nodes, with logistic functions, and a tanh output.  These networks were only allowed to be trained for a maximum of 50 iterations.   We see that the Boosting algorithm performed better on test sets than the Quasi-Newton algorithms.<br><br>

<center><b>Statistics</b></center>
<table bgcolor=#eeeeee border=1 align=center>
<tr><th>Method</th><th>Correct Classifications(%)</th><th>False Positives(%)</th><th>False Negatives(%)</th><th>Total Misclassifications(%)</th></tr>
<tr><td>Adaboost (AB)</td><td>92</td><td>5.2</td><td>2.7</td><td>8</td></tr>
<tr><td>Quasi Newton</td><td>84.4</td><td>7.7</td><td>7.9</td><td>15.6</td></tr>
<tr><td>Nearest Neighbor</td><td>82.1</td><td>6.5</td><td>11.4</td><td>17.9</td></tr>
<tr><td>AB, grid features</td><td>69.5</td><td>7.3</td><td>23.2</td><td>30.5</td></tr>
<tr><td>AB, global only</td><td>94.91</td><td>1.9</td><td>3.2</td><td>5.1</td></tr>
<tr><td>AB, strokes only</td><td>92.3</td><td>3.85</td><td>3.85</td><td>7.7</td></tr>
<tr><td>AB, 1st stroke only</td><td>51.16</td><td>0</td><td>48.84</td><td>48.84</td></tr>
</table><br><br>

<center><b>Programs</b></center>
<table border=1 align=center>
<tr><td>bb</td><td><a href=files/bb.c>Download</a></td><td><a href=man/bb.man.txt>Man</a></td><td>Extracts bounding box</td></tr>
<tr><td>feature</td><td><a href=files/feature.c>Download</a></td><td><a href=man/feature.man.txt>Man</a></td><td>Computes features</td></tr>
<tr><td>fv.pl</td><td><a href=files/fv.txt>Download</a></td><td><a href=man/fv.man.txt>Man</a></td><td>Automates creation of feature vectors</td></tr>
<tr><td>nn.pl</td><td><a href=files/nn.txt>Download</a></td><td><a href=man/nn.man.txt>Man</a></td><td>Computes nearest neighbor</td></tr>
<tr><td>random.pl</td><td><a href=files/random.txt>Download</a></td><td><a href=man/random.man.txt>Man</a></td><td>Randomly swaps lines between files</td></tr>
</table>
