RED-5381: Fixed spit by ruling

This commit is contained in:
deiflaender 2022-10-17 10:56:10 +02:00
parent 15c131d6c4
commit c23dd86b6d
8 changed files with 171 additions and 105 deletions

View File

@ -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) {

View File

@ -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();

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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();
// }
}

View File

@ -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())