OpenCV3编程入门-读书笔记2-core组件

一、颜色空间缩减

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 }

 

posted @ 2017-08-03 18:16  pinhole  阅读(361)  评论(0编辑  收藏  举报