使用abel库执行逆Abel变换时遭遇维度不匹配错误
使用abel库执行逆Abel变换时遭遇维度不匹配错误
首先,我来梳理一下你的问题:你通过Matplotlib的RectangleSelector选择ROI后,尝试用hansenlaw方法执行逆Abel变换,但遇到了如下维度不匹配错误:
ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 0 dimension(s)
错误发生在Abel库分割图像为四个象限的步骤中,第三象限(Q3)被识别为0维空数组,导致拼接失败。
错误原因分析
- 代码笔误导致的混淆:你的
onselect函数中,处理高度奇数的逻辑里,打印的错误信息写错了(把“高度”写成了“宽度”),虽然这不会直接引发错误,但会干扰你调试时的判断。 - ROI的象限分割逻辑问题:尽管你已经将ROI的宽高调整为偶数,但Abel库在使用
hansenlaw方法时,需要确保四个象限都有有效数据。如果某个象限的尺寸为0,就会触发这个错误。 - 参数设置可能存在的偏差:你手动设置了
origin参数,这可能和hansenlaw方法的默认处理逻辑冲突,导致象限分割异常。
解决方案
1. 修正代码笔误
在处理高度奇数的分支中,把打印信息里的“Breedte”(宽度)改为“Hoogte”(高度),避免调试时混淆:
if height % 2 != 0: if y2 > y1: y2 += 1 else: y1 += 1 print(f"Hoogte oneven ({height}), aangepast selectie naar even hoogte.")
2. 强化ROI有效性检查
除了确保宽高为偶数,还要添加ROI最小尺寸检查(至少2x2),避免过小的ROI导致象限分割失败:
# 在ROI有效性检查部分添加 if roi.shape[0] < 2 or roi.shape[1] < 2: print("Fout: geselecteerde ROI is te klein (minstens 2x2 vereist).") return
3. 调试象限分割状态
在调用Abel变换前,手动打印四个象限的形状,确认没有空象限,方便定位问题:
# 计算象限,用于调试 center_y = roi.shape[0] // 2 Q1 = roi[:center_y, :center_x] Q2 = roi[:center_y, center_x:] Q3 = roi[center_y:, center_x:] Q4 = roi[center_y:, :center_x] print(f"ROI shape: {roi.shape}, Center x: {center_x}, Center y: {center_y}") print(f"Q1 shape: {Q1.shape}, Q2 shape: {Q2.shape}, Q3 shape: {Q3.shape}, Q4 shape: {Q4.shape}")
如果输出中Q3的形状是(0, x)或(x, 0),说明你的ROI y/x范围仍有问题,需要重新检查鼠标选择的坐标处理逻辑。
4. 调整Abel变换的参数设置
hansenlaw方法默认假设对称轴为图像的x中心,你可以尝试移除手动设置的origin参数,让库自动处理原点:
try: # 移除origin参数,使用库默认的原点逻辑 abel_transform_result = transform.Transform( roi, method='hansenlaw', symmetry_axis=center_x, direction='inverse', ) except Exception as e: print("Fout tijdens Abel-transformatie:", e) return
5. 更新Abel库到最新版本
这个错误可能是旧版本Abel库的bug导致的,执行以下命令更新库:
pip install --upgrade abel
修改后的完整代码片段
from abel import transform import numpy as np import matplotlib.pyplot as plt from matplotlib.widgets import RectangleSelector # --- Voorbeeld 2D heatmap (voeg je eigen data hier in) --- # heatmap = np.load('heatmap.npy') # of laadt vanuit je script heatmap = np.random.rand(50, 50) # tijdelijke voorbeelddata heatmap_bg = heatmap - np.median(heatmap) heatmap_bg[heatmap_bg < 0] = 0 # --- Functie voor het verwerken van de geselecteerde ROI --- def onselect(eclick, erelease): # Get integer pixel bounds x1, y1 = int(eclick.xdata), int(eclick.ydata) x2, y2 = int(erelease.xdata), int(erelease.ydata) width = abs(x2 - x1) height = abs(y2 - y1) if width % 2 != 0: if x2 > x1: x2 += 1 else: x1 += 1 print(f"Breedte oneven ({width}), aangepast selectie naar even breedte.") if height % 2 != 0: if y2 > y1: y2 += 1 else: y1 += 1 print(f"Hoogte oneven ({height}), aangepast selectie naar even hoogte.") roi = heatmap_bg[min(y1, y2):max(y1, y2), min(x1, x2):max(x1, x2)] # --- Fix: controleer of ROI geldig is en minstens 2D --- if roi.ndim != 2 or roi.shape[0] == 0 or roi.shape[1] == 0: print("Fout: geselecteerde ROI is ongeldig of leeg.") return # 检查ROI最小尺寸 if roi.shape[0] < 2 or roi.shape[1] < 2: print("Fout: geselecteerde ROI is te klein (minstens 2x2 vereist).") return # Compute symmetry axis: center of the ROI in x center_x = roi.shape[1] // 2 center_y = roi.shape[0] // 2 # 调试象限信息 Q1 = roi[:center_y, :center_x] Q2 = roi[:center_y, center_x:] Q3 = roi[center_y:, center_x:] Q4 = roi[center_y:, :center_x] print(f"ROI shape: {roi.shape}, Center x: {center_x}, Center y: {center_y}") print(f"Q1 shape: {Q1.shape}, Q2 shape: {Q2.shape}, Q3 shape: {Q3.shape}, Q4 shape: {Q4.shape}") try: # Inverse Abel transform - 移除origin参数 abel_transform_result = transform.Transform( roi, method='hansenlaw', symmetry_axis=center_x, direction='inverse', ) except Exception as e: print("Fout tijdens Abel-transformatie:", e) return inv_abel = abel_transform_result.transform # Plot the ROI and its reconstruction fig2, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4)) vmin = np.min(inv_abel) vmax = np.max(inv_abel) ax1.imshow(roi, cmap='viridis') ax1.set_title('Selected ROI') ax2.imshow(inv_abel, cmap='viridis', vmin=vmin, vmax=vmax) ax2.set_title('Inverse Abel') plt.tight_layout() plt.show() # --- Main figure with selector --- fig, ax = plt.subplots() ax.imshow(heatmap, cmap='viridis') # 绘制主图的对称轴参考线 cx = heatmap.shape[1] // 2 ax.axvline(x=cx, color='red', linestyle='--') ax.set_title('Drag to select ROI (red line: global symmetry axis)') # Set up the RectangleSelector selector = RectangleSelector( ax, onselect, useblit=True, button=[1], # Left mouse only minspanx=5, minspany=5, # Ignore tiny slivers spancoords='pixels', interactive=True ) plt.show()
额外提示
- 我把你之前误画在ROI子图的竖线移到了主图逻辑里,这样全局对称轴参考线会显示在主图上,更直观。
- 如果调试时发现Q3确实是空的,建议避免选择过于贴近图像边缘的区域,防止ROI的y范围出现异常。
内容来源于stack exchange
相关产品推荐
相关产品推荐

