Get iOS camera to output Floating-Point Values in Swift 2

蹲街弑〆低调 提交于 2019-12-24 05:11:11

问题


I'm trying to implement the example on this site to get float images back from the camera, but the output image I get is still UInt32 pixels (each = 4 x UInt8 color vals).

I can't figure out why the conversion to float32 pixel color components doesn't happen. All I've tweaked is for swift 2.0 updates.

Example code collected together:

let output = AVCaptureVideoDataOutput()
var settings = [kCVPixelBufferPixelFormatTypeKey as NSString:kCVPixelFormatType_32BGRA]
output.videoSettings = settings
output.alwaysDiscardsLateVideoFrames = true

func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!)
// Get Video Buffer
var imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)

// Lock the base address of the pixel buffer
CVPixelBufferLockBaseAddress(imageBuffer, 0)

// Width and height
var width = CVPixelBufferGetWidth(imageBuffer);
var height = CVPixelBufferGetHeight(imageBuffer);

// Get the number of bytes per row for the pixel buffer
var bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer)

// RGB Colorspace
var colorSpace = CGColorSpaceCreateDeviceRGB()

// The raw pointer to the buffer data
var baseAddress : UnsafeMutablePointer<Void> = CVPixelBufferGetBaseAddress(imageBuffer)
var baseAddressUint8 : UnsafeMutablePointer<UInt8> = UnsafeMutablePointer<UInt8>(baseAddress)

// The bitmap info for the buffer data, we have 32BGRA
//var bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue) | CGBitmapInfo.ByteOrder32Little

//I updated the previous to swift 2 with:
let bitmapInfo:CGBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue | CGBitmapInfo.ByteOrder32Little.rawValue)

let destBitmapInfo:CGBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue | CGBitmapInfo.FloatComponents.rawValue | CGBitmapInfo.ByteOrderDefault.rawValue)

// Create a bitmap graphics context with the sample buffer data
let context = CGBitmapContextCreate(baseAddressUint8, width, height, 8, bytesPerRow, colorSpace, bitmapInfo)

var sourceBuffer = vImage_Buffer(data:CGBitmapContextGetData(context), height:vImagePixelCount(height), width:vImagePixelCount(width), rowBytes:bytesPerRow)

var targetBufferPtr = UnsafeMutablePointer<Float>.alloc(width*height*4)

var targetBuffer = vImage_Buffer(data: targetBufferPtr!, height: vImagePixelCount(height), width: vImagePixelCount(width), rowBytes: width*16)

var srcFormat : vImage_CGImageFormat = vImage_CGImageFormat(
            bitsPerComponent: UInt32(8),
            bitsPerPixel: UInt32(32),
            colorSpace: nil,
            bitmapInfo: bitmapInfo,
            version: UInt32(0),
            decode: nil,
            renderingIntent: CGColorRenderingIntent.RenderingIntentDefault
        )

var destFormat : vImage_CGImageFormat = vImage_CGImageFormat(
            bitsPerComponent: UInt32(32),
            bitsPerPixel: UInt32(128),
            colorSpace: nil,
            bitmapInfo: destBitmapInfo,
            version: UInt32(0),
            decode: nil,
            renderingIntent: CGColorRenderingIntent.RenderingIntentDefault
        )

var err : vImage_Error = 0
var c = vImageConverter_CreateWithCGImageFormat(
            &srcFormat,
            &destFormat,
            nil,
            UInt32(kvImagePrintDiagnosticsToConsole),
            &err)

err = vImageConvert_AnyToAny(
                c.takeUnretainedValue(),
                &sourceBuffer,
                &targetBuffer,
                nil,
                UInt32(kvImagePrintDiagnosticsToConsole))

//My addition to get pixel values
let outImage = vImageCreateCGImageFromBuffer( &targetBuffer, &destFormat, nil, nil, vImage_Flags(kvImageNoFlags), &err )
let cameraImage = CIImage(CGImage: outImage.takeUnretainedValue())
let ctx = CIContext(options:nil)
let cgImage = ctx.createCGImage(cameraImage, fromRect:outputImage.extent)
let rawData:NSData = CGDataProviderCopyData(CGImageGetDataProvider(cgImage))!
let pixelcolors = UnsafePointer<Float32>(rawData.bytes)
let pixelcolors_pointer = UnsafeBufferPointer<Float32>(start:pixelcolors, count:4)
var BGRA_index = 0
for pixelcolor in UnsafeBufferPointer(start: pixelcolors_pointer.baseAddress, count: pixelcolors_pointer.count) {
    if (pixelcolor.isNaN){break}
        switch BGRA_index {
        case 0:
            bluemean = CGFloat (pixelcolor)
        case 1:
            greenmean = CGFloat (pixelcolor)
        case 2:
            redmean = CGFloat (pixelcolor)
        case 3:
            break
        default:
            break
        }
        BGRA_index += 1
    }
}

来源:https://stackoverflow.com/questions/32749638/get-ios-camera-to-output-floating-point-values-in-swift-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!