close

使用 PiCamera2 和 OpenCV 實現臉部識別

本文將展示如何使用 PiCamera2 和 OpenCV,在 Raspberry Pi 上實現高效的臉部識別系統。

問題背景與解決方案

在使用 OpenCV 的臉部識別器時,可能遇到如下錯誤:

ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions.
  

這通常是由於圖像大小不一致導致的。通過將圖像統一為固定大小可以解決此問題。

修正代碼以處理圖像大小不一致問題

# 匯入必要模組
import cv2
import numpy as np

# 初始化圖像與標籤的列表
images = []
labels = []

# 定義固定的圖像大小
fixed_size = (100, 100)

# 加載圖像並設置標籤
for index in range(100):
    filename = f'images/h0/{index:03d}.pgm'
    print(f'Reading {filename}')
    img = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)
    
    if img is None:
        print(f'Error: {filename} could not be read!')
        continue

    # 調整圖像大小
    img_resized = cv2.resize(img, fixed_size)
    images.append(img_resized)
    labels.append(0)

# 將列表轉換為 NumPy 陣列
images_array = np.array(images, dtype=np.uint8)
labels_array = np.array(labels, dtype=np.int32)

# 訓練 LBPH 臉部識別器
model = cv2.face.LBPHFaceRecognizer_create()
model.train(images_array, labels_array)
model.save('faces.data')
print('Training done and model saved.')

  

使用 PiCamera2 替代 cv2.VideoCapture

為了提高效率,我們使用 PiCamera2 替代 OpenCV 的視訊流。以下是完整代碼:

# 匯入模組
from picamera2 import Picamera2, Preview
import cv2
import numpy as np

# 加載訓練模型與 Haar 紋波檢測器
model = cv2.face.LBPHFaceRecognizer_create()
model.read('faces.data')
print('Loaded training data successfully')

face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

# 初始化 PiCamera2
picam2 = Picamera2()
camera_config = picam2.create_preview_configuration(main={"size": (640, 480)})
picam2.configure(camera_config)
picam2.start()

# 映射標籤至名稱
names = ['ckk']

try:
    while True:
        # 從 PiCamera2 捕捉影像
        frame = picam2.capture_array()

        # 翻轉並調整大小
        frame = cv2.flip(frame, 1)
        frame = cv2.resize(frame, (600, 336))

        # 轉換為灰階
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # 偵測臉部
        faces = face_cascade.detectMultiScale(gray, 1.1, 3)
        for (x, y, w, h) in faces:
            frame = cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 3)
            face_img = gray[y:y+h, x:x+w]
            face_img = cv2.resize(face_img, (400, 400))

            # 預測臉部
            val = model.predict(face_img)
            print('label:{}, conf:{:.1f}'.format(val[0], val[1]))
            if val[1] < 50:
                cv2.putText(
                    frame, names[val[0]], (x, y - 10), 
                    cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 0), 3
                )

        # 顯示影像
        cv2.imshow('video', frame)
        if cv2.waitKey(1) == 27:  # 按 ESC 退出
            break
except Exception as e:
    print(f"An error occurred: {e}")
finally:
    picam2.stop()
    cv2.destroyAllWindows()

  

結論

通過本文的代碼示例,您可以在 Raspberry Pi 上實現高效的臉部識別系統。請確保已安裝必要的庫(如 picamera2opencv-pythonnumpy),並準備好相關的訓練數據和 Haar 紋波檢測器。

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 liusming 的頭像
    liusming

    劉老師的跨域創想工坊

    liusming 發表在 痞客邦 留言(2) 人氣()