一、光照补偿
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.2
ga=1.8
ga=2.2
ga=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 }