OpenCV图像处理算法——4(自动白平衡之完美反射算法原理及 C++实现)
opencv
OpenCV: 开源计算机视觉库
项目地址:https://gitcode.com/gh_mirrors/opencv31/opencv
·
自动白平衡之完美反射算法
算法原理
此算法的原理非常简单,完美反射理论假设图像中最亮的点就是白点,并以此白点为参考对图像进行自动白平衡,最亮点定义为的最大值
算法步骤
- 计算每个像素之和 R + G + B R+G+B R+G+B并保存。
- 按照的值的大小计算出其前
10%或其他Ratio的白色参考点的阈值 T T T。 - 遍历图像中的每个点,计算 R + G + B R+G+B R+G+B大于 T T T 的所有点的 R 、 G 、 B R、G、B R、G、B分量的累积和的平均值。
- 将每个像素量化到 [ 0 , 255 ] [0,255] [0,255]
C++代码
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
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 img, result;
img = imread("E://Programing Project//OpenCV//Test//OpenCVtest//grayworldtest.jpg", IMREAD_COLOR);
namedWindow("Result", WINDOW_AUTOSIZE);
namedWindow("Origin", WINDOW_AUTOSIZE);
result = PerfectReflectionAlgorithm(img);
if (result.empty())
{
cout << "Error! THE IMAGE IS EMPTY.." << endl;
return -1;
}
else
{
imshow("Origin", img);
imshow("Result", result);
}
waitKey(0);
return 0;
}
代码解释
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
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]);
//计算每一个像素之和
//@param sum:每一个像素之和
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];
//按照的值的大小计算出其前 10% 或其他 Ratio 的白色参考点的阈值 T。
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++;
}
}
}
//计算R+G+BR+G+B大于 T 的所有点的R、G、B分量的累积和的平均值。
AvgB /= cnt;
AvgG /= cnt;
AvgR /= cnt;
//将每一个像素量化到[0,255]
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 img, result;
img = imread("E://Programing Project//OpenCV//Test//OpenCVtest//grayworldtest.jpg", IMREAD_COLOR);
namedWindow("Result", WINDOW_AUTOSIZE);
namedWindow("Origin", WINDOW_AUTOSIZE);
result = PerfectReflectionAlgorithm(img);
if (result.empty())
{
cout << "Error! THE IMAGE IS EMPTY.." << endl;
return -1;
}
else
{
imshow("Origin", img);
imshow("Result", result);
}
waitKey(0);
return 0;
}
可以看到自动白平衡算法之完美反射算法算法有了白平衡的效果,并且该算法的执行速度也是非常的快。
OpenCV: 开源计算机视觉库
最近提交(Master分支:4 个月前 )
1f47f5ba
imgproc: replace assertion in cornerSubPix with descriptive error #28404
Replace CV_Assert with explicit bounds check for initial corners in cornerSubPix.
This provides a descriptive runtime error instead of abrupt termination,
improving error handling for Python and C++ users.
No algorithmic or behavioral change for valid inputs.
Fixes #25139 (Related to #7276).
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
3 小时前
fba658b9
Improve precision of RotatedRect::points 1 天前
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)