W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎勵
今天,大多數(shù)數(shù)字圖像和成像設(shè)備每通道使用8位,從而將設(shè)備的動態(tài)范圍限制在兩個數(shù)量級(實(shí)際上為256級),而人眼可以適應(yīng)10個數(shù)量級的照明條件。當(dāng)我們拍攝現(xiàn)實(shí)世界的場景時,明亮的地區(qū)可能曝光過度,而黑暗的區(qū)域可能曝光不足,所以我們無法使用單次曝光拍攝所有細(xì)節(jié)。HDR圖像與每個通道使用更多8位(通常為32位浮點(diǎn)值)的圖像一起使用,允許更寬的動態(tài)范圍。
有不同的獲取HDR圖像的方法,但最常見的方法是使用不同曝光值拍攝的場景照片。要結(jié)合這種曝光,了解您的相機(jī)的響應(yīng)功能是有用的,并且有算法來估計它。HDR圖像混合后,必須將其轉(zhuǎn)換回8位才能在通常的顯示屏上進(jìn)行查看。這個過程叫做tonemapping。當(dāng)場景或相機(jī)的對象在拍攝之間移動時,會出現(xiàn)額外的復(fù)雜性,因?yàn)榫哂胁煌毓獾膱D像應(yīng)該被注冊和對準(zhǔn)。
在本教程中,我們將介紹如何從曝光序列生成和顯示HDR圖像。在我們的情況下,圖像已經(jīng)對齊,沒有移動的對象。我們還展示了一種稱為曝光融合的替代方法,產(chǎn)生低動態(tài)范圍圖像。HDR管道的每一步都可以使用不同的算法來實(shí)現(xiàn),所以看看參考手冊來看看。
#include <opencv2/photo.hpp>
#include "opencv2/imgcodecs.hpp"
#include <opencv2/highgui.hpp>
#include <vector>
#include <iostream>
#include <fstream>
using namespace cv;
using namespace std;
void loadExposureSeq(String, vector<Mat>&, vector<float>&);
int main(int, char**argv)
{
vector<Mat> images;
vector<float> times;
loadExposureSeq(argv[1], images, times);
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);
Mat ldr;
Ptr<TonemapDurand> tonemap = createTonemapDurand(2.2f);
tonemap->process(hdr, ldr);
Mat fusion;
Ptr<MergeMertens> merge_mertens = createMergeMertens();
merge_mertens->process(images, fusion);
imwrite("fusion.png", fusion * 255);
imwrite("ldr.png", ldr * 255);
imwrite("hdr.hdr", hdr);
return 0;
}
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();
}
vector<Mat> images;
vector<float> times;
loadExposureSeq(argv[1], images, times);
首先,我們從用戶定義的文件夾加載輸入圖像和曝光時間。該文件夾應(yīng)包含包含文件名和反曝光時間的圖像和list.txt文件。
對于我們的圖像序列,列表如下:
memorial00.png 0.03125
memorial01.png 0.0625
...
memorial15.png 1024
Mat response;
Ptr<CalibrateDebevec> calibrate = createCalibrateDebevec();
calibrate->process(images, response, times);
需要了解大量HDR構(gòu)建算法的相機(jī)響應(yīng)函數(shù)(CRF)。我們使用一種校準(zhǔn)算法來估計所有256個像素值的反CRF。
Mat hdr;
Ptr<MergeDebevec> merge_debevec = createMergeDebevec();
merge_debevec->process(images, hdr, times, response);
我們使用Debevec的加權(quán)方案來構(gòu)建使用上一項(xiàng)計算的響應(yīng)的HDR圖像。
Mat ldr;
Ptr<TonemapDurand> tonemap = createTonemapDurand(2.2f);
tonemap->process(hdr, ldr);
由于我們希望通過LDR顯示我們的結(jié)果,我們必須將我們的HDR圖像映射到保留大部分細(xì)節(jié)的8位范圍。這是噸位法的主要目標(biāo)。我們使用tonemapper進(jìn)行雙邊濾波,并將2.2設(shè)置為伽馬校正值。
Mat fusion;
Ptr<MergeMertens> merge_mertens = createMergeMertens();
merge_mertens->process(images, fusion);
如果我們不需要HDR圖像,可以選擇合并我們的曝光。該過程稱為曝光融合,并產(chǎn)生不需要伽馬校正的LDR圖像。它也不使用照片的曝光值。
imwrite("fusion.png", fusion * 255);
imwrite("ldr.png", ldr * 255);
imwrite("hdr.hdr", hdr);
現(xiàn)在是時候看結(jié)果了。請注意,HDR圖像不能以常見圖像格式存儲,因此我們將其保存到Radiance圖像(.hdr)。此外,所有HDR成像功能都會將結(jié)果返回[0,1]范圍,因此我們應(yīng)該將結(jié)果乘以255。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: