Skip to content

Instantly share code, notes, and snippets.

@rescenic
Forked from ajangrahmat/seberapa_mirip.py
Created April 21, 2025 03:12
Show Gist options
  • Save rescenic/8942e8763df05cbb755cc9c249846ff2 to your computer and use it in GitHub Desktop.
Save rescenic/8942e8763df05cbb755cc9c249846ff2 to your computer and use it in GitHub Desktop.
import face_recognition
import cv2
import numpy as np
import argparse
import os
def apply_blur(image, region, light_blur=False):
"""Menerapkan efek blur dengan intensitas berbeda"""
try:
top, right, bottom, left = region
# Pastikan region valid
if top >= bottom or left >= right:
return image
# Ekstrak region
region_img = image[top:bottom, left:right]
if region_img.size > 0:
# Blur kuat untuk wajah, blur ringan untuk background
if light_blur:
# Blur ringan (nilai kernel kecil)
blurred = cv2.GaussianBlur(region_img, (15, 15), 5)
else:
# Blur sangat kuat sampai tidak terlihat
for _ in range(3): # Triple blur untuk efek lebih kuat
blurred = cv2.GaussianBlur(region_img, (99, 99), 30)
region_img = blurred
image[top:bottom, left:right] = blurred
except Exception as e:
print(f"⚠️ Peringatan: Gagal memproses blur: {str(e)}")
return image
def get_face_info(image, model='hog'):
"""Deteksi wajah dan dapatkan encoding"""
face_locations = face_recognition.face_locations(image, model=model)
if not face_locations:
return None, None
if len(face_locations) > 1:
print(f"⚠️ Peringatan: Ditemukan lebih dari satu wajah. Akan menggunakan wajah pertama.")
encoding = face_recognition.face_encodings(image, known_face_locations=[face_locations[0]])[0]
return encoding, face_locations[0]
def classify_similarity(distance):
"""Mengklasifikasikan kemiripan wajah berdasarkan jarak"""
if distance < 0.5:
return "SANGAT MIRIP", (0, 255, 0) # Hijau
elif distance < 0.6:
return "MIRIP", (0, 255, 255) # Kuning
elif distance < 0.7:
return "TIDAK MIRIP", (0, 165, 255) # Oranye
else:
return "SANGAT BERBEDA", (0, 0, 255) # Merah
def draw_info(image, text_lines, color, line_height=30):
"""Menambahkan teks dengan latar belakang pada gambar"""
y = image.shape[0] - (len(text_lines) * line_height) + 20
for line in text_lines:
text_size = cv2.getTextSize(line, cv2.FONT_HERSHEY_SIMPLEX, 0.8, 2)[0]
cv2.rectangle(image, (0, y-25), (text_size[0]+10, y+10), (0, 0, 0), -1)
cv2.putText(image, line, (10, y), cv2.FONT_HERSHEY_SIMPLEX, 0.8, color, 2)
y += line_height
return image
def process_image(image_path, model='hog', blur_faces=False):
"""Memuat dan memproses gambar dengan blur selektif"""
try:
img = cv2.imread(image_path)
if img is None:
raise ValueError(f"Format gambar tidak didukung atau file rusak: {image_path}")
image_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
encoding, face_location = get_face_info(image_rgb, model)
if encoding is None:
raise ValueError(f"Tidak terdeteksi wajah pada {image_path}")
if blur_faces:
# Blur seluruh gambar sedikit (background)
img = apply_blur(img, (0, img.shape[1], img.shape[0], 0), light_blur=True)
# Blur wajah sangat kuat
if face_location:
img = apply_blur(img, face_location, light_blur=False)
return img, encoding, face_location
except Exception as e:
raise ValueError(f"Gagal memproses gambar {image_path}: {str(e)}")
def main():
parser = argparse.ArgumentParser(description="Alat Perbandingan Wajah dengan Blur Privasi")
parser.add_argument("known_image", help="Path ke gambar wajah referensi")
parser.add_argument("test_image", help="Path ke gambar wajah uji")
parser.add_argument("-o", "--output", help="Simpan hasil ke file")
parser.add_argument("-m", "--model", choices=['hog', 'cnn'], default='hog',
help="Model deteksi wajah (hog lebih cepat, cnn lebih akurat)")
parser.add_argument("-b", "--blur", action='store_true',
help="Aktifkan mode privasi: wajah blur kuat, background blur ringan")
args = parser.parse_args()
try:
img1, enc1, loc1 = process_image(args.known_image, args.model, args.blur)
img2, enc2, loc2 = process_image(args.test_image, args.model, args.blur)
except Exception as e:
print(f"❌ Error: {e}")
return
# Hitung kemiripan
distance = face_recognition.face_distance([enc1], enc2)[0]
similarity = (1 - distance) * 100
label, color = classify_similarity(distance)
# Gambar kotak deteksi (jika tidak dalam mode blur)
if not args.blur:
for img, loc in [(img1, loc1), (img2, loc2)]:
if loc:
top, right, bottom, left = loc
cv2.rectangle(img, (left, top), (right, bottom), color, 4)
# Gabungkan gambar
max_height = 600
img1 = resize_image(img1, max_height) if img1 is not None else None
img2 = resize_image(img2, max_height) if img2 is not None else None
if img1 is not None and img2 is not None:
combined = np.hstack((img1, img2))
# Tambahkan info teks dengan warna sesuai klasifikasi
info_lines = [
f"Jarak: {distance:.4f}",
f"Kemiripan: {similarity:.2f}%",
f"Klasifikasi: {label}",
"Mode Privasi: AKTIF" if args.blur else "Mode Privasi: NON-AKTIF"
]
combined = draw_info(combined, info_lines, color)
# Tampilkan atau simpan hasil
if args.output:
cv2.imwrite(args.output, combined)
print(f"✅ Hasil disimpan ke {args.output}")
else:
cv2.imshow("Hasil Perbandingan Wajah", combined)
cv2.waitKey(0)
cv2.destroyAllWindows()
else:
print("❌ Tidak dapat memproses gambar. Pastikan kedua gambar berisi wajah yang terdeteksi.")
def resize_image(image, target_height):
"""Mengubah ukuran gambar secara proporsional ke tinggi target"""
if image is None:
return None
h, w = image.shape[:2]
ratio = target_height / h
return cv2.resize(image, (int(w * ratio), target_height), interpolation=cv2.INTER_AREA)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment