我正在尝试制作一个TensorFlow人脸检测模型。一个文件用于训练模型并将模型导出为.h5文件,如下所示。
import tensorflow as tfimport cv2from tensorflow.keras import layersimport osimport numpy as npfrom PIL import Imagefrom sklearn.model_selection import train_test_splitfrom tensorflow.keras.applications.resnet50 import preprocess_inputimage_size = (224, 224)batch_size = 32epochs = 10def load_widerface_dataset(widerface_dir): images_dir = os.path.join(widerface_dir, 'WIDER_train', 'images') labels_file = os.path.join(widerface_dir, 'wider_face_split', 'wider_face_train_bbx_gt.txt') X = [] y = [] with open(labels_file, 'r') as f: lines = f.readlines() num_images = int(lines[1]) current_line = 2 for _ in range(num_images): image_path = os.path.join(images_dir, lines[current_line - 2].strip()) num_faces = int(lines[num_images]) image = Image.open(image_path) image = image.resize((224, 224)) X.append(np.array(image)) faces = [] for i in range(num_faces): face_line = lines[current_line + i].strip().split(' ') face = [int(coord) for coord in face_line[:4]] faces.append(face) y.append(np.array(faces)) current_line += num_faces if current_line < len(lines) and not lines[current_line].strip(): current_line += 1 X = np.array(X) y = np.array(y) return X, ydef build_model(): model = tf.keras.models.Sequential([ tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(image_size[0], image_size[1], 3)), tf.keras.layers.MaxPooling2D((2, 2)), tf.keras.layers.Conv2D(64, (3, 3), activation='relu'), tf.keras.layers.MaxPooling2D((2, 2)), tf.keras.layers.Conv2D(64, (3, 3), activation='relu'), tf.keras.layers.Flatten(), tf.keras.layers.Dense(64, activation='relu'), tf.keras.layers.Dense(4, activation='sigmoid') ]) return modelwiderface_dir = 'C:/face_training/WIDER_train'X_train, y_train = load_widerface_dataset(widerface_dir)model = build_model()model.compile(optimizer = 'adam', loss = 'mean_squared_error')model.fit(X_train, y_train, batch_size = batch_size, epochs = epochs)model.save('face_detection_model.h5')
另一个文件用于读取视频并使用我训练的模型分析视频,提取检测到人脸的帧。以下是该文件的代码。
import cv2import osfrom tensorflow.keras.models import load_modelimport sysimport numpy as npvidPath = "testclip2.mp4"model_path = 'face_detection_model.h5'model = load_model(model_path)test_tensorflow = 'C:/Users/user/Documents/PyCharmProjects/test_tensorflow'if not os.path.exists(test_tensorflow): os.makedirs(test_tensorflow)cap = cv2.VideoCapture(vidPath)currentFrame = 0while (cap.isOpened()): ret, frame = cap.read() if ret == True: frame = cv2.resize(frame, (224, 224)) frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) frame = frame / 255.0 frames = [frame] for frame in frames: prediction = model.predict(frame.reshape(1, 224, 224, 3)) if prediction.any() > 0.5: cv2.imwrite(os.path.join(test_tensorflow, str(currentFrame) + '.jpg'), frame) currentFrame += 1 else: breakcap.release()sys.exit(0)
现在我遇到了一个问题,程序只提取出黑色的图像。我不确定哪里出了问题,我已经查阅了很多资料,但似乎都没有解决。我非常希望得到您的指导。
回答:
我认为问题在于您对RGB值进行了归一化处理,即将范围从0-255转换为0-1。
这种做法在建模和预测中很常见,但当您尝试使用OpenCV输出结果时,它无法理解这些归一化的像素值。
您可以尝试这里建议的快速修复方法:https://stackoverflow.com/a/54165573/334402
这基本上只是将像素值恢复到OpenCV期望的0-255范围。