基于人工智能的图像处理技术:利用Opencv实现

基于人工智能的图像处理技术

本文档基于电子科技大学软件工程学院的的一门图像处理技术课程要求所撰写,希望后来的学习学妹!!!!不要照抄!!!!!

  • 人工智能概述

人工智能,作为计算机科学的一个重要分支,它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。作为一个面向未来的新技术,值得我们好好探索。

1.1人工智能的发展与现状

人工智能的发展历经了三起三落,才走向今天勃勃生气的繁盛景致。

“人工智能”(ARTIFICIAL INTELLIGENCE)一词最初是在1956年DARTMOUTH学会上提出的。其核心是希望计算机可以帮助人来获取一些认知、感知和决策的难题的解决方案。这样的课题成为了全球技术圈的热点,并相继取得了一些研究成果,如机器定理证明、跳棋程序等,人工智能的序幕就此拉开。人工智能发展初期的突破性极大促进人们对人工智能的期望值,一些科学家开始尝试一些不符合实际的目标方案,陷入接二连三的失败,使得人们对人工智能的期望值大大下降。20世纪70年代开发的专家系统模拟人类专家的知识和经验解决特定领域的问题,标志人工智能实现从理论研究走向实际应用并且能够使用专业知识技术解决专门问题的突破。[1]伴随着人工智能的应用规模扩张与高速增长,专家系统也存在诸多待解决的问题,使得人工智能发展再度受限。20世纪90年代中期,乘着互联网发展的东风,加持云存储、大数据、物联网的赋能,以深度神经网络为代表的人工智能技术发展迅速,人工智能打破了技术牢笼,实现了新的跨越与爆发式增长。其发展历程可以概括为下图。

基于人工智能的图像处理技术:利用Opencv实现_第1张图片

如今,人工智能遍地开花,我们可以把现状概括为——“专用人工智能取得重要突破、通用人工智能尚处于起步阶段”[2]。我们可以看到,对于专业领域上的人工智能,如“阿尔法Go“在下围棋上表现得极为出色。这类人工智能目标更清晰明确,干扰性小,边界明晰,发展也自然更迅速;而对于通用领域来讲,其还达不到完全能领会人们的指令并作出正确判断的地步,泛化领域的人工智能由于其涉足范围广,发展并不超前。

也可以看到,人工智能创新创业走向快车道——对于一些创新创造的人工智能产品,他们正在赋能升级传统行业。搭载了人工智能的融合创新产品显得更加高端智能,逐渐受到消费者喜爱与偏好。

总之,人工智能的社会影响日益显著。其在智能交通、智能家居、智能医疗等智能领域的优势凸显,发展人工智能必对人民、社会、国家产生积极正向的作用。在《工人日报》的一篇社评就写到——人工智能作为新一代产业变革的核心驱动力之一,以AI为典型代表的、基于大模型应用的技术创新和产业成果在我国全面开花,正成为人工智能发展的新趋势。[2]

但是,人工智能目前仍然存在诸多困境。首先,社会上对人工智能存在一些“炒作”,夸大其词的宣传不免让人们对人工智能的真实发展水平产生错误认识认知;同时,隐私保护、知识产权、科技伦理等诸多衍生的现实问题也需要我们一同探讨才能达成共识,找到适合的解决方案。

1.2人工智能的应用

人工智能在各大行业的应用广阔。随着“互联网+万物“概念的引进和提出,人工智能正在逐步渗入我们的各行各业中。

下面将用简单的几个例子说明。

  •  智能家居与物联网

智能家居搭载人工智能,配合智能音箱等设备,可以让用户以自然语言对话的交互方式,实现影视娱乐、生活服务、对话交流、信息拆线呢等操作,并且可以通过链接已经适配的互联网家居产品语音控制家具,同时支持自定义场景达到条件自动触发,达到万物互联的目的。国内的天猫精灵、小米智能家居已经实现这类技术的广泛应用。华为正在尝试更进一步的真正的万物互联模式。

  • 智能交通

“人工智能+交通”的模式,对我们的生活也大有裨益。这类系统能够使实现自动对交通需求和流量的分析,通过全局最优解的快速计算,引导交通流量变化,快速输送用户群体到目的地。诸如人工智能控制的“绿波带”,公交车的调度系统,导航app的堵车预测等。

  •  智能金融

人工智能对金融的生态领域影响也很显著。人工智能可以根据用户的消费行为习惯个性化推荐相关金融产品,推广个性化的金融服务;也可以综合消费者的消费征信记录,自动生成判定用户的信用分。人工智能在金融的巨大价值还藏在金融安全上,例如支付宝的金融风控系统就是依照人工智能对用户的异常行为的判断,及时阻止异常的资金举动,保障用户的金融安全。

  • 个性化推荐

人工智能的个性化推荐在目前的互联网产品中运用广泛。例如世界最大的视频提供商YouTube的基于神经网络的推荐系统,可以实时根据用户的点赞、收藏等行为形成用户画像和视频标签,基于以上特性形成个性化的精准推送,满足不同人群的差异化视频需求。

人工智能的应用在智能医疗、智能教育、智能工业上也有诸多例子。可见,人工智能正在各大行业发光发热,其巨大价值正在逐步发掘。

基于人工智能的图像处理技术:利用Opencv实现_第2张图片

1.3人工智能技术与分类

1.3.1人工智能技术

随着人工智能的发展,人工智能技术也在不断创新突破。目前人工智能的前沿和基础技术主要有以下几类:

  • 机器学习

机器学习是实现智能的基础技术,是使计算机具有智能的根本途径。这项技术可以让计算机通过模拟人的学习方式和动作,从而重新组织已经掌握的知识体系并使得其不断完善

  • 自然语言处理

这项技术可以满足人和计算机用自然语言的有效通信。其可以让人工智能具备一定的理解、反应自然语言的能力,可以让人与人工智能之间实现自然的沟通交流。能够使得人工智能更加普适化、大众化

  • 计算机视觉

计算机视觉解决的是机器“看“的一门科学技术,其利用摄像机和电脑代替人的眼睛进行识别与处理。其技术可运用在识别、捕捉、跟踪、测量、监视、检测等多项功能点上。其需要从图像这一多维数据中获取有效信息并提取处理,形成有效数据。是人脸识别技术的基础技术

  •  人机交互

人机交互是研究机器与使用者间的交互逻辑与关系的学科。用户可以由人机交互的界面进行操作,控制系统施发命令。人机交互使得人与机器之间可以使用某一种特定的交互方式 ,高效率地完成人和机器之间的信息交互。视频APP的点赞按键,核电站的控制台等都可以视为人机交互的平台。

  •  生物特征识别

生物特征识别可以让计算机识别人体的某个指定特征来完成对个体的身份核实和判读。例如常见的指纹识别、人脸识别就是生物识别技术的体现。多用在刑事侦查、保密、权限管理等功能点上。

除此之外,还有“语音识别“技术、”虚拟现实“技术、”决策管理“技术等,门类多而复杂,笔者在此不过多阐述

1.3.2人工智能分类

目前流行的分类方法将人工智能分三类[3]

  • 弱人工智能(ANI)

只能代替人处理某个单方面能力的工作,其本质上只是实现了某种人类具备的技能,但没有取得自主学习的认知。

  • 强人工智能(AGI)

可代替一般人完成生活中的大部分工作,包括不同领域的技术它都能掌握。其各方面都能和人类比肩,它可以思考、认识、理解问题并综合分析。具有一定的经验管理和快速学习能力。

  • 超人工智能(ASI)

在近乎大部分领域都比最聪明的人脑都具备更高的智能,可以如通人类进行自主的学习。其各项水平(包括科创、社交、决断)会远远超越人类。其也具备一定的直觉与意识。

  • 虚拟机与Ubuntu系统的安装

2.1 Linux内核

目前我们常用的操作系统是Windows,而Linux是有别于Windows的一款经典的操作系统内核。不同于Windows的封闭,Linux开源且免费,因而有众多开发者负责运维和维护,其安全性更加高。Linux能运行主要的UNIX工具软件、应用程序和网络协议,兼容性更强。

Linux的内核模块化细分很巧妙,它的模块化运行机制可随时由用户的需求,切换或者增删相应的模块组件,使得Linux系统内核可以被分割得非常小巧,具有高度的自由性。

Linux的核心思想有两点:第一,一切都是文件;第二,每个软件都有确定的用途。

但在桌面版发行之前,一切操作都有终端命令构成,如果不熟知Linux命令,几乎完全无法使用这个系统。

2.2 Ubuntu操作系统

基于人工智能的图像处理技术:利用Opencv实现_第3张图片

Ubuntu是一个以桌面应用为主的构建在Linux内核之上的操作系统,其意思是“人性”“我的存在是因为大家的存在"。

与Windows从根本上不同的是,因为是搭载了Linux内核,Ubuntu操作系统具有与Linux相似的优点——免费,而且开源,其具有巨大的操作空间来修改与编辑。

而与Windows相似的是,其提供了一个可视化桌面,对于普通的、未系统接触Linux命令的人来讲,这极大的降低了学习和试错成本。

正因为其兼具两个系统独有的优势,Ubuntu操作系统广受欢迎。

2.3虚拟机

在本课程中,我们使用了VMware虚拟机来软安装新的操作系统Ubuntu。

使用虚拟机相当于单独开辟了一个操作系统,它与我们本省的操作系统基本上毫无关联,两者大体上讲互不依赖,是两个独立的操作系统。

虚拟机通过软件来模拟计算机软硬件,无需分区就能在同一台计算机上使用多种的操作系统。操作系统相互独立, 可以保护多个的操作系统的稳定性和安全性,他们互不侵犯。不同的操作系统之间也能相互操作,实现文件的转移,热点的共享等内容。也可以通过网卡将几个虚拟机利用网卡连接到一个局域网,十分便捷。

2.4 安装过程

下面来简单介绍一下虚拟机和Ubuntu操作系统的安装过程。

我们需要首先下载VMware软件(版本号16)。

安装好后,双击即进入VMware workstation页面,选择创建一个新的虚拟机。进入安装向导。在新的页面,选择将Ubuntu操作系统的光盘映像文件(.iso文件)导入至VMware中(即图示第二个选项),等待读取。

基于人工智能的图像处理技术:利用Opencv实现_第4张图片

为虚拟机设置名称,并为其分配其合理的存储空间(默认20G)、安装位置和相关配置(包括处理器数量、内核数量、网络设置等)。基于人工智能的图像处理技术:利用Opencv实现_第5张图片

等待其安装成功后会自动回到workstation页面,双击进入虚拟机。

至此,我们的VMware配置基本结束,接下来是Ubuntu的配置。

我们双击进入Ubuntu后,会出下如下图展示的Ubuntu欢迎页面

基于人工智能的图像处理技术:利用Opencv实现_第6张图片

(Ubuntu欢迎页面)

点击“install Ubuntu” 然后在左侧选择语言,继续,随后设置虚拟机的账号和密码,等待安装成功即可进入Ubuntu的页面。

但是当前Ubuntu的屏幕过小,我们下载VMware-tool后点击最上方的放大按钮即可调整大小。

Ubuntu的软件更新默认从国外的源更新,更新速度和下载速度较慢。我们需要在“软件更新”中设置为国内源。笔者将其更换为阿里云的源下载。

基于人工智能的图像处理技术:利用Opencv实现_第7张图片

  • OpenCV的安装与调试

3.1 关于OpenCV

基于人工智能的图像处理技术:利用Opencv实现_第8张图片

OpenCV是一个免费且开源发行的跨平台计算机视觉与机器学习软件库,旨在为计算机视觉应用程序提供通用基础架构。其主要有C语言代码生成编写,在Linux和Windows下可以自如地运行,运行快速,方便调用。OpenCV库拥有超过 2500 种优化算法,可以高效的完成各项图像识别的任务。在人脸识别、运动跟踪、动作识别、物体辨识等方面由诸多应用场景。

3.2 关于编程环境

本课程主要运用到的编程环境为C++与Python,又因为OpenCV主要由C语言编写而成,因此使用OpenCV的主流调用语言为C++/C语言。

C++是一种计算机高级程序设计语言,由核心是C语言的升级与拓展。C++擅长面向对象程序设计,同时也可以基于过程进行程序设计。其可以直面系统底层,也打破了很多C具有的限制;而Python语言是一种利于程序员编写和阅读的高效语言,其具有独特的简洁性、可读性和可拓展性,可以大大减少代码输入量。

3.3关于make

当我们需要运行一个程序时,我们首先需要编译这个程序使得其生成一个可执行文件。对于一些简单的项目,我么直接调用python编译器/g++编译器进行编译即可。但对于车牌识别这类大型工程,我们编写的大型程序往往由多个编译单元构成。因此,构建应用时,发出的编译命令可能会比较长。

为达到此目的,推荐的构建方式是使用make工具。以C++为例,我们需要编写一个CMakeList.txt文档,其包含了我们要编译的所有单元,我们要链接的库函数、头文件以及我们目标生成的运行程序等一系列参数。编译好后在终端中依次发出cmake .make 命令即可完成编译

3.4安装OpenCV

首先我们在终端运行

sudo apt-get install build-essential

安装编译必须的基础程序。编译程序有了这个软件,它才知道头文件和库函数的位置。安装过程中可能出现一些安装失败,为了保证安装成功,我们执行

sudo apt-get install ffmpeg libavcodec-dev libavformat-dev libavdevice-dev libsdl-image1.2-dev

下载这些可能未安装的必备软件。

接着安装cmake并升级:

sudo apt-get install cmake

sudo apt-get update

利用命令cmake –version查看版本,确认版本在3.0以上。

接下来,右键解压OpenCV文件夹到Ubuntu的home处,在OpenCV根目录下创建一个release文件夹,进入release文件夹后打开终端输入:

cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_FFMPEG=ON -D WITH_TBB=ON -D WITH_GTK=ON -D WITH_V4L=ON -D WITH_OPENGL=ON -D WITH_CUBLAS=ON -DWITH_QT=OFF -DCUDA_NVCC_FLAGS="-D_FORCE_INLINES" ..

make -j7

sudo make install

等待OpenCV的编译,完成即可

3.5测试OpenCV的安装

OpenCV为我们提供了一个样例来检测我们是否正确安装了OpenCV。

我们首先进入进入opencv-3.4.8/samples/cpp/example_cmake文件夹中,可以看到OpenCV已经为我们提供了一个程序opencv_example.cpp并且已经编写好了相关CMakeList.txt文档。

我们首先需要链接摄像头:顶部点击player->可移动设备->xxx camera->连接。即可链接摄像头(如下图)。若链接失败需要在player->虚拟机设置->USB控制器将USB兼容性调整为3.x。

基于人工智能的图像处理技术:利用Opencv实现_第9张图片

随后在终端输入cmake . 和make 命令完成编译,随后输入./opencv_example即可打开摄像头,摄像头右上方带有Hello OpenCV字样。

  • 车牌识别

4.1车牌识别应用与技术概要

4.1.1技术简述

车牌识别是计算机视频图像识别技术的一种基础应用,其可以实现在运动的视频或静止的图像里面准确识别车牌 ,通过图像提取、车牌定位、边界处理、字符识别、输出结果等一系列复杂过程实现。常在停车场,道路收费站系统,小区车库,道路电子眼抓拍系统有着广泛的应用。

车牌识别智能车牌识别模块大体共有两个步骤——车牌图像的定位定点,以及字符的识别判读。示意图如下图所示[4]

基于人工智能的图像处理技术:利用Opencv实现_第10张图片

4.1.2 “Plate Locate”的实现过程

车牌图像的定位定点步骤中其实隐藏着三个子步骤,分别是“Plate Locate”,“SVM train ”, “Plate judge” 。其中最重要的部分是第一步“Plate Locate”过程。

Plate Locate的大体识别思路如下——一个未旋转的车牌包含很多垂直边缘,若能寻找到含有诸多垂直边缘的长方形图形块,我们就可以大概判断其为车牌。

其流程如下图所示

基于人工智能的图像处理技术:利用Opencv实现_第11张图片

其中,需要用到两个比较重要的计算机视觉技术——高斯模糊和灰度化。

高斯模糊技术可以大大降低图像噪声以及图像的细节层次[4],其是将图像中指定像素点(例如车牌识别就是将车牌边缘)和周围点加权平均得到的效果,越靠近指定的中心点那么其与核心主体关系更加紧密,我们就可以设置更大的权重值

如下图所示:

基于人工智能的图像处理技术:利用Opencv实现_第12张图片

公式为aef0d779bf0946a095854164683b691c.png

此外,由于计算机的功能限制,彩色的图像图块比纯灰度处理的图像更加难以应付,使用灰度处理技术可以提高算法的运行速度。

我们使用Soble算子检测图像中的垂直边缘,以区分车牌。这种基于边缘特征定位的方法核心是获得数字图像的一阶梯度,把图像中每个像素的上下左右四领域的灰度值加权差,边缘处的加权差将会达到极值,从而我们检测到了边缘。[4]我们可以分别计算二维图像56dfcc9e53794561b584ad1abecb8ea0.png8c99294223344e339d4d233d478def0b.png 方向的梯度6d8e571f1d5a4e75a75ee1c88249c886.png004714a831e345f89df52c33af958974.png ,利用公式:a808f0e7d90b46a18363f9a395a0cad3.png 计算偏离角度,若f3a287de1d09402abcdbadc023388182.png 那么我们可以认为此处为竖直边界。

此后通过二值化(对图像的每个像素做一个阈值处理)以及闭操作(将车牌字母连接成为一个连通域,便于取轮廓)即可取出车牌的轮廓。再进行角度修正、大小统一,即可得到一张标准的车牌图块。

4.1.3 “SVM train”训练过程

SVM 训练类似于人工智能的机器学习,其利用标签这一属性,将明确的车牌图块定义标签,非车牌图块定义另一个标签,机器经过不断的对不同标签的图块的学习,以达到判断图块是否为真正车牌图块的功能(Plate judge)。[5]

其完整训练过程如下:

基于人工智能的图像处理技术:利用Opencv实现_第13张图片

我们首先将可能含车牌的大量图片传递给机器,并为其打上标签,哪些有车牌而哪些无车牌贴上标签,机器对这些图片的相似点不同点进行分析判断,生成车牌模型。再利用Fscore指标进行评价。对于评价体系,我们需要两个指标——“准确率”(precision)和“查全率” (recall)。设置的相关公式如下:

3829e6c85c0c4e5ea82338e3bc8bad88.png

0de60870e60744db9c6a4c725fb36eee.png

f753824e65a343e192472dda53056b17.png

4.1.4 字符识别实现过程

      车牌的样式和编码规则相对固定,我们只需要由取轮廓分割法分割出七个单独的字符块(新能源八个)。且第一个字符永远是省份简称的中文,其他为数字或字母,且字母中没有I与O,减少了识别错误。

字符识别的分块首先仍然需要灰度化、二值化操作,前文已叙述。

类似于SVM train的过程,字符识别也需要机器训练,这里采用基于模板的训练方法(ANN train):首先,我们向机器输送一定量的字符模板,进行训练。随后在程序实际识别中,机器会根据公式85d33cab61ab4f4db374f8eb56d555b5.png 来依次判断七个字符的每个字符与某一模板的相似度(公式中S 代表相似值,I 待测数据,T 为模板),综合相似度大小即可完成字符的判断。

4.2 车牌识别工程实现

      在本项目中,我们采用EasyPR库来辅助完成,其提供了大量已经训练好的车牌定位与字符识别数据,我们只需要调用其库函数识别即可。

我们只需要解压EasyPR的压缩包到home目录,在其根目录下打开终端依次输入cd EasyPR-master

./build.sh

EasyPR即安装成功。(如图为安装成功的界面)

基于人工智能的图像处理技术:利用Opencv实现_第14张图片

在EasyPR提供的根目录中,提供了CMakeList.txt文档,其指向测试程序demo。我们可以借助这个文档加以改编形成自己的make文档。

如下图所示:

基于人工智能的图像处理技术:利用Opencv实现_第15张图片

      我们只需要将CMakeList.txt中的test/main.cpp改为自己的程序代码(比如我的是car/test.cpp)路径,工程名修改为自己的工程名。这样cmake就会编译我们的车牌识别程序并链接上EasyPR相关库函数,生成可执行文件。

以下以识别五个车牌的图片的代码为例,进行相关代码展示。

#include 
#include
#include
#include 
using namespace std;
using namespace easypr;


int main(){
    easypr::CPlateRecognize pr;
    pr.setResultShow(false);
    pr.setDetectType(easypr::PR_DETECT_CMSER);
    pr.setLifemode(true);
                      //启用生活模式,以增大识别范围

    pr.setResultShow(false);
    pr.setMaxPlates(5);
                      //最大车牌识别量


    vector plateVec;

    Mat src = imread("/home/jjq1/EasyPR-master/car/5cars.jpg");

                      //图片的地址

    int result = pr.plateRecognize(src, plateVec);


    if (result == 0)

    {

       int total=plateVec.size();
       std::cout << "车牌识别成功!一共识别到"<

在代码中,第10至17行我们利用了EasyPR提供的参数和库函数进行识别过程的参数设定,为了增强识别效果,我们开启了生活模式。为了规避程序因为开启生活模式识别过多的非车牌信息,我们利用17355dddcee34d2ab1e18cf8cf1c7d6a.png 进行识别最大数量值的限定与限制。

代码的第二个部分(即19-22行)我们传入要识别的图片绝对地址,使程序调用传入至EasyPR的库函数进行识别。

代码的第三个部分(24-41行)是代码的核心输出部分。首先利用result 的值判断程序是否正常识别了车牌,如果识别正常,那么我们利用for循环逐个输出车牌信息。我们调用了EasyPR提供的函数plateVec.size(),来获取程序实际识别的车牌数量。plateVec.at(i) 即是第i个车牌的所有信息(包括图像、车牌字符串、定位等)。我们将信息存储到CPlate 这一类中,再利用EasyPR 提供的license (即是包含了车牌颜色和车牌字符的组合字符串信息),利用输出语句输出即可。

编写好这个函数后,打开终端,依次输入cmake .和make,即可完成编译,随后运行这个程序即可。下图为5个车牌的识别结果:

基于人工智能的图像处理技术:利用Opencv实现_第16张图片

  • 人脸识别

5.1人脸识别应用与技术概要

5.1.1 技术概要

人脸识别是一种基于人的脸部特征信息识别身份的生物识别技术。由于人脸数据由于其唯一性和不可替代性,这种技术应用广泛——用于企业住宅社会出入系统,如人脸识别门禁、打卡考勤系统、宿舍门禁等;用作电子化护照及身份证以及票据,如电子驾照、地铁人脸识别过闸、海关身份确认;用以确保安全,如计算机登录、智能硬件解锁、银行的风险操作、刷脸支付、天网锁定逃犯需要人脸识别。这些应用场景总体来讲细分为三类——是人像检索(DB-SCAN),人像监控(Watchlist)和人像验证(Verification)

基于人工智能的图像处理技术:利用Opencv实现_第17张图片

相比于诸如瞳孔识别、声音识别等其他生物识别方式,人脸识别方便、快捷、准确、直观、无接触,在疫情发生以来运用广泛;同时,由于其隐私性,无需干扰人的正常行径,也为远距离非接触隐蔽监控式识别带来可能。其技术核心是通过对人脸的关键特征点的数据比对分析,查找到最匹配的人物数据。其大致流程图如下[6]

基于人工智能的图像处理技术:利用Opencv实现_第18张图片

5.1.2 预处理工作

      我们常常把人脸检测和人脸规范化称为预处理工作。

通过一定的机器训练,我们首先让程序将从图像中检索所有的面部图块,并分割每一个图块。

但是很遗憾,受限于光线、拍摄角度、清晰度等因素,目前的图像不能被识别,我们需要进一步运用人工智能的图像处理技术进行相关操作。

我们首先将得到的图像的三分量亮度(R,G,B)按权值计算得到一个灰度值,进行灰度化处理以提高计算机运算速度。随后通过几何变化,不断对图像进行平移、翻转、转置、缩放等操作,将原图块映射到新的一个图块上,以减少几何因素带来的错误识别。然后进入图像增强步骤,适当提高图像的对比度使得人脸图像更加清晰可见,常见的算子有直方图均衡化、拉普拉斯算子、Log变换、伽马变换。

       最后进行归一化操作,统一图块的大小、人脸角度、距离、方向等相关因素,方便后续的特征提取更加准确。常见的归一化方式为线性归一化,需要使得结果x0=x-min⁡(x)maxx-x30562e0765794f8e9a15ba7c24900b0d.png 位于区间[0,1]c0f5c09a33c7414da1ad00a83b452744.png 之间。

5.1.3 特征提取与结果识别

      这一步是人脸识别的核心步骤之一,我们需要对要识别的图片和数据库中图片进行特征提取。人脸的特征便是眼睛、鼻子、脸颊、嘴巴等器官的特征点的位置,我们需要首先为这些特征点定点。

      Dlib库为我们提供了68个特征点,如眼睛、嘴巴、鼻子等特征点都属于这个范畴,这些点构成的集合就是这个人的特征点:

      如下图所示,就是一个人的特征点。

基于人工智能的图像处理技术:利用Opencv实现_第19张图片

我们也可以通过机器学习的方式让我们的机器学会辨认这些特征点。

得到特征点后,通过dlib库所含的函数facerec.compute_face_descriptor(图片对象, 特征点)得到一个特征向量,再根据这个唯一的特征向量我们需要得到这个人脸的一个特征值。

在数学上,欧氏距离是一个常用的的距离度量,其反应两个向量之间的直线距离。欧氏距离越小,说明两个向量越接近,也就是两个向量差异越小。

那么假设我们要识别的图片向量为52d75d6971ee42eeb26eebe5a5dbb827.png ,数据库中与之相似的一个图片向量为3e1ee70ef8d44944abe09dd404077429.png ,则这两个向量的欧氏距离的计算公式为:

7eceedde6aca4706bbb0eeddc3b8a871.png

      我们可以认为欧式距离d就是这个人脸的特征值。

      我们只需要逐个对比数据库的人脸的欧式距离和所识别的人脸图块的欧氏距离,当两个欧氏距离的差值小于一定阈值时,我们可以认为这两个人为同一人。我们就可以输出这个人脸的相关信息,完成识别。

5.2 人脸识别工程实现

5.2.1 准备工作

      首先我们需要安装一些特定的依赖库。在终端中输入命令:sudo apt-get install libboost-python-dev安装boost依赖文件。

然后下载pip:sudo apt-get install python-pip,下载pip应用安装软件。

随后安装setuptools: sudo pip install setuptools==42.0.2

      此外我的电脑还需要安装numpy:sudo pip install numpy以便后续调用。

      我们首先解压dlib-19.6.zip到home下,在终端发出命令:sudo mv dlib-19.19.0 /usr/local/lib/python3.6/dist-packages。将dlib库移动到lib目录下。

      进入dlib根目录下,打开终端,输入: sudo python3 setup.py install等待即可完成dlib的安装。

      接下来在终端输入:sudo pip install opencv-python安装opencv-python。

      我们再解压Face-recognition-master文件夹。Dlib库已经给我们提供了人脸关键点检测器和人脸识别模型两个模型。我们只需要将这两个模型库放入Face-recognition-master根目录下即可。(如图为安装成功的界面)

基于人工智能的图像处理技术:利用Opencv实现_第20张图片

      为了能够显示中文,我们还需要下载中文字体simun.ttf并移动到/usr/share/fonts目录下。

5.2.2 导入人脸数据

我们需要在Face-recognition-master根目录下创建candidate-face文件夹,在里面放入我们的照片并重命名为我的学号+姓名。

      随后打开终端运行python candidate_train.py。程序将自动对我们的人脸照片进行训练导入,将识别结果和特征存储在candidates.npy 与 candidates.txt中。

5.2.3 代码实现

      我们输入以下代码,名为this_is_who_camera.py

# -*- coding: UTF-8 -*-



import dlib,numpy
import cv2         
import time
import numpy as np
from PIL import Image, ImageDraw, ImageFont
import freetype





# 1.人脸关键点检测器
predictor_path = "shape_predictor_68_face_landmarks.dat"
# 2.人脸识别模型
face_rec_model_path = "dlib_face_recognition_resnet_model_v1.dat"
# 3.候选人文件
candidate_npydata_path = "candidates.npy"
candidate_path = "candidates.txt"
# 4.储存截图目录
path_screenshots = "screenShots/"
# 加载正脸检测器
detector = dlib.get_frontal_face_detector()
# 加载人脸关键点检测器
sp = dlib.shape_predictor(predictor_path)
# 加载人脸识别模型
facerec = dlib.face_recognition_model_v1(face_rec_model_path)
# 候选人脸描述子list
# 读取候选人数据
npy_data=numpy.load(candidate_npydata_path)
descriptors=npy_data.tolist()
# 候选人名单
candidate = []
file=open(candidate_path, 'r')
list_read = file.readlines()
for name in list_read:
    name = name.strip('\n')
    candidate.append(name)

# 创建 cv2 摄像头对象
cv2.namedWindow("camera", 1)
cap = cv2.VideoCapture(0)
cap.set(3, 480)
# 截图 screenshots 的计数器
cnt = 0
while (cap.isOpened()):  #isOpened()  检测摄像头是否处于打开状态
    ret, img = cap.read()  #把摄像头获取的图像信息保存之img变量
    if ret == True:       #如果摄像头读取图像成功
        # 添加提示
        cv2.putText(img, "press 'S': screenshot", (20, 420), cv2.FONT_HERSHEY_PLAIN, 1, (255, 255, 255), 1, cv2.LINE_AA)
        cv2.putText(img, "press 'Q': quit", (20, 440), cv2.FONT_HERSHEY_PLAIN, 1, (255, 255, 255), 1, cv2.LINE_AA)
        # img_gray = cv2.cvtColor(im_rd, cv2.COLOR_RGB2GRAY)
        dets = detector(img, 1)
        if len(dets) != 0:
            # 检测到人脸
            for k, d in enumerate(dets):
                # 关键点检测
                shape = sp(img, d)

                # 遍历所有点圈出来

                for pt in shape.parts():

                    pt_pos = (pt.x, pt.y)
                    cv2.circle(img, pt_pos, 2, (0, 255, 0), 1)
                face_descriptor = facerec.compute_face_descriptor(img, shape)
                d_test2 = numpy.array(face_descriptor)
                # 计算欧式距离
                dist = []
                for i in descriptors:
                    dist_ = numpy.linalg.norm(i - d_test2)
                    dist.append(dist_)
                num = dist.index(min(dist))  # 返回最小值
                left_top = (dlib.rectangle.left(d), dlib.rectangle.top(d))
                right_bottom = (dlib.rectangle.right(d), dlib.rectangle.bottom(d))
                cv2.rectangle(img, left_top, right_bottom, (0, 255, 0), 2, cv2.LINE_AA)
                text_point = (dlib.rectangle.left(d), dlib.rectangle.top(d) - 5)

        # 标出face

       # cv2读取图片

#————以下为输出中文的代码————
       cv2img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 
# cv2和PIL中颜色的hex码的储存顺序不同,这里读取图像
       pilimg = Image.fromarray(cv2img)
#转换为PIL图像
       str1 = candidate[num][0:23]
#把人名传递给str1字符串
       if not isinstance(str1,unicode):
           str1 = str1.decode('utf-8')
#如果没有解码就先解码,否则有乱码

             # 以下为PIL图片上打印汉字
       draw = ImageDraw.Draw(pilimg)  # 图片上打印
       font = ImageFont.truetype("/home/jjq1/simsun.ttc", 40, encoding="utf-8")  # 参数1:字体文件路径,参数2:字体大小
       draw.text(text_point, str1, (255, 0, 0), font=font)  # 参数1:打印坐标,参数2:文本,参数3:字体颜色,参数4:字体
       # PIL图片转cv2 图片

       cv2charimg = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)
       cv2.imshow("photo", cv2charimg)#中文贴图

            cv2.putText(img, "facesNum: " + str(len(dets)), (20, 50),  cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 0, 0), 2, cv2.LINE_AA)
        else:
            # 没有检测到人脸
            cv2.putText(img, "facesNum:0", (20, 50),  cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 0, 0), 2, cv2.LINE_AA)

        k = cv2.waitKey(1)
        # 按下 's' 键保存
        if k == ord('s'):
            cnt += 1
            print(path_screenshots + "screenshot" + "_" + str(cnt) + "_" + time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) + ".jpg")
            cv2.imwrite(path_screenshots + "screenshot" + "_" + str(cnt) + "_" + time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) + ".jpg", img)

        # 按下 'q' 键退出
        if k == ord('q'):
            break
        cv2.imshow("camera", img)
# 释放摄像头
cap.release()
cv2.destroyAllWindows()

编写好代码后,我们需要先链接摄像头(方法在安装opencv时已经赘述)随后直接在终端输入:python this_is_who_camera.py即可开始运行。

我们可能会遇到下面的问题

首先是源代码显示的仅仅有四个字符的名称,其并未将我们的学号完整打印,而包括名字一共需要23字符。修改方法是:我们就可以将源代码的candidate[num][0:4]修改为candidate[num][0:23]。

其次,由于opencv不支持直接输出中文字符,直接输出可能会出现显示乱码或者“?”字符

我们需要另辟蹊径。我们可以把中文字符绘制成一张PIL图片,再将图片贴于头像旁,在随着实时画面不断循环绘制贴图,即可变相实现输出中文。上方代码的89-109行即是输出中文的代码范例。首先将opencv读取到的图片转化为PIL。再获取candidate的字符并解码为中文。text_point为人脸左上角位置,在此位置利用draw函数绘制中文图片。再将PIL转回opencv图片并输出即可。笔者上面的代码采用的是这种方法。

同样,我们也可以采用定义新函数,在视频上面直接动态添加图片的方法来构造显示中文,函数如下:

def cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=30):

    if (isinstance(img, np.ndarray)):  # 判断是否OpenCV图片类型

        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

    text=text.decode('utf-8')

    # 创建一个可以在给定图像上绘图的对象

    draw = ImageDraw.Draw(img)

    # 字体的格式

    fontStyle = ImageFont.truetype(

        "/home/jjq1/fonts/simsun.ttc", textSize, encoding="utf-8")

    # 绘制文本

    draw.text(position, text, textColor, font=fontStyle)

    # 转换回OpenCV格式

    return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)

调用时只需输入

img=cv2AddChineseText(img,candidate[num][0:20],text_point,(255,0,0),30)

即可调用,更加方便。笔者两种方法均尝试过,且均有效。

我们链接摄像头后运行python this_is_who_camera.py即可。

至此我们的人脸识别即搭建完成

参考文献

[1]谭铁牛.人工智能的历史、现状和未来[J].智慧中国,2019(Z1):87-91.

[2]李国. 人工智能发展锐不可挡[N]. 工人日报,2022-03-15(007).

[3]李亚玲,张美玲,张蕊.大数据背景下人工智能的发展现状及趋势[J].信息与电脑(理论版),2020,32(07):125-127.

[4]杜伟. 基于机器学习的车牌识别算法研究[D]. 辽宁:沈阳师范大学,2017.

[5]张岩. 基于 SVM 算法的文本分类器的实现[D].电子科技大学,2011.

[6]梁晶,史记征.基于Python库的人脸识别方法研究[J].网络安全技术与应用,2019,(07):46-47.

你可能感兴趣的