تشخیص اشیاء با YOLO و پایتون

پروژه‌های بینایی کامپیوتر

پروژه ۷ دقیقه مطالعه
فهرست مطالب
این مطلب از سایت tool.hamidvalad.ir گرفته شده است

معرفی YOLO؛ مدلی برای تشخیص آنی اشیاء

تشخیص اشیا یکی از مهم‌ترین و کاربردی‌ترین بخش‌های بینایی ماشین و هوش مصنوعی است. اگر تا چند سال پیش این کار تنها در اختیار آزمایشگاه‌های تخصصی و مدل‌های پیچیده بود، امروز با ظهور YOLO (مخفف You Only Look Once) این امکان فراهم شده که حتی با یک سیستم خانگی و تنها چند خط کد، بتوانید اشیا را در تصاویر یا ویدیوها شناسایی کنید.

YOLO برخلاف بسیاری از مدل‌های قدیمی که تصویر را چندین بار تحلیل می‌کردند، در یک نگاه کل تصویر را پردازش می‌کند. این یعنی سرعت بسیار بالا، بدون افت دقت. امروز نسخه‌های پیشرفته‌تری مانند YOLOv8 با پشتیبانی شرکت Ultralytics منتشر شده که بهینه‌تر، سریع‌تر و دقیق‌تر از نسخه‌های قبلی عمل می‌کنند.

چیزی که YOLO را منحصربه‌فرد می‌کند، توانایی آن در ترکیب سه ویژگی مهم است:

1. تشخیص دقیق اشیاء
2. سرعت بسیار بالا (Real-Time Detection)
3. سادگی در استفاده برای برنامه‌نویسان

به همین دلیل، از این مدل در کاربردهای مختلف استفاده می‌شود:

• سیستم‌های امنیتی و تشخیص چهره
• کنترل ترافیک و شناسایی خودروها
• رباتیک و هدایت ربات‌ها
• تشخیص اشیاء داخل انبار
• مدیریت خطوط تولید در کارخانه
• پردازش و آنالیز تصاویر پزشکی
و حتی پروژه‌های کوچک دانشجویی که قرار است قابلیت تشخیص شیء داشته باشند.

کتابخانه‌های مورد نیاز برای ساخت برنامه تشخیص اشیاء

برای ساخت یک برنامه دسکتاپ ساده که عکس ورودی را گرفته و اشیای داخل آن را تشخیص دهد، به چند کتابخانه کلیدی نیاز داریم:

Ultralytics (YOLO)
این کتابخانه مدل رسمی YOLOv8 را ارائه می‌کند و تمام مراحل پردازش، تشخیص، خروجی‌گیری و حتی رسم باکس‌ها را به‌صورت خودکار انجام می‌دهد.

OpenCV
برای کارهایی مثل:
• خواندن تصویر
• ذخیره‌سازی خروجی
• رسم Bound Box
• کار با فرمت‌های مختلف تصویر
از این کتابخانه استفاده می‌کنیم.

Pillow (PIL)
این کتابخانه برای نمایش تصویر داخل رابط گرافیکی، تغییر اندازه و ساخت پیش‌نمایش کاربرد دارد.

Tkinter / CustomTkinter
این بخش مسئول ساخت رابط گرافیکی برنامه است. یعنی همان پنجره‌ای که:
• عکس انتخاب می‌کنیم
• دکمه "تشخیص" می‌زنیم
• خروجی اشیا را مشاهده می‌کنیم
استفاده از CustomTkinter باعث زیباتر شدن رابط کاربری می‌شود.

روش نصب کتابخانه‌ها

نصب تمام ابزار مورد نیاز بسیار ساده است. کافی است دستورهای زیر را وارد کنید:

pip install ultralytics
pip install opencv-python
pip install pillow
pip install customtkinter

بعد از نصب، تنها کاری که باید بکنید این است که مدل YOLO را فراخوانی کنید:

from ultralytics import YOLO
model = YOLO("yolov8n.pt")

مدل YOLOv8n سبک‌ترین نسخه است و برای اکثر پروژه‌ها مناسب می‌باشد.

کد اصلی

import customtkinter as ctk
from tkinter import filedialog
from ultralytics import YOLO
from PIL import Image, ImageTk
import cv2
import os

ctk.set_appearance_mode("dark")
ctk.set_default_color_theme("blue")

class YOLOApp(ctk.CTk):

    def __init__(self):
        super().__init__()

        self.title("YOLO Object Detection - Fatemeh")
        self.geometry("700x800")

        self.model = YOLO("yolov8n.pt")
        self.image_path = None
        self.result_image = None

        # ------------------ عنوان ------------------
        self.label_title = ctk.CTkLabel(self, text="تشخیص اشیا با YOLO", font=("IRANSans", 22))
        self.label_title.pack(pady=15)

        # ------------------ دکمه انتخاب عکس ------------------
        self.btn_browse = ctk.CTkButton(self, text="انتخاب تصویر", command=self.open_image)
        self.btn_browse.pack(pady=10)

        # ------------------ نمایش عکس ------------------
        self.image_label = ctk.CTkLabel(self, text="")
        self.image_label.pack(pady=10)

        # ------------------ دکمه شروع تشخیص ------------------
        self.btn_detect = ctk.CTkButton(self, text="شروع تشخیص با YOLO", command=self.detect, state="disabled")
        self.btn_detect.pack(pady=10)

        # ------------------ نمایش خروجی اشیا ------------------
        self.result_label = ctk.CTkLabel(self, text="", font=("IRANSans", 16), justify="center")
        self.result_label.pack(pady=20)

    # ------------------ انتخاب تصویر ------------------
    def open_image(self):
        path = filedialog.askopenfilename(
            filetypes=[("Image Files", "*.jpg *.png *.jpeg *.webp")]
        )

        if path:
            self.image_path = path
            self.show_preview(path)
            self.result_label.configure(text="")
            self.btn_detect.configure(state="normal")

    # ------------------ نمایش تصویر در UI ------------------
    def show_preview(self, path):
        img = Image.open(path)
        img.thumbnail((400, 400))
        self.tk_img = ImageTk.PhotoImage(img)
        self.image_label.configure(image=self.tk_img)

    # ------------------ شروع تشخیص با YOLO ------------------
    def detect(self):
        if not self.image_path:
            return

        results = self.model.predict(self.image_path)

        # خروجی برای نوشتن در UI
        detected_objects = []

        # پردازش نتایج
        for result in results:
            for box in result.boxes:
                cls = int(box.cls[0])
                label = result.names[cls]
                detected_objects.append(label)

        # اگر چیزی پیدا نشد
        if not detected_objects:
            self.result_label.configure(text="❌ هیچ شیئی شناسایی نشد!")
        else:
            unique_items = ", ".join(set(detected_objects))
            self.result_label.configure(text=f"✔ اشیای تشخیص داده شده:\n{unique_items}")

        # کشیدن باکس‌ها روی عکس
        annotated = results[0].plot()

        save_path = "detected_yolo.jpg"
        cv2.imwrite(save_path, annotated)

        # نمایش عکس با باکس‌ها
        final_img = Image.open(save_path)
        final_img.thumbnail((400, 400))
        self.tk_img = ImageTk.PhotoImage(final_img)
        self.image_label.configure(image=self.tk_img)

if __name__ == "__main__":
    app = YOLOApp()
    app.mainloop()

نکات مهم کد YOLO + CustomTkinter

بارگذاری مدل YOLO
self.model = YOLO("yolov8n.pt")
• مدل yolov8n سبک‌ترین نسخه YOLOv8 است.
• سرعت بالا ولی دقت متوسط دارد.
• اگر دقت بیشتری بخواهی می‌توانی از yolov8s.pt یا yolov8m.pt استفاده کنی.
• مدل در زمان اجرای برنامه فقط یک‌بار بارگذاری می‌شود (بهینه).

مدیریت انتخاب فایل
filedialog.askopenfilename(...)
• فقط اجازه انتخاب فرمت‌های تصویری را می‌دهد.
• اگر کاربر کنسل کند، برنامه نمی‌ریزد.
• بعد از انتخاب عکس:
o پیش‌نمایش نمایش داده می‌شود
o متن قبلی حذف می‌شود
o دکمه "شروع تشخیص" فعال می‌شود

نمایش پیش‌نمایش تصویر
img.thumbnail((400, 400))
• تصویر را کوچک می‌کند تا UI سنگین نشود و برنامه هنگ نکند.
• استفاده از Pillow برای نمایش داخل Tkinter لازم است.
• تصویر به صورت PhotoImage ذخیره می‌شود تا از بین نرود.

اجرای YOLO و پردازش نتایج
results = self.model.predict(self.image_path)
• مدل روی تصویر اجرا می‌شود.
• خروجی results شامل:
o باکس‌ها
o کلاس‌ها
o نام اشیا
o احتمال‌ها
o نسخه Annotated تصویر

استخراج کلاس‌ها (اشیا) از نتایج
for result in results:
for box in result.boxes:
cls = int(box.cls[0])
label = result.names[cls]
• result.boxes شامل خروجی تمام bounding box‌هاست.
• Cls شماره کلاس است.
• result.names دیکشنری شامل نام اشیا است.
• همه نام‌ها در یک لیست ذخیره می‌شود.
نکته مهم:
کد همه اشیا را جمع می‌کند اما بعداً فقط unique آنها را نمایش می‌دهد.

نمایش نتیجه در UI
if not detected_objects:
...
else:
unique_items = ", ".join(set(detected_objects))
• اگر YOLO هیچ شیئی پیدا نکرد → پیام خطا
• اگر پیدا کرد → لیست اشیا نمایش داده می‌شود
• استفاده از set باعث حذف تکراری‌ها می‌شود

کشیدن باکس‌ها روی تصویر
annotated = results[0].plot()
cv2.imwrite("detected_yolo.jpg", annotated)
• YOLO خودش باکس می‌کشد (color + thickness).
• خروجی تصویر به صورت فایل ذخیره می‌شود.
• دوباره با Pillow خوانده می‌شود تا داخل Tkinter نشان داده شود.
این کار باعث می‌شود UI خراب نشود.

طراحی UI با CustomTkinter
نکات مهم UI:
• ctk.CTkLabel برای متن
• ctk.CTkButton برای دکمه‌ها
• مود تاریک dark برای ظاهر بهتر
• ساختار برنامه در قالب یک کلاس (OOP) کاملاً درست و اصولی

مدیریت State دکمه‌ها
self.btn_detect.configure(state="disabled")
• دکمه تشخیص تا وقتی عکس انتخاب نشود غیرفعال است.
• این موضوع باعث جلوگیری از خطاهای احتمالی می‌شود.

ذخیره و نمایش تصویر خروجی
• فایل خروجی همیشه با نام detected_yolo.jpg ذخیره می‌شود
• اگر بخواهی می‌توانی زمان یا نام فایل اصلی را به خروجی اضافه کنی تا روی هم نیفتد

مقیاس‌بندی تصویر خروجی
final_img.thumbnail((400, 400))
برای اینکه UI سنگین نشود و عکس بزرگ از صفحه نزند بیرون.

جلوگیری از کرش شدن Tkinter
self.tk_img = ImageTk.PhotoImage(...)
self.image_label.configure(image=self.tk_img)
• نگه داشتن PhotoImage به صورت self ضروری است
• اگر لوکال باشد garbage collected می‌شود و عکس ناپدید می‌شود
• این یک نکته کلیدی کار با Tkinter است

جمع‌بندی نکات مهم

• استفاده درست از YOLOv8 برای تشخیص اشیا
• پردازش صحیح خروجی مدل (boxes – names)
• نمایش حرفه‌ای اشیای تشخیص داده‌شده
• کشیدن باکس‌های YOLO به روش درست
• کنترل وضعیت دکمه‌ها
• نمایش پیش‌نمایش قبل و بعد از تشخیص
• معماری شی‌گرا و تمیز
• جلوگیری از کرش با نگه‌داشتن PhotoImage
• سازگار با همه فرمت‌های تصویری مرسوم

نتیجه‌گیری

در مجموع، برنامه‌ای که با ترکیب YOLOv8، OpenCV، Pillow و CustomTkinter ساخته شده، یک نمونه‌ی کامل و قابل‌اعتماد از پیاده‌سازی تشخیص اشیای هوشمند در محیط دسکتاپ است. این پروژه نشان می‌دهد که چطور می‌توان یک مدل قدرتمند هوش مصنوعی را با یک رابط کاربری سبک و قابل فهم ترکیب کرد تا نتیجه‌ای تولید شود که هم از نظر فنی قابل توسعه است و هم از نظر تجربه کاربری کاربردی و روان.

استفاده از YOLOv8 باعث می‌شود موتور اصلی برنامه قادر باشد طیف وسیعی از اشیا را با سرعت بالا و دقت مناسب شناسایی کند، حتی با نسخه سبک yolov8n. همچنین OpenCV وظیفه‌ی تجسم نتایج را برعهده دارد و باکس‌هایی که روی تصویر کشیده می‌شوند، خروجی پردازش را برای کاربر ملموس‌تر می‌کنند. در کنار این‌ها، استفاده از Pillow برای پیش‌نمایش تصاویر و CustomTkinter برای ساخت یک محیط ظاهراً مدرن و حرفه‌ای، باعث شده برنامه شکل نهایی جذاب و کاربرپسندی پیدا کند.

این پروژه اثبات می‌کند که برای ساخت یک ابزار کاربردی و قابل ارائه، نیازی به پیچیدگی بیش‌ازحد نیست؛ فقط باید کتابخانه‌های مناسب ترکیب شوند و جریان منطقی بین انتخاب تصویر، اجرای تشخیص، نمایش نتیجه و ارائه خروجی برقرار شود.

این ساختار نه‌تنها برای افراد مبتدی قابل فهم است، بلکه برای توسعه‌دهندگان حرفه‌ای نیز یک پایه مناسب برای پروژه‌های پیشرفته‌تر مثل سیستم‌های مانیتورینگ، امنیتی، شناسایی محصول و پردازش خودکار تصاویر محسوب می‌شود.

در نهایت، این پروژه یک نمونه عملی از قدرت ترکیب AI + GUI است؛ جایی که هوش مصنوعی تصمیم می‌گیرد و رابط کاربری، آن را به شکلی ساده، زیبا و قابل استفاده به کاربر نمایش می‌دهد. این ساختار نه‌تنها قابل توسعه است بلکه می‌تواند به شکل مستقیم در پروژه‌های تجاری و واقعی مورد استفاده قرار گیرد.