Compare commits
4 Commits
master
...
RED-5381-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dbc2e8e2f8 | ||
|
|
4616420e8f | ||
|
|
29f47fb17a | ||
|
|
dafc140f11 |
@ -1,5 +1,8 @@
|
||||
package com.iqser.red.service.redaction.v1.model;
|
||||
|
||||
import com.dslplatform.json.JsonAttribute;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
@ -14,4 +17,101 @@ public class Rectangle {
|
||||
private float height;
|
||||
|
||||
private int page;
|
||||
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
@JsonAttribute(ignore = true)
|
||||
public float getX1(int dir, float pageWidth, float pageHeight) {
|
||||
|
||||
if (dir == 90) {
|
||||
return topLeft.getX();
|
||||
}
|
||||
else if (dir == 180) {
|
||||
return pageWidth - topLeft.getX() + width;
|
||||
|
||||
}
|
||||
else if (dir == 270) {
|
||||
|
||||
return topLeft.getY() + height;
|
||||
}
|
||||
else {
|
||||
return topLeft.getX();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
@JsonAttribute(ignore = true)
|
||||
public float getX2(int dir, float pageWidth, float pageHeight) {
|
||||
|
||||
if (dir == 90) {
|
||||
return topLeft.getX() + width;
|
||||
}
|
||||
|
||||
else if (dir == 180) {
|
||||
return pageWidth - topLeft.getX();
|
||||
}
|
||||
|
||||
else if (dir == 270) {
|
||||
return topLeft.getY() ;
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
return topLeft.getX() + width;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
@JsonAttribute(ignore = true)
|
||||
public float getY1(int dir, float pageWidth, float pageHeight) {
|
||||
|
||||
if (dir == 90 ) {
|
||||
return topLeft.getY();
|
||||
}
|
||||
|
||||
else if (dir == 180) {
|
||||
return pageHeight - topLeft.getY() + height;
|
||||
|
||||
}
|
||||
|
||||
else if (dir == 270) {
|
||||
return pageHeight - topLeft.getX() ;
|
||||
|
||||
}
|
||||
else {
|
||||
return topLeft.getY();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
@JsonAttribute(ignore = true)
|
||||
public float getY2(int dir, float pageWidth, float pageHeight) {
|
||||
|
||||
if (dir == 90) {
|
||||
return topLeft.getY() + height;
|
||||
}
|
||||
|
||||
else if (dir == 180 ) {
|
||||
|
||||
return pageHeight - topLeft.getY();
|
||||
}
|
||||
|
||||
else if (dir == 270 ) {
|
||||
return pageHeight -topLeft.getX() - width;
|
||||
}
|
||||
|
||||
else {
|
||||
return topLeft.getY() + height;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
package com.iqser.red.service.redaction.v1.server.classification.model;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.model.Rectangle;
|
||||
import com.iqser.red.service.redaction.v1.server.redaction.model.PdfImage;
|
||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.AbstractTextContainer;
|
||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Rectangle;
|
||||
import lombok.Data;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -10,6 +10,8 @@ import lombok.RequiredArgsConstructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||
|
||||
@Data
|
||||
@RequiredArgsConstructor
|
||||
public class Page {
|
||||
@ -32,6 +34,7 @@ public class Page {
|
||||
private StringFrequencyCounter fontStyleCounter = new StringFrequencyCounter();
|
||||
|
||||
private double cropBoxArea;
|
||||
private PDRectangle cropBox;
|
||||
|
||||
|
||||
public boolean isRotated() {
|
||||
|
||||
@ -3,6 +3,7 @@ package com.iqser.red.service.redaction.v1.server.classification.model;
|
||||
import com.dslplatform.json.CompiledJson;
|
||||
import com.dslplatform.json.JsonAttribute;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.iqser.red.service.redaction.v1.server.parsing.model.TextDirection;
|
||||
import com.iqser.red.service.redaction.v1.server.parsing.model.TextPositionSequence;
|
||||
import com.iqser.red.service.redaction.v1.server.redaction.utils.TextNormalizationUtilities;
|
||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.AbstractTextContainer;
|
||||
@ -50,6 +51,115 @@ public class TextBlock extends AbstractTextContainer {
|
||||
private String classification;
|
||||
|
||||
|
||||
private TextDirection getDir(){
|
||||
return sequences.get(0).getDir();
|
||||
}
|
||||
|
||||
private float getPageHeight(){
|
||||
return sequences.get(0).getPageHeight();
|
||||
}
|
||||
|
||||
private float getPageWidth(){
|
||||
return sequences.get(0).getPageWidth();
|
||||
}
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
@JsonAttribute(ignore = true)
|
||||
public float getX1() {
|
||||
|
||||
if (getDir().getDegrees() == 90) {
|
||||
return minY;
|
||||
}
|
||||
else if (getDir().getDegrees() == 180) {
|
||||
return getPageWidth() - maxX;
|
||||
|
||||
}
|
||||
else if (getDir().getDegrees() == 270) {
|
||||
|
||||
return getPageWidth() - maxY ;
|
||||
}
|
||||
else {
|
||||
return minX;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
@JsonAttribute(ignore = true)
|
||||
public float getX2() {
|
||||
|
||||
if (getDir().getDegrees() == 90) {
|
||||
return maxY;
|
||||
}
|
||||
|
||||
else if (getDir().getDegrees() == 180) {
|
||||
return getPageWidth() - minX;
|
||||
}
|
||||
|
||||
else if (getDir().getDegrees() == 270) {
|
||||
return getPageWidth() - minY ;
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
return maxX;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
@JsonAttribute(ignore = true)
|
||||
public float getY1() {
|
||||
|
||||
if (getDir().getDegrees() == 90 ) {
|
||||
return minX;
|
||||
}
|
||||
|
||||
else if (getDir().getDegrees() == 180) {
|
||||
return maxY;
|
||||
|
||||
}
|
||||
|
||||
else if (getDir().getDegrees() == 270) {
|
||||
return getPageHeight() - maxX;
|
||||
|
||||
}
|
||||
else {
|
||||
return getPageHeight() - maxY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
@JsonAttribute(ignore = true)
|
||||
public float getY2() {
|
||||
|
||||
if (getDir().getDegrees() == 90) {
|
||||
return maxX;
|
||||
}
|
||||
|
||||
else if (getDir().getDegrees() == 180 ) {
|
||||
|
||||
return minY;
|
||||
}
|
||||
|
||||
else if (getDir().getDegrees() == 270 ) {
|
||||
return getPageHeight() - minX;
|
||||
}
|
||||
|
||||
else {
|
||||
return getPageHeight() - minY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public TextBlock(float minX, float maxX, float minY, float maxY, List<TextPositionSequence> sequences, int rotation) {
|
||||
this.minX = minX;
|
||||
this.maxX = maxX;
|
||||
|
||||
@ -2,13 +2,17 @@ package com.iqser.red.service.redaction.v1.server.classification.service;
|
||||
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
|
||||
import java.awt.geom.Line2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||
import org.springframework.stereotype.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.FloatFrequencyCounter;
|
||||
import com.iqser.red.service.redaction.v1.server.classification.model.Orientation;
|
||||
import com.iqser.red.service.redaction.v1.server.classification.model.Page;
|
||||
@ -18,7 +22,6 @@ import com.iqser.red.service.redaction.v1.server.classification.utils.PositionUt
|
||||
import com.iqser.red.service.redaction.v1.server.parsing.model.TextPositionSequence;
|
||||
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.Rectangle;
|
||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Ruling;
|
||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Table;
|
||||
|
||||
@ -30,9 +33,9 @@ public class BlockificationService {
|
||||
|
||||
|
||||
public Page blockify(List<TextPositionSequence> textPositions, List<Ruling> horizontalRulingLines,
|
||||
List<Ruling> verticalRulingLines) {
|
||||
List<Ruling> verticalRulingLines, PDRectangle cropbox) {
|
||||
|
||||
sortRotatedSequences(textPositions);
|
||||
// sortRotatedSequences(textPositions);
|
||||
|
||||
List<TextPositionSequence> chunkWords = new ArrayList<>();
|
||||
List<AbstractTextContainer> chunkBlockList1 = new ArrayList<>();
|
||||
@ -44,18 +47,20 @@ public class BlockificationService {
|
||||
Float splitX1 = null;
|
||||
for (TextPositionSequence word : textPositions) {
|
||||
|
||||
boolean lineSeparation = minY - word.getY2() > word.getHeight() * 1.25;
|
||||
boolean startFromTop = word.getY1() > maxY + word.getHeight();
|
||||
boolean lineSeparation = word.getY1() - maxY > word.getHeight() * 1.25;
|
||||
boolean startFromTop = prev != null && word.getY1() < prev.getY1() - prev.getTextHeight();
|
||||
boolean splitByX = prev != null && maxX + 50 < word.getX1() && prev.getY1() == word.getY1();
|
||||
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) ||
|
||||
isSplittedByRuling(minX, minY, word.getX1(), word.getY2(), horizontalRulingLines)
|
||||
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(), horizontalRulingLines)
|
||||
|| isSplittedByRuling(minX, minY, word.getX1(), word.getY2(), verticalRulingLines);
|
||||
|| isSplittedByRuling(maxX, minY, word.getX1(), word.getY1(), horizontalRulingLines,cropbox.getHeight())
|
||||
|| isSplittedByRuling(minX, minY, word.getX1(), word.getY2(), verticalRulingLines,cropbox.getHeight());
|
||||
boolean splitByDir = prev != null && !prev.getDir().equals(word.getDir());
|
||||
|
||||
if (prev != null && (lineSeparation || startFromTop || splitByX || newLineAfterSplit || splittedByRuling)) {
|
||||
if (prev != null && (lineSeparation || startFromTop || xIsBeforeFirstX || splitByX || splitByDir || startFromTop)) {
|
||||
|
||||
Orientation prevOrientation = null;
|
||||
if (!chunkBlockList1.isEmpty()) {
|
||||
@ -107,55 +112,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);
|
||||
}
|
||||
@ -216,10 +221,11 @@ public class BlockificationService {
|
||||
|
||||
|
||||
private boolean isSplittedByRuling(float previousX2, float previousY1, float currentX1, float currentY1,
|
||||
List<Ruling> rulingLines) {
|
||||
List<Ruling> rulingLines, float pageHeight) {
|
||||
|
||||
for (Ruling ruling : rulingLines) {
|
||||
if (ruling.intersectsLine(previousX2, previousY1, currentX1, currentY1)) {
|
||||
var line = new Line2D.Float(pageHeight -ruling.y1 , ruling.x1, pageHeight -ruling.y2, ruling.x2);
|
||||
if (line.intersectsLine(previousX2, previousY1, currentX1, currentY1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -257,17 +263,17 @@ public class BlockificationService {
|
||||
if (documentFontSizeCounter.getMostPopular() != null) {
|
||||
if (textBlock.getMostPopularWordFontSize() >= documentFontSizeCounter.getMostPopular()) {
|
||||
|
||||
if (textBlock.getMinX() < minX) {
|
||||
minX = textBlock.getMinX();
|
||||
if (textBlock.getX1() < minX) {
|
||||
minX = textBlock.getX1();
|
||||
}
|
||||
if (textBlock.getMaxX() > maxX) {
|
||||
maxX = textBlock.getMaxX();
|
||||
if (textBlock.getX2() > maxX) {
|
||||
maxX = textBlock.getX2();
|
||||
}
|
||||
if (textBlock.getMinY() < minY) {
|
||||
minY = textBlock.getMinY();
|
||||
if (textBlock.getY1() < minY) {
|
||||
minY = textBlock.getY1();
|
||||
}
|
||||
if (textBlock.getMaxY() > maxY) {
|
||||
maxY = textBlock.getMaxY();
|
||||
if (textBlock.getY2() > maxY) {
|
||||
maxY = textBlock.getY2();
|
||||
}
|
||||
|
||||
}
|
||||
@ -283,17 +289,17 @@ public class BlockificationService {
|
||||
continue;
|
||||
}
|
||||
for (TextBlock textBlock : cell.getTextBlocks()) {
|
||||
if (textBlock.getMinX() < minX) {
|
||||
minX = textBlock.getMinX();
|
||||
if (textBlock.getX1() < minX) {
|
||||
minX = textBlock.getX1();
|
||||
}
|
||||
if (textBlock.getMaxX() > maxX) {
|
||||
maxX = textBlock.getMaxX();
|
||||
if (textBlock.getX2() > maxX) {
|
||||
maxX = textBlock.getX2();
|
||||
}
|
||||
if (textBlock.getMinY() < minY) {
|
||||
minY = textBlock.getMinY();
|
||||
if (textBlock.getY1() < minY) {
|
||||
minY = textBlock.getY1();
|
||||
}
|
||||
if (textBlock.getMaxY() > maxY) {
|
||||
maxY = textBlock.getMaxY();
|
||||
if (textBlock.getY2() > maxY) {
|
||||
maxY = textBlock.getY2();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -302,7 +308,7 @@ public class BlockificationService {
|
||||
}
|
||||
|
||||
}
|
||||
return new Rectangle(minY, minX, maxX - minX, maxY - minY);
|
||||
return new Rectangle(new Point(minX, minY), maxX - minX, maxY - minY, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
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.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.TextBlock;
|
||||
import com.iqser.red.service.redaction.v1.server.classification.utils.PositionUtils;
|
||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.AbstractTextContainer;
|
||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Rectangle;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -32,7 +33,23 @@ public class ClassificationService {
|
||||
|
||||
for (Page page : document.getPages()) {
|
||||
Rectangle btf = page.isLandscape() ? landscapeBodyTextFrame : bodyTextFrame;
|
||||
|
||||
if (!page.isLandscape() && (page.getRotation() == 90 || page.getRotation() == 270)){
|
||||
var width = btf.getX2(page.getRotation(), page.getCropBox().getWidth(), page.getCropBox().getHeight()) - btf.getX1(page.getRotation(), page.getCropBox().getWidth(), page.getCropBox().getHeight());
|
||||
var height = btf.getY2(page.getRotation(), page.getCropBox().getWidth(), page.getCropBox().getHeight()) - btf.getY1(page.getRotation(), page.getCropBox().getWidth(), page.getCropBox().getHeight());
|
||||
|
||||
var x1= btf.getX1(page.getRotation(), page.getCropBox().getWidth(), page.getCropBox().getHeight());
|
||||
var y1 = btf.getY1(page.getRotation(), page.getCropBox().getWidth(), page.getCropBox().getHeight());
|
||||
|
||||
page.setBodyTextFrame(new Rectangle(new Point(x1, y1), width, height,0));
|
||||
} else if (page.getRotation() == 180) {
|
||||
page.setBodyTextFrame(new Rectangle(new Point(btf.getTopLeft().getX(), page.getCropBox().getHeight() - btf.getTopLeft().getY() -btf.getHeight()), btf.getWidth(), btf.getHeight(),0));
|
||||
} else {
|
||||
page.setBodyTextFrame(btf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
classifyPage(btf, page, document, headlineFontSizes);
|
||||
}
|
||||
}
|
||||
@ -51,6 +68,8 @@ public class ClassificationService {
|
||||
public void classifyBlock(TextBlock textBlock, Rectangle bodyTextFrame, Page page, Document document,
|
||||
List<Float> headlineFontSizes) {
|
||||
|
||||
System.out.println("Page: " + page.getPageNumber() + " rotation " + page.getRotation() +" B " + textBlock.getSequences().get(0).getDir());
|
||||
|
||||
if (document.getFontSizeCounter().getMostPopular() == null) {
|
||||
textBlock.setClassification("Other");
|
||||
return;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package com.iqser.red.service.redaction.v1.server.classification.utils;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.model.Rectangle;
|
||||
import com.iqser.red.service.redaction.v1.server.classification.model.TextBlock;
|
||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Rectangle;
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
@UtilityClass
|
||||
@ -19,10 +19,10 @@ public class PositionUtils {
|
||||
|
||||
double threshold = textBlock.getMostPopularWordHeight() * 3;
|
||||
|
||||
if (textBlock.getMinX() + threshold > btf.getX() &&
|
||||
textBlock.getMaxX() - threshold < btf.getX() + btf.getWidth() &&
|
||||
textBlock.getMinY() + threshold > btf.getY() &&
|
||||
textBlock.getMaxY() - threshold < btf.getY() + btf.getHeight()) {
|
||||
if (textBlock.getMinX() + threshold > btf.getTopLeft().getX() &&
|
||||
textBlock.getMaxX() - threshold < btf.getTopLeft().getX() + btf.getWidth() &&
|
||||
textBlock.getMinY() + threshold > btf.getTopLeft().getY() &&
|
||||
textBlock.getMaxY() - threshold < btf.getTopLeft().getY() + btf.getHeight()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -37,10 +37,10 @@ public class PositionUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rotated && textBlock.getMinX() < btf.getX()) {
|
||||
if (rotated && textBlock.getMinX() < btf.getTopLeft().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 (!rotated && textBlock.getMinY() > btf.getTopLeft().getY() + btf.getHeight()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -57,7 +57,7 @@ public class PositionUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (textBlock.getMaxY() < btf.getY()) {
|
||||
if (textBlock.getMaxY() < btf.getTopLeft().getY()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -74,7 +74,7 @@ public class PositionUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (textBlock.getMinY() < btf.getY()) {
|
||||
if (textBlock.getMinY() < btf.getTopLeft().getY()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
||||
@ -147,29 +147,6 @@ public class TextPositionSequence implements CharSequence {
|
||||
}
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
@JsonAttribute(ignore = true)
|
||||
public float getX1() {
|
||||
|
||||
if (rotation == 90) {
|
||||
return textPositions.get(0).getYDirAdj() - getTextHeight();
|
||||
} else {
|
||||
return textPositions.get(0).getXDirAdj();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
@JsonAttribute(ignore = true)
|
||||
public float getX2() {
|
||||
|
||||
if (rotation == 90) {
|
||||
return textPositions.get(0).getYDirAdj();
|
||||
} else {
|
||||
return textPositions.get(textPositions.size() - 1).getXDirAdj() + textPositions.get(textPositions.size() - 1).getWidthDirAdj() + HEIGHT_PADDING;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
@JsonAttribute(ignore = true)
|
||||
@ -179,15 +156,40 @@ public class TextPositionSequence implements CharSequence {
|
||||
}
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
@JsonAttribute(ignore = true)
|
||||
public float getX1() {
|
||||
|
||||
|
||||
return textPositions.get(0).getXDirAdj();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
@JsonAttribute(ignore = true)
|
||||
public float getX2() {
|
||||
|
||||
|
||||
return textPositions.get(textPositions.size() - 1).getXDirAdj() + textPositions.get(textPositions.size() - 1).getWidthDirAdj() + HEIGHT_PADDING;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
@JsonAttribute(ignore = true)
|
||||
public float getY1() {
|
||||
|
||||
if (rotation == 90) {
|
||||
return textPositions.get(0).getXDirAdj();
|
||||
} else {
|
||||
return pageHeight - textPositions.get(0).getYDirAdj();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return textPositions.get(0).getYDirAdj() - getTextHeight();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -195,14 +197,15 @@ public class TextPositionSequence implements CharSequence {
|
||||
@JsonAttribute(ignore = true)
|
||||
public float getY2() {
|
||||
|
||||
if (rotation == 90) {
|
||||
return textPositions.get(textPositions.size() - 1).getXDirAdj() + getTextHeight() - HEIGHT_PADDING;
|
||||
} else {
|
||||
return pageHeight - textPositions.get(0).getYDirAdj() + getTextHeight();
|
||||
}
|
||||
|
||||
|
||||
|
||||
return textPositions.get(0).getYDirAdj();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
@JsonAttribute(ignore = true)
|
||||
public float getTextHeight() {
|
||||
|
||||
@ -99,21 +99,23 @@ public class PdfSegmentationService {
|
||||
stripper.getText(pdDocument);
|
||||
|
||||
PDRectangle pdr = pdPage.getMediaBox();
|
||||
boolean isLandscape = pdr.getWidth() > pdr.getHeight();
|
||||
|
||||
int rotation = pdPage.getRotation();
|
||||
boolean isRotated = rotation != 0 && rotation != 360;
|
||||
|
||||
CleanRulings cleanRulings = rulingCleaningService.getCleanRulings(pdfTableCells.get(pageNumber), stripper.getRulings(), stripper.getMinCharWidth(), stripper.getMaxCharHeight());
|
||||
Page page = blockificationService.blockify(stripper.getTextPositionSequences(), cleanRulings.getHorizontal(), cleanRulings.getVertical());
|
||||
boolean isLandscape = pdr.getWidth() > pdr.getHeight() && (rotation == 0 || rotation == 180) ||
|
||||
pdr.getHeight() > pdr.getWidth() && (rotation == 90 || rotation == 270);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
float cropboxArea = cropbox.getHeight() * cropbox.getWidth();
|
||||
page.setCropBoxArea(cropboxArea);
|
||||
|
||||
page.setRotation(rotation);
|
||||
page.setLandscape(isLandscape || isRotated);
|
||||
page.setLandscape(isLandscape);
|
||||
page.setPageNumber(pageNumber);
|
||||
page.setCropBox(cropbox);
|
||||
|
||||
tableExtractionService.extractTables(cleanRulings, page);
|
||||
buildPageStatistics(page);
|
||||
|
||||
@ -31,6 +31,10 @@ public class Rectangle extends Rectangle2D.Float {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public Rectangle() {
|
||||
super();
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ public class TableExtractionService {
|
||||
for (AbstractTextContainer abstractTextContainer : page.getTextBlocks()) {
|
||||
TextBlock textBlock = (TextBlock) abstractTextContainer;
|
||||
for (Cell cell : cells) {
|
||||
if (cell.intersects(textBlock.getMinX(), textBlock.getMinY(), textBlock.getWidth(), textBlock.getHeight())) {
|
||||
if (cell.intersects(textBlock.getX1(), textBlock.getY1(), textBlock.getX2() - textBlock.getX1(), textBlock.getY2() - textBlock.getY1())) {
|
||||
cell.addTextBlock(textBlock);
|
||||
toBeRemoved.add(textBlock);
|
||||
break;
|
||||
|
||||
@ -79,7 +79,10 @@ 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 widhth = analyzedPage.getBodyTextFrame().getX2(pdPage.getRotation(), pdPage.getCropBox().getWidth(), pdPage.getCropBox().getHeight()) - analyzedPage.getBodyTextFrame().getX1(pdPage.getRotation(), pdPage.getCropBox().getWidth(), pdPage.getCropBox().getHeight());
|
||||
// var height = analyzedPage.getBodyTextFrame().getY2(pdPage.getRotation(), pdPage.getCropBox().getWidth(), pdPage.getCropBox().getHeight()) - analyzedPage.getBodyTextFrame().getY1(pdPage.getRotation(), pdPage.getCropBox().getWidth(), pdPage.getCropBox().getHeight());
|
||||
|
||||
contentStream.addRect(analyzedPage.getBodyTextFrame().getTopLeft().getX(), analyzedPage.getBodyTextFrame().getTopLeft().getY(), analyzedPage.getBodyTextFrame().getWidth(), analyzedPage.getBodyTextFrame().getHeight());
|
||||
contentStream.stroke();
|
||||
|
||||
contentStream.close();
|
||||
@ -91,18 +94,41 @@ public class PdfVisualisationService {
|
||||
|
||||
contentStream.setStrokingColor(Color.RED);
|
||||
|
||||
contentStream.addRect(textBlock.getMinX(), textBlock.getMinY(), textBlock.getWidth(), textBlock.getHeight());
|
||||
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, 12f);
|
||||
contentStream.setFont(PDType1Font.TIMES_ROMAN, 2f);
|
||||
|
||||
contentStream.newLineAtOffset(textBlock.getMinX(), textBlock.getMaxY());
|
||||
|
||||
contentStream.showText(textBlock.getClassification() + textBlock.getOrientation());
|
||||
|
||||
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();
|
||||
}
|
||||
@ -120,7 +146,7 @@ public class PdfVisualisationService {
|
||||
|
||||
contentStream.setStrokingColor(Color.GREEN);
|
||||
for (TextBlock textBlock : cell.getTextBlocks()) {
|
||||
contentStream.addRect(textBlock.getMinX(), textBlock.getMinY(), textBlock.getWidth(), textBlock.getHeight());
|
||||
contentStream.addRect(textBlock.getX1(), textBlock.getY1(), textBlock.getX2() - textBlock.getX1(), textBlock.getY2() - textBlock.getY1());
|
||||
contentStream.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1168,7 +1168,7 @@ public class RedactionIntegrationTest {
|
||||
|
||||
System.out.println("classificationTest");
|
||||
|
||||
AnalyzeRequest request = prepareStorage("files/Metolachlor/S-Metolachlor_RAR_01_Volume_1_2018-09-06.pdf");
|
||||
AnalyzeRequest request = prepareStorage("files/new/VV-511309_OCR.pdf");
|
||||
|
||||
RedactionRequest redactionRequest = RedactionRequest.builder()
|
||||
.dossierId(request.getDossierId())
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user