iOS   发布时间:2022-03-30  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了ios – 计算AVCaptureVideoDataOutput feed的平均RGB像素值的最快方法 – CPU / GPU大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我希望AVCaptureVideoDataOutput中的整个图像的平均像素值,我正在捕捉图像并循环通过像素来对它们求和.

我想知道是否有更有效的方法来执行GPU / openGL,因为这是一个可并行化的图像处理任务. (也许是一个沉重的高斯模糊,并读取中心像素值?)

一个特定的要求是使用高水平的平均值来获得高精度结果.请注意下面的CGFloat结果.

目前swift 2代码

编辑:添加了CIAreaAverage的实现,如Simon所示.它由useGPU bool分隔.

func captureOutput(captureOutput: AVCaptureOutput!,didOutputSampleBuffer sampleBuffer: CMSampleBuffer!,fromConnection connection: AVCaptureConnection!) {

    var redmean:CGFloat = 0.0;
    var greenmean:CGFloat = 0.0;
    var bluemean:CGFloat = 0.0;

    if (useGPU) {
            let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
            let cameraImage = CIImage(CVPixelBuffer: pixelBuffer!)
            let filter = CIFilter(name: "CIAreaAverage")
            filter!.SETVALue(cameraImage,forKey: kCIInputImageKey)
            let outputImage = filter!.valueForKey(kCIoUtputImageKey) as! CIImage!

            let ctx = CIContext(options:nil)
            let cgImage = ctx.createCGImage(outputImage,fromRect:outputImage.extent)

            let rawData:NSData = CGDataProviderCopyData(CGImageGetDataProvider(cgImagE))!
            let pixels = UnsafePointer<UInt8>(rawData.bytes)
            let bytes = UnsafeBufferPointer<UInt8>(start:pixels,count:rawData.length)
            var BGRA_index = 0
            for pixel in UnsafeBufferPointer(start: bytes.baseAddress,count: bytes.count) {
                switch BGRA_index {
                case 0:
                    bluemean = CGFloat (pixel)
                case 1:
                    greenmean = CGFloat (pixel)
                case 2:
                    redmean = CGFloat (pixel)
                case 3:
                    break
                default:
                    break
                }
                BGRA_index++

            }
     } else {
            let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
            CVPixelBufferLockBaseAddress(imageBuffer!,0)

            let baseAddress = CVPixelBufferGetBaseAddressOfPlane(imageBuffer!,0)
            let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer!)
            let width = CVPixelBufferGetWidth(imageBuffer!)
            let height = CVPixelBufferGetHeight(imageBuffer!)
            let colorSpace = CGColorSpaceCreateDeviceRGB()

            let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawvalue).rawValue | CGBitmapInfo.byteOrder32Little.rawValue

            let context = CGBitmapContextCreate(baseAddress,width,height,8,bytesPerRow,colorSpace,bitmapInfo)
            let imageRef = CGBitmapContextCreateImage(context)
            CVPixelBufferUnlockBaseAddress(imageBuffer!,0)
            let data:NSData = CGDataProviderCopyData(CGImageGetDataProvider(imageRef))!
            let pixels = UnsafePointer<UInt8>(data.bytes)
            let bytes = UnsafeBufferPointer<UInt8>(start:pixels,count:data.length)
            var redsum:CGFloat = 0
            var greensum:CGFloat  = 0
            var bluesum:CGFloat  = 0
            var BGRA_index = 0
            for pixel in UnsafeBufferPointer(start: bytes.baseAddress,count: bytes.count) {
            switch BGRA_index {
            case 0:
                bluesum += CGFloat (pixel)
            case 1:
                greensum += CGFloat (pixel)
            case 2:
                redsum += CGFloat (pixel)
            case 3:
                //alphasum += UInt64(pixel)
                break
            default:
                break
            }

            BGRA_index += 1
            if BGRA_index == 4 { BGRA_index = 0 }
        }
        redmean = redsum / CGFloat(bytes.count)
        greenmean = greensum / CGFloat(bytes.count)
        bluemean = bluesum / CGFloat(bytes.count)            
        }

print("R:\(redmean) G:\(greenmean) B:\(bluemean)")

解决方法

@H_696_20@ CIAreaAverage过滤器性能不佳的问题和原因是缺少输入范围的定义.
因此,滤镜的输出与输入图像的大小相同,因此您可以在完整的图像上循环而不是1×1像素的图像.因此,执行所需的时间与初始版本相同.

如@L_607_11@的文档中所述,您可以指定inputExtent参数.
如何在swift中完成这个问题可以在类似问题的this answer中找到:

let cameraImage = CIImage(CVPixelBuffer: pixelBuffer!)
    let extent = cameraImage.extent
    let inputExtent = CIVector(x: extent.origin.x,y: extent.origin.y,z: extent.size.width,w: extent.size.height)
    let filter = CIFilter(name: "CIAreaAverage",withInputParameters: [kCIInputImageKey: cameraImage,kCIInputExtentKey: inputExtent])!
    let outputImage = filter.outputImage!

如果要挤出更高的性能,可以确保重用CIContext,而不是为每个捕获的帧重新创建它.

大佬总结

以上是大佬教程为你收集整理的ios – 计算AVCaptureVideoDataOutput feed的平均RGB像素值的最快方法 – CPU / GPU全部内容,希望文章能够帮你解决ios – 计算AVCaptureVideoDataOutput feed的平均RGB像素值的最快方法 – CPU / GPU所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。