1、Yolo8
(一) YOLOv8和OpenCV实现货架上的物体计数
们将根据检测到的物体的坐标数据获得的见解确定货架的数量以及货架上的物体数量。
我们使用SKU110K数据集来构建我的目标检测模型。此数据集包含商店货架上对象的边界框注释,并且由一个名为“object”的类组成。
由于我在上一篇文章中已经介绍了模型训练,因此在本文中,我将重点介绍如何处理预测结果。如果您对模型训练感兴趣,可以参考下面的文章:
实战 | YOLOv8自定义数据集训练实现手势识别 (标注+训练+预测 保姆级教程)
本教程涵盖的步骤
分析市场货架需要检查的步骤如下:
- 导入库并使用预测模式
- 坐标数据分析
- 使用 OpenCV 解释数据
- 计数物品和架子
- 转换为参数化程序
导入库并使用预测模式
导入相关库,使用预训练模型进行预测并将结果分配给变量。
import numpy as np
from ultralytics import YOLO
model = YOLO('best.pt')
result=model.predict(
source='test_88.jpg',
conf=0.45,
save=True
)
我在“runs\detect\predict144”文件夹下总共预测了 152 个实例的对象,置信度阈值为 45%。
坐标数据分析
以 xyxy 格式检索框的坐标并将其转换为 numpy 数组。这些数据分别表示框的 xmin、ymin、xmax 和 ymax 坐标。前 25 个输出如下。
arrxy=result[0].boxes.xyxy
coordinates = np.array(arrxy)
coordinates[:25]
array([[ 2082, 1426, 2318, 1635],
[ 2356, 1106, 2678, 1321],
[ 1927, 2442, 2284, 2799],
[ 647, 961, 865, 1149],
[ 2101, 1644, 2323, 1841],
[ 1565, 2472, 1913, 2822],
[ 2334, 1420, 2567, 1640],
[ 1094, 957, 1301, 1138],
[ 967, 3186, 1243, 3369],
[ 873, 956, 1087, 1148],
[ 739, 3466, 993, 3662],
[ 1318, 968, 1512, 1138],
[ 1528, 2948, 1782, 3159],
[ 2109, 1914, 2497, 2128],
[ 1329, 2482, 1559, 2662],
[ 1264, 2947, 1522, 3156],
[ 466, 3655, 738, 3847],
[ 2139, 2135, 2527, 2330],
[ 1526, 1129, 1764, 1330],
[ 468, 3469, 731, 3646],
[ 691, 2976, 963, 3181],
[ 2233, 384, 2458, 582],
[ 1256, 3161, 1509, 3370],
[ 426, 0, 913, 154],
[ 975, 2964, 1252, 3179]], dtype=float32)
由于 (0,0) 坐标代表图像的左上角,因此我需要相应地对它们进行排序。为此,我计算 x 和 y 坐标的中点,并根据 y 坐标对它们进行排序。
arrxy=result[0].boxes.xyxy
coordinates = np.array(arrxy)
x_coords = (coordinates[:, 0] + coordinates[:, 2]) / 2
y_coords = (coordinates[:, 1] + coordinates[:, 3]) / 2
midpoints = np.column_stack((x_coords, y_coords))
rounded_n_sorted_arr = np.round(midpoints[midpoints[:, 1].argsort()]).astype(int)
print(rounded_n_sorted_arr[:25])
[[2762 63]
[2463 66]
[1998 68]
[ 670 77]
[ 241 80]
[1547 370]
[ 978 378]
[1370 399]
[2088 416]
[2102 476]
[ 916 478]
[2346 483]
[ 363 504]
[2774 514]
[1842 527]
[1392 542]
[2559 544]
[1178 552]
[1599 554]
[ 652 579]
[ 916 662]
[3009 677]
[2778 678]
[2122 684]
[2364 688]]
使用 OpenCV 解释数据
使用 OpenCV 分析了物体之间的坐标,为了直观地理解,我将物体中心的坐标用深蓝色圆圈圈了起来。查看排序后的坐标时,可以明显看到 y 轴明显增加,这表明物体在架子上跳了起来。
例如,我们看到 y 轴从 80 到 370 的差异非常大,所以我可以说这绝对是一个架子。
计数物品和架子
从我们的分析中我们可以了解到,如果 y 轴上的值超过某个值,我们可以说这是一个架子。在编写代码时,我有机会在不同的图像上进行测试,如果图像捕捉到所有架子并且是平行拍摄的,我们可以说 130 及以上的跳跃表示一个架子。
count=1
objects=0
group_sizes = []
for i in range(1, len(rounded_n_sorted_arr)):
if(rounded_n_sorted_arr[i][1] - rounded_n_sorted_arr[i-1][1] > 130 ):
group_sizes.append(objects + 1)
count += 1
objects = 0
else:
objects += 1
group_sizes.append(objects + 1)
for i, size in enumerate(group_sizes):
print(f" There are {size} products on {i+1}. shelf")
转换为参数化程序
所有代码放在一起。使用 argparse 库,我将使用以下代码提供我们的输入文件路径。作为输出,我们将打印指示每个货架上有多少产品的数据。
from typing import List
import numpy as np
from ultralytics import YOLO
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--image_path', type=str, required=True, help='image path')
args = parser.parse_args()
image_path = args.image_path
class ShelfDetector:
def __init__(self, model_path: str, confidence: float = 0.45):
self.model = YOLO(model_path)
self.confidence = confidence
def detect_shelves(self, image_path: str) -> List[int]:
result = self.model.predict(source=image_path, cnotallow=self.confidence, save=False)
arrxy = result[0].boxes.xyxy
coordinates = np.array(arrxy)
x_coords = (coordinates[:, 0] + coordinates[:, 2]) / 2
y_coords = (coordinates[:, 1] + coordinates[:, 3]) / 2
midpoints = np.column_stack((x_coords, y_coords))
sorted_midpoints = midpoints[midpoints[:,1].argsort()]
rounded_n_sorted_arr = np.round(sorted_midpoints).astype(int)
group_sizes = []
objects = 0
for i in range(1, len(rounded_n_sorted_arr)):
if rounded_n_sorted_arr[i][1] - rounded_n_sorted_arr[i-1][1] > 130:
group_sizes.append(objects + 1)
objects = 0
else:
objects += 1
group_sizes.append(objects + 1)
return group_sizes
detector = ShelfDetector('best.pt')
result = detector.detect_shelves(image_path)
for i, size in enumerate(result):
print(f"{i+1}. There are {size} products on the shelf")
我们的CMD提示符中的输出将如下所示。这样,我们可以通过提供不同图像的路径来运行代码。
标签:arr,rounded,51c,YOLO,coordinates,objects,path,sorted,合集 From: https://blog.51cto.com/whaosoft/12062311