使用预先训练的SSD模型检测害虫

目录

介绍

选择网络架构

害虫检测代码

它能运行吗?

它可以在边缘设备上工作吗?

下一步


在这里,我们给出了有关如何使用预训练的MobileSSD模型检测对象的简短说明。然后,我们提供并解释用于使用SSD模型检测视频中动物的Python代码。最后,我们在视频文件上演示了某种动物类型(SSD模型能够检测到)的检测结果。

介绍

野蛮的野生生物可能给企业和房主带来痛苦。鹿、驼鹿甚至猫等动物都会对花园、庄稼和财产造成破坏。

在本系列文章中,我们将演示如何在Raspberry Pi上实时(或近实时)检测有害生物(例如驼鹿),然后采取措施消除有害生物。由于我们不想造成任何伤害,我们将通过播放巨大的噪音来吓跑害虫。

欢迎您下载该项目的源代码。我们假设您熟悉Python并且对神经网络的工作原理有基本的了解。

在该系列的上一篇文章中,我们比较了可用于检测有害生物的两种DNN类型:检测器和分类器。检测器赢了。在本文中,我们将开发使用预先训练的检测DNN来检测有害生物的Python代码。

选择网络架构

有几种常见的对象检测网络架构,例如Faster-RCNN单发检测器(SSD只看一次YOLO

由于我们的网络需要在内存和CPU受限的边缘设备上运行,因此我们将使用MobileNet单发检测器(SSD)架构。MobileNet SSD是一种轻量级的对象检测器网络,可以在移动设备和边缘设备上很好地运行。在Pascal VOC 2012数据集上对其进行了训练,该数据集包含一些可能代表害虫的类别,例如猫、牛、狗、马和羊。

我们将使用与该先前的文章系列中用于人类检测的算法相同的算法来检测视频中的害虫。

害虫检测代码

首先,我们需要修改MobileNet代码以使其检测到有害生物。

让我们从创建一些实用程序类开始,以简化此任务:

import cv2
import numpy as np
import os

class CaffeModelLoader:    
    @staticmethod
    def load(proto, model):
        net = cv2.dnn.readNetFromCaffe(proto, model)
        return net

class FrameProcessor:    
    def __init__(self, size, scale, mean):
        self.size = size
        self.scale = scale
        self.mean = mean
    
    def get_blob(self, frame):
        img = frame
        (h, w, c) = frame.shape
        if w>h :
            dx = int((w-h)/2)
            img = frame[0:h, dx:dx+h]
            
        resized = cv2.resize(img, (self.size, self.size), cv2.INTER_AREA)
        blob = cv2.dnn.blobFromImage(resized, self.scale, (self.size, self.size), self.mean, False, False)
        return blob

class Utils:    
    @staticmethod
    def draw_object(obj, label, color, frame):
        (confidence, (x1, y1, w, h)) =  obj
        x2 = x1+w
        y2 = y1+h
        cv2.rectangle(frame, (x1, y1), (x2, y2), color, 2)
        y3 = y1-12
        text = label + " " + str(confidence)+"%"
        cv2.putText(frame, text, (x1, y3), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 1, cv2.LINE_AA)
        
    @staticmethod
    def draw_objects(objects, label, color, frame):
        for (i, obj) in enumerate(objects):
            Utils.draw_object(obj, label, color, frame)

CaffeModelLoader类使用为原型和模型文件提供的路径从磁盘加载Caffe模型。

下一个实用程序类FrameProcessor,将帧转换为Blob(用作CNN输入的特殊结构化数据)。

最后,Utils类在框架中检测到的所有对象周围绘制边界矩形。我们的实用程序类使用的大多数方法来自OpenCVPython版本。让我们详细看看这些。

对于我们的实用程序类就是这样。接下来,我们将编写实际检测有害生物的代码。

SSD类开始,它可以检测框架中指定类的对象:

class SSD:    
    def __init__(self, frame_proc, ssd_net):
        self.proc = frame_proc
        self.net = ssd_net
    
    def detect(self, frame):
        blob = self.proc.get_blob(frame)
        self.net.setInput(blob)
        detections = self.net.forward()
        # detected object count
        k = detections.shape[2]
        obj_data = []
        for i in np.arange(0, k):
            obj = detections[0, 0, i, :]
            obj_data.append(obj)
            
        return obj_data

    def get_object(self, frame, data):
        confidence = int(data[2]*100.0)
        (h, w, c) = frame.shape
        r_x = int(data[3]*h)
        r_y = int(data[4]*h)
        r_w = int((data[5]-data[3])*h)
        r_h = int((data[6]-data[4])*h)
        
        if w>h :
            dx = int((w-h)/2)
            r_x = r_x+dx
        
        obj_rect = (r_x, r_y, r_w, r_h)
        
        return (confidence, obj_rect)
        
    def get_objects(self, frame, obj_data, class_num, min_confidence):
        objects = []
        for (i, data) in enumerate(obj_data):
            obj_class = int(data[1])
            obj_confidence = data[2]
            if obj_class==class_num and obj_confidence>=min_confidence :
                obj = self.get_object(frame, data)
                objects.append(obj)
                
        return objects

该类中的关键方法是detectget_objects

detect方法将加载的DNN模型应用于每个帧,以检测所有可能类别的对象。

get_objects方法查看检测到的对象,并仅选择那些既属于指定类又具有被正确检测到的高概率(置信度)的对象。

然后,我们将使用VideoSSD类,该类在整个视频剪辑上运行有害生物检测:

class VideoSSD:    
    def __init__(self, ssd):
        self.ssd = ssd
    
    def detect(self, video, class_num, min_confidence, class_name):
        detection_num = 0;
        capture = cv2.VideoCapture(video)
        img = None

        dname = 'Pest detections'
        cv2.namedWindow(dname, cv2.WINDOW_NORMAL)
        cv2.resizeWindow(dname, 1280, 960)
       
        # Capture all frames
        while(True):    
            (ret, frame) = capture.read()
            if frame is None:
                break
        
            obj_data = self.ssd.detect(frame)
            class_objects = self.ssd.get_objects(frame, obj_data, class_num, min_confidence)
            p_count = len(class_objects)
            detection_num += p_count
            
            if len(class_objects)>0:
                Utils.draw_objects(class_objects, class_name, (0, 0, 255), frame)
            
            # Display the resulting frame
            cv2.imshow(dname,frame)
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
            
        capture.release()
        cv2.destroyAllWindows()    
        
        return detection_num

该类中唯一的方法是detect。它处理从视频文件提取的所有帧。在每个框架中,它检测由class_num参数指定的类的所有对象,然后在检测到的对象周围显示带有边界矩形的框架。

它能运行吗?

让我们启动代码,看看它如何处理视频文件。以下代码加载视频文件并尝试检测狗:

proto_file = r"C:\PI_PEST\net\mobilenet.prototxt"
model_file = r"C:\PI_PEST\net\mobilenet.caffemodel"
ssd_net = CaffeModelLoader.load(proto_file, model_file)

mobile_proc_frame_size = 300
ssd_proc = FrameProcessor(mobile_proc_frame_size, 1.0/127.5, 127.5)

pest_class = 12
pest_name = "DOG"

ssd = SSD(ssd_proc, ssd_net)

video_file = r"C:\PI_PEST\video\dog_1.mp4"

video_ssd = VideoSSD(ssd)
detections = video_ssd.detect(video_file, pest_class, 0.2, pest_name)

我们将pest_class值设置为12,因为“dog”MobileNet SSD模型中的第12类。这是运行上述代码时捕获的视频。

https://youtube.com/embed/V7efecRb8Lo

它可以在边缘设备上工作吗?

如您所见,当在PC上运行时,我们的SSD检测器成功检测到视频中的狗。边缘设备呢?检测器是否会足够快地处理提要以实时检测物体?我们可以通过测试以每秒帧数(FPS)衡量的帧速率来找出。

我们之前引用文章中,我们借用的模型在Raspberry Pi 3设备上的运行速度约为1.25 FPS。这足以检测到害虫吗?我们可以假设平均而言,动物会在相机上捕获至少23秒。这意味着我们将拥有23个帧来检测有害生物并对其做出反应。听起来很有可能。

下一步

到目前为止,对于野生动植物的检测结果还不是很有希望。但是我们不要放弃!

接下来的文章中,我们将讨论一些想法检测异国情调的害虫,如驼鹿和犰狳。

https://www.codeproject.com/Articles/5289748/Detecting-Pests-Using-Pre-Trained-SSD-Models

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值