用于OCR的iOS UIImage二值化 - 处理具有不同亮度的图像

时间:2013-09-05 08:01:48

标签: ios image-processing ocr gpuimage

我有一个C ++二值化例程,我将其用于以后的OCR操作。 但是我发现它产生了不必要的文本倾斜。 寻找替代方案我发现GPUImage具有重要价值,它解决了倾斜问题。

我在使用OCR之前使用GPUImage code like this二进制化我的输入图像。

然而,阈值不包括我得到的图像范围。 查看输入图像中的两个样本:

enter image description here

enter image description here

我无法使用相同的阈值处理两者。 较低的值似乎在以后很好,而第一个值更高的值。

第二张图片似乎特别复杂,因为我从未让所有的字符都被正确地二进制化,无论我为阈值设置了什么值。另一方面,我的C ++二值化例程似乎做得对,但我没有太多的见解可以像GPUImage中的简单阈值一样进行实验。

我应该如何处理?

更新

我尝试使用GPUImageAverageLuminanceThresholdFilter并使用默认乘数= 1.它适用于第一张图片,但第二张图片仍然存在问题。

一些更加多样化的二值化输入:

enter image description here

enter image description here

更新II:

在浏览this answer by Brad之后,尝试了GPUImageAdaptiveThresholdFilter(也包含了GPUImagePicture,因为之前我只在UIImage上应用它)。

有了这个,我得到了第二张二进制图像。然而,当我设置模糊大小为3.0时,第一个似乎在二值化后有很多噪音。 OCR导致添加额外字符。使用较低的模糊大小值,第二个图像会失去精确度。

这是:

+(UIImage *)binarize : (UIImage *) sourceImage
{
    UIImage * grayScaledImg = [self toGrayscale:sourceImage];
    GPUImagePicture *imageSource = [[GPUImagePicture alloc] initWithImage:grayScaledImg];
    GPUImageAdaptiveThresholdFilter *stillImageFilter = [[GPUImageAdaptiveThresholdFilter alloc] init];
    stillImageFilter.blurSize = 3.0;    

    [imageSource addTarget:stillImageFilter];   
    [imageSource processImage];        

    UIImage *imageWithAppliedThreshold = [stillImageFilter imageFromCurrentlyProcessedOutput];
  //  UIImage *destImage = [thresholdFilter imageByFilteringImage:grayScaledImg];
    return imageWithAppliedThreshold;
}

3 个答案:

答案 0 :(得分:2)

对于预处理步骤,您需要adaptive thresholding

我使用opencv灰度和自适应阈值方法得到了这些结果。也许通过添加低通噪声滤波(高斯或中值),它应该像魅力一样。

luminance

diverse

我使用provisia(它是一个ui来帮助你快速处理图像)来获得我需要的块大小:这里提供的图像为43。如果您从更近或更远的地方拍摄照片,块大小可能会改变。如果你想要一个通用算法,你需要开发一个应该搜索最佳大小的算法(搜索直到检测到数字)

编辑: 我刚看到最后一张图片。它非常小。即使您应用最佳的预处理算法,也不会检测到这些数字。由于噪音将会出现,因此采样不会成为解决方案。

答案 1 :(得分:1)

我最终以自己的方式进行了探索,这是 GPUImage 过滤器的结果:

+ (UIImage *) doBinarize:(UIImage *)sourceImage
{
    //first off, try to grayscale the image using iOS core Image routine
    UIImage * grayScaledImg = [self grayImage:sourceImage];
    GPUImagePicture *imageSource = [[GPUImagePicture alloc] initWithImage:grayScaledImg];
    GPUImageAdaptiveThresholdFilter *stillImageFilter = [[GPUImageAdaptiveThresholdFilter alloc] init];
    stillImageFilter.blurSize = 8.0;

    [imageSource addTarget:stillImageFilter];
    [imageSource processImage];

    UIImage *retImage = [stillImageFilter imageFromCurrentlyProcessedOutput];
    return retImage;
}

+ (UIImage *) grayImage :(UIImage *)inputImage
{    
    // Create a graphic context.
    UIGraphicsBeginImageContextWithOptions(inputImage.size, NO, 1.0);
    CGRect imageRect = CGRectMake(0, 0, inputImage.size.width, inputImage.size.height);

    // Draw the image with the luminosity blend mode.
    // On top of a white background, this will give a black and white image.
    [inputImage drawInRect:imageRect blendMode:kCGBlendModeLuminosity alpha:1.0];

    // Get the resulting image.
    UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return outputImage;
} 

我使用这个几乎达到了90% - 我确信必须有更好的选项,但我尽可能尝试使用blurSize,而8.0是与大多数我的输入图像一起使用的值< / em>的

对于其他任何人,祝你好运!

答案 2 :(得分:0)

<强> SWIFT3

解决方案1 ​​

extension UIImage {

func doBinarize() -> UIImage? {

    let grayScaledImg = self.grayImage()
    let imageSource = GPUImagePicture(image: grayScaledImg)
    let stillImageFilter = GPUImageAdaptiveThresholdFilter()
    stillImageFilter.blurRadiusInPixels = 8.0 

    imageSource!.addTarget(stillImageFilter)
    stillImageFilter.useNextFrameForImageCapture()
    imageSource!.processImage()


    guard let retImage: UIImage = stillImageFilter.imageFromCurrentFramebuffer(with: UIImageOrientation.up) else {
        print("unable to obtain UIImage from filter")
        return nil
    }

    return retImage
}

func grayImage() -> UIImage? {
    UIGraphicsBeginImageContextWithOptions(self.size, false, 1.0)
    let imageRect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)

    self.draw(in: imageRect, blendMode: .luminosity, alpha:  1.0)

    let outputImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return outputImage
}


}

结果将是 enter image description here

解决方案2

使用GPUImageLuminanceThresholdFilter实现100%黑白效果,不带灰色

   let stillImageFilter = GPUImageLuminanceThresholdFilter() 
   stillImageFilter.threshold = 0.9 

例如,我需要检测闪光灯,这对我有用 enter image description here