Python ValueError无法重塑数组:Mac运行正常Windows报错咨询
报错根因
该报错是因为Chrome截图的实际像素尺寸和你定义的observation_space尺寸不匹配:
- 你预期的单通道图像总像素为
689 * 1024 = 705536 - 实际拿到的截图总像素只有685440,换算下来高度为
685440 / 1024 = 669px,比预期少20px - 跨系统表现不一致、手动调整窗口大小无效的核心原因是:你设置的
window-size=1024,768是整个浏览器窗口的大小,包含了不同操作系统独占的标题栏、地址栏、书签栏等控件的高度,Mac系统下这些控件的总高度刚好让剩余网页视口高度为689px,其他系统下控件高度更高,剩余视口高度就偏小。部分设备开启了系统显示缩放(比如Windows 125%缩放、Mac Retina屏缩放)也会导致实际截图像素和逻辑尺寸不匹配。
可行解决方案
按优先级从高到低排列:
方案1:强制固定网页视口尺寸(最稳定)
不要直接设置浏览器窗口大小,改为通过JS计算浏览器控件的高宽占用,自动调整窗口大小使得实际网页视口刚好等于你需要的1024*689,修改初始化代码:
def __init__(self): super(GeometryDash, self).__init__() options = Options() # 新增两个参数,禁用系统DPI缩放,保证像素1:1对应 options.add_argument("--force-device-scale-factor=1") options.add_argument("--high-dpi-support=1") options.add_experimental_option("excludeSwitches", ['enable-automation']) self.driver = webdriver.Chrome( service=Service(ChromeDriverManager().install()), options=options ) self._init_browser() # 页面加载完成后执行以下代码,固定视口尺寸 target_w, target_h = 1024, 689 # 计算需要的窗口总大小:视口大小 + 浏览器控件占用大小 window_w, window_h = self.driver.execute_script(""" return [ window.outerWidth - window.innerWidth + arguments[0], window.outerHeight - window.innerHeight + arguments[1] ]; """, target_w, target_h) self.driver.set_window_size(window_w, window_h) self.action_space = spaces.Discrete(2) # Jump, No action self.observation_space = spaces.Box( low=0, high=255, shape=(689, 1024, 1), dtype=np.uint8 ) #Images
这个方案可以适配所有操作系统,保证截图尺寸完全符合预期,不需要修改图像处理逻辑。
方案2:居中裁剪截图(不破坏画面比例)
如果你之前直接resize后效果差是因为拉伸扭曲了游戏画面比例,可以改为先等比例缩放宽度到1024,再裁剪/补边到目标高度,不会破坏游戏元素的比例:
@property def observation(self) -> np.array: img = Image.open(io.BytesIO(self.driver.get_screenshot_as_png())).convert('L') target_h, target_w = self.observation_space.shape[:2] # 等比例缩放到宽度刚好为1024 img = img.resize((target_w, int(img.height * target_w / img.width)), Image.Resampling.LANCZOS) # 高度超过就上下居中裁剪 if img.height > target_h: top = (img.height - target_h) // 2 img = img.crop((0, top, target_w, top + target_h)) # 高度不足就上下补黑边 elif img.height < target_h: padding = Image.new('L', (target_w, target_h), 0) padding.paste(img, (0, (target_h - img.height) // 2)) img = padding return np.array(img).reshape(self.observation_space.shape)
内容的提问来源于stack exchange,提问作者infantprogrammer
相关产品推荐
相关产品推荐

