输入:
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 }