首页 分享 OpenCV图像处理专栏十二

OpenCV图像处理专栏十二

来源:花匠小妙招 时间:2025-06-24 01:39

前言

这是OpenCV图像处理专栏的第十二篇文章,今天为大家介绍一个用于解决光照不均匀的图像自适应校正算法。光照不均匀其实是非常常见的一种状况,为了提升人类的视觉感受或者是为了提升诸如深度学习之类的算法准确性,人们在解决光照不均衡方面已经有大量的工作。一起来看看这篇论文使用的算法吧,论文名为:《基于二维伽马函数的光照不均匀图像自适应校正算法》。

算法原理

论文使用了Retinex的多尺度高斯滤波求取「光照分量」,然后使用了二「维Gamma函数」针对原图的「HSV空间的V(亮度)分量」进行亮度改变,得到结果。原理还是蛮简单的,因为是中文论文,且作者介绍得很清楚,我就不细说了,可以自己看论文,论文地址见附录。本文的重点在于对算法步骤的解读和OpenCV复现。

算法步骤

在这里插入图片描述

需要注意的点

文中公式5(二维Gamma变换) 有误,公式5为:

其中 的指数应该是,而不是,如果使用后者会得到错误结果,应该是作者笔误了。

代码语言:javascript

代码运行次数:

0

运行

复制

Mat RGB2HSV(Mat src) {int row = src.rows;int col = src.cols;Mat dst(row, col, CV_32FC3);for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {float b = src.at<Vec3b>(i, j)[0] / 255.0;float g = src.at<Vec3b>(i, j)[1] / 255.0;float r = src.at<Vec3b>(i, j)[2] / 255.0;float minn = min(r, min(g, b));float maxx = max(r, max(g, b));dst.at<Vec3f>(i, j)[2] = maxx; //Vfloat delta = maxx - minn;float h, s;if (maxx != 0) {s = delta / maxx;}else {s = 0;}if (r == maxx) {h = (g - b) / delta;}else if (g == maxx) {h = 2 + (b - r) / delta;}else {h = 4 + (r - g) / delta;}h *= 60;if (h < 0)h += 360;dst.at<Vec3f>(i, j)[0] = h;dst.at<Vec3f>(i, j)[1] = s;}}return dst; } Mat HSV2RGB(Mat src) {int row = src.rows;int col = src.cols;Mat dst(row, col, CV_8UC3);float r, g, b, h, s, v;for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {h = src.at<Vec3f>(i, j)[0];s = src.at<Vec3f>(i, j)[1];v = src.at<Vec3f>(i, j)[2];if (s == 0) {r = g = b = v;}else {h /= 60;int offset = floor(h);float f = h - offset;float p = v * (1 - s);float q = v * (1 - s * f);float t = v * (1 - s * (1 - f));switch (offset){case 0: r = v; g = t; b = p; break;case 1: r = q; g = v; b = p; break;case 2: r = p; g = v; b = t; break;case 3: r = p; g = q; b = v; break;case 4: r = t; g = p; b = v; break;case 5: r = v; g = p; b = q; break;default:break;}}dst.at<Vec3b>(i, j)[0] = int(b * 255);dst.at<Vec3b>(i, j)[1] = int(g * 255);dst.at<Vec3b>(i, j)[2] = int(r * 255);}}return dst; } Mat work(Mat src) {int row = src.rows;int col = src.cols;Mat now = RGB2HSV(src);Mat H(row, col, CV_32FC1);Mat S(row, col, CV_32FC1);Mat V(row, col, CV_32FC1);for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {H.at<float>(i, j) = now.at<Vec3f>(i, j)[0];S.at<float>(i, j) = now.at<Vec3f>(i, j)[1];V.at<float>(i, j) = now.at<Vec3f>(i, j)[2];}}int kernel_size = min(row, col);if (kernel_size % 2 == 0) {kernel_size -= 1;}float SIGMA1 = 15;float SIGMA2 = 80;float SIGMA3 = 250;float q = sqrt(2.0);Mat F(row, col, CV_32FC1);Mat F1, F2, F3;GaussianBlur(V, F1, Size(kernel_size, kernel_size), SIGMA1 / q);GaussianBlur(V, F2, Size(kernel_size, kernel_size), SIGMA2 / q);GaussianBlur(V, F3, Size(kernel_size, kernel_size), SIGMA3 / q);for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {F.at <float>(i, j) = (F1.at<float>(i, j) + F2.at<float>(i, j) + F3.at<float>(i, j)) / 3.0;}}float average = mean(F)[0];Mat out(row, col, CV_32FC1);for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {float gamma = powf(0.5, (average - F.at<float>(i, j)) / average);out.at<float>(i, j) = powf(V.at<float>(i, j), gamma);}}vector <Mat> v;v.push_back(H);v.push_back(S);v.push_back(out);Mat merge_;merge(v, merge_);Mat dst = HSV2RGB(merge_);return dst; }

效果

原图1

效果图1

原图2

效果图2

结论

可以看到这个算法对光照不均匀的图像校正效果还是不错的,且没有像Retiex那样在亮度突变处出现色晕现象。

附录

论文原文:https://wenku.baidu.com/view/3570f2c255270722182ef74e.html

欢迎关注GiantPandaCV, 在这里你将看到独家的深度学习分享,坚持原创,每天分享我们学习到的新鲜知识。( • ̀ω•́ )✧

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。

原始发表:2020-02-04

,如有侵权请联系 cloudcommunity@tencent.com 删除

相关知识

OpenCV图像处理专栏十二
基于OpenCV的大叶黄杨叶片特征视频图像检测
关于使用opencv读取经过labelImg工具进行标注后的图像出现的框与图像旋转方向不一致的问题 [author: linkrain]
基于OpenCV的鲜花的图像分类系统详细设计与具体代码实现
OpenCV实战项目——多种颜色识别
opencv
利用OpenCV根据图片识别环境的亮度
使用图像处理技术和卷积神经网络(CNN)的作物病害检测
【OpenCV】45 图像二值化与去噪
深入浅出:利用OpenCV实现手写数字识别之旅

网址: OpenCV图像处理专栏十二 https://www.huajiangbk.com/newsview2073066.html

所属分类:花卉
上一篇: 兰花促花促芽全攻略:精准调控让兰
下一篇: 光照增强下的红外与可见光图像融合

推荐分享