一、颜色空间缩减
1、概念
如果图像是3通道,深度为1个字节,则每个像素有256*256*256种可能值,这么多的可能值会对算法性能造成严重影响。利用颜色空间缩减就能解决这个问题,例如将颜色值0~9取为新值0,10~19取为10,以此类推,这样每个像素有26*26*26种可能值,比上面的可能值要小很多。
2、公式
P_New = ( P_Old / divide ) * divide (P表示像素值)
3、处理
如果对原图像每个像素都进行上面的公式运算,运算量将非常大。可以将0~255这256种情况对应的新值计算出来,存放在table中,然后将原图像的像素值按照table表取出新值即可。
uchar table[256];
for( int i=0; i<256; i++ )
table[i] = ( i / divide ) * divide;
P_New = table[ P_New ];
4、LUT函数
OpenCV提供了LUT函数帮我们完成上面的处理。
示例:
1 Mat srcImage = imread("test.jpg");
2
3 Mat lookUpTable(1,256,CV_8U);
4 uchar* p = lookUpTable.data;
5 for(int i=0; i<256; i++)
6 {
7 p[i] = i/30*30;
8 }
9
10 Mat destImage;
11 destImage.create(srcImage.size(),srcImage.type());
12
13 LUT(srcImage,lookUpTable,destImage);
14
15 imshow("srcImage",srcImage);
16 imshow("destImage",destImage);
二、图像叠加
1 Mat srcImage = imread("E:\\CodeResource\\opencv\\car_pic\\test.jpg");
2 Mat logoImage = imread("E:\\CodeResource\\opencv\\car_pic\\logo.png");
3
4 //255或者1都行,只要非0就行
5 Mat mask(logoImage.size(),CV_8UC1,Scalar::all(255));
6 Rect r1(0,10,mask.cols,10);
7 mask(r1).setTo(0);
8
9 //设置感兴趣区域
10 Mat roiImage = srcImage(Rect(100, 100, logoImage.cols, logoImage.rows));
11 logoImage.copyTo(roiImage, mask);
12
13 imshow("srcImage", srcImage);
14 waitKey(0);
三、线性混合操作
1、概念
线性混合操作是一种典型的二元(两个输入)的像素操作,它的理论公式如下:
g(x) = (1-a)f1(x) + af2(x)
我们通过在范围0~1间改变alpha值,来对两幅图像产生时间上的叠加效果。
2、示例
1 //图像线性混合demo
2 Mat srcImage = imread("E:\\CodeResource\\opencv\\car_pic\\test.jpg");
3 Mat rainImage = imread("E:\\CodeResource\\opencv\\car_pic\\rain.bmp");
4
5 double alphaValue = 0.5;
6 double betaValue = (1.0 - alphaValue);
7
8 //两个叠加的图片大小需一样
9 Mat destImage = srcImage(Rect(0,0,rainImage.cols,rainImage.rows));
10
11 //alpha表示第一个数组的权重
12 //betaValue表示第二个数组的权重
13 //0.0表示加到权重总和上的标量值
14 addWeighted(destImage,alphaValue,rainImage,betaValue,0.0,destImage);
15
16 imshow("srcImage",srcImage);
四、通道分离和混合
1、概述
有时为了更好地分析图像,需要对图像的通道进行分别处理和调整,通过通道分离函数split和通道混合函数merge能够很方便地达到目的。
2、示例
1 //图像通道分离和混合demo
2 Mat srcImage = imread("E:\\CodeResource\\opencv\\car_pic\\test.jpg");
3
4 vector<Mat> channels;
5 //通道分离
6 split(srcImage, channels);
7 Mat imageDest = channels.at(1);
8 //通道混合
9 merge(channels, imageDest);
10
11 imshow("imageDest", imageDest);
五、图像对比度和亮度调整
1、算子
图像对比度和亮度调整的算子如下:
g(x) = a*f(x) + b
其中:
(1)f(x)表示源图像
(2)g(x)表示输出图像
(3)a称为增益(gain),用来控制图像的对比度
(4)b称为偏置(bias),用来控制图像的亮度
2、示例
1 #include <opencv/cv.h>
2 #include <opencv2/highgui.hpp>
3
4 using namespace cv;
5
6 #include <vector>
7 using namespace std;
8
9 int g_nConstrast;
10 int g_nBright;
11 Mat srcImage;
12 Mat dstImage;
13
14 void ShowResult()
15 {
16 for (int y = 0; y < srcImage.rows; y++)
17 {
18 for (int x = 0; x < srcImage.cols; x++)
19 {
20 for (int nChannel = 0; nChannel < 3; nChannel++)
21 {
22 dstImage.at<Vec3b>(y, x)[nChannel] =
23 saturate_cast<uchar>((g_nConstrast*0.01)*(srcImage.at<Vec3b>(y, x)[nChannel]) + g_nBright);
24 }
25 }
26 }
27 imshow("srcImage", srcImage);
28 imshow("dstImage", dstImage);
29 }
30
31 void OnConstrast(int nValue, void *)
32 {
33 g_nConstrast = nValue;
34 ShowResult();
35 }
36
37 void OnBright(int nValue, void *)
38 {
39 g_nBright = nValue;
40 ShowResult();
41 }
42
43 int main()
44 {
45 srcImage = imread("test.jpg");
46 dstImage.create(srcImage.size(), srcImage.type());
47
48 g_nConstrast = 100;
49 g_nBright = 0;
50
51 namedWindow("srcImage", 1);
52 namedWindow("dstImage",1);
53
54 createTrackbar("对比度:", "dstImage", &g_nConstrast, 300, OnConstrast);
55 createTrackbar("亮度:", "dstImage", &g_nBright, 300, OnBright);
56
57 ShowResult();
58
59 while (char(waitKey(1)) != 'q') {}
60 return 0;
61 }