小车AI视觉识别--9.目标检测

一、目标检测概述

        本节主要解决的问题是如何使用OpenCV中的dnn模块,用来导入一个实现训练好的目标检测网络。但是对opencv的版本是有要求的。目前用深度学习进行目标检测,主要有三种方法:

  • Faster R-CNNs
  • You Only Look Once(YOLO)
  • Single Shot Detectors(SSDs)

        Faster R-CNNs是最常听说的基于深度学习的神经网络了。然而,这种方法在技术上是很难懂的(尤其是对于深度学习新手),也难以实现,训练起来也是很困难。此外,即使是使用了“Faster”的方法实现R-CNNs(这里R表示候选区域Region Proposal),算法依然是比较慢的,大约是7FPS。如果我们追求速度,我们可以转向YOLO,因为它非常的快,在TianXGPU上可以达到40-90 FPS,最快的版本可能达到155 FPS。但YOLO的问题在于它的精度还有待提高。SSDs最初是由谷歌开发的,可以说是以上两者之间的平衡。相对于Faster R-CNNs,它的算法更加直接。相对于YOLO,又更加准确。

二、模型结构

        MobileNet的主要工作是用depthwise sparable convolutions(深度级可分离卷积)替代过去的standard convolutions(标准卷积)来解决卷积网络的计算效率和参数量的问题。MobileNets模型基于是depthwise sparable convolutions(深度级可分离卷积),它可以将标准卷积分解成一个深度卷积和一个点卷积(1 × 1卷积核)。深度卷积将每个卷积核应用到每一个通道,而1 × 1卷积用来组合通道卷积的输出。

        在MobileNet的基本组件中会加入Batch Normalization(BN),即在每次SGD(随机梯度下降)时,标准化处理,使得结果(输出信号各个维度)的均值为0,方差为1。一般在神经网络训练时遇到收敛速度很慢,或梯度爆炸等无法训练的状况时可以尝试BN来解决。另外,在一般使用情况下也可以加入BN来加快训练速度,提高模型精度。

        除此之外,模型还使用ReLU激活函数,所以depthwise separable convolution的基本结构如下图所示:

网络解析(二):MobileNets详解

        而MobileNets网络是由很多上图所示的depthwise separable convolution组合而成的。其具体的网络结构如下图所示:

网络解析(二):MobileNets详解

三、实验源码

#!/usr/bin/env python3
# -*-coding: utf-8 -*-
"""
    @Project: python-learning-notes
    @File   : openpose_for_image_test.py
    @Author : panjq
    @E-mail : pan_jinquan@163.com
    @Date   : 2019-07-29 21:50:17
"""
import time
import cv2 as cv
import numpy as np
######################### Detection ##########################
# load the COCO class names
with open('object_detection_coco.txt', 'r') as f: class_names = f.read().split('\n')
# get a different color array for each of the classes
COLORS = np.random.uniform(0, 255, size=(len(class_names), 3))
# load the DNN modelimage
model = cv.dnn.readNet(model='frozen_inference_graph.pb', config='ssd_mobilenet_v2_coco.txt', framework='TensorFlow')

######################### openpose ##########################
BODY_PARTS = {"Nose": 0, "Neck": 1, "RShoulder": 2, "RElbow": 3, "RWrist": 4,
          "LShoulder": 5, "LElbow": 6, "LWrist": 7, "RHip": 8, "RKnee": 9,
          "RAnkle": 10, "LHip": 11, "LKnee": 12, "LAnkle": 13, "REye": 14,
          "LEye": 15, "REar": 16, "LEar": 17, "Background": 18}
POSE_PAIRS = [["Neck", "RShoulder"], ["Neck", "LShoulder"], ["RShoulder", "RElbow"],
          ["RElbow", "RWrist"], ["LShoulder", "LElbow"], ["LElbow", "LWrist"],
          ["Neck", "RHip"], ["RHip", "RKnee"], ["RKnee", "RAnkle"], ["Neck", "LHip"],
          ["LHip", "LKnee"], ["LKnee", "LAnkle"], ["Neck", "Nose"], ["Nose", "REye"],
          ["REye", "REar"], ["Nose", "LEye"], ["LEye", "LEar"]]
net = cv.dnn.readNetFromTensorflow("graph_opt.pb")

def Target_Detection(image):
    image_height, image_width, _ = image.shape
    # create blob from image
    blob = cv.dnn.blobFromImage(image=image, size=(300, 300), mean=(104, 117, 123), swapRB=True)
    model.setInput(blob)
    output = model.forward()
    # loop over each of the detections
    for detection in output[0, 0, :, :]:
        # extract the confidence of the detection
        confidence = detection[2]
        # draw bounding boxes only if the detection confidence is above...
        # ... a certain threshold, else skip
        if confidence > .4:
            # get the class id
            class_id = detection[1]
            # map the class id to the class
            class_name = class_names[int(class_id) - 1]
            color = COLORS[int(class_id)]
            # get the bounding box coordinates
            box_x = detection[3] * image_width
            box_y = detection[4] * image_height
            # get the bounding box width and height
            box_width = detection[5] * image_width
            box_height = detection[6] * image_height
            # draw a rectangle around each detected object
            cv.rectangle(image, (int(box_x), int(box_y)), (int(box_width), int(box_height)), color, thickness=2)
            # put the class name text on the detected object
            cv.putText(image, class_name, (int(box_x), int(box_y - 5)), cv.FONT_HERSHEY_SIMPLEX, 1, color, 2)
    return image


def openpose(frame):
    frameHeight, frameWidth = frame.shape[:2]
    net.setInput(cv.dnn.blobFromImage(frame, 1.0, (368, 368), (127.5, 127.5, 127.5), swapRB=True, crop=False))
    out = net.forward()
    out = out[:, :19, :, :]  # MobileNet output [1, 57, -1, -1], we only need the first 19 elements
    assert (len(BODY_PARTS) == out.shape[1])
    points = []
    for i in range(len(BODY_PARTS)):
        # Slice heatmap of corresponging body's part.
        heatMap = out[0, i, :, :]
        # Originally, we try to find all the local maximums. To simplify a sample
        # we just find a global one. However only a single pose at the same time
        # could be detected this way.
        _, conf, _, point = cv.minMaxLoc(heatMap)
        x = (frameWidth * point[0]) / out.shape[3]
        y = (frameHeight * point[1]) / out.shape[2]
        # Add a point if it's confidence is higher than threshold.
        points.append((int(x), int(y)) if conf > 0.2 else None)
    for pair in POSE_PAIRS:
        partFrom = pair[0]
        partTo = pair[1]
        assert (partFrom in BODY_PARTS)
        assert (partTo in BODY_PARTS)
        idFrom = BODY_PARTS[partFrom]
        idTo = BODY_PARTS[partTo]
        if points[idFrom] and points[idTo]:
            cv.line(frame, points[idFrom], points[idTo], (0, 255, 0), 3)
            cv.ellipse(frame, points[idFrom], (3, 3), 0, 0, 360, (0, 0, 255), cv.FILLED)
            cv.ellipse(frame, points[idTo], (3, 3), 0, 0, 360, (0, 0, 255), cv.FILLED)
    return frame


if __name__ == '__main__':
    capture = cv.VideoCapture(0)
    cv_edition = cv.__version__
    if cv_edition[0] == '3': capture.set(cv.CAP_PROP_FOURCC, cv.VideoWriter_fourcc(*'XVID'))
    else: capture.set(cv.CAP_PROP_FOURCC, cv.VideoWriter.fourcc('M', 'J', 'P', 'G'))
    capture.set(cv.CAP_PROP_FRAME_WIDTH, 640)
    capture.set(cv.CAP_PROP_FRAME_HEIGHT, 480)
    state=True
    while capture.isOpened():
        start = time.time()
        ret, frame = capture.read()
        action = cv.waitKey(10) & 0xFF
        if state==True: 
            frame = Target_Detection(frame)
            cv.putText(frame, "Detection", (240, 30), cv.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 1)
        else: 
            frame = openpose(frame)
            cv.putText(frame, "Openpose", (240, 30), cv.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 1)
        if action == ord('q') or action == ord('Q'): break
        if action == ord('f') or action == ord('F'): state = not state
        end = time.time()
        fps = 1 / (end - start)
        text = "FPS : " + str(int(fps))
        cv.putText(frame, text, (20, 30), cv.FONT_HERSHEY_SIMPLEX, 0.9, (100, 200, 200), 1)
        cv.imshow('frame', frame)
        
    capture.release()
    cv.destroyAllWindows()

四、源码解析 

可识别的物体列表

[person, bicycle, car, motorcycle, airplane, bus, train, truck, boat, traffic light, fire hydrant, street sign, stop sign, parking meter, bench, bird, cat, dog, horse, sheep, cow, elephant, bear, zebra, giraffe, hat, backpack, umbrella, shoe, eye glasses, handbag, tie, suitcase, frisbee, skis, snowboard, sports ball, kite, baseball bat, baseball glove, skateboard, surfboard, tennis racket, bottle, plate, wine glass, cup, fork, knife, spoon, bowl, banana, apple, sandwich, orange, broccoli, carrot, hot dog, pizza, donut, cake, chair, couch, potted plant, bed, mirror, dining table, window, desk, toilet, door, tv, laptop, mouse, remote, keyboard, cell phone, microwave, oven, toaster, sink, refrigerator, blender, book, clock, vase, scissors, teddy bear, hair drier, toothbrush]

加载类别【object_detection_coco.txt】,导入模型【frozen_inference_graph.pb】,指定深度学习框架【TensorFlow】。

# 加载COCO类名称
with open('object_detection_coco.txt', 'r') as f: class_names = f.read().split('\n')
# 对于不同目标显示不同颜色
COLORS = np.random.uniform(0, 255, size=(len(class_names), 3))
# 加载DNN图像模型
model = cv.dnn.readNet(model='frozen_inference_graph.pb', config='ssd_mobilenet_v2_coco.txt', framework='TensorFlow')

导入图片,提取了高度和宽度,计算了300x300的像素blob,把这个blob传入神经网络.

def Target_Detection(image):
    image_height, image_width, _ = image.shape
    # 从图像中创建blob
    blob = cv.dnn.blobFromImage(image=image, size=(300, 300), mean=(104, 117, 123), swapRB=True)
    model.setInput(blob)
    output = model.forward()
    # 遍历每个检测
    for detection in output[0, 0, :, :]:
        # 提取检测的置信度
        confidence = detection[2]
        # 仅在检测置信度高于某个阈值时,绘制边界框,否则跳过
        if confidence > .4:
            # 获取类的ID
            class_id = detection[1] 
            # 将类的id 映射到类
            class_name = class_names[int(class_id) - 1]
            color = COLORS[int(class_id)]
            # 获取边界框坐标
            box_x = detection[3] * image_width
            box_y = detection[4] * image_height
            # 获取边界框的宽度和高度
            box_width = detection[5] * image_width
            box_height = detection[6] * image_height
            # 在每个检测到的对象周围绘制一个矩形
            cv.rectangle(image, (int(box_x), int(box_y)), (int(box_width), int(box_height)), color, thickness=2)
            # 将类名文本写在检测到的对象上
            cv.putText(image, class_name, (int(box_x), int(box_y - 5)), cv.FONT_HERSHEY_SIMPLEX, 1, color, 2)
    return image

五、启动

注意: 以下面命令需要vnc登录小车运行。

cd /home/pi/project_demo/07.AI_Visual_Recognition/detection

python target_detection_USB.py

点击图像框后,使用键盘【f】键切换人体姿态估计。

if action == ord('f') or action == ord('F'):state = not state  # 功能切换

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2023年9月GESPC++一级真题解析

一、单选题(每题2分,共30分) 题号 123456789101112131415 答案 CDBCDBACACBBDDA 1. 我们通常说的 “ 内存 ” 属于计算机中的()。 A. 输出设备 B. 输 ⼊ 设备 C. 存储设备 D. 打印设备 【答案】 C 【考纲知识点】…

VS2022进行Libigl库编译

目录 一 编译OK 二 编译难点 2.1 cmake问题 2.2 文件编码问题 三 调用链接 一 编译OK 二 编译难点 2.1 cmake问题 vs2022直接多次cmake生成即可。 2.2 文件编码问题 格式保存为GB2312. 三 调用链接 https://github.com/libigl/libigl-example-project

Vue3 el-table 默认选中 传入的数组

一、效果&#xff1a; 二、官网是VUE2 现更改为Vue3写法 <template><el-table:data"tableData"border striperow-key"id"ref"tableRef":cell-style"{ text-align: center }":header-cell-style"{background: #b7babd…

晶圆测试中自动化上下料的重要性与应用

随着科技的飞速发展&#xff0c;硅光技术在通信、数据处理等领域展现出巨大的应用潜力。硅光晶圆作为硅光技术的核心源头组件&#xff0c;其性能的稳定性和可靠性对于整个系统的运行至关重要。因此&#xff0c;对硅光晶圆的测试成为生产过程中不可或缺的一环。近年来&#xff0…

udp_socket

文章目录 UDP服务器封装系统调用socketbind系统调用bzero结构体清0sin_family端口号ip地址inet_addrrecvfromsendto 新指令 netstat -naup (-nlup)包装器 的两种类型重命名方式包装器使用统一可调用类型 关键字 typedef 类型重命名系统调用popen关于inet_ntoa UDP服务器封装 系…

Perfetto学习大全

Perfetto 是一个功能强大的性能分析和追踪工具&#xff0c;主要用于捕获和分析复杂系统中的事件和性能数据&#xff0c;特别是在 Android 和 Linux 环境下。它的核心目标是帮助开发者深入了解系统和应用程序的运行状态&#xff0c;以便优化性能和诊断问题。 Perfetto的主要作用…

IDEA2023 SpringBoot整合MyBatis(三)

一、数据库表 CREATE TABLE students (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(100) NOT NULL,age INT,gender ENUM(Male, Female, Other),email VARCHAR(100) UNIQUE,phone_number VARCHAR(20),address VARCHAR(255),date_of_birth DATE,enrollment_date DATE,cours…

教学内容全覆盖:航拍杂草检测与分类

1.背景意义 研究背景与意义 随着全球农业生产的不断发展&#xff0c;杂草的管理与控制成为了提升作物产量和质量的重要环节。杂草不仅会与作物争夺水分、养分和光照&#xff0c;还可能成为病虫害的滋生地&#xff0c;从而对农业生产造成严重影响。因此&#xff0c;准确、快速…

【倍数问题——同余系】

题目 代码 #include <bits/stdc.h> using namespace std; const int N 1e5 10, M 1e3 10; int maxx[M][4]; void consider(int r, int x) {if(x > maxx[r][1]){maxx[r][3] maxx[r][2];maxx[r][2] maxx[r][1];maxx[r][1] x;}else if(x > maxx[r][2]){maxx[…

『VUE』33. 组件保持存活,切换组件时的生命周期(详细图文注释)

目录 动态切换组件导致的问题引入keeplive标签总结 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 动态切换组件导致的问题 动态切换组件使得每次组件都会被卸载然后重新初始化,导致数据每次都初始化,无法保存前一个组件的数据. …

【C++】从C到C++

C和C一些语法区别 1.三目运算符&#xff1a;在C语言中返回的是一个常量&#xff0c;是不能被赋值的&#xff1b;而C中返回的是变量&#xff0c;可以被赋值 2.C中的函数必须要写返回值类型 3.在全局下&#xff0c;C不允许int a;和int a10;等这种重定义二义性操作 4.在C中不要…

Redisson学习教程(B站诸葛)

弱智级别 package org.example.controller;public class IndexController {Autowiredprivate Redisson redisson;Autowiredprivate StringRedisTemplate stringRedisTemplate;RequestMapping("/deduct_storck")public String deductStock() {String lockKey "…

2024信创数据库TOP30之蚂蚁集团OceanBase

数据库作为存储、管理和分析这些数据的关键工具&#xff0c;其地位自然不言而喻。随着信息技术的日新月异&#xff0c;数据库技术也在不断演进&#xff0c;以满足日益复杂多变的市场需求。近日&#xff0c;备受瞩目的“2024信创数据库TOP30”榜单由DBC联合CIW/CIS权威发布&…

基于Java后台实现百度、高德和WGS84坐标的转换实战

目录 前言 一、需求的缘由 1、百度坐标拾取 2、高德坐标拾取 3、不同地图的坐标展示 二、后端坐标偏移转换处理 1、相关类库介绍 2、coordtransorm类图介绍 3、后台实际转换 三、总结 前言 在当今数字化时代&#xff0c;地理位置信息的精确性和实时性对于各种应用至…

Wireshark抓取HTTPS流量技巧

一、工具准备 首先安装wireshark工具&#xff0c;官方链接&#xff1a;Wireshark Go Deep 二、环境变量配置 TLS 加密的核心是会话密钥。这些密钥由客户端和服务器协商生成&#xff0c;用于对通信流量进行对称加密。如果能通过 SSL/TLS 日志文件&#xff08;例如包含密钥的…

网络安全,文明上网(6)网安相关法律

列举 1. 《中华人民共和国网络安全法》&#xff1a; - 这是中国网络安全的基本法律&#xff0c;于2017年6月1日开始实施。该法律明确了网络运营者的安全保护义务&#xff0c;包括采取数据分类、重要数据备份和加密等措施。 2. 《中华人民共和国数据安全法》&#xff1a; …

111 - Lecture 10

File I/O and GUI with JavaFX 文件输入/输出与JavaFX图形用户界面 一、Overview 1. File I/O &#xff08;1&#xff09; learning Java File I/O mechanism &#xff08;2&#xff09; writing into and reading from a file 使用文件I/O进行数据读取和…

【架构】主流企业架构Zachman、ToGAF、FEA、DoDAF介绍

文章目录 前言一、Zachman架构二、ToGAF架构三、FEA架构四、DoDAF 前言 企业架构&#xff08;Enterprise Architecture&#xff0c;EA&#xff09;是指企业在信息技术和业务流程方面的整体设计和规划。 最近接触到“企业架构”这个概念&#xff0c;转念一想必定和我们软件架构…

vue3:使用插件递归组件

vue3:使用插件递归组件 首先安装插件 npm i unplugin-vue-define-optionsvite.config.ts 配置插件 // vite.config.ts// 引入 unplugin-vue-define-options import DefineOptions from "unplugin-vue-define-options"; export default defineConfig({// 注册插件 De…

开源远程桌面工具:RustDesk

在远程办公和远程学习日益普及的今天&#xff0c;我们经常需要远程访问办公电脑或帮助他人解决电脑问题。 市面上的远程控制软件要么收费昂贵&#xff0c;要么需要复杂的配置&#xff0c;更让人担心的是数据安全问题。 最近我发现了一款名为 RustDesk 的开源远程桌面工具&…