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.