Python实现图像像素主色转换后调用Pyplot imshow仅显示坐标轴不显示图像
主色转换代码渲染异常排查与修复
问题根因
- 最核心的逻辑错误:
draw函数里的arr.reshape(np.shape(img))写法不对。numpy的reshape方法不会直接修改原数组,只会返回重塑后的新数组。你调用了方法但没有把返回值存下来,arr从头到尾都是把所有像素堆在一起的一维扁平数组,根本没有图像需要的“高度-宽度-颜色通道”三维结构,plt.imshow识别不出合法图像格式,自然只显示坐标轴不渲染内容。 - 容易踩的隐藏坑:原代码里三个分支判断,没有覆盖像素三个通道数值完全相等的场景,这类像素不会被追加到转换列表里,最终列表长度和原图像素总数对不上,哪怕reshape写对了也会直接报维度错误。
- 不良代码习惯:用内置名
list当函数参数、靠全局变量x传值,不仅代码可读性差,多次调用时还会因为全局值残留出现莫名其妙的结果。 - 小细节提醒:8位RGB图像的单通道取值范围是0-255,之前举例提到的(256,0,0)是超出合法范围的写法,代码里用255是正确的。
修复后可直接运行的代码
import matplotlib.pyplot as plt import numpy as np import skimage.data as data def draw(pixel_list, img): arr = np.array(pixel_list) # 接收reshape返回的重塑后数组,对齐原图的三维结构 reshaped_img = arr.reshape(np.shape(img)) plt.imshow(reshaped_img) plt.show() def convert(image): converted_pixels = [] for row in image: for pixel in row: r, g, b = pixel max_val = max(r, g, b) # 把三通道相等的场景归到蓝色分支,避免漏算像素 if max_val == r: converted_pixels.append([255, 0, 0]) elif max_val == g: converted_pixels.append([0, 255, 0]) else: converted_pixels.append([0, 0, 255]) draw(converted_pixels, image) convert(data.rocket())
性能优化小技巧
手动双重循环遍历像素效率很低,可以换成numpy向量化操作,几行代码就能实现相同效果,运行速度比循环快上百倍:
def convert_fast(image): # 直接找每个像素RGB三个通道中最大值所在的索引 max_channel_idx = np.argmax(image, axis=-1) # 初始化全零的三通道图像 result = np.zeros_like(image) # 给对应最大值的通道赋值为255 result[max_channel_idx == 0, 0] = 255 result[max_channel_idx == 1, 1] = 255 result[max_channel_idx == 2, 2] = 255 plt.imshow(result) plt.show()
内容的提问来源于stack exchange,提问作者goup
相关产品推荐
相关产品推荐

