Numpy ndarray ValueError,维度不匹配

mlmc2os5  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(112)

我在np.appendnp.vstack上遇到问题
我正试图将一个48 × 48灰度的面部图像与面部的地标阵列合并结合起来。
所以我可以有一个数组的图像和相应的地标,给予上午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行时,我也得到了与上面相同的Error:

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))
iaqfqrcu

iaqfqrcu1#

我认为np.concatenate()不是你在这种情况下需要的,因为你正在连接1通道image 48 x48 x1(或3通道48 x48 x3,如果不是灰度)和3D坐标列表478 x3。即使扩展landmarks的维数并得到1x 478 x3,也无法进行串联,因为除了串联轴(-1)之外,所有输入数组维数必须完全匹配。
如果您需要将imagelandmarks数据存储在一个数组中,我可以建议创建形状为48 x48 x2的2通道图像(如果不是灰度,则为4通道48 x48 x4),其中第一个通道将是image,第二个通道将是48 x48矩阵,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)

相关问题