fahadcr14 commited on
Commit
89a78a7
·
1 Parent(s): 7badc4e
Files changed (4) hide show
  1. README.md +0 -11
  2. app.py +106 -0
  3. requirements.txt +5 -0
  4. templates/index.html +114 -0
README.md DELETED
@@ -1,11 +0,0 @@
1
- ---
2
- title: Faceshapedetector
3
- emoji: 📈
4
- colorFrom: gray
5
- colorTo: yellow
6
- sdk: docker
7
- pinned: false
8
- short_description: face shape detector model
9
- ---
10
-
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
app.py ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import requests
3
+ from flask import Flask, render_template, request, jsonify
4
+ from werkzeug.utils import secure_filename
5
+ import torch
6
+ import torchvision.transforms as T
7
+ from PIL import Image
8
+ import torch.nn.functional as F # For softmax
9
+
10
+ # Initialize Flask app
11
+ app = Flask(__name__)
12
+
13
+ # Define device
14
+ device = "cuda" if torch.cuda.is_available() else "cpu"
15
+
16
+ # Model and transformation setup
17
+ def download_model_if_not_exists(url, model_path):
18
+ """Download model from Hugging Face repository if it doesn't exist locally."""
19
+ if not os.path.exists(model_path):
20
+ print("Model not found locally, downloading from Hugging Face...")
21
+ response = requests.get(url)
22
+ if response.status_code == 200:
23
+ with open(model_path, 'wb') as f:
24
+ f.write(response.content)
25
+ print(f"Model downloaded and saved to {model_path}")
26
+ else:
27
+ print("Failed to download model. Please check the URL.")
28
+ else:
29
+ print("Model already exists locally.")
30
+
31
+ def load_model(model_path):
32
+ """Load model from the given path."""
33
+ model = torch.load(model_path, map_location=torch.device('cpu'))
34
+ model.eval() # Set model to evaluation mode
35
+ model.to(device)
36
+ return model
37
+
38
+ def preprocess_image(image_path):
39
+ transform = T.Compose([
40
+ T.Resize((224, 224)), # Resize image to 224x224
41
+ T.ToTensor(), # Convert image to Tensor
42
+ T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) # Normalize
43
+ ])
44
+ image = Image.open(image_path).convert("RGB") # Open and convert image to RGB
45
+ return transform(image).unsqueeze(0) # Add batch dimension
46
+
47
+ def get_probabilities(logits):
48
+ """Apply softmax to get probabilities."""
49
+ probabilities = F.softmax(logits, dim=1)
50
+ percentages = probabilities * 100
51
+ return percentages
52
+
53
+ def predict(image_path, model, class_names):
54
+ """Make prediction using the trained model."""
55
+ image_tensor = preprocess_image(image_path).to(device)
56
+ model.eval()
57
+ with torch.inference_mode(): # Disable gradient calculations
58
+ outputs = model(image_tensor)
59
+ percentages = get_probabilities(outputs)
60
+ _, predicted_class = torch.max(outputs, 1) # Get the index of the highest logit
61
+ predicted_label = class_names[predicted_class.item()]
62
+ return predicted_label, percentages
63
+
64
+ # Define class names
65
+ class_names = ['Heart', 'Oblong', 'Oval', 'Round', 'Square']
66
+
67
+ # Path to the model file
68
+ model_path = r"model_85_nn_.pth" # Update this with the correct model path
69
+ model_url = "https://huggingface.co/fahd9999/model_85_nn_/resolve/main/model_85_nn_.pth?download=true"
70
+
71
+ # Download the model only if it doesn't exist locally
72
+ download_model_if_not_exists(model_url, model_path)
73
+
74
+ # Load the model
75
+ model = load_model(model_path)
76
+
77
+ # API to render the index page
78
+ @app.route('/')
79
+ def index():
80
+ return render_template('index.html')
81
+
82
+ # API to handle image upload and prediction
83
+ @app.route('/predict', methods=['POST'])
84
+ def predict_face_shape():
85
+ if 'file' not in request.files:
86
+ return jsonify({'error': 'No file part'})
87
+
88
+ file = request.files['file']
89
+ if file.filename == '':
90
+ return jsonify({'error': 'No selected file'})
91
+
92
+ if file:
93
+ os.makedirs('uploads',exist_ok=True)
94
+ filename = secure_filename(file.filename)
95
+ file_path = os.path.join('uploads', filename)
96
+ file.save(file_path)
97
+
98
+ predicted_label, percentages = predict(file_path, model, class_names)
99
+
100
+ result = {class_names[i]: percentages[0, i].item() for i in range(len(class_names))}
101
+ sorted_result = dict(sorted(result.items(), key=lambda item: item[1], reverse=True))
102
+ print(sorted_result)
103
+ return jsonify(sorted_result)
104
+
105
+ if __name__ == '__main__':
106
+ app.run(debug=False)
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Flask==3.0.3
2
+ Werkzeug==3.0.2
3
+ torch==2.5.1
4
+ torchvision==0.20.1
5
+ Pillow==10.3.0
templates/index.html ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Face Shape Detection</title>
7
+ <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ </head>
10
+ <body class="bg-gray-100">
11
+
12
+ <!-- Navbar -->
13
+ <nav class="bg-blue-600 text-white p-4 flex justify-between items-center">
14
+ <div class="text-lg font-bold">Face Shape Detect</div>
15
+ <div class="space-x-4">
16
+ <a href="#" class="hover:text-gray-300">Detect</a>
17
+ <a href="#" class="hover:text-gray-300">Blog</a>
18
+ <a href="#" class="hover:text-gray-300">About Us</a>
19
+ </div>
20
+ </nav>
21
+
22
+ <!-- Hero Section -->
23
+ <section class="hero bg-blue-500 text-white text-center py-16">
24
+ <h1 class="text-4xl font-semibold">Detect Your Face Shape with AI</h1>
25
+ <p class="mt-4 text-xl">Upload an image and let AI detect your face shape.</p>
26
+ </section>
27
+
28
+ <!-- Upload Section -->
29
+ <section class="upload-section text-center py-16">
30
+ <h2 class="text-3xl font-semibold">Upload Your Image</h2>
31
+ <input type="file" id="file-upload" class="mt-4 p-2 border rounded" />
32
+ <button onclick="uploadImage()" class="mt-4 bg-blue-600 text-white p-2 rounded">Upload and Detect</button>
33
+ </section>
34
+
35
+ <!-- Result Section -->
36
+ <section id="result-section" class="hidden py-16">
37
+ <h2 class="text-3xl font-semibold text-center">Detection Results</h2>
38
+ <!-- Display top result as heading -->
39
+ <h3 id="top-shape" class="text-2xl font-semibold text-center mt-4"></h3>
40
+ <p id="top-percentage" class="text-xl text-center mt-2"></p>
41
+ <div id="result-container" class="mt-8 max-w-xl mx-auto"></div>
42
+ </section>
43
+
44
+ <!-- Workflow Cards -->
45
+ <section class="workflow py-16 bg-gray-200">
46
+ <div class="text-center">
47
+ <h2 class="text-3xl font-semibold">How It Works</h2>
48
+ </div>
49
+ <div class="flex justify-around mt-8">
50
+ <div class="card p-6 bg-white shadow-lg rounded-lg max-w-xs">
51
+ <h3 class="text-xl font-semibold">Upload Image</h3>
52
+ <p>Choose an image from your device to upload.</p>
53
+ </div>
54
+ <div class="card p-6 bg-white shadow-lg rounded-lg max-w-xs">
55
+ <h3 class="text-xl font-semibold">AI Process</h3>
56
+ <p>Our AI, trained on 100 million faces, processes your image.</p>
57
+ </div>
58
+ <div class="card p-6 bg-white shadow-lg rounded-lg max-w-xs">
59
+ <h3 class="text-xl font-semibold">Get Your Face Shape</h3>
60
+ <p>Our AI returns the most accurate prediction with up to 99.9% accuracy.</p>
61
+ </div>
62
+ </div>
63
+ </section>
64
+
65
+ <!-- Footer -->
66
+ <footer class="bg-blue-600 text-white text-center py-4">
67
+ <p>&copy; 2024 Face Shape Detect. All rights reserved.</p>
68
+ </footer>
69
+
70
+ <script>
71
+ function uploadImage() {
72
+ const fileInput = document.getElementById('file-upload');
73
+ const formData = new FormData();
74
+ formData.append('file', fileInput.files[0]);
75
+
76
+ axios.post('/predict', formData)
77
+ .then(response => {
78
+ const resultContainer = document.getElementById('result-container');
79
+ resultContainer.innerHTML = '';
80
+ const result = response.data;
81
+
82
+ // Sort the results in descending order
83
+ const sortedResult = Object.entries(result).sort((a, b) => b[1] - a[1]);
84
+
85
+ // Get the highest percentage result
86
+ const [topShape, topPercentage] = sortedResult[0];
87
+ document.getElementById('top-shape').innerText = `Your face shape is: ${topShape}`;
88
+ document.getElementById('top-percentage').innerText = `${topPercentage.toFixed(2)}%`;
89
+
90
+ // Loop through the sorted result and create progress bars
91
+ sortedResult.forEach(([key, value]) => {
92
+ let progressBar = `
93
+ <div class="mb-4">
94
+ <span class="text-lg">${key}: ${value.toFixed(2)}%</span>
95
+ <div class="w-full bg-gray-300 rounded-full h-2">
96
+ <div class="bg-green-500 h-2" style="width: ${value}%"></div>
97
+ </div>
98
+ </div>
99
+ `;
100
+ resultContainer.innerHTML += progressBar;
101
+ });
102
+
103
+ // Show result section
104
+ document.getElementById('result-section').classList.remove('hidden');
105
+ })
106
+ .catch(error => {
107
+ console.error('Error uploading image:', error);
108
+ });
109
+ }
110
+ </script>
111
+
112
+
113
+ </body>
114
+ </html>