use of com.joliciel.jochre.graphics.Shape in project jochre by urieli.
the class InnerEmptyChupchikLowerLeftFeature method checkInternal.
@Override
public FeatureResult<Boolean> checkInternal(ShapeWrapper shapeWrapper, RuntimeEnvironment env) {
Shape shape = shapeWrapper.getShape();
BitSet bitset = shape.getBlackAndWhiteBitSet(shape.getJochreImage().getBlackThreshold());
boolean[][] grid = new boolean[shape.getWidth()][shape.getHeight()];
for (int i = 0; i < shape.getWidth(); i++) {
for (int j = 0; j < shape.getHeight(); j++) {
if (bitset.get(j * shape.getWidth() + i))
grid[i][j] = true;
}
}
int startX = shape.getWidth() / 2;
int startY = shape.getHeight() / 2;
while (startY < shape.getHeight() && grid[startX][startY]) {
startY += 1;
}
WritableImageGrid mirror = new ImageMirror(shape);
boolean foundChupchikOrOpening = false;
if (startY < shape.getHeight()) {
Stack<HorizontalLineSegment> whiteLineStack = new Stack<HorizontalLineSegment>();
Set<HorizontalLineSegment> whiteLineSet = new TreeSet<HorizontalLineSegment>();
HorizontalLineSegment startLine = new HorizontalLineSegment(startX, startY);
whiteLineStack.push(startLine);
while (!whiteLineStack.empty()) {
HorizontalLineSegment line = whiteLineStack.pop();
if (line.y == shape.getHeight() - 1) {
// found opening to the outside world
if (LOG.isTraceEnabled())
LOG.trace("Reached edge: found opening");
foundChupchikOrOpening = true;
break;
}
if (mirror.getPixel(line.xLeft, line.y) == 1)
continue;
// extend this line to the right and left
for (int i = line.xLeft; i >= 0; i--) {
if (!grid[i][line.y])
line.xLeft = i;
else
break;
}
for (int i = line.xRight; i <= startX; i++) {
if (!grid[i][line.y])
line.xRight = i;
else
break;
}
if (LOG.isTraceEnabled())
LOG.trace(line.toString());
whiteLineSet.add(line);
for (int i = line.xLeft; i <= line.xRight; i++) {
mirror.setPixel(i, line.y, 1);
}
// find lines below and to the left
if (line.y < shape.getHeight() - 1) {
boolean inLine = false;
int row = line.y + 1;
int xLeft = 0;
for (int i = line.xLeft; i <= line.xRight; i++) {
if (!inLine && !grid[i][row]) {
inLine = true;
xLeft = i;
} else if (inLine && grid[i][row]) {
HorizontalLineSegment newLine = new HorizontalLineSegment(xLeft, row);
newLine.xRight = i - 1;
whiteLineStack.push(newLine);
inLine = false;
}
}
if (inLine) {
HorizontalLineSegment newLine = new HorizontalLineSegment(xLeft, row);
newLine.xRight = line.xRight;
whiteLineStack.push(newLine);
}
}
}
if (!foundChupchikOrOpening) {
// if (LOG.isDebugEnabled()) {
// LOG.trace("List of lines");
// for (HorizontalLineSegment line : whiteLineSet) {
// LOG.trace(line.toString());
// }
// }
Iterator<HorizontalLineSegment> iLines = whiteLineSet.iterator();
HorizontalLineSegment bottomLeftLine = iLines.next();
double threshold = shape.getWidth() / 8;
if (LOG.isTraceEnabled())
LOG.trace("Length threshold: " + threshold);
HorizontalLineSegment nextLine = null;
List<HorizontalLineSegment> firstFewLines = new ArrayList<HorizontalLineSegment>();
firstFewLines.add(bottomLeftLine);
HorizontalLineSegment currentLine = bottomLeftLine;
while (iLines.hasNext() && firstFewLines.size() < 3) {
nextLine = iLines.next();
if (nextLine.y != currentLine.y) {
firstFewLines.add(nextLine);
currentLine = nextLine;
}
}
boolean mightHaveChupchik = true;
HorizontalLineSegment prevLine = null;
for (HorizontalLineSegment line : firstFewLines) {
if (LOG.isTraceEnabled())
LOG.trace("Next line left, " + bottomLeftLine.xLeft + ", length: " + bottomLeftLine.length() + ", threshold: " + threshold);
if (line.length() > threshold) {
mightHaveChupchik = false;
break;
}
if (prevLine != null) {
if (line.xLeft + 2 < prevLine.xLeft) {
mightHaveChupchik = false;
break;
}
if (line.length() + 1 < prevLine.length()) {
mightHaveChupchik = false;
break;
}
}
prevLine = line;
threshold = threshold * 1.2;
}
if (mightHaveChupchik)
foundChupchikOrOpening = true;
}
}
FeatureResult<Boolean> outcome = this.generateResult(foundChupchikOrOpening);
return outcome;
}
use of com.joliciel.jochre.graphics.Shape in project jochre by urieli.
the class OpeningOnTopFeature method checkInternal.
@Override
public FeatureResult<Boolean> checkInternal(ShapeWrapper shapeWrapper, RuntimeEnvironment env) {
Shape shape = shapeWrapper.getShape();
int leftPoint = (int) ((double) shape.getWidth() * (1.0 / 8.0));
int rightPoint = (int) ((double) shape.getWidth() * (7.0 / 8.0));
int openingThreshold = shape.getHeight() / 4;
int wallThreshold = shape.getHeight() / 7;
if (LOG.isTraceEnabled()) {
LOG.trace("leftPoint: " + leftPoint);
LOG.trace("rightPoint: " + rightPoint);
LOG.trace("openingThreshold: " + openingThreshold);
LOG.trace("wallThreshold: " + wallThreshold);
}
boolean foundWall = false;
boolean foundOpening = false;
boolean foundAnotherWall = false;
for (int x = rightPoint; x >= leftPoint; x--) {
for (int y = 0; y <= openingThreshold; y++) {
if (!foundWall && y > wallThreshold) {
break;
} else if (!foundWall && shape.isPixelBlack(x, y, shape.getJochreImage().getBlackThreshold())) {
foundWall = true;
if (LOG.isTraceEnabled())
LOG.trace("foundWall x=" + x + ", y=" + y);
break;
} else if (foundWall && !foundOpening && shape.isPixelBlack(x, y, shape.getJochreImage().getBlackThreshold())) {
break;
} else if (foundWall && !foundOpening && y == openingThreshold) {
foundOpening = true;
if (LOG.isTraceEnabled())
LOG.trace("foundOpening x=" + x + ", y=" + y);
break;
} else if (foundOpening && !foundAnotherWall && y >= wallThreshold) {
break;
} else if (foundOpening && !foundAnotherWall && shape.isPixelBlack(x, y, shape.getJochreImage().getBlackThreshold())) {
foundAnotherWall = true;
if (LOG.isTraceEnabled())
LOG.trace("foundAnotherWall x=" + x + ", y=" + y);
break;
}
}
if (foundAnotherWall)
break;
}
FeatureResult<Boolean> outcome = this.generateResult(foundAnotherWall);
return outcome;
}
use of com.joliciel.jochre.graphics.Shape in project jochre by urieli.
the class SectionRelativeBrightnessFeature method checkInternal.
@Override
public FeatureResult<Double> checkInternal(ShapeWrapper shapeWrapper, RuntimeEnvironment env) {
FeatureResult<Double> result = null;
FeatureResult<Integer> xResult = xFeature.check(shapeWrapper, env);
FeatureResult<Integer> yResult = yFeature.check(shapeWrapper, env);
FeatureResult<Integer> verticalSectionsResult = verticalSectionsFeature.check(shapeWrapper, env);
FeatureResult<Integer> horizontalSectionsResult = horizontalSectionsFeature.check(shapeWrapper, env);
FeatureResult<Double> topBottomMarginWidthResult = topBottomMarginWidthFeature.check(shapeWrapper, env);
FeatureResult<Double> leftMarginWidthFeatureResult = leftMarginWidthFeature.check(shapeWrapper, env);
if (xResult != null && yResult != null && verticalSectionsResult != null && horizontalSectionsResult != null && topBottomMarginWidthResult != null && leftMarginWidthFeatureResult != null) {
int x = xResult.getOutcome();
int y = yResult.getOutcome();
int verticalSections = verticalSectionsResult.getOutcome();
int horizontalSections = horizontalSectionsResult.getOutcome();
double topBottomMarginWidth = topBottomMarginWidthResult.getOutcome();
double leftMarginWidth = leftMarginWidthFeatureResult.getOutcome();
Shape shape = shapeWrapper.getShape();
double[][] graduatedBrightnessGrid = shape.getBrightnessBySection(verticalSections, horizontalSections, topBottomMarginWidth, leftMarginWidth, SectionBrightnessMeasurementMethod.RELATIVE_TO_MAX_SECTION);
double graduatedBrightness = graduatedBrightnessGrid[x][y];
result = this.generateResult(graduatedBrightness);
}
return result;
}
use of com.joliciel.jochre.graphics.Shape in project jochre by urieli.
the class SectionRelativeBrightnessNoMarginsFeature method checkInternal.
@Override
public FeatureResult<Double> checkInternal(ShapeWrapper shapeWrapper, RuntimeEnvironment env) {
FeatureResult<Double> result = null;
FeatureResult<Integer> xResult = xFeature.check(shapeWrapper, env);
FeatureResult<Integer> yResult = yFeature.check(shapeWrapper, env);
FeatureResult<Integer> verticalSectionsResult = verticalSectionsFeature.check(shapeWrapper, env);
FeatureResult<Integer> horizontalSectionsResult = horizontalSectionsFeature.check(shapeWrapper, env);
if (xResult != null && yResult != null && verticalSectionsResult != null && horizontalSectionsResult != null) {
int x = xResult.getOutcome();
int y = yResult.getOutcome();
int verticalSections = verticalSectionsResult.getOutcome();
int horizontalSections = horizontalSectionsResult.getOutcome();
Shape shape = shapeWrapper.getShape();
double[][] graduatedBrightnessGrid = shape.getBrightnessBySection(verticalSections, horizontalSections, SectionBrightnessMeasurementMethod.RELATIVE_TO_MAX_SECTION);
double graduatedBrightness = graduatedBrightnessGrid[x][y];
result = this.generateResult(graduatedBrightness);
}
return result;
}
use of com.joliciel.jochre.graphics.Shape in project jochre by urieli.
the class TouchesMeanLineFeature method checkInternal.
@Override
public FeatureResult<Boolean> checkInternal(ShapeWrapper shapeWrapper, RuntimeEnvironment env) {
Shape shape = shapeWrapper.getShape();
boolean result = ((shape.getMeanLine() >= 0) && (shape.getHeight() >= shape.getMeanLine()));
FeatureResult<Boolean> outcome = this.generateResult(result);
return outcome;
}
Aggregations