Saltar al contenido

¿Cómo puedo tomar el promedio de 100 imágenes usando opencv?

Luego de investigar con expertos en la materia, programadores de varias áreas y maestros hemos dado con la respuesta a la cuestión y la compartimos en esta publicación.

Solución:

Debe recorrer cada imagen y acumular los resultados. Dado que es probable que esto provoque un desbordamiento, puede convertir cada imagen en un CV_64FC3 imagen, y acumular en un CV_64FC3 imagen. Puedes usar también CV_32FC3 o CV_32SC3 para esto, es decir, usando float o integer en vez de double.

Una vez que haya acumulado todos los valores, puede utilizar convertTo a ambos:

  • hacer la imagen un CV_8UC3
  • divida cada valor por el número de imágenes para obtener la media real.

Este es un código de muestra que crea 100 imágenes aleatorias y calcula y muestra la media:

#include 
using namespace cv;

Mat3b getMean(const vector& images)

    if (images.empty()) return Mat3b();

    // Create a 0 initialized image to use as accumulator
    Mat m(images[0].rows, images[0].cols, CV_64FC3);
    m.setTo(Scalar(0,0,0,0));

    // Use a temp image to hold the conversion of each input image to CV_64FC3
    // This will be allocated just the first time, since all your images have
    // the same size.
    Mat temp;
    for (int i = 0; i < images.size(); ++i)
    
        // Convert the input images to CV_64FC3 ...
        images[i].convertTo(temp, CV_64FC3);

        // ... so you can accumulate
        m += temp;
    

    // Convert back to CV_8UC3 type, applying the division to get the actual mean
    m.convertTo(m, CV_8U, 1. / images.size());
    return m;


int main()

    // Create a vector of 100 random images
    vector images;
    for (int i = 0; i < 100; ++i)
    
        Mat3b img(598, 598);
        randu(img, Scalar(0), Scalar(256));

        images.push_back(img);
    

    // Compute the mean
    Mat3b meanImage = getMean(images);

    // Show result
    imshow("Mean image", meanImage);
    waitKey();

    return 0;

Suponga que las imágenes no necesitarán sufrir transformaciones (gamma, espacio de color o alineación). El paquete numpy le permite hacer esto de forma rápida y sucinta.

# List of images, all must be the same size and data type.
images=[img0, img1, ...]
avg_img = np.mean(images, axis=0)

Esto promoverá automáticamente los elementos para que floten. Si desea como BGR888, entonces:

avg_img = avg_img.astype(np.uint8)

También podría hacer uint16 para 16 bits por canal. Si está tratando con 8 bits por canal, es casi seguro que no necesitará 100 imágenes.

Calificaciones y reseñas

Nos encantaría que puedieras recomendar esta crónica si te fue de ayuda.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *