RED-8155: bold-detection in ocr-service
This commit is contained in:
parent
fb1fe35bc1
commit
74d5f8d8e0
@ -28,6 +28,8 @@ import com.knecon.fforesight.service.ocr.processor.service.scriptdetection.FontS
|
|||||||
import com.knecon.fforesight.service.ocr.processor.service.threads.OCRThread;
|
import com.knecon.fforesight.service.ocr.processor.service.threads.OCRThread;
|
||||||
import com.knecon.fforesight.service.ocr.processor.settings.OcrServiceSettings;
|
import com.knecon.fforesight.service.ocr.processor.settings.OcrServiceSettings;
|
||||||
|
|
||||||
|
import io.micrometer.observation.ObservationRegistry;
|
||||||
|
import io.micrometer.observation.annotation.Observed;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
@ -48,6 +50,7 @@ public class OCRService {
|
|||||||
OcrResultWriter ocrResultWriter;
|
OcrResultWriter ocrResultWriter;
|
||||||
GhostScriptService ghostScriptService;
|
GhostScriptService ghostScriptService;
|
||||||
FontStyleDetector boldDetector;
|
FontStyleDetector boldDetector;
|
||||||
|
ObservationRegistry registry;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,6 +62,7 @@ public class OCRService {
|
|||||||
* @param fileId Id of file
|
* @param fileId Id of file
|
||||||
* @param out OutputStream where to write to
|
* @param out OutputStream where to write to
|
||||||
*/
|
*/
|
||||||
|
@Observed(name = "OCRService", contextualName = "run-ocr-on-document")
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public void runOcrOnDocument(String dossierId, String fileId, OutputStream out) {
|
public void runOcrOnDocument(String dossierId, String fileId, OutputStream out) {
|
||||||
|
|
||||||
|
|||||||
@ -109,7 +109,6 @@ public class GhostScriptOutputHandler extends Thread {
|
|||||||
if (imageFile == null) {
|
if (imageFile == null) {
|
||||||
throw new IllegalArgumentException(String.format("Page number %d does not exist in this thread. It only has pagenumbers %s", pageNumber, pagesToProcess.keySet()));
|
throw new IllegalArgumentException(String.format("Page number %d does not exist in this thread. It only has pagenumbers %s", pageNumber, pagesToProcess.keySet()));
|
||||||
}
|
}
|
||||||
assert new File(imageFile.absoluteFilePath()).isFile();
|
|
||||||
renderedPageImageFileOutput.add(imageFile);
|
renderedPageImageFileOutput.add(imageFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -198,8 +198,10 @@ public class ImageProcessingThread extends Thread {
|
|||||||
grayScale = pix;
|
grayScale = pix;
|
||||||
} else if (pix.d == 32) {
|
} else if (pix.d == 32) {
|
||||||
grayScale = Leptonica1.pixConvertRGBToGrayFast(pix);
|
grayScale = Leptonica1.pixConvertRGBToGrayFast(pix);
|
||||||
|
LeptUtils.disposePix(pix);
|
||||||
} else if (pix.d == 1) {
|
} else if (pix.d == 1) {
|
||||||
grayScale = Leptonica1.pixConvert1To8(null, pix, (byte) 0, (byte) 255);
|
grayScale = Leptonica1.pixConvert1To8(null, pix, (byte) 0, (byte) 255);
|
||||||
|
LeptUtils.disposePix(pix);
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedOperationException(String.format("Unknown pix format with bpp of %d", pix.d));
|
throw new UnsupportedOperationException(String.format("Unknown pix format with bpp of %d", pix.d));
|
||||||
}
|
}
|
||||||
@ -208,36 +210,33 @@ public class ImageProcessingThread extends Thread {
|
|||||||
float targetFactor = targetDpi / imageDpi;
|
float targetFactor = targetDpi / imageDpi;
|
||||||
if (targetFactor > 2.1) {
|
if (targetFactor > 2.1) {
|
||||||
scaledUp = Leptonica1.pixScaleGray4xLI(grayScale);
|
scaledUp = Leptonica1.pixScaleGray4xLI(grayScale);
|
||||||
|
LeptUtils.disposePix(grayScale);
|
||||||
} else if (targetFactor > 1.1) {
|
} else if (targetFactor > 1.1) {
|
||||||
scaledUp = Leptonica1.pixScaleGray2xLI(grayScale);
|
scaledUp = Leptonica1.pixScaleGray2xLI(grayScale);
|
||||||
|
LeptUtils.disposePix(grayScale);
|
||||||
} else {
|
} else {
|
||||||
scaledUp = grayScale;
|
scaledUp = grayScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove noise and prep for Otsu
|
// remove noise and prep for Otsu
|
||||||
gaussian = Leptonica1.pixConvolve(scaledUp, gaussianKernel, 8, 1);
|
gaussian = Leptonica1.pixConvolve(scaledUp, gaussianKernel, 8, 1);
|
||||||
|
LeptUtils.disposePix(scaledUp);
|
||||||
|
|
||||||
// Threshold to binary
|
// Threshold to binary
|
||||||
if (pix.w < 100 || pix.h < 100) {
|
if (pix.w < 100 || pix.h < 100) {
|
||||||
binarized = Leptonica1.pixThresholdToBinary(gaussian, 170);
|
binarized = Leptonica1.pixThresholdToBinary(gaussian, 170);
|
||||||
} else {
|
} else {
|
||||||
binarized = Leptonica1.pixOtsuThreshOnBackgroundNorm(gaussian, null, 50, 50, 165, 10, 100, 5, 5, 0.2f, null);
|
binarized = Leptonica1.pixOtsuThreshOnBackgroundNorm(gaussian, null, 50, 50, 165, 10, 100, 5, 5, 0.2f, null);
|
||||||
|
|
||||||
if (binarized == null) { // Sometimes Otsu just fails, then we binarize directly
|
if (binarized == null) { // Sometimes Otsu just fails, then we binarize directly
|
||||||
binarized = Leptonica1.pixThresholdToBinary(gaussian, 170);
|
binarized = Leptonica1.pixThresholdToBinary(gaussian, 170);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LeptUtils.disposePix(pix);
|
|
||||||
LeptUtils.disposePix(grayScale);
|
|
||||||
LeptUtils.disposePix(scaledUp);
|
|
||||||
LeptUtils.disposePix(gaussian);
|
LeptUtils.disposePix(gaussian);
|
||||||
|
|
||||||
return binarized;
|
return binarized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static ITessAPI.TessBaseAPI initDetectionScriptHandle() {
|
private static ITessAPI.TessBaseAPI initDetectionScriptHandle() {
|
||||||
|
|
||||||
ITessAPI.TessBaseAPI handle = TessAPI1.TessBaseAPICreate();
|
ITessAPI.TessBaseAPI handle = TessAPI1.TessBaseAPICreate();
|
||||||
|
|||||||
@ -138,11 +138,4 @@ public class Tesseract2 extends Tesseract1 {
|
|||||||
return renderer;
|
return renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void dispose() {
|
|
||||||
|
|
||||||
TessBaseAPIEnd(getHandle());
|
|
||||||
TessBaseAPIDelete(getHandle());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import com.knecon.fforesight.service.ocr.v1.api.model.DocumentRequest;
|
|||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileErrorInfo;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileErrorInfo;
|
||||||
|
|
||||||
import feign.FeignException;
|
import feign.FeignException;
|
||||||
|
import io.micrometer.observation.annotation.Observed;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.experimental.FieldDefaults;
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"name": "tesseract",
|
"name": "tesseract",
|
||||||
"version": "5.3.2"
|
"version": "5.3.3"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "leptonica",
|
"name": "leptonica",
|
||||||
|
|||||||
@ -64,7 +64,7 @@ public class OcrServiceIntegrationTest extends AbstractTest {
|
|||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public void testOcr() {
|
public void testOcr() {
|
||||||
|
|
||||||
String text = testOCR("files/402Study.pdf");
|
String text = testOCR("files/UNAPPROVED_VV-331155 (1).pdf");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user