shadowmage 发表于 2024-8-22 12:52:14

@FishC,OpenCV应该怎样使用

想要给自己本地PC上整理一下,调用OpenCV,辨认一下人脸,把同一人的照片归归类,应该怎么编写代码?
如果OpenCV做不到,请推荐类似人脸识别的库

FishC 发表于 2024-8-22 13:01:39

你好,鱼油!使用OpenCV进行人脸识别并分类有点复杂,但我会尽量简洁地介绍一下基础步骤。如果OpenCV不能满足你的需求,其他库如dlib或facenet也非常强大。

**使用OpenCV进行人脸识别**:

1. **安装OpenCV**:
   pip install opencv-python-headless
   pip install opencv-contrib-python-headless

2. **加载所需模块**:
   import cv2
   import os
   import numpy as np

3. **加载预训练的人脸检测器**:
   face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

4. **编写人脸检测和识别代码**:
   def detect_and_display(image_path):
       # 读取图像
       img = cv2.imread(image_path)
       gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
       faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))

       for (x, y, w, h) in faces:
         cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)

       cv2.imshow('Detected Faces', img)
       cv2.waitKey(0)
       cv2.destroyAllWindows()

5. **调用函数**:
   image_path = 'path_to_your_image.jpg'
   detect_and_display(image_path)

如果要对同一张脸进行分类或聚类,OpenCV中的EigenFace和LBPH算法可以用来实现。你还需要为每个人准备多个训练图像。

**推荐其他库**:

- **dlib**:具有良好的人脸检测和面部嵌入功能。
pip install dlib
pip install face_recognition

演示代码:
import face_recognition

known_image = face_recognition.load_image_file("known_image.jpg")
unknown_image = face_recognition.load_image_file("unknown_image.jpg")

known_encoding = face_recognition.face_encodings(known_image)
unknown_encoding = face_recognition.face_encodings(unknown_image)

results = face_recognition.compare_faces(, unknown_encoding)
print("Is the face same?", results)

- **facenet**:通过TensorFlow实现,精度高但设置稍复杂。

希望以上信息能帮到你,如果有更多问题,欢迎继续提问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

shadowmage 发表于 2024-8-22 15:14:14

FishC 发表于 2024-8-22 13:01
你好,鱼油!使用OpenCV进行人脸识别并分类有点复杂,但我会尽量简洁地介绍一下基础步骤。如果OpenCV不能满 ...

以下代码可以满足顶楼要求吗:

import os
import numpy as np
from sklearn.cluster import DBSCAN
import face_recognition
def load_images_from_folder(folder):
    """
    从指定文件夹加载所有图片。
   
    :param folder: 包含图片的文件夹路径
    :return: 图片列表和对应的文件名列表
    """
    images = []
    filenames = []
    for filename in os.listdir(folder):
      img = face_recognition.load_image_file(os.path.join(folder, filename))
      if img is not None:
            images.append(img)
            filenames.append(filename)
    return images, filenames
def detect_faces_and_extract_encodings(images):
    """
    对每张图片进行人脸检测,并提取每个人脸的特征向量。
   
    :param images: 图片列表
    :return: 每张图片的人脸位置列表和所有人脸的特征向量列表
    """
    all_face_locations = []
    all_face_encodings = []
    for image in images:
      # 检测人脸
      face_locations = face_recognition.face_locations(image)
      # 提取人脸特征
      face_encodings = face_recognition.face_encodings(image, face_locations)
      all_face_locations.append(face_locations)
      all_face_encodings.extend(face_encodings)
    return all_face_locations, all_face_encodings
def cluster_faces(face_encodings):
    """
    使用DBSCAN算法对人脸特征向量进行聚类。
   
    :param face_encodings: 所有人脸的特征向量列表
    :return: 每个人脸所属的聚类标签
    """
    # 使用DBSCAN进行聚类
    clustering = DBSCAN(eps=0.5, min_samples=1).fit(face_encodings)
    return clustering.labels_
def create_and_move_files(filenames, labels, folder_path):
    """
    根据聚类标签创建文件夹,并将图片移动到相应的文件夹中。
   
    :param filenames: 文件名列表
    :param labels: 每个人脸所属的聚类标签
    :param folder_path: 包含原始图片的文件夹路径
    """
    # 获取所有标签的唯一值
    unique_labels = set(labels)
   
    # 对每个标签创建一个文件夹
    for label in unique_labels:
      new_folder = f"Person_{label}"
      os.makedirs(os.path.join(folder_path, new_folder), exist_ok=True)
      
    # 移动文件到相应的文件夹
    for i, filename in enumerate(filenames):
      label = labels
      new_folder = f"Person_{label}"
      old_path = os.path.join(folder_path, filename)
      new_path = os.path.join(folder_path, new_folder, filename)
      os.rename(old_path, new_path)
def organize_faces_by_person(folder_path):
    """
    整个人脸组织流程的主函数。
   
    :param folder_path: 包含原始图片的文件夹路径
    """
    # 加载图片
    images, filenames = load_images_from_folder(folder_path)
   
    # 检测所有人脸并提取特征
    all_face_locations, all_face_encodings = detect_faces_and_extract_encodings(images)
   
    # 聚类人脸
    labels = cluster_faces(all_face_encodings)
   
    # 创建文件夹并移动文件
    create_and_move_files(filenames, labels, folder_path)
folder_path = 'path_to_your_images_folder'# 替换为你的图片文件夹路径
organize_faces_by_person(folder_path)

FishC 发表于 2024-8-22 15:14:28

shadowmage 发表于 2024-08-22 15:14
以下代码可以满足顶楼要求吗:

import os
import...

这段代码有一些缺陷和漏洞,首先来看几个重要的问题:

1. **某些变量初始化为空:**
    - `images = []`
    - `filenames = []`
    - `all_face_locations = []`
    - `all_face_encodings = []`

2. **缺少变量赋值或错误使用:**
    - `label = labels` 应改为 `label = labels`

3. **`face_recognition` 库的依赖问题:**
    - 确保已经安装 `face_recognition` 库,可以用 `pip install face_recognition`。

以下是修正后的代码示例:

import os
import numpy as np
from sklearn.cluster import DBSCAN
import face_recognition

def load_images_from_folder(folder):
    """
    从指定文件夹加载所有图片。
    """
    images = []
    filenames = []
    for filename in os.listdir(folder):
      img = face_recognition.load_image_file(os.path.join(folder, filename))
      if img is not None:
            images.append(img)
            filenames.append(filename)
    return images, filenames

def detect_faces_and_extract_encodings(images):
    """
    对每张图片进行人脸检测,并提取每个人脸的特征向量。
    """
    all_face_locations = []
    all_face_encodings = []
    for image in images:
      # 检测人脸
      face_locations = face_recognition.face_locations(image)
      # 提取人脸特征
      face_encodings = face_recognition.face_encodings(image, face_locations)
      all_face_locations.append(face_locations)
      all_face_encodings.extend(face_encodings)# 将 list of list 展平成一个 list
    return all_face_locations, all_face_encodings

def cluster_faces(face_encodings):
    """
    使用DBSCAN算法对人脸特征向量进行聚类。
    """
    # 使用DBSCAN进行聚类
    clustering = DBSCAN(eps=0.5, min_samples=1).fit(face_encodings)
    return clustering.labels_

def create_and_move_files(filenames, labels, folder_path):
    """
    根据聚类标签创建文件夹,并将图片移动到相应的文件夹中。
    """
    # 获取所有标签的唯一值
    unique_labels = set(labels)
   
    # 对每个标签创建一个文件夹
    for label in unique_labels:
      new_folder = f"Person_{label}"
      os.makedirs(os.path.join(folder_path, new_folder), exist_ok=True)
      
    # 移动文件到相应的文件夹
    for i, filename in enumerate(filenames):
      label = labels
      new_folder = f"Person_{label}"
      old_path = os.path.join(folder_path, filename)
      new_path = os.path.join(folder_path, new_folder, filename)
      os.rename(old_path, new_path)

def organize_faces_by_person(folder_path):
    """
    整个人脸组织流程的主函数。
    """
    # 加载图片
    images, filenames = load_images_from_folder(folder_path)
   
    # 检测所有人脸并提取特征
    all_face_locations, all_face_encodings = detect_faces_and_extract_encodings(images)
   
    # 聚类人脸
    labels = cluster_faces(all_face_encodings)
   
    # 创建文件夹并移动文件
    create_and_move_files(filenames, labels, folder_path)

folder_path = 'path_to_your_images_folder'# 替换为你的图片文件夹路径
organize_faces_by_person(folder_path)

### 额外提示:
- **eps 参数调整**:调整 `DBSCAN` 的 `eps` 参数,根据实际效果来优化识别准确度。
- **调整图像大小**:如果图片特别大,可以考虑调整大小以加速处理。

希望这些改动能帮助你整理和分类本地 PC 上的照片。祝你成功!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: @FishC,OpenCV应该怎样使用