OpenCV 光照补偿和去除光照


一、光照补偿

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 }

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM