树莓派应用--AI项目实战篇来啦-15.SSD Mobilenet V3目标检测

news2024/12/28 13:38:45

1. Mobilenet 介绍

         Mobilenet 是一种专为移动和嵌入式视觉应用而设计的卷积神经网络。它们不使用标准的卷积层,而是基于使用深度可分离卷积的简化架构,使用这种架构,我们可以为移动和嵌入式设备(例如:树莓派)构建低延迟的轻量级深度神经网络。

2. SSD运动目标检测算法介绍

        SSD(single Shot Multi Box Detection)是一种针对多种类别的单次深度神经网络,同时集中了 YOLO 的回归思想和 Faster RCNN 算法的 Anchor 机制,从一个层面来说,采用回归思想可以降低检测过程中卷积计算的复杂度,使得算法时效性整体提高,从另一层面来说,采用 Anchors机制能够提取不同宽、高比例的特征,提高算法的鲁棒性,在识别方面,该算法比YOLO 算法在对某一位置进行全局特征提取时效果更好,因此,SSD 算法的核心思想是基于小卷积滤波器来预测目标,并生成一组固定的默认边界框,并给出类别得分和偏移,这样设计的好处在于,当检测不规则大小形状的物体时鲁棒性增强。


        SSD (Single Shot MultiBox Detector)是一种流行的物体检测算法。SSD 通过消除对区域生成网络的需求来加速该过程。为了防止精度下降,SSD采用了包括多尺度功能和默认框在内的一些改进方法。这些改进使 SSD 能够以较低分辨率的图像匹配更快的R-CNN精度,从而进一步提高检测速度。带有MobileNet的SSD是一种针对移动设备推理进行了优化的对象检测模型。
        这里的关键思想是采用单个网络(速度)而不需要区域提议。相反,它使用不同的边界框,然后作为预测的一部分调整边界框。网络的最后几层中的每一层都负责预测逐渐变小的边界框,并且最终预测是所有这些预测的并集,从而实现不同的边界框预测。

3. OpenCV DNN 模块 MobileNet-SSD 介绍

        OpenCV DNN 模块支持常见的对象检测模型SSD,以及它的移动版Mobile Net-SSD,特别是后者在端侧边缘设备上可以实时计算,基于Caffe训练好的 mobile-net SSD支持20类别对象检测。
在Caffe训练好的 mobile-net SSD 中内置了“background","aeroplane”,"bicycle","bird", "boat","bottle","bus","horse","motorbike","car","cat","chair","person","pottedplant", "sheep","cow","diningtable"," dog"等20种对象检测。

4.源程序代码

        运行程序后,该程序实现了两个 SSD 目标检测实验

4.1 提前录制的视频目标识别

        在网络上下载提前录制好的视频文件,可以看到如下流程的检测各种车辆的识别效果。

# 载入必要的库
import cv2

# 线程函数操作库
import threading # 线程
import ctypes
import inspect

# 线程结束代码
def _async_raise(tid, exctype):
    tid = ctypes.c_long(tid)
    if not inspect.isclass(exctype):
        exctype = type(exctype)
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
        raise SystemError("PyThreadState_SetAsyncExc failed")
        
def stop_thread(thread):
    _async_raise(thread.ident, SystemExit)

def bgr8_to_jpeg(value, quality=75):
    return bytes(cv2.imencode('.jpg', value)[1])
    
import traitlets
import ipywidgets.widgets as widgets
from IPython.display import display

detection_img = widgets.Image(format='jpeg', width=1920, height=1080)
display(detection_img)

config_file = 'ssd_mobilenet_v3_large_coco_2020_01_14.pbtxt'
frozen_model = 'frozen_inference_graph.pb'
model = cv2.dnn_DetectionModel(frozen_model, config_file)
classLabels = []
filename = 'labels.txt'
with open(filename, 'rt') as spt:
    classLabels = spt.read().rstrip('\n').split('\n')

model.setInputSize(320, 320)  #greater this value better the reults but slower. Tune it for best results
model.setInputScale(1.0/127.5)
model.setInputMean((127.5, 127.5, 127.5))
model.setInputSwapRB(True)

cap = cv2.VideoCapture('test_video.mp4')
ret, frame = cap.read()

fourcc = cv2.VideoWriter_fourcc(*'mp4v')
video = cv2.VideoWriter('video.avi', fourcc, 25, (frame.shape[1], frame.shape[0]))  #25 is the frame rate of output video you can change it as required


font = cv2.FONT_HERSHEY_PLAIN

def Video_display():
    while(True):
        ret, frame = cap.read()
        classIndex, confidence, bbox = model.detect(frame , confThreshold=0.65)  #tune the confidence  as required
        if(len(classIndex) != 0):
            for classInd, boxes in zip(classIndex.flatten(), bbox):
                cv2.rectangle(frame, boxes, (255, 0, 0), 2)
                cv2.putText(frame, classLabels[classInd-1], (boxes[0] + 10, boxes[1] + 40), font, fontScale = 1, color=(0, 255, 0), thickness=2)

        video.write(frame)
        detection_img.value = bgr8_to_jpeg(frame) # 实时显示图像

# 开始线程
t = threading.Thread(target=Video_display)
t.setDaemon(True)
t.start()

# 结束线程
stop_thread(t)

4.2 摄像头目标识别

import libcamera
from picamera2 import Picamera2

picamera = Picamera2()
config = picamera.create_preview_configuration(main={"format": 'RGB888', "size": (320, 240)},
                                               raw={"format": "SRGGB12", "size": (1920, 1080)})
config["transform"] = libcamera.Transform(hflip=0, vflip=1)
picamera.configure(config)
picamera.start()

pidetection_img = widgets.Image(format='jpeg', width=640, height=480)
display(pidetection_img)


def PiVideo_display():
    while(True):
        frame = picamera.capture_array()
        classIndex, confidence, bbox = model.detect(frame , confThreshold=0.65)  #tune the confidence  as required
        if(len(classIndex) != 0):
            for classInd, boxes in zip(classIndex.flatten(), bbox):
                cv2.rectangle(frame, boxes, (255, 0, 0), 2)
                cv2.putText(frame, classLabels[classInd-1], (boxes[0] + 10, boxes[1] + 40), font, fontScale = 1, color=(0, 255, 0), thickness=2)

        video.write(frame)
        pidetection_img.value = bgr8_to_jpeg(frame) # 实时显示图像

# 开始线程
t1 = threading.Thread(target=PiVideo_display)
t1.setDaemon(True)
t1.start()

# 结束线程
stop_thread(t1)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2212468.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Navicat 关于SQLserver的连接问题

1、如果出以下问题,就需要安装驱动程序,如下图: 2、在Navicat的根目录下有一个驱动安装文件,安装后就可以连接上了.

Cisco ACI常见问题FAQ科普

这里有个思科的官方链接,不过里面很多是商务说辞,也就是吹牛,仅做为参考。 https://www.cisco.com/c/dam/global/en_sg/solutions/data-center-virtualization/application-centric-infrastructure/insieme_faq.pdf 下面是我自己的理解 0 …

Windows 安装Redis(图文详解)

Windows 安装Redis(图文详解) Redis是什么数据库? Remote Dictionary Server(Redis) 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语…

CleanMyMac X4.15.9破解版激活码许可证

CleanMyMac X:你的Mac电脑的“私人健身教练” ### 一键瘦身,轻松给Mac电脑“减减肥” 🏋️‍♂️ 大家有没有觉得,自己的Mac电脑用久了,就变得越来越“胖”,越来越慢呢?别怕,今天我要…

Qt获取磁盘信息+表格显示

效果展示 主要代码 获取磁盘相关数据 获取磁盘数据 Qt 没有提供相关的接口,需要使用 Windows API。接口解释如下: BOOL GetDiskFreeSpaceExW([in, optional] LPCWSTR lpDirectoryName,[out, optional] PULARGE_INTEGER lpFreeBytesAvailable…

chattts一步步的记录,先跑起来。

0.下载git工具 Git - Downloads (git-scm.com)https://git-scm.com/downloads Download – TortoiseGit – Windows Shell Interface to Githttps://tortoisegit.org/download/ 1.安装 随意,可以安汉化,也可不安。无所谓 2.建个目录,我的上…

Prometheus+Grafana 监控 K8S Ingress-Ningx Controller

文章目录 一、prometheus中添加ingress-nginx的服务发现配置二、ingress-nginx controller的service添加端口暴露监控指标三、grafana添加ingress-nginx controller的监控模版 ingress-nginx默认是没有开启监控指标的,需要我们在ingress-nginx controller的svc里面开…

K8S配置MySQL主从自动水平扩展

前提环境 操作系统Ubuntu 22.04 K8S 1.28.2集群(1个master2个node) MySQL 5.7.44部署在K8S的主从集群 metrics-server v0.6.4 概念简介 在K8s中扩缩容分为两种 ●Node层面:对K8s物理节点扩容和缩容,根据业务规模实现物理节点自动扩…

数字媒体技术基础:色度子采样(4:4:4、4:2:2 、4:2:0)

在数字视频处理中,色度子采样 Chroma Subsampling可以用于压缩视频文件的大小,同时在大多数情况下保持较高的视觉质量,它的原理基于人类视觉系统对亮度 Luminance比对色度 Chrominance更加敏感这一特点。 一、 采样格式的表示方法 色度子采样…

一个技巧实现在SharePoint中使用Copilot

前几天写了在onedrive中使用copilot对单个文件进行提问汇总分析与对多个文件进行比较汇总提问等: Copilot重磅更新!OneDrive全新功能炸裂 很多小伙伴表示特别受用。 于是他们在纷纷尝试了一段时间后,开始把目光转向SharePoint和teams文件&a…

tkinter库的应用小示例:文本编辑器

tkinter库的应用小示例:文本编辑器 要 求: 创建一个文本编辑器,功能包括,创建、打开、编辑、保存文件。一个Button小组件,命名为btn_open,用于打开要编辑的文件,一个Button小组件,命名为btn_s…

Dockerfile 详解

Dockerfile是自定义Docker镜像的一套规则,由多条指令构成,每条指令都会对应于Docker镜像中的每一层,因为Docker是分层存储的。以下是Dockerfile中各个参数的详解及演示解析: 1. FROM 功能:指定待扩展的父级镜像&#…

JavaScript 访问者模式:打造高扩展性的对象结构

一. 前言 在面向对象编程中,访问者模式(Visitor Pattern)是一种行为设计模式,它允许我们向现有的类结构添加新的操作,而无需修改这些类。这对于需要对类层次结构中的元素进行复杂算法处理的场景非常有用。 本文将详细…

【硬件模块】HC-08蓝牙模块

蓝牙模块型号 HC-08蓝牙模块实物图 HC-08蓝牙模块引脚介绍 STATE:状态输出引脚。未连接时,则为低电平。连接成功时,则为高电平。可以在程序中作指示引脚使用; RXD:串口接收引脚。接单片机的 TX 引脚(如…

多线程(三):线程等待获取线程引用线程休眠线程状态

目录 1、等待一个线程:join 1.1 join() 1.2 join(long millis)——"超时时间" 1.3 join(long millis,int nanos) 2、获取当前线程的引用:currentThread 3、休眠当前进程:sleep 3.1 实际休眠时间 3.2 sleep的特殊…

Canvas:AI协作的新维度

在人工智能的浪潮中,OpenAI的最新力作Canvas,不仅是一款新工具,它标志着人工智能协作方式的一次革命性飞跃。Canvas为写作和编程提供了一个全新的交互界面,让用户能够与ChatGPT进行更紧密、更直观的协作。 ​​​​​​​ Canvas的…

LeetCode 面试经典150题 Z字形变换

题目: 将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。 比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下: P A H N A P L S I I G Y I R 之后,你…

无人机无线电侦测核心技术详解

无人机无线电侦测核心技术主要涉及频谱分析、信号处理、定位技术以及智能化识别等多个方面。以下是对这些核心技术的详细解析: 1. 频谱分析技术 频谱探测技术:通过分析信号在频域上的分布和特性,来识别、测量和定位无线电信号。在无人机侦测…

leetcode 491.非递减子序列

1.题目要求: 给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。 …

Python | Leetcode Python题解之第477题汉明距离总和

题目: 题解: class Solution:def totalHammingDistance(self, nums: List[int]) -> int:n len(nums)ans 0for i in range(30):c sum(((val >> i) & 1) for val in nums)ans c * (n - c)return ans