一、光照补偿
1.直方图均衡化
1 #include "stdafx.h"
2 #include<opencv2/opencv.hpp>
3 #include<iostream>
4 using namespace std;
5 using namespace cv;
6
7 int main(int argc, char *argv[])
8 {
9 Mat image = imread("D://vvoo//123.jpg", 1);
10 if (!image.data)
11 {
12 cout << "image loading error" <<endl;
13 return -1;
14 }
15 Mat imageRGB[3];
16 split(image, imageRGB);
17 for (int i = 0; i < 3; i++)
18 {
19 equalizeHist(imageRGB[i], imageRGB[i]);
20 }
21 merge(imageRGB, 3, image);
22 imshow("equalizeHist", image);
23 waitKey();
24 return 0;
25 }
2.gamma corection:
人眼是按照gamma < 1的曲线对输入图像进行处理的。
原图gamma=1.2ga=1.8ga=2.2ga=3.2
1 #include<opencv2/opencv.hpp>
2 #include<iostream>
3 using namespace std;
4 using namespace cv;
5 // Normalizes a given image into a value range between 0 and 255.
6 Mat norm(const Mat& src) {
7 // Create and return normalized image:
8 Mat dst;
9 switch (src.channels()) {
10 case 1:
11 cv::normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
12 break;
13 case 3:
14 cv::normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC3);
15 break;
16 default:
17 src.copyTo(dst);
18 break;
19 }
20 return dst;
21 }
22
23 int main()
24 {
25 Mat image,X,I;
26
27 VideoCapture cap(0);
28 while (1)
29 {
30 cap >> image;
31 image.convertTo(X, CV_32FC1); //转换格式
32 float gamma = 4;
33 pow(X, gamma, I);
34
35 imshow("Original Image", image);
36 imshow("Gamma correction image", norm(I));
37 char key = waitKey(30);
38 if (key=='q' )
39 break;
40 }
41 return 0;
42 }
3.拉普拉斯算子增强
1 int main(int argc, char *argv[])
2 {
3 Mat image = imread("D://vvoo//123.jpg", 1);
4 if (!image.data)
5 {
6 cout << "image loading error" <<endl;
7 return -1;
8 }
9 imshow("原图", image);
10 Mat imageEnhance;
11 Mat kernel = (Mat_<float>(3, 3) << 0, -1, 0, 0, 7, 0, 0, -1, 0);
12 filter2D(image, imageEnhance, CV_8UC3, kernel);
13 imshow("拉普拉斯算子图像增强效果", imageEnhance);
14 imwrite("C://Users//TOPSUN//Desktop//123.jpg",imageEnhance);
15 waitKey();
16 return 0;
17 }
效果不好
4.对数变换
对数图像增强是图像增强的一种常见方法,其公式为: S = c log(r+1),其中c是常数(以下算法c=255/(log(256)),这样可以实现整个画面的亮度增大此时默认v=e,即 S = c ln(r+1)。
如下图,对数使亮度比较低的像素转换成亮度比较高的,而亮度较高的像素则几乎没有变化,这样就使图片整体变亮。
1 int main(int argc, char *argv[])
2 {
3 double temp = 255 / log(256);
4 cout << "doubledouble temp ="<< temp<<endl;
5
6 Mat image = imread("D://vvoo//123.jpg", 1);
7 if (!image.data)
8 {
9 cout << "image loading error" <<endl;
10 return -1;
11 }
12 imshow("原图", image);
13 Mat imageLog(image.size(), CV_32FC3);
14 for (int i = 0; i < image.rows; i++)
15 {
16 for (int j = 0; j < image.cols; j++)
17 {
18 imageLog.at<Vec3f>(i, j)[0] = temp* log(1 + image.at<Vec3b>(i, j)[0]);
19 imageLog.at<Vec3f>(i, j)[1] = temp*log(1 + image.at<Vec3b>(i, j)[1]);
20 imageLog.at<Vec3f>(i, j)[2] = temp*log(1 + image.at<Vec3b>(i, j)[2]);
21 }
22 }
23 //归一化到0~255
24 normalize(imageLog, imageLog, 0, 255, CV_MINMAX);
25 //转换成8bit图像显示
26 convertScaleAbs(imageLog, imageLog);
27 int channel = image.channels();
28 cout << channel << endl;
29 imshow("Soure", image);
30 imshow("after", imageLog);
31 imwrite("C://Users//TOPSUN//Desktop//123.jpg", imageLog);
32 waitKey();
33 return 0;
34 }
二、去除光照
5.RGB归一化
据说能消除光照,自己实现出来好垃圾啊
1 int main(int argc, char *argv[])
2 {
3 //double temp = 255 / log(256);
4 //cout << "doubledouble temp ="<< temp<<endl;
5
6 Mat image = imread("D://vvoo//sun_face.jpg", 1);
7 if (!image.data)
8 {
9 cout << "image loading error" <<endl;
10 return -1;
11 }
12 imshow("原图", image);
13 Mat src(image.size(), CV_32FC3);
14 for (int i = 0; i < image.rows; i++)
15 {
16 for (int j = 0; j < image.cols; j++)
17 {
18 src.at<Vec3f>(i, j)[0] = 255 * (float)image.at<Vec3b>(i, j)[0] / ((float)image.at<Vec3b>(i, j)[0] + (float)image.at<Vec3b>(i, j)[2] + (float)image.at<Vec3b>(i, j)[1]+0.01);
19 src.at<Vec3f>(i, j)[1] = 255 * (float)image.at<Vec3b>(i, j)[1] / ((float)image.at<Vec3b>(i, j)[0] + (float)image.at<Vec3b>(i, j)[2] + (float)image.at<Vec3b>(i, j)[1]+0.01);
20 src.at<Vec3f>(i, j)[2] = 255 * (float)image.at<Vec3b>(i, j)[2] / ((float)image.at<Vec3b>(i, j)[0] + (float)image.at<Vec3b>(i, j)[2] + (float)image.at<Vec3b>(i, j)[1]+0.01);
21 }
22 }
23
24 normalize(src, src, 0, 255, CV_MINMAX);
25
26 convertScaleAbs(src,src);
27 imshow("rgb", src);
28 imwrite("C://Users//TOPSUN//Desktop//123.jpg", src);
29 waitKey(0);
30 return 0;
31 }
6.另一种去除光照的方法
1 void unevenLightCompensate(Mat &image, int blockSize)
2 {
3 if (image.channels() == 3) cvtColor(image, image, 7);
4 double average = mean(image)[0];
5 int rows_new = ceil(double(image.rows) / double(blockSize));
6 int cols_new = ceil(double(image.cols) / double(blockSize));
7 Mat blockImage;
8 blockImage = Mat::zeros(rows_new, cols_new, CV_32FC1);
9 for (int i = 0; i < rows_new; i++)
10 {
11 for (int j = 0; j < cols_new; j++)
12 {
13 int rowmin = i*blockSize;
14 int rowmax = (i + 1)*blockSize;
15 if (rowmax > image.rows) rowmax = image.rows;
16 int colmin = j*blockSize;
17 int colmax = (j + 1)*blockSize;
18 if (colmax > image.cols) colmax = image.cols;
19 Mat imageROI = image(Range(rowmin, rowmax), Range(colmin, colmax));
20 double temaver = mean(imageROI)[0];
21 blockImage.at<float>(i, j) = temaver;
22 }
23 }
24 blockImage = blockImage - average;
25 Mat blockImage2;
26 resize(blockImage, blockImage2, image.size(), (0, 0), (0, 0), INTER_CUBIC);
27 Mat image2;
28 image.convertTo(image2, CV_32FC1);
29 Mat dst = image2 - blockImage2;
30 dst.convertTo(image, CV_8UC1);
31 }
32 int main(int argc, char *argv[])
33 {
34 //double temp = 255 / log(256);
35 //cout << "doubledouble temp ="<< temp<<endl;
36
37 Mat image = imread("C://Users//TOPSUN//Desktop//2.jpg", 1);
38 if (!image.data)
39 {
40 cout << "image loading error" <<endl;
41 return -1;
42 }
43 imshow("原图", image);
44 unevenLightCompensate(image, 12);
45 imshow("rgb", image);
46 imwrite("C://Users//TOPSUN//Desktop//123.jpg", image);
47 waitKey(0);
48 return 0;
49 }
7.又找到一个
1 int highlight_remove_Chi(IplImage* src, IplImage* dst)
2 {
3 int height = src->height;
4 int width = src->width;
5 int step = src->widthStep;
6 int i = 0, j = 0;
7 unsigned char R, G, B, MaxC;
8 double alpha, beta, alpha_r, alpha_g, alpha_b, beta_r, beta_g, beta_b, temp = 0, realbeta = 0, minalpha = 0;
9 double gama, gama_r, gama_g, gama_b;
10 unsigned char* srcData;
11 unsigned char* dstData;
12 for (i = 0; i<height; i++)
13 {
14 srcData = (unsigned char*)src->imageData + i*step;
15 dstData = (unsigned char*)dst->imageData + i*step;
16 for (j = 0; j<width; j++)
17 {
18 R = srcData[j * 3];
19 G = srcData[j * 3 + 1];
20 B = srcData[j * 3 + 2];
21
22 alpha_r = (double)R / (double)(R + G + B);
23 alpha_g = (double)G / (double)(R + G + B);
24 alpha_b = (double)B / (double)(R + G + B);
25 alpha = max(max(alpha_r, alpha_g), alpha_b);
26 MaxC = max(max(R, G), B);// compute the maximum of the rgb channels
27 minalpha = min(min(alpha_r, alpha_g), alpha_b); beta_r = 1 - (alpha - alpha_r) / (3 * alpha - 1);
28 beta_g = 1 - (alpha - alpha_g) / (3 * alpha - 1);
29 beta_b = 1 - (alpha - alpha_b) / (3 * alpha - 1);
30 beta = max(max(beta_r, beta_g), beta_b);//将beta当做漫反射系数,则有 // gama is used to approximiate the beta
31 gama_r = (alpha_r - minalpha) / (1 - 3 * minalpha);
32 gama_g = (alpha_g - minalpha) / (1 - 3 * minalpha);
33 gama_b = (alpha_b - minalpha) / (1 - 3 * minalpha);
34 gama = max(max(gama_r, gama_g), gama_b);
35
36 temp = (gama*(R + G + B) - MaxC) / (3 * gama - 1);
37 //beta=(alpha-minalpha)/(1-3*minalpha)+0.08;
38 //temp=(gama*(R+G+B)-MaxC)/(3*gama-1);
39 dstData[j * 3] = R - (unsigned char)(temp + 0.5);
40 dstData[j * 3 + 1] = G - (unsigned char)(temp + 0.5);
41 dstData[j * 3 + 2] = B - (unsigned char)(temp + 0.5);
42 }
43 }
44 cvShowImage("src", src);
45 cvShowImage("dst", dst);
46
47 return 1;
48 }
49
50 void main()
51 {
52 IplImage *src = cvLoadImage("C://Users//TOPSUN//Desktop//2.jpg");
53 IplImage *dst = cvCreateImage(cvSize(src->width, src->height), src->depth, 3);
54 if (!src)
55 {
56 printf("请确保图像输入正确;");
57 return;
58 }
59 highlight_remove_Chi(src, dst);
60 cvSaveImage("C://Users//TOPSUN//Desktop//123.jpg", dst);
61 cvWaitKey(0);
62 }