ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

转 - 一种简单的图像白平衡计算方法

2019-03-04 22:53:15  阅读:253  来源: 互联网

标签:src const int float 白平衡 minValue bins 图像 计算方法


本文算法摘自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;
}

 

From:一种简单的图像白平衡计算方法

标签:src,const,int,float,白平衡,minValue,bins,图像,计算方法
来源: https://blog.csdn.net/tony2278/article/details/88141853

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有