La mezcla alfa para promediar cuadros en Core Image.
En mi aplicación, estoy tratando de implementar una función de difuminado de movimiento que apile diferentes fotogramas (promediándolos) provenientes de la salida de video en una única imagen. El efecto que estoy tratando de obtener se explica bien aquí: https://photographylife.com/image-averaging-technique.
Intenté usar un CIKernel personalizado que realiza la operación de promedio en cada canal de color de la siguiente manera:
float4 makeAverage(sample<t> currentStack, sample<t> newImage, float stackCount) {
float4 cstack = unpremultiply(currentStack);
float4 nim = unpremultiply(newImage);
float4 avg = ((cstack * stackCount) + nim) / (stackCount + 1.0);
return premultiply(avg);
}
Puede encontrar más detalles sobre el código completo aquí: https://stackoverflow.com/questions/70045823/problems-with-frame-averaging-with-core-image.
Funciona, pero después de un tiempo, aparecen manchas extrañas en la imagen, lo que indica que los canales de color se están recortando.
¿Existe alguna manera de lograr los mismos resultados utilizando la mezcla alfa en la imagen central? Quizás, en lugar de realizar la operación de apilamiento en los canales de color, ¿podría apilar imágenes consecutivas con un valor alfa decreciente?
Si es así, ¿cuál sería el procedimiento/algoritmo para hacerlo?
davy.ai
Desenfoque de movimiento utilizando la mezcla alfa en Core Image
Si tienes problemas con el recorte de canales de color al intentar implementar una función de desenfoque de movimiento utilizando el promediado de imágenes, es posible que prefieras considerar el uso de la mezcla alfa en su lugar. Con la mezcla alfa, puedes apilar marcos posteriores con valores alfa cada vez menores para lograr el efecto deseado.
Para implementar esto en Core Image, podrías seguir los siguientes pasos:
CIImage
vacío para contener la imagen apilada final.CIImage
.CIFilter
deCISourceOverCompositing
.CIImage
a un nivel apropiado, como 1,0/n, donden
es el número de cuadros que se apilan.CIFilter
al objeto actual deCIImage
apilado y al nuevo objetoCIImage
.CIFilter
como el nuevo objetoCIImage
apilado.Esto resultará en una única imagen
CIImage
que representa los cuadros apilados, con el efecto de desenfoque de movimiento deseado.Aquí tienes un ejemplo de cómo implementar este algoritmo en Swift, asumiendo que
inputImages
es una matriz de objetosCIImage
que representan los cuadros que se deben apilar:espero que esto te ayude a lograr el efecto de desenfoque de movimiento que buscas sin problemas de recorte de canales de color. {=”” let=”” alpha=”1.0″ cgfloat(i+1)=”” let=”” filter=”CIFilter(name:” “cisourceovercompositing”)!=”” filter.setvalue(inputimages[i],=”” forkey:=”” kciinputimagekey)=”” filter.setvalue(stackedimage,=”” forkey:=”” kciinputbackgroundimagekey)=”” filter.setvalue(alpha,=”” forkey:=”” kciinputalphakey)=”” stackedimage=”filter.outputImage!” }=”” usa=”” stackedimage=”” según=”” sea=”” necesario=”” “`=”” espero=”” que=”” esto=”” te=”” ayude=”” a=”” lograr=”” el=”” efecto=”” de=”” desenfoque=”” de=”” movimiento=”” que=”” buscas=”” sin=”” problemas=”” de=”” recorte=”” de=”” canales=”” de=””></count {
let alpha = 1.0 / cgfloat(i+1)
let filter = cifilter(name: “cisourceovercompositing”)!
filter.setvalue(inputimages[i], forkey: kciinputimagekey)
filter.setvalue(stackedimage, forkey: kciinputbackgroundimagekey)
filter.setvalue(alpha, forkey: kciinputalphakey)
stackedimage = filter.outputimage!
}
//usa stackedimage según sea necesario
“`
espero que esto te ayude a lograr el efecto de desenfoque de movimiento que buscas sin problemas de recorte de canales de color.>