2008/11/12 Debayan Banerjee <[EMAIL PROTECTED]>

> I did diff -ur my/ their/ > bengali1.patch ; the only changes are in
> baseapi.cpp , baseapi.h and tesseractmain.cpp.
> It detects skew and corrects it, clips matra, and runs the extra clipping
> code only when flags such as ben, hin, ban etc are used.
> I diffed it against the svn checked out copy today.

Sorry, I made some stupid mistakes in creating that patch. Here is the patch
again diffed against rev 193.
I hope this works.

>
>
> --
> BE INTELLIGENT, USE LINUX
> http://lug.nitdgp.ac.in
> http://mukti09.in
> http://planet-india.randomink.org
>
>
>


-- 
BE INTELLIGENT, USE LINUX
http://lug.nitdgp.ac.in
http://mukti09.in
http://planet-india.randomink.org

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"tesseract-ocr" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/tesseract-ocr?hl=en
-~----------~----~----~----~------~----~------~--~---

diff -u tesseract-ocr-read-only/ccmain//baseapi.cpp tesseract-ocr-cvs1/ccmain//baseapi.cpp
--- tesseract-ocr-read-only/ccmain//baseapi.cpp	2008-11-12 17:07:07.000000000 +0530
+++ tesseract-ocr-cvs1/ccmain//baseapi.cpp	2008-11-12 17:43:00.000000000 +0530
@@ -18,7 +18,10 @@
  **********************************************************************/
 
 #include "baseapi.h"
+#include <iostream>
+#include <math.h>
 
+using namespace std;
 
 // Include automatically generated configuration file if running autoconf.
 #ifdef HAVE_CONFIG_H
@@ -393,6 +396,267 @@
   if (omega0_out != NULL) *omega0_out = best_omega_0;
   return best_t;
 }
+////////////DEBAYAN//Deskew begins//////////////////////
+void deskew(float angle,int srcheight, int srcwidth)
+{
+//angle=4;        //45° for example 
+IMAGE tempimage;
+
+
+IMAGELINE line;
+//Convert degrees to radians 
+float radians=(2*3.1416*angle)/360; 
+
+float cosine=(float)cos(radians); 
+float sine=(float)sin(radians); 
+
+float Point1x=(srcheight*sine); 
+float Point1y=(srcheight*cosine); 
+float Point2x=(srcwidth*cosine-srcheight*sine); 
+float Point2y=(srcheight*cosine+srcwidth*sine); 
+float Point3x=(srcwidth*cosine); 
+float Point3y=(srcwidth*sine); 
+
+float minx=min(0,min(Point1x,min(Point2x,Point3x))); 
+float miny=min(0,min(Point1y,min(Point2y,Point3y))); 
+float maxx=max(Point1x,max(Point2x,Point3x)); 
+float maxy=max(Point1y,max(Point2y,Point3y)); 
+
+int DestWidth=(int)ceil(fabs(maxx)-minx); 
+int DestHeight=(int)ceil(fabs(maxy)-miny); 
+
+tempimage.create(DestWidth,DestHeight,1);
+line.init(DestWidth);
+
+for(int i=0;i<DestWidth;i++){ //A white line of length=DestWidth
+line.pixels[i]=1;
+}
+
+for(int y=0;y<DestHeight;y++){ //Fill the Destination image with white, else clipmatra wont work
+tempimage.put_line(0,y,DestWidth,&line,0);
+}
+line.init(DestWidth);
+
+
+
+for(int y=0;y<DestHeight;y++) //Start filling the destination image pixels with corresponding source image pixels
+{ 
+  for(int x=0;x<DestWidth;x++) 
+  { 
+    int Srcx=(int)((x+minx)*cosine+(y+miny)*sine); 
+    int Srcy=(int)((y+miny)*cosine-(x+minx)*sine); 
+    if(Srcx>=0&&Srcx<srcwidth&&Srcy>=0&& 
+         Srcy<srcheight) 
+    { 
+      line.pixels[x]= 
+          page_image.pixel(Srcx,Srcy); 
+    } 
+  } 
+   tempimage.put_line(0,y,DestWidth,&line,0);	
+} 
+ 
+tempimage.write("tempimage.tif");
+page_image=tempimage;//Copy deskewed image to global page image, so it can be worked on further
+tempimage.destroy(); 
+page_image.write("page_image.tif");
+
+}
+/////////////DEBAYAN//Deskew ends/////////////////////
+
+////////////DEBAYAN//Find skew begins/////////////////
+float findskew(int height, int width)
+{
+int topx=0,topy=0,sign,count=0,offset=1,ifcounter=0;
+float slope=-999,avg=0;
+IMAGELINE line;
+line.init(1);
+line.pixels[0]=0;
+///////Find the top most point of the page: begins///////////
+for(int y=height-1;y>0;y--){  
+  for(int x=width-1;x>0;x--){
+    if(page_image.pixel(x,y)==0){
+      topx=x;topy=y;
+      break;
+    }
+    
+  }  
+  
+  if(topx>0){break;};     
+}
+///////Find the top most point of the page: ends///////////
+
+
+///////To find pages with no skew: begins//////////////
+int c1,c2=0;
+for(int x=1;x<.25*width;x++){
+  while(page_image.pixel((width/2)+x,c1++)==1){ }
+  while(page_image.pixel((width/2)-x,c2++)==1){ }
+  if(c1==c2){cout<<"0 ANGLE\n";return (0);}
+  c1=c2=0;
+}
+///////To find pages with no skew: ends//////////////
+
+cout<<"width="<<width;
+if(topx>0 && topx<.5*width){
+  sign=1;
+}
+if(topx>0 && topx>.5*width){
+  sign=-1;
+}
+
+
+if(sign==-1){
+  while((topx-offset)>width/2){  
+    while(page_image.pixel(topx-offset,topy-count)==1){
+    //page_image.put_line(topx-offset,topy-count,1,&line,0);
+    count++;
+    }
+    
+    if((180/3.142)*atan((float)count/offset)<10){
+    slope=(float)count/offset;
+    ifcounter++;
+    avg=(avg+slope);
+    }
+    count=0;
+    offset++;
+  }
+    avg=(float)avg/ifcounter;
+    //cout<<"avg="<<avg<<"\n";
+    page_image.write("findskew.tif");
+    //cout<<"(180/3.142)*atan((float)(count/offset)="<<(180/3.142)*atan(avg)<<"\n";
+    return (sign*(180/3.142)*atan(avg));
+
+}
+if(sign==1){
+  while((topx+offset)<width/2){  
+    while(page_image.pixel(topx+offset,topy-count)==1){
+    //page_image.put_line(topx+offset,topy-count,1,&line,0);
+    count++;
+    }
+    
+    if((180/3.142)*atan((float)count/offset)<10){
+    slope=(float)count/offset;
+    ifcounter++;
+    avg=(avg+slope);
+    }
+    count=0;
+    offset++;
+  }
+    avg=(float)avg/ifcounter;
+    //cout<<"avg="<<avg<<"\n";
+    page_image.write("findskew.tif");
+    //cout<<"(180/3.142)*atan((float)(count/offset)="<<(180/3.142)*atan(avg)<<"\n";
+    return (sign*(180/3.142)*atan(avg));
+
+}
+
+if(sign==0)
+{return 0;}
+cout<<"SHIT";
+return (0);
+}
+////////////DEBAYAN//Find skew ends///////////////////
+
+//Works on the global image page containing devnagri script.
+//Clips the maatraas and then makes the global image ready for the Tesseract engine.
+//Will be executed for all images during training, but during normal operation, will be
+//used only if the language belongs to devnagri, eg, ben, hin etc.
+void TessBaseAPI::ClipMaatraa(int height, int width)
+{
+IMAGELINE line;
+line.init(width);
+int count,count1=0,blackpixels[height-1][2],arr_row=0,maxbp=0,maxy=0,matras[100][3],char_height;
+//cout<<"Connected Script="<<connected_script<<"\n";
+	
+	for(int y=0; y<height-1;y++){
+	  count=0;	  
+	  for(int x=0;x<width-1;x++){
+            if(page_image.pixel(x,y)==0)
+	      {count++;}
+          }
+          
+	  if(count>=.05*width){
+	    
+            blackpixels[arr_row][0]=y;
+            blackpixels[arr_row][1]=count;
+	    arr_row++;
+	  }
+	}
+	blackpixels[arr_row][0]=blackpixels[arr_row][1]='\0';
+	
+	for(int x=0;x<width-1;x++){  //Black Line
+              line.pixels[x]=0;
+        }
+
+	////////////line_through_matra() begins//////////////////////
+	count=1; 
+	//cout<<"\nHeight="<<height<<" arr_row="<<arr_row<<"\n";
+	char_height=blackpixels[0][0]; //max character height per sentence
+	//cout<<"Char Height Init="<<char_height;
+	while(count<=arr_row){
+          //if(count==0){max=blackpixels[count][0];}
+	  if((blackpixels[count][0]-blackpixels[count-1][0]==1) && (blackpixels[count][1]>=maxbp)){
+            maxbp=blackpixels[count][1];
+	    maxy=blackpixels[count][0];
+	    //cout<<"\nMax="<<maxy<<" bpc="<<maxbp;
+	  }
+          
+          if((blackpixels[count][0]-blackpixels[count-1][0])!=1){
+            /////////////drawline(max)//////////////////////
+            
+        //      cout<<"\nmax="<<maxy<<" bpc="<<maxbp;
+	//      page_image.put_line(0,maxy,width,&line,0);
+
+	      char_height=blackpixels[count-1][0]-char_height;
+              matras[count1][0]=maxy; matras[count1][1]=maxbp; matras[count1][2]=char_height; count1++;
+	      char_height=blackpixels[count][0];
+	      
+            //////////// drawline(max)/////////////////////
+            maxbp=blackpixels[count][1];
+          } 
+	  count++;
+        }
+	matras[count1][0]=matras[count1][1]=matras[count1][2]='\0';
+	
+	//delete blackpixels;	
+	////////////line_through_matra() ends//////////////////////
+        
+        ////////////clip_matras() begins///////////////////////////
+        for(int i=0;i<100;i++){ //where 100=max number of sentences per page
+	  if(matras[i][0]=='\0'){break;}
+	  //cout<<"\nY="<<matras[i][0]<<" bpc="<<matras[i][1]<<" chheight="<<matras[i][2];
+	  count=i;
+	}
+	
+	for(int i=0;i<=count;i++){
+	  
+	  for(int x=0;x<width-1;x++){
+	    if(page_image.pixel(x,matras[i][0])==0){
+ 	      count1=0;	    
+	      for(int y=0;y<matras[i][2];y++){
+  	        if(page_image.pixel(x,matras[i][0]-y)==1){count1++;
+                }
+	       }
+	      //cout<<"\nWPR @ "<<x<<","<<matras[i][0]<<"="<<count1;  
+	      if(count1>.8*matras[i][2]){
+	        line.init(matras[i][2]+5);
+	        for(int j=0;j<matras[i][2]+5;j++){line.pixels[j]=1;}
+	        page_image.put_column(x,matras[i][0]-matras[i][2],matras[i][2]+5,&line,0);
+	      }
+	    }  
+ 	  }
+	  
+	}
+	
+page_image.write("bentest.tif");
+
+	////////////clip_matras() ends/////////////////////////////
+
+/////////DEBAYAN/////////////////
+
+
+}
+
 
 // Threshold the given grey or color image into the tesseract global
 // image ready for recognition. Requires thresholds and hi_value
@@ -404,9 +668,11 @@
                                 int width, int height,
                                 const int* thresholds,
                                 const int* hi_values) {
+
   IMAGELINE line;
   page_image.create(width, height, 1);
   line.init(width);
+  
   // For each line in the image, fill the IMAGELINE class and put it into the
   // Tesseract global page_image. Note that Tesseract stores images with the
   // bottom at y=0 and 0 is black, so we need 2 kinds of inversion.
@@ -427,8 +693,14 @@
     page_image.put_line(0, y, width, &line, 0);
     data += bytes_per_line;
   }
+page_image.write("benth.tif");
+float angle=findskew(height,width);
+//cout<<"SKEW ANGLE="<<angle<<"\n";
+if(angle!=0){
+deskew(angle,height,width);
+}
+ClipMaatraa(height,width);
 }
-
 // Cut out the requested rectangle of the binary image to the
 // tesseract global image ready for recognition.
 void TessBaseAPI::CopyBinaryRect(const unsigned char* imagedata,
Only in tesseract-ocr-cvs1/ccmain/: baseapi.cpp~
diff -u tesseract-ocr-read-only/ccmain//baseapi.h tesseract-ocr-cvs1/ccmain//baseapi.h
--- tesseract-ocr-read-only/ccmain//baseapi.h	2008-11-12 17:07:07.000000000 +0530
+++ tesseract-ocr-cvs1/ccmain//baseapi.h	2008-11-12 17:34:29.000000000 +0530
@@ -170,6 +170,13 @@
                             int left, int top, int right, int bottom,
                             int* histogram);
 
+  //Works on the global image page containing devnagri script.
+  //Clips the maatraas and then makes the global image ready for the Tesseract engine.
+  //Will be executed for all images during training, but during normal operation, will be
+  //used only if the language belongs to devnagri, eg, ben, hin etc.
+  static void ClipMaatraa(int height,
+	                  int width);
+
   // Threshold the given grey or color image into the tesseract global
   // image ready for recognition. Requires thresholds and hi_value
   // produced by OtsuThreshold above.
Only in tesseract-ocr-cvs1/ccmain/: baseapi.h~
Only in tesseract-ocr-cvs1/ccmain/: .deps
Common subdirectories: tesseract-ocr-read-only/ccmain//.svn and tesseract-ocr-cvs1/ccmain//.svn
Common subdirectories: tesseract-ocr-read-only/ccmain//temp and tesseract-ocr-cvs1/ccmain//temp
diff -u tesseract-ocr-read-only/ccmain//tesseractmain.cpp tesseract-ocr-cvs1/ccmain//tesseractmain.cpp
--- tesseract-ocr-read-only/ccmain//tesseractmain.cpp	2008-11-12 17:07:07.000000000 +0530
+++ tesseract-ocr-cvs1/ccmain//tesseractmain.cpp	2008-11-12 17:43:25.000000000 +0530
@@ -37,6 +37,10 @@
 #include "tfacep.h"
 #include "callnet.h"
 
+#include <iostream>
+
+using namespace std;
+
 /*
 ** Include automatically generated configuration file if running autoconf
 */
@@ -74,6 +78,7 @@
 const int kMaxIntSize = 22;
 const ERRCODE USAGE = "Usage";
 char szAppName[] = "Tessedit";   //app name
+bool connected_script=false; //whether language is connected script, eg: hindi, bengali etc
 
 void TesseractImage(const char* input_file, IMAGE* image, STRING* text_out) {
   int bytes_per_line = check_legal_image_size(image->get_xsize(),
@@ -156,6 +161,12 @@
     lang = argv[4];
     arg = 5;
   }
+
+   if(strcmp(lang,"ben")==0 || strcmp(lang,"hin")==0 || strcmp(lang,"asm")==0 || 
+     strcmp(lang,"guj")==0 || strcmp(lang,"pan")==0 || strcmp(lang,"ori")==0 || strcmp(lang,"ban")==0){
+  connected_script=true;
+  cout<<"Connected Script Found!!\n";
+  }
   // Find the basename of the input file.
   STRING infile(argv[1]);
   const char* lastdot = strrchr(argv[1], '.');
Only in tesseract-ocr-cvs1/ccmain/: tesseractmain.cpp~

Reply via email to