AWB图像增强算法 Opencv实现

/*
Automatic white balance
直方图法,去掉两端高亮度和低亮度的像素点(1%)后,将剩余像素再归一化到原始区间[min_pre, max_pre]
t' = (t - min_cur) / (max_cur - min_cur) * (max_pre - min_pre)

若BGR三个通道分别去掉首尾1%的像素后,再分别归一化到[min_pre, max_pre],颜色会出现问题
因为三通道去掉首尾后保留的像素区间不一样
比如对两通道边界处理了丢弃了255,而对另一通道没有处理,则只剩下该通道的颜色了

故对BGR三通道所有的值一起去掉首尾1%,用同区间处理BGR三通道
*/
// 图像预处理, 确定min_pre, max_pre, min_cur, max_cur
void image_process(Mat img, float s, int histSize, vector<float>& a)
{
	vector<Mat> channels;
	split(img, channels);

	Mat A1, A2;
	vconcat(channels[0], channels[1], A1);
	vconcat(A1, channels[2], A2);

	Mat hist;
	float range[] = { 0,256 };
	const float *histRanges = { range };
	float interval = 256.0f / histSize;
	calcHist(&A2, 1, 0, Mat(), hist, 1, &histSize, &histRanges, true, false);

	// cout << hist.type() << endl;				// CV_32F
	int image_size = A2.rows * A2.cols;
	vector<float> Hist;
	float sum = 0.0f;
	for (int i = 0; i < hist.rows; ++i)			// 直方图区间的累计和
	{
		sum += hist.at<float>(i);
		Hist.push_back(sum / image_size);
	}

	double min_pre_value, max_pre_value;
	minMaxIdx(A2, &min_pre_value, &max_pre_value);

	int lmin = 0;
	int lmax = histSize - 1;
	while (lmin < histSize)						// 去除最小的s范围内的元素
	{
		if (Hist[lmin] >= s)
		{
			break;
		}
		lmin += 1;
	}
	while (lmax > 0)							// 去除最大的s范围内的元素
	{
		if (Hist[lmax] <= (1 - s))
		{
			break;
		}
		lmax -= 1;
	}

	float min_cur_value, max_cur_value;
	min_cur_value = lmin * interval;
	max_cur_value = lmax * interval;

	a = { min_cur_value, max_cur_value, (float)min_pre_value, (float)max_pre_value };
}

// 按公式t' = (t - min_cur) / (max_cur - min_cur) * (max_pre - min_pre)修改像素值
void awb(Mat& src, Mat& dst, vector<float>& a)
{
	dst = src.clone();
	for (int i = 0; i < dst.rows; ++i)
	{
		for (int j = 0; j < dst.cols; ++j)
		{
			for (int k = 0; k < 3; k++)
			{
				if (dst.at<Vec3b>(i, j)[k] >= (int)round(a[0]) && dst.at<Vec3b>(i, j)[k] <= (int)round(a[1]))
				{
					dst.at<Vec3b>(i, j)[k] = (int)round((dst.at<Vec3b>(i, j)[k] - a[0]) * (a[3] - a[2]) / (a[1] - a[0]) + a[2]);
				}
				else if (dst.at<Vec3b>(i, j)[k] < (int)round(a[0]))
				{
					dst.at<Vec3b>(i, j)[k] = (int)round(a[2]);
				}
				else
				{
					dst.at<Vec3b>(i, j)[k] = (int)round(a[3]);
				}
			}
		}
	}
}
int main()
{
	Mat srcImg = imread("pic.jpg");
	namedWindow("srcImg", CV_WINDOW_NORMAL);
	imshow("srcImg", srcImg);

	vector<float> a;
    Mat awbImg;
	image_process(srcImg, 0.01f, 2000, a);
	awb(srcImg, awbImg, a);
	namedWindow("awbImg", CV_WINDOW_NORMAL);
	imshow("awbImg", awbImg);

	waitKey(0);
	return 0;
}

 实验结果:

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AWB(Auto White Balance)是一种用于自动调整图像白平衡的算法。灰度世界法(Gray World Algorithm)是AWB的一种常见实现方法。在Python中,你可以使用OpenCV库来实现AWB灰度世界法。 下面是一个简单的示例代码: ```python import cv2 import numpy as np def awb_gray_world(image): # 将图像转换为浮点数形式 image = image.astype(np.float32) # 计算每个通道的平均值 avg_b = np.mean(image[:, :, 0]) avg_g = np.mean(image[:, :, 1]) avg_r = np.mean(image[:, :, 2]) # 计算平均灰度值 avg_gray = (avg_b + avg_g + avg_r) / 3 # 计算每个通道的增益系数 gain_b = avg_gray / avg_b gain_g = avg_gray / avg_g gain_r = avg_gray / avg_r # 根据增益系数调整图像 image[:, :, 0] *= gain_b image[:, :, 1] *= gain_g image[:, :, 2] *= gain_r # 将图像转换回整数形式,并进行裁剪 image = np.clip(image, 0, 255).astype(np.uint8) return image # 读取图像 image = cv2.imread('input.jpg') # 调用灰度世界法函数 result = awb_gray_world(image) # 显示结果图像 cv2.imshow('Result', result) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在上面的代码中,首先将图像转换为浮点数形式,然后计算每个通道的平均值。接下来,计算平均灰度值,并根据增益系数调整每个通道的像素值。最后,将图像转换回整数形式,并进行裁剪。你可以将输入图像替换为你自己的图像,并运行代码查看结果。 希望这个示例能够帮助到你!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值