Nesne Sayımı veya Object Counting işlemi basitçe, videodaki nesnelerin sayısının tespit edilmesi anlamına gelir. Öncelikle sayısı tespit edilecek sınıflar karar verilir ve sonrasında Object Tracking algoritmalarınında yardımıyla bu nesneler sayılır. Dolayısıyla bu yazıyı okumaya başlamadan önce nesne takibi yazıma göz atmanızı tavsiye ederim.
Biz bu çalışmada, havalimanında yolcuların bavullarının aktığı bant üzerinden kaç adet bavul geçtiğini sayacağız. Bu yazıda öğreneceğiniz temellerle, kendi nesne sayım uygulamalarınızı gerçekleştirebileceksiniz. Aslında gerçek hayatta da bu konuyla ilgili pek çok örnek vardır:
- Kavşaktan geçen araç sayısı
- Konveyorden akan ürün sayısı
- Metro istasyonuna giren çıkan insan sayısı
gibi uygulamalar nesne sayımı uygulamasına dair güzel örnekledir.
1. Kurulumlar
Nesne sayımı işlemine başlamadan önce ilk olarak Ultralytics ve OpenCV kütüphanesini aşağıdaki komutlarla indirmelisiniz:
pip install ultralytics
pip install opencv-python
Çalışma boyunca kullanacağımız dosyaları blog yazımın başındaki bağlantıdan bilgisayarınıza indirebilirsiniz.
Şimdi dosya düzenini ayarlayalım. Boş bir klasör içerisinde object_counting.py adında bir dosya oluşturalım. Ardından test videomuzu da, yine kendi oluşturduğumuz video adındaki dizine koyalım. Çalışmada kullanacağımız model best.pt olacak. Bunu da, kendi oluşturduğumuz models isimli dizine yüklemeliyiz. burada kullandığımız best.pt modelini daha öncesinde bu çalışma için eğitildi ve sizlerle hazır olarak paylaşılıyor.
Tüm bu işlemler size karmaşık gelmeye başladıysa yukarıdaki videoyu da takip ederek yapabilirsiniz.
2. Nesne Sayımı
Kodlarımızı yazmaya başlamak için object_counting.py dosyamızı açıp kütüphaneleri ekleyelim:
import os
os.environ ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
import cv2
import numpy as np
from ultralytics import YOLO
from collections import defaultdict
Kütüphaneleri ekledikten sonra, metin ve renklendirme için kullanacağımız bazı parametreleri tanımlayalım:
# Text & Color Params
thickness = 2
color_black = (0,0,0)
color_red = (0,0,255)
color_green = (0,255,0)
color_white = (255,255,255)
font_scale = 0.7
font = cv2.FONT_HERSHEY_SIMPLEX
Şimdi videomuzu okuyup buna dair parametreleri tanımlayalım:
# Video Params
video_path = "video/luggage.mp4"
cap = cv2.VideoCapture(video_path)
height, width = 720, 1280
print("[INFO].. Width:", width)
print("[INFO].. Height:", height)
Yukarıdaki kod bloğunda önce videomuzu okuduk ardından videomuzun en/boy değerlerini ve toplam kare sayısını bir değişken içerisinde depoladık. Bu bize videomuzun toplam kaç kareden oluştuğunu gösterecek. Ardından modelimizi ve buna dair parametreleri tanımlayalım:
# Model Params
model_name = "models/best.pt"
model = YOLO(model_name)
counter = {}
track_history = defaultdict(lambda: [])
Artık videomuzu işlemeye hazırız. Bir while
döngüsü kurarak her bir kareyi tek tek işlemeye başlayabiliriz. Aşağıdaki kod bloğu kareleri tek tek okuyup, bant üzerinde akan bavulları saymaktadır. Bu kop bloğunu parçalar halinde düşünerek anlamaya çalışalım. Daha önce yaptığımız Object Tracking çalışmasında da benzer kodlar geliştirmiştik.
while True:
ret, frame = cap.read()
if ret == False:
break
frame = cv2.resize(frame, (width, height))
results = model.track(frame, persist=True, verbose=False)[0]
bboxes = np.array(results.boxes.data.tolist(), dtype="int") # 2.0 -> 2
cv2.line(frame, (int(width/2), 0), (int(width/2), height), color_red, thickness)
cv2.rectangle(frame, (int(width/2)+7, int(height/2)+5), (int(width/2)+175, int(height/2)-25), color_white, -1)
cv2.putText(frame, "Reference Line", (int(width/2)+10, int(height/2)), font, font_scale, color_red, thickness)
# Bagajların ortasına nokta atılacak
for box in bboxes:
x1, y1, x2, y2, track_id, score, class_id = box
text = "ID:{} LUGGAGE".format(track_id)
cx = int((x1+x2)/2)
cy = int((y1+y2)/2)
center_coordinates = (cx, cy)
if cx > int(width/2) :
cv2.circle(frame, center_coordinates, 3, color_red, -1)
cv2.rectangle(frame, (x1,y1), (x2,y2), color_red, 2)
cv2.rectangle(frame, (x1,y1), (x1+175,y1-25), color_red, -1)
cv2.putText(frame, text, (x1, y1-5), cv2.FONT_HERSHEY_SIMPLEX, 0.7, color_white, 2)
else:
cv2.circle(frame, center_coordinates, 3, color_green, -1)
cv2.rectangle(frame, (x1,y1), (x2,y2), color_green, 2)
cv2.rectangle(frame, (x1,y1), (x1+175,y1-25), color_green, -1)
cv2.putText(frame, text, (x1, y1-5), cv2.FONT_HERSHEY_SIMPLEX, 0.7, color_white, 2)
counter[track_id] = x1, y1, x2, y2
number_of_luggage = len(list(counter.keys()))
info = f"Counter: {number_of_luggage}"
cv2.rectangle(frame, (5,5), (150,40), color_white, -1)
cv2.putText(frame, info, (15,30), font, font_scale, color_red, thickness)
cv2.imshow("Object Counting", frame)
if cv2.waitKey(10) & 0xFF == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
Daha önceki object tracking blog yazımda kullandığım kodlardan farklı olarak burada bazı eklemeler olduğunu farketmişsinizdir. Şimdi farklı olan kısmı birlikte inceleyelim:
# find the center point of the objects
for box in bboxes:
x1, y1, x2, y2, track_id, score, class_id = box
text = "ID:{} LUGGAGE".format(track_id)
cx = int((x1+x2)/2)
cy = int((y1+y2)/2)
center_coordinates = (cx, cy)
if cx > int(width/2) :
cv2.circle(frame, center_coordinates, 3, color_red, -1)
cv2.rectangle(frame, (x1,y1), (x2,y2), color_red, 2)
cv2.rectangle(frame, (x1,y1), (x1+175,y1-25), color_red, -1)
cv2.putText(frame, text, (x1, y1-5), cv2.FONT_HERSHEY_SIMPLEX, 0.7, color_white, 2)
else:
cv2.circle(frame, center_coordinates, 3, color_green, -1)
cv2.rectangle(frame, (x1,y1), (x2,y2), color_green, 2)
cv2.rectangle(frame, (x1,y1), (x1+175,y1-25), color_green, -1)
cv2.putText(frame, text, (x1, y1-5), cv2.FONT_HERSHEY_SIMPLEX, 0.7, color_white, 2)
counter[track_id] = x1, y1, x2, y2
number_of_luggage = len(list(counter.keys()))
info = f"Counter: {number_of_luggage}"
cv2.rectangle(frame, (5,5), (150,40), color_white, -1)
cv2.putText(frame, info, (15,30), font, font_scale, color_red, thickness)
Burada tespit ve takip edilen nesnelerin orta noktasına for
döngüsü ile birer daire çiziliyor. Ardından gelen if-else
bloğu ise nesnenin referans çizginin sol tarafına geçip geçmediğini kontrol ediyor. Eğer nesne sol tarafa geçtiyse nesnenin rengi yeşil oluyor. Çizginin sol tarafına geçen her bir nesnenin ID
‘sini bir sözlük içerisinde depolayarak daha sonra bu nesnelerin kaç tane olduğunu hesaplatıp ekrana yazıyoruz.
3. Endüstriyel Uygulamalar
Bu blog yazısı, nesne sayımı işleminin YOLOv8 ile nasıl yapıldığını sizlere anlatmak amacıyla oluşturulmuştur. Buna benzer çalışmaları geliştirmenizi ve benimle paylaşmanızı dört gözle bekliyorum. 🚀
Son olarak, burada paylaşılan kodlar temel seviyede çalışmaları ifade etmektedir. Endüstriyel çalışmalara uygun algoritmalar geliştirmek ve sorunlarınıza hızlı bir şekilde çözüm üretmek için iletişim formu üzerinden benimle iletişime geçebilirsiniz.
Hocam bavul projesini yaptım ama ultralytics için mail atmıştım onu hallettim şimdi de lap hatası veriyor ama neden olabilir acaba
https://files.fm/u/a9zmw9s7s2
Merhaba, görünüşe göre sisteminiz lap paketini kuramamış. Ultralytics paketine gelen güncellemelerle zaman zaman bu tarz ufak tefek hatalar oluşabiliyor. Ayrı bir şekilde pip install ile lap paketini kendiniz kurabilirsiniz. Ayrıca buradaki Github tartışmasını da takip edebilirsiniz: https://github.com/ultralytics/ultralytics/issues/1625