ageitgey / face_recognition

The world's simplest facial recognition api for Python and the command line
MIT License
53.58k stars 13.51k forks source link

RuntimeError: Unsupported image type, must be 8bit gray or RGB image. #1618

Open SumitDhivar opened 4 days ago

SumitDhivar commented 4 days ago

Description

I try to do facial recognition system that generates and stores face encodings from images, then uses a webcam to detect and match faces in real-time. If a match is found, it displays "Face Detected"; otherwise, "Face Not Found." The processed video stream is sent for display, possibly for attendance or access control purposes..

What I Did

import cv2
import os
import face_recognition
import numpy as np
import cvzone
import pickle

def generate_frame():
    # Check if EncodeFile.p exists
    if not os.path.exists("EncodeFile.p"):
        logging.info("EncodeFile.p not found. Generating encodings...")
        images_path = "static/Files/Images/"
        image_files = os.listdir(images_path)

        known_encodings = []
        student_ids = []

        for file in image_files:
            img_path = os.path.join(images_path, file)

            if not (file.lower().endswith(".jpg") or file.lower().endswith(".png")):
                logging.warning(f"Skipping unsupported file format: {file}")
                continue

            try:
                img = cv2.imread(img_path)
                if img is None:
                    logging.error(f"Unable to read image {file}. Skipping.")
                    continue

                if img.ndim != 3 or img.shape[2] not in [3, 4]:
                    logging.warning(f"Skipping {file} due to unsupported channel format.")
                    continue

                if img.shape[2] == 4:  # Convert RGBA to RGB
                    img = cv2.cvtColor(img, cv2.COLOR_BGRA2BGR)
                    logging.info(f"Converted {file} from RGBA to RGB.")

                img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
                encodings = face_recognition.face_encodings(img_rgb)

                if encodings:
                    known_encodings.append(encodings[0])
                    student_id = os.path.splitext(file)[0]
                    student_ids.append(student_id)
                else:
                    logging.warning(f"No face found in {file}. Skipping this image.")

            except Exception as e:
                logging.error(f"Error processing file {file}: {e}")

        if known_encodings and student_ids:
            with open("EncodeFile.p", "wb") as file:
                pickle.dump([known_encodings, student_ids], file)
            logging.info("EncodeFile.p created successfully!")
        else:
            logging.warning("No valid encodings generated. EncodeFile.p was not created.")
            return  # Exit function if no encodings are generated

    # Initialize camera
    capture = cv2.VideoCapture(0)
    if not capture.isOpened():
        raise RuntimeError("Could not start the camera.")

    # Load resources
    img_background = cv2.imread("static/Files/Resources/background.png")
    folder_mode_path = "static/Files/Resources/Modes/"
    img_mode_list = [cv2.imread(os.path.join(folder_mode_path, path)) for path in os.listdir(folder_mode_path)]

    with open("EncodeFile.p", "rb") as file:
        encoded_face_known, student_ids = pickle.load(file)

    counter = 0
    id = -1

    while True:
        success, img = capture.read()
        if not success:
            break

        img_small = cv2.resize(img, (0, 0), None, 0.25, 0.25)
        img_small = cv2.cvtColor(img_small, cv2.COLOR_BGR2RGB)
        face_current_frame = face_recognition.face_locations(img_small)
        encode_current_frame = face_recognition.face_encodings(img_small, face_current_frame)

        img_background[162:162 + 480, 55:55 + 640] = img

        if face_current_frame:
            for encode_face, face_location in zip(encode_current_frame, face_current_frame):
                matches = face_recognition.compare_faces(encoded_face_known, encode_face)
                face_distance = face_recognition.face_distance(encoded_face_known, encode_face)
                match_index = np.argmin(face_distance)

                y1, x2, y2, x1 = [v * 4 for v in face_location]
                bbox = 55 + x1, 162 + y1, x2 - x1, y2 - y1
                img_background = cvzone.cornerRect(img_background, bbox)

                if matches[match_index]:
                    id = student_ids[match_index]
                    if counter == 0:
                        cvzone.putTextRect(img_background, "Face Detected", (65, 200), thickness=2)
                        counter += 1
                else:
                    cvzone.putTextRect(img_background, "Face Not Found", (65, 200), thickness=2)
                    counter = 0

        # Update attendance logic here...

        ret, buffer = cv2.imencode('.jpg', img_background)
        if ret:
            frame = buffer.tobytes()
            yield (b'--frame\r\nContent-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

    capture.release()
INFO:root:EncodeFile.p not found. Generating encodings...
ERROR:root:Error processing file 004223.png: Unsupported image type, must be 8bit gray or RGB image.
ERROR:root:Error processing file nimay.jpg: Unsupported image type, must be 8bit gray or RGB image.
WARNING:root:No valid encodings generated. EncodeFile.p was not created.
INFO:werkzeug:127.0.0.1 - - [22/Nov/2024 18:26:18] "GET /video HTTP/1.1" 200 -
qiqi0308 commented 4 days ago

you can take a look at #1573

SumitDhivar commented 3 days ago

you can take a look at #1573

thanks it's work