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

C++?OpenCV實(shí)現(xiàn)白平衡之完美反射算法

 更新時(shí)間:2022年05月30日 09:58:30   作者:翟天保Steven  
完美反射算法是白平衡各種算法中較常見的一種,比灰度世界算法更優(yōu)。本文將利用C++和OpenCV實(shí)現(xiàn)白平衡中的完美反射算法,需要的可以參考一下

實(shí)現(xiàn)原理

白平衡的意義在于,對(duì)在特定光源下拍攝時(shí)出現(xiàn)的偏色現(xiàn)象,通過加強(qiáng)對(duì)應(yīng)的補(bǔ)色來進(jìn)行補(bǔ)償,使白色物體能還原為白色。

完美反射算法是白平衡各種算法中較常見的一種,比灰度世界算法更優(yōu)。它假設(shè)圖像世界中最亮的白點(diǎn)是一個(gè)鏡面,能完美反射光照;基于白點(diǎn),將三通道的數(shù)值進(jìn)行適當(dāng)?shù)卣{(diào)整,以達(dá)到白平衡效果;除此之外,還需要統(tǒng)計(jì)最亮的一定區(qū)間的三通道均值,該均值與該通道最大值的差距決定了該通道調(diào)整的力度。

通俗的講,若圖像中綠色分量最大值是255,但是綠色最亮的前百分之10個(gè)點(diǎn)的平均值只有80,說明原圖的綠色分量整體較低,需要對(duì)其加強(qiáng);若最大值只有100,那么加強(qiáng)的系數(shù)就較低,白平衡的效果就不達(dá)預(yù)期。這就是完美反射算法比較依賴圖像中存在白點(diǎn)的原因,白點(diǎn)的三通道灰度值接近【255,255,255】。最下方將用實(shí)際圖像作進(jìn)一步說明,以幫助讀者理解。

完美反射算法的實(shí)現(xiàn)流程如下:   

1.計(jì)算圖像RGB三通道各自的灰度最大值Rmax、Gmax、Bmax。

2.利用三通道數(shù)值和,確定圖像最亮區(qū)間的下限T。

3.計(jì)算圖像三通道數(shù)值和大于T的點(diǎn)的三通道均值Rm、Gm、Bm。

4.計(jì)算三通道的補(bǔ)償系數(shù),即單通道最大值除以單通道亮區(qū)平均值。

功能函數(shù)代碼

// 白平衡-完美反射
cv::Mat WhiteBalcane_PRA(cv::Mat src)
{
	cv::Mat result = src.clone();
	if (src.channels() != 3)
	{
		cout << "The number of image channels is not 3." << endl;
		return result;
	}
 
	// 通道分離
	vector<cv::Mat> Channel;
	cv::split(src, Channel);
 
	// 定義參數(shù)
	int row = src.rows;
	int col = src.cols;
	int RGBSum[766] = { 0 };
	uchar maxR, maxG, maxB;
 
	// 計(jì)算單通道最大值
	for (int i = 0; i < row; ++i)
	{
		uchar *b = Channel[0].ptr<uchar>(i);
		uchar *g = Channel[1].ptr<uchar>(i);
		uchar *r = Channel[2].ptr<uchar>(i);
		for (int j = 0; j < col; ++j)
		{
			int sum = b[j] + g[j] + r[j];
			RGBSum[sum]++;
			maxB = max(maxB, b[j]);
			maxG = max(maxG, g[j]);
			maxR = max(maxR, r[j]);
		}
	}
 
	// 計(jì)算最亮區(qū)間下限T
	int T = 0;
	int num = 0;
	int K = static_cast<int>(row * col * 0.1);
	for (int i = 765; i >= 0; --i)
	{
		num += RGBSum[i];
		if (num > K)
		{
			T = i;
			break;
		}
	}
	
	// 計(jì)算單通道亮區(qū)平均值
	double Bm = 0.0, Gm = 0.0, Rm = 0.0;
	int count = 0;
	for (int i = 0; i < row; ++i)
	{
		uchar *b = Channel[0].ptr<uchar>(i);
		uchar *g = Channel[1].ptr<uchar>(i);
		uchar *r = Channel[2].ptr<uchar>(i);
		for (int j = 0; j < col; ++j)
		{
			int sum = b[j] + g[j] + r[j];
			if (sum > T)
			{
				Bm += b[j];
				Gm += g[j];
				Rm += r[j];
				count++;
			}
 
		}
	}
	Bm /= count;
	Gm /= count;
	Rm /= count;
 
	// 通道調(diào)整
	Channel[0] *= maxB / Bm;
	Channel[1] *= maxG / Gm;
	Channel[2] *= maxR / Rm;
 
	// 合并通道
	cv::merge(Channel, result);
 
	return result;
}

C++測(cè)試代碼

#include <iostream>
#include <opencv.hpp>
 
using namespace std;
 
// 白平衡-完美反射
cv::Mat WhiteBalcane_PRA(cv::Mat src)
{
	cv::Mat result = src.clone();
	if (src.channels() != 3)
	{
		cout << "The number of image channels is not 3." << endl;
		return result;
	}
 
	// 通道分離
	vector<cv::Mat> Channel;
	cv::split(src, Channel);
 
	// 定義參數(shù)
	int row = src.rows;
	int col = src.cols;
	int RGBSum[766] = { 0 };
	uchar maxR, maxG, maxB;
 
	// 計(jì)算單通道最大值
	for (int i = 0; i < row; ++i)
	{
		uchar *b = Channel[0].ptr<uchar>(i);
		uchar *g = Channel[1].ptr<uchar>(i);
		uchar *r = Channel[2].ptr<uchar>(i);
		for (int j = 0; j < col; ++j)
		{
			int sum = b[j] + g[j] + r[j];
			RGBSum[sum]++;
			maxB = max(maxB, b[j]);
			maxG = max(maxG, g[j]);
			maxR = max(maxR, r[j]);
		}
	}
 
	// 計(jì)算最亮區(qū)間下限T
	int T = 0;
	int num = 0;
	int K = static_cast<int>(row * col * 0.1);
	for (int i = 765; i >= 0; --i)
	{
		num += RGBSum[i];
		if (num > K)
		{
			T = i;
			break;
		}
	}
	
	// 計(jì)算單通道亮區(qū)平均值
	double Bm = 0.0, Gm = 0.0, Rm = 0.0;
	int count = 0;
	for (int i = 0; i < row; ++i)
	{
		uchar *b = Channel[0].ptr<uchar>(i);
		uchar *g = Channel[1].ptr<uchar>(i);
		uchar *r = Channel[2].ptr<uchar>(i);
		for (int j = 0; j < col; ++j)
		{
			int sum = b[j] + g[j] + r[j];
			if (sum > T)
			{
				Bm += b[j];
				Gm += g[j];
				Rm += r[j];
				count++;
			}
 
		}
	}
	Bm /= count;
	Gm /= count;
	Rm /= count;
 
	// 通道調(diào)整
	Channel[0] *= maxB / Bm;
	Channel[1] *= maxG / Gm;
	Channel[2] *= maxR / Rm;
 
	// 合并通道
	cv::merge(Channel, result);
 
	return result;
}
 
int main()
{
	// 載入原圖
	cv::Mat src = cv::imread("test21.jpg");
 
	// 白平衡-完美反射
	cv::Mat result = WhiteBalcane_PRA(src);
 
	// 顯示
	cv::imshow("src", src);
	cv::imshow("result", result);
	cv::waitKey(0);
 
	return 0;
}

測(cè)試效果

圖1 原圖

圖2 白平衡后圖像

如圖1所示,是傍晚的一張圖像,眾所周知,傍晚的色溫是較低的,此時(shí)采用高于傍晚色溫的色溫值拍照,就會(huì)得到一張暖色系的圖片,偏黃;對(duì)其進(jìn)行白平衡,使圖片顏色回歸真實(shí)的環(huán)境色溫,就得到如圖2的效果。

如果你用過灰度世界算法,你會(huì)發(fā)現(xiàn)完美反射算法的效果更亮些;這是因?yàn)樗{(lán)通道最大值和藍(lán)通道亮區(qū)平均值的差距較大,因而補(bǔ)償?shù)膹?qiáng)度很強(qiáng);若原圖中不存在白色區(qū),那藍(lán)通道的補(bǔ)償就會(huì)較弱,達(dá)不到較好的預(yù)期,因此該算法所處理的圖像中最好有較白的點(diǎn)。

圖3 單色原圖

圖4 單色圖白平衡效果

如圖3所示,是一張色彩相對(duì)一致的圖像,整體呈粉色系?;叶仁澜绶▽⑷ǖ罃?shù)值進(jìn)行平均再補(bǔ)償,就會(huì)使三通道的數(shù)值趨近一致,進(jìn)而呈現(xiàn)灰色;而完美反射算法,計(jì)算的是三通道各自數(shù)值最大值和其亮區(qū)平均值的差距,再進(jìn)行補(bǔ)償,因此三通道的數(shù)值都會(huì)適當(dāng)加強(qiáng),使光感更強(qiáng),即圖片更亮。

接下來做個(gè)有趣的測(cè)試,將原本粉色的墻紙?jiān)O(shè)為較純的綠色。

圖5 調(diào)色后的圖像

圖6 白平衡效果圖

如圖5所示,因?yàn)閳D像中存在色調(diào)相沖的兩個(gè)部分,完美反射算法的優(yōu)勢(shì)在這種場景下體現(xiàn)的很明顯。因?yàn)榫G色區(qū)域較大,灰度世界算法中單純的計(jì)算均值再平衡,會(huì)無腦地將整圖的綠色分量降低,紅色分量提高,使得結(jié)果異常滑稽;而完美反射算法,因?yàn)閳D中有白值,三通道的最大值均在250左右,對(duì)綠色分量而言,其最亮區(qū)的均值接近于230,而紅色分量和藍(lán)色分量而言,其最亮區(qū)的均值也接近于200多,因此三通道的平衡結(jié)果就是整體提亮,而不是被無腦平均。

灰度世界算法效果圖見:

C++ OpenCV實(shí)現(xiàn)白平衡之灰度世界算法

到此這篇關(guān)于C++ OpenCV實(shí)現(xiàn)白平衡之完美反射算法的文章就介紹到這了,更多相關(guān)C++ OpenCV完美反射算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言詳細(xì)分析結(jié)構(gòu)體的內(nèi)存對(duì)齊規(guī)則

    C語言詳細(xì)分析結(jié)構(gòu)體的內(nèi)存對(duì)齊規(guī)則

    C 數(shù)組允許定義可存儲(chǔ)相同類型數(shù)據(jù)項(xiàng)的變量,結(jié)構(gòu)是 C 編程中另一種用戶自定義的可用的數(shù)據(jù)類型,它允許你存儲(chǔ)不同類型的數(shù)據(jù)項(xiàng),本篇讓我們來了解C 的結(jié)構(gòu)體內(nèi)存對(duì)齊
    2022-07-07
  • C語言實(shí)現(xiàn)高精度加減法

    C語言實(shí)現(xiàn)高精度加減法

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)高精度加減法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • C++淺析數(shù)據(jù)在內(nèi)存中如何存儲(chǔ)

    C++淺析數(shù)據(jù)在內(nèi)存中如何存儲(chǔ)

    使用編程語言進(jìn)行編程時(shí),需要用到各種變量來存儲(chǔ)各種信息。變量保留的是它所存儲(chǔ)的值的內(nèi)存位置。這意味著,當(dāng)您創(chuàng)建一個(gè)變量時(shí),就會(huì)在內(nèi)存中保留一些空間。您可能需要存儲(chǔ)各種數(shù)據(jù)類型的信息,操作系統(tǒng)會(huì)根據(jù)變量的數(shù)據(jù)類型,來分配內(nèi)存和決定在保留內(nèi)存中存儲(chǔ)什么
    2022-08-08
  • C語言每日練習(xí)之動(dòng)態(tài)顯示系統(tǒng)時(shí)間

    C語言每日練習(xí)之動(dòng)態(tài)顯示系統(tǒng)時(shí)間

    這篇文章主要介紹了C語言動(dòng)態(tài)顯示系統(tǒng)時(shí),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-11-11
  • C語言之qsort函數(shù)詳解

    C語言之qsort函數(shù)詳解

    這篇文章主要介紹了C語言中qsort函數(shù)的用法實(shí)例詳解的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C語言之雙向鏈表詳解及實(shí)例代碼

    C語言之雙向鏈表詳解及實(shí)例代碼

    這篇文章主要介紹了C語言之雙向鏈表的相關(guān)資料,并附實(shí)例代碼,有需要的小伙伴可以參考下
    2016-09-09
  • 淺析C++的特殊工具與技術(shù)

    淺析C++的特殊工具與技術(shù)

    以下是對(duì)C++中的特殊工具與技術(shù)進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下
    2013-08-08
  • 使用C語言實(shí)現(xiàn)掃雷游戲

    使用C語言實(shí)現(xiàn)掃雷游戲

    這篇文章主要為大家詳細(xì)介紹了使用C語言實(shí)現(xiàn)掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C++超詳細(xì)分析函數(shù)重載的使用

    C++超詳細(xì)分析函數(shù)重載的使用

    C++?允許多個(gè)函數(shù)擁有相同的名字,只要它們的參數(shù)列表不同就可以,這就是函數(shù)的重載(Function?Overloading),借助重載,一個(gè)函數(shù)名可以有多種用途
    2022-04-04
  • 一文詳解C++關(guān)鍵詞auto的用法

    一文詳解C++關(guān)鍵詞auto的用法

    在早期C/C++中auto的含義是:使用auto修飾的變量,是具有自動(dòng)存儲(chǔ)器的局部變量,但遺憾的是一直沒有人去使用它,在 C++11中,auto不再是一個(gè)存儲(chǔ)類型指示符,而是作為一個(gè)新的類型指示符來指示編譯器,本文將給大家詳細(xì)的介紹一下C++關(guān)鍵詞auto的用法,需要的朋友可以參考下
    2024-02-02

最新評(píng)論

民和| 涿州市| 南皮县| 曲水县| 陵川县| 桐庐县| 湘乡市| 平安县| 库伦旗| 灌云县| 万年县| 沙坪坝区| 临西县| 五寨县| 翁牛特旗| 山东省| 景德镇市| 青州市| 崇阳县| 来凤县| 余庆县| 什邡市| 偃师市| 南和县| 津市市| 繁昌县| 温宿县| 福鼎市| 贵南县| 潜江市| 九台市| 福泉市| 胶南市| 白城市| 三原县| 筠连县| 泰兴市| 平凉市| 平武县| 阳城县| 洞口县|