First attempt at using tesseract ocr. I am using Tesseract-ocr v3.02 (I know it's old, but didn't see the need to include neural network code) to read the digits found on an image of a Sudoku puzzle.
I am coding in C#, .Net application. I want to read an unfinished Sudoku puzzle from my local newspaper e-edition, and finish it on my laptop screen. Trivial, or so I thought.
Here is an example input image.
I am grabbing each sub-square individually, and processing that to get just one digit at a time.
The code includes an offset to make the sub-square smaller, to eliminate the lined borders around the digits in the image.
Here is my code:
{
string docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
Bitmap img = new Bitmap(Path.Combine(docPath, "SudokuBoard.jpg"));
int i = 1;
int iOffset = 10;
for (int y = 0; y < img.Height - 10; y += img.Height / 9)
{
int j = 0;
for (int x = 0; x < img.Width - 10; x += img.Width / 9)
{
++j;
TesseractEngine engine = new TesseractEngine("./tessdata", "eng", EngineMode.Default);
engine.SetVariable("tessedit_char_whitelist", "123456789");
Rect rectangle = new Rect(x + iOffset, y + iOffset, (img.Width / 9) - (2 + iOffset), (img.Height / 9) - iOffset);
try
{
Page page = engine.Process(img, rectangle, PageSegMode.SingleChar);
Pix pix = page.GetThresholdedImage();
pix.Save(Path.Combine(docPath, "SudokuOcrImg_" + i.ToString() + "," + j.ToString() + ".bmp"), ImageFormat.Bmp);
string strOcrText = page.GetText();
if (page.GetText().Length > 0)
{
if (char.IsDigit(char.Parse(strOcrText.Substring(0,1))))
{
Console.WriteLine(page.GetText().Substring(0, 1));
}
else
{
Console.WriteLine(".");
}
}
else
{
Console.WriteLine(".");
}
}
catch (Exception e)
{
Console.WriteLine("exception");
}
}
++i;
}
I process the entire image one row at a time, 9 cells in each row.
I output a dot where the image has an empty cell.
I'm wondering about the info dumped to the Console in between valid digits.
I highlighted one such info dump in red.
Here is the output to the console:
.
4
.
Bottom=0, top=76, base=0, x=0
Total count=0
Min=0.00 Really=0
Lower quartile=0.00
Median=0.00, ile(0.5)=0.00
Upper quartile=0.00
Max=0.00 Really=0
Range=1
Mean= 0.00
SD= 0.00
.
2
Bottom=0, top=76, base=0, x=0
Total count=0
Min=0.00 Really=0
Lower quartile=0.00
Median=0.00, ile(0.5)=0.00
Upper quartile=0.00
Max=0.00 Really=0
Range=1
Mean= 0.00
SD= 0.00
.
.
.
.
1
6
.
3
5
Bottom=0, top=76, base=0, x=0
Total count=0
Min=0.00 Really=0
Lower quartile=0.00
Median=0.00, ile(0.5)=0.00
Upper quartile=0.00
Max=0.00 Really=0
Range=1
Mean= 0.00
SD= 0.00
.
7
.
.
3 <- this is from a blank sub-square
9
<- this is from a blank sub-square
2
4
7
Bottom=0, top=76, base=0, x=0
Total count=0
Min=0.00 Really=0
Lower quartile=0.00
Median=0.00, ile(0.5)=0.00
Upper quartile=0.00
Max=0.00 Really=0
Range=1
Mean= 0.00
SD= 0.00
.
3
3
<- this is from a blank sub-square
. <- this is missing the value "6"
Bottom=0, top=76, base=0, x=0
Total count=0
Min=0.00 Really=0
Lower quartile=0.00
Median=0.00, ile(0.5)=0.00
Upper quartile=0.00
Max=0.00 Really=0
Range=1
Mean= 0.00
SD= 0.00
.
7
5
.
.
.
.
.
.
<- this is missing value "2"
Bottom=0, top=76, base=0, x=0
Total count=0
Min=0.00 Really=0
Lower quartile=0.00
Median=0.00, ile(0.5)=0.00
Upper quartile=0.00
Max=0.00 Really=0
Range=1
Mean= 0.00
SD= 0.00
.
Bottom=0, top=76, base=0, x=0
Total count=0
Min=0.00 Really=0
Lower quartile=0.00
Median=0.00, ile(0.5)=0.00
Upper quartile=0.00
Max=0.00 Really=0
Range=1
Mean= 0.00
SD= 0.00
.
Bottom=0, top=76, base=0, x=0
Total count=0
Min=0.00 Really=0
Lower quartile=0.00
Median=0.00, ile(0.5)=0.00
Upper quartile=0.00
Max=0.00 Really=0
Range=1
Mean= 0.00
SD= 0.00
.
.
9
.
Bottom=0, top=76, base=0, x=0
Total count=0
Min=0.00 Really=0
Lower quartile=0.00
Median=0.00, ile(0.5)=0.00
Upper quartile=0.00
Max=0.00 Really=0
Range=1
Mean= 0.00
SD= 0.00
.
Bottom=0, top=76, base=0, x=0
Total count=0
Min=0.00 Really=0
Lower quartile=0.00
Median=0.00, ile(0.5)=0.00
Upper quartile=0.00
Max=0.00 Really=0
Range=1
Mean= 0.00
SD= 0.00
.
.
6
Bottom=0, top=76, base=0, x=0
Total count=0
Min=0.00 Really=0
Lower quartile=0.00
Median=0.00, ile(0.5)=0.00
Upper quartile=0.00
Max=0.00 Really=0
Range=1
Mean= 0.00
SD= 0.00
.
Bottom=0, top=76, base=0, x=0
Total count=0
Min=0.00 Really=0
Lower quartile=0.00
Median=0.00, ile(0.5)=0.00
Upper quartile=0.00
Max=0.00 Really=0
Range=1
Mean= 0.00
SD= 0.00
.
.
.
7
<- this is from a blank sub-square
1
4
.
5
7
<- this is from a blank sub-square
9
.
6
3
4
.
.
.
.
1
Bottom=0, top=76, base=0, x=0
Total count=0
Min=0.00 Really=0
Lower quartile=0.00
Median=0.00, ile(0.5)=0.00
Upper quartile=0.00
Max=0.00 Really=0
Range=1
Mean= 0.00
SD= 0.00
.
4
5
.
3
.
<- this is missing the value "9"
.
.
.
Bottom=0, top=76, base=0, x=0
Total count=0
Min=0.00 Really=0
Lower quartile=0.00
Median=0.00, ile(0.5)=0.00
Upper quartile=0.00
Max=0.00 Really=0
Range=1
Mean= 0.00
SD= 0.00
.
1
Bottom=0, top=76, base=0, x=0
Total count=0
Min=0.00 Really=0
Lower quartile=0.00
Median=0.00, ile(0.5)=0.00
Upper quartile=0.00
Max=0.00 Really=0
Range=1
Mean= 0.00
SD= 0.00
.
.
7
.
I am including the pix images of each sub-square that was processed.
there are 81 of them - sorry. Why do some have additional noise?
Looks like I am not getting the center of each sub-square as I thought I was.
<- this 9 doesn't show the bar at the top edge
I hope someone can lead me toward a solution for what seems like such a simple problem.
Thanks,
Mark Bussey