暗光图像增强—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版权协议,转载请附上原文出处链接和本声明。