RSS-83: More improvements for section detection

This commit is contained in:
deiflaender 2022-10-05 10:18:31 +02:00
parent 65daab4372
commit d7d2bfff6b
6 changed files with 102 additions and 12 deletions

View File

@ -1,5 +1,6 @@
package com.iqser.red.service.redaction.v1.server.classification.service;
import com.iqser.red.service.redaction.v1.model.Point;
import com.iqser.red.service.redaction.v1.server.classification.model.Document;
import com.iqser.red.service.redaction.v1.server.classification.model.Orientation;
import com.iqser.red.service.redaction.v1.server.classification.model.Page;
@ -12,6 +13,8 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
@ -36,12 +39,49 @@ public class ClassificationService {
for (Page page : document.getPages()) {
Rectangle btf = page.isLandscape() ? landscapeBodyTextFrame : bodyTextFrame;
// if (page.getRotation() == 180 || page.getRotation() == 270){
// var nBtf = getRectangle(btf.x, btf.y, btf.width, btf.height, page.getRotation(),((TextBlock) page.getTextBlocks().get(0)).getSequences().get(0).getPageWidth(),((TextBlock) page.getTextBlocks().get(0)).getSequences().get(0).getPageHeight());
// btf = new Rectangle(nBtf.getTopLeft().getX(), nBtf.getTopLeft().getY(), nBtf.getWidth(), nBtf.getHeight());
// }
page.setBodyTextFrame(btf);
classifyPage(btf, page, document, headlineFontSizes);
}
}
public com.iqser.red.service.redaction.v1.model.Rectangle getRectangle(float x, float y, float width, float height, int rotation, float pageWidth, float pageHeight) {
Point2D bottomLeft = new Point2D.Double(x, pageHeight - y);
Point2D topRight = new Point2D.Double(x + width,pageHeight - y - height);
AffineTransform transform = new AffineTransform();
if (rotation == 0 || rotation == 180) {
transform.rotate(Math.toRadians(rotation), pageWidth / 2f, pageHeight / 2f);
transform.translate(0f, pageHeight);
transform.scale(1., -1.);
} else if (rotation == 90) {
transform.rotate(Math.toRadians(rotation), pageWidth / 2f, pageWidth / 2f);
transform.translate(0f, pageWidth);
transform.scale(1., -1.);
} else {
transform.rotate(Math.toRadians(rotation), pageHeight / 2f, pageHeight / 2f);
transform.translate(0f, pageWidth);
transform.scale(1., -1.);
}
bottomLeft = transform.transform(bottomLeft, null);
topRight = transform.transform(topRight, null);
return new com.iqser.red.service.redaction.v1.model.Rectangle( //
new Point((float) bottomLeft.getX(), (float) bottomLeft.getY()), (float) (topRight.getX() - bottomLeft.getX()), (float) (topRight.getY() - bottomLeft.getY()), 0);
}
public void classifyPage(Rectangle bodyTextFrame, Page page, Document document, List<Float> headlineFontSizes) {
for (AbstractTextContainer textBlock : page.getTextBlocks()) {
@ -92,7 +132,7 @@ public class ClassificationService {
document.setHeadlines(true);
}
else if (PositionUtils.isOverBodyTextFrame(bodyTextFrame, textBlock, page.isRotated()) && (document.getFontSizeCounter()
else if (PositionUtils.isOverBodyTextFrame(bodyTextFrame, textBlock) && (document.getFontSizeCounter()
.getMostPopular() == null || textBlock.getHighestFontSize() <= document.getFontSizeCounter()
.getMostPopular())) {
textBlock.setClassification("Header");

View File

@ -31,16 +31,16 @@ public class PositionUtils {
}
public boolean isOverBodyTextFrame(Rectangle btf, TextBlock textBlock, boolean rotated) {
public boolean isOverBodyTextFrame(Rectangle btf, TextBlock textBlock) {
if (btf == null || textBlock == null) {
return false;
}
if (rotated && textBlock.getMinX() < btf.getX()) {
if ((textBlock.getRotation() == 0 || textBlock.getRotation() == 180) && textBlock.getMinX() < btf.getX()) {
// Its very strange, P{0,0} is on top left in this case, instead of lower left.
return true;
} else if (!rotated && textBlock.getMinY() > btf.getY() + btf.getHeight()) {
} else if ((textBlock.getRotation() == 90 || textBlock.getRotation() == 270) && textBlock.getMinY() > btf.getY() + btf.getHeight()) {
return true;
} else {
return false;
@ -89,6 +89,9 @@ public class PositionUtils {
public Float getApproxLineCount(TextBlock textBlock) {
// float height = textBlock.getRotation() == 0 || textBlock.getRotation() == 180 ? textBlock.getHeight() : textBlock.getWidth();
return textBlock.getHeight() / textBlock.getMostPopularWordHeight();
}
}

View File

@ -93,9 +93,11 @@ public class PdfSegmentationService {
stripper.getText(pdDocument);
PDRectangle pdr = pdPage.getMediaBox();
boolean isLandscape = pdr.getWidth() > pdr.getHeight();
int rotation = pdPage.getRotation();
boolean isLandscape = pdr.getWidth() > pdr.getHeight() && (rotation == 0 || rotation == 180) ||
pdr.getHeight() > pdr.getWidth() && (rotation == 90 || rotation == 270);
System.out.println("PageNr: " + pageNumber + " rotation: "+rotation);
@ -125,7 +127,7 @@ public class PdfSegmentationService {
page.setCropBoxArea(cropboxArea);
page.setRotation(rotation);
page.setLandscape(isLandscape || isRotated);
page.setLandscape(isLandscape);
page.setPageNumber(pageNumber);

View File

@ -1,9 +1,13 @@
package com.iqser.red.service.redaction.v1.server.visualization.service;
import com.iqser.red.service.redaction.v1.model.Point;
import com.iqser.red.service.redaction.v1.model.Rectangle;
import com.iqser.red.service.redaction.v1.server.classification.model.Document;
import com.iqser.red.service.redaction.v1.server.classification.model.Page;
import com.iqser.red.service.redaction.v1.server.classification.model.Paragraph;
import com.iqser.red.service.redaction.v1.server.classification.model.TextBlock;
import com.iqser.red.service.redaction.v1.server.parsing.model.RedTextPosition;
import com.iqser.red.service.redaction.v1.server.parsing.model.TextDirection;
import com.iqser.red.service.redaction.v1.server.tableextraction.model.AbstractTextContainer;
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Cell;
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Table;
@ -16,6 +20,8 @@ import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.springframework.stereotype.Service;
import java.awt.Color;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.io.IOException;
import java.util.List;
@ -85,7 +91,11 @@ public class PdfVisualisationService {
contentStream.setStrokingColor(Color.YELLOW);
contentStream.addRect((float) analyzedPage.getBodyTextFrame().getX(), (float) analyzedPage.getBodyTextFrame().getY(), (float) analyzedPage.getBodyTextFrame().getWidth(), (float) analyzedPage.getBodyTextFrame().getHeight());
var rect = getRectangle((float) analyzedPage.getBodyTextFrame().getX(),(float) analyzedPage.getBodyTextFrame().getY(),(float) analyzedPage.getBodyTextFrame().getWidth(), (float) analyzedPage.getBodyTextFrame().getHeight(), pdPage.getRotation(), pdPage.getCropBox().getWidth(), pdPage.getCropBox().getHeight());
contentStream.addRect(rect.getTopLeft().getX(), rect.getTopLeft().getY(), rect.getWidth(), rect.getHeight());
contentStream.stroke();
contentStream.close();
@ -97,7 +107,9 @@ public class PdfVisualisationService {
contentStream.setStrokingColor(Color.RED);
contentStream.addRect(textBlock.getMinX(), textBlock.getMinY(), textBlock.getWidth(), textBlock.getHeight());
var rect = getRectangle(textBlock.getMinX(), textBlock.getMinY(), textBlock.getWidth(), textBlock.getHeight(), textBlock.getRotation(), textBlock.getSequences().get(0).getPageWidth(), textBlock.getSequences().get(0).getPageHeight());
contentStream.addRect(rect.getTopLeft().getX(), rect.getTopLeft().getY(), rect.getWidth(), rect.getHeight());
contentStream.stroke();
if (textBlock.getClassification() != null) {
@ -106,7 +118,7 @@ public class PdfVisualisationService {
contentStream.setNonStrokingColor(Color.BLUE);
contentStream.setFont(PDType1Font.TIMES_ROMAN, 6f);
contentStream.newLineAtOffset(textBlock.getMinX(), textBlock.getMaxY());
contentStream.newLineAtOffset(rect.getTopLeft().getX(), rect.getTopLeft().getY());
contentStream.showText(textBlock.getClassification() /*" textBlock.getOrientation() + "--> "*/ + number);
@ -115,6 +127,39 @@ public class PdfVisualisationService {
}
public Rectangle getRectangle(float x, float y, float width, float height, int rotation, float pageWidth, float pageHeight) {
Point2D bottomLeft = new Point2D.Double(x, pageHeight - y);
Point2D topRight = new Point2D.Double(x + width,pageHeight - y - height);
AffineTransform transform = new AffineTransform();
if (rotation == 0 || rotation == 180) {
transform.rotate(Math.toRadians(rotation), pageWidth / 2f, pageHeight / 2f);
transform.translate(0f, pageHeight);
transform.scale(1., -1.);
} else if (rotation == 90) {
transform.rotate(Math.toRadians(rotation), pageWidth / 2f, pageWidth / 2f);
transform.translate(0f, pageWidth);
transform.scale(1., -1.);
} else {
transform.rotate(Math.toRadians(rotation), pageHeight / 2f, pageHeight / 2f);
transform.translate(0f, pageWidth);
transform.scale(1., -1.);
}
bottomLeft = transform.transform(bottomLeft, null);
topRight = transform.transform(topRight, null);
return new Rectangle( //
new Point((float) bottomLeft.getX(), (float) bottomLeft.getY()), (float) (topRight.getX() - bottomLeft.getX()), (float) (topRight.getY() - bottomLeft.getY()), 0);
}
private void visualizeTable(Table table, PDPageContentStream contentStream) throws IOException {
for (List<Cell> row : table.getRows()) {
for (Cell cell : row) {

View File

@ -336,7 +336,7 @@ public class RedactionIntegrationTest {
System.out.println("Detailed quantitative and qualitative information on the composition of the plant ".length());
ClassPathResource pdfFileResource = new ClassPathResource("files/Trinexapac/91 Trinexapac-ethyl_RAR_01_Volume_1_2018-02-23.pdf");
ClassPathResource pdfFileResource = new ClassPathResource("files/Metolachlor/S-Metolachlor_RAR_02_Volume_2_2018-09-06.pdf");
AnalyzeRequest request = prepareStorage(pdfFileResource.getInputStream());
analyzeService.analyzeDocumentStructure(new StructureAnalyzeRequest(request.getDossierId(), request.getFileId()));
@ -1096,7 +1096,7 @@ public class RedactionIntegrationTest {
public void classificationTest() throws IOException {
System.out.println("classificationTest");
ClassPathResource pdfFileResource = new ClassPathResource("files/Trinexapac/91 Trinexapac-ethyl_RAR_01_Volume_1_2018-02-23.pdf");
ClassPathResource pdfFileResource = new ClassPathResource("files/RSS/02 - A22833B - Acute Oral (Up and Down) - Final Report.pdf");
AnalyzeRequest request = prepareStorage(pdfFileResource.getInputStream());