RED-5381: Fixed spit by ruling
This commit is contained in:
parent
15c131d6c4
commit
c23dd86b6d
@ -3,6 +3,7 @@ package com.iqser.red.service.redaction.v1.server.classification.service;
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
@ -33,7 +34,7 @@ public class BlockificationService {
|
||||
|
||||
|
||||
public Page blockify(List<TextPositionSequence> textPositions, List<Ruling> horizontalRulingLines,
|
||||
List<Ruling> verticalRulingLines, PDRectangle cropbox) {
|
||||
List<Ruling> verticalRulingLines, int rotation, PDRectangle cropbox) {
|
||||
|
||||
// sortRotatedSequences(textPositions);
|
||||
|
||||
@ -53,14 +54,14 @@ public class BlockificationService {
|
||||
boolean xIsBeforeFirstX = prev != null && word.getX1() < minX;
|
||||
boolean newLineAfterSplit = prev != null && word.getY1() != prev.getY1() && wasSplitted && splitX1 != word.getX1();
|
||||
boolean splittedByRuling =
|
||||
isSplittedByRuling(maxX, minY, word.getX1(), word.getY1(), verticalRulingLines,cropbox.getHeight()) ||
|
||||
isSplittedByRuling(minX, minY, word.getX1(), word.getY2(), horizontalRulingLines,cropbox.getHeight())
|
||||
isSplittedByRuling(maxX, minY, word.getX1(), word.getY1(), verticalRulingLines, word.getDir().getDegrees(), cropbox.getWidth(), cropbox.getHeight()) ||
|
||||
isSplittedByRuling(minX, minY, word.getX1(), word.getY2(), horizontalRulingLines, word.getDir().getDegrees(), cropbox.getWidth(), cropbox.getHeight())
|
||||
|
||||
|| isSplittedByRuling(maxX, minY, word.getX1(), word.getY1(), horizontalRulingLines,cropbox.getHeight())
|
||||
|| isSplittedByRuling(minX, minY, word.getX1(), word.getY2(), verticalRulingLines,cropbox.getHeight());
|
||||
|| isSplittedByRuling(maxX, minY, word.getX1(), word.getY1(), horizontalRulingLines, word.getDir().getDegrees(), cropbox.getWidth(), cropbox.getHeight())
|
||||
|| isSplittedByRuling(minX, minY, word.getX1(), word.getY2(), verticalRulingLines, word.getDir().getDegrees(), cropbox.getWidth(), cropbox.getHeight());
|
||||
boolean splitByDir = prev != null && !prev.getDir().equals(word.getDir());
|
||||
|
||||
if (prev != null && (lineSeparation || startFromTop || xIsBeforeFirstX || splitByX || splitByDir || startFromTop)) {
|
||||
if (prev != null && (lineSeparation || startFromTop || xIsBeforeFirstX || splitByX || splitByDir || startFromTop || splittedByRuling)) {
|
||||
|
||||
Orientation prevOrientation = null;
|
||||
if (!chunkBlockList1.isEmpty()) {
|
||||
@ -112,55 +113,55 @@ public class BlockificationService {
|
||||
chunkBlockList1.add(cb1);
|
||||
}
|
||||
|
||||
// Iterator<AbstractTextContainer> itty = chunkBlockList1.iterator();
|
||||
//
|
||||
// TextBlock previousLeft = null;
|
||||
// TextBlock previousRight = null;
|
||||
// while (itty.hasNext()) {
|
||||
// TextBlock block = (TextBlock) itty.next();
|
||||
//
|
||||
// if (previousLeft != null && block.getOrientation().equals(Orientation.LEFT)) {
|
||||
// if (previousLeft.getMinY() > block.getMinY() && block.getMaxY() + block.getMostPopularWordHeight() > previousLeft
|
||||
// .getMinY()) {
|
||||
// previousLeft.add(block);
|
||||
// itty.remove();
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (previousRight != null && block.getOrientation().equals(Orientation.RIGHT)) {
|
||||
// if (previousRight.getMinY() > block.getMinY() && block.getMaxY() + block.getMostPopularWordHeight() > previousRight
|
||||
// .getMinY()) {
|
||||
// previousRight.add(block);
|
||||
// itty.remove();
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (block.getOrientation().equals(Orientation.LEFT)) {
|
||||
// previousLeft = block;
|
||||
// } else if (block.getOrientation().equals(Orientation.RIGHT)) {
|
||||
// previousRight = block;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// itty = chunkBlockList1.iterator();
|
||||
// TextBlock previous = null;
|
||||
// while (itty.hasNext()) {
|
||||
// TextBlock block = (TextBlock) itty.next();
|
||||
//
|
||||
// if (previous != null && previous.getOrientation().equals(Orientation.LEFT) && block.getOrientation()
|
||||
// .equals(Orientation.LEFT) && equalsWithThreshold(block.getMaxY(), previous.getMaxY()) || previous != null && previous
|
||||
// .getOrientation()
|
||||
// .equals(Orientation.LEFT) && block.getOrientation()
|
||||
// .equals(Orientation.RIGHT) && equalsWithThreshold(block.getMaxY(), previous.getMaxY())) {
|
||||
// previous.add(block);
|
||||
// itty.remove();
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// previous = block;
|
||||
// }
|
||||
Iterator<AbstractTextContainer> itty = chunkBlockList1.iterator();
|
||||
|
||||
TextBlock previousLeft = null;
|
||||
TextBlock previousRight = null;
|
||||
while (itty.hasNext()) {
|
||||
TextBlock block = (TextBlock) itty.next();
|
||||
|
||||
if (previousLeft != null && block.getOrientation().equals(Orientation.LEFT)) {
|
||||
if (previousLeft.getMinY() > block.getMinY() && block.getMaxY() + block.getMostPopularWordHeight() > previousLeft
|
||||
.getMinY()) {
|
||||
previousLeft.add(block);
|
||||
itty.remove();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (previousRight != null && block.getOrientation().equals(Orientation.RIGHT)) {
|
||||
if (previousRight.getMinY() > block.getMinY() && block.getMaxY() + block.getMostPopularWordHeight() > previousRight
|
||||
.getMinY()) {
|
||||
previousRight.add(block);
|
||||
itty.remove();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (block.getOrientation().equals(Orientation.LEFT)) {
|
||||
previousLeft = block;
|
||||
} else if (block.getOrientation().equals(Orientation.RIGHT)) {
|
||||
previousRight = block;
|
||||
}
|
||||
}
|
||||
|
||||
itty = chunkBlockList1.iterator();
|
||||
TextBlock previous = null;
|
||||
while (itty.hasNext()) {
|
||||
TextBlock block = (TextBlock) itty.next();
|
||||
|
||||
if (previous != null && previous.getOrientation().equals(Orientation.LEFT) && block.getOrientation()
|
||||
.equals(Orientation.LEFT) && equalsWithThreshold(block.getMaxY(), previous.getMaxY()) || previous != null && previous
|
||||
.getOrientation()
|
||||
.equals(Orientation.LEFT) && block.getOrientation()
|
||||
.equals(Orientation.RIGHT) && equalsWithThreshold(block.getMaxY(), previous.getMaxY())) {
|
||||
previous.add(block);
|
||||
itty.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
previous = block;
|
||||
}
|
||||
|
||||
return new Page(chunkBlockList1);
|
||||
}
|
||||
@ -221,10 +222,10 @@ public class BlockificationService {
|
||||
|
||||
|
||||
private boolean isSplittedByRuling(float previousX2, float previousY1, float currentX1, float currentY1,
|
||||
List<Ruling> rulingLines, float pageHeight) {
|
||||
List<Ruling> rulingLines, float rotation, float pageWidth, float pageHeight) {
|
||||
|
||||
for (Ruling ruling : rulingLines) {
|
||||
var line = new Line2D.Float(pageHeight -ruling.y1 , ruling.x1, pageHeight -ruling.y2, ruling.x2);
|
||||
var line = convertToJavaCoord(ruling, rotation, pageWidth, pageHeight);
|
||||
if (line.intersectsLine(previousX2, previousY1, currentX1, currentY1)) {
|
||||
return true;
|
||||
}
|
||||
@ -233,6 +234,74 @@ public class BlockificationService {
|
||||
}
|
||||
|
||||
|
||||
private Line2D.Float convertToJavaCoord(Ruling ruling, float rotation, float pageWidth, float pageHeight){
|
||||
|
||||
|
||||
return new Line2D.Float(convertPoint(ruling.x1, ruling.y1, rotation, pageWidth, pageHeight), convertPoint(ruling.x2, ruling.y2, rotation, pageWidth, pageHeight));
|
||||
|
||||
|
||||
}
|
||||
|
||||
private Point2D convertPoint(float x, float y, float rotation, float pageWidth, float pageHeight){
|
||||
var xAdj = getXRot(x,y,rotation, pageWidth, pageHeight);
|
||||
var yAdj = 0f;
|
||||
if (rotation == 0 || rotation == 180)
|
||||
{
|
||||
yAdj = pageHeight - getYLowerLeftRot(x,y,rotation, pageWidth, pageHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
yAdj = pageWidth - getYLowerLeftRot(x,y,rotation, pageWidth, pageHeight);
|
||||
}
|
||||
return new Point2D.Float(xAdj, yAdj);
|
||||
}
|
||||
|
||||
private float getXRot(float x, float y, float rotation, float pageWidth, float pageHeight)
|
||||
{
|
||||
if (rotation == 0)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
else if (rotation == 90)
|
||||
{
|
||||
return y;
|
||||
}
|
||||
else if (rotation == 180)
|
||||
{
|
||||
return pageWidth - x;
|
||||
}
|
||||
else if (rotation == 270)
|
||||
{
|
||||
return pageHeight - y;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
private float getYLowerLeftRot(float x, float y, float rotation, float pageWidth, float pageHeight)
|
||||
{
|
||||
if (rotation == 0)
|
||||
{
|
||||
return y;
|
||||
}
|
||||
else if (rotation == 90)
|
||||
{
|
||||
return pageWidth - x;
|
||||
}
|
||||
else if (rotation == 180)
|
||||
{
|
||||
return pageHeight - y;
|
||||
}
|
||||
else if (rotation == 270)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public Rectangle calculateBodyTextFrame(List<Page> pages, FloatFrequencyCounter documentFontSizeCounter,
|
||||
boolean landscape) {
|
||||
|
||||
|
||||
@ -106,7 +106,7 @@ public class PdfSegmentationService {
|
||||
|
||||
PDRectangle cropbox = pdPage.getCropBox();
|
||||
CleanRulings cleanRulings = rulingCleaningService.getCleanRulings(pdfTableCells.get(pageNumber), stripper.getRulings(), stripper.getMinCharWidth(), stripper.getMaxCharHeight());
|
||||
Page page = blockificationService.blockify(stripper.getTextPositionSequences(), cleanRulings.getHorizontal(), cleanRulings.getVertical(), cropbox);
|
||||
Page page = blockificationService.blockify(stripper.getTextPositionSequences(), cleanRulings.getHorizontal(), cleanRulings.getVertical(), rotation, cropbox);
|
||||
|
||||
|
||||
float cropboxArea = cropbox.getHeight() * cropbox.getWidth();
|
||||
|
||||
@ -4,6 +4,7 @@ import com.dslplatform.json.JsonAttribute;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.iqser.red.service.redaction.v1.model.Rectangle;
|
||||
import com.iqser.red.service.redaction.v1.server.classification.model.Orientation;
|
||||
import com.iqser.red.service.redaction.v1.server.classification.model.TextBlock;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
@ -30,35 +31,31 @@ public abstract class AbstractTextContainer {
|
||||
@JsonIgnore
|
||||
private Orientation orientation = Orientation.NONE;
|
||||
|
||||
|
||||
public abstract String getText();
|
||||
|
||||
|
||||
public boolean contains(AbstractTextContainer other) {
|
||||
public boolean containsBlock(TextBlock other) {
|
||||
return this.minX <= other.getX1() && this.maxX >= other.getX2() && this.minY >= other.getY1() && this.maxY <= other.getY2();
|
||||
}
|
||||
|
||||
|
||||
public boolean contains(AbstractTextContainer other) {
|
||||
return this.minX <= other.minX && this.maxX >= other.maxX && this.minY >= other.minY && this.maxY <= other.maxY;
|
||||
}
|
||||
|
||||
|
||||
public boolean contains(Rectangle other) {
|
||||
|
||||
return page == other.getPage() && this.minX <= other.getTopLeft().getX() && this.maxX >= other.getTopLeft().getX() + other.getWidth() && this.minY <= other.getTopLeft()
|
||||
.getY() && this.maxY >= other.getTopLeft().getY() + other.getHeight();
|
||||
return page == other.getPage() && this.minX <= other.getTopLeft().getX() && this.maxX >= other.getTopLeft().getX() + other.getWidth() && this.minY <= other.getTopLeft().getY() && this.maxY >= other.getTopLeft().getY() + other.getHeight();
|
||||
}
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
@JsonAttribute(ignore = true)
|
||||
public float getHeight() {
|
||||
|
||||
return maxY - minY;
|
||||
}
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
@JsonAttribute(ignore = true)
|
||||
public float getWidth() {
|
||||
|
||||
return maxX - minX;
|
||||
}
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@ public class TableExtractionService {
|
||||
Iterator<AbstractTextContainer> itty = page.getTextBlocks().iterator();
|
||||
while (itty.hasNext()) {
|
||||
AbstractTextContainer textBlock = itty.next();
|
||||
if (table.contains(textBlock) && position == -1) {
|
||||
if (textBlock instanceof TextBlock ? table.containsBlock((TextBlock) textBlock) : table.contains(textBlock) && position == -1) {
|
||||
position = page.getTextBlocks().indexOf(textBlock);
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,41 +97,41 @@ public class PdfVisualisationService {
|
||||
contentStream.addRect(textBlock.getX1(), textBlock.getY1(), textBlock.getX2() - textBlock.getX1(), textBlock.getY2() - textBlock.getY1());
|
||||
contentStream.stroke();
|
||||
|
||||
if (textBlock.getClassification() != null) {
|
||||
contentStream.beginText();
|
||||
|
||||
contentStream.setFont(PDType1Font.TIMES_ROMAN, 6f);
|
||||
|
||||
contentStream.newLineAtOffset(textBlock.getX1(), textBlock.getY2() + 2);
|
||||
contentStream.showText(textBlock.getClassification() + textBlock.getOrientation() + "-->" + textBlock.getSequences().get(0).getDir());
|
||||
|
||||
contentStream.endText();
|
||||
|
||||
|
||||
contentStream.setNonStrokingColor(Color.BLUE);
|
||||
contentStream.setFont(PDType1Font.TIMES_ROMAN, 2f);
|
||||
|
||||
|
||||
|
||||
contentStream.beginText();
|
||||
contentStream.newLineAtOffset(textBlock.getX1(), textBlock.getY1());
|
||||
contentStream.showText("MinX,MinY(" + textBlock.getX1() + "," + textBlock.getY1() + ")");
|
||||
contentStream.endText();
|
||||
contentStream.beginText();
|
||||
contentStream.newLineAtOffset(textBlock.getX2(), textBlock.getY1());
|
||||
contentStream.showText("MaxX,MinY(" + textBlock.getX2() + "," + textBlock.getY1() + ")");
|
||||
contentStream.endText();
|
||||
contentStream.beginText();
|
||||
contentStream.newLineAtOffset(textBlock.getX1(), textBlock.getY2());
|
||||
contentStream.showText("MinX,MaxY(" + textBlock.getX1() + "," + textBlock.getY2() + ")");
|
||||
contentStream.endText();
|
||||
contentStream.beginText();
|
||||
contentStream.newLineAtOffset(textBlock.getX2(), textBlock.getY2());
|
||||
contentStream.showText("MaxX,MaxY(" + textBlock.getX2() + "," + textBlock.getY2() + ")");
|
||||
|
||||
|
||||
contentStream.endText();
|
||||
}
|
||||
// if (textBlock.getClassification() != null) {
|
||||
// contentStream.beginText();
|
||||
//
|
||||
// contentStream.setFont(PDType1Font.TIMES_ROMAN, 6f);
|
||||
//
|
||||
// contentStream.newLineAtOffset(textBlock.getX1(), textBlock.getY2() + 2);
|
||||
// contentStream.showText(textBlock.getClassification() + textBlock.getOrientation() + "-->" + textBlock.getSequences().get(0).getDir());
|
||||
//
|
||||
// contentStream.endText();
|
||||
//
|
||||
//
|
||||
// contentStream.setNonStrokingColor(Color.BLUE);
|
||||
// contentStream.setFont(PDType1Font.TIMES_ROMAN, 2f);
|
||||
//
|
||||
//
|
||||
//
|
||||
// contentStream.beginText();
|
||||
// contentStream.newLineAtOffset(textBlock.getX1(), textBlock.getY1());
|
||||
// contentStream.showText("MinX,MinY(" + textBlock.getX1() + "," + textBlock.getY1() + ")");
|
||||
// contentStream.endText();
|
||||
// contentStream.beginText();
|
||||
// contentStream.newLineAtOffset(textBlock.getX2(), textBlock.getY1());
|
||||
// contentStream.showText("MaxX,MinY(" + textBlock.getX2() + "," + textBlock.getY1() + ")");
|
||||
// contentStream.endText();
|
||||
// contentStream.beginText();
|
||||
// contentStream.newLineAtOffset(textBlock.getX1(), textBlock.getY2());
|
||||
// contentStream.showText("MinX,MaxY(" + textBlock.getX1() + "," + textBlock.getY2() + ")");
|
||||
// contentStream.endText();
|
||||
// contentStream.beginText();
|
||||
// contentStream.newLineAtOffset(textBlock.getX2(), textBlock.getY2());
|
||||
// contentStream.showText("MaxX,MaxY(" + textBlock.getX2() + "," + textBlock.getY2() + ")");
|
||||
//
|
||||
//
|
||||
// contentStream.endText();
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1098,7 +1098,7 @@ public class RedactionIntegrationTest {
|
||||
|
||||
System.out.println("classificationTest");
|
||||
|
||||
AnalyzeRequest request = prepareStorage("files/new/VV-511309_OCR.pdf");
|
||||
AnalyzeRequest request = prepareStorage("files/Metolachlor/S-Metolachlor_RAR_01_Volume_1_2018-09-06.pdf");
|
||||
|
||||
RedactionRequest redactionRequest = RedactionRequest.builder()
|
||||
.dossierId(request.getDossierId())
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user