opencv之光照补偿和去除光照

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:

 

http://www.cambridgeincolour.com/tutorials/gamma-correction.htm

人眼是按照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. }

 

 

未完待续。。。

 

  • 0
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
去除图像的光照不均,可以使用一些图像处理技术。首先,你需要加载OpenCV-Python模块。可以使用pip进行安装,命令如下: ``` pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python ``` 安装完成后,可以使用以下步骤去除图像的光照不均: 1. 加载图像:使用`cv2.imread()`函数加载图像文件。 2. 将图像转换为灰度图像:使用`cv2.cvtColor()`函数将彩色图像转换为灰度图像。 3. 去除光照不均:有多种方法可以去除光照不均,一种常用的方法是使用自适应阈值处理。可以使用`cv2.adaptiveThreshold()`函数进行自适应阈值处理,通过调整参数来适应不同的图像。 4. 显示处理后的图像:使用`cv2.imshow()`函数显示处理后的图像。 下面是示例代码: ```python import cv2 # 加载图像 img = cv2.imread('image.jpg') # 转换为灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 去除光照不均 # 使用自适应阈值处理 adaptive_threshold = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2) # 显示处理后的图像 cv2.imshow('Processed Image', adaptive_threshold) cv2.waitKey(0) cv2.destroyAllWindows() ``` 这样就可以去除图像的光照不均了。你可以根据需要调整自适应阈值处理的参数,以达到更好的效果。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [jetson nano opencv 打开 CSI摄像头_opencv-python图形图像处理入门基础知识](https://blog.csdn.net/weixin_39775354/article/details/110121584)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [opencv-python图形图像处理入门基础知识](https://blog.csdn.net/LaoYuanPython/article/details/108015331)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值