Search in sources :

Example 61 with Shape

use of com.joliciel.jochre.graphics.Shape in project jochre by urieli.

the class ShapeSequence method getRectangleInGroup.

/**
 * Return the rectangle enclosing this shape sequence in a particular group.
 */
public Rectangle getRectangleInGroup(GroupOfShapes group) {
    boolean haveShapes = false;
    RectangleImpl rectangle = new RectangleImpl(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE);
    for (ShapeInSequence shapeInSequence : this) {
        Shape shape = shapeInSequence.getShape();
        if (shape.getGroup().equals(group)) {
            haveShapes = true;
            if (shape.getLeft() < rectangle.getLeft())
                rectangle.setLeft(shape.getLeft());
            if (shape.getTop() < rectangle.getTop())
                rectangle.setTop(shape.getTop());
            if (shape.getRight() > rectangle.getRight())
                rectangle.setRight(shape.getRight());
            if (shape.getBottom() > rectangle.getBottom())
                rectangle.setBottom(shape.getBottom());
        }
    }
    if (!haveShapes)
        rectangle = null;
    return rectangle;
}
Also used : Shape(com.joliciel.jochre.graphics.Shape) RectangleImpl(com.joliciel.jochre.graphics.RectangleImpl)

Example 62 with Shape

use of com.joliciel.jochre.graphics.Shape in project jochre by urieli.

the class TrainingCorpusShapeSplitter method split.

@Override
public List<ShapeSequence> split(Shape shape) {
    List<ShapeSequence> shapeSequences = new ArrayList<ShapeSequence>();
    ShapeSequence shapeSequence = new ShapeSequence();
    shapeSequences.add(shapeSequence);
    Set<String> nonSplittableLetters = jochreSession.getLinguistics().getDualCharacterLetters();
    String testLetter = shape.getLetter().replace("|", "");
    if (testLetter.length() == 1 || nonSplittableLetters.contains(testLetter)) {
        shapeSequence.addShape(shape);
    } else {
        int lastLeft = 0;
        Comparator<Shape> shapeComparator = null;
        if (jochreSession.getLinguistics().isLeftToRight())
            shapeComparator = new ShapeLeftToRightComparator();
        else
            shapeComparator = new ShapeRightToLeftComparator();
        TreeSet<Shape> splitShapes = new TreeSet<Shape>(shapeComparator);
        for (Split split : shape.getSplits()) {
            Shape newShape = shape.getJochreImage().getShape(shape.getLeft() + lastLeft, shape.getTop(), shape.getLeft() + split.getPosition(), shape.getBottom());
            lastLeft = split.getPosition() + 1;
            splitShapes.add(newShape);
        }
        Shape lastShape = shape.getJochreImage().getShape(shape.getLeft() + lastLeft, shape.getTop(), shape.getRight(), shape.getBottom());
        splitShapes.add(lastShape);
        List<String> splitLetters = new ArrayList<String>();
        char lastChar = 0;
        boolean haveSplitLetter = false;
        for (int i = 0; i < shape.getLetter().length(); i++) {
            char c = shape.getLetter().charAt(i);
            if (c == '|')
                haveSplitLetter = true;
            if (lastChar != 0) {
                String doubleChar = "" + lastChar + c;
                if (nonSplittableLetters.contains(doubleChar)) {
                    splitLetters.add(doubleChar);
                    lastChar = 0;
                } else {
                    splitLetters.add("" + lastChar);
                    lastChar = c;
                }
            } else {
                lastChar = c;
            }
        }
        if (lastChar != 0)
            splitLetters.add("" + lastChar);
        if (splitLetters.size() == 0)
            splitLetters.add("");
        // mean end a split a or start a split b
        if (haveSplitLetter) {
            int i = 0;
            List<String> newSplitLetters = new ArrayList<String>();
            boolean inSplit = false;
            for (String letter : splitLetters) {
                if (letter.equals("|")) {
                    if (i == 1 && i == splitLetters.size() - 2) {
                        // smack in the middle - ambiguous split mark
                        Shape previousShape = null;
                        Shape nextShape = null;
                        String previousLetter = splitLetters.get(0);
                        String nextLetter = splitLetters.get(2);
                        if (shape.getIndex() > 0) {
                            previousShape = shape.getGroup().getShapes().get(shape.getIndex() - 1);
                        }
                        if (shape.getIndex() < shape.getGroup().getShapes().size() - 1) {
                            nextShape = shape.getGroup().getShapes().get(shape.getIndex() + 1);
                        }
                        boolean backwardsSplit = true;
                        if (previousShape != null && previousShape.getLetter().equals("|" + previousLetter)) {
                            backwardsSplit = true;
                        } else if (nextShape != null && nextShape.getLetter().equals(nextLetter + "|")) {
                            backwardsSplit = false;
                        } else if (previousShape != null && previousShape.getLetter().length() == 0) {
                            backwardsSplit = true;
                        } else if (nextShape != null && nextShape.getLetter().length() == 0) {
                            backwardsSplit = false;
                        } else {
                            throw new JochreException("Impossible split for shape " + shape.getId() + ": " + previousLetter + "|" + nextLetter);
                        }
                        if (backwardsSplit) {
                            // start split
                            String letterWithSplit = newSplitLetters.get(0) + "|";
                            newSplitLetters.remove(0);
                            newSplitLetters.add(letterWithSplit);
                        } else {
                            inSplit = true;
                        }
                    } else if (i == 1) {
                        // start split
                        String letterWithSplit = newSplitLetters.get(0) + "|";
                        newSplitLetters.remove(0);
                        newSplitLetters.add(letterWithSplit);
                    } else if (i == splitLetters.size() - 2) {
                        // end split
                        inSplit = true;
                    } else {
                        throw new JochreException("Impossible split location for shape " + shape.getId() + ": " + shape.getLetter());
                    }
                } else if (inSplit) {
                    newSplitLetters.add("|" + letter);
                    inSplit = false;
                } else {
                    newSplitLetters.add(letter);
                }
                i++;
            }
            splitLetters = newSplitLetters;
        }
        if (splitLetters.size() != splitShapes.size()) {
            throw new JochreException("Cannot have more shapes than letters in shape " + shape.getId() + ": " + shape.getLetter() + ", " + splitLetters);
        }
        int i = 0;
        for (Shape splitShape : splitShapes) {
            shapeSequence.addShape(splitShape, shape);
            splitShape.setLetter(splitLetters.get(i++));
        }
    }
    return shapeSequences;
}
Also used : Shape(com.joliciel.jochre.graphics.Shape) ShapeRightToLeftComparator(com.joliciel.jochre.graphics.ShapeRightToLeftComparator) ArrayList(java.util.ArrayList) JochreException(com.joliciel.jochre.utils.JochreException) ShapeLeftToRightComparator(com.joliciel.jochre.graphics.ShapeLeftToRightComparator) TreeSet(java.util.TreeSet)

Example 63 with Shape

use of com.joliciel.jochre.graphics.Shape in project jochre by urieli.

the class SplitShapeWidthRatioFeature method checkInternal.

@Override
public FeatureResult<Double> checkInternal(Split split, RuntimeEnvironment env) {
    FeatureResult<Double> result = null;
    Shape shape = split.getShape();
    int rightWidth = (shape.getWidth() - 1) - (split.getPosition() + 1);
    int leftWidth = split.getPosition() - 1;
    double ratio = (double) leftWidth / (double) rightWidth;
    if (ratio > 1)
        ratio = 1 / ratio;
    result = this.generateResult(ratio);
    return result;
}
Also used : Shape(com.joliciel.jochre.graphics.Shape)

Example 64 with Shape

use of com.joliciel.jochre.graphics.Shape in project jochre by urieli.

the class TrueContourSlopeDifferenceFeature method checkInternal.

@Override
public FeatureResult<Double> checkInternal(Split split, RuntimeEnvironment env) {
    FeatureResult<Double> result = null;
    FeatureResult<Integer> contourDistanceResult = contourDistanceFeature.check(split, env);
    if (contourDistanceResult != null) {
        int contourDistance = contourDistanceResult.getOutcome();
        int[][] verticalContour = split.getShape().getVerticalContour();
        int startX = split.getPosition();
        Shape shape = split.getShape();
        int topStart = verticalContour[startX][0];
        int bottomStart = verticalContour[startX][1];
        SimpleRegression topRightRegression = new SimpleRegression();
        SimpleRegression bottomRightRegression = new SimpleRegression();
        SimpleRegression topLeftRegression = new SimpleRegression();
        SimpleRegression bottomLeftRegression = new SimpleRegression();
        topRightRegression.addData(startX, topStart);
        topLeftRegression.addData(startX, topStart);
        bottomRightRegression.addData(startX, bottomStart);
        bottomLeftRegression.addData(startX, bottomStart);
        int lastTopRight = topStart;
        int lastTopLeft = topStart;
        int lastBottomRight = bottomStart;
        int lastBottomLeft = bottomStart;
        for (int i = 1; i <= contourDistance; i++) {
            int x = startX + i;
            if (x < shape.getWidth()) {
                if (shape.isPixelBlack(x, lastTopRight)) {
                    for (int y = lastTopRight - 1; y >= -1; y--) {
                        if (y < 0 || !shape.isPixelBlack(x, y)) {
                            lastTopRight = y + 1;
                            topRightRegression.addData(x, lastTopRight);
                            break;
                        }
                    }
                } else {
                    for (int y = lastTopRight + 1; y <= shape.getHeight(); y++) {
                        if (y == shape.getHeight() || shape.isPixelBlack(x, y)) {
                            lastTopRight = y;
                            topRightRegression.addData(x, lastTopRight);
                            break;
                        }
                    }
                }
                if (shape.isPixelBlack(x, lastBottomRight)) {
                    for (int y = lastBottomRight + 1; y <= shape.getHeight(); y++) {
                        if (y == shape.getHeight() || !shape.isPixelBlack(x, y)) {
                            lastBottomRight = y - 1;
                            bottomRightRegression.addData(x, lastBottomRight);
                            break;
                        }
                    }
                } else {
                    for (int y = lastBottomRight - 1; y >= -1; y--) {
                        if (y < 0 || shape.isPixelBlack(x, y)) {
                            lastBottomRight = y;
                            bottomRightRegression.addData(x, lastBottomRight);
                            break;
                        }
                    }
                }
            }
            x = startX - i;
            if (x >= 0) {
                if (shape.isPixelBlack(x, lastTopLeft)) {
                    for (int y = lastTopLeft - 1; y >= -1; y--) {
                        if (y < 0 || !shape.isPixelBlack(x, y)) {
                            lastTopLeft = y + 1;
                            topLeftRegression.addData(x, lastTopLeft);
                            break;
                        }
                    }
                } else {
                    for (int y = lastTopLeft + 1; y <= shape.getHeight(); y++) {
                        if (y == shape.getHeight() || shape.isPixelBlack(x, y)) {
                            lastTopLeft = y;
                            topLeftRegression.addData(x, lastTopLeft);
                            break;
                        }
                    }
                }
                if (shape.isPixelBlack(x, lastBottomLeft)) {
                    for (int y = lastBottomLeft + 1; y <= shape.getHeight(); y++) {
                        if (y == shape.getHeight() || !shape.isPixelBlack(x, y)) {
                            lastBottomLeft = y - 1;
                            bottomLeftRegression.addData(x, lastBottomLeft);
                            break;
                        }
                    }
                } else {
                    for (int y = lastBottomLeft - 1; y >= -1; y--) {
                        if (y < 0 || shape.isPixelBlack(x, y)) {
                            lastBottomLeft = y;
                            bottomLeftRegression.addData(x, lastBottomLeft);
                            break;
                        }
                    }
                }
            }
        }
        // get the slopes
        double topRightSlope = topRightRegression.getSlope();
        double bottomRightSlope = bottomRightRegression.getSlope();
        double topLeftSlope = topLeftRegression.getSlope();
        double bottomLeftSlope = bottomLeftRegression.getSlope();
        // convert slopes to angles
        double topRightAngle = Math.atan(topRightSlope);
        double bottomRightAngle = Math.atan(bottomRightSlope);
        double topLeftAngle = Math.atan(topLeftSlope);
        double bottomLeftAngle = Math.atan(bottomLeftSlope);
        // calculate the right & left-hand differences
        double rightDiff = Math.abs(topRightAngle - bottomRightAngle);
        double leftDiff = Math.abs(topLeftAngle - bottomLeftAngle);
        // normalise the differences from 0 to 1
        rightDiff = rightDiff / Math.PI;
        leftDiff = leftDiff / Math.PI;
        double product = rightDiff * leftDiff;
        if (LOG.isTraceEnabled()) {
            LOG.trace("topRightAngle: " + topRightAngle);
            LOG.trace("bottomRightAngle: " + bottomRightAngle);
            LOG.trace("topLeftAngle: " + topLeftAngle);
            LOG.trace("bottomLeftAngle: " + bottomLeftAngle);
            LOG.trace("rightDiff: " + rightDiff);
            LOG.trace("leftDiff: " + leftDiff);
            LOG.trace("product: " + product);
        }
        result = this.generateResult(product);
    }
    return result;
}
Also used : Shape(com.joliciel.jochre.graphics.Shape) SimpleRegression(org.apache.commons.math.stat.regression.SimpleRegression)

Example 65 with Shape

use of com.joliciel.jochre.graphics.Shape in project jochre by urieli.

the class TwoPointSlopeDifferenceFeature method checkInternal.

@Override
public FeatureResult<Double> checkInternal(Split split, RuntimeEnvironment env) {
    FeatureResult<Double> result = null;
    FeatureResult<Integer> contourDistanceResult = contourDistanceFeature.check(split, env);
    if (contourDistanceResult != null) {
        int contourDistance = contourDistanceResult.getOutcome();
        int[][] verticalContour = split.getShape().getVerticalContour();
        int x = split.getPosition();
        Shape shape = split.getShape();
        int topStart = verticalContour[x][0];
        int bottomStart = verticalContour[x][1];
        SimpleRegression topRightRegression = new SimpleRegression();
        SimpleRegression bottomRightRegression = new SimpleRegression();
        SimpleRegression topLeftRegression = new SimpleRegression();
        SimpleRegression bottomLeftRegression = new SimpleRegression();
        topRightRegression.addData(x, topStart);
        topLeftRegression.addData(x, topStart);
        bottomRightRegression.addData(x, bottomStart);
        bottomLeftRegression.addData(x, bottomStart);
        int[] minTopRight = new int[] { x, topStart };
        int[] minTopLeft = new int[] { x, topStart };
        int[] maxTopRight = new int[] { x, topStart };
        int[] maxTopLeft = new int[] { x, topStart };
        int[] minBottomRight = new int[] { x, bottomStart };
        int[] minBottomLeft = new int[] { x, bottomStart };
        int[] maxBottomRight = new int[] { x, bottomStart };
        int[] maxBottomLeft = new int[] { x, bottomStart };
        for (int i = 1; i <= contourDistance; i++) {
            if (x + i < shape.getWidth()) {
                if (verticalContour[x + i][0] < minTopRight[1])
                    minTopRight = new int[] { x + i, verticalContour[x + i][0] };
                if (verticalContour[x + i][0] > maxTopRight[1])
                    maxTopRight = new int[] { x + i, verticalContour[x + i][0] };
                if (verticalContour[x + i][1] < minBottomRight[1])
                    minBottomRight = new int[] { x + i, verticalContour[x + i][1] };
                if (verticalContour[x + i][1] > maxBottomRight[1])
                    maxBottomRight = new int[] { x + i, verticalContour[x + i][1] };
            }
            if (x - i >= 0) {
                if (verticalContour[x - i][0] < minTopLeft[1])
                    minTopLeft = new int[] { x - i, verticalContour[x - i][0] };
                if (verticalContour[x - i][0] > maxTopLeft[1])
                    maxTopLeft = new int[] { x - i, verticalContour[x - i][0] };
                if (verticalContour[x - i][1] < minBottomLeft[1])
                    minBottomLeft = new int[] { x - i, verticalContour[x - i][1] };
                if (verticalContour[x - i][1] > maxBottomLeft[1])
                    maxBottomLeft = new int[] { x - i, verticalContour[x - i][1] };
            }
        }
        if (minTopRight[0] == x)
            topRightRegression.addData(maxTopRight[0], maxTopRight[1]);
        else
            topRightRegression.addData(minTopRight[0], minTopRight[1]);
        if (minTopLeft[0] == x)
            topLeftRegression.addData(maxTopLeft[0], maxTopLeft[1]);
        else
            topLeftRegression.addData(minTopLeft[0], minTopLeft[1]);
        if (maxBottomRight[0] == x)
            bottomRightRegression.addData(minBottomRight[0], minBottomRight[1]);
        else
            bottomRightRegression.addData(maxBottomRight[0], maxBottomRight[1]);
        if (maxBottomLeft[0] == x)
            bottomLeftRegression.addData(minBottomLeft[0], minBottomLeft[1]);
        else
            bottomLeftRegression.addData(maxBottomLeft[0], maxBottomLeft[1]);
        // get the slopes
        double topRightSlope = topRightRegression.getSlope();
        double bottomRightSlope = bottomRightRegression.getSlope();
        double topLeftSlope = topLeftRegression.getSlope();
        double bottomLeftSlope = bottomLeftRegression.getSlope();
        // convert slopes to angles
        double topRightAngle = Math.atan(topRightSlope);
        double bottomRightAngle = Math.atan(bottomRightSlope);
        double topLeftAngle = Math.atan(topLeftSlope);
        double bottomLeftAngle = Math.atan(bottomLeftSlope);
        // calculate the right & left-hand differences
        double rightDiff = Math.abs(topRightAngle - bottomRightAngle);
        double leftDiff = Math.abs(topLeftAngle - bottomLeftAngle);
        // normalise the differences from 0 to 1
        rightDiff = rightDiff / Math.PI;
        leftDiff = leftDiff / Math.PI;
        double product = rightDiff * leftDiff;
        if (LOG.isTraceEnabled()) {
            LOG.trace("topRightAngle: " + topRightAngle);
            LOG.trace("bottomRightAngle: " + bottomRightAngle);
            LOG.trace("topLeftAngle: " + topLeftAngle);
            LOG.trace("bottomLeftAngle: " + bottomLeftAngle);
            LOG.trace("rightDiff: " + rightDiff);
            LOG.trace("leftDiff: " + leftDiff);
            LOG.trace("product: " + product);
        }
        result = this.generateResult(product);
    }
    return result;
}
Also used : Shape(com.joliciel.jochre.graphics.Shape) SimpleRegression(org.apache.commons.math.stat.regression.SimpleRegression)

Aggregations

Shape (com.joliciel.jochre.graphics.Shape)74 ArrayList (java.util.ArrayList)22 GroupOfShapes (com.joliciel.jochre.graphics.GroupOfShapes)14 JochreImage (com.joliciel.jochre.graphics.JochreImage)13 Paragraph (com.joliciel.jochre.graphics.Paragraph)9 RowOfShapes (com.joliciel.jochre.graphics.RowOfShapes)9 Decision (com.joliciel.talismane.machineLearning.Decision)8 Test (org.junit.Test)8 JochreSession (com.joliciel.jochre.JochreSession)7 JochrePage (com.joliciel.jochre.doc.JochrePage)7 Config (com.typesafe.config.Config)7 TreeSet (java.util.TreeSet)7 JochreDocument (com.joliciel.jochre.doc.JochreDocument)6 BufferedImage (java.awt.image.BufferedImage)6 ShapeInSequence (com.joliciel.jochre.boundaries.ShapeInSequence)5 ShapeSequence (com.joliciel.jochre.boundaries.ShapeSequence)5 GraphicsDao (com.joliciel.jochre.graphics.GraphicsDao)5 RuntimeEnvironment (com.joliciel.talismane.machineLearning.features.RuntimeEnvironment)5 SplitFeature (com.joliciel.jochre.boundaries.features.SplitFeature)4 JochreException (com.joliciel.jochre.utils.JochreException)4