Вероятно, самый быстрый способ сделать это - использовать шейдеры OpenGL ES 2.0, чтобы применить порог к вашему изображению. Мой GPUImage фреймворк инкапсулирует это, так что вам не нужно беспокоиться о более технических аспектах за кулисами.
Используя GPUImage, вы можете получить пороговую версию UIImage с использованием GPUImageLuminanceThresholdFilter и кода, подобного следующему:
GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:inputImage];
GPUImageLuminanceThresholdFilter *stillImageFilter = [[GPUImageLuminanceThresholdFilter alloc] init];
stillImageFilter.threshold = 0.5;
[stillImageSource addTarget:stillImageFilter];
[stillImageFilter useNextFrameForImageCapture];
[stillImageSource processImage];
UIImage *imageWithAppliedThreshold = [stillImageFilter imageFromCurrentFramebuffer];
Вы можете просто передать свое цветное изображение в это, потому что это автоматически извлекает яркость из каждого пикселя и применяет порог к этому. Любой пиксель выше порога становится белым, а любой ниже этого - черным. Вы можете настроить порог в соответствии с вашими конкретными условиями.
Однако, еще лучшим выбором для того, что вы собираетесь передать в Tesseract, был бы мой GPUImageAdaptiveThresholdFilter, который можно использовать так же, как GPUImageLuminanceThresholdFilter, только без порогового значения. Адаптивный порог выполняет операцию порога на основе 9-пиксельной области вокруг текущего пикселя, приспосабливаясь к местным условиям освещения. Это специально разработано, чтобы помочь с приложениями OCR, поэтому это может быть путь сюда.
Примеры изображений из обоих типов фильтров можно найти в этом ответе .
Обратите внимание, что обход через UIImage медленнее, чем обработка необработанных данных, поэтому эти фильтры намного быстрее при работе с прямыми источниками видео или фильмов и могут работать в режиме реального времени для этих входов. У меня также есть вывод необработанных пикселей, который может быть быстрее для использования с Tesseract.