Update app.py
Browse files
app.py
CHANGED
@@ -27,23 +27,25 @@ project = rf.workspace(workspace).project(project_name)
|
|
27 |
yolo_model = project.version(model_version).model
|
28 |
|
29 |
# ========== Fungsi Deteksi Kombinasi ==========
|
30 |
-
|
31 |
-
# Konversi gambar PIL ke format numpy array
|
32 |
-
image_np = np.array(image)
|
33 |
-
|
34 |
-
# Resize gambar ke 640x640 tanpa mengubah warna atau format
|
35 |
-
image_resized = cv2.resize(image_np, (640, 640))
|
36 |
|
37 |
-
|
|
|
|
|
38 |
with tempfile.NamedTemporaryFile(delete=False, suffix=".jpg") as temp_file:
|
39 |
-
|
40 |
temp_path = temp_file.name
|
41 |
|
42 |
try:
|
43 |
-
#
|
|
|
|
|
|
|
|
|
|
|
44 |
yolo_pred = yolo_model.predict(temp_path, confidence=50, overlap=80).json()
|
45 |
|
46 |
-
# Hitung
|
47 |
nestle_class_count = {}
|
48 |
nestle_boxes = []
|
49 |
for pred in yolo_pred['predictions']:
|
@@ -54,13 +56,16 @@ def detect_combined(image):
|
|
54 |
total_nestle = sum(nestle_class_count.values())
|
55 |
|
56 |
# ========== [2] OWLv2: Deteksi Kompetitor ==========
|
57 |
-
headers = {
|
58 |
-
|
59 |
-
|
|
|
|
|
|
|
|
|
60 |
with open(temp_path, "rb") as f:
|
61 |
files = {"image": f}
|
62 |
response = requests.post("https://api.landing.ai/v1/tools/text-to-object-detection", files=files, data=data, headers=headers)
|
63 |
-
|
64 |
result = response.json()
|
65 |
owlv2_objects = result['data'][0] if 'data' in result else []
|
66 |
|
@@ -69,6 +74,7 @@ def detect_combined(image):
|
|
69 |
for obj in owlv2_objects:
|
70 |
if 'bounding_box' in obj:
|
71 |
bbox = obj['bounding_box'] # Format: [x1, y1, x2, y2]
|
|
|
72 |
if not is_overlap(bbox, nestle_boxes):
|
73 |
class_name = obj.get('label', 'unknown').strip().lower()
|
74 |
competitor_class_count[class_name] = competitor_class_count.get(class_name, 0) + 1
|
@@ -85,14 +91,13 @@ def detect_combined(image):
|
|
85 |
for class_name, count in nestle_class_count.items():
|
86 |
result_text += f"{class_name}: {count}\n"
|
87 |
result_text += f"\nTotal Products Nestle: {total_nestle}\n\n"
|
88 |
-
|
89 |
if competitor_class_count:
|
90 |
result_text += f"Total Unclassified Products: {total_competitor}\n"
|
91 |
else:
|
92 |
result_text += "No Unclassified Products detected\n"
|
93 |
|
94 |
# ========== [4] Visualisasi ==========
|
95 |
-
img =
|
96 |
|
97 |
# Gambar bounding box untuk produk Nestlé (Hijau)
|
98 |
for pred in yolo_pred['predictions']:
|
@@ -110,7 +115,6 @@ def detect_combined(image):
|
|
110 |
cv2.putText(img, f"{display_name} {comp['confidence']:.2f}",
|
111 |
(int(x1), int(y1 - 10)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
|
112 |
|
113 |
-
# Simpan gambar hasil deteksi
|
114 |
output_path = "/tmp/combined_output.jpg"
|
115 |
cv2.imwrite(output_path, img)
|
116 |
|
@@ -121,7 +125,6 @@ def detect_combined(image):
|
|
121 |
finally:
|
122 |
os.remove(temp_path)
|
123 |
|
124 |
-
|
125 |
def is_overlap(box1, boxes2, threshold=0.3):
|
126 |
"""
|
127 |
Fungsi untuk mendeteksi overlap bounding box.
|
@@ -254,4 +257,4 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue="teal", secondary_hue="teal", ne
|
|
254 |
outputs=[output_image, output_text]
|
255 |
)
|
256 |
|
257 |
-
iface.launch()
|
|
|
27 |
yolo_model = project.version(model_version).model
|
28 |
|
29 |
# ========== Fungsi Deteksi Kombinasi ==========
|
30 |
+
from PIL import Image
|
|
|
|
|
|
|
|
|
|
|
31 |
|
32 |
+
# Fungsi untuk deteksi dengan resize
|
33 |
+
def detect_combined(image):
|
34 |
+
# Simpan gambar input ke file sementara
|
35 |
with tempfile.NamedTemporaryFile(delete=False, suffix=".jpg") as temp_file:
|
36 |
+
image.save(temp_file, format="JPEG")
|
37 |
temp_path = temp_file.name
|
38 |
|
39 |
try:
|
40 |
+
# Resize gambar input menjadi 640x640
|
41 |
+
img = Image.open(temp_path)
|
42 |
+
img = img.resize((640, 640), Image.ANTIALIAS)
|
43 |
+
img.save(temp_path, format="JPEG")
|
44 |
+
|
45 |
+
# ========== [1] YOLO: Deteksi Produk Nestlé (Per Class) ==========
|
46 |
yolo_pred = yolo_model.predict(temp_path, confidence=50, overlap=80).json()
|
47 |
|
48 |
+
# Hitung per class Nestlé dan simpan bounding box (format: (x_center, y_center, width, height))
|
49 |
nestle_class_count = {}
|
50 |
nestle_boxes = []
|
51 |
for pred in yolo_pred['predictions']:
|
|
|
56 |
total_nestle = sum(nestle_class_count.values())
|
57 |
|
58 |
# ========== [2] OWLv2: Deteksi Kompetitor ==========
|
59 |
+
headers = {
|
60 |
+
"Authorization": "Basic " + OWLV2_API_KEY,
|
61 |
+
}
|
62 |
+
data = {
|
63 |
+
"prompts": OWLV2_PROMPTS,
|
64 |
+
"model": "owlv2"
|
65 |
+
}
|
66 |
with open(temp_path, "rb") as f:
|
67 |
files = {"image": f}
|
68 |
response = requests.post("https://api.landing.ai/v1/tools/text-to-object-detection", files=files, data=data, headers=headers)
|
|
|
69 |
result = response.json()
|
70 |
owlv2_objects = result['data'][0] if 'data' in result else []
|
71 |
|
|
|
74 |
for obj in owlv2_objects:
|
75 |
if 'bounding_box' in obj:
|
76 |
bbox = obj['bounding_box'] # Format: [x1, y1, x2, y2]
|
77 |
+
# Filter objek yang sudah terdeteksi oleh YOLO (Overlap detection)
|
78 |
if not is_overlap(bbox, nestle_boxes):
|
79 |
class_name = obj.get('label', 'unknown').strip().lower()
|
80 |
competitor_class_count[class_name] = competitor_class_count.get(class_name, 0) + 1
|
|
|
91 |
for class_name, count in nestle_class_count.items():
|
92 |
result_text += f"{class_name}: {count}\n"
|
93 |
result_text += f"\nTotal Products Nestle: {total_nestle}\n\n"
|
|
|
94 |
if competitor_class_count:
|
95 |
result_text += f"Total Unclassified Products: {total_competitor}\n"
|
96 |
else:
|
97 |
result_text += "No Unclassified Products detected\n"
|
98 |
|
99 |
# ========== [4] Visualisasi ==========
|
100 |
+
img = cv2.imread(temp_path)
|
101 |
|
102 |
# Gambar bounding box untuk produk Nestlé (Hijau)
|
103 |
for pred in yolo_pred['predictions']:
|
|
|
115 |
cv2.putText(img, f"{display_name} {comp['confidence']:.2f}",
|
116 |
(int(x1), int(y1 - 10)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
|
117 |
|
|
|
118 |
output_path = "/tmp/combined_output.jpg"
|
119 |
cv2.imwrite(output_path, img)
|
120 |
|
|
|
125 |
finally:
|
126 |
os.remove(temp_path)
|
127 |
|
|
|
128 |
def is_overlap(box1, boxes2, threshold=0.3):
|
129 |
"""
|
130 |
Fungsi untuk mendeteksi overlap bounding box.
|
|
|
257 |
outputs=[output_image, output_text]
|
258 |
)
|
259 |
|
260 |
+
iface.launch()
|