为 OpenCV 和 ImageAI 对象检测查找训练数据
在本文中,我们将创建一个对象检测模型。
在本系列文章中,我们将学习如何使用Python、OpenCV(一个开源计算机视觉库)和ImageAI(一个用于视觉的深度学习库)来训练AI,以检测工人是否佩戴安全帽。在此过程中,我们将创建一个可用于实际生活的端到端解决方案——这不仅仅是学术练习!
这是一个重要的用例,因为许多公司必须确保工人配备了适当的安全设备。但我们学到的知识不仅仅能用于检测安全帽。在本系列文章结束时,您将能够使用AI检测图像或视频流中的几乎任何类型的对象。
您目前正在阅读第2篇(共6篇)文章
- 为对象检测安装 OpenCV 和 ImageAI
- 为 OpenCV 和 ImageAI 对象检测查找训练数据
- 使用预训练模型通过OpenCV和ImageAI检测对象
- 为使用 OpenCV 和 ImageAI 的对象检测准备图像
- 使用OpenCV和ImageAI训练自定义模型
- 使用OpenCV和ImageAI检测自定义模型对象
在上篇文章中,我们设置了检测安全帽合规性所需的所有开发工具,并使用OpenCV。
但是开发工具还不够。要训练AI计算机视觉模型,我们还需要一组包含人物图像的训练数据,其中一些人戴着安全帽,一些人没有。这些数据将使我们能够教会模型区分戴安全帽的人和不戴安全帽的人。
创建对象检测模型通常有三个步骤
- 加载要分类的数据样本
- 在样本数据上训练模型
- 在包含匹配和不匹配项的不同样本数据上测试模型
查找训练图像
我们将使用一个名为ImageNet的图像数据库来获取此阶段的大部分源数据。ImageNet维护一个图像数据库,使用WordNet的名词层次结构进行组织。例如,该数据库允许我们检索层次结构中的所有图像
人造物品 -> 覆盖物 -> 服装 -> 头饰/头盔 -> 头盔 -> 安全帽
ImageNet还提供了一个公共API,该API根据名词ID返回图像URL列表。让我们使用这个API下载大量戴安全帽的人的图像。该API的格式是
http://www.image-net.org/api/text/imagenet.synset.geturls?wnid=<WordNet ID>
我们将使用两个WordNet名词:安全帽名词(如上所述),ID为n03492922;以及杂项 -> 人名词,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。然后,我们使用指向我们请求库的req
变量查询API,并通过此库将两个方法链接在一起
.get
– 接受一个字符串URL并返回响应.text
– 接受一个二进制响应并将其转换为字符串值
一旦我们从API获得了源图像列表,我们就使用os.path.exists
方法检查是否有要下载图像的文件夹。如果我们没有目录存放它们,.makedirs()
方法将创建该目录。
接下来,我们启动for
循环,该循环使用我们从API下载的URL。我们按每个换行符(\n)拆分字符串,并将该字符串推送到变量i
。为了捕获下载文件的任何错误,我们还打开一个try
块。
在try
块中,此过程将遍历我们从API下载的所有URL。对于每个循环或URL,都会发生以下过程
- 我们使用
.get()
尝试下载文件。我们还使用可选参数timeout
在0.5秒后停止尝试下载文件 - 然后我们使用
.split()
两次拆分URL字符串。 - 第一次拆分发生在每个“/”处,数组中的-1值获取最后一个值。
- 第二次拆分会删除末尾的回车符。
- 下一步使用
.headers
数组检查下载的文件是否为jpeg。此数组包含来自响应的所有HTML头。 - 确认是jpeg后,我们再检查文件大小是否合适,以免处理任何错误图像。
- 如果下载的文件符合我们的要求,我们将使用
with
语句块将文件保存到hardhat文件夹。 - 最后,我们使用语句关闭所有
if
和try
块,以打印任何错误。
现在让我们运行这个代码块。您将看到代码运行并打印出通过API下载的每个图像的成功或失败情况。这可能需要几分钟,所以让它运行并等待完成消息。
检查下载的数据
运行下载器代码块后,您会注意到一些失败的消息。这很好,因为我们希望我们的文件夹中有准确的图像供分类器使用。打开一个资源管理器窗口,查看包含Jupyter Notebook的文件夹。现在您应该有一个名为“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 **************')
当我们运行这个代码块时,它应该和以前一样工作。但这次,如果我们检查保存Jupyter Notebook的文件夹,应该有一个包含没有戴安全帽的人的通用图像的“people”文件夹。
接下来
现在我们有了一个可用于训练和测试安全帽检测AI模型的数据集。
接下来,我们将看看使用我们的图像与预训练模型可以获得的结果。