我写的 openCV 图像深度学习教程
我写的 openCV 图像深度学习教程
作者:吴甜甜 个人博客网站:wutiantian.github.io —
官方资料
官方地址
官方主页 | openCV Github主页 | 官方论坛 | 中文openCV论坛,于仕琪 |
http://opencv.org | https://github.com/opencv | https://answers.opencv.org/questions/ | http://www.opencv.org.cn |
我的学习书籍
2014年-2016年 | 学习的 | 纸质书 |
---|---|---|
《学习OpenCV》于仕琪 译 | 《OpenCV3编程入门》毛星云 | 《数字图像处理》冈萨雷斯 |
随着时间推移,更多版本迭代,电子与纸质资源增加,请观看者以自身实时状况选择合适资料。
学习资料的使用
书籍的使用
-
《OpenCV3编程入门》毛星云,这本书的前半部分是能够帮助新手快速把程序跑起来,到中后期的话,基本没什么用,内容不多。【短期浏览】
-
《学习OpenCV》于仕琪 译,这本书像砖头的大小,刚开始不要硬啃。拿到手看看目录,随意翻翻。到中后期,遇到原理性问题(非实际程序运行的非具体问题),需要查看原理,需要研读。【中期阅读】
-
《数字图像处理》冈萨雷斯,这本书前期老师上课讲一讲,学生随便听一听。后期关于业务的本质,解决问题思路的锤炼,需要仔细明白现象本质时需要研读。 【长期阅读】
书是让我们缩短做笔记的时间,可以将自己的笔记直接记录在对应章节备查!
电子书的使用
Learning OpenCV_3rd.pdf 电子书关键字查询
官方API手册https://docs.opencv.org/
网站 https://docs.opencv.org/
下载压缩包,解压后,找到 “index.html”文件即可打开总目录进行查询
营利性性教学视频
营利性的视频往往课时较多,且不会直击要点。
当资源较全较优质可选择、内容较多的情况下,获得知识的速度是:PPT>视频>书。
觉得有用、有时间就看视频,没有时间就看PPT及代码。
把书上的东西转变为自己能够理解的内容,需要时间与精力。视频讲解就是引导我们来理解书上的内容,简化了时间与精力。这也是为什么视频需要花钱购买。如果自己能够直接看书理解,大部分人应该是不会去花这部分钱购买课程的。
如果看视频有不明白的地方,那么有以下几种情况:(1)讲课者能力水平有限,不能在有限时间内把书上内容说明白,甚至把内容像翻译外文书一样翻译错误。这时候可以通过学生提问来解决或者自己找原书来看网上搜索等。(2)知识交叉部分淡薄,例如需要3根鸡腿能饱,但是手头只有1根鸡腿,那么就需要去寻找3根以上鸡腿才行。解决方法基本上是继续(被收割韭菜)买视频或者自己下苦功去把交界处的内容索性再多学一点,不要抱着侥幸心理。
官方学习课程https://courses.learnopencv.com
开源教学项目
https://www.pyimagesearch.com/ 国外的opencv教学网站,有简易答题卡识别
环境搭建
此处,我以 “编译平台 VS2017 + 开源计算机视觉库 openCV4 + 插件 ImageWatch”为例
- 为什么选择“Visual studio”?
为 Windows 下用户设计程序,所以用“微软”公司自家的软件比较专业,同平台调试更直接方便。windows 操作系统是能把“简单的事情变得更简单”,所以适合轻量级的应用程序开发。
VS2017软件安装(不占用C盘空间方法)
Visual studio2017是稳定的编译运行C++环境。尽管2019年出了新款,但是有较多幺蛾子。
然而官网的2017只提供在线下载方式,导致下载的缓存都在C盘!
第一步:下载软件安装程序Visual Studio Installer
平常的安装方式,不论是在线安装还是下载的离线安装包,都会在安装过程中将vs2017的安装包保存在C:\ProgramData\Microsoft\VisualStudio\Packages
文件夹下并占用大量的空间(安装多少,占用多少,即使你不将VS装在C盘)。
下载地址:https://www.jb51.net/softs/539119.html
脚本之家:微软Visual Studio 2017正式版 15.8 (专业版) 官方简体中文版(附序列号)
软件大小:1.09MB
注意:安装好后,仍然不要删除Visual Studio Installer,因为后面如果装“组件”出现问题还得靠它打补丁! 第二步:打开vs_professional.exe 打开这个文件,会自动的在系统上安装一个Visual Studio Installer。打开vs_professional.exe,程序运行到这一步就把程序关掉。
关闭后,会在C:\ProgramData\Microsoft\VisualStudio下创建一个Packages。
第三步:删除多余的文件 把这个Packages文件夹删掉(如果不删除,否则创建软链接时会报错:当文件已存在时,无法创建该文件)。
第四步:新建文件夹,再创建软连接
新建文件夹用来存储软件缓存包 D:\vs2017offline
以管理员身份打开命令提示符cmd,运行下边代码。注意(D:\vs2017offline 是你下载的那个文件夹的位置。)
mklink /D C:\ProgramData\Microsoft\VisualStudio\Packages D:\vs2017offline
如果输入命令正确,会提示 为C:\ProgramData\Microsoft\VisualStudio\Packages <<===>> D:\vs2017offline 创建的符号链接
第五步:安装vs2017
</h4><p>之前安装了一个 Visual Studio Installer ,打开这个软件,就可以安装自己想要的功能了。安装时所有需要的组件都会秒下载,并且不会占用C盘的空间</p>
注意:安装过程中,你可能还会不放心,去看看C:\ProgramData\Microsoft\VisualStudio下面有没有文件占用,此时右击文件夹属性会显示软链接地址,就对了。你可能还会疑惑旁边怎么有700KB的
`C:\ProgramData\Microsoft\VisualStudio\Setup`
正常的,不用担心,就这么个大小不会变。
注意:在Visual Studio的勾选 默认安装的情况下,有文件默认是没有勾选的,也就是默认不安装的。 如果不勾选,C++文件编译时会一堆报错! 第六步:激活KEY:KBJFW-NXHK6-W4WJM-CRMQB-G3CDH
注意:安装好后的C盘仍然会有42MB的内容,千万不要删除,新建工程会报错!
vs2017需要联网安装,有的时候还可能要重装系统
openCV4安装的过程->自解压程序
opencv各个版本之间的选择
opencv是开源库文件,有社区在定期维护与增加内容。库文件是可以个人修改的,原则上不是有太大影响,但使用的各种编译软件经常升级会导致旧版本不再维护,所以最好还是和软件一样使用较新的稳定版本。
opencv4 里面的 include 头包含文件下只有一个文件夹:opencv2,也就是没有再增加头文件的内容,保持2版本状态。
通过 opencv 各个版本的推出,目录文件的命名,可以看出时代需求的变化越来越追求技术落地。 例如到opencv410版本时,目录源码有 C++、java、python 三种语言格式 。
opencv库的文件夹内容
openCV文件夹下
build | 预编译文件 | ||||
bin | |||||
etc | |||||
include | 类库头文件 | 【1】 | 在VS中配置环境时需要 | ||
java | |||||
python | |||||
x86 | vc15 | bin | dll 动态库文件 | 【2】 | |
代表 Microsoft Visual Studio2017 | lib | 静态库文件 | 【3】 | ||
sources | 源代码文件 |
vc11表示VS2012;vc14表示VS2015。
openCV环境文件【三构建】
将3个文件放到新建文件夹“openCV xxx”中。假设【三构建】文件夹路径为 D:/opencv/opencv400
环境变量配置
- 立即生效法
openCV 自构建的 bin 文件下的 dll 文件直接拷贝,放置到 c :/windows/syswow64 或者 C:\Windows\System32 (我64位机VS选择64的Debug模式是需要放置到该文件夹下才生效!)
- 重启生效法 配置 bin文件的 PATH 路径 。
属性管理器【三添加】
每次新建工程都要重新配置,其实不用这样麻烦,可以一劳永逸。
(1)新建项目:打开 VS ,文件 -> 新建 -> 项目 -> 空项目。
(2)新建cpp源文件:源文件->添加->新建项->C++文件->添加
(3)菜单栏属性配置:视图->属性管理器
注意:首次需要2次配置属性【三修改】分别在菜单的属性管理器、项目的属性。
在属性管理器中进行第一次配置,就相当于进行了通用的配置过程。
【1】include文件配置
解决方案的项目名,右击属性 -> VC++ 目录 -> 包含目录 ->添加” D:/opencv/opencv400/include;”
【2】lib库目录配置
解决方案的项目名,右击属性 -> VC++ 目录 -> 库目录 ->添加” D:/opencv/opencv400/lib;”
【3】链接器配置
解决方案的项目名,右击属性 -> 链接器 -> 输入 -> 附加依赖项 ->添加 lib的 debug 项目“opencv_ts300d.lib;opencv_world300d.lib”
以上三步修改后,修改行均会变粗并且加黑,以方便识别。
以上三步的配置路径可能因为复制路径而产生错误,请用鼠标点击设置添加文件夹方式层层选择进入到目录下!
为了方便与书中同步,因为书中的旧版本项目文件多,用来完整阐述,请读者安装最新版本时做适当的知识迁移,或者观看我的 B 站免费视频讲解。
备查的附加说明(可不看)
“包含目录”与“附加包含目录”的区别是:全局还是当前
-
“VC++目录” 设置“包含目录”:全局设置,对所有项目默认生效。
-
“连接器”->“常规”->“附加包含目录”:用于当前项目,对其他项目没有影响。
当需要对某工程添加目录时,通常情况下,都是在“附加包含目录”和“附加库”中添加的。
【三修改】的应用:如何使用一个库
- 附加包含目录->添加工程的头文件目录
项目->属性->配置属性->c/c++->常规->附加包含目录:加上头文件的存放目录。
- 附加库目录->添加文件引用的 lib 静态库路径
项目->属性->配置属性->链接器->常规->附加包含目录:加上 lib 文件的存放目录
- 附加依赖项->添加工程引用的 lib 文件名
项目->属性->配置属性->链接器->输入->附加依赖项:加上 lib 文件名
当需要向项目中添加 .dll动态库时,将需要添加的 .dll文件拖拽到项目生成的 .exe 所在的文件夹即可。【优先采用统一目录下面的 dll 文件】
项目->属性->配置属性->链接器->常规->输出目录,可以查看 exe 生成在哪个目录下。
Debug 调试版本 与 Release发布版本
Debug 调试版本 与 Release发布版本 的区别在于:是否含有调试信息。 |Debug|Release| |:—:|:—:| |包含调试信息,并且不作任何优化,便于程序员调试程序。|代码最小和运行速度最快,以便用户很好地使用。|
注意:VS2017 菜单栏下有“解决方案配置”,注意F5运行时,选择“Debug”模式。
lib下的文件 |||| |—|—|—| |opencv_ts300.lib|8,664kB|没有加d| |opencv_ts300d.lib|11,764kB|加“d”是debug项目里的| |opencv_world300.lib|1,661kB| |opencv_world300d.lib|1,666kB|
注意openCV3以后把”d”文件合并到一个文件里面了。
微软图像插件 ImageWatch
可用于调试时显示和监视图像变量。
VS2017菜单栏:工具->扩展和更新->联机->搜索:Image Watch 2017
组件大小:1.3MB
下载好后,关闭 VS2017 软件就能自动安装。
下载 Error 报错:如果无法安装组件,用 Visual Studio Installer 安装程序的“自动修复”功能,自动打补丁!
常见编译错误及解决思路
在编程中,经常会出现各种错误。出现错误后,不要闭眼抱头作痛苦状。
出现错误后,需要做的第一件事情是阅读出错信息。出错信息虽然看似凌乱,但是能够提供很多有价值的信息,帮你解决问题。
报错类型 | 原因 | 备注 | 典型错误 |
---|---|---|---|
找不到头文件 | (1)头文件的文件名拼写错误; (2)未将头文件所在路径添加到开发环境中 |
(1)从别的地方复制过来的时候,因为字符编码的问题,一样会造成很多未定义的问题 (2)项目-属性-CV++目录:注意上方的平台是否选错,设置后再设置包含路径 |
找不到core.h |
拼写错误 | (1)编写不仔细 (2)语法规则 |
(1)比如拼写错误、漏了半个括号、漏了分号等。 (2)源代码不符合语法规则,则会造成编译错误。 |
|
链接错误 | unresolved external symbol无法解析外部命令 | “链接器”依赖的库文件添加项目设置 | |
运行时错误 | 比较常见的运行时错误是内存错误。 | 在程序编写中,对于数组和指针等,要特别地小心。因为对于空指针以及数组越界等问题,编译器无法在编译时给出错误提示。这类错误一旦在运行时发生,排除起来非常困难。 |
为什么要一边学一遍敲代码
学习一种编程技术,我们可能买纸质书、搜索网页教程、听老师讲课(算法原理)、上机实验(调参)、做作业等等。
我想谈下我在学习新编程技术的时候为什么要敲代码。
我个人觉得“敲代码”和“推导算法公司”都是一样的,都是加强理解
我只是个普通人,不是天生就会所有内容的。我也需要像机器一样去学习,给一串命令,然后吃进不同的数据,去通过大数据分析对比得出自己需要的公式,以保证我在下一次任务来临时能够得到自己想要的结果。
-
敲代码是需要时间的。而且这时间里可能有大量都是无效的,可能是在试错,把自己可能犯的错误都试一遍。
-
这里面可能有字母敲错了,大小写问题,当然这些问题一定会随着犯错的增多而长记性在之后的练习中避免。这种试错,让人牢记了代码位置的变换组合。它可能是把预定义和赋值合并了,也可能是和其他语句排序有所变化,只要这种变化在一定的逻辑合理范围内,都需要认识,立马反应过来。
-
通过敲代码,这个函数、单词,看了一遍,嘴上默念一遍,手指敲击时默写一遍,眼睛还要核对一遍,眼睛、嘴巴、肌肉、脑子形成一套闭环。这套闭环加深了印象。
-
知识是不断发展的,前后是有联系和对比的。很多函数的产生是因为原有函数已经不能满足人们需要,所以需要创造出来。这种创造出的新特性或者说区别,是决定人处理问题思路的重要判断标准,是人的专业性具体体现。如此关键,需要加深印象,立即运行程序,查看区别,这区别可能通过反馈面板显示运行时长,可以通过图片数值反应处理效果。
-
犯错的过程,就是训练排查思路的过程,甚至是产生更好的算法思路过程。速度越快越好,最好还能帮助别人排错做有价值的事,这就是经验。
-
细节的对比,调参的过程,对比的过程。
为什么有的人骑半小时电动车去健身房去跑步机?
跑步就行了,为什么还要去健身房花钱跑?
走路有“功用”,健身房跑步没意义还花钱,这是为什么?
(1)每年死在路上的意外蛮多的,骑电动车是为了减少风险时间。–> 短小精悍的程序例子保障你的学习成果。
(2)走路有功用,跑步机没有功用还耗钱;送快递跑步有用,但是举杠铃高强度增加肌肉活性。不是每个送外卖的都是长跑冠军。 –> 高强度才能让人熟练,真正提升并且达到一定高度。
版本升级带来的函数变化问题
在opencv2和opencv3上面都没有问题的代码,在opencv4上就出现了问题。
由于宏定义名称变更提示“”未定义的标识符“”问题
(1)硬方法–使用旧路径文件
生成解决方案的时候,会提示“CV_BGR2GRAY 未声明的标识符”,但是之前都没有这个问题的。
在代码中添加
include "opencv2/imgproc/types_c.h"
就可以了。
(2)软方法–使用新命名函数
ex:CV_WINDOW_AUTOSIZE未声明的标识符
原因:OpenCV3中取消了Opencv1中残留的CV_式的宏定义前缀,使用新的命名规范
情形1 直接去掉CV_前缀
A.namedWindow()函数中,CV_WINDOW_AUTOSIZE改为WINDOW_AUTOSIZE 【窗口设置时注意用】
B.threshold()函数中,CV_THRESH——BINARY改为THRESH_BINARY
C.line函数中,CV_FILED改为FILLED
D.remap()函数中CV_INTER_LINEAR改为INTER_LINEAR
情形二:需要新的前缀替换
A.line()函数中,CV_AA改为LINE_AA
B.cvtColoar()函数,CV_BGR2HSV改为COLOR_BGR2HSV 【颜色变换时注意用】
C.morphologyEx()函数CV_MOP_OPEN改为MORPH_OPEN
情形三:需要新的命名空间中使用
A.TermCriteria()函数中,CV_TERMCRIT_EPS改为TermCriteria::EPS
B.CascadeClassifer::detectMultScale()函数中,CV_HAAR_SACLE_IMAGE改为CASCADE_SCALE_IMAGE
vector要加using namespace std;
读懂代码
画面识别,实际上是寻找人类的视觉关联方式,并再次应用。——日本会津大学博士:于建国
头文件
include\opencv2\opencv.hpp
opencv库的头文件地址:opencv\build\include\opencv2
该地址下有个特别的文件“opencv.hpp”,包含了openCV各模块的头文件,转到定义
各种库头文件简介
【calib3d】——其实就是就是Calibration(校准)加3D这两个词的组合缩写。这个模块主要是相机校准和三维重建相关的内容。基本的多视角几何算法,单个立体摄像头标定,物体姿态估计,立体相似性算法,3D信息的重建等等。
【contrib】——也就是Contributed/Experimental Stuf的缩写, 该模块包含了一些最近添加的不太稳定的可选功能,不用去多管。2.4.8里的这个模块有新型人脸识别,立体匹配,人工视网膜模型等技术。
【core】——核心功能模块,包含如下内容: OpenCV基本数据结构(CvPoint,CvSize,CvScalar等);动态数据结构(CvMemStorage,CvMemBlock等);绘图函数(cvLine,cvRectangle等);数组操作相关函数(cvCreateImage,cvCreateMat等);辅助功能(数据保存和运行时类型信息:CvFileStorage,cvOpenFileStorage等;错误处理和系统函数:cvGetErrStatus,cvAlloc,cvFree等 )与系统函数和宏;与OpenGL的互操作
【imgproc】——Image和Processing这两个单词的缩写组合。图像处理模块,这个模块包含了如下内容: 线性和非线性的图像滤波;图像的几何变换;其它(Miscellaneous)图像转换;直方图相关;结构分析和形状描述;运动分析和对象跟踪;特征检测;目标检测等内容。
【features2d】 ——也就是Features2D, 2D功能框架 ,包含如下内容: 特征检测和描述;特征检测器(Feature Detectors)通用接口;描述符提取器(Descriptor Extractors)通用接口;描述符匹配器(Descriptor Matchers)通用接口;通用描述符(Generic Descriptor)匹配器通用接口; 关键点绘制函数和匹配功能绘制函数
【flann】—— Fast Library for Approximate Nearest Neighbors,高维的近似近邻快速搜索算法库,包含两个部分:快速近似最近邻搜索;聚类
【gpu】——运用GPU加速的计算机视觉模块
【highgui】——也就是high gui,高层GUI图形用户界面,包含媒体的I / O输入输出,视频捕捉、图像和视频的编码解码、图形交互界面的接口等内容。
【legacy】——一些已经废弃的代码库,保留下来作为向下兼容,包含如下相关的内容: 运动分析;期望最大化;直方图;平面细分(C API);特征检测和描述(Feature Detection and escription);描述符提取器(Descriptor Extractors)的通用接口;通用描述符(Generic Descriptor Matchers)的常用接口;匹配器
【ml】——Machine Learning,机器学习模块, 基本上是统计模型和分类算法,包含如下内容: 统计模型 (Statistical Models);一般贝叶斯分类器 (Normal Bayes Classifier);K-近邻 K-NearestNeighbors);支持向量机 (Support Vector Machines);决策树 (Decision Trees);提升(Boosting);梯度提高树(Gradient Boosted Trees);随机树 (Random Trees);超随机树 (Extremely randomized trees);期望最大化 (Expectation Maximization);神经网络 (Neural Networks) MLData
【nonfree】,也就是一些具有专利的算法模块 ,包含特征检测和GPU相关的内容。最好不要商用,可能会被告哦。
【objdetect】——目标检测模块,包含Cascade Classification(级联分类)和Latent SVM这两个部分。
【ocl】——即OpenCL-accelerated Computer Vision,运用OpenCL加速的计算机视觉组件模块
【photo】——也就是Computational Photography,包含图像修复和图像去噪两部分
【stitching】——images stitching,图像拼接模块,包含如下部分: 拼接流水线;特点寻找和匹配图像;估计旋转;自动校准;图片歪斜;接缝估测;曝光补偿;图片混合
【superres】——SuperResolution,超分辨率技术的相关功能模块
【ts】——opencv测试相关代码,不用去管他
【video】——视频分析组件,该模块包括运动估计,背景分离,对象跟踪等视频处理相关内容。
【Videostab】——Video stabilization,视频稳定相关的组件,官方文档中没有多作介绍,不管它了。
include
iostream 是标准输入输出流,如果你的程序中没有输入也没有输出的话,就没有必要加上 #include
stdafx.h 到底有什么用
在新建一个项目的时候,很多时候有stdafx.h,我就在想这个文件究竟是干什么的?
stdafx.h : 标准系统包含文件的包含文件,或是经常使用但不常更改的;特定于项目的包含文件。
1.预编译头
头文件夹下会默认有头文件stdafx.h,而源文件夹下则默认有源文件stdafx.cpp,手动将这些文件删除后,编译时系统还会报错
stdafx.h并不是标准C++头文件,也就是说,该文件本质上相当于自定义的一个头文件( 这里是VS默认自定义的文件),与项目的源代码文件存放在同一个文件文件夹下,通过#include”stdafx.h”引用;
从内容上来说,头文件stdafx.h是
1.包含标准头文件 ,就是这个头文件包含标准C的头文件,例如:stdio.h、string.h这些,这种做法实际在我们项目中很常见,把大部分.c文件需要的头文件,放在一个头文件中,这样只有include这一个头文件就行,省事
2.包含项目中的不会轻易改动的头文件
2.预编译头设置
在项目->属性->c/c++->预编译头,进行设置,
1.开启、关闭预编译头
2.改变预编译头的名字,所以并一定用stdafx名字
3.修改预编译头输出文件的路径
3.预编译头的原理
每一次的预编译宏展开和不同的源文件需要包含一些相同头文件,只要某个源文件发生变化,都要重新做一次宏展开,浪费了很多时间,所以引入了预编译头,预编译头一次编译,重复使用,除非有修改
在编译过程中,stdafx.cpp和stdafx.h文件用于生成一个预编译头文件 project.pch和预编译类型文件stdafx.obj。
但是预编译头文件包含有众多头文件的处理信息,故而其本身会占用较大的存储空间,故而可以注意清理不需要的预编译头。
4.关于报错
- 无法打开预编译头文件”xxx.pch”:no such file or directory 的问题
分析:根据上面的原理解释,可能是由于编译器无法通过stdafx.cpp创建一个预编译文件,从而其他文件没有办法去引用该pch文件。
解决方案:选中源文件stdafx.cpp,右键 -> 属性 -> C/C++ -> 预编译头,出现上述问题一般是由于预编译头的选项从 创建 变为了 使用 ,通过将选项重新改为创建可解决问题。
- 在查找预编译头文件时遇到意外的文件结尾
需要将指令#include”stdafx.h” 放在每个文件的开始位置,以供处理。
命名空间
OpenCV 中的 C++ 类和函数都是定义在命名空间 CV 之内的,有两种方法可以访问。 |方法|内容| |—|—| |推荐|代码开头的适当位置加上 using namespace cv;| |麻烦|使用 OpenCV类和函数时,都加入 cv:: 命名空间,这4个字符|
using namespace cv;
详细包含头文件见“各种库头文件简介”章节
命名规范
命名基本原则:变量名=属性+类型+对象描述,其中每一对象的名称都要求有明确含义,可以取对象名字全称或名字的一部分。
变量命名规则
前缀写法 | 类型 | 描述 | 实例 |
---|---|---|---|
ch | char | 8位字符 | chGrade |
ch | TCHAR | 如果_UNICODE 定义,则为16位字符 | chName |
b | BOOL | 布尔值 | bEnable |
n | int | 整形(大小依赖于操作系统) | nLength |
n | UINT | 无符号值(大小依赖于操作系统) | nHeight |
w | WORD | 16位无符号值 | wPos |
l | LONG | 32位有符号整形 | IOffset |
dw | DWORD | 32位无符号整形 | dwRange |
P | * | 指针 | pDoc |
lp | FAR* | 远指针 | lpszName |
lpsz | LPSTR | 32位字符串指针 | lpszName |
lpsz | LPCTSTR | 如果_UNICODE定义,则为32位常量字符串指针 | lpszName |
h | handle | Windows对象句柄 | hWnd |
lpfn | callback | 指向CALLBACK函数的远指针 | LpfnName |
关键字字母组合
描述内容 | 使用的关键字母组合 |
---|---|
最大值 | Max |
最小值 | Min |
初始化 | Init |
临时变量 | T(或Temp) |
源对象 | Src |
目的对象 | Dst |
函数与参数
函数命名规则
cvActionTargeMod()
Action 核心函数 Targe 目标图像区域(轮廓、多边形) Mod 可选变种(变量类型)
main 函数
C/C++的main 函数标准写法:
int main(int argc,char** argv)
所以OpenCV 开源视觉库代码中,常有argc和argv的出现。
arg 指的是“参数”,例如:arguments,argument counter和argument vector.
argc 和 argv 这两个参数一般在命令行编译程序时有用。
main | 函数中 | 的参数 |
---|---|---|
参数 | argc | argv |
表示 | argc为整数 | *argv[] 字符串数组 |
含义 | 统计运行程序时送给main函数 的命令行参数的个数 |
存放指向字符串参数的指针数组, 每一个元素指向一个参数 |
值 | 默认值为1 | 各成员含义: argv[0]指向程序运行的全路径名 argv[0]指向在DOS命令行中执行程序名后的第一个字符串 argv[2]指向执行程序名后的第二个字符串 argv[argc]为NULL |
- 各个版本的 Visual studio 编译器中,函数体中是否使用 argc 和argv,返回值为 void 或不为 void ,都是合法的。
在 Visual studio 中如果使用 argc 和argv,且没有在 【项目属性】-【配置属性】-【调试】-【命令参数】中指定参数的值,就会报错。这是研究OpenCV官方提供的示例程序时经常碰到的错误。例如:
Mat srcImage=imread(argv[1],1); //读取字符串名为 argv[1]的图片
替换为
Mat srcImage=imread("1.jpg",1); //工程目录下有一张名为“1.jpg”的图片
格式输出 printf() 函数
printf 函数并非 OpenCV 中的函数,而是标准 C 语言函数,包含在 studio.h 之中。
只不过 OpenCV 对其也有包含,只需要包含头文件如 opencv.hpp 就可以使用它。
格式字符串 | 作用 |
---|---|
%d | 将整数转成十进制 |
%f | 将整数转成浮点数 |
%u | 十进制无符号整数 |
%o | 将整数转成八进制 |
%c | 将整数转成对应的 ASCII 字符 |
%s | 将整数转成字符串 |
%x | 整数转成小写十六进制 |
%X | 整数转成大写十六进制 |
%p | 输出地址符 |
%% | 输出百分比符号,不进行转换 |
规定字符 | 作用 |
---|---|
\n | 换行操作 |
\f | 清屏并换页 |
\r | 回车 |
\t | Tab 符 |
必须牢记的基础
白色 | 黑色 |
---|---|
有数值 | 没有数值 |
OpenCV 的数据结构
新版本衍生出新的结构,降低使用门槛,提高生产力。
- 矩阵数据类型
CV_
例如:CV_8UCI 表示8位无符号单通道矩阵
- 图像数据类型
IPL_DEPTH_
IPL_DEPTH_8U 表示8位无符号整数图像
point 点
Scalar 颜色
size 尺寸
Rect 矩形
Mat
对应OpenCV1.0时代的IpIImage,主要用来存放图像的数据结构就行了。
cv::Rect
RotatedRect
形态学原理
基本函数
显示lena的灰度图片
源代码
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
Mat src = imread("lena.jpg",IMREAD_GRAYSCALE);
imshow("原画", src);
waitKey(0);
}
- 加载图像(用cv::imread)
imread功能是加载图像文件成为一个Mat对象,其中第一个参数表示图像文件名称
第二个参数名 | 值 | 表示加载的图像是什么类型 |
---|---|---|
IMREAD_UNCHANGED | (<0) | 表示加载原图,不做任何改变 |
IMREAD_GRAYSCALE | ( 0) | 表示把原图作为灰度图像加载进来 |
IMREAD_COLOR | (>0) | 表示把原图作为RGB图像加载进来 |
- 显示图像 (cv::namedWindos 与cv::imshow)
imshow 根据窗口名称显示图像到指定的窗口上去,第一个参数是窗口名称,第二参数是Mat对象。
- 修改图像 (cv::cvtColor)
cvtColor 的功能是把图像从一个彩色空间转换到另外一个色彩空间,有三个参数,第一个参数表示源图像、第二参数表示色彩空间转换之后的图像、第三个参数表示源和目标色彩空间如:COLOR_BGR2HLS 、COLOR_BGR2GRAY 等
cvtColor( image, gray_image, COLOR_BGR2GRAY );
用到再查名词
alpha通道的透明效果
阿尔法通道是一个8位的灰度通道,该通道用256级灰度来记录图像中的透明度信息,定义透明、不透明和半透明区域,其中白表示不透明,黑表示透明,灰表示半透明。
Alpha通道作用
阿尔法通道(Alpha Channel)是指一张图片的透明和半透明度。例如:一个使用16位存储的图片,可能5位表示红色,5位表示绿色,5位表示蓝色,1位是阿尔法。在这种情况下,它要么表示透明要么不是。一个使用32位存储的图片,每8位表示红绿蓝,和阿尔法通道。在这种情况下,就不光可以表示透明还是不透明,阿尔法通道还可以表示256级的半透明度。 在新的或现有的 Alpha 通道中,可以将任意选区存储为蒙版。可以编辑 Alpha 通道,添加或删除其中的颜色,并且可为蒙版颜色和不透明度指定设置。通俗的说就是上图时作透明效果的。 一般alpha值取0~1之间。 通道分为三种通道。也就是有三个作用。
创建 Alpha 通道
1、按住 Alt 键 (Windows) 或 Option 键 (Mac OS) 并单击“通道”面板底部的“新建通道”按钮,或从“通道”面板菜单中选取“新建通道”。
2、在“新建通道”对话框中指定选项。
3、在新通道上绘画以蒙版图像区域。
Alpha通道与蒙版
当您选择某个图像的部分区域时,未选中区域将“被蒙版”或受保护以免被编辑。因此,创建了蒙版后,当您要改变图像某个区域的颜色,或者要对该区域应用滤镜或其它效果时,您可以隔离并保护图像的其余部分。您也可以在进行复杂的图像编辑时使用蒙版,比如将颜色或滤镜效果逐渐应用于图像。
蒙版示例A. 用于保护背景并编辑“蝴蝶”的不透明蒙版 B. 用于保护“蝴蝶”并为背景着色的不透明蒙版 C. 用于为背景和部分“蝴蝶”着色的半透明蒙版 蒙版存储在 Alpha 通道中。蒙版和通道都是灰度图像,因此可以使用绘画工具、编辑工具和滤镜像编辑任何其它图像一样对它们进行编辑。在蒙版上用黑色绘制的区域将会受到保护;而蒙版上用白色绘制的区域是可编辑区域。
使用快速蒙版模式可将选区转换为临时蒙版以便更轻松地编辑。快速蒙版将作为带有可调整的不透明度的颜色叠加出现。可以使用任何绘画工具编辑快速蒙版或使用滤镜修改它。退出快速蒙版模式之后,蒙版将转换回为图像上的一个选区。 要更加长久地存储一个选区,可以将该选区存储为 Alpha 通道。Alpha 通道将选区存储为“通道”面板中的可编辑灰度蒙版。一旦将某个选区存储为 Alpha 通道,就可以随时重新载入该选区或将该选区载入到其它图像中。
饱和度
饱和度指色彩的纯洁性,也叫饱和度或彩度,是“色彩三属性”之一。如大红就比玫红更红,这就是说大红的色度要高。它是HSV色彩属性模式,孟塞尔颜色系统等的描述色彩变量。
饱和度可定义为彩度除以明度,与彩度同样表征彩色偏离同亮度灰色的程度。
纯的颜色都是高度饱和的,如鲜红,鲜绿。混杂上白色,灰色或其他色调的颜色,是不饱和的颜色,如绛紫,粉红,黄褐等。
基本业务
我们学前班半年就已经熟练做加减乘除算术题,可却用了六年去做加减乘除的“应用题”。
画图能力
代码千万行,注释第一行。
融合能力
解决问题
小练习1-
图像数据操作(内存分配与释放,图像复制、设定和转换)
图像/视频的输入输出(支持文件或摄像头的输入,图像/视频文件的输出) 矩阵/向量数据操作及线性代数运算(矩阵乘积、矩阵方程求解、特征值、奇异值分解) 支持多种动态数据结构(链表、队列、数据集、树、图) 基本图像处理(去噪、边缘检测、角点检测、采样与插值、色彩变换、形态学处理、直方图、 图像金字塔结构) 结构分析(连通域/分支、轮廓处理、距离转换、图像矩、模板匹配、霍夫变换、多项式逼 近、曲线拟合、椭圆拟合、狄劳尼三角化) 摄像头定标(寻找和跟踪定标模式、参数定标、基本矩阵估计、单应矩阵估计、立体视觉匹 配) 运动分析(光流、动作分割、目标跟踪) 目标识别(特征方法、HMM 模型) 基本的 GUI(显示图像/视频、键盘/鼠标操作、滑动条) 图像标注(直线、曲线、多边形、文本标注)