Numpy ndarray ValueError,尺寸不匹配

问题描述 投票:0回答:1

我对

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))
python numpy numpy-ndarray
1个回答
0
投票

我认为

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)
© www.soinside.com 2019 - 2024. All rights reserved.