欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python使用OpenCV獲取高動(dòng)態(tài)范圍成像HDR

 更新時(shí)間:2022年04月29日 15:00:21   作者:liferecords  
這篇文章主要介紹了python使用OpenCV獲取高動(dòng)態(tài)范圍成像HDR,如何使用不同曝光設(shè)置拍攝的多張圖像創(chuàng)建高動(dòng)態(tài)范圍圖像HDR,下文嗎更詳細(xì)的內(nèi)容介紹,需要的小伙伴可以參考一下

1 背景

1.1 什么是高動(dòng)態(tài)范圍(HDR)成像?

大多數(shù)數(shù)碼相機(jī)和顯示器將彩色圖像捕獲或顯示為24位矩陣。每個(gè)顏色通道有8位,一共三個(gè)通道,因此每個(gè)通道的像素值在0到255之間。換句話(huà)說(shuō),普通相機(jī)或顯示器具有有限的動(dòng)態(tài)范圍。

然而,我們周?chē)氖澜珙伾幸粋€(gè)非常大的變化范圍。當(dāng)燈關(guān)閉時(shí),車(chē)庫(kù)會(huì)變黑;太陽(yáng)照射下,車(chē)庫(kù)看起來(lái)變得非常明亮。即使不考慮這些極端情況,在日常情況下,8位也幾乎不足以捕捉場(chǎng)景。因此,相機(jī)會(huì)嘗試估計(jì)光線(xiàn)并自動(dòng)設(shè)置曝光,以使圖像中最有用的部分具有良好的動(dòng)態(tài)顏色范圍,而太暗和太亮的部分分別被設(shè)置為0和255。

在下圖中,左側(cè)的圖像是正常曝光的圖像。請(qǐng)注意,背景中的天空已完全消失,因?yàn)橄鄼C(jī)決定使用一個(gè)能夠讓小孩被正確拍攝而明亮的天空被忽略的設(shè)置。右側(cè)圖像是iPhone生成的HDR圖像。

[OpenCV實(shí)戰(zhàn)]23 使用OpenCV獲取高動(dòng)態(tài)范圍成像HDR_#include

iPhone如何捕獲HDR圖像?它實(shí)際上在三種不同的曝光下拍攝3張圖像。圖像是連續(xù)快速拍攝的,因此三次拍攝之間幾乎沒(méi)有偏移。然后組合三個(gè)圖像以產(chǎn)生HDR圖像。

1.2 高動(dòng)態(tài)范圍(HDR)成像如何工作?

在本節(jié)中,我們將介紹使用OpenCV創(chuàng)建HDR圖像的步驟。

1)使用不同曝光設(shè)置拍攝多張圖像

當(dāng)我們使用相機(jī)拍照時(shí),每個(gè)通道只有8位來(lái)表示場(chǎng)景的動(dòng)態(tài)范圍(亮度范圍)。但是我們可以通過(guò)改變快門(mén)速度在不同曝光下拍攝場(chǎng)景的多個(gè)圖像。大多數(shù)單反相機(jī)都有一個(gè)稱(chēng)為自動(dòng)包圍曝光(AEB)的功能,只需按一下按鈕,我們就可以在不同曝光下拍攝多張照片。在相機(jī)上使用AEB或在手機(jī)上使用自動(dòng)包圍應(yīng)用程序,我們可以一個(gè)接一個(gè)地快速拍攝多張照片,因此場(chǎng)景不會(huì)改變。當(dāng)我們?cè)趇Phone中使用HDR模式時(shí),它需要三張照片(安卓可以下載超級(jí)相機(jī)這個(gè)軟件)。

  • 1曝光不足的圖像:此圖片比正確的曝光圖像暗。目標(biāo)是拍攝非常明亮的圖像部分。
  • 2正確曝光的圖像:這是相機(jī)根據(jù)估計(jì)的照明度拍攝的常規(guī)圖像。
  • 3過(guò)度曝光的圖像:此圖片比正確的曝光圖像亮。目標(biāo)是捕捉非常黑暗的圖像部分。

但是,如果場(chǎng)景的動(dòng)態(tài)范圍非常大,我們可以拍攝三張以上的圖片來(lái)構(gòu)成HDR圖像。在本教程中,我們將使用曝光時(shí)間為1/30,0.25,2.5和15秒拍攝的4張圖像??s略圖如下所示。

[OpenCV實(shí)戰(zhàn)]23 使用OpenCV獲取高動(dòng)態(tài)范圍成像HDR_#include_02

有關(guān)SLR相機(jī)或手機(jī)使用的曝光時(shí)間和其他設(shè)置的信息通常存儲(chǔ)在JPEG文件的EXIF元數(shù)據(jù)中。通過(guò)以下鏈接可學(xué)習(xí)查看存儲(chǔ)在Windows和Mac中的JPEG文件中的EXIF元數(shù)據(jù)。

windows下右鍵圖片-屬性-詳細(xì)信息,有圖像具體信息。如下所示:

[OpenCV實(shí)戰(zhàn)]23 使用OpenCV獲取高動(dòng)態(tài)范圍成像HDR_sed_03

或者,您可以使用我最喜歡的名為EXIFTOOL的EXIF命令行實(shí)用程序。

2 代碼

2.1 運(yùn)行環(huán)境配置

由于本文所用代碼涉及到opencv非免費(fèi)代碼,createTonemapMantiuk這部分算法都是申請(qǐng)專(zhuān)利需要收費(fèi)(本文可以不要這段代碼)。在使用時(shí)編譯opencv和opencv_contrib需要選擇OPENCV_ENABLE_NONFREE

如果是python,直接安裝指定版本opencv就行了:

pip install opencv-contrib-python==3.4.2.17

在使用非免費(fèi)代碼

頭文件和命名空間如下:

#include <opencv2/xphoto.hpp>
using namespace xphoto;

2.2 讀取圖像和曝光時(shí)間

手動(dòng)輸入圖像,曝光時(shí)間以及圖像個(gè)數(shù)。

代碼如下: C++:

/**
 * @brief 讀圖
 *
 * @param images
 * @param times
 */
void readImagesAndTimes(vector<Mat> &images, vector<float> &times)
{
    //圖像個(gè)數(shù)
    int numImages = 3;
    //圖像曝光時(shí)間
    static const float timesArray[] = { 1.0 / 25 ,1.0 / 17, 1.0 / 13 };
    times.assign(timesArray, timesArray + numImages);

    static const char* filenames[] = { "1_25.jpg", "1_17.jpg", "1_13.jpg"};
    //讀取圖像
    for (int i = 0; i < numImages; i++)
    {
        Mat im = imread(filenames[i]);
        images.push_back(im);
    }
}

python:

def readImagesAndTimes():
  # List of exposure times
  times = np.array([ 1/30.0, 0.25, 2.5, 15.0 ], dtype=np.float32)

  # List of image filenames
  filenames = ["img_0.033.jpg", "img_0.25.jpg", "img_2.5.jpg", "img_15.jpg"]
  images = []
  for filename in filenames:
    im = cv2.imread(filename)
    images.append(im)
  return images, times

2.3 圖像對(duì)齊

用于合成HDR圖像的原始圖像未對(duì)準(zhǔn)可能導(dǎo)致嚴(yán)重的偽影。在下圖中,左側(cè)圖像是使用未對(duì)齊圖像組成的HDR圖像,右側(cè)圖像是使用對(duì)齊圖像的圖像。通過(guò)放大圖像的一部分,使用紅色圓圈顯示,我們?cè)谧髨D像中看到嚴(yán)重的重影瑕疵。

[OpenCV實(shí)戰(zhàn)]23 使用OpenCV獲取高動(dòng)態(tài)范圍成像HDR_sed_04

當(dāng)然,在拍攝用于創(chuàng)建HDR圖像的照片時(shí),專(zhuān)業(yè)攝影師將相機(jī)安裝在三腳架上。他們還使用一種稱(chēng)為反光鏡鎖死的功能來(lái)減少額外的振動(dòng)。即使這樣,圖像也可能無(wú)法完美對(duì)齊,因?yàn)闊o(wú)法保證無(wú)振動(dòng)的環(huán)境。使用手持相機(jī)或手機(jī)拍攝圖像時(shí),對(duì)齊問(wèn)題會(huì)變得更糟。

幸運(yùn)的是,OpenCV 提供了一種簡(jiǎn)單的方法,使用AlignMTB對(duì)齊這些圖像。該算法將所有圖像轉(zhuǎn)換為中值閾值位圖median threshold bitmaps(MTB)。圖像的MTB生成方式為將比中值亮度亮的點(diǎn)分配為1,其余為0。MTB不隨曝光時(shí)間的改變而改變。因此不需要我們指定曝光時(shí)間就可以對(duì)齊MTB。

代碼如下:

C++:

// Align input images
Ptr&lt;AlignMTB&gt; alignMTB = createAlignMTB();
alignMTB-&gt;process(images, images);

python:

# Align input images
alignMTB = cv2.createAlignMTB()
alignMTB.process(images, images)

2.4 恢復(fù)相機(jī)響應(yīng)功能

典型相機(jī)的響應(yīng)與場(chǎng)景亮度不是線(xiàn)性的。那是什么意思?假設(shè),一個(gè)攝像機(jī)拍攝了兩個(gè)物體,其中一個(gè)物體的亮度是現(xiàn)實(shí)世界中的兩倍。當(dāng)您測(cè)量照片中兩個(gè)對(duì)象的像素強(qiáng)度時(shí),較亮對(duì)象的像素值將不會(huì)是較暗對(duì)象的兩倍。在不估計(jì)相機(jī)響應(yīng)函數(shù)(CRF)的情況下,我們將無(wú)法將圖像合并為一個(gè)HDR圖像。將多個(gè)曝光圖像合并為HDR圖像意味著什么?

在圖像的某個(gè)位置(x,y)僅考慮一個(gè)像素。如果CRF是線(xiàn)性的,則像素值將與曝光時(shí)間成正比,除非像素在特定圖像中太暗(即接近0)或太亮(即接近255)。我們可以過(guò)濾出這些不好的像素(太暗或太亮),并且將像素值除以曝光時(shí)間來(lái)估計(jì)像素的亮度,然后在像素不差的所有圖像(太暗或太亮)上對(duì)亮度值取平均。我們可以對(duì)所有像素進(jìn)行這樣的處理,并通過(guò)對(duì)“好”像素進(jìn)行平均來(lái)獲得所有像素的單張圖像。但是CRF不是線(xiàn)性的,我們需要在評(píng)估CRF前把圖像強(qiáng)度變成線(xiàn)性。

好消息是,如果我們知道每張圖像的曝光時(shí)間,可以從圖像中估算CRF。與計(jì)算機(jī)視覺(jué)中的許多問(wèn)題一樣,找到CRF的問(wèn)題被設(shè)置為優(yōu)化問(wèn)題,其中目標(biāo)是最小化由數(shù)據(jù)項(xiàng)和平滑項(xiàng)組成的目標(biāo)函數(shù)。這些問(wèn)題通常會(huì)減少到使用奇異值分解(SVD)求解的線(xiàn)性最小二乘問(wèn)題,而奇異值分解是所有線(xiàn)性代數(shù)包的一部分。CRF恢復(fù)算法細(xì)節(jié)見(jiàn)論文Recovering High Dynamic Range Radiance Maps from Photographs。

使用CalibrateDebevec或在OpenCV中僅使用兩行代碼來(lái)查找CRF CalibrateRobertson。在本教程中我們將使用CalibrateDebevec。

代碼如下:

C++:

// Obtain Camera Response Function (CRF)
Mat responseDebevec;
Ptr&lt;CalibrateDebevec&gt; calibrateDebevec = createCalibrateDebevec();
calibrateDebevec-&gt;process(images, responseDebevec, times);

python:

# Obtain Camera Response Function (CRF)
calibrateDebevec = cv2.createCalibrateDebevec()
responseDebevec = calibrateDebevec.process(images, times)

下圖顯示了使用紅色,綠色和藍(lán)色通道圖像恢復(fù)的CRF。

[OpenCV實(shí)戰(zhàn)]23 使用OpenCV獲取高動(dòng)態(tài)范圍成像HDR_python_05

2.5 合并圖像

一旦估計(jì)了CRF,我們就可以將曝光圖像合并為一個(gè)HDR圖像MergeDebevec。C ++和Python代碼如下所示。

C++:

// Merge images into an HDR linear image
Mat hdrDebevec;
Ptr&lt;MergeDebevec&gt; mergeDebevec = createMergeDebevec();
mergeDebevec-&gt;process(images, hdrDebevec, times, responseDebevec);
// Save HDR image.
imwrite("hdrDebevec.hdr", hdrDebevec);

Python:

# Merge images into an HDR linear image
mergeDebevec = cv2.createMergeDebevec()
hdrDebevec = mergeDebevec.process(images, times, responseDebevec)
# Save HDR image.
cv2.imwrite("hdrDebevec.hdr", hdrDebevec)

上面保存的HDR圖像可以在Photoshop中加載并進(jìn)行色調(diào)映射。一個(gè)例子如下所示。

[OpenCV實(shí)戰(zhàn)]23 使用OpenCV獲取高動(dòng)態(tài)范圍成像HDR_python_06

2.6 色調(diào)映射

現(xiàn)在我們將曝光圖像合并為一個(gè)HDR圖像。你能猜出這張圖片的最小和最大像素值嗎?對(duì)于漆黑條件,最小值顯然為0。什么是理論最大值?無(wú)窮!實(shí)際上,不同情況下的最大值是不同的。如果場(chǎng)景包含非常明亮的光源,我們將看到非常大的最大值。盡管我們已經(jīng)使用多個(gè)圖像恢復(fù)了相對(duì)亮度信息,但我們現(xiàn)在面臨的挑戰(zhàn)是將此信息保存為24位圖像以用于顯示。

色調(diào)映射:將高動(dòng)態(tài)范圍(HDR)圖像轉(zhuǎn)換為每通道8位圖像同時(shí)保留盡可能多的細(xì)節(jié)的過(guò)程稱(chēng)為色調(diào)映射。

有幾種色調(diào)映射算法。OpenCV實(shí)現(xiàn)了其中的四個(gè)。要記住的是,沒(méi)有正確的方法來(lái)進(jìn)行色調(diào)映射。通常,我們希望在色調(diào)映射圖像中看到比在任何一個(gè)曝光圖像中更多的細(xì)節(jié)。有時(shí),色調(diào)映射的目標(biāo)是產(chǎn)生逼真的圖像,并且通常目標(biāo)是產(chǎn)生超現(xiàn)實(shí)的圖像。在OpenCV中實(shí)現(xiàn)的算法傾向于產(chǎn)生逼真的,因此不那么引人注目的結(jié)果。

我們來(lái)看看各種選項(xiàng)。下面列出了不同色調(diào)映射算法的一些常見(jiàn)參數(shù)。

  • 1)伽馬gamma:此參數(shù)通過(guò)應(yīng)用伽馬校正來(lái)壓縮動(dòng)態(tài)范圍。當(dāng)gamma等于1時(shí),不應(yīng)用校正。小于1的灰度會(huì)使圖像變暗,而大于1的灰度會(huì)使圖像變亮。
  • 2)飽和度saturation:此參數(shù)用于增加或減少飽和度。當(dāng)飽和度高時(shí),顏色更豐富,更強(qiáng)烈。飽和度值接近零,使顏色漸漸變?yōu)榛叶取?/li>
  • 3)對(duì)比度contrast:控制輸出圖像的對(duì)比度(即log(maxPixelValue / minPixelValue))。

讓我們來(lái)探索OpenCV中可用的四種色調(diào)映射算法

  • Drago Tonemap

Drago Tonemap的參數(shù)如下所示:

createTonemapDrago
(
float   gamma = 1.0f,
float   saturation = 1.0f,
float   bias = 0.85f
)

這里,bias是[0,1]范圍內(nèi)偏置函數(shù)的值。從0.7到0.9的值通常會(huì)得到最好的結(jié)果。默認(rèn)值為0.85。有關(guān)更多技術(shù)細(xì)節(jié),請(qǐng)參閱此文章。參數(shù)通過(guò)反復(fù)試驗(yàn)獲得。最終輸出乘以3只是因?yàn)樗o出了最令人滿(mǎn)意的結(jié)果。更多的技術(shù)細(xì)節(jié)見(jiàn):

結(jié)果如下所示:

[OpenCV實(shí)戰(zhàn)]23 使用OpenCV獲取高動(dòng)態(tài)范圍成像HDR_python_07

  • Durand Tonemap

Durand Tonemap的參數(shù)如下所示:

createTonemapDurand
(
  float     gamma = 1.0f,
  float     contrast = 4.0f,
  float     saturation = 1.0f,
  float     sigma_space = 2.0f,
  float     sigma_color = 2.0f
);

該算法基于將圖像分解為基礎(chǔ)層和細(xì)節(jié)層。使用稱(chēng)為雙邊濾波器的邊緣保留濾波器獲得基礎(chǔ)層。sigma_space和sigma_color是雙邊濾波器的參數(shù),分別控制空間域和顏色域中的平滑量。更多的技術(shù)細(xì)節(jié)見(jiàn):

結(jié)果如下所示:

[OpenCV實(shí)戰(zhàn)]23 使用OpenCV獲取高動(dòng)態(tài)范圍成像HDR_#include_08

  • Reinhard Tonemap

Reinhard Tonemap的參數(shù)如下所示:

createTonemapReinhard
(
float   gamma = 1.0f,
float   intensity = 0.0f,
float   light_adapt = 1.0f,
float   color_adapt = 0.0f
)

參數(shù)intensity應(yīng)在[-8,8]范圍內(nèi)。強(qiáng)度值越大,結(jié)果越明亮。參數(shù)light_adapt控制燈光適應(yīng)并且在[0,1]范圍內(nèi)。值1表示僅基于像素值的自適應(yīng),值0表示全局自適應(yīng)。中間值可以用于兩者的加權(quán)組合。參數(shù)color_adapt控制色度適應(yīng)并且在[0,1]范圍內(nèi)。如果值設(shè)置為1,則獨(dú)立處理通道,如果值設(shè)置為0,則每個(gè)通道的適應(yīng)級(jí)別相同。中間值可用于兩者的加權(quán)組合。更多的技術(shù)細(xì)節(jié)見(jiàn):

結(jié)果如下所示:

[OpenCV實(shí)戰(zhàn)]23 使用OpenCV獲取高動(dòng)態(tài)范圍成像HDR_sed_09

  • Mantiuk Tonemap

Mantiuk Tonemap的參數(shù)如下所示:

createTonemapMantiuk
(
float   gamma = 1.0f,
float   scale = 0.7f,
float   saturation = 1.0f
)

scale是對(duì)比度比例因子。從0.6到0.9的值產(chǎn)生最佳結(jié)果。更多的技術(shù)細(xì)節(jié)見(jiàn):

結(jié)果如下所示:

[OpenCV實(shí)戰(zhàn)]23 使用OpenCV獲取高動(dòng)態(tài)范圍成像HDR_#include_10

上面所有色調(diào)映射代碼見(jiàn):

C++:

    // Tonemap using Drago's method to obtain 24-bit color image 色調(diào)映射算法
    cout &lt;&lt; "Tonemaping using Drago's method ... ";
    Mat ldrDrago;
    Ptr&lt;TonemapDrago&gt; tonemapDrago = createTonemapDrago(1.0, 0.7);
    tonemapDrago-&gt;process(hdrDebevec, ldrDrago);
    ldrDrago = 3 * ldrDrago;
    imwrite("ldr-Drago.jpg", ldrDrago * 255);
    cout &lt;&lt; "saved ldr-Drago.jpg" &lt;&lt; endl;

    // Tonemap using Durand's method obtain 24-bit color image 色調(diào)映射算法
    cout &lt;&lt; "Tonemaping using Durand's method ... ";
    Mat ldrDurand;
    Ptr&lt;TonemapDurand&gt; tonemapDurand = createTonemapDurand(1.5, 4, 1.0, 1, 1);
    tonemapDurand-&gt;process(hdrDebevec, ldrDurand);
    ldrDurand = 3 * ldrDurand;
    imwrite("ldr-Durand.jpg", ldrDurand * 255);
    cout &lt;&lt; "saved ldr-Durand.jpg" &lt;&lt; endl;

    // Tonemap using Reinhard's method to obtain 24-bit color image 色調(diào)映射算法
    cout &lt;&lt; "Tonemaping using Reinhard's method ... ";
    Mat ldrReinhard;
    Ptr&lt;TonemapReinhard&gt; tonemapReinhard = createTonemapReinhard(1.5, 0, 0, 0);
    tonemapReinhard-&gt;process(hdrDebevec, ldrReinhard);
    imwrite("ldr-Reinhard.jpg", ldrReinhard * 255);
    cout &lt;&lt; "saved ldr-Reinhard.jpg" &lt;&lt; endl;

    // Tonemap using Mantiuk's method to obtain 24-bit color image 色調(diào)映射算法
    cout &lt;&lt; "Tonemaping using Mantiuk's method ... ";
    Mat ldrMantiuk;
    Ptr&lt;TonemapMantiuk&gt; tonemapMantiuk = createTonemapMantiuk(2.2, 0.85, 1.2);
    tonemapMantiuk-&gt;process(hdrDebevec, ldrMantiuk);
    ldrMantiuk = 3 * ldrMantiuk;
    imwrite("ldr-Mantiuk.jpg", ldrMantiuk * 255);
    cout &lt;&lt; "saved ldr-Mantiuk.jpg" &lt;&lt; endl;

Python:

  # Tonemap using Drago's method to obtain 24-bit color image
  print("Tonemaping using Drago's method ... ")
  tonemapDrago = cv2.createTonemapDrago(1.0, 0.7)
  ldrDrago = tonemapDrago.process(hdrDebevec)
  ldrDrago = 3 * ldrDrago
  cv2.imwrite("ldr-Drago.jpg", ldrDrago * 255)
  print("saved ldr-Drago.jpg")

  # Tonemap using Durand's method obtain 24-bit color image
  print("Tonemaping using Durand's method ... ")
  tonemapDurand = cv2.createTonemapDurand(1.5,4,1.0,1,1)
  ldrDurand = tonemapDurand.process(hdrDebevec)
  ldrDurand = 3 * ldrDurand
  cv2.imwrite("ldr-Durand.jpg", ldrDurand * 255)
  print("saved ldr-Durand.jpg")

  # Tonemap using Reinhard's method to obtain 24-bit color image
  print("Tonemaping using Reinhard's method ... ")
  tonemapReinhard = cv2.createTonemapReinhard(1.5, 0,0,0)
  ldrReinhard = tonemapReinhard.process(hdrDebevec)
  cv2.imwrite("ldr-Reinhard.jpg", ldrReinhard * 255)
  print("saved ldr-Reinhard.jpg")

  # Tonemap using Mantiuk's method to obtain 24-bit color image
  print("Tonemaping using Mantiuk's method ... ")
  tonemapMantiuk = cv2.createTonemapMantiuk(2.2,0.85, 1.2)
  ldrMantiuk = tonemapMantiuk.process(hdrDebevec)
  ldrMantiuk = 3 * ldrMantiuk
  cv2.imwrite("ldr-Mantiuk.jpg", ldrMantiuk * 255)
  print("saved ldr-Mantiuk.jpg")

2.7 工程代碼

本文所有代碼見(jiàn):

C++:

#include "pch.h"
#include <opencv2/opencv.hpp>
#include <opencv2/xphoto.hpp>
#include <vector>
#include <iostream>
#include <fstream>
using namespace cv;
using namespace std;
using namespace xphoto;
/**
 * @brief 讀圖
 *
 * @param images
 * @param times
 */
void readImagesAndTimes(vector<Mat> &images, vector<float> &times)
{
    //圖像個(gè)數(shù)
    int numImages = 3;
    //圖像曝光時(shí)間
    static const float timesArray[] = { 1.0 / 25 ,1.0 / 17, 1.0 / 13 };
    times.assign(timesArray, timesArray + numImages);
    static const char* filenames[] = { "1_25.jpg", "1_17.jpg", "1_13.jpg"};
    //讀取圖像
    for (int i = 0; i < numImages; i++)
    {
        Mat im = imread(filenames[i]);
        images.push_back(im);
    }
}
int main()
{
    // Read images and exposure times 讀取圖像和圖像曝光時(shí)間
    cout << "Reading images ... " << endl;
    //圖像
    vector<Mat> images;
    //曝光時(shí)間
    vector<float> times;
    //讀取圖像和圖像曝光時(shí)間
    readImagesAndTimes(images, times);
    // Align input images 圖像對(duì)齊
    cout << "Aligning images ... " << endl;
    Ptr<AlignMTB> alignMTB = createAlignMTB();
    alignMTB->process(images, images);

    // Obtain Camera Response Function (CRF) 獲得CRF
    cout << "Calculating Camera Response Function (CRF) ... " << endl;
    Mat responseDebevec;
    Ptr<CalibrateDebevec> calibrateDebevec = createCalibrateDebevec();
    calibrateDebevec->process(images, responseDebevec, times);

    // Merge images into an HDR linear image 圖像合并為HDR圖像
    cout << "Merging images into one HDR image ... ";
    Mat hdrDebevec;
    Ptr<MergeDebevec> mergeDebevec = createMergeDebevec();
    mergeDebevec->process(images, hdrDebevec, times, responseDebevec);
    // Save HDR image. 保存HDR圖像
    imwrite("hdrDebevec.hdr", hdrDebevec);
    cout << "saved hdrDebevec.hdr " << endl;

    // Tonemap using Drago's method to obtain 24-bit color image 色調(diào)映射算法
    cout << "Tonemaping using Drago's method ... ";
    Mat ldrDrago;
    Ptr<TonemapDrago> tonemapDrago = createTonemapDrago(1.0, 0.7);
    tonemapDrago->process(hdrDebevec, ldrDrago);
    ldrDrago = 3 * ldrDrago;
    imwrite("ldr-Drago.jpg", ldrDrago * 255);
    cout << "saved ldr-Drago.jpg" << endl;

    // Tonemap using Durand's method obtain 24-bit color image 色調(diào)映射算法
    cout << "Tonemaping using Durand's method ... ";
    Mat ldrDurand;
    Ptr<TonemapDurand> tonemapDurand = createTonemapDurand(1.5, 4, 1.0, 1, 1);
    tonemapDurand->process(hdrDebevec, ldrDurand);
    ldrDurand = 3 * ldrDurand;
    imwrite("ldr-Durand.jpg", ldrDurand * 255);
    cout << "saved ldr-Durand.jpg" << endl;
    // Tonemap using Reinhard's method to obtain 24-bit color image 色調(diào)映射算法
    cout << "Tonemaping using Reinhard's method ... ";
    Mat ldrReinhard;
    Ptr<TonemapReinhard> tonemapReinhard = createTonemapReinhard(1.5, 0, 0, 0);
    tonemapReinhard->process(hdrDebevec, ldrReinhard);
    imwrite("ldr-Reinhard.jpg", ldrReinhard * 255);
    cout << "saved ldr-Reinhard.jpg" << endl;
    // Tonemap using Mantiuk's method to obtain 24-bit color image 色調(diào)映射算法
    cout << "Tonemaping using Mantiuk's method ... ";
    Mat ldrMantiuk;
    Ptr<TonemapMantiuk> tonemapMantiuk = createTonemapMantiuk(2.2, 0.85, 1.2);
    tonemapMantiuk->process(hdrDebevec, ldrMantiuk);
    ldrMantiuk = 3 * ldrMantiuk;
    imwrite("ldr-Mantiuk.jpg", ldrMantiuk * 255);
    cout << "saved ldr-Mantiuk.jpg" << endl;
    return 0;
}

Python:

import cv2
import numpy as np
def readImagesAndTimes():
  times = np.array([ 1/30.0, 0.25, 2.5, 15.0 ], dtype=np.float32)
  filenames = ["img_0.033.jpg", "img_0.25.jpg", "img_2.5.jpg", "img_15.jpg"]
  images = []
  for filename in filenames:
    im = cv2.imread(filename)
    images.append(im)
  return images, times
if __name__ == '__main__':
  # Read images and exposure times
  print("Reading images ... ")
  images, times = readImagesAndTimes()
  # Align input images
  print("Aligning images ... ")
  alignMTB = cv2.createAlignMTB()
  alignMTB.process(images, images)
  # Obtain Camera Response Function (CRF)
  print("Calculating Camera Response Function (CRF) ... ")
  calibrateDebevec = cv2.createCalibrateDebevec()
  responseDebevec = calibrateDebevec.process(images, times)
  # Merge images into an HDR linear image
  print("Merging images into one HDR image ... ")
  mergeDebevec = cv2.createMergeDebevec()
  hdrDebevec = mergeDebevec.process(images, times, responseDebevec)
  # Save HDR image.
  cv2.imwrite("hdrDebevec.hdr", hdrDebevec)
  print("saved hdrDebevec.hdr ")
  # Tonemap using Drago's method to obtain 24-bit color image
  print("Tonemaping using Drago's method ... ")
  tonemapDrago = cv2.createTonemapDrago(1.0, 0.7)
  ldrDrago = tonemapDrago.process(hdrDebevec)
  ldrDrago = 3 * ldrDrago
  cv2.imwrite("ldr-Drago.jpg", ldrDrago * 255)
  print("saved ldr-Drago.jpg")
  # Tonemap using Durand's method obtain 24-bit color image
  print("Tonemaping using Durand's method ... ")
  tonemapDurand = cv2.createTonemapDurand(1.5,4,1.0,1,1)
  ldrDurand = tonemapDurand.process(hdrDebevec)
  ldrDurand = 3 * ldrDurand
  cv2.imwrite("ldr-Durand.jpg", ldrDurand * 255)
  print("saved ldr-Durand.jpg")
  # Tonemap using Reinhard's method to obtain 24-bit color image
  print("Tonemaping using Reinhard's method ... ")
  tonemapReinhard = cv2.createTonemapReinhard(1.5, 0,0,0)
  ldrReinhard = tonemapReinhard.process(hdrDebevec)
  cv2.imwrite("ldr-Reinhard.jpg", ldrReinhard * 255)
  print("saved ldr-Reinhard.jpg")
  # Tonemap using Mantiuk's method to obtain 24-bit color image
  print("Tonemaping using Mantiuk's method ... ")
  tonemapMantiuk = cv2.createTonemapMantiuk(2.2,0.85, 1.2)
  ldrMantiuk = tonemapMantiuk.process(hdrDebevec)
  ldrMantiuk = 3 * ldrMantiuk
  cv2.imwrite("ldr-Mantiuk.jpg", ldrMantiuk * 255)
  print("saved ldr-Mantiuk.jpg")

到此這篇關(guān)于python使用OpenCV獲取高動(dòng)態(tài)范圍成像HDR的文章就介紹到這了,更多相關(guān)OpenCV獲取HDR內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論