OpenCV实例(六)行人检测

news2025/1/18 20:26:09

OpenCV实例(六)行人检测

  • 1.行人检测概述
  • 2.行人检测基础实现
    • 2.1基本流程
    • 2.2实现程序
    • 2.3参数优化
  • 3.完整行人检测程序

作者:Xiou

1.行人检测概述

行人检测是目标检测的一个分支。目标检测的任务是从图像中识别出预定义类型目标,并确定每个目标的位置。用来检测行人的目标检测系统被称为行人检测系统。

行人检测主要用来判断输入图片(或视频)内是否包含行人。若检测到行人,则给出其具体的位置信息。该位置信息是智能视频监控、人体行为分析、智能驾驶、智能机器人等应用的关键基础。由于行人可能处于移动状态,也可能处于静止状态,且外观容易受到体型、姿态、衣着、拍摄角度、遮挡等多种因素的影响,因此行人检测在计算机视觉领域内成为研究热点与难点。

一种比较常用的行人检测方式是统计学习方法,即根据大量样本构建行人检测分类器。提取的特征主要有目标的灰度、边缘、纹理、颜色、梯度等信息。分类器主要包括人工神经网络、SVM、Adaboost及卷积神经网络等。

OpenCV采用的行人检测算法是基于Dalal的论文实现的,我们可以直接调用行人检测器实现行人检测。

2.行人检测基础实现

2.1基本流程

在OpenCV中直接调用行人检测器即可完成行人检测,具体过程如下:

● 调用hog=cv2.HOGDescriptor(),初始化HOG描述符。
● 调用setVMDetector,将SVM设置为预训练的行人检测器。该检测器通过cv2.HOGDescriptor_getDefaultPeopleDetector()函数加载。

● 使用detectMultiScale函数检测图像中的行人,返回值为行人对应的矩形框和矩形框的权重值。在该函数中待检测图像是必选参数,除此之外,还有若干个很重要的可选参数,19.3节将对这些可选参数进行介绍。

2.2实现程序

代码实例:使用OpenCV自带的行人检测器实现行人检测。

import cv2
image = cv2.imread("back.jpg")            
hog = cv2.HOGDescriptor()   #初始化方向梯度直方图描述子
#设置SVM为一个预先训练好的行人检测器
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())  
#调用函数detectMultiScale,检测行人对应的边框
(rects, weights) = hog.detectMultiScale(image)
#遍历每一个矩形框,将之绘制在图像上
for (x, y, w, h) in rects:  
    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2)
cv2.imshow("image", image)     #显示检测结果
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果:

在这里插入图片描述

从本例的运行结果可以看出,当前识别效果还不错。但是,在面对复杂情况时,该程序的识别效果将差很多,还需要进一步的优化。

2.3参数优化

OpenCV为了提高自带的行人检测器的识别准确率提供了非常多的参数。函数detectMultiScale的语法格式如下:

在这里插入图片描述
其中:
● rects表示检测到的行人对应的矩形框。
● weights表示矩形框的权重值。
● image表示待检测行人的输入图像。
● winStride表示HOG检测窗口移动步长。
● padding表示边缘扩充的像素个数。
● scale表示构造金字塔结构图像时使用的缩放因子,默认值为1.05。
● useMeanshiftGrouping表示是否消除重叠的检测结果。

参数winStride

● WinStride值越小,覆盖的对象越多,能够找到的对象越多,但是运算效率会降低。● WinStride值越大,覆盖的对象越少,能够找到的对象越少,但是运算效率会提高,具有更好的实时性。通常,需要在实时性和提取精度之间取得平衡。一般,将WinStride设置为(4,4)会有比较好的效果。

代码实例:观察不同的winStride值的使用情况


import cv2
import time
def detect(image,winStride):
    imagex=image.copy()   #函数内部做个副本,让每个函数运行在不同的图像上        
    hog = cv2.HOGDescriptor()   #初始化方向梯度直方图描述子
    #设置SVM为一个预先训练好的行人检测器
    hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())  
    #调用函数detectMultiScale,检测行人对应的边框
    time_start = time.time()     #记录开始时间
    #获取(行人对应的矩形框、对应的权重)
    (rects, weights) = hog.detectMultiScale(imagex,winStride=winStride)    
    time_end = time.time()    #记录结束时间
    # 绘制每一个矩形框
    for (x, y, w, h) in rects:  
        cv2.rectangle(imagex, (x, y), (x + w, y + h), (0, 0, 255), 2)
    print("size:",winStride,",time:",time_end-time_start)
    name=str(winStride[0]) + "," + str(winStride[0])
    cv2.imshow(name, imagex)     #显示原始效果
    # cv2.imwrite( str(time.time())+".bmp" ,imagex)   #保存,书稿用的
image = cv2.imread("back.jpg") 
detect(image,(4,4))
detect(image,(12,12))
detect(image,(24,24))
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果:

在这里插入图片描述
从程序输出结果可以看出,当步长较小时,遍历的区域更多,花费的时间更长。

参数padding

代码实例:观察参数padding不同值的检测效果。

import cv2
import time
def detect(image,padding):
    imagex=image.copy()   #函数内部做个副本,让每个函数运行在不同的图像上        
    hog = cv2.HOGDescriptor()   #初始化方向梯度直方图描述子
    #设置SVM为一个预先训练好的行人检测器
    hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())  
    #调用函数detectMultiScale,检测行人对应的边框
    time_start = time.time()     #记录开始时间
    #获取(行人对应的矩形框、对应的权重)
    (rects, weights) = hog.detectMultiScale(imagex,
                        winStride=(16,16),padding=padding)    
    time_end = time.time()    #记录结束时间
    # 绘制每一个矩形框
    for (x, y, w, h) in rects:  
        cv2.rectangle(imagex, (x, y), (x + w, y + h), (0, 0, 255), 2)
    print("Padding size:",padding,",time:",time_end-time_start)
    name=str(padding[0]) + "," + str(padding[0])
    cv2.imshow(name, imagex)     #显示原始效果
image = cv2.imread("backPadding2.jpg") 
detect(image,(0,0))
detect(image,(8,8))
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果:

在这里插入图片描述
由程序输出结果可以看出,在扩边后可检测到靠近图像边缘的行人,但是运算量加大,耗时更长。

参数scale

参数scale是检测过程构造金字塔结构图像使用的比例值。

代码实例:观察不同scale参数值的检测效果


import cv2
import time
def detect(image,scale):
    imagex=image.copy()   #函数内部做个副本,让每个函数运行在不同的图像上        
    hog = cv2.HOGDescriptor()   #初始化方向梯度直方图描述子
    #设置SVM为一个预先训练好的行人检测器
    hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())  
    #调用函数detectMultiScale,检测行人对应的边框
    time_start = time.time()     #记录开始时间
    #获取(行人对应的矩形框、对应的权重)
    (rects, weights) = hog.detectMultiScale(imagex,scale=scale)    
    time_end = time.time()    #记录结束时间
    # 绘制每一个矩形框
    for (x, y, w, h) in rects:  
        cv2.rectangle(imagex, (x, y), (x + w, y + h), (0, 0, 255), 2)
    print("sacle size:",scale,",time:",time_end-time_start)
    name=str(scale) 
    cv2.imshow(name, imagex)     #显示原始效果
image = cv2.imread("back.jpg") 
detect(image,1.01)
detect(image,1.05)
detect(image,1.3)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果:

在这里插入图片描述

从程序输出结果可以看出,使用小的scale值能够更好地检测到图像内的行人目标,但是耗时较长;使用较大的scale值,速度较快,实时性好,但是可能会发生漏检。因此,需要在二者之间取得平衡。通常情况下,scale值的设置范围为[1.01,1.5]。

参数useMeanshiftGrouping
参数useMeanshiftGrouping用来控制是否消除重叠的检测结果。

代码实例:观察重叠边界处理结果

import cv2
import time
def detect(image,useMeanshiftGrouping):
    imagex=image.copy()   #函数内部做个副本,让每个函数运行在不同的图像上        
    hog = cv2.HOGDescriptor()   #初始化方向梯度直方图描述子
    #设置SVM为一个预先训练好的行人检测器
    hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())  
    #调用函数detectMultiScale,检测行人对应的边框
    time_start = time.time()     #记录开始时间
    #获取(行人对应的矩形框、对应的权重)
    (rects, weights) = hog.detectMultiScale(imagex,
                            scale=1.01,
                            useMeanshiftGrouping=useMeanshiftGrouping)    
    time_end = time.time()    #记录结束时间
    # 绘制每一个矩形框
    for (x, y, w, h) in rects:  
        cv2.rectangle(imagex, (x, y), (x + w, y + h), (0, 0, 255), 2)
    print("useMeanshiftGrouping:",useMeanshiftGrouping,",time:",time_end-time_start)
    name=str(useMeanshiftGrouping) 
    cv2.imshow(name, imagex)     #显示原始效果
image = cv2.imread("back.jpg") 
detect(image,False)
detect(image,True)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果:
在这里插入图片描述

3.完整行人检测程序

代码实例:

import cv2
def detect(image,winStride,padding,scale,useMeanshiftGrouping):   
    hog = cv2.HOGDescriptor()   #初始化方向梯度直方图描述子
    #设置SVM为一个预先训练好的行人检测器
    hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())  
    #获取(行人对应的矩形框、对应的权重)
    (rects, weights) = hog.detectMultiScale(image,
                            winStride = winStride,
                            padding = padding,
                            scale = scale,
                            useMeanshiftGrouping=useMeanshiftGrouping)    
    # 绘制每一个矩形框
    for (x, y, w, h) in rects:  
        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2)
    cv2.imshow("result", image)     #显示原始效果
image = cv2.imread("back.jpg") 
winStride = (8,8)
padding = (2,2)
scale = 1.03
useMeanshiftGrouping=True
detect(image,winStride,padding,scale,useMeanshiftGrouping)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果:

在这里插入图片描述

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

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

相关文章

【Python】json数据解析

目录 json文件数据解析 爬虫获取王者荣耀英雄信息json数据包并解析 爬虫获取抖音视频json数据包并解析 json文件数据解析 json字符串:通常类似python数据类型中的列表和字典的结合,也可能是单独的列表或者字典格式,通常可以通过json模块的…

亚马逊影响搜索排名的主要因素有哪些,使用测评做排名有哪些要求?

亚马逊产品的排名越高就意味着分配的流量越多而且带来更高的销量。那主要有哪些因素影响产品的排名呢? 1、产品销量 产品销量反映了该产品在同类产品中的销售情况,该数值会在产品Listing中展示,平台会每小时更新一次该排行榜。在平台算法看…

【Linux】线程控制分析:如何获取线程ID?线程如何自动回收?

Linux系统中, 线程是轻量级的进程. 我们已经介绍过了线程的相关概念, 见过了线程再Linux操作系统中的存在形式. 我们知道, 进程有自己相关控制接口, 等待、创建等 而线程作为轻量级的进程, 其实也是有控制接口的. 文章目录线程控制线程的创建与回收演示获取线程idpthread_sel…

用户管理系统-自动化测试

文章目录1. 思维导图编写 Web 自动化测试用例2. 创建测试项目3. 根据思维导图设计用户管理系统自动化测试用例3.1 准备工具类3.2 测试登录页面3.3 测试用户列表页3.4 测试添加用户页3.5 测试修改用户页3.6 未登录状态4. 自动化测试项目总结4.1 自动化测试项目实现步骤4.2 当前项…

图数据库驱动的基础设施运维实操

本文系图技术在大型、复杂基础设施之中 SRE/DevOps 的实践参考,并以 OpenStack 系统之上的图数据库增强的运维案例为例,揭示图数据库、图算法在智能运维上的应用。本文所有示例代码开源。 最近,有些尚未使用过图技术、DevOps/Infra 领域的工程…

除了Java,还可以培训学习哪些IT技术?

除了Java,还可以培训学习哪些IT技术?转行IT学Java似乎已经成为很多人的首选,原因无非是开发技术含量高、开发有前景、开发是一个互联网企业的核心岗位,最重要的是开发薪资待遇高。但其实只单纯因为薪资选择Java的话,小…

Flask数据迁移详细步骤

数据迁移详细步骤: 1. 安装好数据迁移的包 flask-sqlalchemy和flask-migrate Flask模型相关包安装 2. 在exts.py中初始化Migrate和SQLAlchemy 3. 在models中定义好模型 4. 在views.py中一定要导入models模块 from .models import * 5. 配置好数据库(sql…

MYSQL笔记01 数据库概述,SELECT语句,运算符,排序与分页,多表查询

数据库概述 为什么要使用数据库 持久化:把数据保存在可掉电式存储设备中以供之后使用。大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存到硬盘上加以"固化",而持久化的实现过程大多通过各种关系数据…

详解 23 种设计模式(多图 + 代码)

创建型模式 创建型模式的作用就是创建对象,说到创建一个对象,最熟悉的就是 new 一个对象,然后 set 相关属性。但是,在很多场景下,我们需要给客户端提供更加友好的创建对象的方式,尤其是那种我们定义了类&a…

每68个孩子里,就有一个自闭症,“来自星星的孩子”,离我们很近

今年4月2日是世界上第14个“世界自闭症日”。自闭症儿童,又称“星星儿童”,形容他们像遥远的星星一样独自在夜空中闪耀。自闭症并不少见根据世卫组织的调查,世界上每160名儿童中就有一人患有自闭症。根据《中国自闭症(自闭症&…

【从零开始学Skynet】基础篇(四):网络模块常用API

游戏服务端要处理客户端请求,作为服务端引擎,网络编程也是Skynet的核心功能。1、学习网络模块 skynet.socket模块提供了网络编程的API,常用的API如下表所示:Lua API说明socket.listen(address ,port)监听一个端口,返回…

你需要知道的企业网页制作流程

企业网页制作是企业建立线上形象和宣传的重要手段之一,它不仅可以提高企业的品牌知名度,还可以扩大企业的影响力和拓展客户群。下面,我们将介绍一些企业网页制作的基本流程和技巧,并结合一个案例来详细解析。 企业网页制作的基本…

【DT】蒸脱机的结构和工作原理

DT蒸脱机的结构和工作原理什么是DTDT结构图工作过程什么是DT DT 蒸脱机(DesolventazationerToaster),根据英文名可以看出来,他的作用是脱溶、烘烤。用于蒸脱湿豆粕中的溶剂。 大豆油生产工艺有2种:压榨油的加工工艺是…

C++标准库--IO库(Primer C++ 第五版 · 阅读笔记)

C标准库--IO库(Primer C 第五版 阅读笔记)第8章 IO库8.1、IO类8.2、文件输入输出8.3、string流总结:第8章 IO库 8.1、IO类 为了支持这些不同种类的IO处理操作,在istream和ostream之外,标准库还定义了其他一些IO类型。 如下图分…

Java中的注解,自定义注解

文章目录1. 注解概述2. 注解与注释3. 注解的重要性4. 常见的Annotation作用4.1 生成文档相关的注解4.2 在编译时进行格式检查(JDK内置的三个基本注解)5. 元注解6. 自定义注解6.1 定义自定义注解6.2 使用自定义注解6.3 读取和处理自定义注解框架 注解 反射 设计模式 1. 注解概…

PC安装虚拟化平台趟坑记录

合肥先进光源永磁多极铁电机控制系统的规划 Zstack EPICS Archiver在小课题组的使用经验 神仙同学的永磁四极铁样铁已经开始加工了,过一个月左右就要回来了,电机控制部分交给留国做,调试的也差不多了。项目买过一台工控机,到时候…

STM32F407ZGT6实现OLED显示屏

1、调试工具 2、OLED简介 3、硬件电路(接线) 本文采用7脚,倘若采用4脚,资料代码啥的可以在江科大B站视频下载: 资料下载:https://pan.baidu.com/s/1SqKyKr5Fsl_9gBJi8aVxTw, 提取码:8kzh&#x…

日本首相会见奥特曼,考虑引入 ChatGPT 技术

文|小戏卖萌屋日本4月12日电,日本国第101任首相,日本自民党总裁岸田文雄4月10日于东京会见了奥特曼先生,二人就 ChatGPT 引入日本的可能性问题交换了意见并进行了深入的讨论。奥特曼先生表示,希望为日本人创造伟大的东…

NumPy 秘籍中文第二版:三、掌握常用函数

原文:NumPy Cookbook - Second Edition 协议:CC BY-NC-SA 4.0 译者:飞龙 在本章中,我们将介绍许多常用函数: sqrt(),log(),arange(),astype()和sum()ceil(),modf()&…

如何突破LinkedIn领英限制,导出非好友邮箱等社交方式

相信做外贸的朋友都有使用过Linkedin,如果还没有使用过的话,我只能说您错过一个很好的平台。只要是厉害的外贸人都特别擅长用Linkedin找客户。 那为什么说Linkedin是外贸业务员开发客户最有效的途径呢?主要基于以下几点: 第一&a…