2015-12-14 15 views
8

Attualmente sono bloccato su un video projet dalle immagini.Scegli la luminosità (esposizione) dall'immagine HDR

Problema:

sto estrarre immagini da UE4, a causa di un bug, non tutte le luci sono presi in considerazione durante il rendering della schermata. Le uscite sono immagini HDR. Voglio ottenere una luminosità migliore perché l'immagine esportata è molto scura, come la prima esposizione.

enter image description here

Con il parametro "Compensazione dell'esposizione" in UE4 io sono in grado di vero bene luminosità della mia scena, ma non può applicare questo parametro per il rendering screenshot: enter image description here

Tentativi:

utilizzando l'algoritmo Tonemapper (speciafically cv::TonemapDrago) io sono in grado di ottenere un risultato migliore immagine: enter image description here

Il problema principale, nel mio caso, dell'algoritmo Tonemap è dovuto al fatto che la luminosità globale viene modificata in base alla luminosità delle aree: nella seconda immagine, la finestra aggiunge molta luce, quindi l'algoritmo riduce tutta la luminosità per regolare il significare. Nel video reso, il cambiamento di luce è molto brutale.

Ho provato a cambiare brightness e la saturazione senza successo. Ho modificato il codice dello TonemapDrago cercando di utilizzare le costanti per alcuni steps dell'algoritmo.

Domanda:

vorrei "scegliere il tempo di esposizione" da un'immagine HDR. Tonemap si basa su diversi tempi di esposizione della stessa immagine, non interessanti nel mio caso.

Qualsiasi altra idea è benvenuta.

EDIT:

profondità CV :: Mat è 5, il tipo è CV_32FC3

cout << mat.step mi danno 19200

Qui ci sono 2 campioni che uso per provare a risolvere il mio problema:

First Image

Image with light window

Edit 2:

Impossibile immagine .HDR aperto con gimp, evento con il plugin "explosure blend". Sono in grado di ottenere risultati abbastanza grandi con Photoshop. Qualche idea dell'algoritmo dietro a questo? Ognuna delle 6 alghe Tonemap di OpenCV consente di scegliere una correzione dell'esposizione. enter image description here

EDIT 3:

ho seguito l'algoritmo spiegare in questo tuto per OpenGL, che sta dando questo codice C + a me:

cv::Mat exposureTonemap (cv::Mat m, float gamma = 2.2, float exposure = 1) 
{ 
    // Exposure tone mapping 
    cv::Mat exp; 
    cv::exp((-m) * exposure, exp); 

    cv::Mat mapped = cv::Vec3f(1.0) - exp; 
    // Gamma correction 
    cv::pow(exp, 1.0f/gamma, exp); 

    cv::imshow("exposure tonemap", exp); 
    cv::waitKey(); 

    return exp; 
} 

L'applicazione di questo algo sul mio. Immagine HDR Ho ottenuto risultati molto brillanti anche con una correzione di 1 e 1 per gamma ed esposizione: enter image description here

Leggendo il codice, c'è qualcosa di sbagliato perché 1 e 1 come argomento non dovrebbero modificare l'immagine. Risolto il problema, la risposta è pubblicata. grazie mille a @ user3896254 (Ge l'ha visto anche nel commento)

+0

Che formato è l'immagine di uscita in? Se non ha una profondità di bit sufficiente potresti non essere in grado di recuperare i dati persi. –

+0

@MarkRansom Il formato del pixel dell'immagine .hdr aperto con opencv è CV_32FC3 – Marcassin

+0

Se carichi un esempio di questa immagine da qualche parte, sarebbe più facile per noi aiutarti. È possibile scaricare il buffer di immagini raw in file binari e dire la risoluzione dell'immagine per consentire ad altri di utilizzarlo. – alexisrozhkov

risposta

2

considerare l'utilizzo di Retinex. Usa l'immagine singola per l'input ed è inclusa in GIMP, quindi è facile da giocare, inoltre è possibile ottenere il suo codice sorgente (o lanciare il proprio, che è comunque abbastanza semplice). Dal momento che hai rendering al posto delle foto - non c'è rumore e teoricamente sei in grado di adattare i colori alle tue esigenze.

Ma come ha già detto @ mark-ransom, è possibile che si riscontrino problemi nel recupero delle informazioni dall'output sottoposto a rendering. hai detto che hai immagini HDR come output di rendering, ma non sono sicuro di cosa intendi. È una singola immagine RGB? Qual è la profondità del colore di ogni canale? Ho provato ad applicare retinex al tuo campione, ma ovviamente non ha un bell'aspetto, a causa della compressione e dell'intervallo limitato applicato prima del salvataggio. Se il tuo output ha un range elevato e non è compresso, otterrai risultati migliori.

EDIT: Ho provato il retinex sul tuo input e si è rivelato non molto buono - le parti luminose dell'immagine (lampade/finestre) hanno introdotto brutti aloni scuri attorno a loro.

In questo caso la correzione gamma & è molto migliore. Il tuo codice è stato quasi bene, appena avuto un piccolo errore di battitura: invece di cv::pow(exp, 1.0f/gamma, exp); si dovrebbe avere avuto v::pow(mapped, 1.0f/gamma, exp);

ho pasticciato con il tuo codice, e ho notato che questo tonemapping sembra a degradare la saturazione del colore. Per ovviare a ciò, lo eseguo solo sul canale V dell'immagine HSV. Confrontate i risultati da soli (a sinistra - pieno spazio a viraggio, a destra - solo V): enter image description here enter image description here Note colore del pavimento, cielo in finestra e colore della luce giallastro che si è conservato con questo approccio.

Qui è pieno di codice per ragioni di completezza:

#include <opencv2/opencv.hpp> 

using namespace cv; 

Mat1f exposureTonemap (Mat1f m, float gamma = 2.2, float exposure = 1) { 
    // Exposure tone mapping 
    Mat1f exp; 
    cv::exp((-m) * exposure, exp); 
    Mat1f mapped = 1.0f - exp; 

    // Gamma correction 
    cv::pow(mapped, 1.0f/gamma, mapped); 

    return mapped; 
} 

Mat3f hsvExposureTonemap(Mat &a) { 
    Mat3f hsvComb; 
    cvtColor(a, hsvComb, COLOR_RGB2HSV); 

    Mat1f hsv[3]; 
    split(hsvComb, hsv); 

    hsv[2] = exposureTonemap(hsv[2], 2.2, 10); 

    merge(hsv, 3, hsvComb); 

    Mat rgb; 
    cvtColor(hsvComb, rgb, COLOR_HSV2RGB); 

    return rgb; 
} 

int main() { 
    Mat a = imread("first.HDR", -1); 
    Mat b = imread("withwindow.HDR", -1); 

    imshow("a", hsvExposureTonemap(a)); 
    imshow("b", hsvExposureTonemap(b)); 
    waitKey(); 

    return 0; 
} 
+0

Wooo bella, la tonemap sul 'valore' di L'immagine HSV dà risultati migliori. Grazie per questa soluzione! – Marcassin

0

Che tipo di illuminazione di scena stai usando attualmente? Sembra che tu stia usando punti luce dove sarebbero le lampadine, ma non sono abbastanza luminose. Nella scena non resa, la scena sarà piena di luminosità. Nella scena renderizzata, otterrai l'oscurità.

vorrei consigliare forse almeno un cielo luce minima in modo da avere sempre un po 'di luce in tutta la scena (a meno che non si dispone di aree di oscurità reale)

+0

Il problema di questo errore è che alcune luci di atmosfera e luci a punta non sono prese nel rendering a 360 di un punto di vista in UE. L'aggiunta di uno skybox più luminoso aumenterà la luce dalla finestra e il Tonemapper algo sarà ancora più brutale con il movimento della fotocamera.Anche con quello, l'immagine estratta sarà troppo scura per essere usata 'così com'è' – Marcassin

0
cv::Mat exposureTonemap (cv::Mat m, float gamma = 2.2, float exposure = 1) 
{ 
    // Exposure tone mapping 
    cv::Mat exp; 
    cv::exp((-m) * exposure, exp); 
    cv::Mat mapped = cv::Scalar(1.0f, 1.0f, 1.0f) - exp; 

    // Gamma correction 
    cv::pow(mapped, 1.0f/gamma, mapped); 

    /* 
    cv::imshow("exposure tonemap", mapped); 
    cv::waitKey(); 
    */ 

    return mapped; 
} 

Questo algoritmo è un Tonemapper cercando di simulare Correzione esposizione in un HDR Se si desidera utilizzarlo in OpenCV 3.0 non dimenticare di aprire con -1 come ultimo argomento di imread cv::Mat img = cv::imread("mypicture.HDR", -1);

enter image description here

Problemi correlati