JIT
Professional anpr frontend
can you make my frontend and backend more professional my html is <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Real-Time Pakistani ANPR System</title> <link rel="stylesheet" href="style.css"> <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap" rel="stylesheet"> </head> <body> <div class="container"> <h1 class="title">Real-Time Pakistani Number Plate Detection System</h1> <p class="subtitle">Intelligent ANPR for Pakistani Vehicles – Detect, Read, and Log in Real-Time</p> <div class="car-gallery"> <div class="car-card"> <img src="https://images.unsplash.com/photo-1502877338535-766e1452684a?w=800" alt="Pakistani Car 1"> </div> <div class="car-card"> <img src="https://images.unsplash.com/photo-1503376780353-7e6692767b70?w=800" alt="Pakistani Car 2"> </div> </div> <div class="upload-section"> <form id="uploadForm" enctype="multipart/form-data"> <label for="fileInput" class="upload-label"> <div class="upload-box"> <span class="upload-icon">📷</span> <p>Drag & Drop or Click to Upload Image/Video</p> <p class="small">Supported: JPG, PNG, JFIF, MP4, AVI</p> </div> </label> <input type="file" id="fileInput" name="file" accept="image/*,video/*" hidden> <button type="submit" id="detectBtn">Detect & Read Plate</button> </form> <div id="loading" class="loading hidden"> <div class="spinner"></div> <p>Processing... Please wait</p> </div> </div> <div id="result" class="result hidden"> <h2>Detection Result</h2> <p id="textResult"></p> <p id="confResult"></p> <div class="result-images"> <img id="annotatedImg" alt="Annotated Image"> <img id="croppedImg" alt="Cropped Plate"> </div> <button id="copyTextBtn">Copy Plate Text</button> </div> </div> <script src="script.js"></script> </body> </html> my css is * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Poppins', sans-serif; background: linear-gradient(135deg, #667eea, #764ba2); color: #333; min-height: 100vh; padding: 20px; } .container { max-width: 1000px; margin: 0 auto; background: rgba(255, 255, 255, 0.95); padding: 40px; border-radius: 20px; box-shadow: 0 20px 40px rgba(0,0,0,0.2); text-align: center; } .title { font-size: 2.8em; color: #1a237e; margin-bottom: 10px; animation: fadeInDown 1.2s ease-out; } .subtitle { font-size: 1.2em; color: #555; margin-bottom: 40px; opacity: 0; animation: fadeInUp 1.2s ease-out 0.5s forwards; } .car-gallery { display: flex; justify-content: center; gap: 20px; margin-bottom: 50px; flex-wrap: wrap; } .car-card { width: 300px; overflow: hidden; border-radius: 15px; box-shadow: 0 10px 20px rgba(0,0,0,0.1); transition: transform 0.3s ease; } .car-card:hover { transform: translateY(-10px); } .car-card img { width: 100%; height: 200px; object-fit: cover; transition: transform 0.5s ease; } .car-card:hover img { transform: scale(1.1); } .upload-section { margin-bottom: 40px; } .upload-label { display: block; cursor: pointer; } .upload-box { border: 3px dashed #667eea; border-radius: 15px; padding: 60px 20px; background: #f8f9ff; transition: all 0.3s ease; } .upload-box:hover { background: #e8f0ff; border-color: #764ba2; } .upload-icon { font-size: 3em; margin-bottom: 10px; } button { background: linear-gradient(135deg, #667eea, #764ba2); color: white; border: none; padding: 15px 40px; font-size: 1.1em; border-radius: 50px; cursor: pointer; margin-top: 20px; transition: all 0.3s ease; } button:hover { transform: translateY(-3px); box-shadow: 0 10px 20px rgba(102, 126, 234, 0.4); } .result { background: white; padding: 30px; border-radius: 15px; box-shadow: 0 10px 30px rgba(0,0,0,0.1); } .result-images { display: flex; gap: 20px; justify-content: center; margin: 20px 0; } .result-images img { max-width: 45%; border-radius: 10px; box-shadow: 0 5px 15px rgba(0,0,0,0.1); } .loading { display: flex; flex-direction: column; align-items: center; margin: 40px 0; } .spinner { width: 50px; height: 50px; border: 5px solid #f3f3f3; border-top: 5px solid #667eea; border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @keyframes fadeInDown { from { opacity: 0; transform: translateY(-30px); } to { opacity: 1; transform: translateY(0); } } @keyframes fadeInUp { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } } /* Existing style code here... */ .loading { margin-top: 30px; display: none; flex-direction: column; align-items: center; } .loading.hidden { display: none; } .spinner { width: 50px; height: 50px; border: 5px solid #f3f3f3; border-top: 5px solid #27ae60; border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .loading-message { margin-top: 15px; font-size: 1.2em; color: #27ae60; animation: pulse 1.5s infinite; } @keyframes pulse { 0% { opacity: 1; } 50% { opacity: 0.5; } 100% { opacity: 1; } } .result { background: #ecf0f1; padding: 20px; border-radius: 8px; margin-top: 30px; } .result.hidden { display: none; } .result p { font-size: 1.1em; margin-bottom: 15px; } and my js is document.getElementById('uploadForm').addEventListener('submit', async function(e) { e.preventDefault(); const formData = new FormData(this); const resultDiv = document.getElementById('result'); const loadingDiv = document.getElementById('loading'); loadingDiv.classList.remove('hidden'); resultDiv.classList.add('hidden'); try { const response = await fetch('/predict', { method: 'POST', body: formData }); const data = await response.json(); loadingDiv.classList.add('hidden'); if (data.error) { resultDiv.innerHTML = `<p style="color:red;">Error: ${data.error}</p>`; } else { resultDiv.innerHTML = ` <h2>Detection Result</h2> <p><strong>Detected Plate Text:</strong> ${data.text || 'N/A'}</p> <p><strong>Detection Confidence:</strong> ${data.confidence.toFixed(2)}%</p> <div class="result-images"> <img src="${data.annotated_image}" alt="Annotated Image"> <img src="${data.cropped_image}" alt="Cropped Plate"> </div> `; } resultDiv.classList.remove('hidden'); } catch (error) { loadingDiv.classList.add('hidden'); resultDiv.innerHTML = `<p style="color:red;">Failed to connect to server.</p>`; resultDiv.classList.remove('hidden'); } }); and my app/py is from flask import Flask, request, jsonify, send_from_directory from flask_cors import CORS from ultralytics import YOLO import cv2 import easyocr import os import time import csv from werkzeug.utils import secure_filename import base64 app = Flask(__name__, static_folder='../frontend', static_url_path='') CORS(app) # Connection error khatam # Model load (absolute path) project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) model_path = os.path.join(project_root, "backend", "models", "best.pt") model = YOLO(model_path) # EasyOCR reader = easyocr.Reader(['en'], gpu=False) # Folders UPLOAD_FOLDER = "uploads" DETECTED_FOLDER = "detected_images" CROPPED_FOLDER = "saved_plates" os.makedirs(UPLOAD_FOLDER, exist_ok=True) os.makedirs(DETECTED_FOLDER, exist_ok=True) os.makedirs(CROPPED_FOLDER, exist_ok=True) LOG_FILE = "plates_log.csv" if not os.path.exists(LOG_FILE): with open(LOG_FILE, "w", newline="") as f: writer = csv.writer(f) writer.writerow(["Timestamp", "Original_Image", "Annotated_Image", "Cropped_Plate", "YOLO_Confidence", "OCR_Text", "OCR_Confidence"]) app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER @app.route('/') def home(): return send_from_directory(app.static_folder, 'index.html') @app.route('/predict', methods=['POST']) def predict(): try: if 'file' not in request.files: return jsonify({"error": "No file uploaded"}), 400 file = request.files['file'] if file.filename == '': return jsonify({"error": "No file selected"}), 400 filename = secure_filename(file.filename) file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) file.save(file_path) # ✅ ALWAYS CONVERT TO JPG (supports .jfif, .avif, .webp etc.) img = cv2.imread(file_path) if img is None: return jsonify({"error": "Invalid or unsupported image format"}), 400 # New filename as .jpg new_filename = os.path.splitext(filename)[0] + '.jpg' new_file_path = os.path.join(app.config['UPLOAD_FOLDER'], new_filename) cv2.imwrite(new_file_path, img) # Delete original if different if new_file_path != file_path: os.remove(file_path) file_path = new_file_path filename = new_filename # YOLO detection results = model(file_path, conf=0.5) # Annotated image save and base64 annotated_filename = f"annotated_{filename}" annotated_path = os.path.join(DETECTED_FOLDER, annotated_filename) results[0].save(annotated_path) with open(annotated_path, "rb") as f: annotated_base64 = base64.b64encode(f.read()).decode('utf-8') # Crop and OCR ocr_text = "N/A" ocr_conf = 0.0 cropped_base64 = "" for box in results[0].boxes: if int(box.cls) == 0: yolo_conf = float(box.conf) x1, y1, x2, y2 = map(int, box.xyxy[0]) plate_crop = img[y1:y2, x1:x2] timestamp = int(time.time()) cropped_filename = f"plate_crop_{timestamp}.jpg" cropped_path = os.path.join(CROPPED_FOLDER, cropped_filename) cv2.imwrite(cropped_path, plate_crop) with open(cropped_path, "rb") as f: cropped_base64 = base64.b64encode(f.read()).decode('utf-8') # OCR plate_gray = cv2.cvtColor(plate_crop, cv2.COLOR_BGR2GRAY) ocr_result = reader.readtext(plate_gray) if ocr_result: ocr_text = ocr_result[0][1].upper().replace(" ", "") ocr_conf = ocr_result[0][2] # CSV log with open(LOG_FILE, "a", newline="") as f: writer = csv.writer(f) writer.writerow([time.strftime("%Y-%m-%d %H:%M:%S"), file_path, annotated_path, cropped_path, yolo_conf, ocr_text, ocr_conf]) break return jsonify({ "text": ocr_text, "confidence": round(ocr_conf * 100, 2), "annotated_image": f"data:image/jpeg;base64,{annotated_base64}", "cropped_image": f"data:image/jpeg;base64,{cropped_base64}" if cropped_base64 else "" }) except Exception as e: print(f"Error: {str(e)}") return jsonify({"error": str(e)}), 500 @app.route('/<path:filename>') def serve_static(filename): return send_from_directory(app.static_folder, filename) if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=5000) plzz make the frorntend more professional

I'll help you make your frontend more professional. Let me first read your current files to understand the structure, then provide improvements.

Read file
Read file
Read file

Let me check the current directory structure to understand your project layout:

Let me check if there are any files in the directory:

I notice the file listing isn't showing any files. Let me try a different approach to find your files:

Let me try reading the files with different approaches:

Read file

I see the issue - the files aren't in the current directory. Since you've provided the code content, I'll create professional versions of your frontend files. Let me start by creating a more professional HTML structure:

Write file
Write file
Write file
Professional frontend redesign with modern UI/UX
v1