加速 - 降低对比度拉伸的阈值
Accelerate - Lower the threshold for contrast stretching
我正在使用 Swift 和 Accelerate,并尝试使用 Accelerate 的 vImage 模块中提供的 vImageContrastStretch 方法对图像进行色彩校正。
当我尝试拉伸直方图时,我得到的结果确实符合我的要求,但有点过于宽松。生成的图像直方图的两侧仍然有不需要的 space。
正如您在图像中看到的,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!
从描述来看,文档中的 vImageEndsInContrastStretch_ARGB8888()
offers the capability you're looking for. From the Histogram overview 似乎是:
Ends-in contrast stretch is a more complex version of the contrast stretch operation. These types of functions are best used on images that have some pixels at or near the lowest and highest values of the intensity spectrum, but whose histogram is still mainly concentrated in one area. The ends-in contrast stretch functions map all intensities less than or equal to a certain level to 0; all intensities greater than or equal to a certain level to 255; and perform a contrast stretch on all the values in between. The low and high levels are not defined directly by two given intensity values, but by percentages: the ends-in contrast stretch operation must find intensity levels such that a certain percent of pixels are below one of the intensity values, and a certain percent are above the other intensity value.
我正在使用 Swift 和 Accelerate,并尝试使用 Accelerate 的 vImage 模块中提供的 vImageContrastStretch 方法对图像进行色彩校正。
当我尝试拉伸直方图时,我得到的结果确实符合我的要求,但有点过于宽松。生成的图像直方图的两侧仍然有不需要的 space。
我怎样才能同时剪掉直方图的红色部分?我必须编写自己的算法还是使用 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!
从描述来看,文档中的 vImageEndsInContrastStretch_ARGB8888()
offers the capability you're looking for. From the Histogram overview 似乎是:
Ends-in contrast stretch is a more complex version of the contrast stretch operation. These types of functions are best used on images that have some pixels at or near the lowest and highest values of the intensity spectrum, but whose histogram is still mainly concentrated in one area. The ends-in contrast stretch functions map all intensities less than or equal to a certain level to 0; all intensities greater than or equal to a certain level to 255; and perform a contrast stretch on all the values in between. The low and high levels are not defined directly by two given intensity values, but by percentages: the ends-in contrast stretch operation must find intensity levels such that a certain percent of pixels are below one of the intensity values, and a certain percent are above the other intensity value.