为何代码中括号会引发OpenCV的imwrite断言错误?
问题:OpenCV imwrite报错
!_img.empty(),修改索引括号后解决的原因? 错误信息
cv.imwrite(f'spidershow{i+1}.png',canvas[i*height:i*(height+1)-1,0:500]) cv2.error: OpenCV(4.8.0) /Users/runner/work/opencv-python/opencv-python/opencv/modules/imgcodecs/src/loadsave.cpp:787: error: (-215:Assertion failed) !_img.empty() in function 'imwrite'
原代码
import cv2 as cv import numpy as np height = 2048 canvas = np.zeros((height*30,500,3), dtype=np.uint8) for i in range(30): cv.imwrite(f'spidershow{i+1}.png',canvas[i*height:i*(height+1)-1,0:500])
修改后可运行的代码
cv.imwrite(f'spidershow{i+1}.png',canvas[i*height:i*height+height-1,0:500])
原因解析
问题核心是数学运算优先级导致的索引计算错误:
原代码的索引表达式
i*(height+1)-1,运算顺序是先算括号内的height+1,再乘i,最后减1。当i=1时,计算结果为1*(2048+1)-1=2048,而起始索引是i*height=2048——此时切片变成2048:2048,在numpy中,起始索引等于结束索引会返回空数组,直接触发了OpenCVimwrite要求输入图片非空的断言错误。修改后的表达式
i*height+height-1,运算顺序是先分别计算i*height和height-1再相加,展开后等价于(i+1)*height -1。对于循环中任意i(0~29),结束索引始终大于起始索引,切片长度为height-1(2047),是有效的非空数组,因此imwrite可以正常执行。
另外补充:原代码的索引逻辑从一开始就不符合拆分30个分片的意图——比如i=0时,原代码的结束索引是-1,numpy会将其转换为数组总长度-1(61439),相当于把几乎整个canvas作为一个分片写入,完全不是预期的2048行分片;修改后的表达式则正确划分了每个分片的范围,每个分片对应canvas中连续的2047行数据。
内容的提问来源于stack exchange,提问作者jfa
相关产品推荐
相关产品推荐

