陶敏,今天继续我们 open cv 学习,那今天内容呢,也很简单,我们啊做一个项目,这个项目呢就是通过 opencv 来进行人脸检测。今天我们的目标就是说确定图片中人脸的位置,并且呢画出这个矩形框, 比如说如下图所示啊,我们这个照片当中有一张人脸,对吧?然后我们的这个项目呢,最终他会实现能够确定这个人脸在在哪里, 同时呢在这个人脸的周围画上一个矩形框。今天任务啊,主要就是这个,那么当这个任务实现之后呢,我们也会通过我们笔记本自带的摄像头来进行这个人脸的一个检测。 ok, 这个就是我们今天的主要任务,那我们如何来实现这个功能呢?也很简单,今天啊,我们呢主要还是通过 opens 自带的这个啊,分类算法,或说这个检测算法,也就是这个叫 hard cascade, 这个叫 hard 吉年算法。那么在这里呢,我还是需要先给大家稍微讲解一下它的原理,然后我们再通过代码实现以上的所有功能, 那它的原理呢,也很简单,主要是四个方面。呃,这个算法啊,我推荐大家如果感兴趣呢,可以去读一下我这个下面这篇论文。这个论文呢是在二零零一年发表的,也就是说将近二十年前发表的一篇论文,它非常具有里程碑的意义,所以呢,各位朋友可以去看一下。然后呢 我们先了解一下它的原理啊,它的原理,其整个论文,它的论文啊,呃,就说读完下来,主要是讲了四个点,第一个呢就是说我们通过这个叫 hard 这个特征去做检测,它的功能 很简单,就是说在一张照片当中不断的去检索,哪里会出现人脸?就他他的这个第一步啊,主要是去检测检测这个人脸会在什么地方, 那第二步是什么呢?就说叫做 integral imager。 integral imager 什么意思啊?就是积分图的意思,这个第二步的这个功能呢,就是说通过积分图来加速这个特征的计算。 为什么呢?因为我们一张照片里面人脸可能会非常多,可能不止一张人脸,对吧?也有可能是有很多很多人在一起, 那么如果你去一个一个的去做这种检测,那么他的这个最终的计算量是非常非常惊人的,就算是一张非常小的照片,那么整个计算量下来也可能是非常惊人的。那么我们这个积分图的作用就是说来加速他的一个计算。那接下来关这个积分图 如何去计算?我建议大家呢可以看一下这个我推荐的这个博文,这个博文里面呢,对整个积分图他如何计算的?这个算法的原理讲的非常清楚,各位朋友啊,可以感兴趣看一下。由于这个时间,时间原因啊,我这里呢就不给大家详细去介绍他这个过程是怎样的。 那第三一步呢,就是这个 her 这个吉吉年算法呢,它用了一个叫做 other boost 算法,这个算法 我给大家显示一下,就是这个算法呢,他是什么呢?他是选择关键的一些特征,然后呢在整张照片里面进行一个人脸和非人脸的一个分类 啊,对,那么这个 other boost 的算法呢?它也,呃就说它是什么呢?它是通过啊,我们这个里面一些弱分类器,把让这些弱分类器呢去检测人脸,最终呢就是说通过弱分类器的一个 结果啊,我们来做一些判断,哪里是人脸,哪里是非人脸。主要是这个功能啊,这个 add boost 的算法呢,它主要是继承于我们那个叫 boosting 算法啊,感兴趣的朋友啊,也可以去了解一下这个 boosting 算法。那么第四一步是什么呢?第四一步就是吉年,也就是我跟我们这个叫哈尔吉年 啊,一样的一个意思啊,吉年他什么意思啊?因为我们这个 other boost 的算法之后呢,他会有很多的弱分类器,那么吉年的时候呢,就说把这些弱分类器啊,全部的堆叠在一起,形成一个强分类器,就他的功能啊,就说 把所有的弱的全部堆叠,就一层一层叠加在一起,形成一个更加强大的分类。这个有点像我们中国有句古话叫做三个啊,臭皮匠啊,对吧?赛过诸葛亮,也就这个意思啊啊 cascade, 你可以把它这样去理解, 那么我们整片论文啊,主要是讲了这四点,感兴趣的朋友呢,可以去看一下这个这个原文啊,我觉得讲的还是比较详细的,那么,呃,当然如果你看这个论文不太理解,也可以 看下面这个叫参考博文它里面的这个这个详解吧,我觉得作业还是非常不错的,非常详细。 那么,呃,这个叫 open cv 源码是什么意思呢? openc 源码,就是说,呃,我们需要,因为做我们这个项目啊,你需要到这个 github 上,就说你需要输入这个网址,你可以把这个网址呢拷贝一份,然后在你的浏览器里面把它输入进来,粘贴一下, 然后呢你会进入到这样一个页面,在这个页面啊,你需要把它下载下来,就把我们这个 open cv 的原码库给它下载下来,也也就是 download 这个 z p。 那下载下来之后呢,你只需要解压一下就可以了,解压之后 会得到什么呢?它就会得到我们这样一个,呃,就是 openca 诶,它就会得到一个叫 openca 的一个一个文件, 那这个在这个文档当中啊,他有很多他的原码,这个原码呢,待会我们会用到里面的一些文件,这里呢我,我先不给大家介绍,待会我们用到我再给大家介绍。 ok, 这个就是我们这个哈尔基呢,它的主要的四个过程, 其实这个原理啊,你也没如果真的不能理解,呃,也不太影响,为什么呢?因为我们后期接下来就是直接通过 open c v 库去调用一些方法 啊,用起来是非常简单。 ok, 那么在这里呢,我还是想强调一下,就说对这个第一步做一下稍微的讲解啊,做一下稍微的讲解。这个图片呢,是我从这个论文当中截取的,给大家做一下参考。那么他的第一步啊,就说使用这个哈尔 like 特征做检测啊,这一步啊,它主要是计算一个特征值,那么这个特征值它怎么计算的呢?很简单,就是说啊,因为我们这个,呃,这个算法呢,它提供了一些这种叫做特征模板,比如说有边缘检测,边缘检测特征模板,还有呢叫做这个线条或者线性 检测特征模板,还有一个就是对角线的一个特征模板,他这个特征模板主要是用来检测我们人脸的,比如说,呃,根据这个论文所讲解他这个特征值的计算,就说我们这个白色矩形的像素和 减去黑色,减去黑色矩形像素和比如说我们这是一个人脸,对吧?我们这个特征模板,哎哎,他不断在这个图片上进行一个人脸检测,那么当他停到一个区域的时候,他 会把所有这个白色区域所对应的像素值全部累加,然后呢再减去这个黑色区域所累加的所有的像素值,那么最后相减之后就得到一个特征值, ok, 这个特征值呢?他会进后期啊,他会进行一个排序,进行一个排序, 然后呢将这个最大的特征值当做我们人脸所在的一个区域。 ok, 这个我只是通呃,把这个论文当中啊我理解的这一点呢,给大家做一个讲解,感兴趣的朋友呢也可以去看一下这篇啊论文。 ok, 我只是这边稍微提一下他这个特征值怎么计算的。 ok, 那么在我们这个 open cv 库当中,呃,也就是我们这个 hard 这个算法呢,他也提供了四个分类器,这四个分类器啊,不需要我们自己去训练或说去运行,我们 opencv 直接提供了,接下来我们 直接调用就可以,这个你不用去记忆,我们待会给大家进行演示,非常简单。 ok, 我只是给大家提呃,提示一下,他有针对这个人脸的正面的这种分类器直接可以调用。那么今天内容呢,主要是讲这一款,那接下来我们通过代码给大家进行一下演示,怎么去实现一个人脸检测,对吧? ok, 首先呢还是要打开我们的拍 charm 这样一个集成开发这个工具,那么由于我们是做这个软件检测呢,呃,各位朋友可以新创建一个工程项目,就是 new create, new project, 然后在这里呢,你需要重命名,比如说你随便选一个名字都可以啊, 然后我这里呢,由于提前已经创建好了,我就不去创建了,那么这个项目工程创建好之后,呃,很重要的一点就是你需要添加一些软件库,怎么添加呢?我这里再给大家演示一下。首先是拍 chop, 然后有个叫 呃 preferences, 就说啊,这个偏后设置,那么在这里呢,我们要选中这个叫 project 啊,然后再选中这个叫 project interpret, 也就是我们的项目的解释器。那么如果你是刚创建的一个项目啊,这边呢,基本上都是空白的,就你这啊,可能也就只有一两个,这种,就这个叫软件库,或者或者说叫软件包,可能你只有一两个,不像我这里有这么多,那么你怎么去怎么去安装这些呢? 也很简单,直接去添加这个加号,添加加号就可以了。在这里呢,你可以比如说我想安装 open cv, 输入 open cv, 对吧?然后你找一下 open cv, 比如说这边有 opencv, 对吧?那么你一般来说,你只需要安装这个 passion, 呃,安装这个 opencv passion 就可以了啊? ok, 呃,当然,呃,应该是这个 opencv passion, 然后点击 install package, 这就可以了,因为我们这个呢是安装好的啊,我这边我没有安装,我可以点一下安装,那么它就会自动安装,当然你也可以安装其他包,比如说我想安装这个 nampai, 对吧? nampai 安装好成功之后,它会提示你的叫做 successfully, 如果说你想安装南派呢,点一下南派,然后安装, 他就会自动安装,这么简单,就说你这些库啊,这些包,你都可以通过这个加号进行安装,哎,非常简单,比如说我想安装 mart plot lib 这个库,你也可以点一下安装就可以了, 非常简单,它会自动安装, ok, 这个就是如何给我们整个项目呢?去安装一些软件库,软件包, 那么就是这样安装的,安装好之后啊,你可以点一下这个叫 apply 应用,或者 ok 就可以了啊,非常简单。那么这个项目这个库安装好之后啊,接下来呢,我们就进行我们代码的一个编写了,首先我们 在这里呢,一般来说啊,因为我这边已经提前给大家创建好了一个一个 package, 怎么创建呢?呃,如果你是一个空的一个项目啊,你需要右击,然后一个叫 new, 然后一个叫 python packager, 你这里呢可以重名,比如说你可以说 face, 对吧?比如说我说 detection 啊脸,人脸的一个检测,那么你也可以说人脸的一个识别 recognition, 对吧? 这这个就是就像我们在桌面创建一个文件夹一样,一模一样。那么今天我们主要是讲这个人脸检测,还没有讲到人脸识别,我们就创建一个叫人脸检测一个文件,我一个文档, 然后呢在下面我呢拷贝了这四个分类器,或者一个哈尔吉的一个分类器,因为刚才我们在 ppt 里面讲过啊,在这里这四个分类器啊,是我们 opencv 提供好的,我们直接把它拷贝过来就行了。怎么拷贝呢? 也很简单啊,因为你刚才我刚才给大家介绍过,第一步就是你需要下载这个 open cv 的源码库,然后在源码库里面,在这个 data 这边有个叫 data, 然后你看一下 data 这里呢有一个叫做 hard cascades, 比如说 hard 几年分类器, 他这里呢帮你把所有的分离器呢,哈尔吉的分离器全部放在这里了,你看到了吗?有很多。那今天由于我们是检测人脸啊,那么我们只需要选择,比如说像第一个对吧?这个是一个 face 对吧?这个是,这个是检测眼睛的,对吧? i 就是检测眼睛的,我们今天不讲眼睛,我们主要是检测人脸,第一个是,第二个是对吧?第三个是 front face, 就是正脸的意思,正脸第四个对吧?第五个,第六个, ok。 呃,就我们这个 oppo c v 算法呢,给我们提供了五 五个关于人脸、正脸的一个检测分类器。我们把这几个啊可以这样拷贝一下, copy 就拷贝一下就行了。拷贝之后呢,我们需要把它附粘贴到我们的这个项目下面。怎么粘贴呢?也很简单, 比如说这是我们刚刚创建的一个文件夹,右击,然后叫 review, 就说你去找到它在我们目录当中这个文件夹的一个位置,那么你找到之后呢,双击一下, 把我们的所有的这个啊分类器啊,直接这样粘贴就过来就可以了。我这边已经粘贴好了,所以我就不给大家演示了, 粘贴好之后呢,然后你把它关闭就可以了,那么这里的这个分类器啊,就全部在这里呢给大家给就说全部罗列出来了。分类器我们拷贝好之后,接下来呢,我们可以呢去啊拷贝一些素材,比如说今天我们要做人脸检测,那么我们会检测这张图 片,他能不能发现这里面有三张人脸,还有一个呢,我们也会检测这张人脸,就说你看这些人脸的方位,他不是方方正正的,他有角度对吧?他有斜的,有侧的,那我们这个分类器能不能很好的检测出来? 今天的任务呢,就是去检测这两张图片当当中这个当中的人脸。 ok 啊,那么这图片怎么去添加的呢?跟这个添加分类器一模一样,你还是 review 对吧? review, 然后呢进入到我们这个文件夹,也就这个 face detection, 然后把你想要检测的人脸图片拷贝进来就可以了,然后把它关掉,那么他就会在我们这个项目里面出现。 ok, 那么前期的工作啊,就是这样的,创建一个项目,然后呢添加我们的软件库,然后把这个分类器从 opencv 库里面给他拷贝过来就可以了, 然后把你的素材拷贝过来,那接下来呢,我们就是通过代码来实现这个图片上的人脸检测,首先我们需要右击一个 python 文件,比如说 python 对吧?然后我这里呢,比如说 face, 对吧?啊? hard detection 对吧?我们用的是 hard 这种算法进行一个人脸检测 detection, 然后呢直接是这样回车就可以了,我们现在新建了一个拍摄文件,接下来呢我们就写代码来实现,我们啊输,首先我们先不要写代码,我们先就是想一下这个思路 怎么去进行图片上的这个人脸检测。我们先想一下这个思路,我们先用中文给大家描述一下,比如说第一步你是不是要导入一个库,对吧?那么第二步呢?你要干嘛?你是,你是不是还是跟我们之前讲的一样,就说你要定一个方法,这个方法主要是显示图片的显示图片,因为我 我这边比如说我要传递这张图片,那最后我要显示出来,对吧?那这个方法呢?主要是用来显示的,他的功能主要是显示图片。那么第三步我们要干什么?我们想一下就说你图片显示啊,方法定义好了,那接下来我们是不是也要定一个方法, 这个方法要干嘛呢?你是不是要绘制图片中检测到的人脸,对不对?就说这个方法,我们就是让他来检啊,绘制这个人脸的这个矩形框,表示我们这个,呃,这个 ppt 当中, 你看这是一张图片,对吧?那么这个方法就是说我要画出这样一个矩形框,它的功能就是画出矩形框。 ok, 我们也要定义这样一个方法,简就说画出人流的矩形框。那第四一步我们要干嘛?我们是不是要写一个主函数,对吧?比如说我们写一个主函数,那这个主函数里面我们要实 哪些功能呢?也很简单,比如说我这边给大家演示一下,比如说主函数写好之后,我们是不是要要读取一张图片,因为我们这边放了两张素材,那接下来呢?我们要读取,对吧?也就说我要读取 一张图片,对吧?啊?读取一张图片,那之后我们要干嘛?读取图片之后,你是不是要把我们的这张 bgl, 也就是说彩色图片转换成灰度图片?因为我们叫哈尔分离器啊,就说你在读取图片的时候必须要转换成灰度,也就是你要转换成 灰度图片, ok, 这是第六步。那么第七步你要干嘛?你转换成灰度图片之后,是不是要用我们 open cv 自带的这个叫海尔分类器来进行这个,这个分类,对吧?或者来进行检测。这个就是我为什么说这个项目 简单,因为我们这个 open cv 啊,给我们提供了一些方法,所以呢非常简单。第七步呢,我就要写一下,比如说通过 open cv 自带的方法,对吧?那他这个方法是什么呢?其实就是我们这有一个叫做 cascade, cascade, cascade, 然后是一个分类器 classy fire, 对,我们通过这个分类器呢?干嘛呢?来加载? 比如说吉年分类器,就我们用它来加载我们的这个分类器来进行区分。呃,这个图片上哪里是人脸,哪里不是人脸?就它的功能主要是用来分类的,比如说以下,哎, ok, 主要是这个功能 通过 open cv 自带的这个方法来进行这个分类,对人脸进行分类。 ok, 那么 这是我们第七步。那第八步我们要干嘛?说你这个,你这个人脸啊?就说我,我这边通过 open cv 加载了这个分离器之后,那么第八步呢?我是不是要通过这个分离器来对图片中的人脸进行检测,对吧?因为刚开刚开始我们是加载嘛,加载这个分离器, 那接下来呢,我们要通过这个分离器对人脸进行检测,那我这边写一下,比如说通过第七步,对吧?那么通过第七步加载,通过第七步吧,然后呢对图像中的人脸进行检测,这是第八步了, ok, 基于上一步来对图像中的人脸进行检测。那么第九步是什么呢?是不是当我们把所有的人脸检测到之后,我们是不是要去绘制了?那绘制的时候,其实就是调用这个方法, 调用这个绘制图片中检测到人脸的这个方法来绘制就可以了,所以我们这边写一下,比如说绘制图片中的图片中检测到的人脸就行了,对吧? ok, 这是第九步 啊,第九步,那么第十步是什么呢?当我们把这个人脸绘制出来之后,我们是不是要显示啊?对吧?那么你显示呢?是不是跟我们上节课讲到的一样,你要创建一个画布,对吧?那我们这个人脸显示这个图片显示在这个画布上,所以你这边要创建 画布。 ok, 创建画布之后,那么最终呢,我们是不是要显示了?所以我们这边最终显示整个检测效果, ok, 就这么简单。那最后呢,我们是不是还要这边有一个主程序,对吧?进入到我们这个慢函数主程序 去入口, ok, 就这么简单,就我们整个项目啊,主要是这十二部分,那么我们再捋一下,首先你要导入库,然后呢你要定一个方法来显示我们这个图片的。 那么第三步呢,就说你要绘制图片中检测到的人脸,因为我们后续后期啊,会通过我们这个 opencv 的这个哈尔基联呢,他会检测到人脸,那你要把它绘制出来,对吧?画一个矩形框嘛? 那么我们接下来就我们的主函数了,第一步呢就是读取图片,然后呢转换成灰度图片,然后我们要调用这个 open cv 库里面这个叫吉年分类器, 那么通过这个极点分类器呢,我们要对图像中的人脸进行检测,对吧?那么啊检人脸检测到之后,接下来我们就要调用这个方法来绘制这个图片中的人脸,那最后呢,我们要创建画布来显示整个检 效果,整个过程就这么简单,那接下来我们通过代码实现第一步很简单吧,我们首先是导入我们的 oppo cv 库,然后呢在在主要是 oppo cv 库,对吧?然后我们在干嘛?是不是我们还需要导入我们的南派,对吧?南派 还需要导入什么?我们的 mart, plot lip, 对吧?这个基本上我们前面都讲过,这几个库基本上都要导入,那么接下来我们要显示这个方法,怎么显示呢?是不是修,对吧?修 image, 你要显示这个图片吧, 那么你显示图片,你是不是要传进来一张图片,然后呢你还需要传进来它的这个 title, 也就是标题, 同时呢你还要传进来这个图片显示的位置,所以这这三个参数啊,你都要传进来,通过我们的主函数来传进来,然后呢我们需要将我们传进来传进的这个图片的这个顺序啊,就是通道 改一下顺序,它本来是 b g 二的,对吧?我们要把它转换成什么呢? r g b 啊?这一块呢,我也是在之前的视频当中反复给大家强调过,我们这边需要给它转换一下的, 比如说我这边写一个 i m g, 然后呢是 r g b, 这是一个变量名,一个名称而已,我们需要将传进来的图片这个 image, 呃,转换成 r g b 这个通道的一个顺序,怎么转换呢?前面的高和宽不变,把后面的通道的序列顺序转换一下就可以了。 那接下来呢,我们需要把它放在一个指定的位置上,我们这里啊,就写一个叫二两行两列吧,对吧?两行,呃,两行,呃,两行两列吧,两行两列,对。然后呢就说我们一共显示四张图 片,为什么四张图片啊?我后面会给大家讲解到,为什么这样要让他显示四张图片啊?二和二的意思是说我们一共啊会出现四张图图图片,那么这个 pose 呢,就说我要把这张图片放在哪一个位置上,因为他有一二三四嘛,对吧?你要放一个位置,指定一个位置, 那这里呢,我们继续,比如说 p o t title, 我们要啊,指定一个 title, 对吧?然后呢我们是不是要显示一下 p o t i'm show, i'm show 什么呢?你是不是要把这张图片给它显示出来,对吧?然后呢,你还需要关闭这个坐标,你要关闭它的坐标 看一下啊,你要关闭整个他的坐标轴,怎么关闭呢?很简单,直接是 off 就可以了。关闭这个这个方法,这几行代码呢,就是显示我们的图片的, ok, 哎,那接下来呢,我们写一下,实现一下如何绘制图片中检测到的人脸?比如说,我这边写一个方法,比如说叫做 plot 吧,因为我们要画一个矩形框嘛, rectangle, 对吧?画一个矩形框, 然后你要画卷印框,你是不是要把这张图片传进来?同时呢,你需要把你检测到的人脸给我传进来,也就 faces, 我不管你检测检测到几张人脸,你都要给我把这个数据传进来,对吧?那我这里呢,先不写,我先 pass 一下,待会我再来实现这个方法。 ok, 我们接下来呢,实现一下这个主函数吧。首先是读取一张图片,比如说我这边 imager, 然后呢, i'm read 读取一张图片。我,我今天我们先试验这个 family 这张图片,我们先检测这个 family 吧,我们这边呢,读取一张 family 这个图片。 首先,呃,读取图片之后,接下来呢,我们需要对他进一个灰度的转换。怎么转换呢?有没有印象?是不是 open cv 库里面有个叫 cvt 卡了,对吧?然后呢,我们把这个图片放在第一个参参数,然后对他进一个灰度的转换 color, 对吧?然后是 b g r to gray 就行了。 ok, 这个主要是进行一个灰度的转换。 那那接下来呢,我们是第七步通过 open cv 自带的这个,呃,分类器就集联分类器啊。呃,我们要加载一下这个分类器, 怎么加载呢?很简单, opcv 就是用的这个方法,非常简单。我们首先这里啊,加载一个分类器,那我们今天呢,先用,因为他这里有四个分类器啊,刚才给大家讲过了,他有四个分类器,那我们今天呢,还是先用第二个吧。 我们先演示一下第二个,这几种方法其实差不多,我们先演示用第二个分类器,我们这边呢命名一下,比如说,呃,分类器用的是第二个,对吧?然后我这边调用一下,叫做 c v, 也就是叫做喀斯 class k d 的 classy file, 对吧?调用我们的分类器,那么这里呢,我们要填一下,就我们要填写这个分类器的名称,你要和这个一模一样,比如我这边拷贝一下,怎么拷贝呢?我们这边有个叫做,呃,当然你也可以这样写啊,比如说我这边 review 一下, 因为你不要自己去拼写去敲,你可能会写错这个名称,不然哪里报错你都不知道。我们这边点一下,对吧?我们拷贝一份他的这个名称,全选拷贝就可以了,缩小一下。在这里呢,我们把他这分类器的名称要拷贝过来。这里 呀,你可以自己去敲代码敲一一的对照,但是呢,我担心你会写错或者你漏写,这容易报错的啊,千万要注意。我这边呢直接把这个分类器啊,就给他已经加载好了,因为他已经 opencv 提供的嘛,我就加载好了。 那接下来加载好之后,我们是不是要用通过我们这个分类器对人人脸进行检测了,对吧?怎么检测呢?也很简单,比如我这边直接是还是用这个 face 吧, art a face art, 然后呢 detect 就进行检测,怎么检测呢?直接是调用它,它有一个方法就是 detect, 你看 detect multi scale 就就多维度的一个检测,我们调用这个方法就可以了,然后把我们转换的这个灰度的图片给他传过来就可以了,他就会针针对这张图片进行一个人脸的检测, 那么检测之后啊,他就会返回这样一个结果,就说检测到的一个结果,比如说它里面包含了几张人脸,对吧?他就会给你返回回来。那这个结果我们拿到之后,是不是我们要在啊这个图片上把这些人脸给他绘制出来,也就画一些矩形框。那么在这里呢,我们需要传给我们的方法,这个方法就是 绘制图片中检测到的人脸,也就我们要传给这个方法,叫做 plot, 对吧? rectangle 方法,我们要传给给他,传递给他,怎么传递呢?这个太简单喽,我们直接是 plot, 对吧? 调用这个方法,然后你要把图片传进去,那这里的图片传呢?不是传灰度了,而是传这个 image 这个图片。我们这里啊,我们可以这样写,把这张图片给它传进去,然后我们 copy 一下,就说我们用它的一个备份,不用这张图片本身,我们用一张备份的,当然你也可以用它本身 没有问题,你可以这样传,没问题,但是呢你也可以用他的一个备份,对,就保持他原有图片不会被修改啊, copy 一下就可以了,就拷贝一份图片,然后呢我们后面把这个结果给他,给他拷贝过来,这是我们检测到人脸的一个结果,给他放里面, 然后呢他就绘制绘制这个绘制好之后,他是不是要给我返回一个绘制好的图片,所以我们这边一定要命名一个,就是一个去接收他,比如我这边还是这样, 因为我是用的这个方法嘛, result 吧,就说你绘制完这个图片之后,你必须要给我返回一张图片,也就说你绘制好的那个人脸的图片,对不对? ok, 就因为接下来我要把这个图片,把这个结果啊给他进行显示的, ok, 那么这边,比如说你传给这个方法之后,具体怎么实现,我这边还没写,我先不管, 对吧?我先不管,我先把下面下面的写完。比如这边要创建一个画布,怎么创建画布呢?有没有印象?是不是我们的 pot 叫飞哥,对吧?然后呢?飞哥, size 也就我们的这个画布的一个尺寸的九六,对吧? 然后呢,我们要创建他的一个标题 super title, 对吧?比如说我们这边随便写个要 face detection, 对吧?威斯,我们用的是 heart 这个分类器或者吉年分类器 kid 卡斯,对吧?卡斯 kid 还有卡斯 kid 没问题。然后呢,我们需要呃,给他一个字体大小吧? from size 吧这个超级标题,用我们的标题画布的标题,我们给他一个字体的大小十四,然后呢,字体的粗细,我们给他一个 呃,加粗 bow 的,对吧? ok, 这是创建了一个画布,那创建画布之后,我们最终呢要显示整个检测效果,怎么显示呢?我们想一下,是不是我们直接调用这个方法就可以了?因为我们这里呢定了一个 显示结果或显示图片的一个方法,我们调用它就可以了。怎么调用呢?很简单,这是 show imager, 把我们的这个结果啊给他传传递给他就可以了,我们这边给他传过去。那么传过去之后,我们是不是还要给他一个标题,因为我们是用的这个方法,我们就这样命名,然后呢我们把这个结果显示在第一个位置上,就是第一个位置,我们显示最终的这个检检测结果。 那么接下来呢,我们关键就是实现一下他怎么去在这个图片上把那些人脸给他绘制出来,很简单哦,很简单。这边啊,我们 这个拿到这个检测到人脸之后呢,我们比如说我这边拿到检测到的人脸数据,其实这个数据啊,比如这个 faces, 你给我传过来之后呢,他是有一些数据的,他这边有四个值,他会返回四个值, 比如四个字。我写一下,首先是这个坐标,他有坐标给你返回回来,比如说这个人脸啊,他的一个坐标 x, y, 他会给你,同时呢他也会返回这个人脸坐标,他的那个矩形框的一个宽和高,宽 高它会给你返回回来,我这边给你写一下,比如说宽是 wait 吧,高是 hit, 就它会给你返回四个值,那么你你只要拿到这四个值啊,把这四个值呢啊,就说它绘制出来就可以了,非常简单。怎么绘制呢?我这里啊直接用一个 for 循环,首先 你给我传过来一个 x, 一个 y, 对吧?而且还有一个宽,我这边用 w 可以去指代它, h 呢,是代表就是高。然后是 in 什么呢?是不是 in 我们这个 faces, 对吧?因为你给我 传过来一个检测到的一个原理的结果,我这边就可以直接用 faces 就可以了。然后呢我们直接用我们的 cv 库里面叫一个 rectangle 啊,关于这个如何绘制基本图形啊,我在前面的视频当中给大家讲解过啊,如果不太了解的朋友啊,可以返回返到看前面的视频去了解一下 啊。我们要画一个矩形框,我们现在已经知道坐标宽和高,怎么去画呢?是不是你要在这个图片上去画,然后你要把它的起始点的坐标,也就 x, y 也你要给它,同时呢你要把它那个,比如说我们看一下,你要绘制一个矩形,你是不是需要知道 这个啊?趋势点的一个坐标,对吧?你还需要知道他这个对角线的一个坐标,只要知道这两个坐标,那么你这个矩形框就马上就能画出来了吗?那我们这个绘制矩形框的原理是一样,找到这样一个,呃,找到第一个坐标,找到第二个坐标,那么整个矩形框马上就绘制出来了, 所以我们这里呢也是利用的是这个原理啊,比如说第二个坐标是不是 x, 你要加上一个 y, 对吧?那么这个 y 呢? 你要呃 x, 你要加上一个 w, 加上一个宽,那么 y 呢?你要加上一个 h, 我们还是看一下这个 ppt, 比如你这边是一个 x, y, 对吧?那么我这个呃宽是,比如是 w, 那么你这个坐标是不是 x 加上一个 w 就是它的一个红坐标,那么你这边如果是纵坐标是 y, 我这个高是只是 h, 那么你这边的纵坐标是不是 这个 y 加上 h, 是吧?就这个坐标是很好理解的,你只要加上它,加上它的宽和高,那么就是另一个坐标的这个另一个坐标的一个值。然后呢,我们要给这个矩形框复一个它的边框 加一个颜色,加一个颜色啊,加一个蓝色吧。 bgr 嘛,就是叫第一个就是奥乌,就是蓝色嘛。然后呢这个边框的粗细我们是一个三, ok, 这样呢,通过一个循环下来,就能够把里面检测到的每一个人脸呢,给他画上一个矩形框,给他画上一个矩形框,然后呢我们需要 需要把这个 imager 再给他返回回去,因为我们这个这个矩形框在这个图上画好之后,你是不是要把这个新的图片给他传回去,那么传回来之后呢,他就会被我们这个结果被这个变量给接收到,然后呢 我们通过在画布上把这个结果啊给他展示出来就可以了,就整个结果啊,他的流程是非常简单的,就说你一步一步去做吗?他是非常清晰的,非常清晰。所以我写代码呢,刚开始啊,我可能不会马上去写代码,我会用中文去表述出来他每一步到底怎么去做, 然后你把每一步呢用代码去实现就可以了,就这么简单,非常简单。然后我们这里啊,我们要写一个主函,主函数这边没写,我们要写一个 man 函数,对吧?我们把它放在一个 man 函数里面,在这里呢,我们需要从 man 函数, 呃,运行这个进入嘛,所以我们这边呢需要写一个慢函数的一个入口,一个主程序的一个入口,这样就可以了。就我们整个程序啊,就是一步一步,你看第一步,第二步,第三步非常非常清晰。然后我们运行一下,看一下效果吧,因为也不知道会会不会报错,我们 我们看一下,检测一下这个 family 这个图片,这三张人脸能不能检测到?我们运行一下, run 一下, 哎,好像没有显示一闪而过,为什么呢?因为啊,我们这里呢,一定要用一个 plot 把它显示一下,在我看一下啊,在这里你要显示一下,在在在在在在在在这里,在这里,最后 要用一个 p o t 把整个画布,你要显示一下,我们再运行一下。 哎,他显示了,你看到这个结果了吗?有没看到?你看哦,这个做这个照片上呢有三个人脸,但是呢,我们这个算法呢,他只能检测出两个人脸,只能检测出两个人脸, ok, 所以他这个效果是不好的啊,因为我们这个 hori 级别分类器呢, 他这个算法说实在的啊,在当下这个深度学习这个,这个这个潮流之下,他这个算法真的是老古董了,是老古董,那我为什么要讲呢?主要是让大家知道这个人脸检测他的原理是怎样实现的 啊?怎样实现的?它这个效果是最差的,毕竟这个算法它是二十年前的,感觉真的就是一个老爷车了。但是呢,我也要给大家讲一下, ok, 这个就是通过我们号儿算法来对图片中的人脸进行检测,那这个是 family, 我们再检测一下这个 girl, 看看它能不能检测出这种 人脸有角度的这个图片,我们再把它换一下,比如说我这边给它替换一下,比如说换成 girls, 然后我们再运行一下,我们再运行一下。哎,你会发现啊,他一个人脸都没有检测出来,为什么呢?因为我们这号儿 算法呢,它主要是检测人的一个正面的一个人脸,你如果是侧,比如你是侧的,对吧?或者你是弯着 啊,角度不一样,他一个都检测不出来,所以这个算法是非常非常差劲的,非常差劲的, ok, 但是呢啊,还是那句话,就给大家做一个演示,你要知道这个算法怎么去调用,其实我们 open cv 库里面有很多算法,那后续我也会讲,比如像 l、 b、 p, 当然也是一个比较老的算法,还有我们 深度学习,或者说我们的这个啊,这个机器学习的一些模型的这种算法。那这那种算法呢?他对人脸的检测就非常非常精细。后续啊,我们会讲,会讲解一个算法叫做 m、 t、 c、 n、 n, 他能够检测非常非常小的人脸,不管你这个位置多么偏,人脸角度多么偏,他都能够检测出来啊,我这个算法我也是非常非常喜欢的,就 m、 t、 c、 n 这个算法, 那今天呢,我们稍微提一下, ok, 这个是对图片的一个软脸的检测。那接下来呢,我们把这个代码稍微改变一下,通过我们的摄像头,我们笔记本的摄像头来进行一个软脸的检测。怎么改呢?非常简单,我们这里啊,直接再拷贝一份就 copy, 我们先创建一个新的一个文档,比如说 face, 对吧? 哈尔。然后呢,呃 video, 我们通过视频来检测人脸,我们把整个代码拷贝一份, 我们把整个代码拷贝一份拿过来,对吧?我们稍微做一下改变就可以了,怎么改呢?也非常简单,首先啊,我们把 这边的去掉,这边都不需要,因为我们是通过摄像头来读取嘛,这些都不需要。然后我们把这个,呃显示图片不需要,为什么呢?因为我们是通过 c v 库这个 m 秀直接显, 是直接显示,所以不需要通过我们的 p o t 这个画布来显示,这个也去掉,然后这个这个肯定需要的,我们要剪,把这个软点给它绘制出来,所以这个方法我们是需要的。 ok, 这里看有没有需要改变的,这里我们不需要动, 这里不需要动。 ok, 然后这里看看有没有要改的,这个要改,因为我们是通过摄像头读取嘛,所以你这个我们要给他删掉,是吧?给他删掉,然后我们这边比如读取摄像头,我们要改变一下读取摄像头, 读取摄像头,然后呢我们这边改一下,比如叫做 capture 读取摄像头这个功能,还有没印象我们在之前的课程里面讲过的啊? 如果不太了解的朋友啊,可以往前看,往前去翻,里面都有都有详细的一个讲解。如何通过摄像头来读取视频,这边用的一个方法叫 video capture 就行了。 video capture, 然后呢? 零吧通过我们的笔记本自带的摄像头来读取。 ok, 然后接下来我们还需要做哪些改变呢?我看一下 这个读取摄像头之后啊,我们再继续看一下,说我这边要做一个分类器,加载分类器,我这边要加载一个分类器,哎,我先把这个给他删掉,这边我们先删掉,不需要 读取摄像头,我们要通过 opencv 加载一个分离器,这个我们需要加载一个分离器。那接下来我们干嘛?我们是不是要判断一下我们摄像头是否能够正常工作在这里呢?我们 我们看一下,我看一下,这里,要改还得改这边,比如说判断摄像头是否正常工作,怎么判断呢?是不是用一个叫 if, 用一个 if capture 来判断,如果判断 is open, 判断是否是 啊?是否正常工作,如果他不能正常工作,那我就输出一个,比如说叫做 camera arrow, 摄像头 错误,对吧?如果这个摄像头呢?他不能打开,我就说你这个摄像头坏了,对吧?或者错了, ok, 那么摄像头如果能够正常运行怎么办呢?我们是不是要用一个外循环不断的去读取我们的摄像头,让他一直不断在读取里面的每一针,也就每一张照片, ok, ok, 这在这里呢,我们啊继续,我们要获取每一针,通过摄像头获取每一针,在这里啊,我们要做一下, 呃,这个获取怎么获取呢?首先你要获取 rat, 这个 rat 啊,就判断你这个摄像头是否能够读取到照片,就是他返回一个 true 或 force, 如果是这个 rat 啊,它是 true, 那么说明你这个摄像头能够读取到照 片,然后呢是一个返回一个真 friend, 然后呢我这里啊,用一个 capture, 通过这个 read 方法来读取这个照片,然后接下来我们要干嘛?读取照片之后,我们是不是要用我们这个 分类器来检测我们这里的这个这个每一针,对吧?所以我这里呢,我先把这个往下拖一下,全部往里面, ok, 这样就可以了。接下来呢,我们要通过对图片,也就对这个 freem 中的进行检测。我其他这个备注我先不改了啊,我就把这里改一下 这个每一针,每一针,这里我们还是需要做一下灰度的一个变换的,这里我要做一个判断,我还得做一个判断,我要判断这个 right 啊,它是否为处,如果说它为处的话,也就我们这个摄像头,它能正常的读取到 这个,这个视频流,也就读取到每一针嘛。所以说如果他为处的话,我就把这个照片,把这个 friend 每一针做一个灰度的一个转换, cvt 都开了,对吧?然后是 friend, 然后是做一个灰灰度的一个转换 开了,对吧?然后 bigger 到 gray, 这样就可以了。这边也是做一个灰度转换,备注一下灰度转换, 然后呢?做完这边我再往里面再缩进,这个缩进用的快捷键就是 table 键,他就会同时往里面缩进,你千万不要一行一行的去缩进,那太慢了 啊。各位朋友可以去看一下 phone 的一些快捷键到底有哪些,非常简单。然后呢?呃,如果转换成灰度,我们就把这个灰度图片传给了这个分类器, 他就会进一个检测人脸的检测,然后呢?我们拿到了这个检测,检测的结果,拿到检测结果之后我们要干嘛?我们是不是要绘制了?我们是不是要绘制他? 呃,我们要把它这个检测结果传给这个方法,因为我们要把人脸绘制在这个呃,人脸的矩形框,哎, sorry, 我们要把人脸的矩形框绘制在这这张图片上, ok, 我们要调用这个方法, 调用这个 plot rectangle 方法,然后这个,这个你要改变一下,这个不是 image 了,我们不是 image 了,这个应该是 frame 了,我们这个针这个也要变一下, 结果拿到了,然后呢我们会得到一个结果,对吧?得到这个结果,那得到这个结果之后,我们是不是要通过 opencv 把它显示出来,那这个画布什么的我们就把它全部删掉,我们不需要 全部,不需要这个,也不需要全部删掉,然后看一下拿到结果了,我们要通过 open cv, 通过 im show 把它进行一个显示,比如说我这边写一个 face detection 人脸检测, 然后呢把我们这个结果给他放在这里就可以了。 ok 啊,就这么简单。那么我们 oppo c v 因为是视频读取,我们是不是也要加上这个判断?就说当你按下一个 q 键就退出嘛?所以我这边呢还需要一个 wet, 呃,应该是看一下,应该是 c v 库里面有个叫 wet k, 对吧?他的功能就说让我们的图片就你要显示,不能一闪而过。然后这里呢这个很固定哦,很固定。我这里呢不给大家讲解,因为之前视频我给大家详细讲解过,然后这个方法直接是这样就可以了, 他主要是判断你的你是否按了这个 q 键来退出,你是否按了这个 q 键来退出,如果按了 q, 那么他就把整个摄像头啊给给你关闭了,我这边就用一个 break 终止循环就可以了。 然后呢我们要把整个摄像头给他释放,整个资源进行一个释放,看看有没有问题。呃, capture why? 这里没问题。然后呢我们我们要把整个摄像头给他一个释放, 然后呢要关闭所有的一个窗口,这个一定要关闭,不然他会占用我们的这个内存的。 ok, 全部关闭,我们主要做了这样一些改变,看一下, 主要你看啊,绘制图方法,主函数读取,然后呢加载分离器,判断摄像头是否正常工作,获取每 每一针灰度转换,对吧?然后呢,哎,我把这个全部删掉吧,不然影响大家,我把这个给他删掉,删掉, 删掉, ok, 这样就可以了,我们运行一下,看一下效果啊,我们通过我们的摄像头来读取,然后呢来进行一个人脸检测,我不知道会不会报错,我们看一下这个效果。我这里啊给大家找了一张图片,让大家呢来看一下他能不能正常的一个检测这个人脸。 我这边比如说我运行一下, run 一下,看看会不会报错, 哎,好像没有显示哦,好像报错了哟。呃,这里报错了,看看在十七行报错了,这儿报错了,我看看为 为什么报错啊?先是这个,看看为什么报错, 哦,这个这个,这个,看一下,应该是这个,这样就可以了,我们再运行一下, 哎,还是有错还是有错,看看哪里爆错了, 在二十八行很正常,因为我们这个程序啊,你运行写完代码不可能保证百分之百他能够正常运行,他总会有各种错误的,总会有各种错误, 我们这边有个叫 gray friend color, 对吧? great to be sure 二十八行, 如果他那就进行检测,看一下 invalid number of channels 无效的 cvt color cv 没问题啊,看一下,看看哪里错了,我,我来检测一下,看一下 它报错呢,主要是这儿写错了,因为我这个是 great to b g 二嘛,这个是不对的,为什么呢?因为我们这个 friend 嘛,它获取到的每一针它是一个 b g 二,所以我这边顺序写错了,我应该把它改成一个 啊, b g 二, two gra, 这样就对了,就我这个顺序写错了,所以他会报错。那接下来呢?我们再运行一下,看看他会不会报错。我这边比如说,对吧?一个看看有没有问题啊?我们这边 run 一下, run, 哎,没有问题,你看,哦,没有问题,他能够检测,比如说我这边是一个摄像头,对吧?然后我这边准备了一张素材,比如说我这边给各位朋友看一下,比如说我这个摄像头对准了我这个图片, 他就能够把这张图片上的三张人脸都能够给他显示出来,非常非常的非常准确,每张人脸都能够在视频里面 非常简单。 ok, 当然你也可以啊,对吧?去,去识别一些其他一些图片,没有问题,这个是实时的一个视频的一个识别,没有问题。好了,那这个呢,就是我们通过我们的视频,通过我们的摄像头来进行一个人脸的一个识别 啊,我们主要是通过前面的这个代码呢,做了一下改变啊,刚才报错呢,主要是儿的顺序写错了,所以他会报错。 ok, 你看这个通过摄像头识别呢,这个代码呢,他就非常非常简单啦,非常少啦,没有那么多啦,我这边把它先 ok 关掉,删掉这些备注, 这顺序我给他删掉,没有问题吧? ok, 今天呢主要讲了这个人脸检测,一个是通过图片来进行一个人脸检测,一个是通过我们的摄像头来进行人脸检测。那么关于这两个文件的代码我都会分享在我的云盘里面,各位朋友呢,可以去下载, 然后把这个代码自己去啊,就是敲一敲,敲一敲,然后运行一下,看看有没有问题,当然你也可以做一些自己的一些小实验,没有问题啊, 当然我还是要说一下这个哈尔吉的算法,他是比较一个古古老的一个算法,所以他的检测效率,检测度非常非常低。那么后续呢,我们会介绍一些一些更加 高级的一些算法,他对人脸的检测识别是非常非常准确的。 ok, 今天主要主要是,呃让大家小试牛刀吧,感受一下这个算法的一个魅力。 那今天内容呢,主要是这一块,那如果各位朋友啊啊有任何问题可以在视频下方给我留言,当然啊,如果你有一些什么啊好的意见也可以在下面给我提。那今天内容呢,主要是先到这里,那欢迎大家呢,继续学习后续的课程,拜拜。
粉丝2317获赞5216

虽然安装 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。 这时我们可以直接导入那么派的包,并打印出他的版本号。 南派又是什么东西?南派是派森专门处理高位数组的包,他用来存储和处理大型矩阵,比派森自身欠套列表结构要高效的多。另外针对数组运算提供大量的数学函数,苦真的又快又好用。



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

今天给大家介绍一个鸡蛋计数器的项目,使用 opencv 和优乐 v 八检测鸡蛋个数,能够高效、准确、安全、可靠的完成鸡蛋个数的统计工作。 ulov 八是一个使用配套取框架创建和训练的剪辑神经网络模型,是计算机视觉领域最流行的目标检测算法之一,运行代码来看看结果吧!

如何用拍子?嗯,结合 open cv 实现 ai 斗地主?用到拍奥特 gui 模块和 open cv 模块, 利用 do zero 斗地主 a i 模型,利用 open cv 模块识别谁做地主玩家手牌,其他玩家出的牌,每一轮利用 ai 计算出什么牌胜率最高,利用派 uto g u i 操作欢乐斗地主出牌。

今天我们在 cpu 上测试一下 open 飞乐对模型的加速效果。先选择机 times for the 轻量 ssd 检测模型,在只有 cpu 的苹果电脑上测试, 可以看到 oppo vino 对 ssd 的加速非常明显,达到了每秒六百针,但是检测效果很差。再选择基于拍 touch 重一点的 ulv 五检测模型,可以看到 oppo vino 对 ulv 五的加速也不错,可以达到每秒六十针,而且检测效果也更好一点。 windows 电脑上 cpu 的测试结果与苹果电脑基本一致,再用舒美派配合神经计算加速棒测试一下,一路为我可以跑到十针左右,检测的效果也不错,老样子,圆满已开圆课程一同不更新!


大家好,我是田叔,今天是二零二一年的七月十五,我给大家科普一下,小白在进入机器视觉这个行业,应该怎么选择一门视觉处理软件, 我们鸟叔视觉培训中心提供了有四门语言啊,第一欧喷 cv 啊,第二莱布 vivo, 第三龟身 pro, 第四好喷, 那么根据自身的情况啊,我们应该怎样去选择呢?首先我们看一下这个欧分思维,他是一款开远的软件,基于事业家的一个算法库, 经历过被美国卡脖子之后啊,很多人也会,也许会说呀,看一下其实挺好的嘛,但是呢,欧文思维对于我们这个工程师的这个 软件功底要求比较深,而且项目开发周期会比较长,如果啊,你不是这个计算机相关专业的,一般我不会去推荐大家去碰他啊,如果你这个企业呢,是中小企业啊,一般也不去推荐大家去碰他 啊。其次我们看一下 like, 它也是美国的一款软件,是美国国家一汽啊恩爱开发的,基于图形化的一个编程, 整体来说,他这个理念是挺好的啊,这几年呢,在机器人啊,还是这个界面的这个设计这一块呢,实际上是有不少的工程师在使用,但是 啊,在这几年来看呢,在视觉这个行业来说呢,他是渐行渐远啊,淡淡的已经淡出了人们的这个视线啊。第三, 我们看一下微信 pro, 他是美国康莱斯的一款软件,在视觉行业里面呢,也是久负盛名。他呢入门很简单,图形化的操作,开发周期也短啊,算法也非常的稳定, 但是对于个人来讲呢啊,他的入门门槛是比较低的啊,意味着呢,我们的这个学员又很容易被啊后续者给替代,对我们个人来说呢啊,不是一个长久之计, 所以呢,我一般也不推荐大家啊,选择这个卫生铺啊。第四啊,我们看一下这个蒿肯,他是德国的一款软件,在视觉行业里面呢,举足轻重,属于这个一哥这个地位,他呢, 这个功能是最全的,性能也是最稳定的,效率也是最高的,使用起来呢也是最稳定的啊,特别是在这个缺陷啊啊,很多这个项目啊,都是使用这个毫喷的啊,他不仅被工程师啊,然后说喜欢啊,企业 各个企业呢也非常青睐啊,这个蒿坑啊,综合来讲呢啊,如果你是个小白,想在视觉行业里面呢做长久的发展,那么田叔呢,就推荐大家学习蒿坑 啊,他的理由是就业的薪水高,就业面非常宽啊,你的次序会更长久,而且这样的人才呢啊,更容易受到企业的一个青睐。