es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Obtén el promedio RGB de “CIAreaAverage” del CMSampleBuffer con una precisión de punto flotante en Swift.

Estoy tratando de obtener el valor promedio RGB de mi flujo de “AVCaptureVideoDataOutput”. Encontré la siguiente solución en StackOverflow:

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

Pero esto produce el promedio como un entero, pero lo necesito en formato flotante con la precisión actual. El redondeo es un problema en el dominio del problema con el que estoy trabajando. ¿Hay alguna manera de obtener un promedio flotante de manera eficiente?

¡Muchas gracias!

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Sí, puedes calcular el promedio como un número de punto flotante dividiendo la suma de los valores RGB por 3. Aquí tienes el código modificado que devuelve el promedio como un Float:

    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
    var sum: CGFloat = 0
    for pixel in UnsafeBufferPointer(start: bytes.baseAddress, count: bytes.count) {
         switch BGRA_index {
             case 0:
                  sum += CGFloat(pixel)
             case 1:
                  sum += CGFloat(pixel)
             case 2:
                  sum += CGFloat(pixel)
             case 3:
                  break
             default:
                  break
         }
         BGRA_index++
    }
    let average = Float(sum / 3)
    

    Este código calcula la suma de los valores RGB como un CGFloat, y luego lo divide por 3 para obtener el promedio como un Float.

Comments are closed.