# 算法步骤

• 计算每个像素之和并保存。
• 按照的值的大小计算出其前`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 dst = PerfectReflectionAlgorithm(src);
imshow("origin", src);
imshow("result", dst);
imwrite("F:\\res.jpg", dst);
waitKey(0);
}
```

# 后记

0 条评论

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

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

• ### C#笔记：LinqToObject用法

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

• ### python笔记：字符串

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

• ### 详解三道一维的动态规划算法题

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

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

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

• ### C#笔记：异步的复杂实现

4、调用beginInvoke，传入异步操作的参数，传入回调处理函数，传入回调函数（作为回调处理函数的参数）

• ### C#笔记：动态规划算法

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

• ### C#笔记：反射的简单用法

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

• ### 接口自动化测试平台系列：场景化执行

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