From 15ea385f4d65f69cac010efde9a58c33dd073822 Mon Sep 17 00:00:00 2001 From: Kilian Schuettler Date: Tue, 30 Apr 2024 10:44:32 +0200 Subject: [PATCH] RED-8825: general improvements * some more refactoring * fixed text ruling classification for vertical text * shrunk min graphics size --- .../processor/LayoutParsingPipeline.java | 11 ++--- .../services/TextRulingsClassifier.java | 2 +- .../DocstrumBlockificationService.java | 19 ++++++-- .../graphics/GraphicExtractorService.java | 5 +- .../LayoutparsingVisualizations.java | 4 +- .../server/LayoutparserEnd2EndTest.java | 2 +- .../services/TextRulingsClassifierTest.java | 46 ++++++++++++++++++ .../RotateTextWithRulingsTestFile.pdf | Bin 0 -> 13421 bytes .../service/ViewerDocumentService.java | 3 +- 9 files changed, 73 insertions(+), 19 deletions(-) create mode 100644 layoutparser-service/layoutparser-service-server/src/test/java/com/knecon/fforesight/service/layoutparser/server/services/TextRulingsClassifierTest.java create mode 100644 layoutparser-service/layoutparser-service-server/src/test/resources/files/Minimal Examples/RotateTextWithRulingsTestFile.pdf diff --git a/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/LayoutParsingPipeline.java b/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/LayoutParsingPipeline.java index c04ccf7..7921d37 100644 --- a/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/LayoutParsingPipeline.java +++ b/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/LayoutParsingPipeline.java @@ -280,8 +280,9 @@ public class LayoutParsingPipeline { redactManagerBlockificationService.blockify(stripper.getTextPositionSequences(), cleanRulings, classificationDocument.getVisualizations()); case DOCUMINE_OLD -> docuMineBlockificationService.blockify(words, cleanRulings); case DOCUMINE, REDACT_MANAGER, REDACT_MANAGER_PARAGRAPH_DEBUG -> - docstrumBlockificationService.blockify(words, cleanRulings, true, classificationDocument.getVisualizations()); - case CLARIFYND, CLARIFYND_PARAGRAPH_DEBUG -> docstrumBlockificationService.blockify(words, cleanRulings, false, classificationDocument.getVisualizations()); + docstrumBlockificationService.blockify(words, cleanRulings, true, classificationDocument.getVisualizations(), layoutParsingType); + case CLARIFYND, CLARIFYND_PARAGRAPH_DEBUG -> + docstrumBlockificationService.blockify(words, cleanRulings, false, classificationDocument.getVisualizations(), layoutParsingType); }; classificationPage.setCleanRulings(cleanRulings); @@ -311,12 +312,6 @@ public class LayoutParsingPipeline { tableExtractionService.extractTables(emptyTableCells, classificationPage); - if (layoutParsingType == LayoutParsingType.REDACT_MANAGER) { - docstrumBlockificationService.combineBlocks(classificationPage); - } else if (layoutParsingType == LayoutParsingType.CLARIFYND) { - docstrumBlockificationService.mergeIntersectingBlocks(classificationPage, 0, 6.5f); - } - buildPageStatistics(classificationPage); increaseDocumentStatistics(classificationPage, classificationDocument); diff --git a/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/TextRulingsClassifier.java b/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/TextRulingsClassifier.java index 26987c7..2565413 100644 --- a/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/TextRulingsClassifier.java +++ b/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/TextRulingsClassifier.java @@ -37,7 +37,7 @@ public class TextRulingsClassifier { float strikethroughCenterX = (float) word.getBoundingBox().getCenterX(); float strikethroughBoxHeight = (float) ((word.getHeight() * STRIKETHROUGH_ZONE) / 2); - float underlineCenterX = (float) (word.getDir().equals(TextDirection.QUARTER_CIRCLE) ? word.getBoundingBox().getMinX() : word.getBoundingBox().getMaxX()); + float underlineCenterX = (float) (word.getDir().equals(TextDirection.QUARTER_CIRCLE) ? word.getBoundingBox().getMaxX() : word.getBoundingBox().getMinX()); float underlineBoxHeight = (float) ((word.getHeight() * UNDERLINE_ZONE) / 2); float leftX = Math.min(underlineCenterX - underlineBoxHeight, strikethroughCenterX - strikethroughBoxHeight); diff --git a/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/blockification/DocstrumBlockificationService.java b/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/blockification/DocstrumBlockificationService.java index 618e20e..d5e4ed1 100644 --- a/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/blockification/DocstrumBlockificationService.java +++ b/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/blockification/DocstrumBlockificationService.java @@ -9,6 +9,7 @@ import java.util.ListIterator; import org.springframework.stereotype.Service; +import com.knecon.fforesight.service.layoutparser.internal.api.queue.LayoutParsingType; import com.knecon.fforesight.service.layoutparser.processor.docstrum.DocstrumSegmentationService; import com.knecon.fforesight.service.layoutparser.processor.docstrum.model.Zone; import com.knecon.fforesight.service.layoutparser.processor.docstrum.utils.DoubleUtils; @@ -36,7 +37,11 @@ public class DocstrumBlockificationService { static final float THRESHOLD = 1f; - public ClassificationPage blockify(List textPositions, CleanRulings rulings, boolean xyOrder, LayoutparsingVisualizations visualizations) { + public ClassificationPage blockify(List textPositions, + CleanRulings rulings, + boolean xyOrder, + LayoutparsingVisualizations visualizations, + LayoutParsingType layoutParsingType) { CleanRulings usedRulings = rulings.withoutTextRulings(); @@ -59,6 +64,12 @@ public class DocstrumBlockificationService { mergeIntersectingBlocks(classificationPage, 0, 0); + combineBlocks(classificationPage); + + if (layoutParsingType == LayoutParsingType.CLARIFYND) { + mergeIntersectingBlocks(classificationPage, 0, 6.5f); + } + return classificationPage; } @@ -77,8 +88,7 @@ public class DocstrumBlockificationService { } - private List toAbstractPageBlocks(List zones, boolean xyOrder, - CleanRulings usedRulings) { + private List toAbstractPageBlocks(List zones, boolean xyOrder, CleanRulings usedRulings) { List abstractPageBlocks = new ArrayList<>(); zones.forEach(zone -> { @@ -103,6 +113,7 @@ public class DocstrumBlockificationService { TextPageBlock previous = new TextPageBlock(); ListIterator itty = page.getTextBlocks().listIterator(); + CleanRulings usedRulings = page.getCleanRulings().withoutTextRulings(); while (itty.hasNext()) { AbstractPageBlock block = itty.next(); @@ -114,7 +125,7 @@ public class DocstrumBlockificationService { if (previous != null && !previous.getSequences().isEmpty()) { - if (current.getDir() != previous.getDir()) { + if (current.getDir() != previous.getDir() || usedRulings.lineBetween(current.getBBox(), previous.getBBox())) { previous = current; continue; } diff --git a/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/graphics/GraphicExtractorService.java b/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/graphics/GraphicExtractorService.java index 8a89d9a..9add9b3 100644 --- a/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/graphics/GraphicExtractorService.java +++ b/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/graphics/GraphicExtractorService.java @@ -21,6 +21,9 @@ import lombok.SneakyThrows; @RequiredArgsConstructor public class GraphicExtractorService { + private static final int MIN_GRAPHICS_SIDE_LENGTH = 30; + private static final int MIN_GRAPHICS_AREA = 500; + private final GraphicsClusteringService graphicsClusteringService; private final FindGraphicsRaster findGraphicsRaster; @@ -55,7 +58,7 @@ public class GraphicExtractorService { List clusters = graphicsClusteringService.getClusters(filteredGraphicBBoxes, 14); return clusters.stream() - .filter(box -> box.area() > 500 && box.height() > 50 && box.width() > 50) + .filter(box -> box.area() > MIN_GRAPHICS_AREA && box.height() > MIN_GRAPHICS_SIDE_LENGTH && box.width() > MIN_GRAPHICS_SIDE_LENGTH) .toList(); } diff --git a/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/visualization/LayoutparsingVisualizations.java b/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/visualization/LayoutparsingVisualizations.java index f50f753..cb90b5c 100644 --- a/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/visualization/LayoutparsingVisualizations.java +++ b/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/visualization/LayoutparsingVisualizations.java @@ -127,8 +127,8 @@ public class LayoutparsingVisualizations { } VisualizationsOnPage visualizationsOnPage = getOrCreateVisualizationsOnPage(pageNumber, this.rulings); visualizationsOnPage.getColoredLines() - .addAll(Stream.of(cleanRulings.getHorizontals(), cleanRulings.getVerticals()) - .flatMap(Collection::stream) + .addAll(cleanRulings.buildAll() + .stream() .map(ruling -> new ColoredLine(ruling, decideOnRulingColor(ruling), 1)) .toList()); } diff --git a/layoutparser-service/layoutparser-service-server/src/test/java/com/knecon/fforesight/service/layoutparser/server/LayoutparserEnd2EndTest.java b/layoutparser-service/layoutparser-service-server/src/test/java/com/knecon/fforesight/service/layoutparser/server/LayoutparserEnd2EndTest.java index f69a399..d04af07 100644 --- a/layoutparser-service/layoutparser-service-server/src/test/java/com/knecon/fforesight/service/layoutparser/server/LayoutparserEnd2EndTest.java +++ b/layoutparser-service/layoutparser-service-server/src/test/java/com/knecon/fforesight/service/layoutparser/server/LayoutparserEnd2EndTest.java @@ -34,7 +34,7 @@ public class LayoutparserEnd2EndTest extends AbstractTest { @Test public void testLayoutParserEndToEnd() { - String filePath = "/home/kschuettler/Dokumente/TestFiles/large number of prod files/101 S-Metolachlor_RAR_01_Volume_1_2018-09-06.pdf"; + String filePath = "/home/kschuettler/Dokumente/TestFiles/RotateTextWithRulingsTestFile.pdf"; runForFile(filePath); } diff --git a/layoutparser-service/layoutparser-service-server/src/test/java/com/knecon/fforesight/service/layoutparser/server/services/TextRulingsClassifierTest.java b/layoutparser-service/layoutparser-service-server/src/test/java/com/knecon/fforesight/service/layoutparser/server/services/TextRulingsClassifierTest.java new file mode 100644 index 0000000..dc6e8ae --- /dev/null +++ b/layoutparser-service/layoutparser-service-server/src/test/java/com/knecon/fforesight/service/layoutparser/server/services/TextRulingsClassifierTest.java @@ -0,0 +1,46 @@ +package com.knecon.fforesight.service.layoutparser.server.services; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Collections; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import com.knecon.fforesight.service.layoutparser.processor.model.PageContents; +import com.knecon.fforesight.service.layoutparser.processor.model.table.CleanRulings; +import com.knecon.fforesight.service.layoutparser.processor.model.table.Ruling; +import com.knecon.fforesight.service.layoutparser.processor.model.text.TextPositionSequence; +import com.knecon.fforesight.service.layoutparser.processor.services.PageContentExtractor; +import com.knecon.fforesight.service.layoutparser.processor.services.RulingCleaningService; +import com.knecon.fforesight.service.layoutparser.processor.services.TextRulingsClassifier; +import com.knecon.fforesight.service.layoutparser.processor.utils.RectangularIntersectionFinder; + +import lombok.SneakyThrows; + +public class TextRulingsClassifierTest { + + @Test + @SneakyThrows + public void textRulingExtractionTest() { + + String fileName = "files/Minimal Examples/RotateTextWithRulingsTestFile.pdf"; + List pageContents = PageContentExtractor.getSortedPageContents(fileName); + RulingCleaningService rulingCleaningService = new RulingCleaningService(); + + for (PageContents pageContent : pageContents) { + CleanRulings cleanRulings = rulingCleaningService.deduplicateAndStraightenRulings(Collections.emptyList(), pageContent.getRulings()); + RectangularIntersectionFinder.find(cleanRulings.getHorizontals(), cleanRulings.getVerticals()); + TextRulingsClassifier.classifyUnderlinedAndStrikethroughText(pageContent.getSortedTextPositionSequences(), cleanRulings); + + assertTrue(pageContent.getSortedTextPositionSequences().stream().filter(word -> word.toString().equals("Underlined")).allMatch(TextPositionSequence::isUnderline)); + assertTrue(pageContent.getSortedTextPositionSequences().stream().filter(word -> word.toString().equals("Striketrough")).allMatch(TextPositionSequence::isStrikethrough)); + + assertEquals(4, cleanRulings.buildAll().stream().filter(ruling -> ruling.getClassification().equals(Ruling.Classification.STRIKETROUGH)).count()); + assertEquals(4, cleanRulings.buildAll().stream().filter(ruling -> ruling.getClassification().equals(Ruling.Classification.UNDERLINE)).count()); + } + + } + +} diff --git a/layoutparser-service/layoutparser-service-server/src/test/resources/files/Minimal Examples/RotateTextWithRulingsTestFile.pdf b/layoutparser-service/layoutparser-service-server/src/test/resources/files/Minimal Examples/RotateTextWithRulingsTestFile.pdf new file mode 100644 index 0000000000000000000000000000000000000000..da0590441fc23328b1653ed7f4aed181357d0524 GIT binary patch literal 13421 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 T{Bs{hW=0MU7*bMEIkEo&$ZO>Q literal 0 HcmV?d00001 diff --git a/layoutparser-service/viewer-doc-processor/src/main/java/com/knecon/fforesight/service/viewerdoc/service/ViewerDocumentService.java b/layoutparser-service/viewer-doc-processor/src/main/java/com/knecon/fforesight/service/viewerdoc/service/ViewerDocumentService.java index c761c69..04233da 100644 --- a/layoutparser-service/viewer-doc-processor/src/main/java/com/knecon/fforesight/service/viewerdoc/service/ViewerDocumentService.java +++ b/layoutparser-service/viewer-doc-processor/src/main/java/com/knecon/fforesight/service/viewerdoc/service/ViewerDocumentService.java @@ -185,8 +185,7 @@ public class ViewerDocumentService { contentStream.setFont(font, placedText.fontSize()); contentStream.beginText(); contentStream.setNonStrokingColor(placedText.color()); - if (placedText.renderingMode() - .isPresent()) { + if (placedText.renderingMode().isPresent()) { contentStream.setRenderingMode(placedText.renderingMode().get()); } else { contentStream.setRenderingMode(RenderingMode.FILL);