《OpenCV3编程入门-毛星云》第二部分 初探core组件

平台:Win7 64bits + Visual Studio 2012 + OpenCV 2.4.10


童鞋们,我们继续翻目录,哈哈哈

当然我不是翻目录,我是真的已经一字一句看过了,我自认为C语言基础还是很好的,代码方面可以看得很快。但是算法方面有点吃力。

下面红色文字是我自己的总结!


第二部分 初探core组件 83


第4章 OpenCV数据结构与基本绘图 85

4.1 基础图像容器Mat 86

4.1.1 数字图像存储概述 86

4.1.2 Mat结构的使用 86

OpenCV 1.x版本用IplImage作为图像存储结构体,OpenCV 2.0开始引入C++类,封装了Mat图像数据结构。

Mat类的好处,不必再手动为其开辟空间,不必再在不需要时立即释放,自动开辟自动释放。

浅拷贝: 拷贝构造函数 或者 赋值构造函数

深拷贝:clone() / copyTo()

4.1.3 像素值的存储方法 88

RGB:三原色

HSV/HLS:色调、饱和度和亮度/明度

4.1.4 显式创建Mat对象的七种方法 89

4.1.5 OpenCV中的格式化输出方法 91

cout << format(r, "python/csv/numpy/C/") << endl;

关键是format函数

4.1.6 输出其他常用数据结构 94

4.1.7 示例程序:基础图像容器Mat类的使用 95

4.2 常用数据结构和函数 95

4.2.1 点的表示:Point类 96

Point_<int> / Point2i / Point 互相等价;Point_<float> / Point2f 互相等价

4.2.2 颜色的表示:Scalar类 96

注意颜色顺序:Scalar(B, G, R);

4.2.3 尺寸的表示:Size类 96

尺寸就是宽度和高度,Size_<int> / Size2i / Size 三个类型名等价

4.2.4 矩形的表示:Rect类 97

Rect四个数据成员:x, y, width, height,分别为左上角点的坐标和整个矩形的宽高。

方法成员:Size()-宽高 / area()-面积 / tl()-左上角点坐标 / br()-右下角点坐标。

矩形交集:Rect rect = rect1 & rect2;

矩形并集:Rect rect = rect1 | rect2;

4.2.5 颜色空间转换:cvtColor()函数 98

函数原型:void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0)

案例:cvtColor(srcImage, DstImage, CV_BGR2GRAY);

强调:OpenCV默认的图片通道存储顺序是BGR,即蓝绿红,而不是RGB。

4.2.6 其他常用的知识点 100

4.3 基本图形的绘制 100

4.3.1 DrawEllipse()函数的写法 101

画椭圆,给定参数:椭圆中心点,矩形区域,旋转角度,线色,线宽,线型

4.3.2 DrawFilledCircle()函数的写法 102

画圆,给定参数:圆中心点,半径,线色,线宽(如果是-1,则圆是实心圆),线型

4.3.3 DrawPolygon()函数的写法 102

画多边形,给定参数:顶点集合,顶点数量,多边形数量,线色,线型

4.3.4 DrawLine()函数的写法 103

画线,给定参数:起点,终点,线色,线宽,线型

4.3.5 main函数的写法 104

应用实例,可以直接运行玩下效果先

4.4 本章小结 106



第5章 core组件进阶 107

5.1 访问图像中的像素 108

5.1.1 图像在内存之中的存储方式108

强调:OpenCV默认的图片通道存储顺序是BGR,即蓝绿红,而不是RGB。

注意图像在内存里面的阵列,首先有像素行列,然后每个像素还有多个通道。比如BGR三个通道的图像占内存,3*W*H Byte。

5.1.2 颜色空间缩减 108

一般用查表法

5.1.3 LUT函数:Look uptable操作 109

5.1.4 计时函数 110

getTickCount():CPU自开机后运行的时钟周期总数

getTickFrequency():CPU一秒钟花费的时钟周期数

5.1.5 访问图像中像素的三类方法110

a. 指针或者下标访问[]

uchar *data = outputImage.ptr<uchar>(i);   //获取第i行的首地址

data[j]或者*(data+j)

b. 迭代器iterator

Mat_<Vec3b>::iterator it = outputImage.begin<Vec3b>(); //将迭代器指向初始位置

(*it)[0]

(*it)[1]

(*it)[2]

c. 动态地址计算

outputIMage.at<Vec3b>(w, h)[0]--B

outputIMage.at<Vec3b>(w, h)[1]--G

outputIMage.at<Vec3b>(w, h)[2]--R

Vec3b,是由三个unsigned char组成的向量


5.1.6 示例程序 114

5.2 ROI区域图像叠加&图像混合 114

5.2.1 感兴趣区域:ROI 115

Region Of Interest:划出我们重点关注的区域

矩形法:imageROI = image(Rect(500, 250, logo.cols, logo.rows);

行列法:imageROI = image(Range(250, 250+logo.rows), Range(200, 200+logo.cols));

这个功能可以用来给图片加水印,呵呵。还有运动轨迹跟踪时,圈出跟踪目标。

5.2.2 线性混合操作 116

画面叠加、影片转场

5.2.3 计算数组加权和:addWeighted()函数 117

加权:dst = src1[I] * alpha + src2[I] * beta + gamma; 

gamma先不管, alpha + beta = 1,哪个值更大,哪张图片更清楚。

5.2.4 综合示例:初级图像混合120

结合ROI和addWeighted(),就可以加半透明的水印啦,哈哈

5.3 分离颜色通道、多通道图像混合 125

5.3.1 通道分离:split()函数 125

vector<Mat> channels;

split(srcImage, channels);

imageROI = channels.at(0);//BGR,at(0)就是蓝色通道数据

5.3.2 通道合并:merge()函数 126

split的逆操作

5.3.3 示例程序:多通道图像混合127

5.4 图像对比度、亮度值调整 131

5.4.1 理论依据 131

g(x) = a * f(x) + b

f(x)是源图像,g(x)是输出图像,a是增益(控制对比度,0.0-3.0),b是偏置(控制亮度)

5.4.2 访问图片中的像素 131

5.1.5章节中已经讲过了,为什么又要讲一遍!

5.4.3 示例程序:图像对比度、亮度值调整 132

两个滑动条,分别调整图片的对比度和亮度

5.5 离散傅里叶变换 135

5.5.1 离散傅里叶变换的原理135

将图像从空间域转换到频域。

在频域里,高频部分代表图像的细节、纹理信息;低频部分代表图像的轮廓信息。

傅里叶变换在图像处理中可以做到图像增强与图像去噪、图像分割之边缘检测、图像特征提取、图像压缩等

5.5.2 dft()函数详解 136

函数作用:对一维或二维浮点数数组进行正向或反向离散傅里叶变换。

例程看不懂,不知道目的是什么

5.5.3 返回DFT最优尺寸大小:getOptimalDFTSize()函数 137

计算DFT变换的尺寸

dftSize.width = getOptimalDFTSize(A.cols + B.cols - );

dftSize.height = getOptimalDFTSize(A.rows + B.rows -1);

getOptimalDFTSize函数返回给定向量尺寸的傅里叶最有尺寸大小。为了提高离散傅里叶变换的运行速度,需要扩充图像,而具体扩充多少,由此得到。

5.5.4 扩充图像边界:copyMakeBorder()函数 137

结合getOptimalDFTSize使用,将待处理图像扩充到最优尺寸,并初始化像素值

5.5.5 计算二维矢量的幅值:magnitude()函数 138

5.5.6 计算自然对数:log()函数 138

5.5.7 矩阵归一化:normalize()函数 138

5.5.8 示例程序:离散傅里叶变换139

程序看得懂,但是不知道目的是要干嘛嘞?!

5.6 输入输出XML和YAML文件 144

5.6.1 XML和YAML文件简介 144

XML——eXtensible Markup Language 可扩展标记语言

我知道它可以用来保存人脸识别的训练文件

5.6.2 FileStorage类操作文件的使用引导 144

负责XML文件的读写工作

5.6.3 示例程序:XML和YAML文件的写入 147

5.6.4 示例程序:XML和YAML文件的读取 148

5.7 本章小结 150



终于复习完了!
其实我是每次正在看当前的部分,同时写前一部分的文章,相当于我在复习前面的知识。

也就是说,此时我正在看本书第三部分的内容,同时在写本文——第二部分。
好了,我继续第三部分的学习了!!!
加油!

猜你喜欢

转载自blog.csdn.net/linqianbi/article/details/79166430