暗光图像增强—opencv(C++)

暗光图像增强—opencv(C++)

code1

// An highlighted block
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <stdio.h>
#include<math.h>
using namespace cv;
using namespace std;
//图像的三个颜色通道
#define BLUE 	0	
#define GREEN	1
#define RED 	2

#ifndef SCREEN_XY
#define SCREEN_XY(x, y)  (255 - ((255 - (x))*(255 - (y)) >> 8))//将新的图层与原图做滤色混合
//x为原始图像像素值,y为新图层的像素值
#endif
double Transform(double x)
{
	if (x <= 0.05)return x * 2.64;
	return 1.099 * pow(x, 0.9 / 2.2) - 0.099;
}
struct zxy {
	double x, y, z;
}s[2500][2500];

Mat work(Mat input_img) {
	int rows = input_img.rows;
	int cols = input_img.cols;
	double r, g, b;
	double lwmax = -1.0, base = 0.75;
	for (int i = 0; i < rows; i++) {
		for (int j = 0; j < cols; j++) {
			b = (double)input_img.at<Vec3b>(i, j)[0] / 255.0;
			g = (double)input_img.at<Vec3b>(i, j)[1] / 255.0;
			r = (double)input_img.at<Vec3b>(i, j)[2] / 255.0;
			s[i][j].x = (0.4124 * r + 0.3576 * g + 0.1805 * b);
			s[i][j].y = (0.2126 * r + 0.7152 * g + 0.0722 * b);
			s[i][j].z = (0.0193 * r + 0.1192 * g + 0.9505 * b);
			lwmax = max(lwmax, s[i][j].y);
		}
	}
	for (int i = 0; i < rows; i++) {
		for (int j = 0; j < cols; j++) {
			double xx = s[i][j].x / (s[i][j].x + s[i][j].y + s[i][j].z);
			double yy = s[i][j].y / (s[i][j].x + s[i][j].y + s[i][j].z);
			double tp = s[i][j].y;
			//修改CIE:X,Y,Z
			s[i][j].y = 1.0 * log(s[i][j].y + 1) / log(2 + 8.0 * pow((s[i][j].y / lwmax), log(base) / log(0.5))) / log10(lwmax + 1);
			double x = s[i][j].y / yy * xx;
			double y = s[i][j].y;
			double z = s[i][j].y / yy * (1 - xx - yy);

			//转化为用RGB表示
			r = 3.2410 * x - 1.5374 * y - 0.4986 * z;
			g = -0.9692 * x + 1.8760 * y + 0.0416 * z;
			b = 0.0556 * x - 0.2040 * y + 1.0570 * z;

			if (r < 0)r = 0; if (r > 1)r = 1;
			if (g < 0)g = 0; if (g > 1)g = 1;
			if (b < 0)b = 0; if (b > 1)b = 1;

			//修正补偿
			r = Transform(r), g = Transform(g), b = Transform(b);
			
			input_img.at<Vec3b>(i, j)[0] = int(b * 255);
			input_img.at<Vec3b>(i, j)[1] = int(g * 255);
			input_img.at<Vec3b>(i, j)[2] = int(r * 255);
			
		} 
	}
	
	return input_img;
}
int main() {
	Mat src_1=imread("c:\\users\\fhgx\\desktop\\image\\1.jpg");
	imshow("原图", src_1);
	Mat out2;
	out2=work(src_1);
	imshow("增强后的图像1", out2);
	Mat out;
	medianBlur(out2, out, 5);
	imshow("滤波后的图像", out);
	waitKey();
	return 0;
}

结果:

 

code2

// An highlighted block
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <stdio.h>
#include<math.h>
using namespace cv;
using namespace std;
//图像的三个颜色通道
#define BLUE 	0	
#define GREEN	1
#define RED 	2

#ifndef SCREEN_XY
#define SCREEN_XY(x, y)  (255 - ((255 - (x))*(255 - (y)) >> 8))//将新的图层与原图做滤色混合
//x为原始图像像素值,y为新图层的像素值
#endif

Mat dark_light(Mat src)
{
	int size = src.cols * src.rows;//获取原图像的大小
	uchar r = 0, g = 0, b = 0, g_alpha = 0;//定义参数初始值
	uchar* pSrcData = src.data;//获取图图像的像素值
	for (int i = 0; i < size; i++, pSrcData += 3)//
	{
		//将绿色通道反色,与b、g、r通道分别相乘,得到新的图层颜色
		g_alpha = 255 - pSrcData[GREEN];//将绿色通道反色
		b = pSrcData[BLUE] * g_alpha >> 8;
		g = pSrcData[GREEN] * g_alpha >> 8;
		r = pSrcData[RED] * g_alpha >> 8;

		//将上个步骤得到的新图层,与原始图做滤色混合,即执行f(a,b)=1-(1-a)*(1-b)的操作
		pSrcData[BLUE] = SCREEN_XY(pSrcData[BLUE], b);
		pSrcData[GREEN] = SCREEN_XY(pSrcData[GREEN], g);
		pSrcData[RED] = SCREEN_XY(pSrcData[RED], r);
		//如果发现使用一次照度增强后,图片仍然偏暗,再运行一次上述代码
		//如果觉得合适,就只增强一次即可
		g_alpha = 255 - pSrcData[GREEN];
		b = pSrcData[BLUE] * g_alpha >> 8;
		g = pSrcData[GREEN] * g_alpha >> 8;
		r = pSrcData[RED] * g_alpha >> 8;

		pSrcData[BLUE] = SCREEN_XY(pSrcData[BLUE], b);
		pSrcData[GREEN] = SCREEN_XY(pSrcData[GREEN], g);
		pSrcData[RED] = SCREEN_XY(pSrcData[RED], r);
	}
	return src;
}

int main() {
	//方法一
	Mat src = imread("c:\\users\\fhgx\\desktop\\image\\1.jpg");
	imshow("原图", src);
	Mat out1=dark_light(src);
	imshow("增强后的图像", out1);
	Mat out;
	medianBlur(out1, out, 5);
	imshow("滤波后的图像", out);

	waitKey();
	return 0;
}

结果

code3

//=================================
/*
day:2021.5.20
低照度增强代码
*/
//=================================
#include <stdio.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc_c.h>
#include <iostream>
#include <math.h>
#include <vector>
#include <string.h>
#include <fstream>

using namespace cv;
using namespace std;


Mat ALTM(Mat src)
{
	//--------------------------------
	//计算Lwmax(亮度最大值)
	float Lwmax = 0;

	//将cv:Mat转换成const cvArr
	IplImage tmp = cvIplImage(src);;
	CvArr* arr = (CvArr*)&tmp;

	CvScalar scalar;	//scalar
	for (int i = 0; i <= src.rows - 1; ++i) {
		for (int j = 0; j <= src.cols - 1; ++j) {

			scalar = cvGet2D(arr, i, j);	//获取像素点的RGB颜色分量

			float Lw = 0.299f * scalar.val[2] + 0.587f * scalar.val[1] + 0.114f * scalar.val[0];

			if (Lw > Lwmax)
			{
				Lwmax = Lw;
			}

		}
	}
	//cout << "Lwmax:" << Lwmax << endl;

	//-------------------------------------------------
	//计算Lwaver(亮度平均)
	float Lwaver;
	float sum = 0;

	for (int i = 0; i <= src.rows - 1; ++i) {
		for (int j = 0; j <= src.cols - 1; ++j) {

			scalar = cvGet2D(arr, i, j);	//获取像素点的RGB颜色分量

			float Lw = 0.299f * scalar.val[2] + 0.587f * scalar.val[1] + 0.114f * scalar.val[0];

			sum += log(0.001f + Lw);
			//cout << "sum:" << sum << endl;
		}
	}
	sum /= src.cols * src.rows;
	//cout << "sum:" << sum << endl;
	Lwaver = exp(sum);

	//对原图进行计算,并输出结果
	Mat newImage;
	newImage.create(src.size(), src.type());

	//将cv:Mat转换成const cvArr
	IplImage tmpNew = cvIplImage(newImage);
	CvArr* arrNew = (CvArr*)&tmpNew;

	//设置容器存放RGB
	vector<Mat> channels;


	for (int i = 0; i <= src.rows - 1; ++i) {
		for (int j = 0; j <= src.cols - 1; ++j) {

			scalar = cvGet2D(arr, i, j);	//获取像素点的RGB颜色分量

			float Lw = 0.299f * scalar.val[2] + 0.587f * scalar.val[1] + 0.114f * scalar.val[0];

			float Lg = log(Lw / Lwaver + 1) / log(Lwmax / Lwaver + 1);
			//cout << "Lg:" << Lg << endl;
			float gain = Lg / Lw;
			//cout << "gain:" << gain << endl;
			scalar.val[2] = scalar.val[2] * gain * 255;//B
			scalar.val[1] = scalar.val[1] * gain * 255;//G
			scalar.val[0] = scalar.val[0] * gain * 255;//R

			//float max0,max1,max2;

			//Mat color = merge([B,G,R]);

			//将cv:Mat转换成const cvArr
			//IplImage tmpNew = IplImage(newImage);
			//CvArr* arrNew = (CvArr*)&tmpNew;

			cvSet2D(arrNew,i,j, scalar);

			//cout << "scalar.val[2]:" << scalar.val[2] << endl;
		}
	}


	Mat img = cv::cvarrToMat(arrNew);
	imshow("低照度图像增强结果", img);
	return img;
}

int main(int argc,char** argv)
{
    //提供了00和11两张图片,可以测试一下
	//Mat srcImage = imread("00.png", 1);
	Mat srcImage = imread("1.jpg", 1);
	if (srcImage.empty())
	{
		std::cout << "打开图片失败,请检查" << std::endl;
		return -1;
	}
	imshow("原图像", srcImage);

	//图片进行灰度化
	Mat greyImage;
	//cvtColor(srcImage, greyImage,CV_RGB2BGR);
	//imshow("灰度化", greyImage);

	//调用函数
	//ALTM(greyImage);
	ALTM(srcImage);
	//Mat dstIamge=ALTM(greyImage);
	//imshow("低照度增强", dstIamge);

	waitKey();
	return 0;
}

结果


版权声明:本文为weixin_44690935原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。