一杯清酒邀明月
天下本无事,庸人扰之而烦耳。
输入:
Mat src = imread(“test.jpg”);

直方图均衡化

 1     Mat copy1;
 2     src.copyTo(copy1);
 3     Mat imageRGB[3];
 4     split(copy1, imageRGB);
 5     for (int i = 0; i < 3; i++)
 6     {
 7         equalizeHist(imageRGB[i], imageRGB[i]);
 8     }
 9     merge(imageRGB, 3, copy1);
10     imwrite("直方图均衡化.jpg", copy1);

对数变换

 1     Mat imageLog(src.size(), CV_32FC3);
 2     for (int i = 0; i < src.rows; i++)
 3     {
 4     for (int j = 0; j < src.cols; j++)
 5     {
 6     imageLog.at<Vec3f>(i, j)[0] = log(1 + src.at<Vec3b>(i, j)[0]);
 7     imageLog.at<Vec3f>(i, j)[1] = log(1 + src.at<Vec3b>(i, j)[1]);
 8     imageLog.at<Vec3f>(i, j)[2] = log(1 + src.at<Vec3b>(i, j)[2]);
 9     }
10     }
11     //归一化到0~255
12     normalize(imageLog, imageLog, 0, 255, CV_MINMAX);
13     //转换成8bit图像显示
14     convertScaleAbs(imageLog, imageLog);
15     imwrite("对数变换.jpg", imageLog);

拉普拉斯算子增强

1     Mat imageEnhance;
2     Mat kernel = (Mat_<float>(3, 3) << 0, -1, 0, 0, 5, 0, 0, -1, 0);
3     filter2D(src, imageEnhance, CV_8UC3, kernel);
4     imwrite("拉普拉斯1.jpg", imageEnhance);

伽马变换

 1     Mat imageGamma(src.size(), CV_32FC3);
 2     for (int i = 0; i < src.rows; i++)
 3     {
 4     for (int j = 0; j < src.cols; j++)
 5     {
 6     imageGamma.at<Vec3f>(i, j)[0] = (src.at<Vec3b>(i, j)[0])*(src.at<Vec3b>(i, j)[0])*(src.at<Vec3b>(i, j)[0]);
 7     imageGamma.at<Vec3f>(i, j)[1] = (src.at<Vec3b>(i, j)[1])*(src.at<Vec3b>(i, j)[1])*(src.at<Vec3b>(i, j)[1]);
 8     imageGamma.at<Vec3f>(i, j)[2] = (src.at<Vec3b>(i, j)[2])*(src.at<Vec3b>(i, j)[2])*(src.at<Vec3b>(i, j)[2]);
 9     }
10     }
11     //归一化到0~255
12     normalize(imageGamma, imageGamma, 0, 255, CV_MINMAX);
13     //转换成8bit图像显示
14     convertScaleAbs(imageGamma, imageGamma);
15     imwrite("伽马变换1.jpg", imageGamma);

Retinex(MSRCR)色彩均衡

  1 /*===========================================================
  2 * 函数:FastFilter
  3 * 说明:给出任意大小的sigma值,都可以通过使用图像金字塔与可分离滤波器计算高斯卷积;
  4 * 参数:
  5 *   IplImage *src: 输入图像
  6 *   double sigma: 高斯核标准偏差
  7 * --------------------------------------------------------
  8 * Summary:
  9 * Performs gaussian convolution of any size sigma very fast by using
 10 * both image pyramids and seperable filters.  Recursion is used.
 11 *
 12 * Arguments:
 13 * Mat src - Input Image.
 14 * Mat &dst - Output Image.
 15 * double sigma - the standard deviation of the gaussian kernel to use.
 16 =============================================================
 17 */
 18 void FastFilter(IplImage *img, double sigma)
 19 {
 20     int filter_size;
 21 
 22     // Reject unreasonable demands
 23     // 设置上限
 24     if (sigma > 300) sigma = 300;
 25 
 26     // get needed filter size (enforce oddness)
 27     // 获取需要的滤波尺寸,且强制为奇数;
 28     filter_size = (int)floor(sigma * 6) / 2;
 29     filter_size = filter_size * 2 + 1;
 30 
 31     // If 3 sigma is less than a pixel, why bother (ie sigma < 2/3)
 32     // 如果3 * sigma小于一个像素,则直接退出
 33     if (filter_size < 3) return;
 34 
 35     // Filter, or downsample and recurse
 36     // 处理方式:(1) 滤波  (2) 高斯光滑处理  (3) 递归处理滤波器大小
 37     if (filter_size < 10) {
 38 
 39 #ifdef USE_EXACT_SIGMA
 40         FilterGaussian(img, sigma);
 41 #else
 42         cvSmooth(img, img, CV_GAUSSIAN, filter_size, filter_size);
 43 #endif
 44 
 45     }
 46     else
 47     {
 48         if (img->width < 2 || img->height < 2) return;
 49         IplImage* sub_img = cvCreateImage(cvSize(img->width / 2, img->height / 2), img->depth, img->nChannels);
 50         cvPyrDown(img, sub_img);
 51         FastFilter(sub_img, sigma / 2.0);
 52         cvResize(sub_img, img, CV_INTER_LINEAR);
 53         cvReleaseImage(&sub_img);
 54     }
 55 }
 56 
 57 /*===========================================================
 58 * 函数:Retinex
 59 * 说明:单通道SSR方法,基础Retinex复原算法。原图像和被滤波的图像需要被转换到
 60 *   对数域,并做减运算;
 61 * 参数:
 62 *   Mat src: 输入图像
 63 *   Mat &dst: 输出图像
 64 *   double sigma: 高斯核标准偏差
 65 *   int gain: 图像像素值改变范围的增益
 66 *   int offset: 图像像素值改变范围的偏移量
 67 * --------------------------------------------------------
 68 * Summary:
 69 * Basic retinex restoration. The image and a filtered image are converted
 70 * to the log domain and subtracted.
 71 *
 72 * Arguments:
 73 * Mat src - Input Image.
 74 * Mat &dst - Output Image.
 75 * sigma - the standard deviation of the gaussian kernal used to filter.
 76 * gain - the factor by which to scale the image back into visable range.
 77 * offset - an offset similar to the gain.
 78 =============================================================
 79 */
 80 void Retinex(Mat src, Mat &dst, vector<double> sigma, int gain, int offset)
 81 {
 82     IplImage *tmp_ipl;
 83     tmp_ipl = &IplImage(src);
 84     IplImage *A, *fA, *fB, *fC;
 85 
 86     // Initialize temp images
 87     // 初始化缓存图像
 88     fA = cvCreateImage(cvSize(tmp_ipl->width, tmp_ipl->height), IPL_DEPTH_32F, tmp_ipl->nChannels);
 89     fB = cvCreateImage(cvSize(tmp_ipl->width, tmp_ipl->height), IPL_DEPTH_32F, tmp_ipl->nChannels);
 90     fC = cvCreateImage(cvSize(tmp_ipl->width, tmp_ipl->height), IPL_DEPTH_32F, tmp_ipl->nChannels);
 91 
 92     // Compute log image
 93     // 计算对数图像
 94     cvConvert(tmp_ipl, fA);
 95     cvLog(fA, fB);
 96 
 97     // Compute log of blured image
 98     // 计算滤波后模糊图像的对数图像
 99     A = cvCloneImage(tmp_ipl);
100     FastFilter(A, sigma[0]);
101     cvConvert(A, fA);
102     cvLog(fA, fC);
103 
104     // Compute difference
105     // 计算两图像之差
106     cvSub(fB, fC, fA);
107 
108     // Restore
109     // 恢复图像
110     cvConvertScale(fA, tmp_ipl, gain, offset);
111 
112     // Release temp images
113     // 释放缓存图像
114     cvReleaseImage(&A);
115     cvReleaseImage(&fA);
116     cvReleaseImage(&fB);
117     cvReleaseImage(&fC);
118     dst = cvarrToMat(tmp_ipl);
119 }
120 
121 int main()
122 {
123     Mat src = imread("test.jpg");
124     vector<double> sigema;
125     vector<double> weight;
126     for (int i = 0; i < 3; i++)
127     weight.push_back(1. / 3);
128     // 由于MSRCR.h中定义了宏USE_EXTRA_SIGMA,所以此处的vector<double> sigema并没有什么意义
129     sigema.push_back(30);
130     sigema.push_back(150);
131     sigema.push_back(300);
132     char key;
133     Mat img, imgdst;
134     src.copyTo(img);
135     Msrcr msrcr;
136     msrcr.Retinex(img, imgdst, sigema, 128, 128);
137     imwrite("Retinex.jpg", imgdst);
138 }

分段线性变换

 1 void ChangeValue(Mat &img)
 2 {
 3     int a = 50, b = 140, c = 30, d = 240;//变换范围
 4     for (int i = 0; i < img.rows; i++)
 5     {
 6         for (int j = 0; j > img.cols; j++)
 7         {
 8             uchar* data = (uchar*)img.data + i*img.cols;
 9             if (data[j] < a)
10                 data[j] = (c / a)*data[j];
11             else if (data[j] >= b)
12                 data[j] = ((255 - b) / (255 - d))*(data[j] - b) + d;
13             else
14                 data[j] = ((d - c) / (b - a))*(data[j] - a) + c;
15         }
16     }
17 }
18 
19 int main()
20 {
21     cvtColor(src, src, CV_RGB2GRAY);
22     ChangeValue(src);
23     imwrite("线性变换.jpg", src);
24 }

 

posted on 2022-02-23 16:11  一杯清酒邀明月  阅读(432)  评论(0编辑  收藏  举报