0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用FOMO物体检测算法实现无人机野生动物计数系统的设计

科技观察员 来源:Jallson Suryo 作者:Jallson Suryo 2022-08-22 14:56 次阅读

人工智能在牲畜和野生动物监测中的作用预计将显着增长。这个项目就是一个例子,展示了人工智能如何使用嵌入式机器学习以快速有效的方式跟踪和计数对象(动物或农作物)。该跟踪系统使用无人机飞越场地(向下扫描表面)的计算机视觉,摄像头朝下。ML 模型将能够检测和区分动物或作物的类型,并可以实时计算每种对象(动物/作物)的累积数量。这使野生动物救援队能够监测动物/作物的数量,也可以用于企业计算畜牧和农业市场的潜在收入。

本项目使用 Edge Impulse 的 FOMO(Faster Objects, More Objects)物体检测算法。野生动物/牲畜/资产跟踪环境可以通过选择灰度图像块和具有 2 个输出类(例如乌龟和鸭子)的 FOMO 对象检测来模拟和执行。该项目利用 FOMO 快速高效的算法对对象进行计数,同时使用受限微控制器或单板基于 Linux 的计算机(如 Raspberry Pi)。

pYYBAGMDJ8aAUTAHAAEQqdXrvD4355.png

Edge Impulse 模型也在我们的 Python 代码中实现,以便它可以累积计算对象。该算法将当前帧的坐标与之前的帧进行比较;查看相机上是否有新对象,或者该对象之前是否已计数。在我们的测试中,有时计算的对象数量仍然不准确,因为该模型仍处于概念验证阶段。不过我们相信这个概念可以进一步发展到现实世界的应用中。

该项目共包括 5 个步骤:

准备

数据采集​​和标记

使用 FOMO 对象检测训练和构建模型

在 Raspberry Pi 上部署和测试对象检测

构建 Python 应用程序以检测和计数(累积)

第 1 步:准备

poYBAGMDJ8yAJxPuAALRo4wuStU795.png

使用更新的 Raspberry Pi OS(Buster 或 Bullseye)准备您的 Raspberry Pi。然后打开您的终端应用程序并ssh到您的 Pi。

从上方拍摄不同位置的物体(例如鸭子和乌龟),背景不同的照明条件,以确保模型可以在不同的条件下工作(防止过度拟合)。在这个项目中,我使用智能手机摄像头捕捉图像以进行数据收集,以方便使用。

注意:尽量保持图片中物体大小相似,物体大小的显着差异会混淆 FOMO 算法。

poYBAGMDJ9GAEbe6AAS8uAfdB9Q409.png

项目使用 Edge Impulse 作为机器学习平台,所以我们需要登录(首先创建一个帐户),然后转到Edge Impulse并创建新项目。

poYBAGMDJ9eALkK8AACNEPnMPEs709.png

第 2 步:数据采集和标记

选择图像项目选项,然后分类多个对象。

pYYBAGMDJ9yAK3MaAAJRP1wP2IM072.png

在 Dashboard 》 Project Info 中,选择 Bounding Boxes 进行标记方法,选择 Raspberry Pi 4 进行延迟计算。

pYYBAGMDJ-GAKkdKAAHyYjTWbkY941.png

然后在数据采集中,单击上传数据选项卡,选择您的文件,选择自动拆分,然后单击开始上传。

poYBAGMDJ-aAQxY1AAEtKB0R-QY449.png

现在,是时候贴标签了。单击标签队列选项卡,然后开始在对象周围拖动一个框并标记它(鸭或乌龟)并保存。重复直到标记所有图像。确保训练和测试数据之间的比率是理想的,大约为 80/20。

poYBAGMDJ-qAAIqQAAKAjXjmrVI662.png

第 3 步:使用 FOMO 对象检测训练和构建模型

准备好数据集后,转到 Create Impulse 并将 96 x 96 设置为图像宽度 - 高度(这有助于使模型的内存大小保持较小)。然后选择拟合最短轴,并选择图像和对象检测作为学习块。

pYYBAGMDJ_CABT7-AAFcdATcLhY661.png

转到图像参数部分,选择颜色深度作为灰度,然后按保存参数。

poYBAGMDJ_SAbQEtAAEcNkEbGnw102.png

最后,单击 Generate features 按钮,您应该会得到如下图所示的结果。

pYYBAGMDJ_mAWdwHAAD-V7ArCwQ581.png

然后,导航到目标检测部分,并保持神经网络的训练设置不变——在我们的例子中是非常平衡的预训练模型,然后我们选择 FOMO (MobileNet V2 0.35)。通过按开始训练来训练模型,您可以看到进度。如果一切正常,您应该会看到如下内容:

poYBAGMDJ_-ADe5qAAF8MD9LSWA267.png

之后我们可以测试模型,进入模型测试部分并单击全部分类。如果准确率结果超过 80%,那么我们可以进行下一步——部署。注意:如果准确率结果不如预期,请重新开始使用质量数据、标签,或者只是通过训练周期和学习率设置更改重新训练模型。

pYYBAGMDKAWAXKiGAAEL0vlga3U969.png

第 4 步:部署训练好的模型并在 Raspberry Pi 上进行测试

现在,我们可以切换到 Raspberry Pi。确保您的 Pi 已安装所有依赖项和 Edge Impulse for Linux CLI (如步骤 1 所示)并连接您的 Pi 摄像头(或 USB 网络摄像头)。然后,通过终端ssh你的 Pi 并输入:

$ edge-impulse-linux-runner

(如果您有多个项目,请添加- - clean )在此过程中,您将被要求登录您的 Edge Impulse 帐户。

这将自动下载您的模型并将其编译到您的 Pi,然后开始分类。结果将显示在终端窗口中。

您还可以在浏览器上启动视频流:http:// 你的树莓派 IP 地址:4912

Turtle 和 Duck 已通过 x、y 坐标实时成功识别(每次推理时间非常短)。

在这一步之前,我们已经取出数据并在 Edge Impulse 平台上训练了一个对象检测模型,并在我们的 Raspberry Pi 板上本地运行该模型。因此,可以得出结论,它已成功部署。

第 5 步:构建 Python 程序进行检测和计数

为了使该项目对特定用例更有意义,我们希望它计算从移动相机(通过无人机)拍摄的每种类型对象的累积计数。我们采用 Edge Impulse 的示例对象检测程序,并通过解决加权二分匹配问题将其转变为对象跟踪程序,以便可以跨不同帧跟踪同一对象。有关更多详细信息,您可以在下面的代码中查看。

因为我们使用 Python,所以我们需要安装 Python 3 Edge Impulse SDK 并从之前的 Edge Impulse 示例中克隆存储库。

您还需要下载经过训练的模型文件,以便我们正在运行的程序可以访问它。输入这个来下载它:

$ edge-impulse-linux-runner --download modelfile.eim

确保您/我们的程序 《count_moving_ducks》 放置在正确的目录中,例如:

$ cd linux-sdk-python/examples/image

然后,使用以下命令运行程序:

$ python3 count_moving_ducks.py ~/modelfile.eim

最后,我们成功实现了 Edge Impulse FOMO 对象检测模型,并在树莓派本地运行累积计数程序。以我们获得的速度和精度水平,我们有信心这个项目也可以用于微控制器,如 Arduino 的 Nicla Vision 或 ESP32 CAM,因此更容易安装到无人机上。

count_moving_ducks.py:

'''
Author: Jallson Suryo & Nicholas Patrick
Date: 2022-07-25
License: CC0
Source: Edge Impulse python SDK example file (classify.py) -- modified
Description: Program to count livestock or wildlife from a drone (moving camera) using
Edge Impulse FOMO trained model.
'''
#!/usr/bin/env python

import device_patches # Device specific patches for Jetson Nano (needs to be before importing cv2)

from math import inf, sqrt
from queue import Queue
import cv2
import os
import sys, getopt
import signal
import time
from edge_impulse_linux.image import ImageImpulseRunner

runner = None
# if you don't want to see a camera preview, set this to False
show_camera = True
if (sys.platform == 'linux' and not os.environ.get('DISPLAY')):
show_camera = False

def now():
return round(time.time() * 1000)

def get_webcams():
port_ids = []
for port in range(5):
print("Looking for a camera in port %s:" %port)
camera = cv2.VideoCapture(port)
if camera.isOpened():
ret = camera.read()[0]
if ret:
backendName =camera.getBackendName()
w = camera.get(3)
h = camera.get(4)
print("Camera %s (%s x %s) found in port %s " %(backendName,h,w, port))
port_ids.append(port)
camera.release()
return port_ids

def sigint_handler(sig, frame):
print('Interrupted')
if (runner):
runner.stop()
sys.exit(0)

signal.signal(signal.SIGINT, sigint_handler)

def help():
print('python classify.py ')

def main(argv):
try:
opts, args = getopt.getopt(argv, "h", ["--help"])
except getopt.GetoptError:
help()
sys.exit(2)

for opt, arg in opts:
if opt in ('-h', '--help'):
help()
sys.exit()

if len(args) == 0:
help()
sys.exit(2)

model = args[0]

dir_path = os.path.dirname(os.path.realpath(__file__))
modelfile = os.path.join(dir_path, model)

print('MODEL: ' + modelfile)

with ImageImpulseRunner(modelfile) as runner:
try:
model_info = runner.init()
print('Loaded runner for "' + model_info['project']['owner'] + ' / ' + model_info['project']['name'] + '"')
labels = model_info['model_parameters']['labels']
if len(args)>= 2:
videoCaptureDeviceId = int(args[1])
else:
port_ids = get_webcams()
if len(port_ids) == 0:
raise Exception('Cannot find any webcams')
if len(args)<= 1 and len(port_ids)> 1:
raise Exception("Multiple cameras found. Add the camera port ID as a second argument to use to this script")
videoCaptureDeviceId = int(port_ids[0])

camera = cv2.VideoCapture(videoCaptureDeviceId)
ret = camera.read()[0]
if ret:
backendName = camera.getBackendName()
w = camera.get(3)
h = camera.get(4)
print("Camera %s (%s x %s) in port %s selected." %(backendName,h,w, videoCaptureDeviceId))
camera.release()
else:
raise Exception("Couldn't initialize selected camera.")

HEIGHT = 96
WIDTH = 96

next_frame_start_time = 0
prev_frame_objects = []
cumulative_counts = {'duck' : 0, 'turtle' : 0}

# iterate through frames
for res, img in runner.classifier(videoCaptureDeviceId):
# print('classification runner response', res)

if "classification" in res["result"].keys():
print('Result (%d ms.) ' % (res['timing']['dsp'] + res['timing']['classification']), end='')
for label in labels:
score = res['result']['classification'][label]
print('%s: %.2f\t' % (label, score), end='')
print('', flush=True)

elif "bounding_boxes" in res["result"].keys():
curr_frame_objects = res["result"]["bounding_boxes"]
m, n = len(prev_frame_objects), len(curr_frame_objects)
print('Found %d bounding boxes (%d ms.)' % (n, res['timing']['dsp'] + res['timing']['classification']))
# iterate through identified objects
for bb in curr_frame_objects:
print('\t%s (%.2f): x=%d y=%d w=%d h=%d' % (bb['label'], bb['value'], bb['x'], bb['y'], bb['width'], bb['height']))
img = cv2.rectangle(img, (bb['x'], bb['y']), (bb['x'] + bb['width'], bb['y'] + bb['height']), (255, 0, 0), 1)

# Pairs objects seen in both the previous frame and the current frame.
# To get a good pairing, each potential pair is given a cost. The problem
# then transforms into minimum cost maximum cardinality bipartite matching.

# populate table
def get_c(a0, a1):
# computes cost of pairs. A cost of inf implies no edge.
A, B = sqrt(HEIGHT ** 2 + WIDTH ** 2) / 8, 5
if a0['label'] != a1['label']: return inf
d2 = (a0['x'] - a1['x']) ** 2 + (a0['x'] - a1['x']) ** 2
dn4 = d2 ** -2 if d2 else 10**20
val = a0['value'] * a1['value'] * (((1 + B) * dn4) / (dn4 + A ** -4) - B)
return inf if val <= 0 else 1 - val
match_c = [[get_c(i, j) for j in curr_frame_objects] for i in prev_frame_objects]

# solves the matching problem in O(V^2E) by repeatedly finding augmenting paths
# using shortest path faster algorithm (SPFA).
# A modified Hungarian algorithm could also have been used.
# 0..m-1: prev, left
# m..m+n-1: this, right
# m+n: source
# m+n+1: sink
source, sink, V = m + n, m + n + 1, m + n + 2
matched = [-1] * (m + n + 2)
adjLis = [[] for i in range(m)] + [[(sink, 0)] for _ in range(n)] + [[(i, 0) for i in range(m)], []]
# left right source sink
for i in range(m):
for j in range(n):
if match_c[i][j] != inf:
adjLis[i].append((j + m, match_c[i][j]))

# finds augmenting paths until no more are found.
while True:
# SPFA
distance = [inf] * V
distance[source] = 0
parent = [-1] * V
Q, inQ = Queue(), [False] * V
Q.put(source); inQ[source] = True
while not Q.empty():
u = Q.get(); inQ[u] = False
for v, w in adjLis[u]:
if u < m and matched[u] == v: continue
if u == source and matched[v] != -1: continue
if distance[u] + w < distance[v]:
distance[v] = distance[u] + w
parent[v] = u
if not inQ[v]: Q.put(v); inQ[v] = True
aug = parent[sink]
if aug == -1: break
# augment the shortest path
while aug != source:
v = aug
aug = parent[aug]
u = aug
aug = parent[aug]
adjLis[v] = [(u, -match_c[u][v - m])]
matched[u], matched[v] = v, u

# updating cumulative_counts by the unmatched new objects
for i in range(n):
if matched[m + i] == -1:
cumulative_counts[curr_frame_objects[i]['label']] += 1

# preparing prev_frame_objects for the next frame
next_prev_frame_objects = curr_frame_objects
# considering objects that became invisible (false negative) for a few frames.
for i in range(m):
if matched[i] != -1: continue
prev_frame_objects[i]['value'] *= 0.7
if prev_frame_objects[i]['value'] >= 0.35:
next_prev_frame_objects.append(prev_frame_objects[i])
prev_frame_objects = next_prev_frame_objects

print("current cumulative_counts:\n %d ducks, %d turtles" % (cumulative_counts['duck'], cumulative_counts['turtle']))

if (show_camera):
cv2.imshow('edgeimpulse', cv2.cvtColor(img, cv2.COLOR_RGB2BGR))
if cv2.waitKey(1) == ord('q'):
break

if (next_frame_start_time > now()):
time.sleep((next_frame_start_time - now()) / 1000)
# operates at a maximum of 5fps
next_frame_start_time = now() + 200
finally:
if (runner):
runner.stop()

if __name__ == "__main__":
main(sys.argv[1:])

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据采集
    +关注

    关注

    38

    文章

    4504

    浏览量

    112310
  • 无人机
    +关注

    关注

    224

    文章

    9873

    浏览量

    174774
  • 检测算法
    +关注

    关注

    0

    文章

    117

    浏览量

    25148
  • 计数系统
    +关注

    关注

    0

    文章

    4

    浏览量

    5440
收藏 人收藏

    评论

    相关推荐

    科学家呼吁避免无人机打扰动物

    `目前,无人机被越来越广泛用于监控和保护野生生物。但研究人员近日在《当代生物学》期刊上撰文称,应制定策略,确保无人机不会对动物造成过度压力。“即便
    发表于 06-12 13:39

    AMEYA360设计方案丨通用无人机解决方案

    、灾难救援、观察野生动物、监控传染病、测绘、新闻报道、电力巡检、救灾、影视拍摄、制造浪漫等等领域的应用,大大的拓展了无人机本身的用途,发达国家也在积极扩展行业应用与发展无人机技术。2、方案概述Ameya360
    发表于 10-25 13:49

    无人机飞控系统

    不再只是简单的靶机,也不仅仅只是“会飞的照相机”,它现在在广泛的场景中发挥着作用。无人机不仅在军事中作用巨大,还在航拍、农业、植保、微型自拍、快递运输、灾难救援、观察野生动物、监控传染病、测绘、新闻报道
    发表于 07-21 08:03

    基于GPRS的野生动物远程监测系统设计

    笔者从实际应用出发,以GPRS模块为核心,设计一种无线远程监测系统,用以检测野生动物的体温、运动量和环境温度,采集导数据经数据处理模块处理后,通过GPRS接入Internet进行远程传
    发表于 06-19 11:22 1812次阅读
    基于GPRS的<b class='flag-5'>野生动物</b>远程监测<b class='flag-5'>系统</b>设计

    使用物联网和英特尔Movidius神经计算棒自动执行野生动物图像处理

    Where of the Bear(WTB)的设计和实施,这是一种用于野生动物监测的端到端分布式物联网系统
    的头像 发表于 11-12 06:09 2159次阅读

    物联网和人工智能如何保护野生动物

    由于偷猎活动的增加,野生动物濒临灭绝。世界各国政府正在通过使用物联网(IOT)和人工智能来保护濒临灭绝的野生动物,旨在解决这一严重问题。
    的头像 发表于 02-12 17:22 4842次阅读

    AI助力野生动物保护行动 或将扭转物种数量持续减少的恶性趋势

    为了更有效地保护野生动物,谷歌与七家国际动物保护组织联合起来,凭借运动相机拍摄的照片,绘制了450多万只野生动物的行动地图。这些照片都发布在了野生动物观察平台(Wildlife Ins
    发表于 03-18 10:44 522次阅读

    VR野生动物系统,拉近了人们与野生动物之间的距离

    实现参与者与设备不用产生实际接触的交互式科普体验。 VR野生动物与传染病科普是一款致力于帮助人们走进动物的VR应用,它提供的互动体验可以让体验者与地球上的濒危动物面对面交流。 此外,在
    发表于 08-05 15:55 1873次阅读

    使用无人机、热成像仪和人工智能帮助野生动物和土地的保护

    国外Tech Republic网站12月23日报道称,许多研究人员正在利用大量技术手段来帮助野生动物和土地的保护,包括用面部识别跟踪加拿大西部的熊、通过深度学习预测美国的野火……而在澳大利亚,昆士兰科技大学(QUT)的研究小组正在利用人工智能(AI)、无人机、热成像和机器
    发表于 12-24 16:54 942次阅读

    智能野生动物追踪和监测系统的6大好处

    导读 :野生动物保护面临着越来越多的挑战,这使得物联网智能野生动物跟踪和监测系统的出现成为自然资源保护者、研究人员和反偷猎团队的分水岭。让我们探索一些挑战和好处。 有效的野生动物保护是
    的头像 发表于 04-15 15:46 5021次阅读

    555定时器构成的野生动物驱避传感器

    电子发烧友网站提供《555定时器构成的野生动物驱避传感器.zip》资料免费下载
    发表于 08-11 10:33 3次下载
    555定时器构成的<b class='flag-5'>野生动物</b>驱避传感器

    Xiraffe桅杆上的智能野生动物观测站

    电子发烧友网站提供《Xiraffe桅杆上的智能野生动物观测站.zip》资料免费下载
    发表于 10-20 09:37 0次下载
    Xiraffe桅杆上的智能<b class='flag-5'>野生动物</b>观测站

    WAiT:野生动物追踪器

    电子发烧友网站提供《WAiT:野生动物追踪器.zip》资料免费下载
    发表于 10-31 09:38 2次下载
    WAiT:<b class='flag-5'>野生动物</b>追踪器

    野生动物探测器开源分享

    电子发烧友网站提供《野生动物探测器开源分享.zip》资料免费下载
    发表于 10-31 09:36 0次下载
    <b class='flag-5'>野生动物</b>探测器开源分享

    基于单片机开发的GPS野生动物追踪系统

    在研究野生动物的生活习性和活动范围上,包括鸟类的迁徙,经常会用到GPS定位系统来进行跟踪。单片机开发人员分享了一个基于单片机开发的GPS野生动物追踪系统方案。使用该方案,可以跟踪
    的头像 发表于 07-11 09:21 639次阅读
    基于单片机开发的GPS<b class='flag-5'>野生动物</b>追踪<b class='flag-5'>系统</b>