| 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 |
|
|
| |
| 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") |
|
|
| genai.configure(api_key=GOOGLE_API_KEY) |
|
|
| app = Flask(__name__) |
| CORS(app) |
|
|
| |
| 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\"." |
|
|
| |
| 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. |
| """ |
|
|
| |
| 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: |
| |
| unique_filename = str(uuid.uuid4()) + os.path.splitext(file.filename)[1] |
| filename = os.path.join(app.config['UPLOAD_FOLDER'], unique_filename) |
| file.save(filename) |
|
|
| |
| 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]) |
|
|
| |
| cleaned_response_text = response.text.replace('\n', '') |
|
|
| try: |
| |
| 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 = [] |
|
|
| |
| image = Image.open(filename) |
| draw = ImageDraw.Draw(image) |
|
|
| draw_success = True |
|
|
| for item in detection_results: |
| try: |
| box = item['box_2d'] |
| label = item['label'] |
|
|
| |
| box_tuple = tuple(box) |
|
|
| draw.rectangle(box_tuple, outline=(255, 0, 0), width=2) |
| text_position = (box[0], box[1] - 10) |
|
|
| |
| label_str = str(label) |
|
|
| |
| 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 |
| break |
|
|
| |
| response = model.generate_content([DESCRIPTION_PROMPT, image_part]) |
| description = response.text |
|
|
| |
| if draw_success: |
| |
| 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: |
| |
| return jsonify({ |
| 'image_path': None, |
| '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 |
|
|
| |
| @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) |