写点什么

昇腾 AI 行业案例(二):基于 AI 图像处理的安全帽检测

作者:AI布道Mr.Jin
  • 2025-01-22
    上海
  • 本文字数:11211 字

    阅读完需:约 37 分钟

昇腾AI行业案例(二):基于 AI 图像处理的安全帽检测

00 - 前言

欢迎学习《昇腾行业应用案例》的 “基于 AI 图像处理的安全帽检测” 实验。在本实验中,你将深入了解如何运用计算机视觉(CV)领域的 AI 模型,搭建一个高效精准的安全帽检测系统,并利用开源数据集对模型效果加以验证。为此,我们将使用昇腾的 AI 硬件以及 CANN 等软件产品。


学习目标

在本课程中,您将学习一些与使用 AI 图像处理技术实现安全帽检测有关的重要概念,包括:

  • 图像数据的预处理方法

  • 采用计算机视觉检测人物和安全帽的方法

  • 目标检测后处理的方法

  • 端到端深度学习工作流


目录

本实验分为四个核心部分。第一部分主要介绍案例的应用场景,第二部分会详细阐述端到端的解决方案,搭建起技术实现的整体框架。第三部分会手把手指导您完成代码编写与实现,最后一部分给出测试题,帮助您巩固学习内容。

  1. 场景介绍

  2. 解决方案

  3. 代码实战

  4. 课后测试

JupyterLab

在本实操实验中,我们将使用 JupyterLab 管理我们的环境。JupyterLab 界面是一个控制面板,可供您访问交互式 iPython Notebook、所用环境的文件夹结构,以及用于进入 Ubuntu 操作系统的终端窗口,只需要点击菜单栏的小三角就可以运行代码。

尝试执行下方单元中的一条简单的 print(打印)语句。

# DO NOT CHANGE THIS CELL# activate this cell by selecting it with the mouse or arrow keys then use the keyboard shortcut [Shift+Enter] to executeprint('This is just a simple print statement')
复制代码


This is just a simple print statement
复制代码

01 场景介绍

在各类建筑工地、工厂车间等生产作业场所,安全问题始终是重中之重。安全帽作为保护工作人员头部免受意外伤害的关键防护装备,正确佩戴与否直接关乎生命安全。然而,现实场景中,因人员疏忽、管理不善等因素,未佩戴或未正确佩戴安全帽的情况屡见不鲜,这无疑极大地增加了安全事故发生的风险。


据相关统计数据显示,在建筑行业,因头部受伤导致的伤亡事故占比颇高。每年,全球范围内都有众多工人因未规范佩戴安全帽,在高空坠物、设备碰撞等意外发生时,遭受重创甚至失去生命。这些惨痛的教训凸显出安全帽检测技术的迫切性与重要性。随着 AI 图像处理技术与深度学习的飞速发展,企业得以借助先进的 AI 技术实现作业现场的实时监控,精准、快速地判断工人是否正确佩戴安全帽。这项技术通过分析现场摄像头采集的图像,对画面中的人头进行定位识别,再细致判断安全帽的佩戴情况,一经发现违规现象,立即触发警报,通知现场管理人员及时纠正,从而有效预防安全事故的发生,为安全生产保驾护航。

02 解决方案

安全帽检测已然成为众多企业安全生产监控系统中的关键一环。典型的安全帽检测方案主要包含以下几大模块:


  1. 图像预处理模块:负责接收现场摄像头实时传输的图像数据,进行降噪、增强、尺寸调整等预处理操作,提升图像质量,剔除干扰信息,为后续模型处理奠定良好基础。

  2. 人物检测模型和头盔检测模型:运用 CV 领域成熟的目标检测模型,例如本课程选用的 YOLOv5 模型,精准定位图像中的人物位置和头盔位置,判断所有人物是否有佩戴安全帽。

  3. 目标检测后处理模块:目标检测模型的输出结果通常会包含很多重复框,为了方便我们进行结果分析,我们需要对目标检测结果去重,主要使用的是 non_max_suppression 算法。

2.1 图像预处理模块

在真实业务场景中,需要连续分析多帧图像,所以需要构建一个图片管理器,持续给 AI 模型输送图片。此外,原始图片的形状、像素值往往和 AI 模型的输入要求不一致,所以我们需要对原始图片进行处理,包括 resizetransposepadding 等操作。

2.2 目标检测模型

目标检测算法历经传统机器学习与 AI 视觉两个发展阶段。早期的机器学习模型多依赖手工设计特征,像 Haar 特征结合 AdaBoost 分类器,或是基于 HOG(Histogram of Oriented Gradients)特征与 SVM(Support Vector Machine)的组合。这些方法在简单场景下有一定效果,但面对复杂多变的施工现场,光照不均、人员密集、遮挡严重等问题使其泛化能力大打折扣,检测精度与效率难以满足需求。深度学习兴起后,基于卷积神经网络(CNN)的目标检测算法渐成主流,YOLOv5 模型便是其中佼佼者,凭借出色的实时性与准确性,广泛应用于目标检测任务。



YOLOv5 模型的主干网络采用的是 CSPDarknet53 结构,能够高效提取图像多尺度特征,为后续检测夯实基础,快速捕捉人物和头盔关键信息。Neck 部分引入了特征金字塔网络(FPN)与 PAN(Path Aggregation Network)结构,可以融合不同层次特征图,增强模型对不同大小目标物体的检测能力,确保小目标也无处遁形。YOLOv5 的 Head 部分负责最终分类与边界框回归任务,依据 Neck 传来的特征图,精准输出检测结果,框定目标位置,附带置信度信息。本课程选用 YOLOv5 模型有诸多优势:高准确性,经大量数据训练优化,精准定位人物和头盔;实时性能佳,满足施工现场实时监控需求;多尺度检测能力强,适配不同距离、大小的目标;模型结构紧凑,便于部署与优化。

03 动手实验

3.1 实验准备

数据集准备

实验所用图像数据源自公开的建筑工地监控数据集,该数据集收纳了海量工人施工场景图片,且均精准标注了安全帽佩戴情况,本实验选取了少量图片,存放于 ./test_data 目录下。


模型权重

本实验采用的 YOLOv5_s 模型权重可从GitHub 仓库下载,确保其适配安全帽佩戴判断任务;下载解压后,妥善置于指定目录,方便后续代码快速加载与调用。万事俱备,接下来让我们正式步入代码实操环节!

3.2 构建图像处理类

从测试图片目录读取图像,构建 Python 类封装图像预处理流程,实现代码复用与高效管理。首先,导入所需三方库:

import cv2import globimport numpy as npfrom pathlib import Path
复制代码


创建图像预处理类 LoadImages:


class LoadImages:    def __init__(self, path, img_size=640, stride=32, auto=True):        """        Initializes YOLOv5 loader for images, supporting directories.                Args:            path (str): Directory path containing images.            img_size (int): Image size for resizing.            stride (int): Stride for resizing.            auto (bool): Automatic image resizing.        """        self.img_size = img_size        self.stride = stride        self.auto = auto        self.files = sorted(glob.glob(str(Path(path).resolve()) + '/*.*'))  # directory
self.nf = len(self.files) # number of files assert self.nf > 0, f"No images found in {path}. Supported formats are: {IMG_FORMATS}"
def __iter__(self): """Initializes iterator by resetting count and returns the iterator object itself.""" self.count = 0 return self
def __next__(self): """Advances to the next file in the dataset, raising StopIteration if at the end.""" if self.count == self.nf: raise StopIteration path = self.files[self.count]
self.count += 1 im0 = cv2.imread(path) # BGR assert im0 is not None, f"Image Not Found {path}"
# Padded resize im = letterbox(im0, self.img_size, stride=self.stride, auto=self.auto)[0] # padded resize im = im.transpose((2, 0, 1))[::-1] # HWC to CHW, BGR to RGB im = np.ascontiguousarray(im) # contiguous
return path, im, im0
复制代码


其中的 letterbox 函数用于对图像进行填充:

def letterbox(im, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True, stride=32):    """Resizes and pads image to new_shape with stride-multiple constraints, returns resized image, ratio, padding."""    shape = im.shape[:2]  # current shape [height, width]    if isinstance(new_shape, int):        new_shape = (new_shape, new_shape)
# Scale ratio (new / old) r = min(new_shape[0] / shape[0], new_shape[1] / shape[1]) if not scaleup: # only scale down, do not scale up (for better val mAP) r = min(r, 1.0)
# Compute padding ratio = r, r # width, height ratios new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r)) dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1] # wh padding if auto: # minimum rectangle dw, dh = np.mod(dw, stride), np.mod(dh, stride) # wh padding elif scaleFill: # stretch dw, dh = 0.0, 0.0 new_unpad = (new_shape[1], new_shape[0]) ratio = new_shape[1] / shape[1], new_shape[0] / shape[0] # width, height ratios
dw /= 2 # divide padding into 2 sides dh /= 2
if shape[::-1] != new_unpad: # resize im = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR) top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1)) left, right = int(round(dw - 0.1)), int(round(dw + 0.1)) im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color) # add border return im, ratio, (dw, dh)
复制代码


测试该类,读取并预处理图像:

source = "./test_data/"dataset = LoadImages(source)for path, im, im0 in dataset:    print(im.shape)
复制代码


(3, 448, 640)(3, 640, 416)
复制代码

3.3 使用 YOLOv5 模型检测人物和头盔

依据 2.2 章节知识,用 YOLOv5_s 模型精准定位人头。首先,我们需要在服务器的工作目录克隆模型代码,并且把代码仓路径添加到 python 环境,便于我们调用模型:


# git clone https://github.com/ultralytics/yolov5# export PYTHONPATH="./yolov5/:$PYTHONPATH"
复制代码


此外,还需要下载 yolov5_s 的预训练权重 helmet_head_person_s.pt 。接下来测试一下模型的推理功能:

from models.common import DetectMultiBackend  # 导入yolov5_s模型import torchimport torch_npu  # 使用昇腾硬件推理from torch_npu.contrib import transfer_to_npu  # 使用昇腾硬件推理import warningswarnings.filterwarnings('ignore')model = DetectMultiBackend("./helmet_head_person_s.pt")img_loader = LoadImages('./test_data')for path, im, im0s in img_loader:    im = torch.from_numpy(im)    im = im.half() if model.fp16 else im.float()  # uint8 to fp16/32    im /= 255  # 0 - 255 to 0.0 - 1.0    if len(im.shape) == 3:        im = im[None]  # expand for batch dim    pred = model(im)[0]    print(pred.shape)
复制代码


Fusing layers... YOLOv5s summary: 232 layers, 7251912 parameters, 0 gradients

torch.Size([1, 17640, 8])torch.Size([1, 16380, 8])
复制代码

3.4 目标检测结果的后处理流程

正如前面提到的,模型输出的检测框可能存在大量重复的情况,所以我们需要实现 non_max_suppression 算法及其相关的支撑函数,来对这些结果进行过滤和优化。在实现 non_max_suppression 之前,我们需要先实现 2 个依赖函数,xywh2xyxy 用来把检测框的 [x, y, w, h] 坐标转成 [x1, y1, x2, y2] 坐标,box_iou 用来计算检测框之间的重合度。


# (x, y, w, h)的坐标格式转成(x1, y1, x2, y2)def xywh2xyxy(x):    """Convert nx4 boxes from [x, y, w, h] to [x1, y1, x2, y2] where xy1=top-left, xy2=bottom-right."""    y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x)    y[..., 0] = x[..., 0] - x[..., 2] / 2  # top left x    y[..., 1] = x[..., 1] - x[..., 3] / 2  # top left y    y[..., 2] = x[..., 0] + x[..., 2] / 2  # bottom right x    y[..., 3] = x[..., 1] + x[..., 3] / 2  # bottom right y    return y
# 计算方框之间的 IOU(Intersection over Union)def box_iou(box1, box2, eps=1e-7): # https://github.com/pytorch/vision/blob/master/torchvision/ops/boxes.py """ Return intersection-over-union (Jaccard index) of boxes.
Both sets of boxes are expected to be in (x1, y1, x2, y2) format.
Arguments: box1 (Tensor[N, 4]) box2 (Tensor[M, 4])
Returns: iou (Tensor[N, M]): the NxM matrix containing the pairwise IoU values for every element in boxes1 and boxes2 """ # inter(N,M) = (rb(N,M,2) - lt(N,M,2)).clamp(0).prod(2) (a1, a2), (b1, b2) = box1.unsqueeze(1).chunk(2, 2), box2.unsqueeze(0).chunk(2, 2) inter = (torch.min(a2, b2) - torch.max(a1, b1)).clamp(0).prod(2)
# IoU = inter / (area1 + area2 - inter) return inter / ((a2 - a1).prod(2) + (b2 - b1).prod(2) - inter + eps)
复制代码


接下来,我们就可以实现非极大抑制算法了。这个算法的步骤如下:

  1. 置信度排序:对于每个图像,NMS 算法首先根据检测到的对象的置信度(confidence)进行排序。置信度通常是指模型对于检测到的对象属于某个类别的概率。

  2. 选择最佳边界框:选择置信度最高的边界框,将其作为参考框(reference box)。

  3. 计算交并比(IoU):计算参考框与其他所有边界框的交并比(Intersection over Union,IoU)。IoU 是一个衡量两个边界框重叠程度的指标,计算公式为两个边界框交集面积与并集面积的比值。

  4. 抑制重叠边界框:如果某个边界框与参考框的 IoU 超过了预设的阈值(iou_thres),则认为这两个边界框重叠过多,将该边界框抑制(即从候选列表中移除)。

  5. 迭代处理:在移除所有与当前参考框重叠过多的边界框后,选择置信度次高的边界框作为新的参考框,重复步骤 3 和 4,直到所有边界框都被处理。

  6. 输出结果:经过 NMS 处理后,剩下的边界框即为最终的检测结果。


代码实现如下:

# 非极大抑制去除重复框def non_max_suppression(    prediction,    conf_thres=0.25,    iou_thres=0.45,    classes=None,    agnostic=False,    multi_label=True,    labels=(),    max_det=300,    nm=0,  # 掩码的数量):    """    在推理结果上执行非最大抑制(NMS)以拒绝重叠的检测结果。
返回: 检测结果的列表,每个图像对应一个(n,6)张量 [x1, y1, x2, y2, conf, cls] """ # 入参检查 assert 0 <= conf_thres <= 1, f"置信度阈值 {conf_thres} 无效,有效值应在0.0和1.0之间" assert 0 <= iou_thres <= 1, f"IoU {iou_thres} 无效,有效值应在0.0和1.0之间" if isinstance(prediction, (list, tuple)): # YOLOv5模型在验证模型中,输出 = (推理输出, 损失输出) prediction = prediction[0] # 仅选择推理输出
bs = prediction.shape[0] # 批量大小 nc = prediction.shape[2] - nm - 5 # 类别数量 xc = prediction[..., 4] > conf_thres # 候选框
# 设置超参 max_wh = 7680 # (像素)最大框宽和高 max_nms = 30000 # 传入torchvision.ops.nms()的最大框数 time_limit = 0.5 + 0.05 * bs # 超时时间 redundant = True # 需要冗余检测 multi_label &= nc > 1 # 每个框多个标签(增加0.5ms/图像) merge = False # 不使用合并NMS
t = time.time() mi = 5 + nc # 掩码起始索引 output = [torch.zeros((0, 6 + nm), device=prediction.device)] * bs # 初始化输出检测框 for xi, x in enumerate(prediction): # 遍历推理检测结果 x = x[xc[xi]] # 获取置信度 # 如果自动标记,则添加先验标签 if labels and len(labels[xi]): lb = labels[xi] v = torch.zeros((len(lb), nc + nm + 5), device=x.device) v[:, :4] = lb[:, 1:5] # 框 v[:, 4] = 1.0 # 置信度 v[range(len(lb)), lb[:, 0].long() + 5] = 1.0 # 类别 x = torch.cat((x, v), 0)
# 如果没有剩余的处理下一张图像 if not x.shape[0]: continue
# 计算置信度 x[:, 5:] *= x[:, 4:5] # 置信度 = 目标置信度 * 类别置信度
# 框/掩码 box = xywh2xyxy(x[:, :4]) # (中心x, 中心y, 宽度, 高度) 转换为 (x1, y1, x2, y2) mask = x[:, mi:] # 如果没有掩码则为零列
# 检测矩阵 nx6 (xyxy, conf, cls) if multi_label: i, j = (x[:, 5:mi] > conf_thres).nonzero(as_tuple=False).T x = torch.cat((box[i], x[i, 5 + j, None], j[:, None].float(), mask[i]), 1) else: # 仅最佳类别 conf, j = x[:, 5:mi].max(1, keepdim=True) x = torch.cat((box, conf, j.float(), mask), 1)[conf.view(-1) > conf_thres]
# 按类别过滤 if classes is not None: x = x[(x[:, 5:6] == torch.tensor(classes, device=x.device)).any(1)]
# 检查形状 n = x.shape[0] # 框的数量 if not n: # 没有框 continue
x = x[x[:, 4].argsort(descending=True)[:max_nms]] # 按置信度排序并移除多余的框
# 批量NMS c = x[:, 5:6] * (0 if agnostic else max_wh) # 类别 boxes, scores = x[:, :4] + c, x[:, 4] # 框(按类别偏移), 得分 # 调用torchvision封装好的NMS接口 i = torchvision.ops.nms(boxes, scores, iou_thres) # NMS i = i[:max_det] # 限制检测数量 if merge and (1 < n < 3e3): # 合并NMS(使用加权平均合并框) # 更新框为 boxes(i,4) = weights(i,n) * boxes(n,4) iou = box_iou(boxes[i], boxes) > iou_thres # IoU矩阵 weights = iou * scores[None] # 框权重 x[i, :4] = torch.mm(weights, x[:, :4]).float() / weights.sum(1, keepdim=True) # 合并框 if redundant: i = i[iou.sum(1) > 1] # 需要冗余
output[xi] = x[i] if (time.time() - t) > time_limit: LOGGER.warning(f"警告 ⚠️ NMS 时间限制 {time_limit:.3f}s 超过") break # 时间限制超过
return output
复制代码


此外,我们还需要设计一个函数对检测框的坐标进行缩放,原因是我们在推理时为了让图片能够被 AI 模型处理,对它的形状进行了改变。为了让检测框准确地描绘在原来的图片上,我们需要时缩放函数 scale_boxes 及其支撑函数 clip_boxes


def clip_boxes(boxes, shape):    """Clips bounding box coordinates (xyxy) to fit within the specified image shape (height, width)."""    if isinstance(boxes, torch.Tensor):  # faster individually        boxes[..., 0].clamp_(0, shape[1])  # x1        boxes[..., 1].clamp_(0, shape[0])  # y1        boxes[..., 2].clamp_(0, shape[1])  # x2        boxes[..., 3].clamp_(0, shape[0])  # y2    else:  # np.array (faster grouped)        boxes[..., [0, 2]] = boxes[..., [0, 2]].clip(0, shape[1])  # x1, x2        boxes[..., [1, 3]] = boxes[..., [1, 3]].clip(0, shape[0])  # y1, y2        def scale_boxes(img1_shape, boxes, img0_shape, ratio_pad=None):    """Rescales (xyxy) bounding boxes from img1_shape to img0_shape, optionally using provided `ratio_pad`."""    if ratio_pad is None:  # calculate from img0_shape        gain = min(img1_shape[0] / img0_shape[0], img1_shape[1] / img0_shape[1])  # gain  = old / new        pad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2  # wh padding    else:        gain = ratio_pad[0][0]        pad = ratio_pad[1]
boxes[..., [0, 2]] -= pad[0] # x padding boxes[..., [1, 3]] -= pad[1] # y padding boxes[..., :4] /= gain clip_boxes(boxes, img0_shape) return boxes
复制代码


最后,我们还需要设计一个函数,用来分析检测到的人物和头盔,看看谁没有带头盔:

# 找到没有佩戴安全帽的人def find_person_without_helmet(detections):    person_without_helmet = []    # 将检测结果按类别分开存储    person_detections = []    helmet_detections = []        for det in detections:        x1, y1, x2, y2, confidence, label = det        if label == 0:  # 'person'            person_detections.append((x1, y1, x2, y2))        elif label == 2:  # 'helmet'            helmet_detections.append((x1, y1, x2, y2))        # 检查每个'person'检测框是否包含'helmet'    for person_box in person_detections:        person_x1, person_y1, person_x2, person_y2 = person_box        person_area = (person_x2 - person_x1) * (person_y2 - person_y1)                # 检查是否有'helmet'的90%区域落在'person'检测框内        contains_helmet = False        for helmet_box in helmet_detections:            helmet_x1, helmet_y1, helmet_x2, helmet_y2 = helmet_box            helmet_area = (helmet_x2 - helmet_x1) * (helmet_y2 - helmet_y1)                        # 计算'helmet'和'person'的交集面积            intersection_x1 = max(person_x1, helmet_x1)            intersection_y1 = max(person_y1, helmet_y1)            intersection_x2 = min(person_x2, helmet_x2)            intersection_y2 = min(person_y2, helmet_y2)                        intersection_area = max(0, intersection_x2 - intersection_x1) * max(0, intersection_y2 - intersection_y1)                        # 检查'helmet'的90%是否在'person'内            if intersection_area / helmet_area >= 0.9:                contains_helmet = True                break                # 如果当前'person'不包含'helmet'        if not contains_helmet:            person_without_helmet.append((person_x1, person_y1, person_x2, person_y2))        return person_without_helmet
复制代码

3.5 整合代码实现端到端检测

为达成施工现场安全帽佩戴情况的实时、精准监测,需将前文的图像预处理、安全帽佩戴判断等环节代码有机整合,封装成完整的端到端检测流程。


from ultralytics.utils.plotting import Annotator, colorsimport timeimport torchvision
conf_thres=0.25 # confidence thresholdiou_thres=0.45 # NMS IOU thresholdmax_det=1000 # maximum detections per imagehide_labels = Falsehide_conf = Falseline_thickness = 3model = DetectMultiBackend("./helmet_head_person_s.pt")stride, names, pt = model.stride, model.names, model.ptimgsz=(640, 640)model.warmup(imgsz=(1 if pt or model.triton else 1, 3, *imgsz)) # warmupimg_loader = LoadImages('./test_data')save_dir = "./detect_imgs/"# Run inferencefor path, im, im0s in img_loader: im = torch.from_numpy(im) im = im.half() if model.fp16 else im.float() # uint8 to fp16/32 im /= 255 # 0 - 255 to 0.0 - 1.0 if len(im.shape) == 3: im = im[None] # expand for batch dim pred = model(im)[0]
# Apply NMS pred = non_max_suppression(pred, conf_thres, iou_thres, classes=None, agnostic=False, max_det=max_det) # Process detections for i, det in enumerate(pred): # per image annotator = Annotator(im0s, line_width=line_thickness, example=str(names)) if len(det): number_of_person = np.sum(np.array(det[:, 5] == 0.0)) number_of_helmet = np.sum(np.array(det[:, 5] == 2.0)) if number_of_helmet < number_of_person: print("Notice! Someone is not wearing a helmet!") no_helmet_person = find_person_without_helmet(det) # Rescale boxes from img_size to im0 size det[:, :4] = scale_boxes(im.shape[2:], det[:, :4], im0s.shape).round() # Print results for *xyxy, conf, cls in reversed(det): c = int(cls) # integer class if tuple(xyxy) in no_helmet_person: label = "No helmet, Dangerous!" annotator.box_label(xyxy, label, color=(0, 0, 255)) else: label = None if hide_labels else (names[c] if hide_conf else f'{names[c]} {conf:.2f}') annotator.box_label(xyxy, label, color=colors(c, True))
# Save results (image with detections) print("save_path: ", save_dir + path.split("/")[-1]) cv2.imwrite(str(save_dir + path.split("/")[-1]), im0s)
复制代码


Fusing layers... YOLOv5s summary: 232 layers, 7251912 parameters, 0 gradients

save_path: ./detect_imgs/000012.jpgNotice! Someone is not wearing a helmet!save_path: ./detect_imgs/000178.jpg
复制代码


查看目标检测后的结果:


如此一来,便能一站式获取图像中所有人物的检测结果以及对应的安全帽佩戴状态。还可拓展代码,将检测结果可视化,标注在原始图像上,或是接入实时视频流,实现不间断监控,让安全生产管理更智能、高效。恭喜你!至此,你已成功完成基于 AI 图像处理的安全帽检测全部实验流程,希望你能熟练掌握这套技术方案,为更多安全生产场景赋能。

3.6 软件依赖

本实验的依赖软件版本信息如下:


  1. Python:为了方便开发者进行学习,本课程采用 Python 代码实现,您可以在服务器上安装一个 Conda,用于创建 Python 环境,本实验使用的是 python 3.10

  2. ultralytics:AI 视觉模型三方库,提供了多种 CV 模型的调用接口,内置了模型的前后处理,方便用户调用模型,本实验使用的是 8.3.48 版本;

  3. opencv-python:opencv-python 是 OpenCV 库的 Python 接口,它提供了对 OpenCV 功能的访问,包括图像处理、视频分析、计算机视觉算法和实时图像处理等,使得开发者能够在 Python 环境中轻松实现复杂的视觉任务,本实验使用的是 4.10.0.84 版本;

  4. numpy: 开源的 Python 科学计算库,用于进行大规模数值和矩阵运算,本实验使用的是 1.26.4 版本;

  5. torch:AI 计算框架,本实验使用的是 2.1.0 版本;

  6. torch_npu:torch 在昇腾硬件上的适配插件,可以让 torch 在昇腾硬件上执行,本实验使用的是 2.1.0.post6 版本;

  7. torchvision:提供了处理图像和视频的常用工具和预训练模型,本实验使用的是 0.16.0 版本;

  8. CANN(Compute Architecture for Neural Networks):Ascend 芯片的使能软件,本实验使用的是 8.0.rc2 版本

04 课后测试

如果把输入数据换成视频,如何处理?(提示:参考昇腾AI行业案例(一):基于AI图像处理的疲劳驾驶检测


发布于: 刚刚阅读数: 2
用户头像

还未添加个人签名 2020-11-13 加入

还未添加个人简介

评论

发布
暂无评论
昇腾AI行业案例(二):基于 AI 图像处理的安全帽检测_AI布道Mr.Jin_InfoQ写作社区