File size: 3,607 Bytes
df1b115
 
28a8a18
 
 
 
375763b
df1b115
28a8a18
 
8456c9d
28a8a18
 
9bb2f86
 
28a8a18
 
875b742
f8bd99e
375763b
 
 
f8bd99e
375763b
 
 
 
4377408
375763b
76c32f4
 
f8bd99e
bb22818
d7fbded
82da095
4546572
82da095
4546572
bb22818
 
4546572
28a8a18
bb22818
28a8a18
 
bb22818
 
 
 
 
 
 
375763b
bb22818
 
 
 
375763b
bb22818
 
 
 
 
28a8a18
bb22818
 
 
 
28a8a18
 
bb22818
 
 
 
375763b
bb22818
 
 
 
ddcdb0f
bb22818
 
28a8a18
9bb2f86
 
 
 
 
bb22818
9bb2f86
82da095
9bb2f86
 
 
 
bb22818
 
 
 
 
 
28a8a18
 
 
bb22818
 
82da095
76c32f4
28a8a18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import numpy as np
import pandas as pd
import gradio as gr
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
import json
import cv2
from ultralytics import YOLO

# ======================= МОДЕЛЬ ===================================
model = YOLO("yolov11m_best.pt")

# ================== ЧТЕНИЕ НАЗВАНИЙ И ЦЕН =======================
with open('Fruit_Veggies_Price.json', 'r', encoding='utf-8') as file:
    fruits_data = json.load(file)

# =========================== ДЕТЕКЦИЯ ПЛОДА ============================
def detect_fruit(image):
    # Считываем изображение
    # Предполагается, что image - это объект PIL Image
    image_cv = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
    
    # Выполняем детекцию
    detections = model.predict(source=image_cv, conf=0.5)

    # Проверка на наличие детекций
    if len(detections) == 0:
        return image

    result_np_image = detections[0].plot()
    result_np_image = cv2.cvtColor(result_np_image, cv2.COLOR_BGR2RGB)

    detected_fruit = None

    print(model.names)
    for det in detections:
        print(det)
        label = model.names[int(det[5])]  # название фрукта
        if label in fruits_data:
            detected_fruit = label
            break

    return result_np_image, detected_fruit

# =========================== ЧЕК ============================
def create_receipt(detected_fruit, weight):
    data = fruits_data[detected_fruit];
    fruit_name = data['name']
    price = data['price_per_kg']
    total_price = round(price * weight, 2)
    receipt_img = Image.new("RGB", (300, 200), color="white")
    draw = ImageDraw.Draw(receipt_img)

    try:
        font = ImageFont.truetype("arial.ttf", 18)
    except IOError:
        font = ImageFont.load_default()

    draw.text((10, 10), "Чек", fill="black", font=font)
    draw.text((10, 50), f"Продукт: {fruit_name}", fill="black", font=font)
    draw.text((10, 80), f"Вес: {weight} кг", fill="black", font=font)
    draw.text((10, 110), f"Цена за кг: {price} руб.", fill="black", font=font)
    draw.text((10, 140), f"Сумма: {total_price} руб.", fill="black", font=font)

    with BytesIO() as output:
        receipt_img.save(output, format="PNG")
        output.seek(0)
        return output.getvalue()

# ======================= ИНТЕРФЕЙС ============================
def gradio_interface(image, weight):
    if weight <= 0:
        gr.Info('Укажите вес товара')
        return None, None

    result_np_image, detected_fruit = detect_fruit(image)
    if not fruit_name:
        gr.Info('Не удалось определить товар')
        return result_np_image, None
        
    receipt = create_receipt(detected_fruit, weight)
    return result_np_image, receipt

image_input = gr.Image(
    label="Изображение",
    width=640,
    height=480
)
weight_input = gr.Number(label="Вес (кг)")
image_output = gr.Image(
    label="Распознанный товар",
    type="numpy",
    width=640,
    height=480
)
receipt_output = gr.Image(
    label="Чек",
    type="numpy",
    width=640,
    height=480
)

gr.Interface(
    fn=gradio_interface,
    inputs=[image_input, weight_input],
    outputs=[image_output, receipt_output],
    title="Определение товара и создание чека",
    description="Загрузите изображение, введите вес и получите чек"
).launch()