【CV with Pytorch】第 9 章 :视频分析

机器学习之旅从很久以前的结构化数据开始,一直到提取有意义的预测的过程。随着数据的增长,机器学习也开始探索其他数据类型。今天,可以处理的数据类型没有限制。

从结构化数据开始,我们开始分析文本数据。我们开始理解文本并使用文本中的特征进行预测。然后我们也跳到图像。尽管这个过程有时具有挑战性,但由于 GPU 和 TPU 处理能力的进步,事情开始顺利进行。

然后是音频处理。这涉及使用频率处理音频或将音频转换为文本,然后进行预测。

所有这些概念的组合称为视频分析。

那里可用的视频数据量是巨大的。世界每一秒都在创造视频内容。娱乐和体育行业依靠视频运行,安全摄像头正在捕捉每一个动作。如图9-1所示,仅 YouTube 就有超过 20 亿用户。想一想从视频中生成的数据量。随着我们看到更多的数据,就会出现更多的问题,而人工智能将被用来解决这些问题。

图 9-1 YouTube

视频内容分析或视频内容分析,也称为视频分析或视频分析,是自动分析视频以检测和确定时间和空间事件的能力。

问题陈述

在我们考虑问题陈述之前,让我们列出一些可能的视频分析数据源。

  • YouTube

  • 社交媒体

  • 运动的

  • 娱乐产业

  • 监控摄像头

  • 教学平台

  • 手机录音

此时对视频处理的需求至关重要。由于数据量大,手动审核由各种来源(如监控摄像头和其他录音)创建的视频片段是不可能的。

每个行业都有可以使用视频解决的问题。让我们在这里讨论一些用途。

  • 计算购物中心、零售店等处的人数。

  • 视频中的个人人口统计信息识别,例如年龄和性别

  • 货架补货警报的库存计划

  • 使用运动检测的商店安全和监视

  • 停车场用例

  • 人脸识别

  • 行为检测

  • 人物追踪

  • 人群检测

  • 人数/人数

  • 时间管理

  • 区域管理和分析/边界检测

  • 交通控制系统

  • 安全/监控

  • 运动检测

  • 队列管理

  • 上门监控

  • 流量监控

  • 车辆计数

  • 运动分析,如图9-2

图 9-2 运动视频分析

我们从这个列表中挑选了一些用例并将实施它们。我们将使用 PyTorch 实现以下用例。

  • 计算零售店的顾客数量

  • 识别零售店中的热点

  • 使用运动检测管理安全和监视

  • 确定人口统计数据(年龄和性别)

方法

我们将使用视频作为我们算法的输入。该视频基本上有两个组成部分:

  • 视觉效果或系列图像

  • 声音的

我们需要从视频中提取这些子组件来处理它并解决用例。我们只对这个项目的第一个组件感兴趣。一旦我们根据用例提取了一系列图像,我们就可以使用算法或预训练模型。图9-3显示了视频分析的解决方法。

图 9-3 解决办法

最后一部分是图像处理,可以包括与视频分析相关的各种任务。

  • 图像分类:对从视频中提取的图像进行分类。例如,识别视频中人物的性别。

  • 对象检测:检测图像中的对象。例如,检测停车场中的汽车。

  • 对象跟踪:一旦检测到对象,识别对象的移动。

  • 分割:生成边界框以识别图像中的各种对象。

执行

让我们看看如何实现这些用例中的每一个。我们需要先安装克隆库。我们正在使用基于 SFNet 架构的预训练模型。它具有基于编码器-解码器的卷积神经网络和具有注意力的双路径多尺度融合网络。图9-4显示了样本人群和热图。

图 9-4 人群和热图

我们也在使用FaceLib 库对于人脸检测,我们可以尝试预测年龄和性别。对于图像处理和任何其他操作,让我们使用 OpenCV。

# 安装需要的包
!pip install git+https://github.com/sajjjadayobi/FaceLib.git
!git clone https://github.com/Pongpisit-Thanasutives/Variations-of-SFANet-for-Crowd-Counting #only model
# 导入包
import cv2
from PIL import Image
import pandas as pd
import numpy as np
%pylab inline
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import glob
#import torch
import torch
from torchvision import transforms
#import model
import os
os.chdir('/content/Variations-of-SFANet-for-Crowd-Counting')
from models import M_SFANet_UCF_QNRF
#import facelib
from facelib import FaceDetector, AgeGenderEstimator

数据

我们使用了 YouTube 上的几个视频。下载这些视频并将它们保存在本地。

  1. 这是来自一家零售店的视频链接。

https://www.youtube.com/watch?v=KMJS66jBtVQ

  1. 这是停车场的视频链接。

https://www.youtube.com/watch?v=eE2ME4BtXrk

下载这些视频,然后我们将它们上传到 Google Colab 以进行进一步分析。

将所需视频上传到 Google Colab

下一步,我们需要将视频上传到Google Colab.

# 上传视频
from google.colab import files
# 上传
files.upload()
files.upload()

我们还需要上传一个模型权重文件,后面会用到。从以下链接下载:https://drive.google.com/file/d/1oaXIBVg-dgyqRvEXsYDiJh5GNzP35vO-/view

将此模型的权重文件上传到Colab:

print('Upload model weights')
files.upload()

将视频转换为一系列图像

如前所述,视频分析就是从视频中生成帧。其余步骤与图像处理时相同。

让我们构建一个在输入视频时生成图像的函数。

# 生成图像的函数
def video_to_image(path, folder):
    global exp_fld
    # 导入视频
    vidcap=cv2.VideoCapture(path)
    exp_fld=folder
    # 错误处理
    try:
        if not os.path.exists(exp_fld):
            os.makedirs(exp_fld)
    except OSError:
        print ('Error: Creating directory of data')
    Count = 0
    sec = 0
    frameRate = 1 # secs of the video
    while(True):
        vidcap.set(cv2.CAP_PROP_POS_MSEC,sec*1000)
        hasFrames,image = vidcap.read()
        sec = sec + frameRate
        sec = round(sec, 2)
        # 导出图像
        if hasFrames:
            name='./' + exp_fld +'/frame'+str(Count) + '.jpg'
            cv2.imwrite(name, image)     # 将帧保存为 JPG 文件
            Count +=1
        else:
            break
    return print("Image Exported")

图像提取

现在,让我们使用之前创建的函数为视频生成帧。让我们为两个视频都这样做。

# 设置路径
os.chdir('/content')
# 提取图像并存储第一个视频
video_to_image('HD CCTV Camera video 3MP 4MP iProx CCTV HDCCTVCameras.net retail store.mp4', 'crowd')
# 为停车场视频提取图像
video_to_image('AI Security Camera with IR Night Vision (Bullet IP Camera).mp4', 'movement')

Image Exported

Image Exported

数据准备

现在,让我们运行一些快速的数据准备步骤。与结构化数据相比,在进行图像处理时准备和清理数据更容易。这里的关键步骤是调整图像的大小。原始图像可以是任何大小或像素。但是模型总是在一定的尺寸上进行训练。所以我们需要调整输入图像的大小以匹配模型。

这是调整图像大小的函数。

# 调整图像大小
def img_re_sizing(dnst_mp, image):
    # 规范化
    dnst_mp = 255*dnst_mp/np.max(dnst_mp)
    dnst_mp= dnst_mp[0][0]
    image= image[0]
    # 空图像
    result_img = np.zeros((dnst_mp.shape[0]*2, dnst_mp.shape[1]*2))
    # 迭代每张图片
    for i in range(result_img.shape[0]):
        for j in range(result_img.shape[1]):
            result_img[i][j] = dnst_mp[int(i / 2)][int(j / 2)] / 4
    result_img  = result_img.astype(np.uint8, copy=False)
    #output
    return result_img

现在我们已经完成了视频摄取、图像提取和大小调整,让我们来解决用例。

让我们从计算客户数量和生成热图开始。我们需要统计这个零售店的顾客数量(见图9-5)。

图 9-5 零售店_

商店的收入取决于有多少人光顾。显而易见,人群越多,购买的可能性就越大。这就是商店想要了解有多少人光顾,以便预测销售额的原因。许多决定都是根据这些信息做出的,比如商店的规模、如何计划库存等。

识别零售店中的热点

在商店中放置库存非常重要,这样可以最大限度地提高购买量。我们可以利用商店内的热点来做出决定。我们还可以使用此信息识别趋势产品。我们可以使用热图概念来获取此类信息。它会生成客户花费大部分时间的地点,这有助于确定该地点对产品的需求。图9-6显示了示例热图。

图 9-6 热图

让我们编写一些函数来生成热图并统计人数。以下函数将拍摄图像并生成热图。

# 获取热图的函数
def generate_dstys_map(o, dsty, cc, image_location):
    # 定义fgr_imure
    fgr_im=plt.fgr_imure()
    # 定义 size
    col = 2
    rws = 1
    X = o
    #sum
    add = int(np.sum(dsty))
    dsty = image_re_sizing(dsty, o)
    # 添加原始图像和新生成的热图图像
    for i in range(1, col*rws +1):
        # 生成原始图像
        if i == 1:
            image = X
            fgr_im.add_subplot(rws, col, i)
            # 设置轴
            plt.gca().set_axis_off()
            plt.margins(0,0)
                # 定位器
            plt.gca().xaxis.set_major_locator(plt.NullLocator())
            plt.gca().yaxis.set_major_locator(plt.NullLocator())
                # 调整子图
            plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, hspace = 0, wspace = 0)
                # 显示图像
            plt.imshow(image)
        # 生成 dstys 图像
        if i == 2:
            image = dsty
            fgr_im.add_subplot(rws, col, i)
                # 设置轴
            plt.gca().set_axis_off()
            plt.margins(0,0)
                # 定位器
            plt.gca().xaxis.set_major_locator(plt.NullLocator())
            plt.gca().yaxis.set_major_locator(plt.NullLocator())
                # 调整子图
            plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, hspace = 0, wspace = 0)
                # 添加计数
            plt.text(1, 80, 'M-SegNet* Est: '+str(add)+', Gt:'+str(cc), fontsize=7, weight="bold", color = 'w')
                # 显示图像
            plt.imshow(image)#, cmap=CM.jet)
    #image_nm with location
    image_nm = image_location.split('/')[-1]
    image_nm = image_nm.replace('.jpg', '_heatpmap.png')
    #saving the image
    plt.savefgr_im(image_location.split(image_nm)[0]+'seg_'+image_nm, transparent=True, bbox_inches='tight', pad_inches=0.0, dpi=200)

以下函数将图像作为输入并计算人数。它还会触发我们刚才创建的热图功能。最后,它输出人数、图像密度和密度图。

# 统计人数
def get_count_people(image):
    # 简单的预处理。
    trans = transforms.Compose([transforms.ToTensor(),
                                transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
                               ])
    # 具有高度和宽度的样本图像
    img = Image.open(image).convert('RGB')
    height, width = img.size[1], img.size[0]
    height = round(height / 16) * 16
    width = round(width / 16) * 16
    # 重新调整图像大小
    img_den = cv2.resize(np.array(img), (width,height), cv2.INTER_CUBIC)
    # 转换
    img = trans(Image.fromarray(img_den))[None, :]
    # 让我们定义模型
    model = M_SFANet_UCF_QNRF.Model()
    # 加载模型
    model.load_state_dict(torch.load('/content/best_M-SFANet__UCF_QNRF.pth',
 map_location = torch.device('cpu')))
    #评估模型
    model.eval()
    dnst_mp = model(img)
    # 最终计数
    count = torch.sum(dnst_mp).item()
    #retun count, density and map
    return count,img_den,dnst_mp

至此,我们已经创建了计算和生成热图的函数。接下来,让我们对从视频中提取的图像使用这些函数。

在此之前,让我们导入图像。

导入图像

# 获取路径中的所有图片
image_location = []
path_sets = ['/content/crowd']
# 加载所有图片
for path in path_sets:
    for img_path in glob.glob(os.path.join(path, '*.jpg')):
        image_location.append(img_path)
image_location[:3]

['/content/crowd/frame91.jpg',

'/content/crowd/frame12.jpg',

'/content/crowd/frame26.jpg']

获取人群计数

让我们遍历我们通过之前创建的函数导入的每个图像。最后,我们附加计数和图像 ID 以创建将充当输出的数据框。

# 通过图像获取人数
# 定义空列表
list_df = []
# 循环遍历每张图片
for i in image_location :
    count, img_den, dnst_mp = get_count_people(i)
    generate_dens_map(img_den, dnst_mp.cpu().detach().numpy(), 0, i)
    list_df = list_df + [[i,count]]
# 创建带有图像ID和计数的数据框
df = pd.DataFrame(list_df,columns=['image','count'])
# 排序并显示
df.sort_values(['image']).head()

9-7a显示了模型的输出。它给出了每一帧的客户数量。这让我们了解每天有多少客户来访。让我们对这个预测做一些基本的统计。

Df.describe()

图 9-7a 输出

import seaborn as sns
sns.histplot(data=df['count'])

正如我们从图9-7b9-7c中可以观察到的那样,商店中任何时候平均有 15 名顾客。

图 9-7b 输出

图 9-7c 输出

让我们看一下同时生成的一些热图。图9-89-9显示了给定时间实例的热图。左侧是原始图像,右侧是热图。白色和黄色块表示该特定区域的客户密度。使用这些信息,我们可以轻松识别商店中的热点。

图 9-8 原始图像和热图

图 9-9 原始图像和热图

这是我们看到计数和密度图的一个例子。在下一个用例中,让我们看看如何使用相同的概念执行安全和监视。

安全和监控

在本世纪,安全已成为一个大问题。视频监控已经存在很长时间了,但是它的工作方式正在发生变化。有很大的自动化空间。有了人工智能,这正在成为现实。见图9-10

图 9-10 人工监控

我们可以通过使用视频处理检测移动的人来分析限制或敏感区域是否有任何移动。这样,现场人员就不必 7 天 24 小时不间断地查看安全录像。如果有任何动静,系统会向负责的安全人员发出警报。

可以训练模型来预测不良事件。使用此类软件持续监控事件将节省大量人工时间并降低安全风险。

让我们看看我们上传的第二个视频并检测其中的运动。

# 获取路径中的所有图片
image_location = []
path_sets = ['/content/movement']
# loading 停车场视频的所有图像
for path in path_sets:
    for img_path in glob.glob(os.path.join(path, '*.jpg')):
        image_location.append(img_path)
image_location[:3]
# 通过图像获取人数
list_df = []

现在所有图像都已加载,下一步是遍历每张图像,看看禁区内是否有人。

让我们在名为movement的数据框的新列中捕捉人类的存在。

#checking if there is any movement for each frame in video
for i in image_location :
    count, img_den, dnst_mp = get_count_people(i)
    generate_dens_map(img_den, dnst_mp.cpu().detach().numpy(), 0, i)
    list_df = list_df + [[i,count]]
#saving the data into dataframe
detected_df = pd.DataFrame(list_df,columns=['image','count'])
detected_df['movement'] = np.where(detected_df['count'] > 3 ,'yes','no')
detected_df.filter(items = [45,56,53], axis=0)

#检查视频中的每一帧是否有任何移动

对于我在 image_location 中:

计数,img_den,dnst_mp = get_count_people(i)

generate_dens_map(img_den, dnst_mp.cpu().detach().numpy(), 0, i)

list_df = list_df + [[i,count]]

#将数据保存到dataframe中

detected_df = pd.DataFrame(list_df,columns=['image','count'])

detected_df['movement'] = np.where(detected_df['count'] > 3 ,'yes','no')

detected_df.filter(项目= [45,56,53],轴= 0)

9-11显示了输出。正如我们所观察到的,frame33在运动列中报告是,这意味着在特定的那一秒有人在场。

图 9-11

输出_

一旦 movement 变量变为yes,我们就可以提醒系统触发相应的权限。

让我们看几个我们观察到一些运动的例子。

#打印 movement = 'yes' 的图像

图片 = '/content/movement/frame25.jpg'

图片.open(图片)

图片 = '/content/movement/frame27.jpg'

图片.open(图片)

9-129-13显示了画面中有人的图像,并且成功检测到运动。在下一节中,我们将了解如何检测示例视频中的年龄/性别。

图 9-12

输出

图 9-13

输出_

确定人口统计数据(年龄和性别)

大多数营销活动取决于目标客户的人口统计数据。如果我们可以从这些来自商场的实时视频中确定年龄和性别,我们就可以使用这些信息来定位适当的营销活动。

让我们尝试使用我们之前提取的图像来检测年龄和性别。

# 导入函数

face_detector = FaceDetector()

age_gender_detector = AgeGenderEstimator()

# 读取图像

img = '/content/movement/frame0.jpg'

image = cv2.imread(img,cv2.IMREAD_UNCHANGED)

图片.open(img)

9-14显示了将检测性别和年龄的样本图像。

#检查性别

面孔、框、分数、地标 = face_detector.detect_align(image)

性别,年龄 = age_gender_detector.detect(faces)

打印(性别,年龄)

['男'] [32]

图 9-14

输入图像

该模型预测了这张图片中人物的年龄和性别:

  • 32岁

  • 性别为男

概括

我们探索了视频分析的各种用例,并选择了四个用例来实施。讨论了解决方法以及用于实现该解决方案的库。

一个关键方面是将视频转换为图像,然后对该信息执行传统的图像处理。主要挑战是视频会生成大量图像,处理它们需要时间和资源。在许多情况下,一切都需要实时发生才能充分利用预测。

我们讨论了一些基本用例,但还有大量用例需要探索、学习和实施。还有许多技术挑战需要解决,处于研究阶段。现在我们已经学习并为不同的应用构建了一些计算机视觉模型,下一章将深入探讨计算机视觉模型的输出,并讨论计算机视觉的可解释人工智能。

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sonhhxg_柒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值