huggingkhalil commited on
Commit
1a192ff
·
verified ·
1 Parent(s): 3b47e1f

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +150 -0
app.py ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+ import gradio as gr
4
+ from PIL import Image
5
+
6
+ def detect_shapes(image):
7
+ """
8
+ Detect shapes in an image and return the annotated result
9
+ """
10
+ # Convert PIL Image to OpenCV format
11
+ img = np.array(image)
12
+ img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
13
+
14
+ # Create a copy for drawing contours
15
+ img_contour = img.copy()
16
+
17
+ # Convert to grayscale
18
+ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
19
+
20
+ # Apply Gaussian blur
21
+ blur = cv2.GaussianBlur(gray, (5, 5), 1)
22
+
23
+ # Edge detection
24
+ edges = cv2.Canny(blur, 50, 150)
25
+
26
+ # Find contours
27
+ contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
28
+
29
+ shapes_detected = []
30
+
31
+ # Process each contour
32
+ for cnt in contours:
33
+ area = cv2.contourArea(cnt)
34
+ if area > 500: # Filter small contours
35
+ # Approximate contour to polygon
36
+ epsilon = 0.02 * cv2.arcLength(cnt, True)
37
+ approx = cv2.approxPolyDP(cnt, epsilon, True)
38
+
39
+ # Get bounding rectangle
40
+ x, y, w, h = cv2.boundingRect(approx)
41
+
42
+ # Determine shape based on number of vertices
43
+ nb_sommets = len(approx)
44
+ shape = "Indéfini"
45
+
46
+ if nb_sommets == 3:
47
+ shape = "Triangle"
48
+ elif nb_sommets == 4:
49
+ ratio = w / float(h)
50
+ shape = "Carré" if 0.95 < ratio < 1.05 else "Rectangle"
51
+ elif nb_sommets > 6:
52
+ shape = "Cercle"
53
+
54
+ # Draw contour and label
55
+ cv2.drawContours(img_contour, [approx], 0, (0, 255, 0), 2)
56
+ cv2.putText(img_contour, shape, (x, y - 10),
57
+ cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
58
+
59
+ shapes_detected.append({
60
+ 'shape': shape,
61
+ 'vertices': nb_sommets,
62
+ 'area': int(area),
63
+ 'position': f"({x}, {y})"
64
+ })
65
+
66
+ # Convert back to RGB for display
67
+ img_contour = cv2.cvtColor(img_contour, cv2.COLOR_BGR2RGB)
68
+
69
+ # Create summary text
70
+ summary = f"Détecté {len(shapes_detected)} forme(s):\n"
71
+ for i, shape_info in enumerate(shapes_detected, 1):
72
+ summary += f"{i}. {shape_info['shape']} - {shape_info['vertices']} sommets - Aire: {shape_info['area']} pixels\n"
73
+
74
+ return img_contour, summary
75
+
76
+ # Create Gradio interface
77
+ def create_interface():
78
+ with gr.Blocks(title="Détecteur de Formes Géométriques", theme=gr.themes.Soft()) as interface:
79
+ gr.Markdown("# 🔍 Détecteur de Formes Géométriques")
80
+ gr.Markdown("Téléchargez une image pour détecter et identifier les formes géométriques (triangles, carrés, rectangles, cercles)")
81
+
82
+ with gr.Row():
83
+ with gr.Column():
84
+ input_image = gr.Image(
85
+ type="pil",
86
+ label="📸 Image d'entrée",
87
+ height=400
88
+ )
89
+
90
+ detect_btn = gr.Button(
91
+ "🔍 Détecter les formes",
92
+ variant="primary",
93
+ size="lg"
94
+ )
95
+
96
+ gr.Markdown("### Instructions:")
97
+ gr.Markdown("""
98
+ - Téléchargez une image contenant des formes géométriques
99
+ - Les formes doivent être suffisamment grandes (aire > 500 pixels)
100
+ - Fonctionne mieux avec des formes aux contours nets
101
+ - Supporte: triangles, carrés, rectangles, cercles
102
+ """)
103
+
104
+ with gr.Column():
105
+ output_image = gr.Image(
106
+ label="🎯 Formes détectées",
107
+ height=400
108
+ )
109
+
110
+ output_text = gr.Textbox(
111
+ label="📊 Résumé de détection",
112
+ lines=8,
113
+ max_lines=15
114
+ )
115
+
116
+ # Examples section
117
+ gr.Markdown("### 📝 Exemples")
118
+ gr.Examples(
119
+ examples=[
120
+ # You can add example images here if you have them
121
+ # ["path/to/example1.jpg"],
122
+ # ["path/to/example2.jpg"],
123
+ ],
124
+ inputs=input_image,
125
+ label="Cliquez sur un exemple pour le tester"
126
+ )
127
+
128
+ # Event handlers
129
+ detect_btn.click(
130
+ fn=detect_shapes,
131
+ inputs=input_image,
132
+ outputs=[output_image, output_text]
133
+ )
134
+
135
+ input_image.change(
136
+ fn=detect_shapes,
137
+ inputs=input_image,
138
+ outputs=[output_image, output_text]
139
+ )
140
+
141
+ return interface
142
+
143
+ # Launch the app
144
+ if __name__ == "__main__":
145
+ interface = create_interface()
146
+ interface.launch(
147
+ share=True,
148
+ server_name="0.0.0.0",
149
+ server_port=7860
150
+ )