opencv图像增强之MSR

Retinex图像增强算法

  最近在研究图像增强算法,发现Retinex这个算法在彩色增强,尤其是低对比度下特别好用,基于网上已经有不少相关的算法原理了,我这里就不说原理性的东西了,下面给出一条连接请初学者自行get(~~)

https://blog.csdn.net/ajianyingxiaoqinghan/article/details/71435098

下面给出一张未经过增强的原图,很明显该原图对比度很低,不仔细看几乎就获取不到任何有用信息,那么就是我们Retinex大显身手的时候了,下面直接上代码,让我带你去挖掘它的本质(>oo<)


#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int M1 = 0;
int M2 = 0;
int M3 = 0;
void MSR(int, void* userdata)
{
	Mat src = imread("fog2.png");
	src.convertTo(src, CV_32FC1, 1.0, 1.0);
	Mat gaussian_src, gaussian_src1, gaussian_src2;
	
	//这里我是使用的很简单的高斯模糊,网上也给出了很多不同方式的高斯模糊以及加速,请自行尝试
	//分别在不同尺度下进行高斯模糊,我分别取了19,39,59的卷积核,各位也可自行尝试←_←
	GaussianBlur(src, gaussian_src, Size(19, 19), 0, 0);
	GaussianBlur(src, gaussian_src1, Size(39, 39), 0, 0);
	GaussianBlur(src, gaussian_src2, Size(59, 59), 0, 0);
	
	//核心,这里就是MSR的“M”,通过不同程度的自增达到multi的效果,各位也可以自行尝试更野的路子O(∩_∩)O
	for (int i = 0; i < M1;i++)
		add(gaussian_src, gaussian_src, gaussian_src);
	for (int i = 0; i < M2; i++)
		add(gaussian_src, gaussian_src, gaussian_src);
	for (int i = 0; i < M3; i++)
		add(gaussian_src2, gaussian_src2, gaussian_src2);
	
	//自增之后当然要进行合并了嘛,不然就不叫累积了嘛
	add(gaussian_src, gaussian_src1, gaussian_src);
	add(gaussian_src, gaussian_src2, gaussian_src);
	log(gaussian_src, gaussian_src);
	log(src, src);
	subtract(src, gaussian_src, src);


	//下面的这个也是核心之一,到了上面这一步,从原理出发,我应该用exp将图片转换回去然后归一化
	//但如果这么操作的话效果很差,几乎可以说没有进行增强,至于为什么?各位自行百度,毕竟我只是个码农%>_<%
	//因此我采图像的均值、方差,使用图像的均值方差等信息进行变换,利用如下的公式
	//(1) Min = Mean - Dynamic * Var;  
	//(2) Max = Mean + Dynamic * Var;
	//然后对Log[R(x,y)]的每一个值Value,进行线性映射: 
	//(3)R(x,y) = ( Value - Min ) / (Max - Min) * (255-0)
	Mat mean_val, stddev_value;
	meanStdDev(src, mean_val, stddev_value);
	double min[3];
	double max[3];
	double minmax[3];
	for (int i = 0; i < 3; i++)
	{
		min[i] = mean_val.at<double>(i, 0) - 2 * stddev_value.at<double>(i, 0);
		max[i] = mean_val.at<double>(i, 0) + 2 * stddev_value.at<double>(i, 0);
		minmax[i] = max[i] - min[i];
	}
	for (int i = 0; i < src.rows; i++)
	for (int j = 0; j < src.cols; j++)
	for (int t = 0; t < 3; t++)
		src.at<Vec3f>(i, j)[t] = 255 * (src.at<Vec3f>(i, j)[t] - min[t]) / minmax[t];
	src.convertTo(src, CV_8UC1, 1);
	imshow("fog", src);
}
int main(int argc,char** argv[])
{
	//原理:S(x,y)= R(x,y)*L(x,y),其中,S(x,y)为你看到的图像,L(x,y)为光照,R(x,y)为物体的本质
	//什么叫增强?无非就是挖掘物体的本身,撇开这个L(x,y)的R(x,y)就是结果!!!
	//这里创建一个窗口作为主窗口
	namedWindow("fog", WINDOW_AUTOSIZE);
	
	//这里创建几个trackbar来便于观看不同权值下的效果
	//这里给出的滚动条的值是为了进行不同程度的自增从而实现不同程度的权值,主要是为了方便,方便,方便!!!
	//如果这里不进行自增而单纯的都赋值为0那就是SSR
	createTrackbar("rate1", "fog", &M1, 10, MSR);
	createTrackbar("rate2", "fog", &M2, 10, MSR);
	createTrackbar("rate3", "fog", &M3, 10, MSR);
	waitKey(0);




}

效果测试,如图



猜你喜欢

转载自blog.csdn.net/qq_37333087/article/details/80135506