2016-03-23 5 views
6

Я исследовал все, чтобы найти ядро, которое выполняет адаптивное пороговое значение для iOS. К сожалению, я не понимаю язык ядра или его логику. Ниже, я нашел программу, которая выполняет пороговую (https://gist.github.com/xhruso00/a3f8a9c8ae7e33b8b23d)Adaptive Threshold CIKernel/CIFilter iOS

static NSString * const kKernelSource = @"kernel vec4 thresholdKernel(sampler image)\n" 
"{\n" 
" float inputThreshold = 0.05;\n" 
" float pass = 1.0;\n" 
" float fail = 0.0;\n" 
" const vec4 vec_Y = vec4(0.299, 0.587, 0.114, 0.0);\n" 
" vec4 src = unpremultiply(sample(image, samplerCoord(image)));\n" 
" float Y = dot(src, vec_Y);\n" 
" src.rgb = vec3(compare(Y - inputThreshold, fail, pass));\n" 
" return premultiply(src);\n" 
"}"; 

Можно ли переписать в адаптивном ядро ​​порогов? Изображение, которое я ему подаю, превратилось в B & W и уже размыто. Есть ли какие-то ресурсы, на которые вы могли бы обратить меня? Я хотел бы придерживаться CoreImage, поскольку вокруг него строится весь мой стек.

Edit: Лучший пример/ссылка от того, что я пытаюсь достичь был реализован в GPUImageAdaptiveThresholdFilter GPUImage в - https://github.com/BradLarson/GPUImage/blob/c5f0914152419437869c35e29858773b1a06083c/framework/Source/GPUImageAdaptiveThresholdFilter.m

ответ

2

Фильтр Саймона является правильным подходом для достижения желаемого эффекта, однако, вы должны изменить пару вещей.

Прежде всего, переключите порядок imageLuma и thresholdLuma, так как мы хотим, чтобы черные буквы оставались черными, а не наоборот. Кроме того, вы должны добавить константу (я выбрал 0.01), чтобы удалить шум.

var thresholdKernel = CIColorKernel(string: 
    "kernel vec4 thresholdFilter(__sample image, __sample threshold)" + 
     "{" + 
     " float imageLuma = dot(image.rgb, vec3(0.2126, 0.7152, 0.0722));" + 
     " float thresholdLuma = dot(threshold.rgb, vec3(0.2126, 0.7152, 0.0722));" + 
     " return vec4(vec3(step(thresholdLuma, imageLuma+0.001)), 1);"  
    "}" 

override var outputImage: CIImage! { 
    guard let inputImage = inputImage, 
     let thresholdKernel = thresholdKernel else { 
     return nil 
    } 
    let blurred = inputImage.applyingFilter("CIBoxBlur", withInputParameters: [kCIInputRadiusKey: 5]) // block size 
    let extent = inputImage.extent 
    let arguments = [inputImage, blurred] 
    return thresholdKernel.apply(withExtent: extent, arguments: arguments) 
} 

И это то, что вы получите только с помощью Apple, основного изображения, без необходимости установки каких-либо внешних библиотек :)

enter image description here

Конечно, вы можете поиграть немного со значениями константы и размера блока.

+0

Паскаль, спасибо за ваш ответ. Любая идея о том, как реализовать это в CoreImage? https://github.com/ctodobom/OpenNoteScanner/blob/master/app/src/main/java/com/todobom/opennotescanner/ImageProcessor.java#L409 – mmackh

+0

Вы упомянули константу 0.01, но у вас есть 0.001, это ошибка? Кроме того, вы применяете эту константу к imageLuma или пороговой яркости (при условии, что мне нужны белые буквы с черным фоном. – Pochi

+0

0.01 и 0.001, похоже, не слишком сильно отличаются друг от друга. Вы можете попробовать разные значения в соответствии с вашими потребностями , – triiiiista

4

Как это выглядит: Я использовал CoreImage CIBoxBlur (хотя выделенные сверточные фильтры могут Быстрее) и передал вывод этого в мой existing threshold filter.

class AdaptiveThresholdFilter: CIFilter 
{ 
    var inputImage : CIImage? 


    var thresholdKernel = CIColorKernel(string: 
    "kernel vec4 thresholdFilter(__sample image, __sample threshold)" + 
    "{" + 
    " float imageLuma = dot(image.rgb, vec3(0.2126, 0.7152, 0.0722));" + 
    " float thresholdLuma = dot(threshold.rgb, vec3(0.2126, 0.7152, 0.0722));" + 

    " return vec4(vec3(step(imageLuma, thresholdLuma)), 1.0);" + 
    "}" 
    ) 


    override var outputImage: CIImage! 
    { 
     guard let inputImage = inputImage, 
      thresholdKernel = thresholdKernel else 
     { 
      return nil 
     } 

     let blurred = inputImage.imageByApplyingFilter("CIBoxBlur", 
       withInputParameters: [kCIInputRadiusKey: 9]) 

     let extent = inputImage.extent 
     let arguments = [inputImage, blurred] 

     return thresholdKernel.applyWithExtent(extent, arguments: arguments) 
    } 
} 

Я нашел this image затененного страницы и с этим кодом:

let page = CIImage(image: UIImage(named: "son1.gif")!) 

let filter = AdaptiveThresholdFilter() 

filter.inputImage = page 

let final = filter.outputImage 

Я получил этот результат:

enter image description here

Ура!

Simon

+0

Спасибо, что начали меня. Я искал что-то более похожее на http://homepages.inf.ed.ac.uk/rbf/HIPR2/images/son1adp2.gif однако – mmackh

 Смежные вопросы

  • Нет связанных вопросов^_^