我对
np.append
和 np.vstack
有疑问
我正在尝试将 48x48 灰度面部图像与面部标志数组相结合。
所以我可以有一个包含图像和相应地标的数组,用于训练 ML 模型。
landmarks_train = []
X_train_with_landmarks = []
all_landmarks = np.empty((0, 478, 3))
for i in range(len(X_train)):
image = X_train[i]
image = image.astype(np.uint8)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
landmarks = get_landmarks(image)
if len(landmarks) == 478:
# only save them and the image if all 478 are found
landmarks = np.array(landmarks)
print(landmarks.shape) # -> result is (478,3)
print(X_train[i].shape) # -> result (48, 48, 1)
all_landmarks = np.vstack((all_landmarks, landmarks))
X_train_with_landmarks.append(np.concatenate((X_train[i], landmarks), axis=-1))
X_train_with_landmarks = np.array(X_train_with_landmark
在 get_landmarks() 方法中,它使用 MediaPipe Face 网格获取地标:
mp_face_mesh = mp.solutions.face_mesh
face_mesh = mp_face_mesh.FaceMesh(max_num_faces=1, refine_landmarks=True)
# convert to RGB so that MediaPipe can work with it and then back
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
results_face_mesh = face_mesh.process(image)
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
if results_face_mesh.multi_face_landmarks:
for facial_landmarks in results_face_mesh.multi_face_landmarks:
facial_landmarks_res = []
for landmark in facial_landmarks.landmark:
x, y, z = landmark.x, landmark.y, landmark.z
facial_landmarks_res.append([x, y, z])
return facial_landmarks_res
然后我得到一个 ValueError ,表明当我执行操作时尺寸不一样:
all_landmarks = np.vstack((all_landmarks, landmarks))
ValueError:所有输入数组必须具有相同的维数,但索引 0 处的数组有 3 个维度,索引 1 处的数组有 2 个维度
当我删除
np.vstack
行时,我也得到与上面相同的错误,对于这个:
X_train_with_landmarks.append(np.concatenate((X_train[i], landmarks), axis=-1))
我现在不确定出了什么问题,也找不到任何解决方案来解决这个问题。
也许有人可以帮忙。
PS:也许这也有帮助。我如何构建 X_train,图像来自 fer2013 数据集并加载到 pandas DataFrama df 中。
train_set = df[df['Usage'] == 'Training']
X_train = np.array([np.fromstring(image, dtype=int, sep=' ') for image in train_set['pixels']])
X_train = X_train.reshape(-1, 48, 48, 1).astype('float32')
我尝试了几种操作来扩展这些数组,如下所示,但没有任何效果。
expanded_X_train = np.expand_dims(X_train[i], axis=0)
X_train_with_landmarks.append(np.concatenate((expanded_X_train, landmarks), axis=-1))
我认为
np.concatenate()
不是您在这种情况下需要的,因为您需要连接 1 通道 image
48x48x1(或 3 通道 48x48x3,如果不是灰度)和 3D 坐标列表 478x3。即使扩展 landmarks
的维度并获得 1x478x3,串联也是不可能的,因为除了串联轴(即 -1)之外的所有输入数组维度都必须完全匹配。
如果您需要将
image
和 landmarks
数据存储在一个数组中,我可以建议创建形状为 48x48x2 的 2 通道图像(如果不是灰度,则创建 4 通道 48x48x4),其中第一个通道为 image
和第二个通道将是 48x48 矩阵,以 z 坐标作为值,并为所有不在 base_number
中的坐标添加一些 landmarks
。请注意,我的假设是前两个 landmarks
坐标(x 和 y)在 0 到 48 之间,z 坐标可以是任何值。
base_number = 0 # or any other
matrix = np.ones((X_train[0].shape[0], X_train[0].shape[1], 1)) * base_number
matrix[landmarks[:, 0].astype(int), landmarks[:, 1].astype(int), 0] = landmarks[:, 2]
result = np.dstack((X_train[0], matrix)) # [48, 48, 2] or [48, 48, 4]
X_train_with_landmarks.append(result)