OpenCV(C++版)入门

一般来说大家看到一门新的知识都会很迷茫,也不知道该从哪下手,也不知道用什么软件,然后今天我来写一个OpenCV的入门,给大家开个头,看完这个开头之后基本也就知道应该怎么学OpenCV了。

实际上Opencv就是一个有关视觉处理的库,就和学C语言的时候用的math、time那一堆库一样,学习一个库的流程其实就是:
1.了解这个库是干什么的
2.学习这个库自带的一些函数应该如何使用,以及这些函数有什么效果
3.学了多个函数之后,通过对这些函数进行组合来实现一些复杂的功能。

强调一下这篇文章讲的是在WindowsC++语法的OpenCV,接下来的教程也是讲C++语法,不是python的。

然后说一下用什么软件来进行OpenCV的开发,一般的配置就是使用VS配置一个opencv的库来进行学习,下面附上所需的安装包链接。
VS2019 提取码:5162
Opencv-4.1.0提取码:n7lz
注意一下opencv的语法是有变革的,由开始的2到3,现在又更新到了4。其中3和4的语法大致相同,2和3在某些函数的参数上有一定的区别,所以在移植代码的时候,如果移过来发现报错,有可能是Opencv版本不一样,到时候改一下报错函数的参数就可以了。

安装的过程分四步:
1.装VS2019
2.装Opencv的库
3.把Opencv的库放到环境变量里
4.在VS里建一个工程,把这个工程连接上Opencv的库
具体步骤给大家一个我以前配的时候用的链接(步骤有些繁琐,我就不自己写了……)VS2019配置Opencv教程

因为是入门,所以先讲以下五个内容,都是些比较简单的函数,而且很有趣。
1.展示图片
2.灰度图片
3.模糊图片
4.边缘检测
5.保存图片

在进行操作之前,我们需要先放一张图片到自己新建的工程处,一我这个为例,我新建的工程是OpencvTest1,我找到这个工程main.cpp所在的路径,放了一张bilibili.jpg到这个地方。

1.展示图片

#include <opencv2/opencv.hpp>
#include <iostream>using namespace std;
using namespace cv;int main()
{Mat src = imread("bilibili.jpg");imshow("lalala",src);waitKey(0);return 0;
}

效果:出现一个小黑框和一张图片。

下面我们能来解释这段代码的内容。

#include <opencv2/opencv.hpp>
#include <iostream>
这两句话是分别引入opencv的库和c++的标准库
using namespace std;
using namespace cv;
这两句是引入工作空间,std是c++标准库的工作空间名,cv是opencv的工作空间名。
(工作空间的目的是避免 如果两个库有相同的函数名,在调用函数时发生冲突,上文这两个库里没有重复的函数名,所以直接引入工作空间不会有影响。)
int main()
{Mat src = imread("bilibili.jpg");imshow("lalala",src);waitKey(0);return 0;
}//这一段是主函数。
Mat src = imread("bilibili.jpg");//其实是两条语句合在一起。分别为:
Mat src;//定义一个Mat类型的变量,变量名是src
src = imread("bilibili.jpg");//调用imread函数读取图片并把这张图片赋值给src。imshow("lalala",src);//调用函数imshow展示图片,第一个参数lalala是显示图片所用的窗口的名字,src是上面刚刚被一张图片赋值的变量。waitkey(0);//显示图片后开始等待下一步操作。如果不加这条命令的话,自己屏幕上会有一个黑框一闪而过,
//图片也不会显示出来,因为程序没有停下来,显示图片后直接关闭了程序。return 0;//程序结束的标志,C语言上常用。因为这个主函数的返回值类型是int,所以最后返回一个0让程序结束。

这样一来一个最简单的Opencv程序就写好了,他的作用是调用一张图片并显示。
PS:
1.在使用 imread() 读取函数的时候如果图片处于main.cpp所在文件夹下时,可以直接输入图片的名字来进行读取图片。
当然我们也可以输入图片的绝对路径来进行读取图片。如imread(“D:\\vs\\OpencvTest1\\OpencvTest1\\bilibili.jpg”)
注意在分隔路径时我使用的是 “\\” 而不是 “\” ,因为按C/C++的语法,只写一个"\",可能会被当做转义字符,从而使"\“无法作用,所以要用”\\“来进行路径间的分隔。
当然不用”\\"的话也可以用/进行分隔,如:imread(“D:/vs/OpencvTest1/OpencvTest1/bilibili.jpg”)
2. imshow() 的第一个参数是窗口名

2.灰度图片
显示灰度图像的常规方式有两种:第一种是在读取图片的时候就按灰度格式读取。第二种是先读入图片,然后再转化图片。
第一种方法:

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{Mat src = imread("bilibili.jpg",0);imshow("lalala",src);waitKey(0);return 0;
}
//可以发现其实和第一次的代码区别不大,只是修改了一下imread的参数Mat src = imread("bilibili.jpg",0);//imread()函数有两个参数,第一个参数是图片的路径或图片的名字,第二个参数是以何种格式来读取图片。//默认值是1,也就是原本的格式读取;如果输入参数为0的话就是以黑白格式读取。

效果:


第二种方法:
调用cvtColor()函数

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{Mat src = imread("bilibili.jpg");Mat dst;cvtColor(src,dst,COLOR_BGR2GRAY);imshow("lalala",dst);waitKey(0);return 0;
}
//我们的操作是新建了一个Mat对象dst,又调用了函数cvtColor()来进行图片的灰度化,最终显示的图片也变成了dst。cvtColor(src,dst,COLOR_BGR2GRAY);//第一个参数是输入图像,第二个参数是输出图像,第三个参数是进行何种转换。//BGR2GRAY的意思是图片由BGR(三原色)格式变为灰度图格式。

效果:
3.模糊图片
介绍模糊图片的时候,我们要先介绍三种形态学处理:腐蚀,膨胀,滤波。
腐蚀:erode() 将一张图片边界点去除。
膨胀:dilate() 对图像的边界进行扩张。
如下为膨胀和腐蚀的效果图,这两个操作正好是相反的,他们操作的组合还能组成开运算,闭运算,顶帽,黑帽等一系列形态学处理。

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{Mat src = imread("bilibili.jpg");imshow("src", src);Mat dst1,dst2;Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));erode(src, dst1, element);imshow("erode",dst1);dilate(src, dst2, element);imshow("dilate", dst2);waitKey(0);return 0;
}

效果:
滤波:滤波是用来去噪的,外界的干扰可能会掩盖图像的一些特征,使得图像变得模糊,使用滤波可以让图像特征更加明显。(PS:是特征更加明显,不一定代表图片看起来更加清晰。)

在讲图片滤波的原理之前先讲一些预备知识(划重点,这里很重要)。
首先我们前面定义那个可以接受图片的变量,它的类型是Mat,这其实是一种矩阵类型的变量。实际上图片就是一个大矩阵,比如我们看到一个像素值是100*100的图片,其实就是说这个图片是个100*100的大矩阵,矩阵上的每个值都是三原色混合出来的一种颜色,图片通过对每个像素点颜色的调节使得图片变得丰富多彩。(如果可以找到那种像素很低的图片,我们可以发现它几乎是由一个一个颜色不同得小方块构成的,那些小方块其实就是像素点。)
说完这些,我们就可以讲滤波的原理是什么了,我们得到一张图片,也就相当于得到一个大矩阵。我们先将这个大矩阵进行分区,比如把一个100*100的大矩阵分成25个4*4的小矩阵。所谓图像的特征其实就是矩阵上的值的特征,我们希望一个图像特征更加明显,就是希望该图像的像素值变得更有特点。所以我们可以对每个4*4小矩阵的值进行一些操作,比如找这些数的中位数、平均值、加权值,在找到特征值之后把矩阵中的值替换为特征值,这样我们图片的特征就更明显了。

我们举一个最常见的均值滤波的例子:
如果我们有一个大矩阵需要进行均值滤波,我们先在其中找一个小的3*3矩阵对它进行操作,实际上就是将九宫格最中间的值改为这个九宫格所有值的平均值。
因为(75+193+37+121+80+189+45+94+232)/9=118,所以我们将中间值80改为118.即:

75 193 37
121 80 189
45 94 232

变为

75 193 37
121 118 189
45 94 232

到此滤波原理结束,我们开始看一下效果。

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{Mat src = imread("bilibili.jpg");imshow("src", src);Mat dst;blur(src, dst, Size(7, 7));imshow("blur", dst);waitKey(0);return 0;
}blur(src, dst, Size(7, 7));//1.输入图像,2.输出图像,
//3.进行滤波时选择小矩阵的大小(注意要要是n*n的矩阵,且n为奇数)。

效果:
4.边缘检测
边缘检测其实就是找到图像上的边缘,很好玩,进行边缘检测的前提是先将图片灰度化,如果想边缘更清晰的话,可以在检测前加一步滤波。

如果对一个函数的参数不是很了解,可以去修改参数的值,看效果发生变化,就知道这个参数的影响在哪里了。

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{Mat src = imread("bilibili.jpg");imshow("src", src);Mat dst;cvtColor(src, src, COLOR_BGR2GRAY);blur(src, src, Size(3, 3));Canny(src, dst, 3, 9, 3);imshow("canny", dst);waitKey(0);return 0;
}
//流程:读图,灰度化,滤波,边缘检测。Canny(src, dst, 3, 9, 3);//1.输入2.输出3.最小阈值4.最大阈值5.sobel算子的大小//最大最小阈值用来使在阈值范围内的像素值才能保留。sobel算子的用处是与原图进行卷积运算,得到一个新的图,这个图根据阈值范围留下数据后就是效果图。

效果:

5.保存图片
只用一个函数imwrite()即可实现。

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{Mat src = imread("bilibili.jpg");imshow("src", src);Mat dst;cvtColor(src, src, COLOR_BGR2GRAY);blur(src, src, Size(3, 3));Canny(src, dst, 3, 9, 3);imshow("canny", dst);imwrite("canny.jpg",dst);waitKey(0);return 0;
}
//和上一个代码相比只加了一个函数imwrite("canny.jpg",dst);
imwrite("canny.jpg",dst);//第一个参数是图片名,记得加后缀。这里也可以写绝对路径。第二个参数是保存哪张照片,这里选择边缘检测之后的图片。

我们发现main.cpp所在文件夹下多了一张“canny.jpg”。
文章到此结束,下一篇写一篇stm32有关流水灯的教程,因为发现上一篇讲配keil5配32的文章阅读量好多。
下一篇大概要隔一天再发,因为这个写起来好费时间,作业还莫得写完……

Opencv入门(C++)相关推荐

  1. 【OpenCV入门指南】第十三篇 人脸检测

    原文出处:http://blog.csdn.net/MoreWindows/article/details/8426318#t2 本篇介绍图像处理与模式识别中最热门的一个领域--人脸检测(人脸识别). ...

  2. 【OpenCV入门指南】第五篇轮廓检测 下

    上一篇<[OpenCV入门指南]第五篇轮廓检测上>介绍了cvFindContours函数和cvDrawContours函数,并作了一个简单的使用示范.本篇将展示一个实例,让大家对轮廓检测有 ...

  3. 【OpenCV入门指南】第五篇 轮廓检测 上

    <[OpenCV入门指南]第三篇Canny边缘检测>中介绍了边缘检测,本篇介绍轮廓检测,轮廓检测的原理通俗的说就是掏空内部点,比如原图中有3*3的矩形点.那么就可以将中间的那一点去掉. 在 ...

  4. 【转】【OpenCV入门教程之一】 安装OpenCV:OpenCV 3.0、OpenCV 2.4.8、OpenCV 2.4.9 +VS 开发环境配置

    本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接: http://blog.csdn.net/poem_qianmo/article/details/19809337 作者:毛星云(浅 ...

  5. 【AI白身境】搞计算机视觉必备的OpenCV入门基础

    文章首发于微信公众号<有三AI> [AI白身境]搞计算机视觉必备的OpenCV入门基础 今天是新专栏<AI白身境>的第五篇. 曾经看过一个视频,树莓派自平衡机器人自动追着小球跑 ...

  6. 转载:【opencv入门教程之六】创建Trackbar图片对比度、亮度值调整

    [OpenCV入门教程之六] 创建Trackbar & 图像对比度.亮度值调整 浅墨_毛星云 2014-03-18 21:43:18 103746 收藏 21 最后发布:2014-03-18 ...

  7. 转载:【OpenCV入门教程之五】 分离颜色通道多通道图像混合

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/21176257 作者:毛星云(浅墨) ...

  8. 转载:【OpenCV入门教程之四】 ROI区域图像叠加初级图像混合 全剖析

    [OpenCV入门教程之四] ROI区域图像叠加&初级图像混合 全剖析 浅墨_毛星云 2014-03-10 12:48:05 157425 收藏 19 最后发布:2014-03-10 12:4 ...

  9. 转载:【opencv入门教程之三】:图片的载入|显示|输出

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/20537737 作者:毛星云(浅墨) ...

  10. 转载:【opencv入门教程之三】:组件结构

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/19925819 作者:毛星 ...

最新文章

  1. Yslow on Nodejs server
  2. Linux下挂载存储设备
  3. php mysql全能权威指南 pdf_《PHP+MySQL全能权威指南(配光盘)》怎么样_目录_pdf在线阅读 - 课课家教育...
  4. 在ASP.NET页面中动态添加控件
  5. linux中spawn远程执行,linux 远程登录执行命令
  6. php 获取已用空间,PHP5:获取导入的名称空间列表 - php
  7. 甜甜圈和拓扑学也有关系,你想的到吗?
  8. 在前端网页设计中 align 和 valign 两种对齐方式的不同取值区分(持续补充)
  9. 【操作系统】实验 设计一个按优先权调度算法实现处理器调度的程序
  10. php多个请求只执行一次,php使用redis的blPop/brPop,一台服务器多个并发,也只能一次一次执行?...
  11. 序列最小最优化算法(SMO)
  12. kali 克隆网页_Web侦察工具HTTrack (网站克隆)
  13. Stata连享会:分享一大堆资料
  14. C++一本通题库1008
  15. 2018年全国职业院校技能大赛中职组网络空间安全正式赛卷
  16. 鸣人和佐助(广度搜索)
  17. 【愚公系列】2021年11月 攻防世界-进阶题-MISC-030(red_green)
  18. 【解决方案】RTSP/Onvif安防视频直播解决方案EasyNVR在某省高速上云项目中的应用分析
  19. 图形 1.4 PC手机图形API介绍
  20. ENVI5.3.1Landsat 8影像基于单窗算法和辐射传输方程进行地表温度反演

热门文章

  1. fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include stdafx.h”
  2. 企鹅智酷“2015年互联网终极报告——解读九大行业红利”
  3. english: spoken english collection
  4. 使用python获取共享汽车平台Evcard 的车辆位置信息
  5. acwing1107魔板
  6. 基于3Ds Max实现客厅的设计与实现.docx(毕业设计、成绩评定评分表、成绩评定评审等级表)
  7. 禅道----项目经理创建项目
  8. 高通SDM450 Android9上调试RS485接口温湿度传感器调试介绍
  9. 使用JAVA编写“超市购物打印清单”——超亲民(直白点:纯纯小辣鸡的作品)
  10. C++学习32:侯捷C++11,14新特性(标准库部分)