RED-5381 Test 2
This commit is contained in:
parent
5f0b7d8344
commit
2f72dc895c
@ -1,5 +1,8 @@
|
|||||||
package com.iqser.red.service.redaction.v1.model;
|
package com.iqser.red.service.redaction.v1.model;
|
||||||
|
|
||||||
|
import com.dslplatform.json.JsonAttribute;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@ -15,4 +18,100 @@ public class Rectangle {
|
|||||||
|
|
||||||
private int page;
|
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,9 +1,8 @@
|
|||||||
package com.iqser.red.service.redaction.v1.server.classification.model;
|
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.redaction.model.PdfImage;
|
||||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.AbstractTextContainer;
|
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.Data;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@ -11,6 +10,8 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class Page {
|
public class Page {
|
||||||
@ -33,6 +34,7 @@ public class Page {
|
|||||||
private StringFrequencyCounter fontStyleCounter = new StringFrequencyCounter();
|
private StringFrequencyCounter fontStyleCounter = new StringFrequencyCounter();
|
||||||
|
|
||||||
private double cropBoxArea;
|
private double cropBoxArea;
|
||||||
|
private PDRectangle cropBox;
|
||||||
|
|
||||||
|
|
||||||
public boolean isRotated() {
|
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.CompiledJson;
|
||||||
import com.dslplatform.json.JsonAttribute;
|
import com.dslplatform.json.JsonAttribute;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
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.parsing.model.TextPositionSequence;
|
||||||
import com.iqser.red.service.redaction.v1.server.redaction.utils.TextNormalizationUtilities;
|
import com.iqser.red.service.redaction.v1.server.redaction.utils.TextNormalizationUtilities;
|
||||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.AbstractTextContainer;
|
import com.iqser.red.service.redaction.v1.server.tableextraction.model.AbstractTextContainer;
|
||||||
@ -50,6 +51,115 @@ public class TextBlock extends AbstractTextContainer {
|
|||||||
private String classification;
|
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 minX;
|
||||||
|
}
|
||||||
|
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 maxX;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 minY;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (getDir().getDegrees() == 180) {
|
||||||
|
return getPageHeight() - maxY;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (getDir().getDegrees() == 270) {
|
||||||
|
return getPageHeight() - maxX;
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return minY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@JsonAttribute(ignore = true)
|
||||||
|
public float getY2() {
|
||||||
|
|
||||||
|
if (getDir().getDegrees() == 90) {
|
||||||
|
return maxY;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (getDir().getDegrees() == 180 ) {
|
||||||
|
|
||||||
|
return getPageHeight() - minY;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (getDir().getDegrees() == 270 ) {
|
||||||
|
return getPageHeight() - minX;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
return maxY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public TextBlock(float minX, float maxX, float minY, float maxY, List<TextPositionSequence> sequences, int rotation) {
|
public TextBlock(float minX, float maxX, float minY, float maxY, List<TextPositionSequence> sequences, int rotation) {
|
||||||
|
|
||||||
this.minX = minX;
|
this.minX = minX;
|
||||||
|
|||||||
@ -9,6 +9,8 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
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.FloatFrequencyCounter;
|
||||||
import com.iqser.red.service.redaction.v1.server.classification.model.Orientation;
|
import com.iqser.red.service.redaction.v1.server.classification.model.Orientation;
|
||||||
import com.iqser.red.service.redaction.v1.server.classification.model.Page;
|
import com.iqser.red.service.redaction.v1.server.classification.model.Page;
|
||||||
@ -18,7 +20,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.parsing.model.TextPositionSequence;
|
||||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.AbstractTextContainer;
|
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.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.Ruling;
|
||||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Table;
|
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Table;
|
||||||
|
|
||||||
@ -32,7 +33,7 @@ public class BlockificationService {
|
|||||||
public Page blockify(List<TextPositionSequence> textPositions, List<Ruling> horizontalRulingLines,
|
public Page blockify(List<TextPositionSequence> textPositions, List<Ruling> horizontalRulingLines,
|
||||||
List<Ruling> verticalRulingLines) {
|
List<Ruling> verticalRulingLines) {
|
||||||
|
|
||||||
sortRotatedSequences(textPositions);
|
// sortRotatedSequences(textPositions);
|
||||||
|
|
||||||
List<TextPositionSequence> chunkWords = new ArrayList<>();
|
List<TextPositionSequence> chunkWords = new ArrayList<>();
|
||||||
List<AbstractTextContainer> chunkBlockList1 = new ArrayList<>();
|
List<AbstractTextContainer> chunkBlockList1 = new ArrayList<>();
|
||||||
@ -108,55 +109,55 @@ public class BlockificationService {
|
|||||||
chunkBlockList1.add(cb1);
|
chunkBlockList1.add(cb1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator<AbstractTextContainer> itty = chunkBlockList1.iterator();
|
// Iterator<AbstractTextContainer> itty = chunkBlockList1.iterator();
|
||||||
|
//
|
||||||
TextBlock previousLeft = null;
|
// TextBlock previousLeft = null;
|
||||||
TextBlock previousRight = null;
|
// TextBlock previousRight = null;
|
||||||
while (itty.hasNext()) {
|
// while (itty.hasNext()) {
|
||||||
TextBlock block = (TextBlock) itty.next();
|
// TextBlock block = (TextBlock) itty.next();
|
||||||
|
//
|
||||||
if (previousLeft != null && block.getOrientation().equals(Orientation.LEFT)) {
|
// if (previousLeft != null && block.getOrientation().equals(Orientation.LEFT)) {
|
||||||
if (previousLeft.getMinY() > block.getMinY() && block.getMaxY() + block.getMostPopularWordHeight() > previousLeft
|
// if (previousLeft.getMinY() > block.getMinY() && block.getMaxY() + block.getMostPopularWordHeight() > previousLeft
|
||||||
.getMinY()) {
|
// .getMinY()) {
|
||||||
previousLeft.add(block);
|
// previousLeft.add(block);
|
||||||
itty.remove();
|
// itty.remove();
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (previousRight != null && block.getOrientation().equals(Orientation.RIGHT)) {
|
// if (previousRight != null && block.getOrientation().equals(Orientation.RIGHT)) {
|
||||||
if (previousRight.getMinY() > block.getMinY() && block.getMaxY() + block.getMostPopularWordHeight() > previousRight
|
// if (previousRight.getMinY() > block.getMinY() && block.getMaxY() + block.getMostPopularWordHeight() > previousRight
|
||||||
.getMinY()) {
|
// .getMinY()) {
|
||||||
previousRight.add(block);
|
// previousRight.add(block);
|
||||||
itty.remove();
|
// itty.remove();
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (block.getOrientation().equals(Orientation.LEFT)) {
|
// if (block.getOrientation().equals(Orientation.LEFT)) {
|
||||||
previousLeft = block;
|
// previousLeft = block;
|
||||||
} else if (block.getOrientation().equals(Orientation.RIGHT)) {
|
// } else if (block.getOrientation().equals(Orientation.RIGHT)) {
|
||||||
previousRight = block;
|
// previousRight = block;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
itty = chunkBlockList1.iterator();
|
// itty = chunkBlockList1.iterator();
|
||||||
TextBlock previous = null;
|
// TextBlock previous = null;
|
||||||
while (itty.hasNext()) {
|
// while (itty.hasNext()) {
|
||||||
TextBlock block = (TextBlock) itty.next();
|
// TextBlock block = (TextBlock) itty.next();
|
||||||
|
//
|
||||||
if (previous != null && previous.getOrientation().equals(Orientation.LEFT) && block.getOrientation()
|
// if (previous != null && previous.getOrientation().equals(Orientation.LEFT) && block.getOrientation()
|
||||||
.equals(Orientation.LEFT) && equalsWithThreshold(block.getMaxY(), previous.getMaxY()) || previous != null && previous
|
// .equals(Orientation.LEFT) && equalsWithThreshold(block.getMaxY(), previous.getMaxY()) || previous != null && previous
|
||||||
.getOrientation()
|
// .getOrientation()
|
||||||
.equals(Orientation.LEFT) && block.getOrientation()
|
// .equals(Orientation.LEFT) && block.getOrientation()
|
||||||
.equals(Orientation.RIGHT) && equalsWithThreshold(block.getMaxY(), previous.getMaxY())) {
|
// .equals(Orientation.RIGHT) && equalsWithThreshold(block.getMaxY(), previous.getMaxY())) {
|
||||||
previous.add(block);
|
// previous.add(block);
|
||||||
itty.remove();
|
// itty.remove();
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
previous = block;
|
// previous = block;
|
||||||
}
|
// }
|
||||||
|
|
||||||
return new Page(chunkBlockList1);
|
return new Page(chunkBlockList1);
|
||||||
}
|
}
|
||||||
@ -258,17 +259,17 @@ public class BlockificationService {
|
|||||||
if (documentFontSizeCounter.getMostPopular() != null) {
|
if (documentFontSizeCounter.getMostPopular() != null) {
|
||||||
if (textBlock.getMostPopularWordFontSize() >= documentFontSizeCounter.getMostPopular()) {
|
if (textBlock.getMostPopularWordFontSize() >= documentFontSizeCounter.getMostPopular()) {
|
||||||
|
|
||||||
if (textBlock.getMinX() < minX) {
|
if (textBlock.getX1() < minX) {
|
||||||
minX = textBlock.getMinX();
|
minX = textBlock.getX1();
|
||||||
}
|
}
|
||||||
if (textBlock.getMaxX() > maxX) {
|
if (textBlock.getX2() > maxX) {
|
||||||
maxX = textBlock.getMaxX();
|
maxX = textBlock.getX2();
|
||||||
}
|
}
|
||||||
if (textBlock.getMinY() < minY) {
|
if (textBlock.getY1() < minY) {
|
||||||
minY = textBlock.getMinY();
|
minY = textBlock.getY1();
|
||||||
}
|
}
|
||||||
if (textBlock.getMaxY() > maxY) {
|
if (textBlock.getY2() > maxY) {
|
||||||
maxY = textBlock.getMaxY();
|
maxY = textBlock.getY2();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -284,17 +285,17 @@ public class BlockificationService {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (TextBlock textBlock : cell.getTextBlocks()) {
|
for (TextBlock textBlock : cell.getTextBlocks()) {
|
||||||
if (textBlock.getMinX() < minX) {
|
if (textBlock.getX1() < minX) {
|
||||||
minX = textBlock.getMinX();
|
minX = textBlock.getX1();
|
||||||
}
|
}
|
||||||
if (textBlock.getMaxX() > maxX) {
|
if (textBlock.getX2() > maxX) {
|
||||||
maxX = textBlock.getMaxX();
|
maxX = textBlock.getX2();
|
||||||
}
|
}
|
||||||
if (textBlock.getMinY() < minY) {
|
if (textBlock.getY1() < minY) {
|
||||||
minY = textBlock.getMinY();
|
minY = textBlock.getY1();
|
||||||
}
|
}
|
||||||
if (textBlock.getMaxY() > maxY) {
|
if (textBlock.getY2() > maxY) {
|
||||||
maxY = textBlock.getMaxY();
|
maxY = textBlock.getY2();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -303,7 +304,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,15 +1,14 @@
|
|||||||
package com.iqser.red.service.redaction.v1.server.classification.service;
|
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.Document;
|
||||||
import com.iqser.red.service.redaction.v1.server.classification.model.Page;
|
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.model.TextBlock;
|
||||||
import com.iqser.red.service.redaction.v1.server.classification.utils.PositionUtils;
|
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.AbstractTextContainer;
|
||||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Rectangle;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -34,7 +33,23 @@ public class ClassificationService {
|
|||||||
|
|
||||||
for (Page page : document.getPages()) {
|
for (Page page : document.getPages()) {
|
||||||
Rectangle btf = page.isLandscape() ? landscapeBodyTextFrame : bodyTextFrame;
|
Rectangle btf = page.isLandscape() ? landscapeBodyTextFrame : bodyTextFrame;
|
||||||
page.setBodyTextFrame(btf);
|
|
||||||
|
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);
|
classifyPage(btf, page, document, headlineFontSizes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,34 +65,37 @@ public class ClassificationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void classifyBlock(TextBlock textBlock, Rectangle bodyTextFrame, Page page, Document document, List<Float> headlineFontSizes) {
|
public void classifyBlock(TextBlock textBlock, Rectangle bodyTextFrame, Page page, Document document,
|
||||||
|
List<Float> headlineFontSizes) {
|
||||||
|
|
||||||
|
System.out.println("B" + textBlock.getSequences().get(0).getDir());
|
||||||
|
|
||||||
if (document.getFontSizeCounter().getMostPopular() == null) {
|
if (document.getFontSizeCounter().getMostPopular() == null) {
|
||||||
textBlock.setClassification("Other");
|
textBlock.setClassification("Other");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (PositionUtils.isOverBodyTextFrame(bodyTextFrame, textBlock, page.isRotated()) && (document.getFontSizeCounter()
|
if (PositionUtils.isOverBodyTextFrame(bodyTextFrame, textBlock, page.isRotated()) && (document.getFontSizeCounter()
|
||||||
.getMostPopular() == null || textBlock.getHighestFontSize() <= document.getFontSizeCounter().getMostPopular())) {
|
.getMostPopular() == null || textBlock.getHighestFontSize() <= document.getFontSizeCounter()
|
||||||
|
.getMostPopular())) {
|
||||||
textBlock.setClassification("Header");
|
textBlock.setClassification("Header");
|
||||||
|
|
||||||
} else if (PositionUtils.isUnderBodyTextFrame(bodyTextFrame, textBlock) && (document.getFontSizeCounter()
|
} else if (PositionUtils.isUnderBodyTextFrame(bodyTextFrame, textBlock) && (document.getFontSizeCounter()
|
||||||
.getMostPopular() == null || textBlock.getHighestFontSize() <= document.getFontSizeCounter().getMostPopular())) {
|
.getMostPopular() == null || textBlock.getHighestFontSize() <= document.getFontSizeCounter()
|
||||||
|
.getMostPopular())) {
|
||||||
textBlock.setClassification("Footer");
|
textBlock.setClassification("Footer");
|
||||||
} else if (page.getPageNumber() == 1 && (!PositionUtils.isTouchingUnderBodyTextFrame(bodyTextFrame,
|
} else if (page.getPageNumber() == 1 && (!PositionUtils.isTouchingUnderBodyTextFrame(bodyTextFrame, textBlock) && PositionUtils
|
||||||
textBlock) && PositionUtils.getHeightDifferenceBetweenChunkWordAndDocumentWord(textBlock,
|
.getHeightDifferenceBetweenChunkWordAndDocumentWord(textBlock, document.getTextHeightCounter()
|
||||||
document.getTextHeightCounter().getMostPopular()) > 2.5 && textBlock.getHighestFontSize() > document.getFontSizeCounter().getMostPopular() || page.getTextBlocks()
|
.getMostPopular()) > 2.5 && textBlock.getHighestFontSize() > document.getFontSizeCounter()
|
||||||
.size() == 1)) {
|
.getMostPopular() || page.getTextBlocks().size() == 1)) {
|
||||||
if (!Pattern.matches("[0-9]+", textBlock.toString())) {
|
if (!Pattern.matches("[0-9]+", textBlock.toString())) {
|
||||||
textBlock.setClassification("Title");
|
textBlock.setClassification("Title");
|
||||||
}
|
}
|
||||||
} else if (PositionUtils.isWithinBodyTextFrame(bodyTextFrame, textBlock) && textBlock.getMostPopularWordFontSize() > document.getFontSizeCounter()
|
} else if (PositionUtils.isWithinBodyTextFrame(bodyTextFrame, textBlock) && textBlock.getMostPopularWordFontSize() > document
|
||||||
.getMostPopular() && PositionUtils.getApproxLineCount(textBlock) < 4.9 && (textBlock.getMostPopularWordStyle().equals("bold") || !document.getFontStyleCounter()
|
.getFontSizeCounter()
|
||||||
.getCountPerValue()
|
.getMostPopular() && PositionUtils.getApproxLineCount(textBlock) < 4.9 && (textBlock.getMostPopularWordStyle()
|
||||||
.containsKey("bold") && textBlock.getMostPopularWordFontSize() > document.getFontSizeCounter().getMostPopular() + 1) && textBlock.getSequences()
|
.equals("bold") || !document.getFontStyleCounter().getCountPerValue().containsKey("bold") && textBlock.getMostPopularWordFontSize() > document
|
||||||
.get(0)
|
.getFontSizeCounter()
|
||||||
.getTextPositions()
|
.getMostPopular() + 1) && textBlock.getSequences().get(0).getTextPositions().get(0).getFontSizeInPt() >= textBlock.getMostPopularWordFontSize()) {
|
||||||
.get(0)
|
|
||||||
.getFontSizeInPt() >= textBlock.getMostPopularWordFontSize()) {
|
|
||||||
|
|
||||||
for (int i = 1; i <= headlineFontSizes.size(); i++) {
|
for (int i = 1; i <= headlineFontSizes.size(); i++) {
|
||||||
if (textBlock.getMostPopularWordFontSize() == headlineFontSizes.get(i - 1)) {
|
if (textBlock.getMostPopularWordFontSize() == headlineFontSizes.get(i - 1)) {
|
||||||
@ -85,25 +103,28 @@ public class ClassificationService {
|
|||||||
document.setHeadlines(true);
|
document.setHeadlines(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!textBlock.getText().startsWith("Table ") && !textBlock.getText().startsWith("Figure ") && PositionUtils.isWithinBodyTextFrame(bodyTextFrame,
|
} else if (!textBlock.getText().startsWith("Table ") && !textBlock.getText()
|
||||||
textBlock) && textBlock.getMostPopularWordStyle().equals("bold") && !document.getFontStyleCounter()
|
.startsWith("Figure ") && PositionUtils.isWithinBodyTextFrame(bodyTextFrame, textBlock) && textBlock.getMostPopularWordStyle()
|
||||||
|
.equals("bold") && !document.getFontStyleCounter()
|
||||||
.getMostPopular()
|
.getMostPopular()
|
||||||
.equals("bold") && PositionUtils.getApproxLineCount(textBlock) < 2.9 && textBlock.getSequences()
|
.equals("bold") && PositionUtils.getApproxLineCount(textBlock) < 2.9 && textBlock.getSequences().get(0).getTextPositions().get(0).getFontSizeInPt() >= textBlock.getMostPopularWordFontSize()) {
|
||||||
.get(0)
|
|
||||||
.getTextPositions()
|
|
||||||
.get(0)
|
|
||||||
.getFontSizeInPt() >= textBlock.getMostPopularWordFontSize()) {
|
|
||||||
textBlock.setClassification("H " + (headlineFontSizes.size() + 1));
|
textBlock.setClassification("H " + (headlineFontSizes.size() + 1));
|
||||||
document.setHeadlines(true);
|
document.setHeadlines(true);
|
||||||
} else if (PositionUtils.isWithinBodyTextFrame(bodyTextFrame, textBlock) && textBlock.getMostPopularWordFontSize() == document.getFontSizeCounter()
|
} else if (PositionUtils.isWithinBodyTextFrame(bodyTextFrame, textBlock) && textBlock.getMostPopularWordFontSize() == document
|
||||||
.getMostPopular() && textBlock.getMostPopularWordStyle().equals("bold") && !document.getFontStyleCounter().getMostPopular().equals("bold")) {
|
.getFontSizeCounter()
|
||||||
|
.getMostPopular() && textBlock.getMostPopularWordStyle()
|
||||||
|
.equals("bold") && !document.getFontStyleCounter().getMostPopular().equals("bold")) {
|
||||||
textBlock.setClassification("TextBlock Bold");
|
textBlock.setClassification("TextBlock Bold");
|
||||||
} else if (PositionUtils.isWithinBodyTextFrame(bodyTextFrame, textBlock) && textBlock.getMostPopularWordFont()
|
} else if (PositionUtils.isWithinBodyTextFrame(bodyTextFrame, textBlock) && textBlock.getMostPopularWordFont()
|
||||||
.equals(document.getFontCounter().getMostPopular()) && textBlock.getMostPopularWordStyle()
|
.equals(document.getFontCounter().getMostPopular()) && textBlock.getMostPopularWordStyle()
|
||||||
.equals(document.getFontStyleCounter().getMostPopular()) && textBlock.getMostPopularWordFontSize() == document.getFontSizeCounter().getMostPopular()) {
|
.equals(document.getFontStyleCounter()
|
||||||
|
.getMostPopular()) && textBlock.getMostPopularWordFontSize() == document.getFontSizeCounter()
|
||||||
|
.getMostPopular()) {
|
||||||
textBlock.setClassification("TextBlock");
|
textBlock.setClassification("TextBlock");
|
||||||
} else if (PositionUtils.isWithinBodyTextFrame(bodyTextFrame, textBlock) && textBlock.getMostPopularWordFontSize() == document.getFontSizeCounter()
|
} else if (PositionUtils.isWithinBodyTextFrame(bodyTextFrame, textBlock) && textBlock.getMostPopularWordFontSize() == document
|
||||||
.getMostPopular() && textBlock.getMostPopularWordStyle().equals("italic") && !document.getFontStyleCounter()
|
.getFontSizeCounter()
|
||||||
|
.getMostPopular() && textBlock.getMostPopularWordStyle()
|
||||||
|
.equals("italic") && !document.getFontStyleCounter()
|
||||||
.getMostPopular()
|
.getMostPopular()
|
||||||
.equals("italic") && PositionUtils.getApproxLineCount(textBlock) < 2.9) {
|
.equals("italic") && PositionUtils.getApproxLineCount(textBlock) < 2.9) {
|
||||||
textBlock.setClassification("TextBlock Italic");
|
textBlock.setClassification("TextBlock Italic");
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
package com.iqser.red.service.redaction.v1.server.classification.utils;
|
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.classification.model.TextBlock;
|
||||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Rectangle;
|
|
||||||
|
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public class PositionUtils {
|
public class PositionUtils {
|
||||||
|
|
||||||
|
|
||||||
public boolean isWithinBodyTextFrame(Rectangle btf, TextBlock textBlock) {
|
public boolean isWithinBodyTextFrame(Rectangle btf, TextBlock textBlock) {
|
||||||
|
|
||||||
//TODO Currently this is not working for rotated pages.
|
//TODO Currently this is not working for rotated pages.
|
||||||
@ -19,7 +19,10 @@ public class PositionUtils {
|
|||||||
|
|
||||||
double threshold = textBlock.getMostPopularWordHeight() * 3;
|
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;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -34,10 +37,10 @@ public class PositionUtils {
|
|||||||
return false;
|
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.
|
// Its very strange, P{0,0} is on top left in this case, instead of lower left.
|
||||||
return true;
|
return true;
|
||||||
} else if (!rotated && textBlock.getMinY() > btf.getY() + btf.getHeight()) {
|
} else if (!rotated && textBlock.getMinY() > btf.getTopLeft().getY() + btf.getHeight()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -54,7 +57,7 @@ public class PositionUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (textBlock.getMaxY() < btf.getY()) {
|
if (textBlock.getMaxY() < btf.getTopLeft().getY()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -71,7 +74,7 @@ public class PositionUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (textBlock.getMinY() < btf.getY()) {
|
if (textBlock.getMinY() < btf.getTopLeft().getY()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -81,14 +84,11 @@ public class PositionUtils {
|
|||||||
|
|
||||||
|
|
||||||
public float getHeightDifferenceBetweenChunkWordAndDocumentWord(TextBlock textBlock, Float documentMostPopularWordHeight) {
|
public float getHeightDifferenceBetweenChunkWordAndDocumentWord(TextBlock textBlock, Float documentMostPopularWordHeight) {
|
||||||
|
|
||||||
return textBlock.getMostPopularWordHeight() - documentMostPopularWordHeight;
|
return textBlock.getMostPopularWordHeight() - documentMostPopularWordHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Float getApproxLineCount(TextBlock textBlock) {
|
public Float getApproxLineCount(TextBlock textBlock) {
|
||||||
|
|
||||||
return textBlock.getHeight() / textBlock.getMostPopularWordHeight();
|
return textBlock.getHeight() / textBlock.getMostPopularWordHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -163,14 +163,6 @@ public class TextPositionSequence implements CharSequence {
|
|||||||
if (getDir().getDegrees() == 90) {
|
if (getDir().getDegrees() == 90) {
|
||||||
return textPositions.get(0).getYDirAdj() - getTextHeight();
|
return textPositions.get(0).getYDirAdj() - getTextHeight();
|
||||||
}
|
}
|
||||||
else if (getDir().getDegrees() == 180) {
|
|
||||||
return pageWidth - textPositions.get(textPositions.size() - 1).getXDirAdj() - textPositions.get(textPositions.size() - 1).getWidthDirAdj() - HEIGHT_PADDING;
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (getDir().getDegrees() == 270) {
|
|
||||||
|
|
||||||
return pageWidth - textPositions.get(0).getYDirAdj() ;
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
return textPositions.get(0).getXDirAdj();
|
return textPositions.get(0).getXDirAdj();
|
||||||
}
|
}
|
||||||
@ -185,14 +177,6 @@ public class TextPositionSequence implements CharSequence {
|
|||||||
return textPositions.get(0).getYDirAdj();
|
return textPositions.get(0).getYDirAdj();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (getDir().getDegrees() == 180) {
|
|
||||||
return pageWidth - textPositions.get(0).getXDirAdj() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (getDir().getDegrees() == 270) {
|
|
||||||
return pageWidth - textPositions.get(0).getYDirAdj() + getTextHeight();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
else {
|
||||||
return textPositions.get(textPositions.size() - 1).getXDirAdj() + textPositions.get(textPositions.size() - 1).getWidthDirAdj() + HEIGHT_PADDING;
|
return textPositions.get(textPositions.size() - 1).getXDirAdj() + textPositions.get(textPositions.size() - 1).getWidthDirAdj() + HEIGHT_PADDING;
|
||||||
@ -211,16 +195,11 @@ public class TextPositionSequence implements CharSequence {
|
|||||||
return textPositions.get(0).getXDirAdj();
|
return textPositions.get(0).getXDirAdj();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (getDir().getDegrees() == 180) {
|
if (getDir().getDegrees() == 270) {
|
||||||
return textPositions.get(0).getYDirAdj() - getTextHeight();
|
return textPositions.get(0).getYDirAdj() - getTextHeight();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
else if (getDir().getDegrees() == 270) {
|
|
||||||
return pageHeight - textPositions.get(textPositions.size() - 1).getXDirAdj() - getTextHeight() + HEIGHT_PADDING;
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
return pageHeight - textPositions.get(0).getYDirAdj();
|
return pageHeight - textPositions.get(0).getYDirAdj();
|
||||||
}
|
}
|
||||||
@ -235,15 +214,10 @@ public class TextPositionSequence implements CharSequence {
|
|||||||
return textPositions.get(textPositions.size() - 1).getXDirAdj() + getTextHeight() - HEIGHT_PADDING;
|
return textPositions.get(textPositions.size() - 1).getXDirAdj() + getTextHeight() - HEIGHT_PADDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (getDir().getDegrees() == 180 ) {
|
if (getDir().getDegrees() == 270) {
|
||||||
|
|
||||||
return textPositions.get(0).getYDirAdj();
|
return textPositions.get(0).getYDirAdj();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (getDir().getDegrees() == 270 ) {
|
|
||||||
return pageHeight - textPositions.get(0).getXDirAdj();
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
else {
|
||||||
return pageHeight - textPositions.get(0).getYDirAdj() + getTextHeight();
|
return pageHeight - textPositions.get(0).getYDirAdj() + getTextHeight();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -99,10 +99,10 @@ public class PdfSegmentationService {
|
|||||||
stripper.getText(pdDocument);
|
stripper.getText(pdDocument);
|
||||||
|
|
||||||
PDRectangle pdr = pdPage.getMediaBox();
|
PDRectangle pdr = pdPage.getMediaBox();
|
||||||
boolean isLandscape = pdr.getWidth() > pdr.getHeight();
|
|
||||||
|
|
||||||
int rotation = pdPage.getRotation();
|
int rotation = pdPage.getRotation();
|
||||||
boolean isRotated = rotation != 0 && rotation != 360;
|
boolean isLandscape = pdr.getWidth() > pdr.getHeight() && (rotation == 0 || rotation == 180) ||
|
||||||
|
pdr.getHeight() > pdr.getWidth() && (rotation == 90 || rotation == 270);
|
||||||
|
|
||||||
CleanRulings cleanRulings = rulingCleaningService.getCleanRulings(pdfTableCells.get(pageNumber),
|
CleanRulings cleanRulings = rulingCleaningService.getCleanRulings(pdfTableCells.get(pageNumber),
|
||||||
stripper.getRulings(),
|
stripper.getRulings(),
|
||||||
@ -115,8 +115,9 @@ public class PdfSegmentationService {
|
|||||||
page.setCropBoxArea(cropboxArea);
|
page.setCropBoxArea(cropboxArea);
|
||||||
|
|
||||||
page.setRotation(rotation);
|
page.setRotation(rotation);
|
||||||
page.setLandscape(isLandscape || isRotated);
|
page.setLandscape(isLandscape);
|
||||||
page.setPageNumber(pageNumber);
|
page.setPageNumber(pageNumber);
|
||||||
|
page.setCropBox(cropbox);
|
||||||
|
|
||||||
tableExtractionService.extractTables(cleanRulings, page);
|
tableExtractionService.extractTables(cleanRulings, page);
|
||||||
buildPageStatistics(page);
|
buildPageStatistics(page);
|
||||||
|
|||||||
@ -20,12 +20,11 @@ public class Rectangle extends Rectangle2D.Float {
|
|||||||
public static final Comparator<Rectangle> ILL_DEFINED_ORDER = new Comparator<Rectangle>() {
|
public static final Comparator<Rectangle> ILL_DEFINED_ORDER = new Comparator<Rectangle>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(Rectangle o1, Rectangle o2) {
|
public int compare(Rectangle o1, Rectangle o2) {
|
||||||
|
if (o1.equals(o2)) return 0;
|
||||||
if (o1.equals(o2)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (o1.verticalOverlap(o2) > VERTICAL_COMPARISON_THRESHOLD) {
|
if (o1.verticalOverlap(o2) > VERTICAL_COMPARISON_THRESHOLD) {
|
||||||
return o1.isLtrDominant() == -1 && o2.isLtrDominant() == -1 ? -java.lang.Double.compare(o1.getX(), o2.getX()) : java.lang.Double.compare(o1.getX(), o2.getX());
|
return o1.isLtrDominant() == -1 && o2.isLtrDominant() == -1
|
||||||
|
? -java.lang.Double.compare(o1.getX(), o2.getX())
|
||||||
|
: java.lang.Double.compare(o1.getX(), o2.getX());
|
||||||
} else {
|
} else {
|
||||||
return java.lang.Float.compare(o1.getBottom(), o2.getBottom());
|
return java.lang.Float.compare(o1.getBottom(), o2.getBottom());
|
||||||
}
|
}
|
||||||
@ -33,25 +32,23 @@ public class Rectangle extends Rectangle2D.Float {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
public Rectangle() {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public Rectangle() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Rectangle(float top, float left, float width, float height) {
|
public Rectangle(float top, float left, float width, float height) {
|
||||||
|
|
||||||
super();
|
super();
|
||||||
this.setRect(left, top, width, height);
|
this.setRect(left, top, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param rectangles
|
* @param rectangles
|
||||||
* @return minimum bounding box that contains all the rectangles
|
* @return minimum bounding box that contains all the rectangles
|
||||||
*/
|
*/
|
||||||
public static Rectangle boundingBoxOf(List<? extends Rectangle> rectangles) {
|
public static Rectangle boundingBoxOf(List<? extends Rectangle> rectangles) {
|
||||||
|
|
||||||
float minx = java.lang.Float.MAX_VALUE;
|
float minx = java.lang.Float.MAX_VALUE;
|
||||||
float miny = java.lang.Float.MAX_VALUE;
|
float miny = java.lang.Float.MAX_VALUE;
|
||||||
float maxx = java.lang.Float.MIN_VALUE;
|
float maxx = java.lang.Float.MIN_VALUE;
|
||||||
@ -66,62 +63,50 @@ public class Rectangle extends Rectangle2D.Float {
|
|||||||
return new Rectangle(miny, minx, maxx - minx, maxy - miny);
|
return new Rectangle(miny, minx, maxx - minx, maxy - miny);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int compareTo(Rectangle other) {
|
public int compareTo(Rectangle other) {
|
||||||
|
|
||||||
return ILL_DEFINED_ORDER.compare(this, other);
|
return ILL_DEFINED_ORDER.compare(this, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// I'm bad at Java and need this for fancy sorting in
|
// I'm bad at Java and need this for fancy sorting in
|
||||||
// technology.tabula.TextChunk.
|
// technology.tabula.TextChunk.
|
||||||
public int isLtrDominant() {
|
public int isLtrDominant() {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public float getArea() {
|
public float getArea() {
|
||||||
|
|
||||||
return this.width * this.height;
|
return this.width * this.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public float verticalOverlap(Rectangle other) {
|
public float verticalOverlap(Rectangle other) {
|
||||||
|
|
||||||
return Math.max(0, Math.min(this.getBottom(), other.getBottom()) - Math.max(this.getTop(), other.getTop()));
|
return Math.max(0, Math.min(this.getBottom(), other.getBottom()) - Math.max(this.getTop(), other.getTop()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean verticallyOverlaps(Rectangle other) {
|
public boolean verticallyOverlaps(Rectangle other) {
|
||||||
|
|
||||||
return verticalOverlap(other) > 0;
|
return verticalOverlap(other) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public float horizontalOverlap(Rectangle other) {
|
public float horizontalOverlap(Rectangle other) {
|
||||||
|
|
||||||
return Math.max(0, Math.min(this.getRight(), other.getRight()) - Math.max(this.getLeft(), other.getLeft()));
|
return Math.max(0, Math.min(this.getRight(), other.getRight()) - Math.max(this.getLeft(), other.getLeft()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean horizontallyOverlaps(Rectangle other) {
|
public boolean horizontallyOverlaps(Rectangle other) {
|
||||||
|
|
||||||
return horizontalOverlap(other) > 0;
|
return horizontalOverlap(other) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public float verticalOverlapRatio(Rectangle other) {
|
public float verticalOverlapRatio(Rectangle other) {
|
||||||
|
|
||||||
float rv = 0, delta = Math.min(this.getBottom() - this.getTop(), other.getBottom() - other.getTop());
|
float rv = 0, delta = Math.min(this.getBottom() - this.getTop(), other.getBottom() - other.getTop());
|
||||||
|
|
||||||
if (other.getTop() <= this.getTop() && this.getTop() <= other.getBottom() && other.getBottom() <= this.getBottom()) {
|
if (other.getTop() <= this.getTop() && this.getTop() <= other.getBottom()
|
||||||
|
&& other.getBottom() <= this.getBottom()) {
|
||||||
rv = (other.getBottom() - this.getTop()) / delta;
|
rv = (other.getBottom() - this.getTop()) / delta;
|
||||||
} else if (this.getTop() <= other.getTop() && other.getTop() <= this.getBottom() && this.getBottom() <= other.getBottom()) {
|
} else if (this.getTop() <= other.getTop() && other.getTop() <= this.getBottom()
|
||||||
|
&& this.getBottom() <= other.getBottom()) {
|
||||||
rv = (this.getBottom() - other.getTop()) / delta;
|
rv = (this.getBottom() - other.getTop()) / delta;
|
||||||
} else if (this.getTop() <= other.getTop() && other.getTop() <= other.getBottom() && other.getBottom() <= this.getBottom()) {
|
} else if (this.getTop() <= other.getTop() && other.getTop() <= other.getBottom()
|
||||||
|
&& other.getBottom() <= this.getBottom()) {
|
||||||
rv = (other.getBottom() - other.getTop()) / delta;
|
rv = (other.getBottom() - other.getTop()) / delta;
|
||||||
} else if (other.getTop() <= this.getTop() && this.getTop() <= this.getBottom() && this.getBottom() <= other.getBottom()) {
|
} else if (other.getTop() <= this.getTop() && this.getTop() <= this.getBottom()
|
||||||
|
&& this.getBottom() <= other.getBottom()) {
|
||||||
rv = (this.getBottom() - this.getTop()) / delta;
|
rv = (this.getBottom() - this.getTop()) / delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,85 +114,64 @@ public class Rectangle extends Rectangle2D.Float {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public float overlapRatio(Rectangle other) {
|
public float overlapRatio(Rectangle other) {
|
||||||
|
double intersectionWidth = Math.max(0,
|
||||||
double intersectionWidth = Math.max(0, Math.min(this.getRight(), other.getRight()) - Math.max(this.getLeft(), other.getLeft()));
|
Math.min(this.getRight(), other.getRight()) - Math.max(this.getLeft(), other.getLeft()));
|
||||||
double intersectionHeight = Math.max(0, Math.min(this.getBottom(), other.getBottom()) - Math.max(this.getTop(), other.getTop()));
|
double intersectionHeight = Math.max(0,
|
||||||
|
Math.min(this.getBottom(), other.getBottom()) - Math.max(this.getTop(), other.getTop()));
|
||||||
double intersectionArea = Math.max(0, intersectionWidth * intersectionHeight);
|
double intersectionArea = Math.max(0, intersectionWidth * intersectionHeight);
|
||||||
double unionArea = this.getArea() + other.getArea() - intersectionArea;
|
double unionArea = this.getArea() + other.getArea() - intersectionArea;
|
||||||
|
|
||||||
return (float) (intersectionArea / unionArea);
|
return (float) (intersectionArea / unionArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Rectangle merge(Rectangle other) {
|
public Rectangle merge(Rectangle other) {
|
||||||
|
|
||||||
this.setRect(this.createUnion(other));
|
this.setRect(this.createUnion(other));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public float getTop() {
|
public float getTop() {
|
||||||
|
|
||||||
return (float) this.getMinY();
|
return (float) this.getMinY();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setTop(float top) {
|
public void setTop(float top) {
|
||||||
|
|
||||||
float deltaHeight = top - this.y;
|
float deltaHeight = top - this.y;
|
||||||
this.setRect(this.x, top, this.width, this.height - deltaHeight);
|
this.setRect(this.x, top, this.width, this.height - deltaHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public float getRight() {
|
public float getRight() {
|
||||||
|
|
||||||
return (float) this.getMaxX();
|
return (float) this.getMaxX();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setRight(float right) {
|
public void setRight(float right) {
|
||||||
|
|
||||||
this.setRect(this.x, this.y, right - this.x, this.height);
|
this.setRect(this.x, this.y, right - this.x, this.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public float getLeft() {
|
public float getLeft() {
|
||||||
|
|
||||||
return (float) this.getMinX();
|
return (float) this.getMinX();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setLeft(float left) {
|
public void setLeft(float left) {
|
||||||
|
|
||||||
float deltaWidth = left - this.x;
|
float deltaWidth = left - this.x;
|
||||||
this.setRect(left, this.y, this.width - deltaWidth, this.height);
|
this.setRect(left, this.y, this.width - deltaWidth, this.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public float getBottom() {
|
public float getBottom() {
|
||||||
|
|
||||||
return (float) this.getMaxY();
|
return (float) this.getMaxY();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setBottom(float bottom) {
|
public void setBottom(float bottom) {
|
||||||
|
|
||||||
this.setRect(this.x, this.y, this.width, bottom - this.y);
|
this.setRect(this.x, this.y, this.width, bottom - this.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Point2D[] getPoints() {
|
public Point2D[] getPoints() {
|
||||||
|
return new Point2D[]{new Point2D.Float(this.getLeft(), this.getTop()),
|
||||||
return new Point2D[]{new Point2D.Float(this.getLeft(), this.getTop()), new Point2D.Float(this.getRight(), this.getTop()), new Point2D.Float(this.getRight(),
|
new Point2D.Float(this.getRight(), this.getTop()), new Point2D.Float(this.getRight(), this.getBottom()),
|
||||||
this.getBottom()), new Point2D.Float(this.getLeft(), this.getBottom())};
|
new Point2D.Float(this.getLeft(), this.getBottom())};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
String s = super.toString();
|
String s = super.toString();
|
||||||
sb.append(s.substring(0, s.length() - 1));
|
sb.append(s.substring(0, s.length() - 1));
|
||||||
|
|||||||
@ -7,10 +7,8 @@ import com.iqser.red.service.redaction.v1.server.classification.model.TextBlock;
|
|||||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.AbstractTextContainer;
|
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.Cell;
|
||||||
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Table;
|
import com.iqser.red.service.redaction.v1.server.tableextraction.model.Table;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||||
@ -26,6 +24,7 @@ import java.util.List;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class PdfVisualisationService {
|
public class PdfVisualisationService {
|
||||||
|
|
||||||
|
|
||||||
public void visualizeParagraphs(Document classifiedDoc, PDDocument document) throws IOException {
|
public void visualizeParagraphs(Document classifiedDoc, PDDocument document) throws IOException {
|
||||||
|
|
||||||
for (int page = 1; page <= document.getNumberOfPages(); page++) {
|
for (int page = 1; page <= document.getNumberOfPages(); page++) {
|
||||||
@ -67,6 +66,7 @@ public class PdfVisualisationService {
|
|||||||
PDPage pdPage = document.getPage(page - 1);
|
PDPage pdPage = document.getPage(page - 1);
|
||||||
PDPageContentStream contentStream = new PDPageContentStream(document, pdPage, PDPageContentStream.AppendMode.APPEND, true);
|
PDPageContentStream contentStream = new PDPageContentStream(document, pdPage, PDPageContentStream.AppendMode.APPEND, true);
|
||||||
|
|
||||||
|
|
||||||
for (AbstractTextContainer textBlock : analyzedPage.getTextBlocks()) {
|
for (AbstractTextContainer textBlock : analyzedPage.getTextBlocks()) {
|
||||||
if (textBlock == null) {
|
if (textBlock == null) {
|
||||||
continue;
|
continue;
|
||||||
@ -79,10 +79,10 @@ public class PdfVisualisationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
contentStream.setStrokingColor(Color.YELLOW);
|
contentStream.setStrokingColor(Color.YELLOW);
|
||||||
contentStream.addRect((float) analyzedPage.getBodyTextFrame().getX(),
|
// var widhth = analyzedPage.getBodyTextFrame().getX2(pdPage.getRotation(), pdPage.getCropBox().getWidth(), pdPage.getCropBox().getHeight()) - analyzedPage.getBodyTextFrame().getX1(pdPage.getRotation(), pdPage.getCropBox().getWidth(), pdPage.getCropBox().getHeight());
|
||||||
(float) analyzedPage.getBodyTextFrame().getY(),
|
// var height = analyzedPage.getBodyTextFrame().getY2(pdPage.getRotation(), pdPage.getCropBox().getWidth(), pdPage.getCropBox().getHeight()) - analyzedPage.getBodyTextFrame().getY1(pdPage.getRotation(), pdPage.getCropBox().getWidth(), pdPage.getCropBox().getHeight());
|
||||||
(float) analyzedPage.getBodyTextFrame().getWidth(),
|
|
||||||
(float) analyzedPage.getBodyTextFrame().getHeight());
|
contentStream.addRect(analyzedPage.getBodyTextFrame().getTopLeft().getX(), analyzedPage.getBodyTextFrame().getTopLeft().getY(), analyzedPage.getBodyTextFrame().getWidth(), analyzedPage.getBodyTextFrame().getHeight());
|
||||||
contentStream.stroke();
|
contentStream.stroke();
|
||||||
|
|
||||||
contentStream.close();
|
contentStream.close();
|
||||||
@ -94,33 +94,40 @@ public class PdfVisualisationService {
|
|||||||
|
|
||||||
contentStream.setStrokingColor(Color.RED);
|
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();
|
contentStream.stroke();
|
||||||
|
|
||||||
if (textBlock.getClassification() != null) {
|
if (textBlock.getClassification() != null) {
|
||||||
contentStream.beginText();
|
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.setNonStrokingColor(Color.BLUE);
|
||||||
contentStream.setFont(PDType1Font.TIMES_ROMAN, 2f);
|
contentStream.setFont(PDType1Font.TIMES_ROMAN, 2f);
|
||||||
|
|
||||||
contentStream.newLineAtOffset(textBlock.getMinX(), textBlock.getMaxY() + 10);
|
|
||||||
contentStream.showText(textBlock.getClassification() + textBlock.getOrientation() + "-->" + textBlock.getSequences().get(0).getDir());
|
|
||||||
|
contentStream.beginText();
|
||||||
|
contentStream.newLineAtOffset(textBlock.getX1(), textBlock.getY1());
|
||||||
|
contentStream.showText("MinX,MinY(" + textBlock.getX1() + "," + textBlock.getY1() + ")");
|
||||||
contentStream.endText();
|
contentStream.endText();
|
||||||
contentStream.beginText();
|
contentStream.beginText();
|
||||||
contentStream.newLineAtOffset(textBlock.getMinX(), textBlock.getMinY());
|
contentStream.newLineAtOffset(textBlock.getX2(), textBlock.getY1());
|
||||||
contentStream.showText("MinX,MinY");
|
contentStream.showText("MaxX,MinY(" + textBlock.getX2() + "," + textBlock.getY1() + ")");
|
||||||
contentStream.endText();
|
contentStream.endText();
|
||||||
contentStream.beginText();
|
contentStream.beginText();
|
||||||
contentStream.newLineAtOffset(textBlock.getMaxX(), textBlock.getMinY());
|
contentStream.newLineAtOffset(textBlock.getX1(), textBlock.getY2());
|
||||||
contentStream.showText("MaxX,MinY");
|
contentStream.showText("MinX,MaxY(" + textBlock.getX1() + "," + textBlock.getY2() + ")");
|
||||||
contentStream.endText();
|
contentStream.endText();
|
||||||
contentStream.beginText();
|
contentStream.beginText();
|
||||||
contentStream.newLineAtOffset(textBlock.getMinX(), textBlock.getMaxY());
|
contentStream.newLineAtOffset(textBlock.getX2(), textBlock.getY2());
|
||||||
contentStream.showText("MinX,MaxY");
|
contentStream.showText("MaxX,MaxY(" + textBlock.getX2() + "," + textBlock.getY2() + ")");
|
||||||
contentStream.endText();
|
|
||||||
contentStream.beginText();
|
|
||||||
contentStream.newLineAtOffset(textBlock.getMaxX(), textBlock.getMaxY());
|
|
||||||
contentStream.showText("MaxX,MaxY");
|
|
||||||
|
|
||||||
|
|
||||||
contentStream.endText();
|
contentStream.endText();
|
||||||
@ -129,7 +136,6 @@ public class PdfVisualisationService {
|
|||||||
|
|
||||||
|
|
||||||
private void visualizeTable(Table table, PDPageContentStream contentStream) throws IOException {
|
private void visualizeTable(Table table, PDPageContentStream contentStream) throws IOException {
|
||||||
|
|
||||||
for (List<Cell> row : table.getRows()) {
|
for (List<Cell> row : table.getRows()) {
|
||||||
for (Cell cell : row) {
|
for (Cell cell : row) {
|
||||||
|
|
||||||
@ -160,5 +166,4 @@ public class PdfVisualisationService {
|
|||||||
contentStream.endText();
|
contentStream.endText();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1098,7 +1098,7 @@ public class RedactionIntegrationTest {
|
|||||||
|
|
||||||
System.out.println("classificationTest");
|
System.out.println("classificationTest");
|
||||||
|
|
||||||
AnalyzeRequest request = prepareStorage("files/new/RotateTestFile.pdf");
|
AnalyzeRequest request = prepareStorage("files/RSS/02 - A22833B - Acute Oral (Up and Down) - Final Report1.pdf");
|
||||||
|
|
||||||
RedactionRequest redactionRequest = RedactionRequest.builder()
|
RedactionRequest redactionRequest = RedactionRequest.builder()
|
||||||
.dossierId(request.getDossierId())
|
.dossierId(request.getDossierId())
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user