使用OpenCV和ImageAI进行硬帽检测

在许多行业中,确保工人佩戴适当的安全设备是至关重要的。本文将介绍如何使用OpenCV和ImageAI库来训练人工智能,以检测工人是否佩戴了安全帽。这不仅是一种重要的用例,而且学到的知识也适用于检测图像或视频流中的任何类型的对象。

目前,正在阅读的是系列文章的第2篇,共6篇:

  • 安装OpenCV和ImageAI进行对象检测
  • 为OpenCV和ImageAI对象检测寻找训练数据
  • 使用预训练模型检测对象
  • 使用OpenCV和ImageAI准备图像进行对象检测
  • 使用OpenCV和ImageAI训练自定义模型
  • 使用OpenCV和ImageAI检测自定义模型对象

创建对象检测模型的三个一般步骤

  1. 加载要分类的数据样本
  2. 在样本数据上训练模型
  3. 在包含匹配和不匹配的不同样本数据上测试模型

寻找训练图像

将使用一个名为ImageNet的图像数据库来获取这个阶段的大部分源数据。ImageNet维护着一个使用WordNet名词层次结构组织的图像数据库。例如,这个数据库允许检索层次结构中的所有图像:

artefact -> covering -> clothing -> headdress/headgear -> helmet -> hardhat

ImageNet还有一个公共API,根据名词ID返回图像URL列表。让使用这个API下载大量佩戴安全帽的人的图像。该API的形式是:

http://www.image-net.org/api/text/imagenet.synset.geturls?wnid=<WordNet ID>

将使用两个WordNet名词:安全帽名词(如上所述)的ID为n03492922;以及misc -> people名词的ID为n07942152。

要从API下载所有安全帽图像,请创建以下代码块:

hardhatLoc = 'http://www.image-net.org/api/text/imagenet.synset.geturls?wnid=n03492922' hardhatImages = req.get(hardhatLoc).text noOfImages = 0 if not os.path.exists('hardhat'): os.makedirs('hardhat') for i in hardhatImages.split('\n'): try: r = req.get(i, timeout=0.5) file = i.split("/")[-1].split('\r')[0] if 'image/jpeg' in r.headers['Content-Type']: if len(r.content) > 8192: with open('hardhat\\' + file, 'wb') as outfile: outfile.write(r.content) noOfImages += 1 print('Success: ' + file) else: print('Failed: ' + file + '-- Image too small') else: print('Failed: ' + file + '-- Not an image') except Exception as e: print('Failed: ' + file + '-- Error') print('*********** Download Finished **************')

这段代码执行了很多操作,让逐步了解。首先,使用变量hardhatLoc设置想要调用的API的URL。然后,使用指向requests库的变量req查询API,并使用这个库将两个方法链接在一起:

  • .get - 接受一个字符串URL并返回响应
  • .text - 接受二进制响应并将其转换为字符串值

一旦从API获得了源图像列表,使用os.path.exists方法检查是否有一个文件夹可以下载图像。如果没有目录来放置它们,方法os.makedirs()将创建目录。

接下来,开始for循环,它使用从API下载的URL。将字符串在每个换行符(\n)处分割,并将该字符串推送到变量i中。为了捕获下载文件时的任何错误,还打开了一个try块。

在try块内,这个过程将遍历从API下载的所有URL。对于每个循环或URL,发生以下过程:

  • 使用.get()尝试下载文件。还使用可选参数timeout在0.5秒后停止尝试下载文件。
  • 使用.split()两次分割URL字符串。第一次分割发生在每个"/"处,数组中的-1值获取最后一个值。第二次分割移除尾随的回车符。
  • 下一步是检查下载的文件是否为jpeg,使用.headers数组。这个数组包含响应的所有HTML头部。
  • 确认它是jpeg后,然后检查文件是否足够大,以便不会处理任何错误图像。
  • 如果下载的文件符合要求,使用with语句块将文件保存到hardhat文件夹中。
  • 最后,关闭所有if和try块的语句,打印任何错误。

现在让运行这个代码块。将看到代码运行并打印出通过API下载的每个图像的成功或失败。这可能需要几分钟,所以让它运行并等待完成消息。

运行下载器代码块后,会注意到一些失败消息。这是好事,因为希望在文件夹中有准确的图像供分类器使用。打开资源管理器窗口,查看包含Jupyter笔记本的文件夹。现在应该有一个名为"hardhat"的子文件夹。打开这个hardhat文件夹并检查下载的图像。最终得到了687张安全帽图像,主要是人们佩戴它们,但也有一些只有安全帽的图像。检查确保有足够的图像。

现在有很多安全帽的图像,让复制代码块并下载一组没有佩戴安全帽的人的样本。复制现有的代码块并进行以下更改:

  • 在任何使用的地方,将hardhat更改为people,包括变量名和文本字符串。
  • 将API id从n03492922更改为n07942152。

代码现在应该看起来像这样:

peopleLoc = 'http://www.image-net.org/api/text/imagenet.synset.geturls?wnid=n07942152' peopleImages = req.get(peopleLoc).text noOfImages = 0 if not os.path.exists('people'): os.makedirs('people') for i in peopleImages.split('\n'): try: r = req.get(i, timeout=0.5) file = i.split("/")[-1].split('\r')[0] if 'image/jpeg' in r.headers['Content-Type']: if len(r.content) > 8192: with open('people\\' + file, 'wb') as outfile: outfile.write(r.content) noOfImages += 1 print('Success: ' + file) else: print('Failed: ' + file + '-- Image too small') else: print('Failed: ' + file + '-- Not an image') except Exception as e: print('Failed: ' + file + '-- Error') print('*********** Download Finished **************')
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485