Re: info on number 4 recognition

View: New views
1 Messages — Rating Filter:   Alert me  

Re: info on number 4 recognition

by Fabrizio Sinato :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Greetings,

 the attached archive contains a patch to recognize the "open" glyph
of the number 4. E.g. as it is handwritten:

                       /
                      /
                     /   |
                    +----+--
                         |

WARNING: there is a bug in this patch: ocrad 0.16 will not recognize
the backquote (`) anymore, so it is just offered as a starting point
for others.

Right now we are using OCRAD on numbers only, and I will probably not
attempt to improve this patch very soon.

You can get this patch and some test images from
http://fax.appix.net/ocrad-0.16-patch.tgz

I hope this helps,

Fabrizio.


[open-4.patch]

Index: profile.h
===================================================================
--- profile.h    (revision 606)
+++ profile.h    (working copy)
@@ -49,6 +49,8 @@
   int  area( int l = 0, int r = -1 ) throw();
   bool increasing( int i = 1 ) throw();
   bool decreasing( int i = 1 ) throw();
+  bool increasing( int b, int e ) throw();
+  bool decreasing( int b, int e ) throw();
   bool isconcave() throw();
   bool isconvex() throw();
   bool isflat() throw();
Index: feats_test0.cc
===================================================================
--- feats_test0.cc    (revision 606)
+++ feats_test0.cc    (working copy)
@@ -335,7 +335,14 @@
     if( urow > b.top() && lrow < b.bottom() && rp.isctip() &&
         ( bp.ispit() || tp.ispit() || ( bp.islpit() && tp.islpit() ) ) &&
         b.escape_right( b.vcenter(), b.hcenter() ) )
-      return 'c';
+      {
+      int tpc = tp.pos(50);
+      int bpc = bp.pos(50);
+      if ( tp.area( tpc, tpc ) + bp.area( bpc, bpc ) < b.height() * 0.20 )
+         return 'c';
+      else
+         return '<';
+      }
     }
 
   if( b.height() > 2 * b.width() && rp.isconvex() )
@@ -473,6 +480,10 @@
 
   if( lp.isconvex() || lp.ispit() )
     {
+    if( ( hbars() == 1 ) && lp.decreasing( lp.pos( 0 ), hbar(0).top() -
b.top() )
+        && (hbar(0).top() > b.top() + lp.pos( 50 ))
+        && (hbar(0).top() < b.top() + lp.pos( 90 )) )
+      return '4';
     int col = 0, row = 0;
     for( int i = rp.pos( 30 ); i <= rp.pos( 60 ); ++i )
       if( rp[i] > col ) { col = rp[i]; row = i; }
Index: profile.cc
===================================================================
--- profile.cc    (revision 606)
+++ profile.cc    (working copy)
@@ -169,7 +169,9 @@
   return area;
   }
 
-
+//
+// profile increase from top towards bottom: rp( 7 ) -> increase
+//
 bool Profile::increasing( int i ) throw()
   {
   if( _limit < 0 ) initialize();
@@ -179,7 +181,9 @@
   return true;
   }
 
-
+//
+// profile decrease from top towards bottom: lp( 4 ) -> decrease
+//
 bool Profile::decreasing( int i ) throw()
   {
   if( _limit < 0 ) initialize();
@@ -192,6 +196,32 @@
   }
 
 
+bool Profile::increasing( int b, int e ) throw()
+  {
+  if( _limit < 0 ) initialize();
+  int stop = e;
+  if ( e > samples() )
+     stop = samples();
+  if( b <= 0 || b > stop - 2 || data[stop-1] - data[b] < 2 )
+    return false;
+  while( ++b < stop ) if( data[b] < data[b-1] ) return false;
+  return true;
+  }
+
+
+bool Profile::decreasing( int b, int e ) throw()
+  {
+  if( _limit < 0 ) initialize();
+  int stop = e;
+  if ( e > samples() )
+     stop = samples();
+  if( b < 0 || b >= stop - 2 || data[stop-1] - data[b] > 2 )
+    return false;
+  while( ++b < stop ) if( data[b] > data[b-1] ) return false;
+  return true;
+  }
+
+
 bool Profile::isconcave() throw()
   {
   if( _isconcave < 0 )
@@ -604,12 +634,12 @@
   if( _limit < 0 ) initialize();
   if( samples() < 5 ) return false;
 
-  const int xl = ( samples() / 30 ) + 1, yl = ( data[xl] + data[xl+1] )
/ 2 ;
+  const int xl = (int)( samples() * 0.30 ) + 1, yl = ( data[xl] +
data[xl+1] ) / 2 ;
   const int xr = samples() - xl - 1,     yr = ( data[xr-1] + data[xr] )
/ 2 ;
   const int dx = xr - xl, dy = yr - yl;
   if( dx <= 0 ) return false;
-  const int dmax = dx * ( ( samples() / 20 ) + 2 );
-  int faults = samples() / 10;
+  const int dmax = dx * ( (int)( samples() * 0.10 ) + 2 );
+  int faults = (int)(samples() * 0.10);
   for( int i = 0; i < samples(); ++i )
     {
     int y = ( dx * yl ) + ( ( i - xl ) * dy );
@@ -620,3 +650,4 @@
   if( _dy ) *_dy = dy;
   return true;
   }
+
Index: feats.cc
===================================================================
--- feats.cc    (revision 606)
+++ feats.cc    (working copy)
@@ -200,14 +200,17 @@
   const Block & b = *_block;
 
   if( hbars() == 1 && hbar(0).top() <= b.top() + ( b.height() / 10 ) &&
+      vbars() == 0 &&
       4 * hbar(0).height() <= b.height() &&
       5 * hbar(0).width() >= 4 * b.width() &&
       rp.increasing( hbar(0).vcenter() - b.top() ) &&
       rp[hbar(0).bottom()-b.top()+2] - rp[hbar(0).bottom()-b.top()] <
b.width() / 4 )
     return '7';
 
-  if( b.height() > b.width() && rp.increasing( 1 ) &&
-      b.seek_left( b.vcenter(), b.hcenter() ) <= b.left() )
+  if( hbars() == 1 &&
+      b.height() > b.width() &&
+      hbar(0).bottom() - b.top() <= b.height() / 5 &&
+      rp.increasing( hbar(0).bottom() - b.top(), rp.pos(80) ) ) //&&
     return '7';
 
   if( tp.minima( b.height() / 4 ) == 1 && bp.minima( b.height() / 4 )
== 1 )
Index: feats_test1.cc
===================================================================
--- feats_test1.cc    (revision 606)
+++ feats_test1.cc    (working copy)
@@ -173,7 +173,7 @@
 
   int col = h.hcenter();
   int row = b.seek_top( h.top(), col, false ) - 1;
-  if( row <= b.top() )
+  if( row <= b.top() + 1 )
     {
     col = h.right(); if( b.right() - h.right() > h.width() ) ++col;
     row = b.seek_top( h.top(), col, false ) - 1;




_______________________________________________
Bug-ocrad mailing list
Bug-ocrad@...
http://lists.gnu.org/mailman/listinfo/bug-ocrad