Ускорение - снизить порог для контрастного растяжения

Я использую Swift и Accelerate и пытаюсь откорректировать цвет изображения, используя метод vImageContrastStretch, доступный в модуле vImage Accelerate.

Когда я пытаюсь растянуть гистограммы, я получаю результат, который делает именно то, что я хочу, но он слишком расслаблен. Результирующие гистограммы изображения по-прежнему имеют нежелательное пространство по бокам. Как вы можете видеть на изображении, результат операции vImageContrastStretch (middle) все еще имеет место для разрезания с обеих сторон гистограммы (отмечена красным). Результат, к которому я стремлюсь, находится справа - обратите внимание на различия гистограммы.

Как я могу отрезать и красные части гистограммы? Должен ли я написать свой собственный алгоритм или есть более простое решение с использованием ускорения?

Пример кода, который я использую для генерации результата:

import UIKit
import PlaygroundSupport
import CoreImage
import Accelerate

let bitmapInfo:CGBitmapInfo = CGBitmapInfo(
    rawValue: CGImageAlphaInfo.last.rawValue)

var format = vImage_CGImageFormat(
    bitsPerComponent: 8,
    bitsPerPixel: 32,
    colorSpace: nil,
    bitmapInfo: bitmapInfo,
    version: 0,
    decode: nil,
    renderingIntent: CGColorRenderingIntent.defaultIntent)

extension CIImage
{
    convenience init?(fromvImageBuffer: vImage_Buffer)
    {
        var mutableBuffer = fromvImageBuffer
        var error = vImage_Error()

        let cgImage = vImageCreateCGImageFromBuffer(
            &mutableBuffer,
            &format,
            nil,
            nil,
            UInt32(kvImageNoFlags),
            &error)

        self.init(cgImage: cgImage!.takeRetainedValue())
    }
}

let inputImage: UIImage = UIImage(named: "IMG_2225.JPG")!

let ciImage = CIImage(cgImage: inputImage.cgImage!)

let imageRef = CIContext().createCGImage(
    ciImage,
    from: ciImage.extent)

var imageBuffer = vImage_Buffer()

vImageBuffer_InitWithCGImage(
    &imageBuffer,
    &format,
    nil,
    imageRef!,
    UInt32(kvImageNoFlags))

let pixelBuffer = malloc(imageRef!.bytesPerRow * imageRef!.height)

var outBuffer = vImage_Buffer(
    data: pixelBuffer,
    height: UInt(imageRef!.height),
    width: UInt(imageRef!.width),
    rowBytes: imageRef!.bytesPerRow)

vImageContrastStretch_ARGB8888(
    &imageBuffer,
    &outBuffer,
    UInt32(kvImageNoFlags))

let outImage = CIImage(fromvImageBuffer: outBuffer)
free(imageBuffer.data)
free(pixelBuffer)

outImage!

1 ответ

Решение

Из описания видно, что vImageEndsInContrastStretch_ARGB8888() предлагает возможности, которые вы ищете. Из обзора гистограммы в документах:

Концевое растяжение - более сложный вариант операции растяжения контраста. Эти типы функций лучше всего использовать на изображениях, у которых некоторые пиксели находятся на уровне или вблизи самых низких и самых высоких значений спектра интенсивности, но гистограмма которых по-прежнему в основном сосредоточена в одной области. Концевые функции растяжения контраста отображают все интенсивности, меньшие или равные определенному уровню, на 0; все интенсивности больше или равны определенному уровню до 255; и выполнить растяжение контраста для всех значений между ними. Низкие и высокие уровни определяются не двумя заданными значениями интенсивности, а процентами: операция растягивания по контрасту должна находить уровни интенсивности таким образом, чтобы определенный процент пикселей был ниже одного из значений интенсивности, а определенный процент выше другого значения интенсивности.

Другие вопросы по тегам