File size: 6,584 Bytes
cf1fd50
a531cbc
ebde434
a531cbc
 
900721d
a531cbc
 
900721d
ebde434
900721d
ebde434
 
900721d
 
 
ebde434
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
900721d
 
ebde434
900721d
cf1fd50
900721d
a531cbc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
900721d
a531cbc
 
 
 
900721d
ebde434
 
 
99dcd62
7926155
a531cbc
 
900721d
a531cbc
 
 
 
 
 
 
 
7926155
a531cbc
 
 
 
7926155
 
a531cbc
ebde434
 
a531cbc
7926155
900721d
7926155
 
cf1fd50
7926155
 
cf1fd50
 
 
 
 
7926155
 
 
cf1fd50
7926155
 
 
 
 
 
 
 
cf1fd50
7926155
 
 
 
 
 
 
 
 
 
cf1fd50
7926155
 
cf1fd50
7926155
 
 
 
a531cbc
7926155
a531cbc
 
 
7926155
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
900721d
 
a531cbc
 
 
ebde434
a531cbc
 
 
 
 
 
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
from flask import Flask, request, jsonify, render_template, send_file
from flask_cors import CORS
from PIL import Image, ImageDraw
import io
import json
import os
import uuid
import google.generativeai as genai

# Configuration de l'API Gemini
generation_config = {
  "temperature": 1,
  "max_output_tokens": 8192,
}

safety_settings = [
  {
    "category": "HARM_CATEGORY_HARASSMENT",
    "threshold": "BLOCK_NONE"
  },
  {
    "category": "HARM_CATEGORY_HATE_SPEECH",
    "threshold": "BLOCK_NONE"
  },
  {
    "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
    "threshold": "BLOCK_NONE"
  },
  {
    "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
    "threshold": "BLOCK_NONE"
  },
]

GOOGLE_API_KEY = os.environ.get("TOKEN") # Assurez vous que la variable d'environnement TOKEN est bien définie

genai.configure(api_key=GOOGLE_API_KEY)

app = Flask(__name__)
CORS(app)

# Prompt pour la détection d'objets
DETECTION_PROMPT = "Detect items, with no more than 20 items. Output a json list where each entry contains the 2D bounding box in \"box_2d\" and a text label in \"label\"."

# Prompt pour la description d'image satellite militaire
DESCRIPTION_PROMPT = """
Décrivez en détail cette image satellite militaire. Soyez précis et exhaustif dans votre analyse. 
Identifiez les éléments clés tels que :
- **Infrastructures** : Bâtiments, routes, ponts, aéroports, ports, etc.
- **Véhicules** : Chars, avions, navires, véhicules de transport de troupes, etc.
- **Unités militaires** : Formations de troupes, positions d'artillerie, camps, etc.
- **Défenses** : Bunkers, tranchées, barbelés, etc.
- **Éléments géographiques** : Relief, végétation, cours d'eau, etc.
- **Activités** : Mouvements de troupes, entraînements, constructions, etc.
- **Anomalies** : Tout ce qui semble inhabituel ou suspect.

Fournissez une évaluation globale de la situation et des implications stratégiques possibles.
"""

# Dossier pour enregistrer temporairement les images
UPLOAD_FOLDER = 'uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
os.makedirs(UPLOAD_FOLDER, exist_ok=True)

@app.route('/', methods=['GET'])
def svt():
    """Renders the SVT page."""
    return render_template("svt.html")

@app.route('/analyze', methods=['POST'])
def analyze_image():
    try:
        if 'file' not in request.files:
            return jsonify({'error': 'No file part'}), 400

        file = request.files['file']
        if file.filename == '':
            return jsonify({'error': 'No selected file'}), 400

        if file:
            # Générer un nom de fichier unique pour éviter les conflits
            unique_filename = str(uuid.uuid4()) + os.path.splitext(file.filename)[1]
            filename = os.path.join(app.config['UPLOAD_FOLDER'], unique_filename)
            file.save(filename)

            # 1. Détection d'objets avec Gemini
            model = genai.GenerativeModel("gemini-2.0-flash-exp",safety_settings=safety_settings,generation_config=generation_config)
            image_part = {
              "mime_type": "image/jpeg",
              "data": open(filename, "rb").read()
            }
            response = model.generate_content([DETECTION_PROMPT, image_part])

            # Nettoyer la réponse JSON en supprimant les sauts de ligne
            cleaned_response_text = response.text.replace('\n', '')

            try:
                # Enlever les ```json et ``` au début et à la fin de la chaîne
                if cleaned_response_text.startswith("```json"):
                    cleaned_response_text = cleaned_response_text[7:]
                if cleaned_response_text.endswith("```"):
                    cleaned_response_text = cleaned_response_text[:-3]
                detection_results = json.loads(cleaned_response_text)
            except json.JSONDecodeError:
                print(f"Erreur de décodage JSON : {cleaned_response_text}")
                detection_results = []  # Initialiser à une liste vide en cas d'erreur

            # 2. Dessiner les boîtes englobantes (avec gestion d'erreur)
            image = Image.open(filename)
            draw = ImageDraw.Draw(image)

            draw_success = True  # Indicateur de succès du dessin

            for item in detection_results:
                try:
                    box = item['box_2d']
                    label = item['label']

                    # Convertir la liste 'box' en tuple
                    box_tuple = tuple(box)

                    draw.rectangle(box_tuple, outline=(255, 0, 0), width=2)
                    text_position = (box[0], box[1] - 10)

                    # S'assurer que le label est une chaîne de caractère
                    label_str = str(label)

                    # Utiliser une couleur valide (blanc)
                    draw.text(text_position, label_str, fill="white")

                except Exception as e:
                    print(f"Erreur lors du dessin des boîtes ou du texte : {e}")
                    draw_success = False  # Échec du dessin
                    break  # Sortir de la boucle en cas d'erreur

            # 3. Générer la description (toujours exécuté)
            response = model.generate_content([DESCRIPTION_PROMPT, image_part])
            description = response.text

            # 4. Renvoyer les résultats
            if draw_success:
                # Enregistrer l'image avec les boîtes si le dessin a réussi
                output_filename = os.path.join(app.config['UPLOAD_FOLDER'], 'output_' + unique_filename)
                image.save(output_filename)
                return jsonify({
                    'image_path': '/uploads/' + 'output_' + unique_filename,
                    'description': description,
                    'detected_objects': detection_results
                })
            else:
                # Renvoyer la description et les résultats de détection, même si le dessin a échoué
                return jsonify({
                    'image_path': None,  # Indiquer qu'aucune image n'a été générée
                    'description': description,
                    'detected_objects': detection_results
                })

    except Exception as e:
        print(f"Une erreur s'est produite : {e}")
        return jsonify({'error': f'Erreur lors du traitement de l\'image : {e}'}), 500

# Servir les fichiers statiques depuis le dossier 'uploads'
@app.route('/uploads/<filename>')
def uploaded_file(filename):
    return send_file(os.path.join(app.config['UPLOAD_FOLDER'], filename))

if __name__ == '__main__':
    app.run(debug=True)