Tuesday, November 6, 2012

OCR Implementation

1) net.sourceforge.javaoc



package net.sourceforge.javaocr;


public interface Image
{

    public abstract int get(int i, int j);

    public abstract void put(int i, int j, int k);

    public abstract int get();

    public abstract void put(int i);

    /**
     * @deprecated Method horizontalSpanEquals is deprecated
     */

    public abstract boolean horizontalSpanEquals(int i, int j, int k, int l);

    /**
     * @deprecated Method verticalSpanEquals is deprecated
     */

    public abstract boolean verticalSpanEquals(int i, int j, int k, int l);

    public abstract int getWidth();

    public abstract int getHeight();

    public abstract int getOriginX();

    public abstract int getOriginY();

    public abstract void iterateH(int i);

    public abstract void iterateH(int i, int j, int k);

    public abstract void iterateV(int i);

    public abstract void iterateV(int i, int j, int k);

    public abstract int next();

    public abstract void next(int i);

    public abstract boolean hasNext();

    public abstract void copy(Image image);

    public abstract void flip(Image image);

    public abstract Image chisel(int i, int j, int k, int l);

    public abstract Image row(int i);

    public abstract Image column(int i);

    public abstract float getAspectRatio();
}


package net.sourceforge.javaocr;


// Referenced classes of package net.sourceforge.javaocr:
//            Image

public interface ImageFilter
{

    public abstract void process(Image image);
}


2) net.sourceforge.javaocr.cluster

package net.sourceforge.javaocr.cluster;

import net.sourceforge.javaocr.Image;

public interface FeatureExtractor
{

    public abstract int getSize();

    public abstract double[] extract(Image image);
}


3)  net.sourceforge.javaocr.ocr


package net.sourceforge.javaocr.ocr;

import net.sourceforge.javaocr.Image;

public abstract class AbstractLinearImage
    implements Image
{

    protected AbstractLinearImage(int arrayWidth, int arrayHeight)
    {
        this(arrayWidth, arrayHeight, 0, 0, arrayWidth, arrayHeight);
    }

    protected AbstractLinearImage(int arrayWidth, int arrayHeight, int originX, int originY, int width, int height)
    {
        this.height = height;
        this.width = width;
        this.arrayHeight = arrayHeight;
        this.originX = originX;
        this.originY = originY;
        this.arrayWidth = arrayWidth;
        aspectRatio = (float)width / (float)height;
    }

    public abstract int get();

    public abstract void put(int i);

    public int get(int x, int y)
    {
        setCurrentIndex(x, y);
        return get();
    }

    protected void setCurrentIndex(int x, int y)
    {
        currentIndex = (y + originY) * arrayWidth + x + originX;
    }

    public void put(int x, int y, int value)
    {
        setCurrentIndex(x, y);
        put(value);
    }

    public int getArrayHeight()
    {
        return arrayHeight;
    }

    public int getArrayWidth()
    {
        return arrayWidth;
    }

    public float getAspectRatio()
    {
        return aspectRatio;
    }

    public int getHeight()
    {
        return height;
    }

    public int getWidth()
    {
        return width;
    }

    public int getOriginX()
    {
        return originX;
    }

    public int getOriginY()
    {
        return originY;
    }

    public boolean horizontalSpanEquals(int y, int from, int to, int value)
    {
        iterateH(y, from, to);
        while(hasNext()) 
            if(next() != value)
                return false;
        return true;
    }

    public boolean verticalSpanEquals(int x, int from, int to, int value)
    {
        iterateV(x, from, to);
        while(hasNext()) 
            if(next() != value)
                return false;
        return true;
    }

    public void iterateV(int x, int from, int to)
    {
        currentIndex = ((from + originY) - 1) * arrayWidth + x + originX;
        border = (to + originY) * arrayWidth + x + originX;
        step = arrayWidth;
    }

    public void iterateH(int y, int from, int to)
    {
        int base = ((y + originY) * arrayWidth + originX) - 1;
        currentIndex = base + from;
        border = base + to + 1;
        step = 1;
    }

    public void iterateH(int y)
    {
        iterateH(y, 0, width - 1);
    }

    public void iterateV(int x)
    {
        iterateV(x, 0, height - 1);
    }

    public boolean hasNext()
    {
        return currentIndex < border;
    }

    public int next()
    {
        currentIndex += step;
        return get();
    }

    public void next(int pixel)
    {
        currentIndex += step;
        put(pixel);
    }

    public void copy(Image dst)
    {
        int height = getHeight();
        for(int i = 0; i < height; i++)
        {
            iterateH(i);
            dst.iterateH(i);
            for(; hasNext(); dst.next(next()));
        }

    }

    public void flip(Image dst)
    {
        int width = getWidth();
        for(int i = 0; i < width; i++)
        {
            iterateV(i);
            dst.iterateH(i);
            for(; hasNext(); dst.next(next()));
        }

    }

    public String toString()
    {
        return (new StringBuilder()).append("AbstractLinearImage{arrayHeight=").append(arrayHeight).append(", arrayWidth=").append(arrayWidth).append(", aspectRatio=").append(aspectRatio).append(", height=").append(height).append(", originX=").append(originX).append(", originY=").append(originY).append(", width=").append(width).append('}').toString();
    }

    public Image row(int y)
    {
        return chisel(0, y, width, 1);
    }

    public Image column(int x)
    {
        return chisel(x, 0, 1, height);
    }

    protected final int arrayWidth;
    protected final int arrayHeight;
    protected final int originX;
    protected final int originY;
    protected final int width;
    protected final int height;
    protected int currentIndex;
    protected final float aspectRatio;
    int step;
    int border;
}



package net.sourceforge.javaocr.ocr;

import net.sourceforge.javaocr.Image;

// Referenced classes of package net.sourceforge.javaocr.ocr:
//            AbstractLinearImage

public class ByteImage extends AbstractLinearImage
{

    public ByteImage(int width, int height)
    {
        this(new byte[width * height], width, height);
    }

    public ByteImage(byte image[], int width, int height)
    {
        this(image, width, height, 0, 0, width, height);
    }

    public ByteImage(byte image[], int arrayWidth, int arrayHeight, int originX, int originY, int width, int height)
    {
        super(arrayWidth, arrayHeight, originX, originY, width, height);
        this.image = image;
    }

    public int get()
    {
        return image[currentIndex] & 0xff;
    }

    public void put(int value)
    {
        image[currentIndex] = (byte)value;
    }

    public Image chisel(int fromX, int fromY, int width, int height)
    {
        return new ByteImage(image, arrayWidth, arrayHeight, originX + fromX, originY + fromY, width, height);
    }

    public String toString()
    {
        return (new StringBuilder()).append("ByteImage{} ").append(super.toString()).toString();
    }

    byte image[];
}



package net.sourceforge.javaocr.ocr;

import net.sourceforge.javaocr.Image;

// Referenced classes of package net.sourceforge.javaocr.ocr:
//            AbstractLinearImage

public class PixelImage extends AbstractLinearImage
{

    public PixelImage(int width, int height)
    {
        this(new int[width * height], width, height, 0, 0, width, height);
    }

    public PixelImage(int pixels[], int width, int height)
    {
        this(pixels, width, height, 0, 0, width, height);
    }

    public PixelImage(int pixels[], int width, int height, int originX, int originY, int boxW, int boxH)
    {
        super(width, height, originX, originY, boxW, boxH);
        this.pixels = pixels;
    }

    public int get()
    {
        return pixels[currentIndex];
    }

    public void put(int value)
    {
        pixels[currentIndex] = value;
    }

    public Image chisel(int fromX, int fromY, int width, int height)
    {
        return new PixelImage(pixels, arrayWidth, arrayHeight, originX + fromX, originY + fromY, width, height);
    }

    public String toString()
    {
        return (new StringBuilder()).append("PixelImage{} ").append(super.toString()).toString();
    }

    public final int pixels[];
}


4) net.sourceforge.javaocr.plugin.moment


package net.sourceforge.javaocr.plugin.moment;

import net.sourceforge.javaocr.Image;
import net.sourceforge.javaocr.ImageFilter;

public abstract class AbstractMomentFilter
    implements ImageFilter
{

    public AbstractMomentFilter(int p, int q)
    {
        this.p = p;
        this.q = q;
    }

    protected abstract double[] precomputeX(Image image);

    protected abstract double[] precomputeY(Image image);

    public void process(Image image)
    {
        coeffx = precomputeX(image);
        coeffy = precomputeY(image);
        for(int y = 0; y < image.getHeight(); y++)
        {
            image.iterateH(y);
            int x = 0;
            while(image.hasNext()) 
                moment += (double)image.next() * coeffx[x++] * coeffy[y];
        }

    }

    public double getMoment()
    {
        return moment;
    }

    final int p;
    final int q;
    double moment;
    double coeffx[];
    double coeffy[];
}


package net.sourceforge.javaocr.plugin.moment;

import net.sourceforge.javaocr.Image;

// Referenced classes of package net.sourceforge.javaocr.plugin.moment:
//            AbstractMomentFilter

public class CentralMomentFilter extends AbstractMomentFilter
{

    public CentralMomentFilter(int p, int q, double xMean, double yMean)
    {
        super(p, q);
        this.xMean = xMean;
        this.yMean = yMean;
    }

    protected double[] precomputeX(Image image)
    {
        double doubles[] = new double[image.getWidth()];
        for(int i = 0; i < doubles.length; i++)
            doubles[i] = Math.pow((double)i - xMean, p);

        return doubles;
    }

    protected double[] precomputeY(Image image)
    {
        double doubles[] = new double[image.getHeight()];
        for(int i = 0; i < doubles.length; i++)
            doubles[i] = Math.pow((double)i - yMean, q);

        return doubles;
    }

    public double normalise(double m00)
    {
        return getMoment() / Math.pow(m00, (p + q) / 2 + 1);
    }

    double xMean;
    double yMean;
}



package net.sourceforge.javaocr.plugin.moment;

import net.sourceforge.javaocr.Image;
import net.sourceforge.javaocr.cluster.FeatureExtractor;

// Referenced classes of package net.sourceforge.javaocr.plugin.moment:
//            RawMomentFilter, CentralMomentFilter

public class HuMoments
    implements FeatureExtractor
{

    public HuMoments()
    {
    }

    public double[] extract(Image image)
    {
        RawMomentFilter M00 = new RawMomentFilter(0, 0);
        M00.process(image);
        double m00 = M00.getMoment();
        RawMomentFilter M10 = new RawMomentFilter(1, 0);
        M10.process(image);
        double m10 = M10.getMoment();
        RawMomentFilter M01 = new RawMomentFilter(0, 1);
        M01.process(image);
        double m01 = M01.getMoment();
        double xMean = m10 / m00;
        double yMean = m01 / m00;
        CentralMomentFilter N20 = new CentralMomentFilter(2, 0, xMean, yMean);
        CentralMomentFilter N02 = new CentralMomentFilter(0, 2, xMean, yMean);
        N20.process(image);
        double n20 = N20.normalise(m00);
        N02.process(image);
        double n02 = N02.normalise(m00);
        double moments[] = new double[8];
        moments[0] = n20 + n02;
        CentralMomentFilter N11 = new CentralMomentFilter(1, 1, xMean, yMean);
        N11.process(image);
        double n11 = N11.normalise(m00);
        moments[1] = Math.pow(n20 - n02, 2D) + 4D * Math.pow(n11, 2D);
        CentralMomentFilter N30 = new CentralMomentFilter(3, 0, xMean, yMean);
        N30.process(image);
        double n30 = N30.normalise(m00);
        CentralMomentFilter N03 = new CentralMomentFilter(0, 3, xMean, yMean);
        N03.process(image);
        double n03 = N03.normalise(m00);
        CentralMomentFilter N21 = new CentralMomentFilter(2, 1, xMean, yMean);
        N21.process(image);
        double n21 = N21.normalise(m00);
        CentralMomentFilter N12 = new CentralMomentFilter(1, 2, xMean, yMean);
        N12.process(image);
        double n12 = N12.normalise(m00);
        moments[2] = Math.pow(n30 - 3D * n12, 2D) + Math.pow(n03 - 3D * n21, 2D);
        moments[3] = Math.pow(n30 + n12, 2D) + Math.pow(n03 + n21, 2D);
        moments[4] = (n30 - 3D * n12) * (n30 + n12) * (Math.pow(n30 + n12, 2D) - 3D * Math.pow(n21 + n03, 2D)) + (n03 - 3D * n21) * (n03 + n21) * (Math.pow(n03 + n21, 2D) - 3D * Math.pow(n30 + n12, 2D));
        moments[5] = (n20 - n02) * (Math.pow(n30 + n12, 2D) - Math.pow(n21 + n03, 2D)) + 4D * n11 * (n30 + n12) * (n03 + n21);
        moments[6] = (3D * n21 - n03) * (n30 + n12) * (Math.pow(n30 + n12, 2D) - 3D * Math.pow(n21 + n03, 2D)) + (n30 - 3D * n12) * (n21 + n03) * (Math.pow(n03 + n21, 2D) - 3D * Math.pow(n30 + n12, 2D));
        moments[7] = n11 * (Math.pow(n30 + n12, 2D) - Math.pow(n03 + n21, 2D)) - (n20 - n02) * (n30 + n12) * (n03 + n21);
        return moments;
    }

    public int getSize()
    {
        return 8;
    }
}


package net.sourceforge.javaocr.plugin.moment;

import net.sourceforge.javaocr.Image;

// Referenced classes of package net.sourceforge.javaocr.plugin.moment:
//            AbstractMomentFilter

public class RawMomentFilter extends AbstractMomentFilter
{

    public RawMomentFilter(int p, int q)
    {
        super(p, q);
    }

    protected double[] precomputeX(Image image)
    {
        double doubles[] = new double[image.getWidth()];
        for(int i = 0; i < doubles.length; i++)
            doubles[i] = Math.pow(i, p);

        return doubles;
    }

    protected double[] precomputeY(Image image)
    {
        double doubles[] = new double[image.getHeight()];
        for(int i = 0; i < doubles.length; i++)
            doubles[i] = Math.pow(i, q);

        return doubles;
    }
}