Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -13,7 +13,7 @@ mp_face_detection = mp.solutions.face_detection.FaceDetection(
|
|
| 13 |
# Initialize model and labels
|
| 14 |
@st.cache_resource
|
| 15 |
def load_model():
|
| 16 |
-
id2label = {0: 'Heart', 1: 'Oblong', 2: 'Oval', 3: 'Round', 4: 'Square'}
|
| 17 |
label2id = {v: k for k, v in id2label.items()}
|
| 18 |
|
| 19 |
model = SwinForImageClassification.from_pretrained(
|
|
@@ -25,9 +25,10 @@ def load_model():
|
|
| 25 |
|
| 26 |
model.load_state_dict(torch.load('swin.pth', map_location='cpu'))
|
| 27 |
model.eval()
|
| 28 |
-
return model, AutoFeatureExtractor.from_pretrained("microsoft/swin-tiny-patch4-window7-224")
|
| 29 |
|
| 30 |
-
model
|
|
|
|
| 31 |
|
| 32 |
glasses_recommendations = {
|
| 33 |
"Heart": "Rimless (tanpa bingkai bawah)",
|
|
@@ -44,11 +45,15 @@ def preprocess_image(image):
|
|
| 44 |
detection = results.detections[0]
|
| 45 |
bbox = detection.location_data.relative_bounding_box
|
| 46 |
h, w, _ = image.shape
|
| 47 |
-
# In the face cropping section
|
| 48 |
x1 = max(0, int(bbox.xmin * w))
|
| 49 |
y1 = max(0, int(bbox.ymin * h))
|
| 50 |
x2 = min(w, int((bbox.xmin + bbox.width) * w))
|
| 51 |
y2 = min(h, int((bbox.ymin + bbox.height) * h))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
image = image[y1:y2, x1:x2]
|
| 53 |
else:
|
| 54 |
raise ValueError("No face detected")
|
|
@@ -56,16 +61,17 @@ def preprocess_image(image):
|
|
| 56 |
image = cv2.resize(image, (224, 224))
|
| 57 |
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
| 58 |
|
| 59 |
-
# Use feature extractor with proper batching
|
| 60 |
inputs = feature_extractor(
|
| 61 |
-
images=[image],
|
| 62 |
return_tensors="pt",
|
| 63 |
-
padding=True
|
| 64 |
)
|
| 65 |
return inputs['pixel_values']
|
| 66 |
|
| 67 |
def predict_face_shape(image):
|
| 68 |
-
|
|
|
|
|
|
|
| 69 |
|
| 70 |
with torch.no_grad():
|
| 71 |
outputs = model(image_tensor)
|
|
@@ -87,6 +93,7 @@ if uploaded_file is not None:
|
|
| 87 |
|
| 88 |
try:
|
| 89 |
with st.spinner('Analyzing...'):
|
|
|
|
| 90 |
prediction = predict_face_shape(cv2.cvtColor(img_array, cv2.COLOR_RGB2BGR))
|
| 91 |
recommendation = glasses_recommendations[prediction]
|
| 92 |
|
|
|
|
| 13 |
# Initialize model and labels
|
| 14 |
@st.cache_resource
|
| 15 |
def load_model():
|
| 16 |
+
id2label = {0: 'Heart', 1: 'Oblong', 2: 'Oval', 3: 'Round', 4: 'Square'} # Moved inside load_model
|
| 17 |
label2id = {v: k for k, v in id2label.items()}
|
| 18 |
|
| 19 |
model = SwinForImageClassification.from_pretrained(
|
|
|
|
| 25 |
|
| 26 |
model.load_state_dict(torch.load('swin.pth', map_location='cpu'))
|
| 27 |
model.eval()
|
| 28 |
+
return model, AutoFeatureExtractor.from_pretrained("microsoft/swin-tiny-patch4-window7-224"), id2label # Return id2label
|
| 29 |
|
| 30 |
+
# Load model components and labels
|
| 31 |
+
model, feature_extractor, id2label = load_model() # Receive id2label here
|
| 32 |
|
| 33 |
glasses_recommendations = {
|
| 34 |
"Heart": "Rimless (tanpa bingkai bawah)",
|
|
|
|
| 45 |
detection = results.detections[0]
|
| 46 |
bbox = detection.location_data.relative_bounding_box
|
| 47 |
h, w, _ = image.shape
|
|
|
|
| 48 |
x1 = max(0, int(bbox.xmin * w))
|
| 49 |
y1 = max(0, int(bbox.ymin * h))
|
| 50 |
x2 = min(w, int((bbox.xmin + bbox.width) * w))
|
| 51 |
y2 = min(h, int((bbox.ymin + bbox.height) * h))
|
| 52 |
+
|
| 53 |
+
# Add validation check
|
| 54 |
+
if (x2 <= x1) or (y2 <= y1) or (x2 - x1 < 10) or (y2 - y1 < 10):
|
| 55 |
+
raise ValueError("Invalid face crop dimensions")
|
| 56 |
+
|
| 57 |
image = image[y1:y2, x1:x2]
|
| 58 |
else:
|
| 59 |
raise ValueError("No face detected")
|
|
|
|
| 61 |
image = cv2.resize(image, (224, 224))
|
| 62 |
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
| 63 |
|
|
|
|
| 64 |
inputs = feature_extractor(
|
| 65 |
+
images=[image],
|
| 66 |
return_tensors="pt",
|
| 67 |
+
padding=True
|
| 68 |
)
|
| 69 |
return inputs['pixel_values']
|
| 70 |
|
| 71 |
def predict_face_shape(image):
|
| 72 |
+
# Force CPU usage on Hugging Face Spaces
|
| 73 |
+
device = torch.device("cpu")
|
| 74 |
+
image_tensor = preprocess_image(image).to(device)
|
| 75 |
|
| 76 |
with torch.no_grad():
|
| 77 |
outputs = model(image_tensor)
|
|
|
|
| 93 |
|
| 94 |
try:
|
| 95 |
with st.spinner('Analyzing...'):
|
| 96 |
+
# Convert PIL image to OpenCV format correctly
|
| 97 |
prediction = predict_face_shape(cv2.cvtColor(img_array, cv2.COLOR_RGB2BGR))
|
| 98 |
recommendation = glasses_recommendations[prediction]
|
| 99 |
|