Ускорение - снизить порог для контрастного растяжения
Я использую 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; и выполнить растяжение контраста для всех значений между ними. Низкие и высокие уровни определяются не двумя заданными значениями интенсивности, а процентами: операция растягивания по контрасту должна находить уровни интенсивности таким образом, чтобы определенный процент пикселей был ниже одного из значений интенсивности, а определенный процент выше другого значения интенсивности.