我正在尝试通过使用AVFoundation框架获取照片亮度/亮度的平均值。我正在做的是从AVCapturePhoto对象获取像素缓冲区(仅带有RAW捕获),通过制作UnsafeMutablePointer并在特定点获取亮度值来访问其像素。我期望得到的平均值应该在528和4095之间(黑白水平)。我不确定从此缓冲区获得什么样的价值,以及我是否以正确的方式访问其像素。我也不确定这是否是最好的方法,但是我从图像本身获得的绿色值似乎是压缩值,因为它永远不会超过255。
下面是我正在使用的代码:
// The pixel buffer stores an image in main memory.
let pixelBuffer = photo.pixelBuffer!
// Locks the BaseAddress of the PixelBuffer to ensure that the memory is accessible.
CVPixelBufferLockBaseAddress(pixelBuffer, CVPixelBufferLockFlags(rawValue: 0))
// Buffer width and height
let bufferWidth = CVPixelBufferGetWidth(pixelBuffer) // 4032
let bufferHeight = CVPixelBufferGetHeight(pixelBuffer) // 3024
/*
Returns the base address of the PixelBuffer.
Retrieving the base address for a PixelBuffer requires that the buffer base address be locked via a successful call to CVPixelBufferLockBaseAddress.
*/
let baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer)
let bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer) // 8064
/*
Returns the bits of the given instance, interpreted as having the specified type.
Use this function only to convert the instance passed as x to a layout-compatible type when conversion through other means is not possible.
*/
let pointer = unsafeBitCast(pixelBuffer, to: UnsafeMutablePointer<UInt16>.self) // what data type to use?
//let pointer = baseAddress?.bindMemory(to: UInt16.self, capacity: CVPixelBufferGetDataSize(pixelBuffer))
var lumaSum: Double = 0.0
for y in 0..<bufferHeight {
for x in 0..<bufferWidth {
let index = y * bufferWidth + x // or y * bytesPerRow + x
let luma = Double(pointer[index])
lumaSum += luma
}
}
let average = lumaSum / Double(bufferWidth * bufferHeight)
print(average)
CVPixelBufferUnlockBaseAddress(pixelBuffer, CVPixelBufferLockFlags(rawValue: 0))
以下是一些有用的信息:
像素格式:kCVPixelFormatType_14Bayer_RGGB ='rgg4',/ *拜耳14位Little-Endian,打包为16位,已排序R G R G ...与G B G B ...... /
缓冲区数据大小:24385600
包含RGB:true
每个组件的位数:8
每行字节数:8064
每块位数:16