Final Commit
|
|
@ -0,0 +1,3 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PyPep8Inspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<option name="ignoredErrors">
|
||||
<list>
|
||||
<option value="W292" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3.12 (tectcrime)" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (tectcrime)" project-jdk-type="Python SDK" />
|
||||
<component name="PyCharmProfessionalAdvertiser">
|
||||
<option name="shown" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/tectcrime.iml" filepath="$PROJECT_DIR$/.idea/tectcrime.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
from flask import Flask, request, jsonify, make_response
|
||||
import numpy as np
|
||||
import cv2
|
||||
from skimage.feature import local_binary_pattern
|
||||
import os
|
||||
from joblib import load
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
def extract_lbp_features(image, radius=1, n_points=8, method='uniform'):
|
||||
lbp = local_binary_pattern(image, n_points, radius, method)
|
||||
(hist, _) = np.histogram(lbp.ravel(), bins=np.arange(0, n_points + 3), range=(0, n_points + 2))
|
||||
# Normalize the histogram
|
||||
hist = hist.astype("float")
|
||||
hist /= (hist.sum() + 1e-7)
|
||||
return hist
|
||||
|
||||
|
||||
# Mendapatkan path lengkap ke file facemodel.joblib
|
||||
model_path = os.path.join(os.path.dirname(__file__), 'facemodel.joblib')
|
||||
# Memuat model dari file
|
||||
knn_model = load(model_path)
|
||||
|
||||
|
||||
@app.route('/classify', methods=['POST'])
|
||||
def classify_face():
|
||||
# Mendapatkan gambar dari request
|
||||
file = request.files['image']
|
||||
|
||||
# Membaca gambar
|
||||
image_bytes = file.read()
|
||||
original_image = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), cv2.IMREAD_COLOR)
|
||||
|
||||
gray_image = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY)
|
||||
gray_image = cv2.equalizeHist(gray_image)
|
||||
|
||||
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
|
||||
faces = face_cascade.detectMultiScale(gray_image, scaleFactor=1.2, minNeighbors=10, minSize=(50, 50))
|
||||
|
||||
predictions = []
|
||||
lbp_features = []
|
||||
|
||||
for i, (x, y, w, h) in enumerate(faces, 1):
|
||||
cropped_face = original_image[y:y + h, x:x + w]
|
||||
resized_face = cv2.resize(cropped_face, (100, 100))
|
||||
gray_resized_face = cv2.cvtColor(resized_face, cv2.COLOR_BGR2GRAY)
|
||||
normalized_face = cv2.normalize(gray_resized_face, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX)
|
||||
test_lbp_features = extract_lbp_features(normalized_face, radius=1, n_points=8, method='uniform')
|
||||
lbp_features.append(test_lbp_features.tolist())
|
||||
predicted_class = knn_model.predict([test_lbp_features])[0]
|
||||
predictions.append(predicted_class) # Hanya menambahkan kelas prediksi
|
||||
|
||||
response = make_response(jsonify(predictions))
|
||||
response.headers['X-LBP-Features'] = str(lbp_features)
|
||||
return response
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True)
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
import numpy as np
|
||||
import cv2
|
||||
from skimage.feature import local_binary_pattern
|
||||
import joblib
|
||||
|
||||
# Load the trained model from file
|
||||
knn_model = joblib.load('facemodel.joblib')
|
||||
|
||||
def extract_lbp_features(image, radius=1, n_points=8, method='uniform'):
|
||||
lbp = local_binary_pattern(image, n_points, radius, method)
|
||||
(hist, _) = np.histogram(lbp.ravel(), bins=np.arange(0, n_points + 3), range=(0, n_points + 2))
|
||||
# Normalize the histogram
|
||||
hist = hist.astype("float")
|
||||
hist /= (hist.sum() + 1e-7)
|
||||
return hist
|
||||
|
||||
# Fungsi untuk deteksi wajah dan cropping
|
||||
def detect_and_crop_faces(image_path):
|
||||
# Baca gambar
|
||||
original_image = cv2.imread(image_path)
|
||||
gray_image = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY)
|
||||
|
||||
# Peningkatan kontras
|
||||
gray_image = cv2.equalizeHist(gray_image)
|
||||
|
||||
# Muat pre-trained Haar Cascade untuk deteksi wajah
|
||||
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
|
||||
|
||||
# Deteksi wajah pada gambar dengan parameter yang disesuaikan
|
||||
faces = face_cascade.detectMultiScale(gray_image, scaleFactor=1.4, minNeighbors=6, minSize=(50, 50))
|
||||
|
||||
# Cek jumlah wajah yang terdeteksi
|
||||
print(f'{image_path}: {len(faces)} face(s) detected')
|
||||
|
||||
# Loop melalui setiap wajah yang terdeteksi, potong, dan tampilkan
|
||||
for i, (x, y, w, h) in enumerate(faces, 1):
|
||||
# Pemotongan (Cropping) wajah
|
||||
cropped_face = original_image[y:y + h, x:x + w]
|
||||
|
||||
# # Tampilkan gambar wajah yang terpotong
|
||||
# cv2.imshow(f'Cropped Face {i}', cropped_face)
|
||||
#
|
||||
# # Tunggu 1 detik sebelum menampilkan gambar berikutnya
|
||||
# cv2.waitKey(1000)
|
||||
|
||||
return faces
|
||||
|
||||
# Path ke gambar wajah uji
|
||||
test_image_path = 'images/testface/Alia Bhatt/Alia Bhatt_77.jpg'
|
||||
|
||||
# Deteksi wajah dan cropping pada gambar uji
|
||||
test_faces = detect_and_crop_faces(test_image_path)
|
||||
|
||||
# Loop melalui setiap wajah yang terdeteksi di gambar uji
|
||||
for i, (x, y, w, h) in enumerate(test_faces, 1):
|
||||
# Pemotongan (Cropping) wajah
|
||||
cropped_test_face = cv2.imread(test_image_path)[y:y + h, x:x + w]
|
||||
|
||||
# Resize gambar menjadi 100x100 piksel
|
||||
resized_test_face = cv2.resize(cropped_test_face, (100, 100))
|
||||
|
||||
# Konversi gambar resized ke grayscale
|
||||
gray_resized_test_face = cv2.cvtColor(resized_test_face, cv2.COLOR_BGR2GRAY)
|
||||
|
||||
# Normalisasi intensitas
|
||||
normalized_test_face = cv2.normalize(gray_resized_test_face, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX)
|
||||
|
||||
# Ekstraksi fitur LBP untuk gambar uji
|
||||
test_lbp_features = extract_lbp_features(normalized_test_face, radius=1, n_points=8, method='uniform')
|
||||
|
||||
# Tampilkan nilai ekstraksi LBP ke konsol
|
||||
print(f'LBP Features for face: {test_lbp_features}')
|
||||
|
||||
# Prediksi kelas menggunakan model K-NN
|
||||
predicted_class = knn_model.predict([test_lbp_features])[0]
|
||||
|
||||
# Tampilkan hasil prediksi
|
||||
print(f'Predicted class for face {i}: {predicted_class}')
|
||||
|
||||
# Tunggu sampai tombol ditekan dan tutup jendela
|
||||
cv2.waitKey(0)
|
||||
cv2.destroyAllWindows()
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
import cv2
|
||||
|
||||
# Membaca gambar asli
|
||||
original_image = cv2.imread('images/backup/testface/Akshay Kumar/Akshay Kumar_40.jpg')
|
||||
cv2.imshow('Original Image', original_image)
|
||||
|
||||
# Mengonversi gambar ke grayscale
|
||||
gray_image = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY)
|
||||
cv2.imshow('Grayscale Image', gray_image)
|
||||
|
||||
# Meningkatkan kontras gambar grayscale
|
||||
contrastpic = cv2.equalizeHist(gray_image)
|
||||
cv2.imshow('Contrast Enhanced Image', contrastpic)
|
||||
|
||||
# Memuat classifier Haar Cascade untuk deteksi wajah
|
||||
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
|
||||
|
||||
# Mendeteksi wajah dalam gambar grayscale
|
||||
faces = face_cascade.detectMultiScale(gray_image, scaleFactor=1.2, minNeighbors=10, minSize=(50, 50))
|
||||
|
||||
# Inisialisasi variabel cropped_face dengan nilai kosong
|
||||
cropped_face = None
|
||||
|
||||
for i, (x, y, w, h) in enumerate(faces, 1):
|
||||
# Memotong wajah dari gambar asli
|
||||
cropped_face = original_image[y:y + h, x:x + w]
|
||||
cv2.imshow(f'Cropped Face {i}', cropped_face)
|
||||
|
||||
# Mengubah ukuran wajah terpotong
|
||||
if cropped_face is not None:
|
||||
resized_face = cv2.resize(cropped_face, (300, 300))
|
||||
cv2.imshow('Resized Face', resized_face)
|
||||
|
||||
# Mengonversi wajah yang diubah ukurannya ke grayscale
|
||||
gray_resized_face = cv2.cvtColor(resized_face, cv2.COLOR_BGR2GRAY)
|
||||
cv2.imshow('Grayscale Resized Face', gray_resized_face)
|
||||
|
||||
# Melakukan normalisasi pada wajah grayscale yang diubah ukurannya
|
||||
normalized_face = cv2.normalize(gray_resized_face, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX)
|
||||
cv2.imshow('Normalized Face', normalized_face)
|
||||
|
||||
cv2.waitKey(0)
|
||||
cv2.destroyAllWindows()
|
||||
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 108 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 153 KiB |
|
After Width: | Height: | Size: 206 KiB |
|
After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 136 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 304 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 224 KiB |
|
After Width: | Height: | Size: 264 KiB |
|
After Width: | Height: | Size: 284 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 108 KiB |
|
After Width: | Height: | Size: 372 KiB |
|
After Width: | Height: | Size: 302 KiB |
|
After Width: | Height: | Size: 166 KiB |
|
After Width: | Height: | Size: 166 KiB |
|
After Width: | Height: | Size: 140 KiB |
|
After Width: | Height: | Size: 130 KiB |
|
After Width: | Height: | Size: 382 KiB |
|
After Width: | Height: | Size: 298 KiB |
|
After Width: | Height: | Size: 210 KiB |
|
After Width: | Height: | Size: 111 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 188 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 260 KiB |
|
After Width: | Height: | Size: 505 KiB |
|
After Width: | Height: | Size: 728 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 944 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 136 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 189 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 83 KiB |
|
After Width: | Height: | Size: 154 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 284 KiB |
|
After Width: | Height: | Size: 340 KiB |
|
After Width: | Height: | Size: 826 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 105 KiB |
|
After Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 267 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 306 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 2.1 MiB |
|
After Width: | Height: | Size: 395 KiB |
|
After Width: | Height: | Size: 968 KiB |
|
After Width: | Height: | Size: 89 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 523 KiB |
|
After Width: | Height: | Size: 557 KiB |
|
After Width: | Height: | Size: 148 KiB |
|
After Width: | Height: | Size: 633 KiB |
|
After Width: | Height: | Size: 88 KiB |
|
After Width: | Height: | Size: 254 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 284 KiB |
|
After Width: | Height: | Size: 128 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 138 KiB |
|
After Width: | Height: | Size: 280 KiB |
|
After Width: | Height: | Size: 151 KiB |
|
After Width: | Height: | Size: 124 KiB |