通过识别图像或视频中的物体及其在捕获帧中的位置,可以构建帮助人们在环境中导航的工具。在这类应用中,使用语音合成算法来叙述给定的单词或句子非常有用。可以让模型识别房间中的对象,然后让语音合成器读出所发现的内容。
本指南将带了解如何使用计算机视觉来叙述房间的内容。将使用两个现成的模型来开始,并构建逻辑来叙述模型的预测结果。让开始吧!
将构建一个应用程序,它能够: 识别某人所在的房间类型; 叙述该房间中的对象。 为了构建这个应用程序,需要使用两个模型。一个模型可以识别照片拍摄的房间类型,另一个模型可以识别房间中的具体对象。 幸运的是,已经有模型可以帮助完成这两个任务。在本教程中,将使用MIT室内场景识别,这是一个图像分类模型,可以让识别照片中的房间类型。还将使用一个名为“all_finalize”的模型,该模型可以识别一些常见的家庭物品,如橱柜和冰箱。 这两个模型的版本都托管在Roboflow Universe上,这是一个开放模型和数据集的存储库。要使用这些模型,需要一个免费的Roboflow账户。 “all_finalize”模型是识别室内物品的良好起点,但可能想要在此基础上构建模型,以提高其检测不同对象的能力,或添加新类别。可以通过下载与模型相关的数据集并添加自己的注释图像来实现这一点。 现在已经选择了要使用的模型,可以开始编写代码逻辑了!
首先,需要创建应用程序脚本,并编写一些代码来配置对Roboflow API和将在本项目中使用的文本到语音库pyttsx3的使用。创建一个名为“app.py”的文件,并粘贴以下代码:
import time
import os
import pyttsx3
import roboflow
rf = roboflow.Roboflow(api_key=os.environ["ROBOFLOW_API_KEY"])
workspace = rf.workspace()
engine = pyttsx3.init()
engine.setProperty("rate", 150)
此代码导入了项目所需的库,通过“workspace”对象可以查询Roboflow模型,并配置了pyttsx3库。150的值指的是模型使用的语音速率。如有必要,可以调整这个值。 需要在环境变量中保留一个名为“ROBOFLOW_API_KEY”的值,该值存储了Roboflow API密钥。可以通过遵循API密钥指南来检索这个值。 现在已经设置了脚本,可以开始编写应用程序的核心逻辑了。
让编写代码来叙述照片拍摄的房间类型。首先,将编写一个包装函数,该函数既可以叙述字符串,也可以将该字符串打印到控制台:
def say(text: str) -> None:
"""
说出文本并在控制台打印该文本。
"""
engine.say(text)
print(text)
engine.runAndWait()
接下来,将编写一个函数,该函数使用Roboflow上的MIT室内场景识别模型来识别照片拍摄的房间类型。这个函数将接受一个参数:要运行推理的图像文件的名称。将返回一个包含模型返回的所有预测的字典。
def get_room_type(image_file: str) -> dict:
"""
获取照片拍摄的房间类型(例如厨房)。
"""
indoor_scene_recognition = workspace.project("mit-indoor-scene-recognition")
model = indoor_scene_recognition.version(5).model
prediction = model.predict(image_file)
room = prediction.json()
return room
为了测试函数,可以调用它并传递一个文件的名称。在这种情况下,将传递一个名为“kitchen1.jpeg”的文件。该文件如下所示:
image = "images/kitchen1.jpeg"
room = get_room_type(image)
room_type = room["predictions"][0]["top"]
say(room)
此代码将读出照片拍摄的房间类型。上面的图像是在厨房拍摄的。当脚本运行时,会叙述出“厨房”这个词。 现在知道了照片拍摄的房间类型,可以继续叙述房间中的具体对象。
将使用“all_finalize”模型来识别房间中的具体对象。让编写一个函数,该函数在Roboflow Universe上使用此模型,并创建一个包含房间中所有物品的列表。还将使用Roboflow Python包中的prediction.save()函数保存预测结果,以便可以可视化代码结果:
def get_items_in_room(image: str) -> list:
"""
在房间中找到物品。
"""
project = workspace.project('all_finalize')
model = project.version(3).model
prediction = model.predict(image, confidence=10)
predictions = prediction.json()
labels = [p["class"] for p in predictions["predictions"]]
prediction.save("out.png")
return labels
让测试这个函数是否有效,通过编写一行代码来调用该函数并打印所有识别的标签到控制台:
print(get_items_in_room(image))
此代码返回以下列表: []
可以打开“out.png”文件查看模型的结果: all_finalize模型已成功识别房间中的一些对象。现在可以编写一个函数来叙述识别出的对象:
def narrate_room(room_type: str, labels: list) -> None:
"""
说出照片拍摄的房间类型和房间中的物品。
"""
say(f"You are in a {room_type}")
time.sleep(1)
if len(labels) > 0:
say("I see")
time.sleep(0.5)
for label in labels:
label = label.lower()
say("A " + label)
time.sleep(0.5)
此函数: 说出“You are in a {room}”,其中{room}等于传入函数的房间类型的名称。 等待一秒钟。 如果房间中发现了物品,则说出“I see”。 说出房间中找到的每个物品的名称。在每个词的开头附加“A”,使工具听起来更会话化。 让调用这个函数并传入编写的代码的结果,该代码识别了房间类型和房间中的物品: labels = get_items_in_room(image) narrate_room(room_type, labels)