2

我正在使用 Swift 和 Accelerate,并尝试使用 Accelerate 的 vImage 模块中提供的 vImageContrastStretch 方法对图像进行颜色校正。

当我尝试拉伸直方图时,我得到的结果确实符合我的要求,但它有点太放松了。生成的图像直方图在侧面仍然有多余的空间。 在此处输入图像描述 正如您在图像中看到的,vImageContrastStretch(中间)操作的结果在直方图(标记为红色)的两侧仍有一些剪切空间。我的目标是在右边——注意直方图的差异。

我怎样才能剪断直方图的红色部分?我必须编写自己的算法还是使用 Accelerate 有更简单的解决方案?

我用来生成结果的代码示例:

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!
4

1 回答 1

3

从描述来看,它似乎vImageEndsInContrastStretch_ARGB8888()提供了您正在寻找的功能。从文档中的直方图概述:

Ends-in contrast 拉伸是对比拉伸操作的更复杂的版本。这些类型的函数最适用于在强度谱的最低和最高值处或附近具有一些像素的图像,但其直方图仍主要集中在一个区域中。ends-in contrast 拉伸函数将所有小于或等于某个级别的强度映射为 0;所有强度大于或等于一定水平至255;并对两者之间的所有值进行对比拉伸。低和高级别不是直接由两个给定的强度值定义,而是由百分比定​​义:对比拉伸操作的末端必须找到强度级别,使得某个百分比的像素低于其中一个强度值,并且某个百分比是高于其他强度值。

于 2018-06-23T00:09:47.673 回答