Hello,
I am writing an OCR program. I have created an PERL object called PixelMap.pm that creates a generic bitmap for XORing with a test image. Each instantiated PixelMap gets saved to file in a "Character Library." The OCR program opens the character libray, imports all of the PixelMaps (or "masks"), and then compares each mask to a test image: if the XORing returns TRUE, we have matched the test image to a character in the library and therefor have recognized it.
The file format is: (just an example from the real thing)_
<ID> Capital_A
<LITERAL>
A
</LITERAL>
<HEIGHT>
9
</HEIGHT>
<WIDTH>
7
</WIDTH>
<DATA>
0,0,0,1,0,0,0,
0,0,0,1,0,0,0,
0,0,1,0,1,0,0,
0,0,1,0,1,0,0,
0,1,0,0,0,1,0,
0,1,0,0,0,1,0,
0,1,1,1,1,1,0,
1,0,0,0,0,0,1,
1,0,0,0,0,0,1,
</DATA>
</ID>
<ID> Capital_B
<LITERAL>
B
</LITERAL>
<HEIGHT>
9
</HEIGHT>
<WIDTH>
5
</WIDTH>
<DATA>
1,1,1,1,0,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,1,1,1,0,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,1,1,1,0,
</DATA>
</ID>
Which you can see is an attempt at object persistence by saving the object to file. My main problem is when it comes time to load the libray.
There are two things that I would like to learn from the experts here at EE:
1. What is the best way to parse (using the above file format) the file for processing?
2. Once the file is parsed, what is the best way of instantiating each one for comparison? Ideally I would like to have an array of references to each PixelMap object so that I can iterate through the collection.
I have done my HW. Currently I am doing the following:
@id=qw(Capital_A Capital_B Capital_C Capital_D Capital_E Capital_F
Capital_G Capital_H Capital_I Capital_J Capital_K Capital_L
Capital_M Capital_N Capital_O Capital_P Capital_Q Capital_R
Capital_S Capital_T Capital_U Capital_V Capital_W Capital_X
Capital_Y Capital_Z lower_a lower_b lower_c lower_d lower_e
lower_f lower_g lower_h lower_i lower_j lower_k lower_l lower_m
lower_n lower_o lower_p lower_q lower_r lower_s lower_t lower_u
lower_v lower_w lower_x lower_y lower_z number_1 number_2
number_3 number_4 number_5 number_6 number_7 number_8 number_9
number_0 symbol_equal symbol_LeftBracket symbol_apstrphe
symbol_fwdSlash symbol_tilday symbol_exclam symbol_at symbol_pound
symbol_dollar symbol_percent symbol_carat symbol_ampersand
symbol_star symbol_leftParenthesis symbol_rightParenthesis
symbol_underscore symbol_plus symbol_leftCurly symbol_rightCurly
symbol_lessThan symbol_greaterThan symbol_question);
foreach(@id) {
# 'mask' starting parameters:
$ref=GetMask($filename, $_);
$id=shift(@$ref);
$literal=shift(@$ref);
$height_mask=shift(@$ref);
$width_mask=shift(@$ref);
$refData=shift(@$ref); # actual pixel data
# ...do comparison with test image
}
sub GetMask {
my $filename=shift;
my $id=shift;
#print $filename."\n";
# we want to find $id in $filename and return the contents of the glyph
$ID_1 = "<ID>"; #<ID> $id
$ID_1 = $ID_1." $id";
$ID_2 = "</ID>";#</ID> at end of mask def
$H_1 = "<HEIGHT>";
$H_2 = "</HEIGHT>";
$W_1 = "<WIDTH>";
$W_2 = "</WIDTH>";
$DATA_1 = "<DATA>";
$DATA_2 = "</DATA>";
$LIT_1 = "<LITERAL>";
$LIT_2 = "</LITERAL>";
open(IN, $filename) || die "$filename could not be found.\n";
chomp(@lines=<IN>);
# search for the requested mask $id in $filename:
$found=0;
$h=0;
$w=0;
$d=0;
$l=0;
@mask=();
push(@mask, $id);
@data=();
LOOP:foreach(@lines) {
if($_ =~ /$ID_1/) {
$found=1;
}
if($_ =~ /$ID_2/) {
$found=0;
}
if($found) {
if($_ =~ /$H_1/) {
$h=1;
next LOOP;
}
if($_ =~ /$H_2/) {
$h=0;
next LOOP;
}
if($_ =~ /$W_1/) {
$w=1;
next LOOP;
}
if($_ =~ /$W_2/) {
$w=0;
next LOOP;
}
if($_ =~ /$DATA_1/) {
$d=1;
next LOOP;
}
if($_ =~ /$DATA_2/) {
$d=0;
next LOOP;
}
if($_ =~ /$LIT_1/) {
$l=1;
next LOOP;
}
if($_ =~ /$LIT_2/) {
$l=0;
next LOOP;
}
}
if($l) {
push(@mask,$_);
}
if($h) {
#print $_."\n";
push(@mask, $_);
}
if($w) {
#print $_."\n";
push(@mask, $_);
}
if($d) {
#print $_."\n";
@unpack=split(/,/,$_);
for($i=0;$i<@unpack;$i++) {
push(@data, $unpack[$i]);
}
}
}
push(@mask, \@data);
return \@mask;
}
Which you can see is VERY LONG. What is a better way? I have seen ozo parse an entire file with one regex expression. "What would ozo do?" (new bumper sticker on my car...)
What I really don't like is that for each new letter I add to the alphabet I have to store its ID in @id. I would rather that the script could get all this from the Character Library text file.
Any suggestions? This question is really a design question because the above code already works - it is just ugly and took a long time to write. Anything to simply the process would be good. Also general design philosophy applied to this problem would be instructive.
Thanks,
sapbucket
Start Free Trial