畢設—高動態範圍圖像渲染算法之基於雙邊濾波的色調映射技術(五)

在項目中,本人直接使用了Open CV提供的雙邊濾波器,對原理不是很理解,只知道他可以保持邊緣、起到平滑的作用。

本人蔘考的論文名字《Fast Bilateral Filtering for the Display of High-Dynamic-Range Images》,核心思路就是:把原圖分解成基本層和細節層,然後增強基本層數據,保留細節層數據,最後融合基本層和細節層。過程如下圖:
在這裏插入圖片描述細分可分爲以下步驟(參考博客):僞代碼

//1、色彩空間轉化,轉換成亮度值圖像
input intensity= 1/61*(R*20+G*40+B);

//2、雙邊濾波得到基本層數據
log(base)=Bilateral(log(input intensity));

//3、計算得到細節層數據
log(detail)=log(input intensity)-log(base);

//4、計算增強因子,增強基本層圖像,並融合
targetContrast=log(5);
compressionfactor = targetContrast/(max(log(base)) - min(log(base))) ;
log_absolute_scale= max(log(base))*compressionfactor;
log (output intensity)=log(base)*compressionfactor+log(detail) - log_absolute_scale;

//5、還原色彩空間
r=R/(input intensity), g=G/input intensity, B=B/input intensity;
R output = r*10^(log(output intensity)), etc.

/*
注意:在進行雙邊的時候,SigmaS一般取值爲0.02*Max(Width,Height),而SigmaR取值0.4(這裏是指數據量化到了0-1之間的)。 
*/

本項目完成這個算法共分爲五步:
1、色彩空間轉化,轉化亮度值圖像(灰度值圖像)

//定義矩陣
Mat tmp_in_image(rows,cols,CV_32FC1);
for(int i = 0; i < rows; i++){
	for(int j = 0; j < cols; j++){
		//色彩空間轉化
		tmp_in_image.at<float>(i,j) = (20*RGB[0] + 40*RGB[1] + RGB[2])/61+a;
		//最值計算,方便後面進行歸一化,因爲前面也提到了,雙邊濾波參數設置時,數據需要量化到0-1之間
		if(tmp_in_image.at<float>(i,j)>Lmax)Lmax=tmp_in_image.at<float>(i,j);
		if(tmp_in_image.at<float>(i,j)<Lmin)Lmin=tmp_in_image.at<float>(i,j);
	}
}

2、歸一化處理並進行伽馬校正(因爲該算法主要是增加對比度,所以我使用伽馬校正來增加圖像亮度)

for(int i = 0; i < rows; i++){
	for(int j = 0; j < cols; j++){

		//歸一化處理
		tmp_in_image.at<float>(i,j)=(log(tmp_in_image.at<float>(i,j)+a)-log(Lmin+a))/(log(Lmax+a)-log(Lmin+a));

		//伽馬校正
		tmp_in_image.at<float>(i,j)=pow(1.0*tmp_in_image.at<float>(i,j),r);
			
	}
}

3、進行雙邊濾波,並計算最值(計算最值方便後面計算增強因子)

//雙邊濾波
bilateralFilter(tmp_in_image,tmp_out_image,5,0.02*max(rows,cols),0.4);

double min_base=INF,max_base=-INF;

for(int i = 0; i < rows; i++){
	for(int j = 0; j < cols; j++){
		if(min_base>tmp_out_image.at<float>(i,j))min_base=tmp_out_image.at<float>(i,j);
		if(max_base<tmp_out_image.at<float>(i,j))max_base=tmp_out_image.at<float>(i,j);
	}
}

4、獲得細節層數據,並增強基本層

double compressionfactor = log(5.0)/(max_base - min_base);

for(int i = 0; i < rows; i++){
	for(int j = 0; j < cols; j++){
		
		//算法核心
		double log_absolute_scale = max_base*compressionfactor;
			
		//計算細節層
		double log_detail = tmp_in_image.at<float>(i,j) - tmp_out_image.at<float>(i,j);

		//增強基本層,保留細節層,並融合
		double log_output_intensity = tmp_out_image.at<float>(i,j) * compressionfactor + log_detail - log_absolute_scale;
		
	}
}

5、還原色彩空間

//還原色彩空間
double tem=pow(10,log_output_intensity);

RGB[0] = RGB[0]*tem/input_Intensity;
RGB[1] = RGB[1]*tem/input_Intensity;
RGB[2] = RGB[2]*tem/input_Intensity;

out_image.at<Vec3b>(i, j)[0] = saturate_cast<uchar>(RGB[2]*255);
out_image.at<Vec3b>(i, j)[1] = saturate_cast<uchar>(RGB[1]*255);
out_image.at<Vec3b>(i, j)[2] = saturate_cast<uchar>(RGB[0]*255);

效果演示:
在這裏插入圖片描述在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章