File size: 3,046 Bytes
b4b4df5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import streamlit as st
from ultralytics import YOLO
from PIL import Image, ImageDraw, ImageFont
import io

# Tải mô hình YOLOv8
@st.cache_resource
def load_model():
    return YOLO("best.pt")  # Đảm bảo bạn đã có file best.pt trong thư mục làm việc

model = load_model()

# Tiêu đề của ứng dụng
st.title("Ứng Dụng Phát Hiện Sâu Răng với YOLOv8")

# Mô tả ngắn
st.write("""
Tải lên hình ảnh hoặc chụp hình bằng camera để hệ thống tự động phát hiện sâu răng và hiển thị các bounding boxes.
""")

# Tùy chọn tải lên hoặc chụp hình
option = st.radio("Chọn phương thức nhập hình ảnh:", ("Tải lên từ máy tính", "Chụp hình bằng camera"))

uploaded_file = None

if option == "Tải lên từ máy tính":
    uploaded_file = st.file_uploader("Chọn hình ảnh", type=["jpg", "jpeg", "png"])
elif option == "Chụp hình bằng camera":
    camera_file = st.camera_input("Chụp hình bằng camera")
    if camera_file:
        uploaded_file = camera_file

if uploaded_file is not None:
    # Hiển thị hình ảnh gốc
    image = Image.open(uploaded_file).convert("RGB")
    st.image(image, caption='Hình ảnh đã tải lên', use_container_width=True)

    # Phát hiện đối tượng
    with st.spinner("Đang phát hiện sâu răng..."):
        results = model.predict(image)

    # Lấy kết quả đầu tiên
    result = results[0]

    # Tạo đối tượng vẽ trên hình
    draw = ImageDraw.Draw(image)
    font = ImageFont.load_default()

    # Danh sách bounding boxes
    boxes = []

    for box in result.boxes:
        x1, y1, x2, y2 = [int(coord) for coord in box.xyxy[0]]
        class_id = int(box.cls[0].item())
        confidence = round(box.conf[0].item(), 2)

        # Nếu chỉ phát hiện lớp 0 (sâu răng)
        if class_id != 0:
            continue

        label = result.names[class_id]
        boxes.append([x1, y1, x2, y2, label, confidence])

        # Vẽ bounding box
        draw.rectangle([x1, y1, x2, y2], outline="red", width=3)

        # Vẽ nhãn và độ tin cậy
        text = f"{label} {confidence}"
        text_bbox = draw.textbbox((0, 0), text, font=font)
        text_size = (text_bbox[2] - text_bbox[0], text_bbox[3] - text_bbox[1])
        draw.rectangle([x1, y1 - text_size[1], x1 + text_size[0], y1], fill="red")
        draw.text((x1, y1 - text_size[1]), text, fill="white", font=font)

    # Hiển thị hình ảnh với bounding boxes
    st.image(image, caption='Hình ảnh sau khi phát hiện', use_container_width=True)

    # Hiển thị bảng kết quả
    if boxes:
        st.subheader("Kết Quả Phát Hiện")
        # Tạo DataFrame để hiển thị bảng đẹp hơn
        import pandas as pd
        df = pd.DataFrame(boxes, columns=["X1", "Y1", "X2", "Y2", "Loại Đối Tượng", "Độ Tin Cậy"])
        st.table(df)
    else:
        st.write("Không phát hiện sâu răng nào trong hình ảnh này.")