首頁 >後端開發 >Python教學 >使用 Python 和 FaceNet 進行人臉識別

使用 Python 和 FaceNet 進行人臉識別

Patricia Arquette
Patricia Arquette原創
2025-01-13 06:36:42172瀏覽

本指南示範了使用facenet-pytorch的人臉相似度偵測工具。該工具利用 FaceNet 模型的高品質人臉嵌入,將目標影像與多個候選影像進行比較,以確定最接近的匹配。 讓我們來探索一下實現方式。

基本工具與函式庫

  1. PyTorch:深度學習操作的基礎。
  2. FaceNet-PyTorch: 提供用於人臉偵測和嵌入產生的預訓練模型。
  3. Pillow (PIL): 處理影像處理任務。
  4. Matplotlib:用於結果視覺化。

採用了兩個核心模型:

  • MTCNN: 偵測影像中的人臉。
  • InceptionResnetV1:擷取臉部嵌入。

初始化

<code class="language-python">import torch
from facenet_pytorch import MTCNN, InceptionResnetV1
from PIL import Image
import requests
from io import BytesIO
import matplotlib.pyplot as plt

# Initialize face detection (MTCNN) and embedding extraction (InceptionResnetV1) modules.
mtcnn = MTCNN(image_size=160, keep_all=True)
resnet = InceptionResnetV1(pretrained='vggface2').eval()</code>

函數定義

1。圖片載入與嵌入擷取:

此函數從 URL 檢索圖像、偵測人臉並計算嵌入。

<code class="language-python">def get_embedding_and_face(image_path):
    """Loads an image, detects faces, and returns the embedding and detected face."""
    try:
        response = requests.get(image_path)
        response.raise_for_status()
        content_type = response.headers.get('Content-Type')
        if 'image' not in content_type:
            raise ValueError(f"Invalid image URL: {content_type}")
        image = Image.open(BytesIO(response.content)).convert("RGB")
    except Exception as e:
        print(f"Image loading error from {image_path}: {e}")
        return None, None

    faces, probs = mtcnn(image, return_prob=True)
    if faces is None or len(faces) == 0:
        return None, None

    embedding = resnet(faces[0].unsqueeze(0))
    return embedding, faces[0]</code>

2。張量到影像的轉換:

準備用於顯示的張量。

<code class="language-python">def tensor_to_image(tensor):
    """Converts a normalized tensor to a displayable image array."""
    image = tensor.permute(1, 2, 0).detach().numpy()
    image = (image - image.min()) / (image.max() - image.min())
    image = (image * 255).astype('uint8')
    return image</code>

3。最相似的人臉辨識:

將目標影像的嵌入與候選影像的嵌入進行比較。

<code class="language-python">def find_most_similar(target_image_path, candidate_image_paths):
    """Identifies the most similar image to the target from a list of candidates."""
    target_emb, target_face = get_embedding_and_face(target_image_path)
    if target_emb is None:
        raise ValueError("No face detected in the target image.")

    highest_similarity = float('-inf')
    most_similar_face = None
    most_similar_image_path = None

    candidate_faces = []
    similarities = []

    for candidate_image_path in candidate_image_paths:
        candidate_emb, candidate_face = get_embedding_and_face(candidate_image_path)
        if candidate_emb is None:
            similarities.append(None)
            candidate_faces.append(None)
            continue

        similarity = torch.nn.functional.cosine_similarity(target_emb, candidate_emb).item()
        similarities.append(similarity)
        candidate_faces.append(candidate_face)

        if similarity > highest_similarity:
            highest_similarity = similarity
            most_similar_face = candidate_face
            most_similar_image_path = candidate_image_path

    # Visualization
    plt.figure(figsize=(12, 8))

    # Display target image
    plt.subplot(2, len(candidate_image_paths) + 1, 1)
    plt.imshow(tensor_to_image(target_face))
    plt.title("Target Image")
    plt.axis("off")

    # Display most similar image
    if most_similar_face is not None:
        plt.subplot(2, len(candidate_image_paths) + 1, 2)
        plt.imshow(tensor_to_image(most_similar_face))
        plt.title("Most Similar")
        plt.axis("off")

    # Display all candidates with similarity scores
    for idx, (candidate_face, similarity) in enumerate(zip(candidate_faces, similarities)):
        plt.subplot(2, len(candidate_image_paths) + 1, idx + len(candidate_image_paths) + 2)
        if candidate_face is not None:
            plt.imshow(tensor_to_image(candidate_face))
            plt.title(f"Score: {similarity * 100:.2f}%")
        else:
            plt.title("No Face Detected")
        plt.axis("off")

    plt.tight_layout()
    plt.show()

    if most_similar_image_path is None:
        raise ValueError("No faces detected in candidate images.")

    return most_similar_image_path, highest_similarity</code>

用法

用於比較的圖片網址:

<code class="language-python">image_url_target = 'https://d1mnxluw9mpf9w.cloudfront.net/media/7588/4x3/1200.jpg'
candidate_image_urls = [
    'https://beyondthesinglestory.wordpress.com/wp-content/uploads/2021/04/elon_musk_royal_society_crop1.jpg',
    'https://cdn.britannica.com/56/199056-050-CCC44482/Jeff-Bezos-2017.jpg',
    'https://cdn.britannica.com/45/188745-050-7B822E21/Richard-Branson-2003.jpg'
]

most_similar_image, similarity_score = find_most_similar(image_url_target, candidate_image_urls)
print(f"Most similar image: {most_similar_image}")
print(f"Similarity score: {similarity_score * 100:.2f}%")</code>

結果

Face Recognition with Python and FaceNet

結論

這個範例展示了facenet-pytorch的臉部辨識功能。 人臉偵測和嵌入產生的結合可以為各種應用程式建立工具,例如身份驗證或內容過濾。

以上是使用 Python 和 FaceNet 進行人臉識別的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn