计算机视觉是一个跨学科的科学领域,涉及计算机如何从数字图像或视频中获得高层次的理解。从工程的角度来看,它致力于理解并自动化人类视觉系统可以执行的任务。如今,任务分类、目标检测、分割和关键点检测是主要的实时计算机视觉应用。那么,大家认为它是如何发展起来的呢?
首先,我们将简要讨论计算机视觉的主要问题。
我认为在看了上面的图片之后,你对与计算机视觉挑战相关的所有关键术语都有了清晰的理解。
每个人都希望有现成的解决方案——只需安装软件包,然后让进程进行——而无需理解后端操作。
解决方案:YOLO
因此,我将谈论一下 Yolov8 和基于区域的计数器项目的概述。
什么是YOLO?
基于CNN的目标检测器主要适用于推荐系统。YOLO(You Only Look Once)模型用于高性能的目标检测。YOLO将图像分成一个网格系统,每个网格在其中检测对象。它们可以根据数据流进行实时目标检测。它们需要非常少的计算资源。
目前发布了YoloV8!YOLOV8的主要特点是什么?
YOLOv8是YOLO算法的最新版本,通过引入各种修改,如空间注意、特征融合和上下文聚合模块,优于先前的版本。在YOLOv8中有多个值得关注的特性。以下是YOLOv8的一些关键特点:
提高准确性:与其前身相比,YOLOv8通过引入新的技术和优化改进了目标检测的准确性。
增强速度:YOLOv8在保持高准确性的同时,实现了比其他目标检测模型更快的推理速度。
多个骨干:YOLOv8支持各种骨干,如EfficientNet、ResNet和CSPDarknet,使用户能够灵活选择适合其特定用例的最佳模型。
自适应训练:YOLOv8使用自适应训练来优化学习率并在训练期间平衡损失函数,从而提高模型性能。
高级数据增强:YOLOv8采用高级数据增强技术,如MixUp和CutMix,以提高模型的鲁棒性和泛化能力。
可定制的架构:YOLOv8的架构高度可定制,使用户能够轻松修改模型的结构和参数以满足其需求。
预训练模型:YOLOv8提供了预训练模型,便于在各种数据集上进行使用和迁移学习。
架构:
YOLOv8的架构是基于先前版本的YOLO算法构建的。YOLOv8利用一个卷积神经网络,可以分为两个主要部分:骨干和头部。
CSPDarknet53架构的修改版本构成了YOLOv8的骨干。该架构包含53个卷积层,并采用跨阶段的部分连接以改善不同层之间的信息流。
YOLOv8的头部由多个卷积层组成,后面是一系列全连接层。
这些层负责预测图像中检测到的对象的边界框、对象性分数和类别概率。
YOLOv8的一个关键特性是在网络头部使用自注意机制。
这个机制允许模型专注于图像的不同部分,并根据它们对任务的相关性调整不同特征的重要性。
YOLOv8的另一个重要特性是其执行多尺度对象检测的能力。该模型利用特征金字塔网络来检测图像中不同尺寸和比例的对象。
这个特征金字塔网络包含多个层次,用于在不同尺度上检测对象,使模型能够检测图像中的大型和小型对象。
YOLOv5与YOLOv8有什么区别?
将C3模块替换为C2f模块
在骨干中,将第一个6x6卷积替换为3x3卷积
删除两个卷积层(YOLOv5配置中的第10和第14层)
在瓶颈中,将第一个1x1卷积替换为3x3卷积
使用解耦的头部并删除对象性分支
现在关注我们使用YOLOv8的基于区域的计数器
使用YoloV8区域计数器,并将其扩展到具有绘制和拖动的多边形区域计数器。这是一个具有广泛应用范围的奇妙想法。本文用例——奶牛计数,这对每个农场主和与安全相关的应用都很有用。
代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Oct 9 16:01:38 2023
Requirements:
- 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 argparse
from collections import defaultdict
from pathlib import Path
import cv2
import numpy as np
from shapely.geometry import Polygon
from shapely.geometry.point import Point
from ultralytics import YOLO
from ultralytics.utils.files import increment_path
from ultralytics.utils.plotting import Annotator, colors
track_history = defaultdict(lambda: [])
current_region = None
counting_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 event
if event == cv2.EVENT_LBUTTONDOWN:
for region in counting_regions:
if region['polygon'].contains(Point((x, y))):
current_region = region
current_region['dragging'] = True
current_region['offset_x'] = x
current_region['offset_y'] = y
# Mouse move event
elif 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'] = x
current_region['offset_y'] = y
# Mouse left button up event
elif event == cv2.EVENT_LBUTTONUP:
if current_region is not None and current_region['dragging']:
current_region['dragging'] = False
def 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 shape
Args:
weights (str): Model weights path.
source (str): Video file path.
device (str): processing device cpu, 0, 1
view_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 thickness
region_thickness (int): Region thickness.
"""
vid_frame_count = 0
# Check source path
if not Path(source).exists():
raise FileNotFoundError(f"Source path '{source}' does not exist.")
# Setup Model
model = YOLO(f'{weights}')
model.to('cuda') if device == '0' else model.to('cpu')
# Video setup
videocapture = 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 setup
save_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 frames
while videocapture.isOpened():
success, frame = videocapture.read()
if not success:
break
vid_frame_count += 1
# Extract the results
results = 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].names
annotator = Annotator(frame, line_width=line_thickness, example=str(names))
for box, track_id, cls in zip(boxes, track_ids, clss):
x, y, w, h = box
label = str(names[cls])
xyxy = (x - w / 2), (y - h / 2), (x + w / 2), (y + h / 2)
# Bounding box plot
bbox_color = colors(cls, True)
annotator.box_label(xyxy, label, color=bbox_color)
# Tracking Lines plot
track = 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 region
for 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] // 2
text_y = centroid_y + text_size[1] // 2
cv2.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 region
region['counts'] = 0
if cv2.waitKey(1) & 0xFF == ord('q'):
break
del vid_frame_count
video_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 ·
HAPPY LIFE
本文仅供学习交流使用,如有侵权请联系作者删除