I would like to get arrays of red, green and blue histogram data from the output of the CIAreaHistogramFilter. My current approach is not working.
According to the docs CIAreaHistogramFilter returns an image with width = bin size (256) in my case and height = 1
so each pixel contains the count of the rgb values for that bin.
if let areahistogram = self.areaHistogramFilter(ciImage) {
let attrs = [kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue, kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue] as CFDictionary
var pixelBuffer : CVPixelBuffer?
let status = CVPixelBufferCreate(kCFAllocatorDefault, Int(areahistogram.extent.size.width), Int(areahistogram.extent.size.height), kCVPixelFormatType_32ARGB, attrs, &pixelBuffer)
guard (status == kCVReturnSuccess) else {
return
}
self.hContext.render(areahistogram, to: pixelBuffer!)
CVPixelBufferLockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0));
let int32Buffer = unsafeBitCast(CVPixelBufferGetBaseAddress(pixelBuffer!), to: UnsafeMutablePointerUInt32.self)
let int32PerRow = CVPixelBufferGetBytesPerRow(pixelBuffer!)
var data = [Int]()
for i in 0..256 {
/* Get BGRA value for pixels */
let BGRA = int32Buffer[i]
data.append(Int(BGRA))
let red = (BGRA 16) & 0xFF;
let green = (BGRA 8) & 0xFF;
let blue = BGRA & 0xFF;
os_log("data[\(i)]:\(BGRA) red: \(red) green: \(green) blue: \(blue)")
}
CVPixelBufferUnlockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
}
results in zeros.
data[0]:0 red: 0 green: 0 blue: 0
data[1]:0 red: 0 green: 0 blue: 0
...
data[255]:134678783 red: 7 green: 7 blue: 7
similarly produces a bunch of zeros
or this
let baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer!)
let buffer = baseAddress!.assumingMemoryBound(to: UInt8.self)
for i in stride(from: 0, to: 256*4, by: 4) {
let blue = buffer[i]
let green = buffer[i+1]
let red = buffer[i+2]
os_log("data[\(i)]: red: \(red) green: \(green) blue: \(blue)")
}
or this variation that seems simpler
var red = [UInt8]()
var green = [UInt8]()
var blue = [UInt8]()
for i in 0..256 {
// Get BGRA value for pixel
let BGRA = int32Buffer[i]
withUnsafeBytes(of: BGRA.bigEndian) {
red.append($0[0])
green.append($0[1])
blue.append($0[2])
}
}