RED-5381: Fixed header and footer detection

This commit is contained in:
deiflaender 2022-10-19 17:07:11 +02:00
parent 4be5487e64
commit b10958cb6a
5 changed files with 125 additions and 87 deletions

View File

@ -19,6 +19,7 @@ import com.iqser.red.service.redaction.v1.server.classification.model.Orientatio
import com.iqser.red.service.redaction.v1.server.classification.model.Page;
import com.iqser.red.service.redaction.v1.server.classification.model.StringFrequencyCounter;
import com.iqser.red.service.redaction.v1.server.classification.model.TextBlock;
import com.iqser.red.service.redaction.v1.server.classification.utils.CoordSystemHelper;
import com.iqser.red.service.redaction.v1.server.classification.utils.PositionUtils;
import com.iqser.red.service.redaction.v1.server.parsing.model.TextPositionSequence;
import com.iqser.red.service.redaction.v1.server.tableextraction.model.AbstractTextContainer;
@ -225,7 +226,7 @@ public class BlockificationService {
List<Ruling> rulingLines, float rotation, float pageWidth, float pageHeight) {
for (Ruling ruling : rulingLines) {
var line = convertToJavaCoord(ruling, rotation, pageWidth, pageHeight);
var line = CoordSystemHelper.convertToDirAdj(ruling, rotation, pageWidth, pageHeight);
if (line.intersectsLine(previousX2, previousY1, currentX1, currentY1)) {
return true;
}
@ -234,71 +235,8 @@ 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;
}

View File

@ -36,18 +36,19 @@ public class ClassificationService {
if(page.getCropBox().getWidth() > page.getCropBox().getHeight() && page.getRotation() == 270) {
page.setBodyTextFrame(new Rectangle(new Point(btf.getTopLeft().getY(),page.getCropBox().getHeight() - btf.getTopLeft().getX()), btf.getHeight(), -btf.getWidth(), 0));
btf = new Rectangle(new Point(btf.getTopLeft().getY(),page.getCropBox().getHeight() - btf.getTopLeft().getX() -btf.getWidth()), btf.getHeight(), btf.getWidth(), 0);
}
else if(page.getCropBox().getWidth() > page.getCropBox().getHeight() && page.getRotation() != 0) {
page.setBodyTextFrame(new Rectangle(new Point(btf.getTopLeft().getY(), btf.getTopLeft().getX()), btf.getHeight(), btf.getWidth(), 0));
btf = new Rectangle(new Point(btf.getTopLeft().getY(), btf.getTopLeft().getX()), btf.getHeight(), btf.getWidth(), 0);
}
else if(page.getRotation() == 180){
page.setBodyTextFrame(new Rectangle(new Point( btf.getTopLeft().getX(), page.getCropBox().getHeight() - btf.getTopLeft().getY()), btf.getWidth(), -btf.getHeight(), 0));
btf = new Rectangle(new Point( btf.getTopLeft().getX(), page.getCropBox().getHeight() - btf.getTopLeft().getY() -btf.getHeight()), btf.getWidth(), btf.getHeight(), 0);
}
else {
page.setBodyTextFrame(btf);
}
@ -72,18 +73,23 @@ public class ClassificationService {
System.out.println("Page: " + page.getPageNumber() + " rotation " + page.getRotation() +" B " + textBlock.getSequences().get(0).getDir());
if (document.getFontSizeCounter().getMostPopular() == null) {
textBlock.setClassification("Other");
return;
}
if (PositionUtils.isOverBodyTextFrame(bodyTextFrame, textBlock, page.isRotated()) && (document.getFontSizeCounter()
.getMostPopular() == null || textBlock.getHighestFontSize() <= document.getFontSizeCounter()
.getMostPopular())) {
// if (document.getFontSizeCounter().getMostPopular() == null) {
// textBlock.setClassification("Other");
// return;
// }
if (PositionUtils.isOverBodyTextFrame(bodyTextFrame, textBlock, page.getRotation()))
// && (document.getFontSizeCounter()
// .getMostPopular() == null || textBlock.getHighestFontSize() <= document.getFontSizeCounter()
// .getMostPopular()))
{
textBlock.setClassification("Header");
} else if (PositionUtils.isUnderBodyTextFrame(bodyTextFrame, textBlock) && (document.getFontSizeCounter()
.getMostPopular() == null || textBlock.getHighestFontSize() <= document.getFontSizeCounter()
.getMostPopular())) {
} else if (PositionUtils.isUnderBodyTextFrame(bodyTextFrame, textBlock, page.getRotation()))
// && (document.getFontSizeCounter()
// .getMostPopular() == null || textBlock.getHighestFontSize() <= document.getFontSizeCounter()
// .getMostPopular()))
{
textBlock.setClassification("Footer");
} else if (page.getPageNumber() == 1 && (!PositionUtils.isTouchingUnderBodyTextFrame(bodyTextFrame, textBlock) && PositionUtils
.getHeightDifferenceBetweenChunkWordAndDocumentWord(textBlock, document.getTextHeightCounter()

View File

@ -0,0 +1,74 @@
package com.iqser.red.service.redaction.v1.server.classification.utils;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
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.tableextraction.model.Ruling;
import lombok.experimental.UtilityClass;
@UtilityClass
public class CoordSystemHelper {
public Rectangle convertToDirAdj(Rectangle rectangle, float rotation, float pageWidth, float pageHeight) {
var topLeft = convertPoint(rectangle.getTopLeft().getX(), rectangle.getTopLeft().getY() + rectangle.getHeight(), rotation, pageWidth, pageHeight);
var bottomRight = convertPoint(rectangle.getTopLeft().getX() + rectangle.getWidth(), rectangle.getTopLeft().getY() , rotation, pageWidth, pageHeight);
return new Rectangle(new Point((float)topLeft.getX(),(float) topLeft.getY()), (float) (bottomRight.getX() - topLeft.getX()), (float) (bottomRight.getY() - topLeft.getY()), 0);
}
public Line2D.Float convertToDirAdj(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;
}
}

View File

@ -31,16 +31,25 @@ public class PositionUtils {
}
public boolean isOverBodyTextFrame(Rectangle btf, TextBlock textBlock, boolean rotated) {
public boolean isOverBodyTextFrame(Rectangle btf, TextBlock textBlock, int rotation) {
if (btf == null || textBlock == null) {
return false;
}
if (rotated && textBlock.getMinX() < btf.getTopLeft().getX()) {
// Its very strange, P{0,0} is on top left in this case, instead of lower left.
if (rotation == 90 && textBlock.getX2() < btf.getTopLeft().getX()) {
return true;
} else if (!rotated && textBlock.getMinY() > btf.getTopLeft().getY() + btf.getHeight()) {
}
if(rotation == 180 && textBlock.getY2() < btf.getTopLeft().getY()){
return true;
}
if (rotation == 270 && textBlock.getX1() > btf.getTopLeft().getX() + btf.getWidth()) {
return true;
}
if (rotation == 0 && textBlock.getY1() > btf.getTopLeft().getY() + btf.getHeight()) {
return true;
} else {
return false;
@ -49,15 +58,26 @@ public class PositionUtils {
}
public boolean isUnderBodyTextFrame(Rectangle btf, TextBlock textBlock) {
public boolean isUnderBodyTextFrame(Rectangle btf, TextBlock textBlock, int rotation) {
//TODO Currently this is not working for rotated pages.
if (btf == null || textBlock == null) {
return false;
}
if (textBlock.getMaxY() < btf.getTopLeft().getY()) {
if (rotation == 90 && textBlock.getX1() > btf.getTopLeft().getX() + btf.getWidth()) {
return true;
}
if (rotation == 180 && textBlock.getY1() > btf.getTopLeft().getY() + btf.getHeight()) {
return true;
}
if (rotation == 270 && textBlock.getX2() < btf.getTopLeft().getX()) {
return true;
}
if (rotation == 0 && textBlock.getY2() < btf.getTopLeft().getY()) {
return true;
} else {
return false;

View File

@ -1098,7 +1098,7 @@ public class RedactionIntegrationTest {
System.out.println("classificationTest");
AnalyzeRequest request = prepareStorage("files/Primicarb/74 Pirimicarb_RAR_01_Volume_1_2017-12-04.pdf");
AnalyzeRequest request = prepareStorage("files/new/VV-511309_OCR.pdf");
RedactionRequest redactionRequest = RedactionRequest.builder()
.dossierId(request.getDossierId())