计算机视觉是一个跨学科的科学领域,涉及计算机如何从数字图像或视频中获得高层次的理解。从工程的角度来看,它致力于理解并自动化人类视觉系统可以执行的任务。如今,任务分类、目标检测、分割和关键点检测是主要的实时计算机视觉应用。那么,大家认为它是如何发展起来的呢?

首先,我们将简要讨论计算机视觉的主要问题。

我认为在看了上面的图片之后,你对与计算机视觉挑战相关的所有关键术语都有了清晰的理解。

每个人都希望有现成的解决方案——只需安装软件包,然后让进程进行——而无需理解后端操作。

解决方案:YOLO

因此,我将谈论一下 Yolov8 和基于区域的计数器项目的概述。

什么是YOLO?

基于CNN的目标检测器主要适用于推荐系统。YOLO(You Only Look Once)模型用于高性能的目标检测。YOLO将图像分成一个网格系统,每个网格在其中检测对象。它们可以根据数据流进行实时目标检测。它们需要非常少的计算资源。

目前发布了YoloV8!YOLOV8的主要特点是什么?

YOLOv8是YOLO算法的最新版本,通过引入各种修改,如空间注意、特征融合和上下文聚合模块,优于先前的版本。在YOLOv8中有多个值得关注的特性。以下是YOLOv8的一些关键特点:

  1. 提高准确性:与其前身相比,YOLOv8通过引入新的技术和优化改进了目标检测的准确性。

  2. 增强速度:YOLOv8在保持高准确性的同时,实现了比其他目标检测模型更快的推理速度。

  3. 多个骨干:YOLOv8支持各种骨干,如EfficientNet、ResNet和CSPDarknet,使用户能够灵活选择适合其特定用例的最佳模型。

  4. 自适应训练:YOLOv8使用自适应训练来优化学习率并在训练期间平衡损失函数,从而提高模型性能。

  5. 高级数据增强:YOLOv8采用高级数据增强技术,如MixUp和CutMix,以提高模型的鲁棒性和泛化能力。

  6. 可定制的架构:YOLOv8的架构高度可定制,使用户能够轻松修改模型的结构和参数以满足其需求。

  7. 预训练模型:YOLOv8提供了预训练模型,便于在各种数据集上进行使用和迁移学习。

架构:

YOLOv8的架构是基于先前版本的YOLO算法构建的。YOLOv8利用一个卷积神经网络,可以分为两个主要部分:骨干和头部。

CSPDarknet53架构的修改版本构成了YOLOv8的骨干。该架构包含53个卷积层,并采用跨阶段的部分连接以改善不同层之间的信息流。

  • YOLOv8的头部由多个卷积层组成,后面是一系列全连接层。

  • 这些层负责预测图像中检测到的对象的边界框、对象性分数和类别概率。

  • YOLOv8的一个关键特性是在网络头部使用自注意机制。

  • 这个机制允许模型专注于图像的不同部分,并根据它们对任务的相关性调整不同特征的重要性。

  • YOLOv8的另一个重要特性是其执行多尺度对象检测的能力。该模型利用特征金字塔网络来检测图像中不同尺寸和比例的对象。

这个特征金字塔网络包含多个层次,用于在不同尺度上检测对象,使模型能够检测图像中的大型和小型对象。

YOLOv5与YOLOv8有什么区别?

  1. 将C3模块替换为C2f模块

  2. 在骨干中,将第一个6×6卷积替换为3×3卷积

  3. 删除两个卷积层(YOLOv5配置中的第10和第14层)

  4. 在瓶颈中,将第一个1×1卷积替换为3×3卷积

  5. 使用解耦的头部并删除对象性分支

现在关注我们使用YOLOv8的基于区域的计数器

使用YoloV8区域计数器,并将其扩展到具有绘制和拖动的多边形区域计数器。这是一个具有广泛应用范围的奇妙想法。本文用例——奶牛计数,这对每个农场主和与安全相关的应用都很有用。

代码:

#!/usr/bin/env python3# -*- coding: utf-8 -*-"""Created on Mon Oct9 16:01:38 2023Requirements:- opencv-python- ultralytics- numpy- shapely"""#ultralytics.checks() #Run inference on an image with YOLOv8n#!yolo predict model=yolov8n.pt source='https://ultralytics.com/images/zidane.jpg'import argparsefrom collections import defaultdictfrom pathlib import Pathimport cv2import numpy as npfrom shapely.geometry import Polygonfrom shapely.geometry.point import Pointfrom ultralytics import YOLOfrom ultralytics.utils.files import increment_pathfrom ultralytics.utils.plotting import Annotator, colorstrack_history = defaultdict(lambda: [])current_region = Nonecounting_regions = [{'name': 'YOLOv8 Polygon Region','polygon': Polygon([(50, 80), (250, 20), (450, 80), (400, 350), (100, 350)]),# Polygon points'counts': 0,'dragging': False,'region_color': (255, 42, 4),# BGR Value'text_color': (255, 255, 255)# Region Text Color},{'name': 'YOLOv8 Rectangle Region','polygon': Polygon([(200, 250), (440, 250), (440, 550), (200, 550)]),# Polygon points'counts': 0,'dragging': False,'region_color': (37, 255, 225),# BGR Value'text_color': (0, 0, 0),# Region Text Color}, ]def mouse_callback(event, x, y, flags, param):"""Mouse call back event."""global current_region# Mouse left button down eventif event == cv2.EVENT_LBUTTONDOWN:for region in counting_regions:if region['polygon'].contains(Point((x, y))):current_region = regioncurrent_region['dragging'] = Truecurrent_region['offset_x'] = xcurrent_region['offset_y'] = y# Mouse move eventelif event == cv2.EVENT_MOUSEMOVE:if current_region is not None and current_region['dragging']:dx = x - current_region['offset_x']dy = y - current_region['offset_y']current_region['polygon'] = Polygon([(p[0] + dx, p[1] + dy) for p in current_region['polygon'].exterior.coords])current_region['offset_x'] = xcurrent_region['offset_y'] = y# Mouse left button up eventelif event == cv2.EVENT_LBUTTONUP:if current_region is not None and current_region['dragging']:current_region['dragging'] = Falsedef run(weights='yolov8n.pt',source=None,device='cpu',view_img=False,save_img=False,exist_ok=False,line_thickness=2,track_thickness=2,region_thickness=2,):"""Run Region counting on a video using YOLOv8 and ByteTrack.Supports movable region for real time counting inside specific area.Supports multiple regions counting.Regions can be Polygons or rectangle in shapeArgs:weights (str): Model weights path.source (str): Video file path.device (str): processing device cpu, 0, 1view_img (bool): Show results.save_img (bool): Save results.exist_ok (bool): Overwrite existing files.line_thickness (int): Bounding box thickness.track_thickness (int): Tracking line thicknessregion_thickness (int): Region thickness."""vid_frame_count = 0# Check source pathif not Path(source).exists():raise FileNotFoundError(f"Source path '{source}' does not exist.")# Setup Modelmodel = YOLO(f'{weights}')model.to('cuda') if device == '0' else model.to('cpu')# Video setupvideocapture = cv2.VideoCapture(source)frame_width, frame_height = int(videocapture.get(3)), int(videocapture.get(4))fps, fourcc = int(videocapture.get(5)), cv2.VideoWriter_fourcc(*'mp4v')# Output setupsave_dir = increment_path(Path('ultralytics_rc_output') / 'exp', exist_ok)save_dir.mkdir(parents=True, exist_ok=True)video_writer = cv2.VideoWriter(str(save_dir / f'{Path(source).stem}.mp4'), fourcc, fps, (frame_width, frame_height))# Iterate over video frameswhile videocapture.isOpened():success, frame = videocapture.read()if not success:breakvid_frame_count += 1# Extract the resultsresults = model.track(frame, persist=True)boxes = results[0].boxes.xywh.cpu()track_ids = results[0].boxes.id.int().cpu().tolist()clss = results[0].boxes.cls.cpu().tolist()names = results[0].namesannotator = Annotator(frame, line_width=line_thickness, example=str(names))for box, track_id, cls in zip(boxes, track_ids, clss):x, y, w, h = boxlabel = str(names[cls])xyxy = (x - w / 2), (y - h / 2), (x + w / 2), (y + h / 2)# Bounding box plotbbox_color = colors(cls, True)annotator.box_label(xyxy, label, color=bbox_color)# Tracking Lines plottrack = track_history[track_id]track.append((float(x), float(y)))if len(track) > 30:track.pop(0)points = np.hstack(track).astype(np.int32).reshape((-1, 1, 2))cv2.polylines(frame, [points], isClosed=False, color=bbox_color, thickness=track_thickness)# Check if detection inside regionfor region in counting_regions:if region['polygon'].contains(Point((x, y))):region['counts'] += 1# Draw regions (Polygons/Rectangles)for region in counting_regions:region_label = str(region['counts'])region_color = region['region_color']region_text_color = region['text_color']polygon_coords = np.array(region['polygon'].exterior.coords, dtype=np.int32)centroid_x, centroid_y = int(region['polygon'].centroid.x), int(region['polygon'].centroid.y)text_size, _ = cv2.getTextSize(region_label, cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.7, thickness=line_thickness)text_x = centroid_x - text_size[0] // 2text_y = centroid_y + text_size[1] // 2cv2.rectangle(frame, (text_x - 5, text_y - text_size[1] - 5), (text_x + text_size[0] + 5, text_y + 5),region_color, -1)cv2.putText(frame, region_label, (text_x, text_y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, region_text_color,line_thickness)cv2.polylines(frame, [polygon_coords], isClosed=True, color=region_color, thickness=region_thickness)if view_img:if vid_frame_count == 1:cv2.namedWindow('Ultralytics YOLOv8 Region Counter Movable')cv2.setMouseCallback('Ultralytics YOLOv8 Region Counter Movable', mouse_callback)cv2.imshow('Ultralytics YOLOv8 Region Counter Movable', frame)if save_img:video_writer.write(frame)for region in counting_regions:# Reinitialize count for each regionregion['counts'] = 0if cv2.waitKey(1) & 0xFF == ord('q'):breakdel vid_frame_countvideo_writer.release()videocapture.release()cv2.destroyAllWindows()def parse_opt():"""Parse command line arguments."""parser = argparse.ArgumentParser()parser.add_argument('--weights', type=str, default='yolov8n.pt', help='initial weights path')parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')parser.add_argument('--source', type=str, required=True, help='video file path')parser.add_argument('--view-img', action='store_true', help='show results')parser.add_argument('--save-img', action='store_true', help='save results')parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')parser.add_argument('--line-thickness', type=int, default=2, help='bounding box thickness')parser.add_argument('--track-thickness', type=int, default=2, help='Tracking line thickness')parser.add_argument('--region-thickness', type=int, default=4, help='Region thickness')return parser.parse_args()def main(opt):"""Main function."""run(**vars(opt))if __name__ == '__main__':opt = parse_opt()main(opt)

运行代码:

python3 your_filename.py --source cow.mp4 --save-img --view-img

输出:

在我看来,这是一个非常优秀的模型,用于识别物体,并且您可以轻松地对其进行微调以适应您特定的对象。关于人工智能或深度学习的具体细节,没有人是全知的。每个人都在使用这个相关的人工智能程序。

· END ·

HAPPYLIFE

本文仅供学习交流使用,如有侵权请联系作者删除