粉丝231获赞291

哈喽,大家好,我是兔子,如果你需要做图像处理,那么你一定离不开一个库,就是 opencv。 今天我就来详细的教一下大家怎么去装基于 passion 的 opencv 的环境,今天会讲这些东西。 首先 open cv 是什么呢? open cv 它不是某一种编程语言,它只是一系列的酷, 他是一系列别人写好的库,然后封装成了各种编程语言可以调用的接口,你去调用这些接口就可以去使去实现相应的功能。他有四加加接口, python 接口,加外接口等等。 我今天教大家安装的是基于 python 的 open c v, 如果你想要看基于私家家的 open c v 的话,你可以在评论区给我留言,如果 人数较多的话,我考虑出一期 c 加加的 open cv 的教安装教程好, 好了,那我们我们来开始安装吧。装 open cv 之前首先要装什么呢?首先我们刚才讲了, opencv 是一系列的库,我们通过拍摄去调用它,所以我们首先要装拍摄的环境,包括什么呢?拍,就包括拍唱和呢?靠,那 拍 charm 是你写代码的地方,是你的编辑器。呃,那 com 大就是你的拍摄环境加一系列的包,建议你装拍 charm 加上的 com 大。 这个我有出过一个教程,你可以去点击我那个安装教程,里面讲解的非常详细,教你一步一步安装好这两。安装好这两个环境之后,我们就可以来装奔 cv 了。首先打开我们的 cmd 命令窗口,或者是嗯呐,康大的这个命令 窗口。三亩地的命令窗口是什么呢?键盘的温加尔会出现左边这个界面,然后三亩地回车,这个就是命令,这个就三亩地命令窗口,那么呢康大的命令窗口是什么呢?你在这里搜索输入,额,南康大,看到这里就出现一个这个,额,南康大这个, 这个就是可以看到他们这个上面是不同的,就是一个是 sam d 的,一个是,呃,康大的这两个都是输入这个命令的, 我们今天就用三亩地来来演示吧,如果你的三亩地不行,你可以尝试一下用这个呢。康大的这个咱们先看一下你你的拍摄环境,首先 要看你的拍子环境变量有没有设置好,你在 cmd 这里输入拍子回车,可以看到这里有拍子的版本,就说明 你你这个拍摄环境是设置好了的,这里这个警告是没有关系的,出现你的拍摄版本就可以试一下你这个拍摄是不是可以用的。一加二 回车,可以看到打印了一个一加二,等于三,打印了一个三,我们的拍摄环境是可以的。如果你这个拍摄环境不可以的话,你要先设置环境变亮在这里 我的电脑属性,然后找到这个高级系统设置,再点看,点到这个高级点这个环境变量, 点击这个系统变量,看到这系统变量里的 pass, 点击编辑,然后可以看,看到看到这几个没?如果你,那 你看一下有没有你的,嗯,那康大的环境在不在这个环境变量里,如果不在环境变量里就找到你,嗯,那康大安装的那个位置,嗯,那康大,嗯,那康大的下面的,下面的这些目录你都给他复制过来,就在这里 新建,然后再复制过来,新建,复制过来,把这几个目录全部都复制过来,然后点击确定,确定就确定就可以了。你可以电脑重启一下, 然后你再在这里打 python, 应该就有了。如果你电脑装了多个 python 的环境, 你想要换这个默认的拍摄环境,也是修改这个,修改刚才的这个环境变量就可以了,再在这里 ctrl z 退出刚才的编辑环境。 编程环境之后,我们要来开始安装了,安装命令是这个,给大家放大一下,这这两行都可以,这个是 pepping store, 这个 open c v 杠 pattern 就可以了,但是如果你这么装的话,他可能会比较慢, 你给他加上杠 r, 然后后面是这个清华镜像的这个网址,就是使用清华镜像版的话,他会快很多,所以我们直接用第二条命令复制一下,然后 复制到这边回撤,等待他安装完成,他没有报错,而且显示已经成功的安装。我们来看一下有没有安装完成。输入一下 pass, 进入 pass 的环境, 然后我们试试 input c v 二,看会不会报错。看没有报错,下面一个问题是很多人想 知道我安装完的 opencv 的库,它的路径是在哪里?找到你安装完的康纳的那个路径,然后你找到这个立步,立步之后有一个撒的 packages, 这个 砸到 packages, 然后在这里你看到这个 c v 二就是你装的 open c v, 我们在代码里,在拍唱里写代码,看看到底对不对。 关于拍 charm 的使用,我也有一个详细的教程去讲它的使用,不了解拍 charm 的使用方法呢,去看我那个视频就可以了,那我们今天就讲问 c v 安装,所以代码就代码 v, c v 的用法就不详细跟大家讲了。 这单代码的功能就是读取一个这个 cat 点 j j p g cat 点 j p g 是这个 cat 点 j p g 是 这个图片是我。首先你要你,你要把你的图片放到这个和你这个代码同一个目录下, 然后你运行这个代码,如果你你放在别的目录下,这里要要改成要改路径,如果你放到和他同一个目录下,这里不用改路径,直接写这个图片的名称就可以了。我们来运行一下右键 run, 运行一下,可以看到这个小猫图片就显示出来了, 说明我们的 open cv 已经完成了。然后再回到我们的代码,如果你之前有写过代码,你就会发现,你就会发现问题,问题是这里这个, 你把鼠标放这边,它显示是报错的,而且仅 o c v 点,你发现它不 不能自动补全了,他理论上来讲就是他自带的阿木瑞子是他自带的那个函数,他应该是可以自动补全的,但是他不行了。然后我们用 pront, 你看他是可以自动补全的, 它下面会显示出这些是可以自动补全的。现在就说明虽然可以用了,但还是有点小问题,这个问题会非常影响我们写代码的体验,所以我们要把这个问题解决。这个问题是高版本的 opencv, 有的四点五之类的, 或者再往前的是没有这个问题的,我们安装的比较新,他有这个问题,我尝试了很多种方法去解决,最后发现最有效,最简单的方法就是这个, 回到我们刚才讲的那个 c v 二的这个,我们说 open c v 是装在这里的,找到这个 c v 二,点 p y d, 把这个文件复制一下, ctrl c 复制,然后返回到上一层,到这个 set packages, 然后粘贴,这里面就有这个 c v r 点 p y d 了,把拍唱关关掉, 然后再重新打开。我们看到这里报错没有了,我们来看一下自动补全行不行吧? c v 看到它这个自动补全可以了,它这边就会提示出它这些自带的一些一些函数了。 到这我们 open c v 就已经安装完成,可以使用了。好啦, open c v 的安装到这里就结束啦,相信你也安装成功了吧,我还在考虑要不要出 open c v 的教 学,看大家有没有这个需求,如果需要的人比较多的话,我就考虑出一系列简单的 oppocv 使用,带领大家简单的入门。好了,今天的视频到这里就结束了,我们下次再见。

虽然安装 open cv 包的时候名字叫 open cv 干拍神,但在导入包的时候是写 input cvr。 为什么叫 c v r 呢?这里面的 r 并不表示 open c v 的版本号, open c v 是基于 c 或 c 加加的, c v 表示底层用的是 c 的 a p i c v r 表示使用的是 c 加加的 a p i。 这主要是一个历史遗留问题,是为了保持先后的兼容性,但为了方便,一般会这么写, 给他取一个别名,这样在打字的时候就可以少敲一个数字,不仅可以保护手指,还能提高效率。通过这行代码 就可以打印出 open cv 的版本号。恭喜你成功实现了 open cv 的第一次调用。刚才巴普老 是有剪刀, c v r 用的是 c 加加的 a p i, 它使用 nampad 来存储和处理图线,所以在安装 open cv 干拍层的时候,自动安装上的依赖库 nampad。 这时我们可以直接导入那么派的包,并打印出他的版本号。 南派又是什么东西?南派是派森专门处理高位数组的包,他用来存储和处理大型矩阵,比派森自身欠套列表结构要高效的多。另外针对数组运算提供大量的数学函数,苦真的又快又好用。

你知道 c 加加怎么等待时间吗?来跟我学。首先,我们要导入一头文件, past time include windows got its greater 的。呵,他是 include resident studio its greater 的。导入之后呢?怎么做我也不知道。 不,我知道我们可以输入函数斯利普秒数一千,那么它是什么意思呢?斯利普函数的中文解释是睡觉,这个还拍散的态势。利普秒数十分相似,其作用是等待。可以这么写, hashtag include less 等于 swim greater。 答案, last time include last 3d i owe that envy the time using name spaces team in maine how less than less than high。 但这是故事里 one one thousand 靠着程序运行 完成 return zero 什么?你还不退出?好吧,其实我做了一个系统盘,可以正常运行,就是这样。这个是系统盘。好了好了,别看了。

欢迎大家学习有 buff 的 open cv 小白入门速成系列视频教程学习本教程需要拍成三的基本语言基础, 如果没有拍摄语言基础的话,请先看巴夫老师的拍摄零基础入门系列教程,在上手进行 ok cv 练习前,需要先安装配置好开发环境。在本教程中,操作系统使用温时 拍摄版本,选择三点八及以上开发工具使用拍恰姆社区版, oppo c v 使用当前的最新版本四点五点五作为演示环境。接下来教大家如何安装 opin c v。 在拍恰姆底部的选项中点击终端,英文叫太密脑,在光标闪烁处输入 p i p install open cv gun pattern, 按回车就会自动开始安装,有时候会报错就多执行 几遍,如果还是不行就换成国内的原机型安装。安装完成后还是在终端里出入 pip 内斯特安,回车后如果显示了纳木派和 open cv 干 pass 这两个库,就说明安装完成了。恭喜你能够完成了最艰巨的一步,下个视频我们就开始携带吗?

在真正教大家如何使用 n、 c、 b 来处理图像之前,我觉得有个事情必须要做,就是向大家解释一下,在计算机眼里一张图到底是什么东西? 比如说可以看到这样一张图里面写了一个黑色的数字五,对不对?那在计算机眼里这张图是怎样的呢?其实他就是把它看成是一个一个的格子所组成的, 那这一个一个的格子就叫做像素,比如说这里十四个像素,就是说我这一张图横着数有十四个格子, 十六个像素的意思就是我竖着数有十六个格子,那这每一个格子或者叫像素里面呢?他其实是存着具体的数值的,那这个数值就叫做像数值。像数值他也有自己的 取值范围,那就是零到二百五十五,如果你的像素值越趋近于零,那么就说明你对应的那个像素就越黑。反之,如果你的像素值越趋近于二百五十五,那么你这个像素就越白。 所以如果我们把像素值全部填进去的话啊,就是这个样子,很简单吧,像这种图里面的像素值只有两种情况的时候,我们就称它为二只图。好,我们继续往下看, 大家可以看到这里有一张灰不拉几的图,那这种灰不拉几的图我们一般都叫他为单通道图,或者叫灰度图。什么叫单通道呢?其实就是我这些像素拼起来,他只能拼出一个长方形来,那既然有单通道,那肯 六多通道,那多通道的话等一下再看,我们先专注于单通道,大家可以看到这一张图,这张图其实就是把我们这张原图放到 ps 啊,或者是那些图片查看器里面,我们把它放大所得到的一张图, 可以看到里面有一个一个的格子,对不对?那这些格子呢,就是所谓的像素了,然后这些像素里面存的那些值就是像素值,所以不管是二指图还是单通道图,他们在计算机眼里其实就是一堆数字所拼成的一个长方形而已。 好,那接下来我们来看一下多通道图,多通道图里面最常见的就是 rgb 三通道图,什么意思呢?比如说这里有一张彩色图片,那这张彩色图片里面的颜色是怎么表示出来的? 其实就是看成是红色加绿色加蓝色这三原色混合而成的,所以呢就叫做 rgb 三通道图 啊。其实这 rgb 三个通道的图为什么会长成这个样子啊?也非常好理解,比如说这个胸部这里是偏黄的,对不对?那么我们知道黄色是由红色加绿色组成的, 是不是?所以呢,你们会看到啊,胸部这一块红色的通道图里面啊,他是更加亮的,然后呢,蓝色通道里面这一块是比较暗的,从这样一个现象可以看得出来,每一个通道所呈现出的明暗啊,说白了就是代表我这样 一个颜色在彩色图里面所占的一个比重。所以不管是单通道图还是多通道图,在计算机眼里啊,就是一对像素值所排列出来的矩阵而已。

下面我们来看如何轻松的实现机器视野中的裂痕检测代码在置顶评论请下载。 好,首先我们增加原始图像的对比度,然后呢找到边缘,再然后进行这种形态学操作 好,然后找到大的联通区域,好,分别对每个联通区域找到,找到之后的话进行细化,细化之后的话对每一个联通区域都进行细化。好,我们循环处理,找到每个细化的区域,最后我们可以顺利的把所有边缘区域找出来,好,最后就把所有的这种裂痕找出来了。


使用欧喷 cv 读取一张图片是通过 im 瑞的方法传入图片的地址,返回读取回来的图像数据,读取回来的图片可以直接打印显示, 可以看到打印显示的结果是数字组成的多维数组。上节视频讲过, c v 二里面使用 num pay 存储图像数据,打印出来的其实就是 num pan 的数组,显示在 im 瑞的方法中 第一个位置参数传入的是图片的路径,这里的路径有两种形式,一,先对路径,二、绝对路径。先对路径是根据程序运行的当前工作目录来写,当前的工作目录下有个 res 的文件夹, 瑞士下有个有 buff 老师的头像,所以可以通过相对路径读取回来图片。绝对路径 是图片文件所在的词盘的完整路径。比如可以这样写, 通过传入完整路径,还可以读取非空城目录下的图片文件。这里特别要注意的是, oppo c v 不支持中文路径和中文图片名称的,在一盘下这张有 buff 点 png 虽然存在, 但是读取后打印的结果是,那 还有一点要注意的是,传入一个全英文的图片路径,但这个图片不存在代码不会报错, 只是读取的结果是烂,所以在操作图像前,要记得对图片进行非空判断。


我是陶美,今天继续我们 open cv 学习,那今天啊,我们主要来讲一个案例,也就是人脸识别,那今天的人脸识别呢?我们主要是基于这个 face 的肯定神来实现的啊,它的原理呢也是非常简单,我们先看一下它的这个效果是怎样的 啊?我呢下载了三张这个图片,分别是三个不同的人物啊,经过我们这个人脸识别系统的时候,他前两个呢都能够正常的识别,那么最后一个呢?他发现啊, 哎,这个人我不认识,就啊 no, 不认识,为什么他不认识呢?因为我们这个数据啊,他没有这个人,所以呢当他检测到一个新的人脸的时候, 他就会给你显示, oh, no, 就是我不认识。如果这个数据库里面他有,比如说有这个刘德华这个图片,他识别到之后他就会,他就会告诉你刘德, ok, 那这个就是我们今天要实现的一个小的人脸识别的一个小的案例。那我们再继续看一下今天啊我们要 用到的哪些方法,因为我们是用这个 face recognition 这个酷来实现它里面呢,首先是有这样一个方法叫 face distance, 这个主要是用来计算两个人脸之间的这个距离,这个距离,因为我们在之前的上一节视频当中也讲过,我们会把人脸的关键点进行一个编码,也就是编编,编码成一百二十八为, 他会计算这两个,一百二十八为这个项链他们之间的一个距离,来判断是否为统一个人。 ok, 那么第二个方法叫做 face locations, 这个方法呢,它主要是用来查找一张图片当中有几张人脸,没事,你给了他一张图片, 里面有三张人脸,他,那么最后他会,他会给你返回什么呢?返回一个列表,这个列表里面有三个数组,每个数组呢都是这个人脸的一个位置,也就是 location 啊。第三个方法叫做 landmarks, landmarks 呢,主要是检索人脸的一个关键点,因为我们在前几页视频当中讲过人脸的关键点呢,他我们目前学到的有六十八个关键点和五个关键点, 一般来说呢,我们会用六十八个关键点,因为他更能够刻画出一个人的一个脸部的一个一个形状, ok。 然后第四一个方法叫做 face includings, 这个方法主要是进行编码的,就是说我把你这个上面找到的这个关键点呢,编码乘一个一百二十八位,我们就是通过这个方法来实现的。那最后一个方法是叫做 这个方法,其实呢他主要是用来比较的,这是我比较你给我的这两个人脸,他们是否是同一个人,如果是,我就给你返回一个 q, 如果不是,我就给你返回一个 force, ok, 然后这边这个叫 tolerance。 零点六,什么意思啊? 我在比较的时候呢,我会设定一个预值,就说如果你小于零点六,那我就说你们两个人这个相似度比比较比较可靠,如果我计算出来这个结果大于零点六,那我就说你们两个人完全是不是同一个人, 他这个就是一个计算的一个过程。那这里啊,我给大家提供了一个 api 的一个文档,叫 face recony 一声的 api 的文档啊,各位朋友可以去看一下,我在这里,这里呢也可以,待会当我们写完整个代码之后,我也会呢,带着大家去看一下它底层 api 的一个实现。 ok, 那接下来 那我们就是开始我们今天的这个项目,首先啊我们还需要打开我们这个拍券,也就是集成开发工具,然后呢打开,打,然后呢打开我们这个啊,项目工程 face reconnation, 对吧?那在这里呢,我们要重新命名一个,呃,拍成 package, 一个一个包,比如说我们今天是人脸识别,对吧? face recognition, 然后呢我们用的是 face recognition, 我们就用这个叫 f r g 吧,对吧? face f r g 来表示,呃,就这样, 然后回车,在这里呢我们要新建一个文件,也就拍摄文件用,主要用来实现我们这个功能的,也就人脸识别这个功能。在这里呢,我们就说 face 吧, f r f s 这样写,行,可以随便写 face r g 啊,回车,然后接下来因为我们要实现 这个人脸识别吗?那我里面是不是要有一些数据啊?这个数据就是用来对比的吗?那我在这里呢,我要放两张图片进去,在这里我先 review, 找到这个文件夹,然后呢双击打开它,在这里啊,我要放放进去两张图片, 这个呢是我刚才从网上下载了两张图片,一个呢是郭富城的这个图片一,一张呢是刘德华的这个图片 啊,一共是两张图片,因为我们毕竟是一个小的案例吗?主要是给大家看一下效果到底是怎么实现的。 ok, 我们现在呢在这个小的这个项目里面,项目里面放了两张图片了, 第一章,第二章,对吧?那接下来我们就来开始写代码实现这个功能,我们稍微捋一下,你怎么去实现这样一个人脸识别呢?那是不是跟过去一样? 我们是不是要加载库?我们这边写一下你要加载库这第一步吧,那第二步你要干嘛?那你是不是,呃,要加载我们的图片,因为我这边提供了两个素材,对吧?我们待会要先我们第一步呢,我们肯定要去。 呃,实现就说把他们的人脸给他找出来,同时给他这个人脸呢进行一个 encoling, 也就是给他进行一个编码,包括他的关键点我们都要找出来,然后呢进行一个编码,那这个图片也是一样的,首先我们要在这张图片当中找出这个人脸在哪里, 然后呢给他这个绘制或说找到他的关键点,也就是他脸部的六十八个关键点,我们全部给他找到。最后呢我们给他进一个编码。呃,流程是这样的,我们这边首先是加载图片吧,或者加载素材都可以。然后这第二步,那第三步我们要干嘛?因为我们这个 open cv 呢, 他默认的这个通道是 b g 二,我们这边必须要给他转换成 r g b, ok, b g 二,我们要进行一下转换,转换成什么呢?转 转啊? rgb, 对吧?这第三步我们要转换一下图片的一个通道格式或顺序。那第四步我们要干嘛?我们这边这样写也行, 就说因为我们这边加载图片之后嘛,这第三步是这样的。第四步,我们是不是要去对这个加载的图片进行一个人脸检测,就像我们刚才讲的,你要给我检测人脸,对不对?所以第四步呢?就是检测 人脸, ok, 第四步,那第五步我们要干嘛呢?人脸检测到了,那我是不是要进行一个编码了,对吧?就说我要给这些人脸给他进行一个编码,就一百二十八位的一个编码,那我这里可以这样写,比如说人脸特 编码,对吧?我可以这样写吧。那么第六步干嘛呢?就说我们编码之后,我是不是要把这两张数图片当做一个数据库啊?当做一个数据库,为什么呢?因为我待会通过我的这个摄像头打开之后呢,我会和我的这个数据来进行比较对比,就说 我检测检测到的这个人脸,他是不是我这个数据库里面存放的这两张人脸?如果不是我就给你说一个叫做啊? no, 我不认识你, 如果是的话,那我就给你说说,他对应的这个名字就是刘德华,这个名字就是郭富城,对吧?就这里呢?第六步,也就是说我要把它放在一起组合成一个数据库,把 所有人脸放在一起当做数据库使用,对吧?这个数据库的作用啊,就是说当我通过 摄像头来识别人脸的时候,我要和这个数据会里面所有的人去比较,一一比较。如果我发现有一个非常相似这两招人脸,那我就判断这是同一个人,我再给你说出一个名称,比如说刘德华,对吧?就这么简单。那第七步要干嘛呢?我们是不是要打开我们的摄像头了?所以我们这边可以这样写,打开摄像头,要打开摄像头了, 读取视频流,对吧?你说打开摄像头读取视频流, ok, 这第七步,那第八步我们干嘛呢?那我们是不是把我们摄像头读取到的每一针,也就每一张图片 转换成一个啊?这个 rgb 格式啊,所以我们这边还是要再做一个转换, b g 二,对吧?转 rgb, 对吧?这第八步,那么第九步我们要干嘛呢?那么是不是我们也要对这个摄像头啊,这个读取到的每一张图片进行一个人脸的 检测,对吧?我们摄像头开就一直打开着,那么他会读取到每一针,我就对每一针进行一个人脸的一个检测,所以我这边呢,肯定是还是跟上面一样进行一个人脸检测, 这第九步,那么第十步我们要干嘛呢?那是不是还是和这里一样,我们要进行一个人脸的一个特征编码,对吧?这我们这边还是一样的,人脸 特征编码是第十步。那第十一步呢?那我们这边进行人脸特征编码之后,那首先啊,你看一下我们这边数据库是不是已经准备好了,然后这里呢,我们又发现了一个新的人脸,也给他进行了编码,那是不是我要进行比较了?我要把这个新的特征编码和语言,这个原来的这个, 这个数据库数据里面的所有的这个特征,这个人脸特征进行一个比较,如果发现相似或相等,我就 判断是同一个人。所以这里呢,肯定是说与数据库中的所有人脸 进行什么进行匹匹配吧,对吧?我我要和他进行一个匹配吧,那第十二步是什么呢?第十二步就是说我在匹配的时候, 我是不是要通过一个循环,因为我这个人脸啊?因为我这边才两张图片,对吧?非常少,这是才两张。那如果我这个数据会有一百万张图片,那你这里是不是还是要通过一个循环去一个一个的去匹配?所以我们这边肯定会写一个循环的。那么之后呢?我们会进行一个匹配, 比如说我这边进行开始进行匹配了,对吧?进行匹配,然后呢?第十三步,干嘛?那我这边进行匹配的时候,你怎么去匹配呢?我是不是要计算你两张图片这个编码的距离啊?刚才 我们就一直在讲,就说我们把所有图片进行一个人脸特征编码之后,他们也就说有各自的一个特征了,那怎么去来判断他们是否相似为同一个人呢?那我这里肯定是要去计算他们之间的一个距离, 这个计算距离啊,我在上一节视频当当中讲过,讲过了那个通过欧式距离去进行一个比较,如果这一块不太了解啊,可以看一下上一期的一个视频计算距离,对吧?对,第十三步。那么计算距离之后, 接下来我们要干嘛?我们是不是要做一个判断?就是说我要判断你这个距离到底是近还是远?如果发现很近,也就是说你匹配了,那我就给你说出一个名字吗?如果我发现你们两个人之间的距离很远,那我就说你们不是同一个人,对吧?所以我这边肯定是要做一个判断的,对吧?肯定会做一个判断, 如果匹配,那么就输出或者获取这个名称吧,对吧?名字,因为我每张图片都对应了名字的,我待会会给他复一个名字,比如说郭富城、刘德华,对吧?我都会给他复一个名字的, ok, 那继续, 这是第十四,那第十五干嘛呢?第十五,我们是不是当我们如果匹配之后了获取到名字了,我们是不是要在这张图片上画出一个矩形框,对吧?把它一个矩形框画出来, 就把他这个人脸给他框住,是不是?那同时呢,我们要在这个他这个下方,这边我会画一个长方形, 显示这个人的名称,就显示在这个矩形框的下方,所以我这边肯定是显示吧,对吧?所以显示呢,肯定是说绘制人脸的矩形框,对吧?绘制 人年举行框,这第十五步,那第十六步干嘛呢?那你是不是也要写上他对应的一个名称,对吧?绘制或说啊,显示吧,对应 人脸的名字,对吧?这你肯定要显示吗?不然你只是把一个人脸框给他框出来了,你下面也没写名字,这肯定,这肯定是不行的。那第十八部是干嘛呢?那最后是不是我们要把整个图片给他显示出来,整个效果给他显示出来,对吧?显示整个效果, 对吧?就这么简单。然后最后呢,我们说要关闭啊,关闭所有所有的资源,关闭所有资源,我们要释放所有资源,对吧?这第十八步,一共就十八步。先我这边呢把一些很小的一些这种操作也给他进行了细化。像我们在写代码的时候啊,你就像那个建房 房子呀,就一块砖一块砖的往里面去垒就可以了,这样呢也比较清晰,我们就接下来呢,就写一下代码吧。首先我们是加入库,一步一步来,是不是你要导入库啊? input, 对吧? input 什么库?是不是 cv 库?还要导入什么库?是不是导入我们的 nan pie, 对吧?我们这个也会用到的, 还需要导入我们很重要的一个库,叫 face recognition, 这个库你必须给我导入进来,因为我们要调用它的方法,刚才 ppt 里面我们着重强调了这几个方法,我们待会儿都会用到。 ok, 我们接下来呢,我们首先是加载图片,比如说我这边留吧,对吧?就是刘德华对应的图片吧, i am ready 的 读取这个图片,这叫刘,对吧?然后呢,我还有读取谁的?这个是郭富城的,对吧?我这边读取郭富城的图片,这边郭, 对吧?点接 bg, ok, 然后呢,这个图片我读取之后,我是不是第三步进行一个 bg 二转二 gb 啊?因为欧本思维默认是 bg 二 bg 二的这种格式或顺序,所以我这边还需要给他做一个通道的一个转换,很简单, 直接是这样,前面的高和宽不变,把后面的通道就颠,呃,颠倒一下顺序就可以了啊,颠倒顺序直接用这种这种写法就可以了,前面两个不变啊,一个负一嘛,这个就是我们列表的一种用法,对吧?所以我们这边一个,然后接下来是国嘛,郭富城的郭, 然后是通道给他做一个颠倒,这样就可以了。 ok, 这样的我们就把 b g 二转换成了 rgb, 那接下来一步呢?是不是我们要检测人脸了,对吧?我们这个图片你你输给了他,他也不知道人脸 在哪里,所以我需要对他进行一个人脸的检测,看看人脸到底在什么方位。所以我这边呢,肯定是有个叫给他一个变量叫六流 face, 对吧?通过我们的 face recognition 调用里面这个方法,通过 face, 然后呢他会提示你的叫 locations, 这个方法呢,主要是用来检测人脸在哪里的,你看他里面,他这里就提示你输入哪些参数了,对吧?他默认用的是 hog 这个算法来进行一个人脸的检测,当然 他还有一个,呃,还有个还有一种选择,就是用 cnn, 也就是通过我们的神经网络卷机神经网络来进行一个人脸检测。他为什么默认用耗子呢? 因为号码它的速度比较快一点,虽然它的精度不高,但是它速度比较快,如果你把这里的默认改成了 cnn, 它的速度就比较慢,速度比较慢啊,如果你的机器啊,你的电脑的性能比较 包,我建议你算用成 c n n, 他的这个精度比较高,我们这边呢就全部选择默认的了啊,这样速度就比较快一点。然后我们这边首先把这个图片你要给他扔进去,对吧? 我们的图片是不是我这边这样写一下,因为我们转换成 rgb 了吗?所以我这边给他做一个标记, rgb, 对吧? 我们就把这个留的这张转换后的 rgb 图片给他扔进去,这样呢,他就能够自动去检测这个人脸了。看看你这个图片里面有几张人脸,他都他都会给你检测出来,最后给你返回他的位置。 ok, 接下来呢,我们就检测一下郭富城的人脸郭, 然后呢 face, 然后再用,再调用这个方法 locations 就可以了,然后是锅而击毙,这样呢,他就会把图片里面所有人脸,这个图片里面所有人脸都会检测出来,这个也会检测出来。人脸检测出来之后, 我们是不是要对他进行一个啊特征的编码了,也就是编码成一个一百二十八位的特征项链,所以我们这边呢,还是调用这个叫 reconnesse 方法,然后调一个叫 face including 这个方法 includings, 他就会给你去做一个编码的一个工作。首先呢,你要把他图片放进来,留 rgb, 对吧?同时呢,你还需要把刚才检测到的人脸的数据给他放进来。为什么?因为你这个留 face, 我们现在这个图片他只有一个人脸在里面,那如果我们这个图片里面有很多张人脸,那你这边 得到的这个留 face 是不是它是一个数组里面有多张人脸的一个坐标,所以你这边呢要把它给它传进来,因为我们现在看到的它这个是一张人脸,但是呢,如果这图片里有多张人脸,多张人脸怎么办呢?所以你这个肯定要传进来,对吧?它这个留 face 可能是一张 人脸,有可能是有多个人脸在里面,然后呢,这样他就可以进行一个人脸的编码,对每一个人脸他都会进行一个一百二十八位的一个特征的一个一个编码。 ok, 那接下来呢,我们看一下锅 那说,呃,锅的一个 recognition re 锅,哎, sorry, 应该是 face reconnession, 我们对他已经一个编码,然后把锅的这个图片先给他传进来 说 rgb 的图片,然后把锅刚才在图片上检测到的这个人脸给他传进来,对吧?没有问题吧?然后给他复 把它,首先啊,付给一个变量,为什么呢?因为我这个减编码之后啊,他会,他会得到什么呢?他会得到很多张人脸的编码,所以我这边一定要给他复制一个变量的,比如说留,对吧? including, 当然我可以加 including, 因为我们我,我们现在知道他这个图片上就一张人脸,所以我这里呢,我就这样去命名了,但这样命名其实不太好,因为你这个刘嘛,刘德华,你这个太,对吧,你就已经知道结果了嘛。但是我们今天主要是演示嘛,我们就先这样写, ok, 然后呢,这这样呢,我们就拿到了每张图片上每个人脸的一个编码,我们全部就拿到了, ok, 那接下来我们就把他们放在一起啊,当做一个数据库去使用,怎么放呢?啊?太简单了。首先是我们,比如说我这边这样写,叫做 incoling spa, 因为是所有的嘛,我都放在一起了,比如第一个是留的 incoling 放,放里面, 然后锅的 encoding 放里面,就是这样就可以放在一起了。然后呢,我要给他们一个命名,就 names 把,就给这两张图片进行命名,因为我们一旦进行人脸识别,我要给他显示个名 称的,所以我这边呢,比如说刘德华,对吧?郭,你要用字符串,郭富城,对吧?这样就可以了,两两张图片,然后呢两个人,两个人点吧,两个人我就给他两个名称,如果你这里有很多姓名的话,你这边可以再放很多姓名都可以, 这个这样呢,我们就组合成了一个,一个数据库,一个数据库,这个是编码,这个是名称。接下来呢,我们就打开摄像头,你看我们这个每一步是非常清晰的,我建议各位朋友写代码呢,也可以这样去写,你先用中文去描述,然后你再写代码,就像那个 啊,建房子一样,你先把骨架搭起来,然后再往里面填这个砖头。然后首先呢,我们打开我们的摄像头,是不是因为我们的 cv, 然后是 v 六 capture, 对吧? ok, 打开摄像头,然后呢,我们 是不是你要判断一下我们这个摄像头他是否正常的打开了,如果没有,那我就要报错,我就要给你一个错误, io arrow 这个错误,比如说 camera row arrow, 对吧?我就会告诉你摄像头错了,你的摄像头设备有问题。 ok, 这样就可以了。那接下来呢,我们是不是要通过一个外循环去不断的读取我们这个摄像头啊?直播间,所以我这里用一个外循环, 然后这边写法很固定啊,然后是 cap, 然后 read, 对吧?这样我就能够读取到每一针了吧,也就是每一张图片这个 frame, 也就是每一张图片 读取号。读取到之后,我是不是要和上面一样进行一个呃, rgb 到 b 教的一个转换,所以我这里呢,直接给他进行一个转换,怎么转啊?是不是跟刚才的一模一样?今天是 frem 吧, fram, 对吧?然后呢?哎,然后是,呃, frem, rgb 吧,还是跟上面写法一模一样吧,这样我们就知道这个 frem 是不是已经转换,转换之后的了, 我们这边还是一样高和宽不变,把它的通道顺序变一下就可以了,这样我们就把它通道给转换好了。那接下来我们是不是和上面一样进行一个人脸检测了吧?就第九步进行人脸的检测, 检测是不是用这个方法,这个 location 一样吧,对吧?所以我们这边还是用这个 location 来进行一个人脸的检测,是不是 fast recognition, 然后呢 location 看一下啊,是 face locations, 这样呢他就会检测你这个图片上的人脸到底有几张人脸在上面。 friend rgb, 然后给他啊,把这个 返回的结果呢复制给一个变量,比如我这边就叫做 faces locations, 据说可能他有好几张人脸的一个图片,这个好几张人脸的这个数据啊,我都给他赋予了这个变量,对吧? 那接下来我们要干嘛?那么我这个人也检测到了,我是不是要给他进行一个编码,跟上面这个步骤是一模一样的,我要对他进行编码,怎么编码?是不是用这个 face recognition 里面有个叫 face includings 啊? 他这个方法都给你写好了,待会我们会看一下他底层的实线是怎样实现的。这里呢,首先我们需要把这个 fram rgb, 你要给他这个原始图片给他,然后呢你还要把这个刚刚找到的这个啊, face faces, faces locations, 刚刚给我们找到的所有的人脸的数据,你要给他,我们给他往里面一放就可以了。最后呢,他会给 给我们返回一个数组,就是一个一个列表,这个列表里面是所有人脸特征的一个编码,所有人脸的一个人脸特征的一个编码,下面这里呢也给他一个命名叫 faces, 对吧? accordance, 这样就可以了,我们就拿到了他的所有的这个人脸特征的一个编码了,全部拿到了,那么接下来是是做什么呢?你是不是要 与我们的这个数据库啊进行一个对比了,就说我通过摄像头识别到的检索到的人脸,我要和我们这边的数据库里面进行对比, 看看到底是不是刘德华还是郭富城,还是说你是其他人,对吧?我这边呢就要进行一个对比,对比你肯定要用一个负负循环嘛,因为我们数据库里面有可能有很多人,我们现在才两个人, 那你如果有一百万一一百万张图片怎么办呢?所以我们这边要用一个负循环做一个对比,对吧?这个对比呢,我们可以这样写,比如说,嗯,我能, 我可以把这个 locations 和 including 可以把它们放在一起,我们可以这样写啊,首先是啊,我先写,写完之后我再跟你讲,为什么我这么写 top, 然后是什么是 right, 然后是 bottom, 然后是什么是 left, 然后呢,这边是一个 locations, 一个 face including, 我先这样写,你还不知道我为什么这么写,对吧?啊? in zip, 然后是我们的 face is locations, 然后是 face is includings, okay, 这样就可以了,我为什么这么写啊?首先我用这个 z 盘数,就是将我的这个刚刚检测到的人脸数据和这个 includings 每个人脸对应的这个 includings 放在一起。这个 zip 函数呢,就是一个粘合函数,把他们组合起 起来,组合在一起,然后我通过一个,通过一个负循环呢,不断的去读取他们里面的每一对数据,我通过一个负循环都是不是在读取啊?那么这个 location 我刚才讲过了,他返回的是什么?返回的是坐标,对不对?就是你的,你的,你,你的这个四个坐标,所以这边呢,给他返回了 top, right, bottom, left 四个点的坐标,我都给他,我都全部给他拿到了, ok, 全部给他拿到了,然后这个 face including 呢?其实就是我们拿到的这个里面每一张人脸的一个特征编码,一一个一百二十八位的一个特征编码, ok, 这个就是负循环的一个作用,就是循通过循环拿到他们相对应的坐标和编码,就这么简单。那接下来我们要干嘛?是不是你拿到了这个编码之后,我需要进行一个匹配啦,对吧?我需要进行匹配,匹配怎么匹配呢? 很简单,我这里,哎,我把这个这个备注放到里面去,接下来就是进行一个匹配,匹配啊,我们也是有一个方法的,叫做 face 啊, recognition, 对吧?然后呢? face 里面有个叫做,看一下啊,叫做 compare, compare faces, 就我们可以用通过这个方法来进行一个比较,或者说通过一个 啊,通过这个方法来进行匹配。它里面你看你要传进去两个编码,一个是已知数,已知的人脸的编码,你要给我传进来,说白了就我们这个数据库吧,刚刚准备的还有一个呢,就是你摄像头检测到的这个 人脸的一个编码,这两个编码你要给我传过来,然后这个是一个默认值,也就是零点零点六一个预值,你不用管他,这个你不用管他,我们找一下刚才这个数据库的编码,叫做 mcolins, 这个你给他拷贝过来,然后呢,我们 通过循环读取到的每一个人脸的编码,你要给我考过来,这啥意思啊?就是说我把我检测的这个第一个人脸和我已知数据库里面所有的人脸进行对比,我看看你们两个人之间是否相似,我会计算出一个,就就是进行匹配嘛, 我会判断你们之间是否相似,会得到一个距离,你这边肯定会给我返回一个距离的,这个就是进行一个距离的一个计算。 ok, 那么,呃,我拿到啊,这边应该是一个匹配, sorry, 不是距离,距离是在下面计算,我们这边应该是因为这边是一个距离,对吧?我们在第十三步,我们会进行距离计算, 这边呢,你会拿这个匹配,他会进行判断,比如说这两个人是否相似,如果相似我就给你一个 choo, 不相似我,我就给你一个 force, 所以这边是一个匹配,叫 matchs, m, a, d, c, h。 我们这样写啊,然后接下来我们才是计算距离, 计算距离也很简单,通过我们的 face, 那肯定是里面有个叫做啊,看一下在哪里叫做 face distance, 对吧?通过这个,通过这个方法,它是计算距离的,而这个是用来进行比较的,所以我们这里呢,可以进行一个距距离的计算,也很简单,直接是 in call things, 然后呢 face including, 这样就可以了,这样就可以了,我们现在呢就可以通过这个方法来计算他们的距离,最后我们就拿到了这个距离,比如说叫做 distance is, 我们现在就拿到了啊,这个人脸和数数据库里面所有人脸进行这个计算之后的这个距离,所以这边呢也是一个列表,他有很多距离的,对吧?因为我这个数据库我现在才两张人脸,如果我有很多张人脸,那么他这个 返回的结果呢?就是有很多很多的这个数据,也就是距离嘛在里面这是一个列表, ok, 那这个距离我们就计算好了,那接下来我们要干嘛?我们是不是要做一个判断,就说我们也就是第十四步,我们要做一个判断, 就说如果匹配我们就获取到他的名字,这个判断怎么判断呢?也很简单,直接是用我们的这个易腐语句,易腐语句我这里啊,我要先将用个内内幕来做一个,就说如果我们这摄像头读取到的这个人脸 不在数据户当中,我就给你返回一个叫 oh no, 我不认识这个人,结果这边呢先给他定一个啊,这个字串的一个一个变调名,就是叫 name oh no。 然后接下来我会做一个匹配,用一个一辅一句来判断,比如说我会说 f matches, 这个里面呢,我会用的就是我们这个叫做呃 呃,距离,那么你在这里写呢?为什么我要用距离啊?其实我们你看我这个图片和数据库里面所有的人呢,做了一个距离的计算,对吧?那么这里呢,其实我会拿到一个,我想拿到一个最小的,什么意思啊?比如说 我摄像头检测到一个人脸了,对吧?我和这里的两张人脸作为一个对比,他最后给我出出来的数据,比如说和他比较相似,那么和他比如说不相似,那么他的距离就比较短,就比较小, 那么这个纸呢?和他的距离就比较大,对不对?那我就想拿到这个最小的一个距离,就说最相似的那个距离,那么这里呢?我就可以这样写,可是我想拿到一个最相似的距离或最小的距离,他又叫 mp, 里面有个叫二哥,对吧?好,二哥 mix, 二哥 mi, 对吧?拿到一个最小距 距离,通过这个方法呢,这个呢?派这个方法呢?他就可以拿到一堆数据当中所有距离当中一个最小的,说白了我就挑那个和我最相似的那个人脸的一个距离,这样我就拿到了,对吧?拿到之后我这里就可以做判断了,我会把这个最相似的距离拿过来。这个匹配,哎, 你是否和我是就你我拿到的这个人呢?或这个距离是否在我这个数据库里面存在?如果存在呢?我就说,哎,匹配上了,如果不存在,那我就说没有匹配上,结果这边呢?可以这样写, 对吧?就说如果他能够匹配上,能够匹配上,那你就去我这个数据库里面嘛,在这里在这个内幕词里面找对应的名称就可以了,对应的名字,对吧?就这里呢?如果你匹配上了,我就这边给你返回相对应的名称。 ak, ak, 其实这个这个二嘎,他的结果呢?他不是一长串的什么什么距离,那个很小,数点特别长,不是他返回的,可能就是一些什么零,对吧?什么一二正下标,就这个返回的他不是具体的数值,而是他对应的下标 啊,所以这个我这边如果这样写,各位不太明白,我就可以这样写, index 就下标的意思吗?我可以这样写,这样呢,可能大家理解起来就比较简单一点,就是 他最后返回的是一些下标,你知道吧?所以我通过这个 max 呢,就可以去找他那个对应的下标,对吧?去找他那个下标,如果他在我们这个呃赢这个数据库里面,那我就给我就说你已经匹配匹配上了,所以呢,我就可以把你这个下标拿过来,去 找他对应的这个 name, ok, 就是在这个 names 里面去找对应的这个 names, 可以,最好可以这样写,因为如果我不嫌 index 呢?很多朋友可能以为就是,哎,你这个距离那么长的数字,对吧?怎么匹配的?其实它返回的是一些下标, ok, 这样我们就能够匹配上了。 那接下来呢,匹配上之后我们要干嘛?我们是不是你要绘制这个人脸的矩形框了,对吧?我把这个备注拿拿过来, 然后绘制。人家举行过,怎么绘制啊?是不是用我们的 rectangle, 对吧? record tango, 首先是我们的 fram, 对吧?然后呢是不是你要坐标给他一个坐标?一共是两个坐标吧,对吧?我们这样先写一下, 然后呢我会这样写边框,举行的边框给他一个颜色粗细,对吧?里面的坐标,第一个坐标就是第一个点的坐标嘛?这个点的坐标很好写哦。首先是一个类 吗?然后呢是一个套,对吧?这个我们在前面的几期视频当中也给大家讲过,我这里就不再重复了。为什么这么去写?因为你一个矩形啊,你一张一拖,对吧?他这里有一个点,然后呢?然后他对角线也有一个点,这样我们就能画出一个矩形, 画出个矩形框,所以这个就是第一个点的一个坐标,那这个呢?就是一个对角线的一个坐标。 ok, 这样我们就能够把一个矩形框给他画出来, ok, 举行框我们已经画出来,那接下来你是不是还要把下面就那个,我要,因为我要显示对应的一个名字嘛,所以那个我也要画一个小的举行框,对不对?因为我要在这个举行框下面显示名称,结果呢?还想再画一个小的举行框, 那怎么画?是不是还是用 rectangle 来画,对吧? recotangle, 然后呢?是 frame, 然后这里的坐标呢?一定要注意这里的坐标,我先不写坐标,然后呢, 我先这样,不然大家可能容易弄混,然后这里还是有一个有零点二五五, 然后呢?有时候宽度还是三八,比如说,因为,呃,我还是给各位看一下 ppt 照,一定要看一下的,不然不容易了解。你看我上面一个这种绿色的一个框,把人家框住了,对吧?然后在下面,下面也就说我想显示人的一个名字在这里,对吧?那你这边是不是 往下就是,呃,他的的第一个点,就是这这个点的坐标和他的横横坐标,呃,和他的这个横坐标是相似的,重坐标是,对吧?呃,重坐标是相似的,横坐标是不同横坐。呃,看一下,哦, 横坐标相同,重坐标是不同的,对吧?第一个点就这个点,他的横坐标是相同,重坐标是不同,对吧?因为重坐标低, 是在这边是零零吗?那你这边的动作标肯定不是零零了,对吧?那这里呢,也是一样的,这里和他的众坐标,众坐标是一致的,但红坐标又不同,所以我们这边可以这样去计算,这个就主要是一个计算的一个 计算的一个过程,比如我们这边可以说他的横坐标相同,对吧?第一个点的横坐标相同,动作标不同,那我就这样写吧, ot 点三十,比如说,因为我是显示在各位朋友,再看一下,我是显示在他下方,对不对?下方,所以呢,我用这个 bottom, 其实这边不用减加也行,我用加吧啊,当然我们待会可以看一下效果, 加一下就行了,因为剪的话这个效果感觉有点丑。然后这边呢,继续一个 right, 这样 bottom, 我们具体待会会看一下效果,来调整他这个坐标的一个位置,我们可以调整的,因为 这边呢,我也是感觉应该是这样的,我们待会可以试一下。啊,这样呢,我们就把这个名称的矩形框给他绘绘制出来。名字的矩形框绘制出来了,那接下来我们要干嘛?你是不是要在这个矩形框里面写上他的名字呀?对吧?所以我们这边可以这样写, 显示啊,啊,显示吧名字,我们把这个改成时期显示名字, ok, 然后呢,我们实现一下,怎么显示啊?是不是我们 cv 库里面叫做 put text 这个功能,对不对?然后呢,是我们的 fram 这个图片,原始图片,然后是我们的要显示的名字,这个名字呢,我在这里已经给大家注视了, 如果他不认识就显示,哦, no, 不认识,如果认识他就会去这个 name 里面根据下标去检索 检索,如果是第一个就是刘德华,第二就郭富城,他会一一对应的去检索,然后这边呢就会显示,然后呢给他一个坐标,比如说这样写吧, let 也是左边的,对吧?这我给大家加个十吧, 这个比较好理解。坐标,这个比较好写,这个显示你只需要,呃,加三十吧,加三十,对,然后呢这个跟这个和上面的要一致,就这个这两我们先一致的看一下,加三十,然后呢我们这个 bottom 减三十,我们这样试一下,然后看一下效果,然后我们的字体,字体是不是之前讲过啊?你不用去记,用这个 complex, 默认的 complex, 然后是一,然后呢是我们的啊,字体颜色,我们就这样写, ok, 然后呢字体的一个大小粗细, ok, 这样就可以了,这样就可以了,我们继续这样,我们就把字体给他写上去了,对吧?写上去之后我们是不是要看一下整体的一个显示效果啊?整体的显示效果,呃,这个很简单,直接是用我们的这个 c v m 秀就可以了, 比如说我们这边叫 face recognition, 对吧?然后呢把这个 flip 给它显示出来就可以了,这边应该是十八了,对吧?我们这边写一下,改成十八, 显示整体效果,这样就可以了,看有没有问题,哎,不对,那这个应该出来,不能在负循环里面,不然会爆错,这样就可以了。那接下来我们是不是要做一个判断,就说如果你这边按下了这个 esc 键,或者说 q 键, q 键,那么我就退出,如果你按下了这个 q 键,我就退出,只用一个 f 一句,然后呢用个 y k, 这个我们在之前讲了很多遍了,我就不去讲这个 功能了,他很固定你,如果你按下了 q 键,我就退出,整个这个循环也就关闭啊,就把整个程序都给他终止了。最后呢,我们会关闭所有的资源。二十 说关闭所有的资源,怎么关闭呢?是不是我们有个叫 cap, 对吧?哎,我看一下是不是在 这边有个叫 cup, 对吧? frake 应该是我们的 cup 点 release release, 然后呢? 然后是什么?是我们的 cv, destroy or windows, 没问题吧?我们会释放所有的资源,对吧?然后我们看一下有没有问题, 没问题,看一下。我担心这个坐标显示的时候可能会有点乱,因为这个坐标你需要算一下的他那个位置,不过影响不大。我们先看一下有没有问题,我们先运行一下,看一下效果。 哎,好像有问题哦好像有问题哦。在这里他说 list index out of range 超出了界限,在四十八号,在这里我们看一下是哪里的问题 啊?二个,对吧? indexes, 然后我们这边用了一个 f matches, 对吧?匹配,我们进一个匹配,然后呢,如果如果他匹配上了,我们就找到他对应这个 names, 对吧?看一下哪里的问题 哦,错呢?你看到他这里说超出了这个范围,其实啊,这里是没有问题的。错,是错在哪里呢?我们这边啊漏写了一个,一漏写了一步,就是在这里漏写了一个东西,在这里出错了, 就我们这边必须要加上他的一个坐标,不一个啊?这个零为什么呢?要提取一下呢?因为我们这边呢,你会发现我们这边是一个人脸,对吧?那么我刚才讲过了,如果这张图 边上有多张人脸的话,那么你这边他肯定就说你这个返回,如果我不写零的话,他返回的是一长串的这个这个 encoding, 就所有的编码,比如说三张人脸,那么他这边拿到的 就是三张人脸的一个特征变吧。那今那我们这边是一个数据库,我们知道他只有一张人脸,所以说我们就只只取第一个人脸的一个数据,所以我们这边必须要加上零, 这个他的作用就是说我们提取里面第一个人脸的一个特征编码,第一个人脸特征编码,我们比如我们这个图片他就一张人脸,对吧?那么我这边计算出来之后,你一定要把它提取一下,就加上这个零, 他就提取他的这个第一个特征编码,如果你这边不加上的话,他就会报错,而且报错呢还很奇怪,他还报错在这里,这里根本就没有超出他的界限和 范围,所以呢我们这个写代码呢,他有时候我们一旦一不小心啊这个就报错,而报错之后你会花很多时间去找这种小问题,这种小问题有时候你很难去一下子找到的,就是,所以我们这个一定要注意,一定要注意,那我们在运行下看看 有没有问题,如果有问题我们就再找问题,我们运行一下让一下, 哎,现在是没有问题,对吧?只是呢他有点卡, 他只是有点卡而已,我们先退出。 呃,有点卡,主要是第一个呢卡可能和我们这个算法有问题吧。还有一个呢, 就是我们这边这个视频,可能这个框窗,这个窗口太大了,我把这边稍微调小一点。怎么调?我在这里稍微调小一点,比如 friend, 对吧?然后点 recise, 我把它呃,把它 recise 一下就行了。应该是这样 re recise, 然后呢?我们的 frame, 然后原图我把它调小成一半吧,就把窗口缩小为一半,这样一半大小,这样会快一点。可能会,我们这样试一下,我们再运行一下,看一下 把窗口调小一点,这样可能会速度快一点,哎,这样就可以了,对吧?你看这样它的速度会比较快一点,只是我们这个字体它显示到上方去了,我们要把这个 这个这个位置要调一下,不然那个字体在上方,对吧?我们再推出再改一下字体,再改一下这个坐标,这个坐标我们这个坐标要改一下,我看一下他往上跑了,往上跑了,就字体在这里,他往上跑了,我们只要改这里就可以了。把这几个改一下。 怎么改呢?他这个应该是不对的,这个应该是因为他往上跑了,往上跑了,我们这边肯定要减十,减十,然后左边左边加十吧, 试一下看下效果怎么样就行了。然后这边不是加,应该是减往下跑,往上跑了,这样我们再再运行,看下效果是怎样的。我们再运行一下这个,这是一个坐标的调整,如果你发现这个坐标他跑的就是 有点偏了,你可以调整一下。哎,这样就这样就可以了,你把坐标调整之后啊,他这个大小这样就可以了,对吧? 你看他现在有时候识别,是啊, no, 无法识别,然后有时候又能识别出刘德华,对吧?把我识别错误了,对,他,因为为什么他会识别错?主要就是我们这边的 数据库的素材太少了,就两张图片,所以呢,他的特征是太有限了。那么接下来呢,我们有另一门课程,就是深度学习,也就轻松学这个拍 touch, 也就深度学习的一个框架。那这是我们新的一门课程。接下来呢,我会通过卷机神经网络来给大家讲一些这种人脸识别的一些项目,它的精度包括速度啊,比这个要快的多。我们这个是算法比较传统,用的是 他集成了一个算法,比较传统,然后呢也比较慢,当然也和我的机器有关,因为我是笔记本,所以他跑起来速度就比较慢,如果你的这个设备比较高级高配, 那可能速度就比较快点。好了,那今天我们这个任务呢,就就先讲到这里,应该刚才出现一个问题啊,主要就是我们这边 要把它提取,第一个我们这个没有提取,所以他就会报错,他会报错这种小问题,其实有时候你你很难发现的,要去找一下。 ok, 那今天任务呢,我们主要是这样的,已经实现好了,那这个代码,包括整个项目的代码我都会分享在我这个云盘里面, 各位朋友可以在视频下方去找一下这个链接啊,可以找到所有的这个项目,包括代码、 ppt、 k。 那我们再稍微看一下这几个方法吧,这是我们今天调用的几个方 方法,像 distance, locations and the marks, 关键点对吧? includings, 然后比较人脸。然后呢,这边有个 ipa 的文档,改进去的朋友呢,可以去看一下,去看一下他这个官方文档。 ok, 那今天我们任务呢,先到这里,如果啊,你有任何疑问呢,可以在视频下方给我留言,那么我将及时啊进行一个回复。那欢迎各位朋友呢,继续学习后续的课程,拜拜。

我是淘米,今天继续我们 open cv 学习,那么在上一节视频当中,我们主要讲了这个人脸的跟踪,那么今天啊,我们主要任务呢是进行一个目标的跟踪,也就是基于我们这个得力不酷啊,选定一个目标物体,然后进行一个跟踪,那它具体的效果是怎样的呢?我们可以看一下这个视频, 有人说我这边有一部手机,然后我选定了这个手机,然后呢当我在移动手机的时候,那这个矩形框他就会随时的跟踪,就时时的跟踪。 我们今天的主要任务就是实现这样一个效果,但是各位朋友还是需要注意一下,在我们这个视频的左上方,他有一些文本的显示,对不对?他会提示你有些信息,比如说,呃,点击鼠标的左键,然后选择一个区域,然后再释放,那么你就你就能够获得一个 跟踪的一个目标,对不对?所以我们这边会有一些信息的显示,而且呢这边还有个,当你按下这个数字一的时候啊,他这边写了叫做 star truck, 就你开始跟踪,当你按下这个这个键盘二的时候呢,他就会提示你 stop tracking, 就是停止跟踪,当你按下键盘 q 的时候,也就说退出我们这个,这个也就退出我们这个摄像头,或者关闭摄像头啊,然后呢这边还有一个状态,就 no tracking, 当你啊选择了二的时候,按下键盘二的时候呢,他就会说我没有在跟踪了,我停止了跟踪,所以这个就是我们今天整个案例的一些功能,包括像信息的显示, 像鼠标事件,对吧?你在键盘上按下数字一二以及 q, 它的功能是不一样的,它显示的信息也不一样, 所以今天的这个案例呢,稍微有一点点复杂,不过也不难,很简单,我们接下来呢就通过代码给大家进行一个呃,进行一个演示。首先我们还是需要打开我们的这个工程 face recognition, 然后呢我们在上一节视频当中,我们是是做的这个 face tracking, 对吧?基于我们这个得力不酷,那么这个就是我们上一节视频当中写的两个代码,那今天啊,我们还是继续创建一个新的一个拍摄文件来实现今天的这个功能。 首先我们是是对于目标的一个跟踪,对吧?所以我们这边命名叫 object, 然后叫 tracking, 对吧?然后基于我们的得力不酷就行了 啊,我们在做这个实现这个功能之前,或实现这个案例之前,我们先捋一下思路,他到底是怎么实现的?我们这边先用中文先捋一下思路,首先是你要加入库, 对不对?那第二步呢,你是不是要打开我们的摄像头,打开摄像头对不对?那么第三步你想一下你要干嘛?第三步你是不是要设定一个窗口名称?窗口名称为什么?因为我们这个像这个案例你看到了 他,当你你在运行之后,他这边是有一个窗口的,那么在窗口里面我们会通过鼠标来选中这个物体, 所以呢他就会有一个鼠标的一个动作或一个事件,对不对?所以我们后期呢会将这个鼠标的动作会添加到这个窗口上来,也就绑定到这个窗口上来,这样你的操作才能够被接收到,被读取到。 所以我们这边必须要先设定窗口的名称。 ok, 之前我们是没有的,不过这次呢,我们需要这样去做。 ok, 因为我们现在增加了一个鼠标动作或鼠标式 事件了。那第四步我们要干嘛?你是不是要将?呃,当我们创建窗口之后,你是不是要将我们这个鼠标的事件,对吧?鼠标的事件绑定到窗口上去,对吧?绑定到窗口上去,这是我们的第四步。 那第五步干完呢?你是不是要进我们这个 delete 库,你要启动这个跟踪器,对吧?因为我们要跟踪这个物体嘛,所以你肯定要启动这个跟踪器的,它是据我们这个 delete 的方法有个里面叫 call relation, 然后叫 tracker, 它是根据这个方法来启动的, 这是第五步。那么第六步呢?当我们启动跟踪器之后,我们是不是也要假设一个状态?这个跟上一节视频当中一样,就说我们这个在摄像头在跟踪的时候,他有一个状态,就一个是处,一个是 force, 当这个状态是处的时候,说明你的摄像头正常在启动, 包括跟踪器在跟踪。如果你这个状态是 force, 说明你这个摄像头会比或者关闭了,或者没有跟踪,对吧?所以我们这边要假设一个跟踪状态的,假设跟踪状态这第六步。 那第七步呢?想一下第七步我们要干嘛?叫你?当你假设这前期的这些工作做好之后,你是不是要通过一个外循环来读取我们这个摄像头读取到的每一针了,对不对?所以我们这边肯定是一个,是肯定是一个循环嘛,对吧?循环读取我们的视频流, 我这里就先写一下歪处,这个是肯定不变的,对吧?歪处,然后呢?第八步是什么呢?第八步你是不是要获取我们这个每一针了,对吧?获取每一针,这第八步,那第九步呢?想一下第九步干嘛?你获取到每一针 之后,因为我们刚才这个案例啊,你看到了他的这个左上角,他是有一些提示信息的,对不对?我刚才也讲了,他有提示信息,当你按下不同的键,他这边显示的这个信息是不同的,所以我们这边还需要。呃,就说有一个方法,这个方法我们这边还没写, 他一定是实现或说显示这个信息的,所以第九步呢,我们这边会调用一个方法来显示提示的信息,我们这边肯定会调用方法的,我这边做一下备注,调用方法,这个这边肯定是调用方法的。那么第十步呢? 想一下,因为我们我刚才讲了我们这边他这个功能怎么实现的,你也看到了,我首先是这样的,我给大家再演示一下,因为这个呢,如果不理解啊,你就可能就觉得这个项目这个案例有点困难,我这边 再给大家演示一下,比如说我这边,对吧?选中了这个点,然后呢再一拖一拖选中了这个手机,对不对?所以你这边首先是第一个点在这里,然后你将你鼠标一松的时候,那么第二个点就在这里,对不对? 当你按下第一个点的时候,那么这个点的坐标就会被被他接收到,那么当你在这里一松鼠标,他就会收取到你的第二个坐标,当这两个坐标被,当第一个坐标和第二个坐标被确定之后,那么这个 这个目标物体啊,他就被框选住了,对不对?所以我们这边会得到两个坐标,一个是这里的坐标,一个是这里的坐标, ok, 所以我们最终呢,我们会接收到两个坐标的,也就是两个点嘛,两个点。所以我们这边呢,也是说,如果啊,我们这样写一下备注,如果获取到的 坐标点为两个,其实肯定是两个了,因为你这边如果你选的话,肯定是一点一个坐标,然后再一拖,再一松,就两个点了吗?那如果你在这随便点一点,他肯定不是一个区域,他就是一个点, 对吧?所以这边肯定是获取了两个坐标,你这两个点,那么就对吧,我这边做一下备注,那么你就绘制出什么呢?绘制出这个矩形框,对不对?你就要绘制出 里面写一下,绘制出矩形框,以及也要用,以及也要让 delete 吧,他的这个,呃 rectangle rectate rec, 他有这个 delete 酷,他有一个 rectangle 方法,让他也知道你这个 这个坐标在哪里,我们这边要写一下啊,知道坐标点在哪里, 为什么呢?就说你为什么要让这个 deliberate recten 过方法知道在哪里呢?因为你你只有让 deliber 酷,他知道你这个,你选的,比如说我你选中的这个物体,对吧?在哪里, 他就能够实时的去跟踪了。就你必须要让这个德利博库里面这个 ton 国也知道你这个坐标,你这个矩形框到底是在哪里 让他知道之后,比如你在移动的时候,那么他就知道,哦,你这个坐标怎么变动的,到底在哪里了,对吧?他就会实时的跟踪。所以你这个,呃,后期我们一定要让这个 delete 的那个泰国方法也要知道这个坐标点,那这点一定很关键,不然的话他会报错或说他就会他他无 无法起到这个叫跟踪的一个起,起到一个跟踪的一个作用,所以这里一定要记住。然后呢我们这个第十一步做完之后啊,第十步做完之后,我们就第十一步, 也是我们要根据这个状态来判断这个跟上一节视频当中一模一样,当你这个状态是去的时候,对吧?那么我就要开始跟踪,我就要启动一个跟踪器, 同时呢我还需要获取到你这个跟踪的这个位置,对不对?然后我在你这个位置上再画出一个矩形框,对吧?这个跟上一节视频是一模一样的,所以我们这边肯定是一个叫判断,对吧?如果跟踪的状态为这个处, 那么对吧?那么我们要干嘛呢?你是不是要更新这个跟踪,更新一下跟踪的这个呃窗口或说更新一下这个跟这张图片你要跟 更新一下,如果你不更新的话,那他就是一张禁止的图片,谁这边一定要更新的同时呢,你还需要获取到这个位置嘛?然后呢绘制矩形框,这个就是我们的任务,这个就是我们第十一步的任务, 那么当你这边判断他是去之后,对吧?你这边就可以获取到了吗?那么第十二步是什么呢?我们刚才讲了, 刚才讲了,在这里我们再看一下,这个 ppt 上,我们这边是不是显示了状态信息,对吧?在这个左上角,当你按下一的时候,他是开始跟踪,二的时候是停止跟踪, q 的时候是退出,所以他这边呢,你必须要做一个判断,你到底是按的是一二还是 q, 所以接下来呢,我们这边是做一个事件的一个判断,就说啊,可以这样写,事件判断,怎么判断呢?主要是根据这个, 呃,按键,按键,根据这个按键,对吧?你到底是按下了是一还是二还是 q, 对吧?那我就做出不同的一个反应嘛,对吧?所以我这边肯定是呃,做一个判断的, 那么最后呢,是显示我们整体的一个效果,最后啊,我这边再写一下,最后呢就是说显示 整体效果,哎,这样呢,我们整个任务啊,他基本上主要就这样实现了,不过这里呢,我们要写两个方法的,第一个方法就说你要显示信息,对不对?所以我们这边呢,要比如说我在这里,比如说我再增加一下啊,定义, 定义方法,他主要是用来显示信息的,对吧?对,我们定义方法,那么你还是在需要定义一个方法,为什么呢?因为我们这边有这个 动作,有一个鼠标点击的动作,对吧?鼠标点击的动作,当你点击之后,他就能够获取到两个点,所以你这边还需要再定义一个方法,也就是定义方法,鼠标点击的事件, 这个这两个方法你肯定要写的。那么接下来呢,我们就一步一步的来实现这个案例的这些功能。首先是我们要加入一个库,要加入 cv 库, 加入我们的格力布库,对吧?这两个库你一定要加入,那接下来呢,我们是不是就是要打开我们的摄像头?我们一步一步来,不用着急,我们先打开我们的摄像头, cv to 里面的叫做 video b do capture, 对吧?这个方法我们写了很多遍了,然后呢给它一个零,默认零。然后呢我们接下来就是要设置窗口的名称, your name 这个 window 吧 window 我随便写一下,比如说 nine window, 你可以这样写,比如这叫做目标跟踪,对吧?目标跟踪我们的 nm window。 然后接下来呢,我们需要, 我们需要就是将这个鼠标事件绑定到窗口上去,那么在绑定的时候呢,我们要调用它一个叫 name 呃 name window, 然后把这个窗户名称给他就行了,这样我们这个窗户呢,他就有了一个名称,对吧?他就有了一个名称,这样呢我们就可以把事件绑定上去,怎么绑定呢?他一个叫做 set mouse, 对吧?他有这样一个方法,我们直接吊用就可以了。然后是我们的 name window, 你要放这里,同时呢,我们是不是要有一个鼠标的点击事件,对吧?鼠标的点击事件我这里还没写,因为刚才已经给大家讲了,我们这个肯定要定一个方法,比如 我这边就定一个方法,定一个鼠标的点击事件,比如说我这边就叫做 mouse, 对吧? event, 对吧? handle 了,这就是我们的一个鼠标事件,我这边先不写他的一个具体代码, pass 一下,然后这里呢肯定就是 啊,把这个点击事件的名称放这里就行了,这样就给他绑定了吗?就把我们这个鼠标点击事件绑定到了这个窗口上了。那接下来呢?我们就是需要启动我们的跟踪器,也是我们这边叫 track, 对吧? tombe deliber 酷,它有一个叫做什么呢?叫 correlation tracker, 这样就能启动我们的跟踪器了。然后第六步就是假设一个跟踪的状态,比如我这边叫做 tracking state, 假设他默认为 force 刚开始没有跟踪。那么接下来呢?就第八步就是巡 读取每一针,那么怎么怎么读呢?是不是太简单了? frame, 然后是 cat petra 点 read 就可以了,这样我们就读取到每一针了。然后我们要显示信息提示,这边我们方法还是没写。我们这边呢?比如肯定还是要再定一个方法叫 show information, 对吧?你肯定要这样写的, 我们先不写这个方法,我们这边直接先定一下,有时候我这边肯定要显示一个叫秀 info, 对吧?你肯定要调用这个方法的,那么第十步你要干嘛呢?他说如果获取到坐标点为两个,那么就绘制数据情况, 也要让 the leopard rectangle 方法知道坐标点在哪里。那么在这里啊,我们首先先把这个方法你要实现一下,比如说你按下了鼠标的点击事件,那你是不是要给我传递进来一些东西?比如首先你这个事件是什么,对吧? 比如说你是鼠标点击还是弹出还是拖拉,对吧?我这边肯定需要一个事件的一个类型,对吧?事件的类型,那接下来我们还需要什么呢?那么你是不是要给我一个坐标,你的 x 坐标和 y 坐标,你说 我在这里拖拉这个点,他这个点的坐标在哪里?你必须要告诉我,对吧?你必须要告诉我,然后呢?他还有个叫默认叫 flax, 这个呢,是默认的,你就说你这个如果去掉这两个参数啊,他是默认的,你去掉这两个参数呢?他会报错,他会报错,但他具体什么意思呢?像这个弗拉格,他就是表示发生时的一个状态,比如说当我们事件在发生的时候,你按下鼠标,松开鼠标, 他就是给他默认的传递了一个这样的一个一个状态,也就是当你在调用这个方法的时候,他就会把这个状态传递给 这个 flax, 现在他是默认的,你不用去管他这个 parm。 是呢,他是什么意思啊?他就说官方讲的,就说他是指向任意对象的指针, 也是说作为一个附件的参数传递给了这个参这个函数,这两个参数你不用管他,你直接往里面一写就行了啊。但是你还不能省,省略他,你省略他,他,他就会爆错,你这边一定要注意一下,注意一下,所以我们这边呢? 呃,在这里啊,我们还需要再定一个一个列表,为什么?因为我们这个鼠标你在点击的时候,你在选中,比如说你在 选中这个物体的时候呢,他会有一些坐标点,对吧?那这个坐标点呢?比如说我这边点了一下啊,一拖在这里一松,这不两个点了吗?那这两个点你要放哪里呢?我们就用了一个列表来存放这个点的坐标,就叫 point, 我们专门用来存放它,就是我这边写一下 存放,对吧?这个鼠标点击鼠标 啊事件的坐标点吧,这样写,就说这个破案你必须要这样写的,他是存放我们这个鼠标事件,他所产生的一些坐标点,我们就放在这个列表里面,一定要写上,因为我们我们要用到的,我们要用到的, 那在这个鼠标事件的时候呢?我们先用一个 global global 什么意思呢?他就是说让一个变量啊,作为一个全局,在我们整个这个程序里面,他都可以随时的被调用,在哪里都可以使用,所以我们前面要加一个叫 global, 为什么呢?因为我们后面要用到这个破案子啊,为啥我们要 通过这个 points, 也就坐标来显示,对吧?来显示的,所以这边肯定要用一个 global points 的,对吧?全 调用,他的作用就是全局调用,他就像是什么呢?他就像加了一个格洛布之后啊,他就等于这个破案子拿了一张这个,呃,通行,通行证啊,全球通行,到哪都可以啊,真的是到哪都可以。 然后呢?这个定义好,这个 pose 之后,我们接下来呢就是要做一个事件的判断了,比如说你这个事件他到底是什么样的一个类型,对吧?如果你这个,比如说应该是也也也会去判断吗?如果他 与这个别说叫做 event, 这个 c 位库里面有个叫 event, 如果呢?他你看他分为鼠标的左 l 就是 left, left, 对吧?如果你这个鼠标是一个档,到我按下的时候,那么它就是一个档一个档的事件,对吧?所以我们这边可以这样写,如果它 是一个鼠标点击,而且鼠标他有两个按键左右,这个一定要注意,当我们按下左边的时候,就是他就是一个档的一个事件,如果他是这个档,我这边再做一下备注,鼠标左键按一下,对吧?这样一个事件, 那当我这个鼠标左键按下,他会干嘛呢?他是不是会产生一个坐标点,对吧?那我就把这个坐标点呢,放到会添加到我们的这个列表当中来, 你当你的鼠标按下他肯定有个坐标点的,那么我就把这个 xy, 对吧?放到这个 point 里面来,放到这个列表当中来,对不对?那么我还需要再做一个判断,就说如果你不是按下, 而是什么呢?而是松开,比如说你这个事件,他是你按下之后,因为我们在这里啊,比如说我在 各位再演示一下,我先把它删掉,插入形状,对吧?我在这里,比如说我按下一个点了,我这样一拖,然后这边一松,对吧?他这个松的,你最后一松,这一下他又有,他又产生了一个点,所以这个坐坐标呢,也会被拿,也会被拿到,所以我们这边叫 event, 对吧?这个叫 up, 你松开了吗?当然是 up 了,对吧?鼠标左键松开,那么它又会产生一个坐标点,那这个坐标点呢?我们还是需要放到这个 price 这个列表当中去,用 a pen 的方法就可以了,然后我们把这个呃 x 和 y 放里面就可以了。 ok, 这样呢,我们就把他的这个鼠标事件啊,一个按下,一个松开的点呢,全部拿到了,对不对?就这么简单。那么当我们拿到了这个事件之后啊,拿到这个 坐标点之后,再就在这里我们就需要做一个判断了,我们需要做一个判断,你说我是不是?比如我这边可以做一个判断,破案一次,我就需要判断你是我是否拿到了两个点,如果你这边, 如果你这里啊只有一个点,那你肯定不是没有,没有选定这个这个坐标吗?没有选定这个物体,对不对?别说我在这里就按了一下子, 你肯定没有选中这个物体,因为他不知道你这个物体到底多大,对不对?所以你肯定要给他选中一个区域,选中一个区域,那这里肯定是有两个点的,没问题吧?没问题。 所以这里呢,我要做一个判断,我是否拿到了两两个点,如果拿到两个点呢?说明我已经选中了一个区域,然后这里在这里呢,我们就可以做一下绘制。 天狗,我有个天狗做一个绘制,对吧?比如说怎么绘制啊?你是不是要把我们这个 friend 放这里,然后呢?是不是我们要放一下坐标点?比如说第一个坐标点是什么?是不是我们的 pons? 也就零嘛?它里面的第一个元素?那第二个坐标点很简单哦, 这是我们的 poins 啊,第二个嘛,对吧?零,也就是他的下标,就是第一个做标点,当 point 一的时候,那就取到了他的第二个做标点,没有问题吧? 然后呢,我们给这个坐标点一个颜色二 o 点零,然后,嗯,再给他一个粗细,比如三吧,对吧?这我们就把这个矩形框给他画出来了,给他画出来了。 那同时呢,我们还需要让 deliber 的这个 recort tengo 方法,要知道这个坐标点在哪里?咱们这边可以用一个 deliber 点 recort tengo 方法, 然后呢把我们的这个坐标点要要告诉他,这就破案子。这里啊,和上面写法有点不太一样,因为这里呢,只要你如果是零的话呢,他就获取到了,就获取到这样一个一个一个坐标点,他是一个原组,对不对?他就获取了 xy 这样一个原组,他们是整体的, 他们是一体的,所以呢,他你这边零啊,他就获取到了,获取到了,这样的,我这边给大家再做一些备注吧,不然有的人可能他不理解这里了,可能就有点迷糊了。这边呢,他就会拿到一个 xy, 一个这样的原组,然后这个 points 一呢,他也会, 他也会拿到一个 sy, 这边是 point, 不是 point, ok, 就说你零和一呢,他分别会取到,呃,坐标,这个是第一个坐标点,这个呢,他会拿到第二坐标点,那么在这里呢, 我们要这样取了零,对吧?然后呢?零,然后呢? points, 对吧?零一,我先写完再跟大家讲,是什么意思? points 一 零, points 一一 okay, 这样呢,我们就告诉了 rectangle 它的这个坐标点,第一个什么意思啊? 这个什么意思啊?是不是我把第一个点,第一个坐标点的 x 告诉了他,对吧?零,零直接取到第一个,如果是零一就取到了 y, 对不对?这是第一个坐标点,他全部给取到了, 那么第二座标点呢?也就这这里一零,他就把这个 x 拿到了,一一,他就把这个 y 给拿到了, ok, 这个就是这局代 码的意或意思,他就是取到了两个坐标点,他们的 xy 分别取到 x 和 y, 然后呢 我们把这个纸啊,哎,这边写,我们然后把它复制一个变量,比如说我们这边叫做的 lib, 对吧?复制的一个变量又 rectangle 嘛?这个矩形的一个一个位置他就拿到了,我们就复制给一个变量, 那接下来呢?我们要判断这个状态呢?他是处,对吧?如果是处我们应该怎么做?所以我们这里呢可以这样做一个判断, f tracking, 对吧?如果我们这个状态 他是,比如说是一个处,他在这个跟踪,那我们这里呢?我们就要时时的更新我们的这个 free, 如果你不更新呢?他这个画面他就会停滞,我们这边要更新画面叫做给,那接下来我们 是不是你要获取到这个位置,对吧?我们的圈课,然后呢? get position, 获取位置坐标,获取位置的坐标,这个我们一定要拿到,然后呢我们是不是要绘制了,对吧?当我们这个在跟,就是说他在启动跟踪之后,我们是不是要绘制他,所以我们这边可以这样写 rectangle, 然后呢我们的 frame, 然后这里呢是不是跟上面写的一模一样?两个坐标,然后呢你还要给他一个颜色,对吧?我们这边奥物我们先这样写完, 然后带一个粗细三,里面是什么?里面是不是我们的?呃,这个,呃,坐标里面就是我们的坐标,两个点的坐标,因为你要画一个矩形框,我们这边已经获取到位置了,对吧?我们这边里里面第 第一个就是第一个坐标,第二个呢就是第二个坐标,我们这边分别写一下,有时候叫 int, 然后是什么?是 post 点,呃,这个 left, 这第一个点坐标,然后呢?第二个点的坐标是 int post, 然后是 top, 对吧?这是第二个点的坐标,这第一个点 left, 这个是第二个点的坐标,我们全部拿到了,对不对?然后呢?哎,这边不对,这边还要,还少了一个,还少了一个, sorry, 看一下硬特,这边容易写错,所以一定要注意,这边非常容易写错。 inter 应该还有一个是 post 点,应该是 top, 对吧?一定要注意,这边容易写错,所以各位朋友一定要注意。 left, 然后呢?这样 inter 这边 还有一个 inter post 点 bottom, 这样我们就拿到了两个点的坐标,这个是第一个点的坐标,这个是第二点的坐标,颜色还那个粗细,我们都全部弄好了,对不对? ok, 那接下来呢,我们要怎么做?我们这边是不是有一个时间的判断了, 倒看你到底是你的按键是一二还是 q, 所以我们这边有一个有 e 辅与句来做一个判断。 if, 我们先像这样写,比如 key 吧,你的按键 key, 首先是我们的 c v to 里面有个叫 wet key 一,然后呢?再零 x f f, 对吧?我们要做一个判断,如果你这个按键他是,比如说他是一,我们应该怎么做?我们他的一,我们这边讲了看一下这个 ppt, 如果你是一的话呢,他就开始一个跟踪,对吧?这边写了, 如果一的话呢,他就开始跟踪,所以我们这边应该是这样写,如果这个按键他是一,那我们就首先要做一个判断,我是否拿到了, 就我是否拿到的点,他有两个坐标,就这很重要,你如果没有没有,只是点了一下,他肯定是画不出来这个这个矩形框的嘛。所以我这边要做一个判断,我是否拿到了两个坐标,如果拿到了坐标的话,那我就给你启动一个,对吧? 启动一个公众器,我这边要做一个判断的, e f 这个 point 是否等于二?如果他等于二,我就启动一个公众器。同时呢,把你的这个刚才 我们通过的内部库这个 rectangle 方法获取到的这个矩形也给他,也告诉他,也告诉我们这个跟踪器,这样呢,他就会实时的去跟踪,因为你这个位置位置啊,一直在变的,他这样就可以实时的去 跟踪了,对吧?放在这个跟踪里面,然后接下来我们要干嘛?是不是你这边还是在需要设置一下他的这个 checking 的这个状态,对吧?你要给他设置成 q, 因为他刚开始设设置的是什么?是 force, 对吧?所以你这边呢,还需要把他的状态改一下,同时你要让他的 points, 对吧?变为空或重置一下。为什么呢?因为我这边重启之后,他变成了去了我这个点,他是实时在更新的,所以我这个里面的坐标要给他重置一下,重置一下就行了。 然后呢,我们要接下来看一下,是吗?另一个 for for 循环,我们再继续看一下,不然这个 e f, 一句说错了,是 e f, 一句我们要再做一个判断, e f。 如果他是说他是二,怎么办?如果当我按下了键是二,他是怎么办呢? 到我们这边看一下,当我按下二键的时候,他是停止了跟踪,然后呢重置了一下,对吧?所以我们这边可以这样写,如果他按下的键是二,那我就把你的这个列表,也就这个坐标点这个列表给你清空,那你就重置了嘛,同时呢把你的跟踪的状态 改为了 force, 就是说我给你重置了,给你重置了,那如果你这边的按键呢?它是 q 怎么办呢?那我那是不是退出了,我就直接退出了,对不对?就我这边就直接退出了,就这么简单。然后最终呢,我们要把整个这个检测的效果给它显示出来, 通过我们的 m 秀就可以了。然后我们这里啊,首先呢,你要把他的这个内幕给他,我们窗口名称你要给他,同时呢你要把我们这个 frem 你要给他,这样就可以了。 最后啊,我们要关闭所有的这个,也就是我们显示整体效果嘛,在这里,对吧?把它拷贝过来,拷贝过来。然后呢在这里呢,我把该关闭的全部给他关闭掉, 然后我这边关闭 capture, 释放所有资源,然后呢关闭所有的窗口, 对吧?没有问题吧?全部关闭了,对吧?这里, ok, 我们这样看一下有没有问题,现在我们把这个鼠标事件给他,已经实现了,对吧?给他实现了,只是我们这边的显示信息还没有实现。显示信息呢,跟我们上一个视频当中讲的是一模一样的,就说,呃,就说 跟这个一模一样,你说你在这里啊,你按下一什么这边去一大堆信息给你显示出来,怎么显示呢?我们可以实现一下,实现之后我们再运行吧,再看功能, 当然我们也可以先这样运行一下,看下效果,看看我们这个鼠标事件有没有问题,如果有问题我们再改,我们先运行一下,看看有没有问题, 哎,没问题,对吧?然后我们这边呢这样写一下,比如说我这边拖住一个矩形框,然后松手, 是不是把我这个你给他框住了,然后我再启动一下,按下一键他就会启动,哎,这边是有问题的哦,你看这边这个矩形和画的是不对的,也就是有问题,那我们改一下这个问题,我们改一下他是应该在蓝色这里,对吧?他这边应该是有问题的,这个问题我来看一下是在哪里?应该是在这里, 应该是在这,对吧?这里是有问题的。其实我们这边的坐标是有问题的,我们重新改一下,因为这里呢确实容易写错,我们这样写一下, 对吧?然后呢我们这里面也继续这样再写一下,也就是他的坐标点,因为刚才我们刚才写的时候,这可能是出错了。 你说我们这边第一个做标点是印特,对吧?然后是我们的 pose 点什么 left, 对吧?第一个我们第二个做标点呢?是不是我们的 pose 点啊?这边是 left, 要加一个括号,不要写错, 这边是容易写错的,所以一定要注意,我们这边是 pose then top。 然后呢第二个这边我们再写一下 int post 点,那时候 right, 对吧?然后我们再继续写 int, 这就是两个点的坐标 post 点 bottom, 对吧?这样就我们再试一下,看有没有问题,因为 确实这个比较长,所以容易写错,我们再运行一下,看有没有问题,哎,然后我们呢选定一个区域,比如我的脸部选定一个区域, 然后呢启动一下更动器,这样就可以了,他这个蓝色框呢?就已经出来了,对吧?没问题。然后我们呢再重置一下,重置是不是按我们那个二,刚才已经通过这个键盘二就重置, 然后呢我拿一个手机,比如说我手机在这里,对吧?然后呢我选中他的这个区域,比如说,哎,我这样拿中,然后呢我选 拖一下第一个点,然后呢我再松开,对吧?一个框选中了,我再按一下,一键这个启动更动器,这样你可以看一下他是不是,哎,还是不太准,哦,还是不太准哦,对吧?哎,效 不是特别好,效果不是特别好,我们可以再重新的试一下,还是不不够准确,对不对?是不是不够准确?我们再试一下,我们再重启一下,重置一下,然后我再这样选定一下这个坐标,你说选定松手, 然后呢我把这个公众器再按一下,一 ok, 他就已经在开始了。 慢一点,是不是在实时的跟踪,但是不够准确,对不对?所以我们这个算法,或者说他这个性能还是有问题,有很大问题的,我们再把它关闭吧,我们关闭一下, 那最后呢,我们实现一下这个信息的一个显示,这个功能怎么显示呢?很简单哦,很简单,跟我们上上一个视频当中讲的是一模一样。在这里啊,我们 直接给他设定他的坐标显示的方位,比如说第十行,第,呃,第十行,第二十列,对吧? 我这边我们给他这样显示一下啊。 pose two, 第十第四十,我随便写的,你也可以设定他的这个显示的坐标的范围或者这个位置,这个位置你可以自己去设置, 问题不大问题不大。然后接下来呢,我们是不是要显示一个信息了? in four 我这边比如说,呃,当然这里不要写中文,写中文他会乱码,所以你这边最好这样写,别说 hold put 吧? left 然后呢是比如说 button, 你的鼠标的一个左键 pot, 然后呢,选中一个区 select an area, 对吧?然后呢, 怎么怎么怎么说呢?然后是 start talking 呗,对吧? start talking 随便写吧, talking 当然可能英文写的不对啊,就这样。然后接下来呢,我们就给他另一个信息, in for two in for two 干嘛?我们这边是不是要提示这个用户,当你按下, 哎,当你这边呢,按下一的时候,是不是你就要开始这个 truck 了?你是不是要开始跟踪了? 当你按下二的时候,你要干嘛?你是不是要停止跟踪? stop tracking 刚才我们功能全部实现了,给大家演示过了,你按下二,他就停止跟踪了,你按下一,他就开始跟踪了。 然后呢,当你按下这个 q 键呢,他就是退出了吗?当你按下 q 键,他就是叫 exit x exit, 他退出了,对吧?这个就是我们 显示信息,然后呢,接下来呢,我们是不是要把它显示出来? put text 首先是我们的这边你要传,传进来他的 frame 的 frame, 同时呢,你要把他的 check in state, 他的啊,跟踪状态,你要给他传进来,然后我们这边首先是 frame, 然后呢,显示第一个信息,对吧?然后呢,他的位置在哪里?是不是 pose 一啊?然后呢,他的字体的字体的格式,我们还是跟上节课一样,选择第一个字体,然后字体的大小, 然后呢?字体的颜色,对吧?没有问题吧?然后呢,我们再显示第二个信息, protects, 然后是我们的 friend, 然后是我们的 in four two, 对吧?我们的 in four two 放在第二个位置,然后我们这边格式是 是一样的啊,然后是 c four 点 front complex, 然后呢大小,零点五,颜色,白色,白色, 这个是很固定的,这种写法很固定,接下来呢,我们就根据这个跟踪的状态来做一个判断了,不同的状态显示不同的信息,如果我们这个 checking 他是一个处,那我们就这样出处嘛,他正在跟踪,对吧?我们可以这样去写,比如 free, 然后我就说 checking now, 正在跟踪,对吧? checking now, 然后呢,在显示他的位置,在三这个方位给他显示,在同时呢,给他一个字体的颜色是 found, 对吧?就这个颜色,然后字体的大小,呃,字体的 颜色刚才是字体的格式啊,那么这个是字体的一个颜色, ok, 然后呢,我们这边用个 lc, 一句,如果你是 force 的话,那我就给你显示另另一条信息吗? frame, 然后呢? stop tracking, stop tracking 停止了这个跟踪,然后呢放在 pose 三这里,它的字体大小就是 font, 没有问题吧,然后是零点五, 然后是二,嗯,零点二五,五点零,这样就可以了,对不对?这样我们就把根据不同的状态显示了不同的信息,对吧? 不同状态显示不同信息,我们再运行一下,看看一下有没有问题啊?这里应该有问题,我再看一下,在应该有问题啊,在这里我们必须要传递 参数过去,这里刚才没有传递,说明这边必须要传递他的 tracking 和这个 frame, 要给他传过去,然后我们再运行,看一下有没有问题。 ok, 你看到了吗?在这个左上角呢,他就已经显示出了这个信息,也就是这个英文的提示,一是开始检测啊跟踪,二是停止跟踪,这个 q 呢是退出,现在是停止停止的一个状态,比如说我现在选定我这个人脸比如说我现在选定我这个人脸, 然后呢再按下一,他就开始了跟踪,对吧?他就开始了跟踪,没有问题吧?那么当我按下二的时候呢,他就会停止跟踪,比如说我按下二键,哎,他就停止了 stop tracking, 对吧?停止了跟踪,那如果我想再次啊跟踪选 问题怎么办呢?我就在选定我的头部,再这样一拖松手,然后呢再按一下一,他就变更换了颜色,这样你就可以再跟踪了。 ok, 这个就是我们基于这个得力不酷来实现这个人脸的跟踪和目标的跟踪 啊,也不是很复杂,但是呢,有很多注意点,比如说像坐标的这个设置这一块,包括像鼠标事件这一块,所以一定要注意, 因为这边容易出错,刚才我们也出错了。好啦,那今天呢,我们的今天,我们的主要任务啊,就是啊,这两个一个是人脸的跟踪,一个是目标的跟踪。 ok, 代码呢,其实并不多,但是呢注意点比较多,他容易出错,容易出错, 其实我们这边刚才也出错了,所以一定要注意,一定要注意,那么各位朋友也不用担心啊,啊,我这个代码呢,所有的项目的代码我都会 分享在这个百度云盘里面,各位朋友呢,可以自己去下载,可以把所有的代码自己去练习练习,这样呢也也比较容易让自己很熟悉一点。 ok, 如果你在学习过程中有任何疑问,可以在视频下方给我留言,那么我将及时的回复。那欢迎大家继续学习后续的课程,拜拜。