0

I am trying to perform a basic number-only OCR on an image by comparing it to bitmaps of the numbers 0 - 9, using the code below. I have tried to follow the code in the answer to this question, but it is not returning the correct results. There are 2 main issues that I am facing:

1: If the program determines that the number 0 is present at any given point, then it also determines that 1, 2, 3, ... , and 9 are present at that location, which is obviously not true.

2: The locations that it finds numbers in ... most of the locations are blank (white) spaces.

I'll be the first to admit that using the lockbits method is new to me, as I usually use the getPixel() method of comparing, but it was far too slow for this project, so I may be making a rookie mistake or 2.

Thanks for the help!!!

P.S. The image to OCR is RTA, and I believe everything else is self-explanatory.

void newOCR()
    {
        Rectangle rect = new Rectangle(0, 0, 8, 9);
        Rectangle numRect = new Rectangle(0, 0, 8, 9);

        for (int i = 0; i < RTA.Width - 8; i++)
        {
            for (int j = 0; j < RTA.Height - 9; j++)
            {
                rect.Location = new Point(i, j);
                for (int n = 0; n < numbers.Length; n++)
                {
                    System.Drawing.Imaging.BitmapData data = RTA.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, RTA.PixelFormat);
                    System.Drawing.Imaging.BitmapData numData = numbers[n].LockBits(numRect, System.Drawing.Imaging.ImageLockMode.ReadOnly, numbers[n].PixelFormat);

                    unsafe
                    {
                        byte* ptr = (byte*)data.Scan0.ToPointer();
                        byte* numPtr = (byte*)data.Scan0.ToPointer();

                        int width = rect.Width * Image.GetPixelFormatSize(data.PixelFormat) / 8;
                        for(int y = 0; y < rect.Height; y++)
                        {
                            bool outBreak = false;
                            for(int x = 0; x < width; x++)
                            {
                                if(*ptr != *numPtr)
                                {
                                    outBreak = true;
                                    break;
                                }
                                else if(y == rect.Height - 1 && x == width - 1)
                                {
                                    timeDict.Add(new Point(i, j), n);
                                }

                                ptr++;
                                numPtr++;
                            }

                            if(outBreak)
                            {
                                break;
                            }

                            ptr += data.Stride - width;
                            numPtr += numData.Stride - width;
                        }

                        RTA.UnlockBits(data);
                        numbers[n].UnlockBits(numData);
                    }
                }
            }
        }
    }
Community
  • 1
  • 1
BrianH
  • 337
  • 1
  • 6
  • 12
  • Shouldn't this `byte* numPtr = (byte*)data.Scan0.ToPointer();` be `byte* numPtr = (byte*)numData.Scan0.ToPointer();`. Looks like you are comparing bitmap to itself :-) – Ivan Stoev Oct 28 '15 at 18:52
  • @IvanStoev YES! That work's perfectly. See - rookie mistake. If you make that an answer I'll accept it :) Thanks so much! – BrianH Oct 28 '15 at 19:02
  • You welcome. I'm not quite sure if I'm supposed to post such as answer, but since you are asking, I will. – Ivan Stoev Oct 28 '15 at 19:07
  • @IvanStoev It is the answer. It fixed the problem, and I appreciate that. I'm just upset someone down-voted my question LOL – BrianH Oct 28 '15 at 19:13
  • No problem, that's easy fixable :-) Take care, mate. – Ivan Stoev Oct 28 '15 at 19:24

1 Answers1

1

There is a (probably copy/paste) mistake in the following line

byte* numPtr = (byte*)data.Scan0.ToPointer();

which is causing comparing the bitmap to itself. It should be

byte* numPtr = (byte*)numData.Scan0.ToPointer();
Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343