Jerry
Jerry

Reputation: 51

Get Pixel RGB value from CVPixelBuffer on Swift 4

My Problem is that I can get the pixel value from CVPixelBuffer, but all the value is 255,255,255. I use code as below:

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.

here is a link for get pixel from CVBuffer

Upvotes: 2

Views: 1640

Answers (1)

t0rn
t0rn

Reputation: 1

It depends on pixel format type.

Here is an example for getting RBG "values" from CVImageBuffer with kCVPixelFormatType_32BGRA type using Accelerate framework.

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)
}

Upvotes: 0

Related Questions