Загрузка...

Python
Bot for analysis of the image by photo, based on yolov11

Thread in Your projects created by awaw Sep 12, 2025. (bumped Sep 13, 2025) 457 views

  1. awaw
    awaw Topic starter Sep 12, 2025 ну купи парсер чатов тг lolz.live/threads/9046721 11,294 Oct 8, 2017
    Сделано на базе YOLOv11. Обнаруживает и подсчитывает объекты на фото - людей, авто, животных, и тд. Сделано было чисто ради изучения и не несёт какой-то пользы, НО с помощью YOLO можно делать много реально интересных вещей при должных знаниях.
    YOLO (You Only Look Once) — система обнаружения объектов в реальном времени, разработанная Джозефом Редмоном и Али Фархади в 2015 году. Название означает «вы смотрите только один раз» — алгоритм обрабатывает всё изображение за один проход, в отличие от традиционных методов, которые анализируют каждый объект по отдельности.

    Как работает:
    Запускаете, открываете любую картину, выдаёт готовый результат. Результаты хранятся в корневой папке output.
    Так же сделал бота для ознакомления, чтобы вам ничего не устанавливать.
    Telegram: ANALISOBJ613246_BOT - заходите, нажимаете /start, отправляете картинку
    1. Для начала нужен Python, я использовал Python 3.10
    2. Нужно установить зависимости - pip install ultralytics tkinterdnd2 tkinter torch pillow
    3. Сам код:
    Python
    import tkinter as tk
    from tkinter import filedialog, messagebox, ttk
    from PIL import Image, ImageTk, ImageGrab
    import os
    import time
    import uuid
    import sys
    import re

    try:
    from tkinterdnd2 import DND_FILES, TkinterDnD
    DND_AVAILABLE = True
    except Exception:
    DND_AVAILABLE = False

    try:
    from ultralytics import YOLO
    HAS_ULTRALYTICS = True
    except Exception:
    YOLO = None
    HAS_ULTRALYTICS = False

    try:
    import torch
    HAS_TORCH = True
    except Exception:
    HAS_TORCH = False

    yolo_model = None
    MODEL_NAME = "yolo11n.pt"
    OUTPUT_DIR = "output"
    ALLOWED_EXT = ('.jpg', '.jpeg', '.png', '.bmp', '.gif', '.webp')

    current_output_path = None
    display_original_pil = None
    zoom_factor = 1.0

    ANIMAL_CLASSES = {"bird","cat","dog","bear","cow"}

    def ensure_output_dir():
    os.makedirs(OUTPUT_DIR, exist_ok=True)
    testfile = os.path.join(OUTPUT_DIR, ".write_test")
    try:
    with open(testfile, "w", encoding="utf-8") as f:
    f.write("ok")
    os.remove(testfile)
    except Exception as e:
    raise RuntimeError(f"")

    def lazy_load_model():
    global yolo_model
    if yolo_model is not None:
    return
    if not HAS_ULTRALYTICS:
    raise RuntimeError("")
    try:
    yolo_model = YOLO(MODEL_NAME)
    except Exception as e:
    raise RuntimeError(f"ошибка загрузки модели '{MODEL_NAME}': {e}")

    def analyze_image(image_path):
    ensure_output_dir()
    lazy_load_model()

    try:
    img = Image.open(image_path).convert("RGB")
    except Exception as e:
    raise RuntimeError(f"ошибка при загрузке '{image_path}': {e}")

    try:
    results = yolo_model(image_path)
    except Exception as e:
    raise RuntimeError(f"ошибка модели: {e}")

    COCO_CLASSES = getattr(yolo_model, "names", None) or {}
    people_count = 0
    vehicle_count = 0
    animals = {}

    for result in results:
    boxes = getattr(result, "boxes", None)
    if boxes is None:
    continue
    for box in boxes:
    try:
    cls_id = int(box.cls[0].item())
    except Exception:
    continue
    cls_name = COCO_CLASSES.get(cls_id, str(cls_id)).lower()
    if cls_name == "person":
    people_count += 1
    elif cls_name in ("car","truck","bus","motorcycle"):
    vehicle_count += 1
    elif cls_name in ANIMAL_CLASSES:
    animals[cls_name] = animals.get(cls_name, 0) + 1

    timestamp = time.strftime("%Y%m%d_%H%M%S")
    uniq = uuid.uuid4().hex[:8]
    save_path = os.path.join(OUTPUT_DIR, f"result_{timestamp}_{uniq}.jpg")
    try:
    results[0].save(filename=save_path)
    except Exception:
    img.save(save_path)

    return save_path, people_count, vehicle_count, animals

    def update_display_image():
    global display_original_pil, zoom_factor, current_display_photo
    if display_original_pil is None:
    return
    max_w = max(100, app.winfo_width() - 60)
    max_h = max(100, app.winfo_height() - 160)
    w, h = display_original_pil.size
    tw = int(w * zoom_factor)
    th = int(h * zoom_factor)
    if tw > max_w or th > max_h:
    scale = min(max_w / tw, max_h / th)
    tw = max(1, int(tw * scale))
    th = max(1, int(th * scale))
    img_resized = display_original_pil.resize((tw, th), Image.LANCZOS)
    photo = ImageTk.PhotoImage(img_resized)
    image_label.config(image=photo)
    image_label.image = photo
    current_display_photo = photo

    def display_image(path):
    global display_original_pil, zoom_factor
    try:
    img = Image.open(path).convert("RGB")
    except Exception as e:
    messagebox.showerror("ошибка", f"не удалось открыть файфл: {e}")
    return
    display_original_pil = img
    zoom_factor = 1.0
    update_display_image()

    def process_image(path):
    global current_output_path
    info_text.set("анализ")
    app.update_idletasks()
    try:
    save_path, people_count, vehicle_count, animals = analyze_image(path)
    except Exception as e:
    messagebox.showerror("ошибка при анализе", str(e))
    info_text.set("ошибка")
    return
    current_output_path = save_path
    display_image(save_path)
    animals_text = ", ".join(f"{k}({v})" for k,v in animals.items()) if animals else "-"
    info_text.set(f"людей: {people_count} авто: {vehicle_count} животные: {animals_text}")
    print(f"сохранено в {save_path}")

    def open_file():
    path = filedialog.askopenfilename(filetypes=[("Images", "*.jpg;*.jpeg;*.png;*.bmp;*.gif;*.webp")])
    if path:
    process_image(path)

    def parse_dnd_paths(data_str):
    parts = re.findall(r'{([^}]*)}', data_str)
    if not parts:
    parts = data_str.split()
    return parts

    def paste_clipboard(event=None):
    try:
    cb = ImageGrab.grabclipboard()
    except Exception as e:
    messagebox.showerror("ошибка", f"буфер обмена пуст {e}")
    return
    if isinstance(cb, Image.Image):
    try:
    ensure_output_dir()
    temp_path = os.path.join(OUTPUT_DIR, f"clipboard_{int(time.time()*1000)}.png")
    cb.save(temp_path)
    process_image(temp_path)
    except Exception as e:
    messagebox.showerror("ошибка", f"не удалось сохранить изображение из буфера: {e}")
    elif isinstance(cb, list) and cb:
    first = cb[0]
    if isinstance(first, str) and os.path.isfile(first):
    process_image(first)
    else:
    messagebox.showinfo("ошибка")
    elif isinstance(cb, str) and os.path.isfile(cb):
    process_image(cb)
    else:
    try:
    txt = app.clipboard_get()
    if txt and os.path.isfile(txt.strip()):
    process_image(txt.strip())
    return
    except Exception:
    pass
    messagebox.showinfo("буфер обмена пуст")

    def drop_file(event):
    paths = parse_dnd_paths(event.data)
    if not paths:
    return
    first = paths[0]
    if os.path.isfile(first) and first.lower().endswith(ALLOWED_EXT):
    process_image(first)
    else:
    messagebox.showinfo("Drag&Drop", "файл не найден/не является поддерживаемым форматом")

    def close_image(event=None):
    global display_original_pil, current_output_path
    image_label.config(image="")
    image_label.image = None
    display_original_pil = None
    current_output_path = None
    info_text.set("закрыто")

    def on_mouse_wheel(event):
    global zoom_factor
    delta = 0
    if hasattr(event, "delta") and event.delta:
    delta = event.delta
    elif event.num == 4:
    delta = 120
    elif event.num == 5:
    delta = -120
    if delta > 0:
    zoom_factor *= 1.1
    else:
    zoom_factor /= 1.1
    zoom_factor = max(0.1, min(10.0, zoom_factor))
    update_display_image()

    def self_check():
    msgs = []
    if not HAS_ULTRALYTICS:
    msgs.append("ultralytics не установлен - pip install -U ultralytics")
    if not HAS_TORCH:
    msgs.append("torch не найден")
    try:
    ensure_output_dir()
    except Exception as e:
    msgs.append(str(e))
    if msgs:
    messagebox.showwarning("проблемы:\n\n" + "\n".join(msgs))
    return False
    try:
    lazy_load_model()
    except Exception as e:
    messagebox.showwarning("модель YOLOv11", f"не загрузилась новая модель '{MODEL_NAME}':\n{e}\n")
    return True

    #интерфейс
    if DND_AVAILABLE:
    app = TkinterDnD.Tk()
    else:
    app = tk.Tk()

    app.title("анализ объектов YOLOv11")
    app.configure(bg="#2b2b2b")
    try:
    app.state("zoomed")
    except Exception:
    pass

    style = ttk.Style(app)
    style.configure("TButton", font=("Arial", 12))

    top_frame = tk.Frame(app, bg="#2b2b2b")
    top_frame.pack(fill="x", pady=8)

    open_btn = ttk.Button(top_frame, text="открыть картинку", command=open_file)
    open_btn.pack(side="left", padx=10)

    close_btn = ttk.Button(top_frame, text="закрыть", command=close_image)
    close_btn.pack(side="left", padx=10)

    info_text = tk.StringVar(value="загрузить, через drag&drop или выбрать из папки")
    info_label = tk.Label(top_frame, textvariable=info_text, fg="white", bg="#2b2b2b", font=("Arial", 12))
    info_label.pack(side="left", padx=20)

    canvas_frame = tk.Frame(app, bg="#1f1f1f")
    canvas_frame.pack(fill="both", expand=True, padx=10, pady=10)

    image_label = tk.Label(canvas_frame, bg="#1f1f1f")
    image_label.pack(expand=True)

    app.bind_all("<Control-v>", paste_clipboard)
    app.bind_all("<Control-V>", paste_clipboard)
    app.bind_all("<Control-w>", close_image)
    app.bind_all("<Control-W>", close_image)

    if DND_AVAILABLE:
    try:
    image_label.drop_target_register(DND_FILES)
    image_label.dnd_bind("<<Drop>>", drop_file)
    except Exception as e:
    print("ошибка DND", e)

    _ok = self_check()
    if not _ok:
    print("")

    app.mainloop()
    [IMG]
     
  2. OPTIMISED
    OPTIMISED Sep 15, 2025
    Маркетплейс игровых товаров и скинов | DIP-X
    5,904 Apr 29, 2017
    Бот мертв
     
    1. awaw Topic starter
      avatarOPTIMISED , снова жив. я за пк сижу - бот жив, ухожу - умирает
Loading...