专栏首页GiantPandaCVOpenCV图像处理专栏四 | 自动白平衡之完美反射算法原理及C++实现

OpenCV图像处理专栏四 | 自动白平衡之完美反射算法原理及C++实现

前言

昨天的推文:点这里介绍的灰度世界算法是最原始的处理白平衡的算法。今天要介绍的完美反射算法也是自动白平衡常用的算法之一。一起来看看吧。

算法原理

此算法的原理非常简答,完美反射理论假设图像中最亮的点就是白点,并以此白点为参考对图像进行自动白平衡,最亮点定义为的最大值

算法步骤

  • 计算每个像素之和并保存。
  • 按照的值的大小计算出其前10%或其他Ratio的白色参考点的阈值T
  • 遍历图像中的每个点,计算其中值大于T的所有点的、、分量的累积和的平均值。
  • 将每个像素量化到。

C++代码实现

#include <stdio.h>
#include <iostream>
#include <immintrin.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/ml/ml.hpp>
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
using namespace cv::ml;
using namespace std;

Mat PerfectReflectionAlgorithm(Mat src) {
	int row = src.rows;
	int col = src.cols;
	Mat dst(row, col, CV_8UC3);
	int HistRGB[767] = { 0 };
	int MaxVal = 0;
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			MaxVal = max(MaxVal, (int)src.at<Vec3b>(i, j)[0]);
			MaxVal = max(MaxVal, (int)src.at<Vec3b>(i, j)[1]);
			MaxVal = max(MaxVal, (int)src.at<Vec3b>(i, j)[2]);
			int sum = src.at<Vec3b>(i, j)[0] + src.at<Vec3b>(i, j)[1] + src.at<Vec3b>(i, j)[2];
			HistRGB[sum]++;
		}
	}
	int Threshold = 0;
	int sum = 0;
	for (int i = 766; i >= 0; i--) {
		sum += HistRGB[i];
		if (sum > row * col * 0.1) {
			Threshold = i;
			break;
		}
	}
	int AvgB = 0;
	int AvgG = 0;
	int AvgR = 0;
	int cnt = 0;
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			int sumP = src.at<Vec3b>(i, j)[0] + src.at<Vec3b>(i, j)[1] + src.at<Vec3b>(i, j)[2];
			if (sumP > Threshold) {
				AvgB += src.at<Vec3b>(i, j)[0];
				AvgG += src.at<Vec3b>(i, j)[1];
				AvgR += src.at<Vec3b>(i, j)[2];
				cnt++;
			}
		}
	}
	AvgB /= cnt;
	AvgG /= cnt;
	AvgR /= cnt;
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			int Blue = src.at<Vec3b>(i, j)[0] * MaxVal / AvgB;
			int Green = src.at<Vec3b>(i, j)[1] * MaxVal / AvgG;
			int Red = src.at<Vec3b>(i, j)[2] * MaxVal / AvgR;
			if (Red > 255) {
				Red = 255;
			}
			else if (Red < 0) {
				Red = 0;
			}
			if (Green > 255) {
				Green = 255;
			}
			else if (Green < 0) {
				Green = 0;
			}
			if (Blue > 255) {
				Blue = 255;
			}
			else if (Blue < 0) {
				Blue = 0;
			}
			dst.at<Vec3b>(i, j)[0] = Blue;
			dst.at<Vec3b>(i, j)[1] = Green;
			dst.at<Vec3b>(i, j)[2] = Red;
		}
	}
	return dst;
}

int main() {
	Mat src = imread("F:\\child.jpg");
	Mat dst = PerfectReflectionAlgorithm(src);
	imshow("origin", src);
	imshow("result", dst);
	imwrite("F:\\res.jpg", dst);
	waitKey(0);
}

效果

后记

可以看到自动白平衡算法之完美反射算法算法有了白平衡的效果,并且该算法的执行速度也是非常的快。

本文分享自微信公众号 - GiantPandaCV(BBuf233)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-12-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • RecSim:推荐系统的可配置仿真平台

    机器学习,语音识别和语言技术的重大进步正在迅速改变推荐系统与用户互动的方式。因此协作交互式推荐器 (CIR) — 推荐系统与用户进行了有意的交互,以最好地满足该...

    代码医生工作室
  • go:处理时间

    超级大猪
  • C#笔记:LinqToObject用法

    Linq作为 .net3.5 可以比肩蓝翔挖掘机的重磅产品,当然可以对万事万物进行查询。而不只是查查xml,数据库可以概括的。自然,我们也能用它对List<T>...

    超级大猪
  • python笔记:字符串

    编码解码非常的复杂,unicode才能encode,其它的编码可以decode成unicode。 所以在python中,推荐使用unicode(python3...

    超级大猪
  • 详解三道一维的动态规划算法题

    在一条直线上,有n个房屋,每个房屋中有数量不等的财宝,有一个盗 贼希望从房屋中盗取财宝,由于房屋中有报警器,如果同时从相邻的两个房屋中盗取财宝就会触发报警器。问...

    帅地
  • 【Git学习笔记7】多人协作时要知道的事儿

    我们在工作中经常会遇到需要添加一个新功能。添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个featur...

    用户6543014
  • C#笔记:异步的复杂实现

    4、调用beginInvoke,传入异步操作的参数,传入回调处理函数,传入回调函数(作为回调处理函数的参数)

    超级大猪
  • C#笔记:动态规划算法

    一个复杂的问题,通常逐级会分解成一系列小问题。而且很多情况下,某些小问题是相似的。但是使用传统的递归,会将相同相似的小问题进行重复的计算。这样浪费了算力。 所谓...

    超级大猪
  • C#笔记:反射的简单用法

    反射其实说白了就是,当你知道类的名字和位置。你可以在程序运行时直接创建实例调用它。没什么大不了的。

    超级大猪
  • 接口自动化测试平台系列:场景化执行

    有一个DataProvider_ForMysql类,作用是重写了Iterator<Object[]>,将集合内的所有接口以迭代器的形式通过DataProvide...

    软件测试君

扫码关注云+社区

领取腾讯云代金券