害虫问题一直是企业和家庭共同的烦恼。无论是鹿、驼鹿还是猫,都有可能对花园、庄稼和财产造成损害。在本系列文章中,将展示如何在树莓派上实时(或近实时)检测害虫(例如驼鹿),然后采取措施将其驱赶。由于不想造成任何伤害,将专注于通过播放响亮的噪音来吓走害虫。
可以随时下载项目的源代码。假设熟悉Python,并且对神经网络的工作原理有基本的了解。
首先,需要配置边缘设备。将使用带有16GB内存的树莓派3B+。操作系统将是树莓派OS(32位)。可以通过PIP通道安装PythonOpenCV库。
为了播放声音,将使用Pygame库。这个包在大多数与树莓派设备一起使用的操作系统上都是预安装的。假设将使用3.5mm耳机插孔播放声音,因此在Pi设备上使用默认的音频输出配置。
请注意,这只是作为一个概念验证。如果试图构建一个商业害虫探测器,可能会想要使用像Jetson或Coral这样的设备。它们提供了既实惠的原型板和生产就绪的硬件 - 所以一旦产品准备好了,就可以轻松地进入大规模生产。
为了在Pi设备上播放声音并测试检测算法,需要编写一些额外的代码。
首先,将使用Pygame混音器模块创建一个声音播放器:
from pygame import mixer
class SoundPlayer:
def __init__(self, sound_file):
mixer.init(44100, -16, 2, 2048)
self.sound = mixer.Sound(sound_file)
def play(self):
self.sound.play()
接下来,需要一个类来测量应用程序的帧处理速度:
import time
class FPS:
def __init__(self):
self.frame_count = 0
self.elapsed_time = 0
def start(self):
self.start_time = time.time()
def stop(self):
self.stop_time = time.time()
self.frame_count += 1
self.elapsed_time += (self.stop_time - self.start_time)
def count(self):
return self.frame_count
def elapsed(self):
return self.elapsed_time
def fps(self):
if self.elapsed_time == 0:
return 0
else:
return self.frame_count / self.elapsed_time
class VideoPDSound:
def __init__(self, md, pd, thresh, sp):
self.md = md
self.pd = pd
self.thresh = thresh
self.sp = sp
self.fps = FPS()
def play(self, file_path):
capture = cv2.VideoCapture(file_path)
md_name = 'Motion objects'
cv2.namedWindow(md_name, cv2.WINDOW_NORMAL)
cv2.resizeWindow(md_name, 640, 480)
counter = 0
play_dt = 10.0
curr_time = time.time()
play_time = curr_time - play_dt - 0.1
detect_count = 0
while True:
(ret, frame) = capture.read()
if frame is None:
break
counter = counter + 1
if (counter % 3) != 0:
continue
self.fps.start()
self.md.process(frame)
objects = self.md.objects()
l = len(objects)
pests = []
if l > 0:
for (i, obj) in enumerate(objects):
(roi, (class_num, class_conf)) = self.pd.detect(frame, obj)
if (class_num > 0) and (class_conf >= self.thresh):
pests.append(roi)
self.fps.stop()
if l > 0:
Utils.draw_objects(objects, "OBJECT", (255, 0, 0), frame)
k = len(pests)
if k > 0:
detect_count = detect_count + 1
Utils.draw_objects(pests, "PEST", (0, 0, 255), frame)
curr_time = time.time()
dt = curr_time - play_time
if dt > play_dt:
self.sp.play()
play_time = curr_time
cv2.imshow(md_name, frame)
time.sleep(0.01)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
capture.release()
cv2.destroyAllWindows()
f = self.fps.fps()
return (detect_count, f)
这段代码现在通过调用self.fps.start和self.fps.stop方法来监控检测过程的性能。请注意,只评估检测算法(运动检测和分类)的执行时间。修改后的代码在检测到一帧中的害虫时,通过调用self.sp.play来播放声音。在现实生活中,驼鹿可能会在连续几帧中被检测到。不想每次驼鹿出现在摄像机视野中时都播放声音。
目标是发出一次可怕的声音,然后等待新的害虫出现。该算法播放声音的频率不超过每10秒一次。所以如果有一群恶意的驼鹿在万寿菊中徘徊,将一次性地吓走它们 - 如果有必要的话,一个接一个。
还需要选择一个适合吓走害虫的声音。让从互联网上许多免费的蜂鸣器声音中选择一个;例如,这个:
buzzer.wav
现在准备在树莓派设备上运行害虫消除算法:
video_file = r"/home/pi/Desktop/PI_PEST/video/moose_1.mp4"
md = MD(0.05, 0.1)
proto = r"/home/pi/Desktop/PI_PEST/net/moose.prototxt"
model = r"/home/pi/Desktop/PI_PEST/net/moose.caffemodel"
pd = PestDetector(proto, model, 128)
sound_file = r"/home/pi/Desktop/PI_PEST/video/buzzer.wav"
scarer = SoundPlayer(sound_file)
v_pd = VideoPDSound(md, pd, 0.99, scarer)
(detect_count, fps) = v_pd.play(video_file)
print("FPS = %s" % fps)
这是处理完的视频:
当视频处理完成后,在控制台显示平均处理速度。对于这个视频文件,它的测量值是11到12 FPS。比基于预训练的SSD模型的算法快一个数量级。(记得吗?那里的速度大约是1.25 FPS)。自定义算法在没有进行硬优化或并行处理的情况下,以几乎实时的速度运行。
在本系列文章中,展示了如何在树莓派设备上使用AI算法消除现实生活中户外环境中的害虫。首先开发了代码,使预训练的SSD模型支持检测常见的害虫,如牛、羊,甚至是猫和狗。
然后为“不寻常”的害虫:驼鹿组装了一组图像样本。应用了几种数据增强方法来增强数据集。然后开发了一个简单的小型DNN分类器模型,并在增强的数据集上进行了训练,准确度相当高,达到了97%。
最后,设计了一个基本的运动检测算法,并将其与DNN分类器结合起来。完整的算法在视频文件上进行了测试,显示出令人惊讶的11到12 FPS的良好性能。