如何更改 OpenCV 输入帧的颜色通道以适合模型?

How to change the color channel of the OpenCV input frame to fit the model?

我对深度学习还是个新手。所以,我正在尝试 运行 OpenCV 捕获帧并将这些帧传递给我训练的模型。模型所需的输入维度为 (48,48,1)。

模型中的第一层:

model.add(Conv2D(input_shape=(48,48,1),filters=64,kernel_size=(3,3),padding="same", activation="relu"))

我正在尝试转换 OpenCV 帧输入以适应模型的尺寸。但是,我尝试使用 cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 并调整大小,但输出尺寸仅为 (48,48)

我尝试了下面显示的另一种方法,但输出为 (48,48,3),然后在添加轴以便能够将其传递给模型后,输出维度为 (1,48,48,3 )

coverted_image= cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces_detected = face_haar_cascade.detectMultiScale(coverted_image)

#Draw Triangles around the faces detected
for (x,y,w,h) in faces_detected:
    cv2.rectangle(frame,(x,y), (x+w,y+h), (255,0,0))
    roi_gray=frame[y:y+w,x:x+h]
    roi_gray=cv2.resize(roi_gray,(48,48))
    
    image_pixels = tf.keras.preprocessing.image.img_to_array(roi_gray)
    print(image_pixels.shape)
    image_pixels = np.expand_dims(image_pixels, axis = 0)
    print(image_pixels.shape)
    image_pixels /= 255
    print(image_pixels.shape)

如何将输入的形状调整为 (48,48,1) 以便能够从模型中获得预测?

openCV 图像只是 numpy 数组,因此可以使用 numpy 命令轻松地对其进行操作。

例如:

import numpy as np
x = np.array(range(48*48)).reshape(48,48)

x.shape

(48, 48)

x = x.reshape(48,48,1)

x.shape

(48, 48, 1)

你应该做的是:

检测人脸

首先你必须像你一样使用face_haar_cascade检测并剪掉面部部分。这为您提供了一个大小为 (n,x,y,c,m) 的数据集,其中 n 对应于检测到的人脸数量,x,y 是像素坐标,“C”是图像通道的数量,在这种情况下3(rgb 格式),m 是大小为 nx1 的向量,包含面部所属的 class。

在 Keras 中使用 FaceNet 进行人脸嵌入

FaceNet 是一个系统,给定一张人脸图像,从人脸中提取高质量特征,并预测这些特征的 128 元素向量表示,称为人脸嵌入。如果您只想要 48 个特征,我建议使用特征选择算法,例如 relief。应用此后,您将得到一个维度数组 (n,128,m),n 是要 classify 的人数,128 是特征数(可减少到 48),m 指的是 class 人脸所属的向量。假设您有 48 张图像,您的数组大小为 (48,48,1)。在此之后,您必须应用预处理步骤,例如规范化数据和删除可以应用任何模型的 outliers.After。

我做人脸嵌入的方式如下:

# calculate a face embedding for each face in the dataset using facenet
from numpy import load
from numpy import expand_dims
from numpy import asarray
from numpy import savez_compressed
from keras.models import load_model

# get the face embedding for one face
def get_embedding(model, face_pixels):
    # scale pixel values
    face_pixels = face_pixels.astype('float32')
    # standardize pixel values across channels (global)
    mean, std = face_pixels.mean(), face_pixels.std()
    face_pixels = (face_pixels - mean) / std
    # transform face into one sample
    samples = expand_dims(face_pixels, axis=0)
    # make prediction to get embedding
    yhat = model.predict(samples)
    return yhat[0]


# load model
model=load_model("/<path to the folder where the model is>/facenet_keras.h5")
# load the face dataset
data = load('/<path to the folder where the dataset of detected and cropped faces is stored>/FacesDetected.npz')
trainX,trainy = data['arr_0'], data['arr_1']


# convert each face in the train set to an embedding
newTrainX = list()
for face_pixels in trainX:
    embedding = get_embedding(model, face_pixels)
    
    newTrainX.append(embedding)
newTrainX = asarray(newTrainX)

# save arrays to one file in compressed format
savez_compressed('<path to the folder where you want to save the face embeddings>/FacesEmbeddings.npz', newTrainX, trainy)

我推荐你看看这个post:https://machinelearningmastery.com/how-to-develop-a-face-recognition-system-using-facenet-in-keras-and-an-svm-classifier/