获取iOS相机以在Swift 2中输出浮点值

时间:2015-09-23 21:16:38

标签: ios swift avfoundation

我正在尝试在this site上实现示例以从相机中获取浮动图像,但我得到的输出图像仍然是UInt32像素(每个= 4 x UInt8颜色值)。

我无法弄清楚为什么不会发生转换为float32像素颜色分量的原因。所有我调整过的都是swift 2.0更新。

一起收集的示例代码:

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

0 个答案:

没有答案