bug-ocrad
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug-ocrad] Re: OCRAD project: library is needed


From: Antonio Diaz Diaz
Subject: [Bug-ocrad] Re: OCRAD project: library is needed
Date: Sun, 11 Jul 2010 14:27:59 +0200
User-agent: Mozilla/5.0 (X11; U; Linux i586; en-US; rv:1.7.11) Gecko/20050905

Hello Dmitry,

Dmitry Katsubo wrote:
I expect that "N" in test cases 1 and 2 is recognized not worse then via
API. Also API recognizes "r" and "t", which may trigger false positives.

Recognition via Blob is giving "better" results because you are cheating, twice. :-)

First, Blob is supposed to represent a "blob of ink", that is, black pixels must be contiguous and must touch the four sides. By adding a white frame you have "enlarged" the Blob, but this can break the code.

Second, you have again "enlarged" the blob in line 107 by using "width, height" instead of "right, bottom". the correct code is:
  Blob* b = new Blob(0, 0, width-1, height-1);

After correcting those two errors (see attached file), Blob and API results are the same. "N"s aren't recognized because they are too small (<10 pixels high), and short, thick slashes are often recognized as "r" or "t".

To solve the problem with the small "N"s, I have just released ocrad-0.20-rc1 which reduces the height limit for "N" to 9 and includes the function "OCRAD_scale". See an example of use in line 152 of the corrected test case attached.
http://download.savannah.gnu.org/releases-noredirect/ocrad/ocrad-0.20-rc1.tar.gz
http://download.savannah.gnu.org/releases-noredirect/ocrad/ocrad-0.20-rc1.tar.lz


When I change to OCRAD_greymap, I get the following result:

This is because in OCRAD_bitmap 0 is white, while in OCRAD_greymap 0 is black. You need to invert the values (see attached file) or pass invert = true to OCRAD_set_image. For a description of map values see ocradlib.h:
   The format for each pixel depends on mode like this:
   OCRAD_bitmap   --> 1 byte  per pixel;  0 = white, 1 = black
   OCRAD_greymap  --> 1 byte  per pixel;  256 level greymap (0 = black)
OCRAD_colormap --> 3 bytes per pixel; 16777216 colors RGB (0,0,0 = black)


Best regards,
Antonio.
#include <iostream>

#include <stdlib.h>
#include <string.h>

#include "ocradlib.h"

// Required by OCRAD, not used here:
#include <vector>
#include <stdio.h>

#include "common.h"
#include "rectangle.h"
#include "bitmap.h"
#include "blob.h"
#include "character.h"

using namespace std;

/* Actual max height is 12, but we leave some more for extensions: */
const char* TESTS[][12] = {
        /* Test1: "N" is not detected */
        {
                "11100001",
                "11110001",
                "11110001",
                "11011001",
                "11011101",
                "11001111",
                "11000111",
                "11000111",
                "11000011",
        },
        /* Test2: "N" is not detected */
        {
                "11000011",
                "11100011",
                "11110011",
                "11110011",
                "10011011",
                "10011111",
                "10001111",
                "10000111",
                "10000111",
        },
        /* Test3: Detected as "r": */
        {
                "000000010",
                "000000111",
                "000001110",
                "000011100",
                "000111000",
                "001111000",
                "011110000",
                "111100000",
                "011000000",
        },
        /* Test4: Detected as "r": */
        {
                "00000011111",
                "00000111100",
                "00011110000",
                "01111100000",
                "11110000000",
                "11000000000",
        },
        /* Test5: Detected as "r": */
        {
                "00111",
                "01110",
                "01110",
                "01110",
                "11100",
                "11100",
                "11100",
                "11000",
                "11000",
        },
        /* Test6: Detected as "t": */
        {
                "00111",
                "00111",
                "00110",
                "01110",
                "01110",
                "01110",
                "11100",
                "11100",
                "11100"
        }
};

char run_test(int n) {
        int height = 0;
        int width = strlen(TESTS[n][0]);

        while (TESTS[n][height] != NULL) {
                height++;
        }

        const char** image = TESTS[n];

        cout << "Test " << n + 1 << ": width x height = " << width << "x" << 
height << endl;

        // Blob for recognition attempt via Character::recognize1():
        Blob* b = new Blob(0, 0, width-1, height-1);

        // OCRAD_Pixmap for recognition attempt via 
OCRAD_result_first_character():
        struct OCRAD_Pixmap* opix = new OCRAD_Pixmap();

        unsigned char* bitmap_data = (unsigned char*) malloc(width * height);
        unsigned char* greymap_data = (unsigned char*) malloc(width * height);

        memset(bitmap_data, 0, width * height);
        memset(greymap_data, 255, width * height);

        opix->height = height;
        opix->width = width;

        opix->mode = OCRAD_bitmap;  opix->data = bitmap_data;
//      opix->mode = OCRAD_greymap; opix->data = greymap_data;

        for (int row = 0; row < height; row++) {
                for (int col = 0; col < width; col++)
                        if (image[row][col] == '1') {
                                b->set_bit(row, col, true);
                                bitmap_data[row * width + col] = 1;
                                greymap_data[row * width + col] = 0;
                        }
                }

        b->find_holes();

        Control control;
        Character a(b);

        // The Blob object was delegated to Character, which will free it on 
destruction:
        b = NULL;

        a.recognize1(control.charset, Rectangle::Rectangle(a.left(), a.top(), 
a.right(), a.bottom()));
        char c1 = a.byte_result();

        // Was the character recognised by OCRAD?
        cout << "+ recognised via Character::recognize1(): " << c1 << endl;

        char c2 = 0;
        OCRAD_Descriptor * const ocrdes = OCRAD_open();

        if (ocrdes && OCRAD_get_errno(ocrdes) == OCRAD_ok &&
            OCRAD_set_image(ocrdes, opix, 0) == 0 &&
            ( height >= 10 || OCRAD_scale( ocrdes, 2 ) == 0 ) &&
            OCRAD_recognize(ocrdes, 0) == 0 )
          c2 = OCRAD_result_first_character(ocrdes);

        OCRAD_close(ocrdes);

        delete opix;
        free(bitmap_data);
        free(greymap_data);

        cout << "+ recognised via OCRAD_result_first_character(): " << c2 << 
endl;
}

int main()
{
        for (unsigned int n = 0; n < 6; n++) {
                run_test(n);
        }
}

reply via email to

[Prev in Thread] Current Thread [Next in Thread]