在 Swift 4 上从 CVPixelBuffer 获取像素 RGB 值

问题描述 投票:0回答:1

我的问题是我可以从 CVPixelBuffer 获取像素值,但所有值都是 255,255,255。 我使用的代码如下:

func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {

    guard let photoPixelBuffer = photo.pixelBuffer else {
        print("Error occurred while capturing photo: Missing pixel buffer (\(String(describing: error)))")

        return
    }
    func pixelFrom(x: Int, y: Int, movieFrame: CVPixelBuffer) -> (UInt8, UInt8, UInt8) {
        let baseAddress = CVPixelBufferGetBaseAddress(movieFrame)

        let width = CVPixelBufferGetWidth(movieFrame)
        let height = CVPixelBufferGetHeight(movieFrame)

        let bytesPerRow = CVPixelBufferGetBytesPerRow(movieFrame)
        let buffer = baseAddress!.assumingMemoryBound(to: UInt8.self)

        let index = x+y*bytesPerRow
        let b = buffer[index]
        let g = buffer[index+1]
        let r = buffer[index+2]

        return (r, g, b)
    }
    print(pixelFrom(x:1,y:1,movieFrame:photoPixelBuffer))
    all the r,g,b value is 255.

这里是从 CVBuffer 获取像素的链接

ios iphone swift ios11
1个回答
0
投票

这取决于像素格式类型。

这是使用 Accelerate 框架从 CVImageBuffer 获取

kCVPixelFormatType_32BGRA
类型的 RBG“值”的示例。

import Foundation
import CoreVideo
import Accelerate

func convert(imageBuffer: CVImageBuffer) throws -> Rgb888ImageData {
    guard CVPixelBufferGetPixelFormatType(imageBuffer) == kCVPixelFormatType_32BGRA else {
        throw ConversionError.invalidPixelFormat
    }
    guard CVPixelBufferLockBaseAddress(imageBuffer, .readOnly) == kCVReturnSuccess else {
        throw ConversionError.bufferLockError
    }
    defer {
        CVPixelBufferUnlockBaseAddress(imageBuffer, .readOnly)
    }
    guard let baseAddress = CVPixelBufferGetBaseAddress(imageBuffer) else {
        throw ConversionError.invalidImageBuffer
    }
    let width = CVPixelBufferGetWidth(imageBuffer)
    let height = CVPixelBufferGetHeight(imageBuffer)
    let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer)
    //Prepare 32BGRA source buffer
    var srcBuffer = vImage_Buffer(data: baseAddress,
                                  height: vImagePixelCount(height),
                                  width: vImagePixelCount(width),
                                  rowBytes: bytesPerRow)
    //Prepare destination RGB data
    let rgbBytesPerRow = width * 3
    var rgbData = Data(count: height * rgbBytesPerRow)
    let rawDestinationPtr = rgbData.withUnsafeMutableBytes{ $0.baseAddress }
    guard let rawDestinationPtr = rawDestinationPtr else {
        throw ConversionError.bufferLockError
    }
    var destBuffer = vImage_Buffer(data: rawDestinationPtr,
                                   height: vImagePixelCount(height),
                                   width: vImagePixelCount(width),
                                   rowBytes: rgbBytesPerRow)
    //Apply conversion BGRA -> RGB using Accelerate framework (CPU)
    let error = vImageConvert_BGRA8888toRGB888(&srcBuffer, &destBuffer, vImage_Flags(kvImageNoFlags))
    guard error == kvImageNoError else {
        throw ConversionError.BGRA8888toRGB888Conversion
    }
    
    return Rgb888ImageData(rgbData: rgbData, imageWidth: width, imageHeight: height)
}
© www.soinside.com 2019 - 2024. All rights reserved.