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

Nir*_*att 5 ocr image-processing ios gpuimage

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

我正在使用这样的GPUImage代码在应用OCR之前对输入图像进行二值化.

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

在此输入图像描述

在此输入图像描述

我不能用相同的阈值处理两者.低价值似乎随后很好,第一个价值更高.

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

我该怎么处理?

更新:

我尝试使用GPUImageAverageLuminanceThresholdFilter默认乘数= 1.它适用于第一张图像,但第二张图像仍然是问题.

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

在此输入图像描述

在此输入图像描述

更新II:

经过布拉德的这个回答后,尝试过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;
}
Run Code Online (Sandbox Code Playgroud)

Nir*_*att 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;
} 
Run Code Online (Sandbox Code Playgroud)

我使用这个实现了几乎 90% - 我确信一定有更好的选择,但我尽我所能尝试,8.0 是适用于我的大多数输入图像blurSize的值。

对于其他人来说,祝你尝试顺利!