• 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 }

  • 相关阅读:
    Bitstream or PCM?
    centos7安装Redis-3.2.8
    【生肉】【不义联盟
    ES6中Map数据结构学习笔记
    机器学习基石入门
    2019/5/9 长难句
    文件遍历选取脚本
    [JS奇怪的世界]No.55 危險小叮嚀:陣列與for in
    OpenGL Panorama Player
    吴裕雄--天生自然MySQL学习笔记:MySQL 连接
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/15698976.html
Copyright © 2020-2023  润新知