Package jjil.j2se.ocr

Source Code of jjil.j2se.ocr.PrecomputeMath

/*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU Lesser General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU Lesser General Public License for more details.
*  You should have received a copy of the Lesser GNU General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package jjil.j2se.ocr;

import java.io.Serializable;
import java.nio.ByteBuffer;

import jjil.core.Vec2;
import jjil.j2se.algorithm.Pair;

// TODO: Auto-generated Javadoc
/**
* The Class PrecomputeMath.
*
* @author webb
*/
public class PrecomputeMath implements Serializable {
   
    /** The Constant serialVersionUID. */
  private static final long serialVersionUID = -2926944121519385162L;
 
  /** The Constant ATAN_TABLE_SIZE. */
  private static final int ATAN_TABLE_SIZE = 64;
   
    /** The Constant RESULT_TABLE_REDUCTION. */
    private static final int RESULT_TABLE_REDUCTION = 4;
   
    /** The Constant RadiusGyrMaxExp. */
    private static final short RadiusGyrMaxExp = 8;
   
    /** The Constant RadiusGyrMaxMan. */
    private static final short RadiusGyrMaxMan = 158;
   
    /** The Constant RadiusGyrMinExp. */
    private static final short RadiusGyrMinExp = 0;
   
    /** The Constant RadiusGyrMinMan. */
    private static final short RadiusGyrMinMan = 255;
   
    /** The Constant SE_TABLE_SIZE. */
    private static final int SE_TABLE_SIZE = 512;
   
    /** The Constant SimilarityCenter. */
    private static final double SimilarityCenter = 0.0075;
   
    /** The Constant SE_TABLE_BITS. */
    private static final int SE_TABLE_BITS = 9;
   
    /** The rpr result. */
    private int rprResult[][][];
   
    /** The Atan table. */
    private short AtanTable[];
   
    /** The Similarity evidence table. */
    public short SimilarityEvidenceTable[];
   
    /**
     * Instantiates a new precompute math.
     */
    public PrecomputeMath() {
     
    }

    /**
     * Instantiates a new precompute math.
     *
     * @param bb the bb
     */
    public PrecomputeMath(ByteBuffer bb) {
    };
   
//    public void initFromByteBuffer() {
//    rprResult = new int[32][64][64];
//    int nPos = 0;
//       for (int i=0; i<rprResult.length; i++) {
//         rprResult[i] = new IntBuffer[64];
//        for (int j=0; j<rprResult[i].length; j++) {
//          this.mbb.position(nPos);
//          this.mbb.limit(nPos += 64*Integer.SIZE/Byte.SIZE);
//          rprResult[i][j] = this.mbb.slice().asIntBuffer();
//        }
//      }
//       this.mbb.position(nPos);
//       this.mbb.limit(nPos += ATAN_TABLE_SIZE*Short.SIZE/Byte.SIZE);
//       AtanTable = this.mbb.slice().asShortBuffer();
//      this.mbb.position(nPos);
//      this.mbb.limit(nPos += SE_TABLE_SIZE*Short.SIZE/Byte.SIZE);
//      SimilarityEvidenceTable = this.mbb.slice().asShortBuffer();
//    }
   
    /**
* Inits the from math.
*/
public void InitFromMath() {
        this.rprResult = new int[32/RESULT_TABLE_REDUCTION][64][64];
for (int i=0; i<32; i+=RESULT_TABLE_REDUCTION) {
            for (int j=0; j<64; j++) {
//              this.rprResult[i][j] = IntBuffer.allocate(64);
                for (int k=0; k<64; k++) {
                    Vec2 sqrtX = MySqrt2(i<<2, j<<13);
                    Vec2 sqrtY = MySqrt2(i<<2, k<<13);
                    this.rprResult[i/RESULT_TABLE_REDUCTION][j][k] =
                            PairVec2Int(ClipRadius(sqrtX, sqrtY));
//                    this.rprResult[i][j][k] =
//                            ClipRadius(sqrtX, sqrtY);
                }
            }
        }       
//        AtanTable = ShortBuffer.allocate(ATAN_TABLE_SIZE);
        AtanTable = new short[ATAN_TABLE_SIZE];
        for (int i = 0; i < ATAN_TABLE_SIZE; i++) {
            AtanTable[i] =
              (short) (Math.atan ((i / (float) ATAN_TABLE_SIZE)) * 128.0 /
                Math.PI + 0.5);
        }
        /* Initialize table for evidence to similarity lookup */
        SimilarityEvidenceTable = new short[SE_TABLE_SIZE];
        for (int i = 0; i < SE_TABLE_SIZE; i++) {
            int IntSimilarity = i << (27 - SE_TABLE_BITS);
            double Similarity = ((double) IntSimilarity) / 65536.0 / 65536.0;
            double Evidence = Similarity / SimilarityCenter;
            Evidence *= Evidence;
            Evidence += 1.0;
            Evidence = 1.0 / Evidence;
            Evidence *= 255.0;

            SimilarityEvidenceTable[i] = (short) (Evidence + 0.5);
        }
    }
   
    /**
     * Gets the result.
     *
     * @param nBLFeat the n bl feat
     * @param nX the n x
     * @param nY the n y
     *
     * @return the result
     */
    public Pair<Vec2,Vec2> getResult(int nBLFeat, int nX, int nY) {
        nBLFeat = Math.max(0, Math.min(31, nBLFeat>>2));
        nX = Math.max(0, Math.min(63, nX>>13));
        nY = Math.max(0, Math.min(63, nY>>13));
        Pair<Vec2,Vec2> pvvResult = Int2PairVec(this.rprResult[nBLFeat/RESULT_TABLE_REDUCTION][nX][nY]);
//        Pair<Vec2,Vec2> pvvResult = this.rprResult[nBLFeat][nX][nY];       
         return pvvResult;
    }
   
    /**
     * Clip radius.
     *
     * @param Rx the rx
     * @param Ry the ry
     *
     * @return the pair< vec2, vec2>
     */
    private static Pair<Vec2, Vec2> ClipRadius(Vec2 Rx, Vec2 Ry) {
        int RxInvLarge, RyInvSmall;

        short AM = RadiusGyrMinMan;
        short AE = RadiusGyrMinExp;
        short BM = (short) Rx.getX();
        short BE = (short) Rx.getY();
        short LastCarry = 1;
        short BitN;
        while ((AM != 0) || (BM != 0)) {
            if (AE > BE) {
                BitN = (short) (LastCarry + (AM & 1) + 1);
                AM >>= 1;
                AE = (short) ((AE==0)?255:AE-1);
            } else if (AE < BE) {
                BitN = (short) (LastCarry + ((~(BM & 1))&1));
                BM >>= 1;
                BE = (short) ((BE==0)?255:BE-1);
            } else {                       /* AE == BE */
                BitN = (short) (LastCarry + (AM & 1) + ((~(BM & 1))&1));
                AM >>= 1;
                BM >>= 1;
                AE = (short) ((AE==0)?255:AE-1);
                BE = (short) ((BE==0)?255:BE-1);
            }
            LastCarry = (short) ((BitN & 2) > 1? 1: 0);
            BitN = (short) (BitN & 1);
        }
        BitN = (short) (LastCarry + 1);
        LastCarry = (short) ((BitN & 2) > 1? 1: 0);
        BitN = (short) (BitN & 1);

        if (BitN == 1) {
            Rx = new Vec2(RadiusGyrMinMan, RadiusGyrMinExp);
        }

        AM = RadiusGyrMinMan;
        AE = RadiusGyrMinExp;
        BM = (short) Ry.getX();
        BE = (short) Ry.getY();
        LastCarry = 1;
        while ((AM != 0) || (BM != 0)) {
            if (AE > BE) {
                BitN = (short) (LastCarry + (AM & 1) + 1);
                AM >>= 1;
                AE = (short) ((AE==0)?255:AE-1);
            } else if (AE < BE) {
                BitN = (short) (LastCarry + ((~(BM & 1))&1));
                BM >>= 1;
                BE = (short) ((BE==0)?255:BE-1);
            } else {                       /* AE == BE */
                BitN = (short) (LastCarry + (AM & 1) + ((~(BM & 1))&1));
                AM >>= 1;
                BM >>= 1;
                AE = (short) ((AE==0)?255:AE-1);
                BE = (short) ((BE==0)?255:BE-1);
            }
            LastCarry = (short) ((BitN & 2) > 1? 1: 0);
            BitN = (short) (BitN & 1);
        }
        BitN = (short) (LastCarry + 1);
        LastCarry = (short) ((BitN & 2) > 1? 1 : 0);
        BitN = (short) (BitN & 1);

        if (BitN == 1) {
            Ry = new Vec2(RadiusGyrMinMan, RadiusGyrMinExp);
        }

        AM = RadiusGyrMaxMan;
        AE = RadiusGyrMaxExp;
        BM = (short) Rx.getX();
        BE = (short) Rx.getY();
        LastCarry = 1;
        while ((AM != 0) || (BM != 0)) {
            if (AE > BE) {
                BitN = (short) (LastCarry + (AM & 1) + 1);
                AM >>= 1;
                AE = (short) ((AE==0)?255:AE-1);
            } else if (AE < BE) {
                BitN = (short) (LastCarry + ((~(BM & 1))&1));
                BM >>= 1;
                BE = (short) ((BE==0)?255:BE-1);
            } else {                       /* AE == BE */
                BitN = (short) (LastCarry + (AM & 1) + ((~(BM & 1))&1));
                AM >>= 1;
                BM >>= 1;
                AE = (short) ((AE==0)?255:AE-1);
                BE = (short) ((BE==0)?255:BE-1);
            }
            LastCarry = (short) ((BitN & 2) > 1? 1 : 0);
            BitN = (short) (BitN & 1);
        }
        BitN = (short) (LastCarry + 1);
        LastCarry = (short) ((BitN & 2) > 1? 1 : 0);
        BitN = (short) (BitN & 1);

        if (BitN == 1) {
            RxInvLarge = 1;
        } else {
            RxInvLarge = 0;
        }
        AM = (short) Ry.getX();
        AE = (short) Ry.getY();
        BM = RadiusGyrMaxMan;
        BE = RadiusGyrMaxExp;
        LastCarry = 1;
        while ((AM != 0) || (BM != 0)) {
            if (AE > BE) {
                BitN = (short) (LastCarry + (AM & 1) + 1);
                AM >>= 1;
                AE = (short) ((AE==0)?255:AE-1);
            } else if (AE < BE) {
                BitN = (short) (LastCarry + ((~(BM & 1))&1));
                BM >>= 1;
                BE = (short) ((BE==0)?255:BE-1);
            } else {                       /* AE == BE */
                BitN = (short) (LastCarry + (AM & 1) + ((~(BM & 1))&1));
                AM >>= 1;
                BM >>= 1;
                AE = (short) ((AE==0)?255:AE-1);
                BE = (short) ((BE==0)?255:BE-1);
            }
            LastCarry = (short) ((BitN & 2) > 1? 1 : 0);
            BitN = (short) (BitN & 1);
        }
        BitN = (short) (LastCarry + 1);
        LastCarry = (short) ((BitN & 2) > 1? 1 : 0);
        BitN = (short) (BitN & 1);

        if (BitN == 1) {
            RyInvSmall = 1;
        } else {
            RyInvSmall = 0;
        }
        if (RxInvLarge != 0 && RyInvSmall != 0) {
            Ry = new Vec2(RadiusGyrMaxMan, RadiusGyrMaxExp);
        }
        return new Pair(Rx, Ry);
    }
   
    /**
     * My sqrt2.
     *
     * @param N the n
     * @param I the i
     *
     * @return the vec2
     */
    private static Vec2 MySqrt2(int N, int I) {
        if (N == 0 || I == 0) {
            return new Vec2(0,0);
        }
        long N2 = N * 41943;

        short k = 9;
        while ((N2 & 0xc0000000) == 0) {
            N2 <<= 2;
            k += 1;
        }

        while ((I & 0xc0000000) == 0) {
            I <<= 2;
            k -= 1;
        }

        if (((N2 & 0x80000000) == 0) && ((I & 0x80000000) == 0)) {
            N2 <<= 1;
            I <<= 1;
        }

        N2 &= 0xffff0000;
        I >>>= 14;
        int Ratio = (int) (N2 / I);

        short BitLocation = 128;
        int SqRoot = 0;
        do {
            int Square = (SqRoot | BitLocation) * (SqRoot | BitLocation);
            if (Square <= Ratio) {
                SqRoot |= BitLocation;
            }
            BitLocation >>>= 1;
        } while (BitLocation != 0);

        if (k < 0) {
            return new Vec2(255, 0);
        } else {
            return new Vec2(SqRoot, k);
        }
    }

    /**
     * Table lookup.
     *
     * @param v the v
     *
     * @return the short
     */
    public short TableLookup(Vec2 v) {
      int X = v.getX();
      int Y = v.getY();
      assert ((X != 0) || (Y != 0));
      int AbsX = Math.abs(X);
      int AbsY = Math.abs(Y);

      int Ratio;
      if (AbsX > AbsY)
        Ratio = Math.min(ATAN_TABLE_SIZE-1, AbsY * ATAN_TABLE_SIZE / AbsX);
      else
        Ratio = Math.min(ATAN_TABLE_SIZE-1, AbsX * ATAN_TABLE_SIZE / AbsY);

      int Angle = this.AtanTable[Ratio];
      int nBits = ((X >= 0)? 4:0) + ((Y >= 0)? 2: 0) + ((AbsX > AbsY)? 1:0);
      switch (nBits) {
          case 0: // X < 0, Y < 0, AbsX <= AbsY
              Angle = 192 - Angle;
              break;
          case 1: // X < 0, Y < 0, AbsX > AbsY
              Angle = 128 + Angle;
              break;
          case 2: // X < 0, Y >= 0, AbsX <= AbsY
              Angle = 64 + Angle;
              break;
          case 3: // X < 0, Y >= 0, AbsX > AbsY
              Angle = 128 - Angle;
              break;
          case 4: // X >= 0, Y < 0, AbsX <= AbsY
              Angle = 192 + Angle;
              break;
          case 5: // X >= 0, Y < 0, AbsX > AbsY
              Angle = 256 - Angle;
              break;
          case 6: // X >= 0, Y >= 0, AbsX <= AbsY
              Angle = 64 - Angle;
              break;
          case 7: // X >= 0, Y >= 0, AbsX > AbsY
              break;
      }

      /* reverse angles to match old feature extractor:   Angle += PI */
      Angle += 128;
      Angle &= 255;
      return (short) Angle;
    }
   
    /**
     * Int2 pair vec.
     *
     * @param l the l
     *
     * @return the pair< vec2, vec2>
     */
    private Pair<Vec2,Vec2> Int2PairVec(int l) {
        short s1 = (short) ((l >>> 24));
        short s2 = (short) (((l << 8) >>> 24));
        short s3 = (short) (((l << 16) >>> 24));
        short s4 = (short) (((l << 24) >>> 24));
        return new Pair<Vec2,Vec2>(new Vec2(s1,s2), new Vec2(s3,s4));
    }

    /**
     * Pair vec2 int.
     *
     * @param pvv the pvv
     *
     * @return the int
     */
    private int PairVec2Int(Pair<Vec2,Vec2> pvv) {
        int s1 = pvv.getFirst().getX();
        int s2 = pvv.getFirst().getY();
        int s3 = pvv.getSecond().getX();
        int s4 = pvv.getSecond().getY();
        assert s1 >= 0 && s2 <= 255 &&
                s2 >= 0 && s2 <= 255 &&
                s3 >= 0 && s3 <= 255 &&
                s4 >= 0 && s4 <= 255;
        return ((int)s1 << 24) | ((int)s2 << 16) | ((int)s3 << 8) | (int)s4;
    }
   
//  @Override
//  public void readExternal(ObjectInput oi) throws IOException,
//      ClassNotFoundException {
//    rprResult = new IntBuffer[32][];
//    int nPos = 0;
//       for (int i=0; i<rprResult.length; i++) {
//         rprResult[i] = new IntBuffer[64];
//        for (int j=0; j<rprResult[i].length; j++) {
//          this.mbb.position(nPos);
//          this.mbb.limit(nPos += 64*Integer.SIZE/Byte.SIZE);
//          rprResult[i][j] = this.mbb.slice().asIntBuffer();
//          for (int k=0; k<rprResult[i][j].capacity(); k++) {
//            rprResult[i][j].put(k, oi.readInt());
//          }
//        }
//      }
//       this.mbb.position(nPos);
//       this.mbb.limit(nPos += ATAN_TABLE_SIZE*Short.SIZE/Byte.SIZE);
//       AtanTable = this.mbb.slice().asShortBuffer();
//      for (int i=0; i<AtanTable.capacity(); i++) {
//        AtanTable.put(i, oi.readShort());
//      }
//      this.mbb.position(nPos);
//      this.mbb.limit(nPos += SE_TABLE_SIZE*Short.SIZE/Byte.SIZE);
//      SimilarityEvidenceTable = this.mbb.slice().asShortBuffer();
//      for (int i=0; i<SimilarityEvidenceTable.capacity(); i++) {
//        SimilarityEvidenceTable.put(i, oi.readShort());
//      }
//   }
//
//  @Override
//  public void writeExternal(ObjectOutput oo) throws IOException {
//       for (int i=0; i<rprResult.length; i++) {
//        for (int j=0; j<rprResult[i].length; j++) {
//          for (int k=0; k<rprResult[i][j].capacity(); k++) {
//            oo.writeInt(rprResult[i][j].get(k));
//          }
//        }
//      }
//      for (int i=0; i<AtanTable.capacity(); i++) {
//        oo.writeShort(AtanTable.get(i));
//      }
//      for (int i=0; i<SimilarityEvidenceTable.capacity(); i++) {
//        oo.writeShort(SimilarityEvidenceTable.get(i));
//      }
//  }
}
TOP

Related Classes of jjil.j2se.ocr.PrecomputeMath

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.