Numpy数组切片报错:形状不匹配问题排查求助
高斯热图生成代码的形状不匹配问题排查
问题描述
我编写了一段基于坐标和置信度在图像像素上生成高斯分布热图的代码,但运行时出现错误。代码如下:
import numpy as np def gen_single_joint_heatmap(x, y, conf, img_size, sigma=0.6, eps=1e-6): heatmap = np.zeros(img_size) # Outside the gaussians all values should be zero for center_x, center_y, confidence in zip(x, y, conf): # center of the gaussians and confidences of the centers if confidence < eps: continue # The centers are scaled between 0 and 1, so multiply by width and height to obtain the real coordinates center_x *= img_size[0] center_y *= img_size[1] # creating a range in which the gaussian is computed start_x = max(0, int(center_x - 3 * sigma)) end_x = min(img_size[0], int(center_x + 3 * sigma)) # sigma is set to 0.6 start_y = max(0, int(center_y - 3 * sigma)) end_y = min(img_size[1], int(center_y + 3 * sigma)) x = np.arange(start_x, end_x, 1, dtype=np.float32) y = np.arange(start_y, end_y, 1, dtype=np.float32) # if the x and y are 0, then continue if not (len(x) and len(y)): continue y = y[:, None] # Compute the gaussian patch = np.exp(-(x - center_x) ** 2 + (y - center_y) ** 2 / 2 / sigma ** 2) patch *= confidence print('x_length', end_x - start_x, end_y - start_y) print(heatmap[start_y:end_y, start_x:end_x].shape) # save the patch if it's higher than values of the heatmap heatmap[start_y:end_y, start_x:end_x] = np.maximum(heatmap[start_y:end_y, start_x:end_x], patch) return heatmap
错误信息
最后一行赋值语句报错:
ValueError: operands could not be broadcast together with shapes (3,0) (3,3)
打印end_x - start_x和end_y - start_y得到3和3,但heatmap[start_y:end_y, start_x:end_x]的形状却是(3,0)。
补充信息:完整热图形状为1920x1080(经整数缩放因子处理),patch通常为3x3形状,有时因整数舍入会更大。完整报错回溯如下:
Traceback (most recent call last): File "/home/samuel/Desktop/internship_implementation/main.py", line 238, in <module> main() File "/home/samuel/Desktop/internship_implementation/main.py", line 190, in main dataset = dataset[0] File "/home/samuel/Desktop/internship_implementation/data/pc3dDataset.py", line 60, in __getitem__ frames = full_preprocess(full_path, data, self.sample_number, self.image_padding, self.channels, File "/home/samuel/Desktop/internship_implementation/pipelines/preprocess.py", line 17, in full_preprocess data = generate_heatmap(data, image_padding, img_size, channels, scale_factor, epsilon, sigma) File "/home/samuel/Desktop/internship_implementation/pipelines/preprocessing/keypoints_heatmap_related.py", line 241, in generate_heatmap frames_heatmap[i] = gen_frame_heatmap(rearranged_skeletons[i], new_img_size, epsilon, sigma) File "/home/samuel/Desktop/internship_implementation/pipelines/preprocessing/keypoints_heatmap_related.py", line 222, in gen_frame_heatmap new_skeletons[channel] = gen_single_joint_heatmap(skeleton[i], skeleton[i + 1], skeleton[i + 2], File "/home/samuel/Desktop/internship_implementation/pipelines/preprocessing/keypoints_heatmap_related.py", line 213, in gen_single_joint_heatmap heatmap[start_y:end_y, start_x:end_x] = np.maximum(heatmap[start_y:end_y, start_x:end_x], patch) ValueError: operands could not be broadcast together with shapes (3,0) (3,3)
错误原因
坐标缩放维度对应错误:
img_size的格式是(高度, 宽度)(即H×W),但你将x坐标(对应图像宽度)乘以了img_size[0](高度),y坐标(对应图像高度)乘以了img_size[1](宽度),导致坐标被错误缩放。当x坐标缩放后超过图像宽度时,会出现start_x > end_x的情况,此时start_x:end_x的切片是空区间,最终热图切片形状变成(3,0),和3×3的patch无法广播运算。输入参数被局部变量覆盖:
函数内部用x = np.arange(...)和y = np.arange(...)覆盖了输入的x、y参数,会导致后续循环中zip(x,y,conf)使用的是局部数组而非原始输入,引发逻辑错误。高斯公式错误:
原代码的高斯分布计算式符号和括号错误,会生成不符合预期的分布,虽然不是直接报错原因,但会影响热图效果。
解决方案
修正后的代码
import numpy as np def gen_single_joint_heatmap(x_coords, y_coords, conf, img_size, sigma=0.6, eps=1e-6): # img_size格式为(高度, 宽度),对应热图的(H, W)维度 heatmap = np.zeros(img_size) for center_x, center_y, confidence in zip(x_coords, y_coords, conf): if confidence < eps: continue # 修正坐标缩放:x对应图像宽度(img_size[1]),y对应图像高度(img_size[0]) center_x *= img_size[1] center_y *= img_size[0] # 计算高斯分布的有效范围 start_x = max(0, int(center_x - 3 * sigma)) end_x = min(img_size[1], int(center_x + 3 * sigma)) start_y = max(0, int(center_y - 3 * sigma)) end_y = min(img_size[0], int(center_y + 3 * sigma)) # 新增检查:避免空切片 if start_x >= end_x or start_y >= end_y: continue # 重命名局部变量,避免覆盖输入参数 x_grid = np.arange(start_x, end_x, 1, dtype=np.float32) y_grid = np.arange(start_y, end_y, 1, dtype=np.float32) y_grid = y_grid[:, None] # 修正高斯公式:正确的二维高斯分布计算方式 patch = np.exp(-((x_grid - center_x)**2 + (y_grid - center_y)**2) / (2 * sigma**2)) patch *= confidence # 更新热图 heatmap[start_y:end_y, start_x:end_x] = np.maximum(heatmap[start_y:end_y, start_x:end_x], patch) return heatmap
关键修正点
- 调整坐标缩放的维度对应关系,确保x、y坐标匹配图像的宽、高。
- 重命名局部网格变量,避免覆盖输入参数。
- 增加切片有效性检查,跳过空区间的计算。
- 修正高斯分布公式,保证生成正确的高斯热图。
内容的提问来源于stack exchange,提问作者Neskelogth
相关产品推荐
相关产品推荐

