2015-01-19 09:05:11 scottly1 阅读数 8994

白平衡,即所谓的白色的平衡。

白平衡的算法有很多,这里记录的是最简单实用的白平衡算法,即灰色世界法!

灰度世界算法(Gray World)是以灰度世界假设为基础的,该假设认为对于一幅有着大量色彩变化的图像, R、 G、 B 三个分量的平均值趋于同一个灰度K。


下面是具体的算法代码:

RGB=imread('test.jpg');

R = RGB(:,:,1);      G = RGB(:,:,2);      B = RGB(:,:,3);
Rx4 = RGB(:,:,1)*4;  Gx4 = RGB(:,:,2)*4;  Bx4 = RGB(:,:,3)*4; //Rx4只是做了一个简单的线性的提亮,可以不用参考。

Rave = mean(mean(R)); 
Gave = mean(mean(G)); 
Bave = mean(mean(B));
Kave = (Rave + Gave + Bave) / 3;

R1 = (Kave/Rave)*R; G1 = (Kave/Gave)*G; B1 = (Kave/Bave)*B; 
R2 = (Kave/Rave)*Rx4; G2 = (Kave/Gave)*Gx4; B2 = (Kave/Bave)*Bx4; 

RGB_white = cat(3, R1, G1, B1);
RGB_whitex4 = cat(3, R2, G2, B2);

RGB_white_out = uint8(RGB_white); RGB_white_outx4 = uint8(RGB_whitex4);

下面是算法的效果:

原图:



白平衡之后:



可见,最原始的算法,效果还是不错的,后面有机会会补充其他好一些的算法。


注:原创文章,转载请注明出处: http://blog.csdn.net/scottly1/article/details/42741495


2012-02-23 10:19:05 hellmonky 阅读数 6100

转载请注明出处和作者,谢谢合作!!!

使用相机等采集图像的过程中,往往由于成像过程中的感光元件或者镜头会对原始色彩造成影响,为了校正这种光线和镜头对颜色影响,都会加入白平衡来对成像结果进行调整,那么今天就介绍一个最简单的白平衡处理方法:灰色世界方法

话不多说了,有不懂原理的可以留言,直接上测试通过的代码:

im = imread('1.jpg','jpg');
im = double(im)./256;
r = im(:,:,1);
g = im(:,:,2);
b = im(:,:,3);
avgR = mean(mean(r));
avgG = mean(mean(g));
avgB = mean(mean(b));
avgGray = (avgR + avgG + avgB)/3;
if avgR == 0
	outR = r;
else
	outR = (avgGray/avgR).*r;
end

if avgG == 0
	outG = g;
else
	outG = (avgGray/avgG).*g;
end

if avgB == 0
	outB = b;
else
	outB = (avgGray/avgB).*b;
end

maxRGB = [max(max(outR)) max(max(outG)) max(max(outG))];

factor = max(maxRGB);
if  factor > 1
	outR = outR./factor;
	outG = outG./factor;
	outB = outB./factor;
end

GWoutIm(:,:,1) = outR;
GWoutIm(:,:,2) = outG;
GWoutIm(:,:,3) = outB;

imshow(GWoutIm);

imwrite(GWoutIm, 'testout.jpg', 'jpg');

avgIn1RGB = [mean(mean(r)) mean(mean(g)) mean(mean(b))];
avgGW1RGB = [mean(mean(outR)) mean(mean(outG)) mean(mean(outB))];
avgIn1 = mean([mean(mean(r)) mean(mean(g)) mean(mean(b))]);
avgGW1 = mean([mean(mean(outR)) mean(mean(outG)) mean(mean(outB))]);

一下是测试图像(来源自网络):

原始图像(色调偏冷)


处理以后的图像(色调转暖):


谢谢您的支持,有任何的问题欢迎留言

2017-04-09 22:56:04 u013085897 阅读数 6609
       本文算法摘自opencv,可以说opencv是一个大宝库,里面有无穷无尽的算法,但是opencv里面的算法属于研究性质,只能解决“有”的问题,还不能解决“好”的问题。比如下面的简单白平衡算法,核心思想是:在rgb三通道上分别计算直方图,然后将1%的最大值和最小值设置为255和0,其余值映射到(0, 255)区间内,这样使得每个通道的值均匀分布,以实现简单的颜色平衡。实际测试效果,对于某些图像效果还是可以的,尤其是偏色比较厉害的图像。不过该算法实现逻辑比较晦涩。
#include "stdafx.h"
#include <cv.h>
#include <highgui.h>

using namespace cv;
using namespace std;

enum
{
	WHITE_BALANCE_SIMPLE = 0,
	WHITE_BALANCE_GRAYWORLD = 1
};

/*白平衡******************************************************************************************************************/
void balanceWhite(std::vector<Mat> &src, Mat &dst, const float inputMin, const float inputMax, const float outputMin, const float outputMax, const int algorithmType)
{
	// 在rgb三通道上分别计算直方图
	// 将1%的最大值和最小值设置为255和0
	// 其余值映射到(0, 255), 这样使得每个值通道的值在rgb中分布较均匀, 以实现简单的颜色平衡
	switch (algorithmType)
	{
	case WHITE_BALANCE_SIMPLE:
		{
			/********************* Simple white balance *********************/
			float s1 = 1.0f;// low quantile
			float s2 = 1.0f;// high quantile

			int depth = 2;// depth of histogram tree
			int bins = 16;// number of bins at each histogram level
			int total = src[0].cols * src[0].rows;
			int nElements = int(pow((float)bins, (float)depth));// number of elements in histogram tree

			for (size_t k = 0; k < src.size(); ++k)
			{
				std::vector<int> hist(nElements, 0);
				uchar *pImag = src[k].data;
				// histogram filling
				for (int i = 0; i < total; i++)
				{
					int pos = 0;
					float minValue = inputMin - 0.5f;
					float maxValue = inputMax + 0.5f;
					float interval = float(maxValue - minValue) / bins;

					uchar val = pImag[i];
					for (int j = 0; j < depth; ++j)
					{
						int currentBin = int((val - minValue + 1e-4f) / interval);
						++hist[pos + currentBin];

						pos = (pos + currentBin)*bins;
						minValue = minValue + currentBin*interval;
						interval /= bins;
					}
				}

				int p1 = 0, p2 = bins - 1;
				int n1 = 0, n2 = total;
				float minValue = inputMin - 0.5f;
				float maxValue = inputMax + 0.5f;
				float interval = float(maxValue - minValue) / bins;

				// searching for s1 and s2
				for (int j = 0; j < depth; ++j)
				{
					while (n1 + hist[p1] < s1 * total / 100.0f)
					{
						n1 += hist[p1++];
						minValue += interval;
					}
					p1 *= bins;

					while (n2 - hist[p2] > (100.0f - s2) * total / 100.0f)
					{
						n2 -= hist[p2--];
						maxValue -= interval;
					}
					p2 = p2*bins - 1;

					interval /= bins;
				}

				src[k] = (outputMax - outputMin) * (src[k] - minValue) / (maxValue - minValue) + outputMin;
			}
			/****************************************************************/
			break;
		}
	default:
		CV_Error_(CV_StsNotImplemented, ("Unsupported algorithm type (=%d)", algorithmType));
	}// switch

	merge(src, dst);
}

void balanceWhite(const Mat &src, Mat &dst, const int algorithmType, const float inputMin = 0.0f, const float inputMax = 255.0f, const float outputMin = 0.0f, const float outputMax = 255.0f)
{
	switch (src.depth())
	{
	case CV_8U:
		{
			std::vector<Mat> mv;
			split(src, mv);
			balanceWhite(mv, dst, inputMin, inputMax, outputMin, outputMax, algorithmType);
			break;
		}
	default:
		CV_Error_(CV_StsNotImplemented, ("Unsupported source image format (=%d)", src.type()));
		break;
	}
}
/**************************************************************************************************************************/

int main()
{
	const char* fileName = "dog.png" ;
	Mat src = imread(fileName);
	imshow("src", src);

	cv::Mat dst(src.size(), src. type());
	balanceWhite(src, dst, WHITE_BALANCE_SIMPLE);
	imshow("dst", dst);
	imwrite("result.jpg", dst);

	cv::waitKey();
	return 0;
}
       效果如下:
    
                                                
                                              
                                              
       简单的算法,有时也有神奇的一面,这也是做图像算法研究的一种乐趣。对于类似下面的图片,该算法还有去雾霾效果,不过由于该算法仅仅是统计并拉伸像素值,所以局限性很大,去雾霾效果如下:
                              

       参考资料:




2020-01-05 15:30:08 qq_42261630 阅读数 18

1.定义

从以下三个方面理解白平衡的定义

  • 通俗理解白平衡

白平衡,字面上的理解是白色的平衡。白平衡是描述显示器中红、绿、蓝三基色混合生成后白色精确度的一项指标。白平衡就涉及到了一个相对颜色的问题,比如一张纯白色的白纸,在白炽灯下拍出来颜色是白色的。但是在烛光下拍出来就是偏暖色,在晴朗的蓝天拍出来就偏冷色。那么这张纸到底是什么颜色?白平衡的初始技能就是将在不同环境色温中的白色物体都还原成真的白色。许多人在使用数码摄像机拍摄的时候都会遇到这样的问题:在日光灯的房间里拍摄的影像会显得发绿,在室内钨丝灯光下拍摄出来的景物就会偏黄,而在日光阴影处拍摄到的照片则莫名其妙地偏蓝,其原因就在于白平衡的设置上。

此图摘自:https://blog.csdn.net/a200800170331/article/details/82013946

  • 从工作原理理解白平衡

白平衡是一个很抽象的概念,最通俗的理解就是让白色所成的像依然为白色,如果白是白,那其他景物的影像就会接近人眼的色彩视觉习惯。调整白平衡的过程叫做白平衡调整,白平衡调整在前期设备上一般有三种方式:预置白平衡、手动白平衡调整和自动跟踪白平衡调整。摄像机内部有三个CCD电子耦合元件,他们分别感受蓝色、绿色、红色的光线,在预置情况下这三个光电路电子放大比例是相同的,为1:1:1的关系,白平衡的调整就是根据被调校的景物改变了这种比例关系。比如被调校景物的蓝、绿、红色光的比例关系是2:1:1(蓝光比例多,色温偏高),那么白平衡调整后的比例关系为1:2:2,调整后的电路放大比例中明显蓝的比例减少,增加了绿和红的比例,这样被调校景物通过白平衡调整电路到所拍摄的影像,蓝、绿、红的比例才会相同。也就是说如果被调校的白色偏一点蓝,那么白平衡调整就改变正常的比例关系减弱蓝电路的放大,同时增加绿和红的比例,使所成影像依然为白色 [5]  

  • 从色温色调角度理解白平衡

白平衡与色温有密切关系。不同色温光源下图像会呈现不同程度的偏色。由于人眼具有独特的适应性,使我们有的时候不能发现色温的变化。比如在钨丝灯下呆久了,并不会觉得钨丝灯下的白纸偏红,如果突然把日光灯改为钨丝灯照明,就会觉查到白纸的颜色偏红了,但这种感觉也只能够持续一会儿。摄像机的CCD并不能像人眼那样具有适应性,所以如果摄像机的色彩调整同景物照明的色温不一致就会发生偏色。那么什么是白平衡呢?白平衡就是针对不同色温条件下,通过调整摄像机内部的色彩电路使拍摄出来的影像抵消偏色,更接近人眼的视觉习惯。白平衡可以简单地理解为在任意色温条件下,摄像机镜头所拍摄的标准白色经过电路的调整,使之成像后仍然为白色。这是一种经常出现的情况,但不是全部,白平衡其实是通过摄像机内部的电路调整(改变蓝、绿、红三个CCD电平的平衡关系)使反射到镜头里的光线都呈现为消色。如果以偏红的色光来调整白平衡,那么该色光的影像就为消色,而其他色彩的景物就会偏蓝(补色关系)在不同光照条件下观看物体时不会出现偏色。

色温:所谓色温,简而言之,就是定量地以开尔文温度(K)来表示色彩。英国著名物理学家开尔文认为,假定某一黑体物质,能够将落在其上的所有热量吸收,而没有损失,同时又能够将热量生成的能量全部以“光”的形式释放出来的话,它便会因受到热力的高低而变成不同的颜色。例如,当黑体受到的热力相当于500-550℃时,就会变成暗红色,达到1050-1150℃时 [1]  ,就变成黄色,温度继续升高会呈现蓝色。光源的颜色成分与该黑体所受的热力温度是相对应的,任何光线的色温是相当于上述黑体散发出同样颜色时所受到的“温度”,这个温度就用来表示某种色光的特性以区别其它,这就是色温。打铁过程中,黑色的铁在炉温中逐渐变成红色,这便是黑体理论的最好例子。

色温:是表示光线中包含颜色成分的一个计量单位。从理论上讲,色温是指绝对黑体从绝对零度( -273℃)开始加温后所呈现的颜色。黑体在受热后,逐渐南黑变红,转黄,发白,最后发出蓝色光。当加热到一定的温度,黑体发出的光所含的光谱成分,就称为这一温度下的色温,计量单位为“K” (开尔文)

白平衡本质上是调节两个参数:色温和色调,色温调节蓝-黄偏色,色调调节绿-品红偏色。通过调节两个参数,来设置白点的位置,从而得到正确的色彩转换。

2.白平衡算法

  • 灰度世界算法GW(自动白平衡)
  • 全反射理论算法PR(自动白平衡最常用之一)
  • GW和PR正交组合算法QCGP
  • 色温估计法

这一部分内容详见如下博客内容

https://blog.csdn.net/a6333230/article/details/82889842

 

 

白平衡是视频图像处理重要的一部分。

博文 来自: wangbaodong070411209
没有更多推荐了,返回首页