OpenCV Imágenes HDR

Una imagen High Dynamic Range (HDR) o Alto Rango Dinámico en español, es un tipo de imagen que busca reproducir los distintos niveles de intensidad de luz que pueden ver nuestros ojos, logrando visualizar una imagen digital lo mas cercano posible a como la veríamos en el mundo real.

No podemos apreciar todo el esplendor de una imagen HDR en un monitor normal, requerimos un monitor con soporte para la tecnología HDR, en la actualidad algunas compañías como samsumg ya los producen, en caso de que no contemos con un moderno monitor, utilizaremos la técnica de Tone Mapping o Mapeo Tonal, para lograr mapear la información HDR a un formato que pueda ser representado adecuadamente por un monitor común.

Para crear una imagen HDR solo necesitamos una cámara que permita el ajuste manual de la exposición de una foto, capturamos una seria de fotografías de la misma escena pero con niveles de exposición diferente, existen cámaras que pueden hacer esto automáticamente. 

hdr opencv

Estas imágenes fueron extraídas de la carpeta de datos de prueba de OpenCV 3.x, las puedes encontrar en: https://github.com/Itseez/opencv_extra/tree/master/testdata/cv/hdr

Creación de un HDRI con OpenCV

Lo primero que haremos será cargar la lista de imágenes y sus distintos tiempos de exposición, los mismos están definidos en el archivo data/exposures/list.txt, leemos el archivo y obtenemos un std::vector<Mat> con las imágenes y un std::vector<float> con los tiempos de exposición inversos de cada imagen. 

//...
    vector<Mat> images;
    vector<float> times;
    loadExposureSeq("data/exposures", images, times);
//...

void loadExposureSeq(String path, vector<Mat>& images, vector<float>& times)
{
    path = path + std::string("/");
    ifstream list_file((path + "list.txt").c_str());
    string name;
    float val;
    while (list_file >> name >> val) {
        Mat img = imread(path + name);
        images.push_back(img);
        times.push_back(1 / val);
    }
    list_file.close();
}

OpenCV 3.x cuenta con las funciones createCalibrateDebevec y createMergeDebevec utilizados para crear los objetos CalibrateDebevec y MergeDebevec respectivamente, estas clases implementan el método Debevec para calcular la función de respuesta de la cámara y fusionar la imágenes expuestas en un HDR.

Mat response;
Ptr<CalibrateDebevec> calibrate = createCalibrateDebevec();
calibrate->process(images, response, times);

Mat hdr;
Ptr<MergeDebevec> merge_debevec = createMergeDebevec();
merge_debevec->process(images, hdr, times, response);

imwrite("memorial.hdr", hdr);

Este código genera el archivo memorial.hdr, es importante mencionar que OpenCV también posee las funciones: createCalibrateRobertson y MergeRobertson si deseas probar o utilizar el método de Robertson.

Mapeo Tonal con OpenCV

Para generar el mapeo tonal utilizaremos la clase TonemarDurand, contamos con otros métodos disponibles como:

  • createTonemapDrago, createTonemapReinhard, y createTonemapMantiuk.
Mat ldr;
Ptr<TonemapDurand> tonemap = createTonemapDurand(2.2f);
tonemap->process(hdr, ldr);

La imagen resultado suele ser llamada LDR por las siglas de Bajo Rango Dinámico, ya que con esta técnica disminuimos el rango dinámico de una imagen HDR para que pueda ser visualizada en un monitor con un reducido rango dinámico.

ldr

En este ejemplo se aplica una corrección gamma de 2.2, existen mas valores que podemos configurar para lograr resultados deseados, si nos los indicamos usaremos los valores de la configuración por defecto. 

Fusión de Exposición

Es una manera más simple de generar una imagen LDR si no necesitamos crear una imagen HDR intermedia ni aplicar mapeo tonal, esta método utiliza la clase MergeMertens para crear una imagen LDR a partir de una colección de imágenes con diferentes exposiciones, no necesitamos los niveles.

Mat fusion;
Ptr<MergeMertens> merge_mertens = createMergeMertens();
merge_mertens->process(images, fusion);

fusion

Proyecto en GitHub: OpenCV Imágenes HDR

Comentarios

Temas relacionados

Entradas populares de este blog

tkinter Grid

Conectar SQL Server con Java

Controles y Contenedores JavaFX 8 - I

tkinter Canvas