RED-7669: optimize OCR-module performance
* second attempt at thread safety
This commit is contained in:
parent
57e194fcd0
commit
77355b5367
@ -45,12 +45,22 @@ public class ExtractedOcrImage implements OcrImage {
|
|||||||
this.originalHeight = bufferedImage.getHeight();
|
this.originalHeight = bufferedImage.getHeight();
|
||||||
this.originalWidth = bufferedImage.getWidth();
|
this.originalWidth = bufferedImage.getWidth();
|
||||||
float imageDPI = Math.abs(bufferedImage.getWidth() / (ctm.getScalingFactorX() / 72));
|
float imageDPI = Math.abs(bufferedImage.getWidth() / (ctm.getScalingFactorX() / 72));
|
||||||
this.pix = ImageProcessingUtils.process(bufferedImage, imageDPI, targetDpi);
|
this.pix = binarize(bufferedImage, imageDPI, targetDpi);
|
||||||
this.height = pix.h;
|
this.height = pix.h;
|
||||||
this.width = pix.w;
|
this.width = pix.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
synchronized private Pix binarize(BufferedImage image, float imageDpi, int targetDpi) {
|
||||||
|
|
||||||
|
ImageProcessingUtils.setAlphaChannelToWhite(image);
|
||||||
|
Pix grayScale = ImageProcessingUtils.convertToGrayScale(image);
|
||||||
|
Pix scaledUp = ImageProcessingUtils.scaleToTargetDpi(imageDpi, targetDpi, grayScale);
|
||||||
|
return ImageProcessingUtils.despecklePix(scaledUp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AffineTransform getImageCTM() {
|
public AffineTransform getImageCTM() {
|
||||||
|
|
||||||
|
|||||||
@ -15,24 +15,7 @@ import net.sourceforge.lept4j.util.LeptUtils;
|
|||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class ImageProcessingUtils {
|
public class ImageProcessingUtils {
|
||||||
|
|
||||||
public Pix process(BufferedImage image, float imageDpi, int targetDpi) {
|
public static Pix despecklePix(Pix scaledUp) {
|
||||||
|
|
||||||
setAlphaChannelToWhite(image);
|
|
||||||
return processWithLeptonica(image, imageDpi, targetDpi);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// LeptUtils and Leptonica1 does not seem to be thread safe, so we must ensure synchronization for the image processing.
|
|
||||||
// There might be a way to get this working multi-threaded, but it does not seem to be a significant runtime factor, so i didn't bother investing the time to dive deeper.
|
|
||||||
synchronized private static Pix processWithLeptonica(BufferedImage image, float imageDpi, int targetDpi) {
|
|
||||||
|
|
||||||
Pix grayScale = convertToGrayScale(image);
|
|
||||||
Pix scaledUp = scaleToTargetDpi(imageDpi, targetDpi, grayScale);
|
|
||||||
return despecklePix(scaledUp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static Pix despecklePix(Pix scaledUp) {
|
|
||||||
|
|
||||||
assert scaledUp.d == 8;
|
assert scaledUp.d == 8;
|
||||||
Pix despeckled = LeptUtils.despeckle(scaledUp, LeptUtils.SEL_STR3, 3);
|
Pix despeckled = LeptUtils.despeckle(scaledUp, LeptUtils.SEL_STR3, 3);
|
||||||
@ -46,7 +29,7 @@ public class ImageProcessingUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static Pix scaleToTargetDpi(float imageDpi, int targetDpi, Pix grayScale) {
|
public static Pix scaleToTargetDpi(float imageDpi, int targetDpi, Pix grayScale) {
|
||||||
|
|
||||||
float targetFactor = targetDpi / imageDpi;
|
float targetFactor = targetDpi / imageDpi;
|
||||||
|
|
||||||
@ -67,7 +50,7 @@ public class ImageProcessingUtils {
|
|||||||
|
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
private static Pix convertToGrayScale(BufferedImage image) {
|
public static Pix convertToGrayScale(BufferedImage image) {
|
||||||
|
|
||||||
Pix pix = LeptUtils.convertImageToPix(image);
|
Pix pix = LeptUtils.convertImageToPix(image);
|
||||||
if (pix.d == 8) {
|
if (pix.d == 8) {
|
||||||
@ -84,7 +67,7 @@ public class ImageProcessingUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void setAlphaChannelToWhite(BufferedImage image) {
|
public static void setAlphaChannelToWhite(BufferedImage image) {
|
||||||
|
|
||||||
if (image.getTransparency() == Transparency.TRANSLUCENT) {
|
if (image.getTransparency() == Transparency.TRANSLUCENT) {
|
||||||
// NOTE: For BITMASK images, the color model is likely IndexColorModel,
|
// NOTE: For BITMASK images, the color model is likely IndexColorModel,
|
||||||
|
|||||||
@ -172,6 +172,7 @@ public class OcrServiceIntegrationTest extends AbstractTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
private void testOCRForFile(File file) {
|
private void testOCRForFile(File file) {
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user