我写的 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.关于报错

  1. 无法打开预编译头文件”xxx.pch”:no such file or directory 的问题

分析:根据上面的原理解释,可能是由于编译器无法通过stdafx.cpp创建一个预编译文件,从而其他文件没有办法去引用该pch文件。

解决方案:选中源文件stdafx.cpp,右键 -> 属性 -> C/C++ -> 预编译头,出现上述问题一般是由于预编译头的选项从 创建 变为了 使用 ,通过将选项重新改为创建可解决问题。

  1. 在查找预编译头文件时遇到意外的文件结尾

需要将指令#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_(S|U|F)C

例如:CV_8UCI 表示8位无符号单通道矩阵

  • 图像数据类型

IPL_DEPTH_(S|U|F)

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(显示图像/视频、键盘/鼠标操作、滑动条) 图像标注(直线、曲线、多边形、文本标注)

论文部分

噪声模型

高斯噪声

瑞利噪声

伽马(爱尔兰)噪声

指数分部噪声

均匀分布噪声

脉冲噪声(椒盐噪声)