viernes, 27 de marzo de 2015

PROMEDIO DE IMÁGENES

En algunas aplicaciones es necesario obtener un promedio sobre ciertas imágenes. Esto con el fin de sacar datos estadísticos o de otra índole para alguna prueba o propósito específico. Para poder llevar a cabo esto es necesario que las imágenes a las cuales se les calculará su valor promedio sean del mismo tamaño en píxeles a lo ancho y alto de la imagen.


     Para este ejemplo, se usarán dos imágenes con el mismo tamaño en píxeles de alto y ancho: 224x270.
     Primeramente se deben crear matrices que sean capaces de almacenar estas imágenes empleando 3 canales debido a que son imágenes a color. La instrucción:
cv::Mat imagenresultante = cv::Mat::zeros(alto, ancho, CV_32FC3);
Dice que la imagen a color será en 3 canales y se manejará con notación decimal, dado que hay que recordar que el máximo valor que puede tomar un píxel es 255, es decir si suma 250+200 le dará como resultado 255, si se pasa a flotante dará 450 y al dividir sobre 2 dará 225 el cual es el valor promedio del píxel.
   Por eso es importante que al final antes de desplegar la imagen resultante, convierta el valor nuevamente a entero sin signo de 8 bits. Un píxel puede variar su valor desde 0 a 255 para cada uno de los 3 canales de la imagen a color.
    La variable count, sirve para indicar el total de imágenes de las que se tomará el valor promedio, es importante que observe que tenga el mismo número de imágenes a las especificadas por la variable para evitar cualquier excepción en tiempo de ejecución.
    Para hacer el cambio a 8 bits sin signo, se aplica el comando:
imagenresultante.convertTo(imagenresultante,CV_8UC3);
      Dentro del ciclo for lo que resta es simplemente sumar imagen tras imagen y al final dividir entre el total cuyo valor está en la variable count.
      A continuación se le lista el código para poder llevar a cabo esta tarea:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace cv;
using namespace std;

int main()
{
    cv::Mat frame, tmp;
    const int count=2;
    const int ancho =224;
    const int alto = 270;
    cv::Mat imagenresultante = cv::Mat::zeros(alto, ancho, CV_32FC3);
    char nombrearchivo[50];
    for(int i=1; i<= count ; i++){
        sprintf(nombrearchivo,"cara%d.jpg",i);
        frame = imread(nombrearchivo, CV_LOAD_IMAGE_COLOR);
        frame.convertTo(tmp,CV_32FC3);
        imagenresultante += tmp;
        cout << "i = "<<i <<endl;
    }
    imagenresultante *= (1.0/count);

    imagenresultante.convertTo(imagenresultante,CV_8UC3);
    imshow("",imagenresultante);

    waitKey(0);
    return 0;
}

    Finalmente el resultado será algo similar a:


      Puede probar ahora usando más imágenes que tenga para ver resultados interesantes.



No hay comentarios:

Publicar un comentario