Spaces:
Sleeping
Sleeping
add file
Browse files- Dockerfile +14 -0
- app.py +39 -0
- requirements.txt +4 -0
- ssim1.py +102 -0
- ssim1_test.py +78 -0
Dockerfile
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
|
2 |
+
# you will also find guides on how best to write your Dockerfile
|
3 |
+
|
4 |
+
FROM python:3.9
|
5 |
+
|
6 |
+
WORKDIR /code
|
7 |
+
|
8 |
+
COPY ./requirements.txt /code/requirements.txt
|
9 |
+
|
10 |
+
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
|
11 |
+
|
12 |
+
COPY . .
|
13 |
+
|
14 |
+
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "7860"]
|
app.py
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import FastAPI, File, UploadFile
|
2 |
+
from fastapi.responses import JSONResponse
|
3 |
+
import uvicorn
|
4 |
+
from ssim1 import compare_images # Import the compare_image function
|
5 |
+
|
6 |
+
import cv2
|
7 |
+
import numpy as np
|
8 |
+
|
9 |
+
app = FastAPI()
|
10 |
+
|
11 |
+
@app.post("/compare")
|
12 |
+
async def compare(image1: UploadFile = File(...), image2: UploadFile = File(...)):
|
13 |
+
try:
|
14 |
+
|
15 |
+
# Read images as binary
|
16 |
+
image1_content = await image1.read()
|
17 |
+
image2_content = await image2.read()
|
18 |
+
|
19 |
+
nparr1 = np.frombuffer(image1_content, np.uint8)
|
20 |
+
img1 = cv2.imdecode(nparr1, cv2.IMREAD_COLOR)
|
21 |
+
|
22 |
+
nparr2 = np.frombuffer(image2_content, np.uint8)
|
23 |
+
img2 = cv2.imdecode(nparr2, cv2.IMREAD_COLOR)
|
24 |
+
|
25 |
+
# Call the compare_image function. You might need to adjust this part
|
26 |
+
# depending on how compare_image is implemented in ssim1.py.
|
27 |
+
# Assuming compare_image accepts bytes and returns a similarity score or result
|
28 |
+
result = compare_images(img1, img2)
|
29 |
+
# print(result)
|
30 |
+
# Return the result as JSON
|
31 |
+
return JSONResponse(content={"result": result})
|
32 |
+
except Exception as e:
|
33 |
+
print(e)
|
34 |
+
return JSONResponse(content={"error": True})
|
35 |
+
|
36 |
+
|
37 |
+
# Run the application
|
38 |
+
if __name__ == "__main__":
|
39 |
+
uvicorn.run(app, host="127.0.0.1", port=8000)
|
requirements.txt
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
fastapi
|
2 |
+
uvicorn
|
3 |
+
opencv-python
|
4 |
+
numpy
|
ssim1.py
ADDED
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import cv2
|
2 |
+
import numpy as np
|
3 |
+
import time
|
4 |
+
|
5 |
+
# Initialize Haar Cascade face detector
|
6 |
+
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
|
7 |
+
|
8 |
+
# Function to detect and crop the face from an image
|
9 |
+
def detect_and_crop_face(image, cascade):
|
10 |
+
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
11 |
+
faces = cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
|
12 |
+
if len(faces) == 0:
|
13 |
+
return None
|
14 |
+
(x, y, w, h) = faces[0]
|
15 |
+
return image[y:y+h, x:x+w]
|
16 |
+
|
17 |
+
# Custom SSIM computation function
|
18 |
+
def compute_ssim(img1, img2):
|
19 |
+
C1 = (0.01 * 255) ** 2
|
20 |
+
C2 = (0.03 * 255) ** 2
|
21 |
+
img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
|
22 |
+
img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
|
23 |
+
img1 = cv2.resize(img1, (100, 100))
|
24 |
+
img2 = cv2.resize(img2, (100, 100))
|
25 |
+
|
26 |
+
target_file_name1 = 'compare-faces/' + ' - ' + str(time.time()) + '.jpg'
|
27 |
+
cv2.imwrite(
|
28 |
+
target_file_name1,
|
29 |
+
img1,
|
30 |
+
)
|
31 |
+
target_file_name2 = 'compare-faces/' + ' - ' + str(time.time()) + '.jpg'
|
32 |
+
cv2.imwrite(
|
33 |
+
target_file_name2,
|
34 |
+
img2,
|
35 |
+
)
|
36 |
+
|
37 |
+
mean_img1 = np.mean(img1)
|
38 |
+
mean_img2 = np.mean(img2)
|
39 |
+
var_img1 = np.var(img1)
|
40 |
+
var_img2 = np.var(img2)
|
41 |
+
std_img1 = np.sqrt(var_img1)
|
42 |
+
std_img2 = np.sqrt(var_img2)
|
43 |
+
covariance = np.mean((img1 - mean_img1) * (img2 - mean_img2))
|
44 |
+
numerator = (2 * mean_img1 * mean_img2 + C1) * (2 * covariance + C2)
|
45 |
+
denominator = (mean_img1 ** 2 + mean_img2 ** 2 + C1) * (var_img1 + var_img2 + C2)
|
46 |
+
ssim = numerator / denominator
|
47 |
+
return ssim
|
48 |
+
|
49 |
+
|
50 |
+
def compare_images(image1_path, image2_path):
|
51 |
+
# image1 = cv2.imread(image1_path)
|
52 |
+
# image2 = cv2.imread(image2_path)
|
53 |
+
|
54 |
+
image1 = image1_path
|
55 |
+
image2 = image2_path
|
56 |
+
|
57 |
+
face1 = detect_and_crop_face(image1, face_cascade)
|
58 |
+
face2 = detect_and_crop_face(image2, face_cascade)
|
59 |
+
# Results variable
|
60 |
+
result = {}
|
61 |
+
|
62 |
+
# Compare the faces if both were detected and cropped
|
63 |
+
if face1 is not None and face2 is not None:
|
64 |
+
ssim_index = compute_ssim(face1, face2)
|
65 |
+
similarity_percentage = ssim_index * 100
|
66 |
+
result["Similarity Percentage"] = similarity_percentage
|
67 |
+
result["Are Faces Similar"] = "Yes" if similarity_percentage > 50 else "No"
|
68 |
+
else:
|
69 |
+
result["Error"] = "Could not detect a face in one or both of the images. Please try with different images."
|
70 |
+
result['Photo 1'] = 'Exist' if face1 is not None else 'Not Exist'
|
71 |
+
result['Photo 2'] = 'Exist' if face2 is not None else 'Not Exist'
|
72 |
+
return result
|
73 |
+
|
74 |
+
|
75 |
+
|
76 |
+
# =================================================================
|
77 |
+
# INTERNAL TEST
|
78 |
+
# =================================================================
|
79 |
+
|
80 |
+
# # Load the images
|
81 |
+
# # Tes 1
|
82 |
+
# image1_path = './dataset/ditya/0106.png'
|
83 |
+
# image2_path = './dataset/zidni/0109.png'
|
84 |
+
|
85 |
+
# # Tes 2
|
86 |
+
# # image1_path = './dataset/rara/User.1.1.jpg'
|
87 |
+
# # image2_path = './dataset/rara/User.1.3.jpg'
|
88 |
+
|
89 |
+
# # Tes 3
|
90 |
+
# # image1_path = './dataset/ika/User.2.5.jpg'
|
91 |
+
# # image2_path = './dataset/ika/User.2.37.jpg'
|
92 |
+
|
93 |
+
# # Tes 4
|
94 |
+
# # image1_path = './dataset/rara/User.1.5.jpg'
|
95 |
+
# # image2_path = './dataset/ika/User.2.37.jpg'
|
96 |
+
|
97 |
+
# # Tes 5
|
98 |
+
# image1_path = './dataset/ditya/0104.png'
|
99 |
+
# image2_path = './dataset/ditya/0105.png'
|
100 |
+
|
101 |
+
# result = compare_images(image1_path, image2_path)
|
102 |
+
# print(result)
|
ssim1_test.py
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import random
|
3 |
+
|
4 |
+
# Assuming cosine5.py is correctly set up with a compare_images function
|
5 |
+
from ssim1 import compare_images
|
6 |
+
|
7 |
+
# Find Threshold
|
8 |
+
from findthreshold import find_best_threshold
|
9 |
+
|
10 |
+
# Path to the dataset directory
|
11 |
+
dataset_path = './dataset'
|
12 |
+
|
13 |
+
def run_test(dataset_path, iterations=10):
|
14 |
+
i = 0
|
15 |
+
r = []
|
16 |
+
|
17 |
+
for _ in range(iterations):
|
18 |
+
# Randomly decide if the images should come from the same folder or different ones
|
19 |
+
same_folder = random.choice([True, False])
|
20 |
+
|
21 |
+
# Get the list of person directories in the dataset
|
22 |
+
persons = [person for person in os.listdir(dataset_path) if os.path.isdir(os.path.join(dataset_path, person))]
|
23 |
+
|
24 |
+
if same_folder:
|
25 |
+
# Randomly select a person's directory and use it for both images
|
26 |
+
selected_person = random.choice(persons)
|
27 |
+
person_paths = [os.path.join(dataset_path, selected_person), os.path.join(dataset_path, selected_person)]
|
28 |
+
else:
|
29 |
+
# Randomly select two person's directories for the two images
|
30 |
+
selected_persons = random.sample(persons, 2) if len(persons) >= 2 else [random.choice(persons), random.choice(persons)]
|
31 |
+
person_paths = [os.path.join(dataset_path, person) for person in selected_persons]
|
32 |
+
|
33 |
+
images = []
|
34 |
+
for person_path in person_paths:
|
35 |
+
# Get the list of image files in the person's directory
|
36 |
+
person_images = [img for img in os.listdir(person_path) if os.path.isfile(os.path.join(person_path, img))]
|
37 |
+
# Randomly select an image from the person's directory
|
38 |
+
images.append(random.choice(person_images))
|
39 |
+
|
40 |
+
# Construct the full image paths
|
41 |
+
image_paths = [os.path.join(person_paths[i], images[i]) for i in range(2)]
|
42 |
+
|
43 |
+
# Compare the images and print the result
|
44 |
+
similarity_result = compare_images(image_paths[0], image_paths[1])
|
45 |
+
# print(f"Test iteration: Comparing images {images[0]} and {images[1]} {'from the same folder' if same_folder else 'from different folders'}")
|
46 |
+
# label = ''
|
47 |
+
# if same_folder: label += 'Yes - '
|
48 |
+
# else: label += 'No - '
|
49 |
+
|
50 |
+
# label += image_paths[0]
|
51 |
+
# label += ' / '
|
52 |
+
# label += image_paths[1]
|
53 |
+
# print(label)
|
54 |
+
|
55 |
+
# print(similarity_result)
|
56 |
+
# print("\n")
|
57 |
+
predict_result = 'YES' if same_folder else 'NO'
|
58 |
+
actual_result = similarity_result.get("Are Faces Similar")
|
59 |
+
error = similarity_result.get('Error')
|
60 |
+
photo_1 = similarity_result.get('Photo 1')
|
61 |
+
photo_2 = similarity_result.get('Photo 2')
|
62 |
+
|
63 |
+
score = similarity_result.get('Similarity Percentage')
|
64 |
+
|
65 |
+
label = image_paths[0] + ',' + image_paths[1] + ',' + str(photo_1) + ',' + str(photo_2) + ',' + str(score) + ',' + str(predict_result) + ',' + str(actual_result) + ',' + str(error)
|
66 |
+
print(label)
|
67 |
+
# r[i]['score_similarity'] = score
|
68 |
+
# r[i]['predict_result'] = predict_result
|
69 |
+
r.append({'score_similarity': 0 if score == None else score, 'predict_result': predict_result})
|
70 |
+
i = i+1
|
71 |
+
|
72 |
+
print(r)
|
73 |
+
best_threshold, best_accuracy = find_best_threshold(r)
|
74 |
+
print(f"Best Threshold: {best_threshold}, Best Accuracy: {best_accuracy}")
|
75 |
+
|
76 |
+
# Specify how many iterations of the test you want to run
|
77 |
+
number_of_tests = 5 # For example, 5 iterations
|
78 |
+
run_test(dataset_path, iterations=number_of_tests)
|