cv2.imshow多图显示时前三窗口同显仅红通道图像的异常问题
问题根因
你看到的三个窗口显示完全相同的零蓝绿通道图像,本质是NumPy数组的赋值浅引用机制导致的:
- 代码里写的
no_blue = img、no_green = img,并没有生成独立的图像数据副本,只是给原本的img数组对象新增了两个指向同一块内存地址的别名。三个变量底层操作的是完全相同的一份图像数据。 - 后续执行
no_blue[:,:,0] = 0给蓝色通道置零、no_green[:,:,1] = 0给绿色通道置零的时候,修改的是所有变量共享的同一块内存。等调用imshow的时候,这份共享数据已经被两步操作改得仅保留红色通道的有效值,所以绑定到这份数据上的三个窗口自然显示完全一样的内容。 - 第四个窗口显示正常,是因为
only_red = img[:,:,2]是单通道切片,虽然同样是浅引用,但它的内容范围本身就仅对应原图的红色通道像素,所以展示效果和预期一致。
修正方案
要生成不受联动影响的独立图像副本,不能直接用等号赋值,需要调用NumPy数组的深拷贝方法开辟独立内存空间:
# 替换原有别名赋值的代码段 no_blue = img.copy() no_green = img.copy() only_red = img[:,:,2].copy()
修改后的代码执行逻辑:
- 基于原始
img的数据,分别在独立的内存空间生成no_blue、no_green两份副本 - 后续对两个副本的通道置零操作,只会修改各自对应的独立数据,不会反向改动原始
img的内容 - 三个多通道窗口会分别展示原始彩色图、去除蓝色通道的图像、去除绿色通道的图像,不会再出现内容联动重叠的问题
快速排查技巧
如果需要快速判断两个数组变量是否共享同一块内存,可以在代码中插入判断语句:print(no_blue.base is img)
当输出为True时,说明两个变量是浅引用关联,必须通过.copy()生成独立副本,否则后续的修改操作会互相影响。
内容的提问来源于stack exchange,提问作者Raz
相关产品推荐
相关产品推荐

