最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

1 背景

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

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

然而,我們周圍的世界顏色有一個非常大的變化范圍。當(dāng)燈關(guān)閉時,車庫會變黑;太陽照射下,車庫看起來變得非常明亮。即使不考慮這些極端情況,在日常情況下,8位也幾乎不足以捕捉場景。因此,相機會嘗試估計光線并自動設(shè)置曝光,以使圖像中最有用的部分具有良好的動態(tài)顏色范圍,而太暗和太亮的部分分別被設(shè)置為0和255。

在下圖中,左側(cè)的圖像是正常曝光的圖像。請注意,背景中的天空已完全消失,因為相機決定使用一個能夠讓小孩被正確拍攝而明亮的天空被忽略的設(shè)置。右側(cè)圖像是iPhone生成的HDR圖像。

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

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

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

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

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

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

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

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

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

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

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

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

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

2 代碼

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

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

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

pip install opencv-contrib-python==3.4.2.17

在使用非免費代碼

頭文件和命名空間如下:

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

2.2 讀取圖像和曝光時間

手動輸入圖像,曝光時間以及圖像個數(shù)。

代碼如下: C++:

/**
 * @brief 讀圖
 *
 * @param images
 * @param times
 */
void readImagesAndTimes(vector<Mat> &images, vector<float> &times)
{
    //圖像個數(shù)
    int numImages = 3;
    //圖像曝光時間
    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 圖像對齊

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

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

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

幸運的是,OpenCV 提供了一種簡單的方法,使用AlignMTB對齊這些圖像。該算法將所有圖像轉(zhuǎn)換為中值閾值位圖median threshold bitmaps(MTB)。圖像的MTB生成方式為將比中值亮度亮的點分配為1,其余為0。MTB不隨曝光時間的改變而改變。因此不需要我們指定曝光時間就可以對齊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ù)相機響應(yīng)功能

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

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

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

使用CalibrateDebevec或在OpenCV中僅使用兩行代碼來查找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)

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

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

2.5 合并圖像

一旦估計了CRF,我們就可以將曝光圖像合并為一個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中加載并進行色調(diào)映射。一個例子如下所示。

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

2.6 色調(diào)映射

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

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

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

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

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

讓我們來探索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的值通常會得到最好的結(jié)果。默認(rèn)值為0.85。有關(guān)更多技術(shù)細(xì)節(jié),請參閱此文章。參數(shù)通過反復(fù)試驗獲得。最終輸出乘以3只是因為它給出了最令人滿意的結(jié)果。更多的技術(shù)細(xì)節(jié)見:

結(jié)果如下所示:

[OpenCV實戰(zhàn)]23 使用OpenCV獲取高動態(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ǔ)層。sigma_space和sigma_color是雙邊濾波器的參數(shù),分別控制空間域和顏色域中的平滑量。更多的技術(shù)細(xì)節(jié)見:

結(jié)果如下所示:

[OpenCV實戰(zhàn)]23 使用OpenCV獲取高動態(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)。強度值越大,結(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,則獨立處理通道,如果值設(shè)置為0,則每個通道的適應(yīng)級別相同。中間值可用于兩者的加權(quán)組合。更多的技術(shù)細(xì)節(jié)見:

結(jié)果如下所示:

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

  • Mantiuk Tonemap

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

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

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

結(jié)果如下所示:

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

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

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 工程代碼

本文所有代碼見:

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)
{
    //圖像個數(shù)
    int numImages = 3;
    //圖像曝光時間
    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 讀取圖像和圖像曝光時間
    cout << "Reading images ... " << endl;
    //圖像
    vector<Mat> images;
    //曝光時間
    vector<float> times;
    //讀取圖像和圖像曝光時間
    readImagesAndTimes(images, times);
    // Align input images 圖像對齊
    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獲取高動態(tài)范圍成像HDR的文章就介紹到這了,更多相關(guān)OpenCV獲取HDR內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python3實現(xiàn)的Mysql數(shù)據(jù)庫操作封裝類

    Python3實現(xiàn)的Mysql數(shù)據(jù)庫操作封裝類

    這篇文章主要介紹了Python3實現(xiàn)的Mysql數(shù)據(jù)庫操作封裝類,涉及Python針對mysql數(shù)據(jù)庫的連接、查詢、更新及關(guān)閉連接等相關(guān)操作技巧,需要的朋友可以參考下
    2018-06-06
  • Python 自動化處理Excel和Word實現(xiàn)自動辦公

    Python 自動化處理Excel和Word實現(xiàn)自動辦公

    毫無疑問,Microsoft Excel 和 Word 是我們?nèi)粘^k公中使用最廣泛的辦公軟件。將反復(fù)、復(fù)雜的工作自動化處理,是我們需要思考的問題,本篇文章幫你解決這個問題
    2021-11-11
  • Python反射機制實例講解

    Python反射機制實例講解

    本文主要介紹了Python反射機制實例,文中運用了大量的代碼講解Python反射機制,感興趣的小伙伴一定不要錯過這篇文章,可以參考參考
    2021-08-08
  • 基于python寫個國慶假期倒計時程序

    基于python寫個國慶假期倒計時程序

    國慶假期快到了,想查查還有幾天幾小時到假期,這對程序員小菜一碟,輕輕松松用python寫個倒計時程序(天、時、分、秒),助你熬到假期
    2021-09-09
  • Python 將Matrix、Dict保存到文件的方法

    Python 將Matrix、Dict保存到文件的方法

    今天小編就為大家分享一篇Python 將Matrix、Dict保存到文件的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10
  • 不到20行代碼用Python做一個智能聊天機器人

    不到20行代碼用Python做一個智能聊天機器人

    小編先向大家介紹一下本次運用到的python庫,本次項目主要運用到的庫有wxpy和chatterbot。對Python做一個智能聊天機器人的相關(guān)知識感興趣的朋友跟隨小編一起看看吧
    2019-04-04
  • Python與xlwings黃金組合處理Excel各種數(shù)據(jù)和自動化任務(wù)

    Python與xlwings黃金組合處理Excel各種數(shù)據(jù)和自動化任務(wù)

    這篇文章主要為大家介紹了Python與xlwings黃金組合處理Excel各種數(shù)據(jù)和自動化任務(wù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪<BR>
    2023-12-12
  • numpy數(shù)組的重塑和轉(zhuǎn)置實現(xiàn)

    numpy數(shù)組的重塑和轉(zhuǎn)置實現(xiàn)

    本文主要介紹了numpy數(shù)組的重塑和轉(zhuǎn)置實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • centos+nginx+uwsgi+Django實現(xiàn)IP+port訪問服務(wù)器

    centos+nginx+uwsgi+Django實現(xiàn)IP+port訪問服務(wù)器

    這篇文章主要介紹了centos+nginx+uwsgi+Django實現(xiàn)IP+port訪問服務(wù)器,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • python代碼打包超詳細(xì)教程

    python代碼打包超詳細(xì)教程

    在Python開發(fā)的過程中我們經(jīng)常會需要將自己的代碼打包成一個可執(zhí)行文件,方便將代碼分享給其他人使用,下面這篇文章主要給大家介紹了關(guān)于python代碼打包的相關(guān)資料,需要的朋友可以參考下
    2023-06-06

最新評論

溧阳市| 永寿县| 阳江市| 当雄县| 靖州| 多伦县| 准格尔旗| 双峰县| 南川市| 玛沁县| 光山县| 青冈县| 孟村| 宜阳县| 临湘市| 左云县| 迭部县| 古浪县| 建水县| 永定县| 澄城县| 湘西| 柏乡县| 眉山市| 新津县| 宜都市| 大化| 五寨县| 运城市| 朔州市| 昌邑市| 龙口市| 婺源县| 南汇区| 繁峙县| 日土县| 罗江县| 舒城县| 虎林市| 恩施市| 乳山市|