Python中用numpy和image_slicer拼接编辑后图像的问题
问题分析与解决方案
嗨,我来帮你解决这个拼接图像的问题~
你遇到的核心问题是:image_slicer.slice返回的tiles列表里存储的是原始切片的引用/数据,哪怕你修改并保存了磁盘上的切片文件,tiles对象本身并不会自动更新这些信息,所以调用join(tiles)时,还是用的最初分割出来的原始图像切片,而非你修改后的版本。
下面给你两种解决思路,一种是修复你现有代码的问题,另一种是更适合新手理解的全流程实现:
方法1:修复现有代码,更新tiles对象数据
在修改完切片并保存后,我们需要手动把tiles里的原始图像替换成修改后的版本,这样join时就会用新的切片了:
import numpy as np import PIL import image_slicer import math from image_slicer import join from PIL import Image # 分割图像,同时记录每个切片的文件名 tiles = image_slicer.slice("einstein.jpg", 16) tile_filenames = [tile.filename for tile in tiles] # 遍历修改每个切片 for filename in tile_filenames: # 只处理分割出来的切片,避免误操作其他png文件 img = Image.open(filename) arr = np.asarray(img) # 灰度图直接取全局均值即可,简化计算 pixelMean = arr.mean() IntMean = math.floor(pixelMean) pixels = img.load() # 遍历填充像素 for i in range(img.size[0]): for j in range(img.size[1]): pixels[i,j] = (IntMean, IntMean, IntMean) img.save(filename) # 关键步骤:更新tiles里的图像数据 for idx, tile in enumerate(tiles): tile.image = Image.open(tile_filenames[idx]) # 现在拼接的就是修改后的切片了 image = join(tiles) image.save("einsteinJoined.jpg") image.show()
方法2:不用image_slicer,手动实现全流程(更适合新手理解)
其实不需要依赖第三方库,直接用PIL和numpy就能完成整个网格分割、均值填充、拼接的流程,逻辑更清晰,还能避免磁盘文件读写的问题:
import numpy as np import math from PIL import Image # 加载图像并转为灰度模式(如果原图像不是灰度的话) img = Image.open("einstein.jpg").convert("L") # 统一尺寸为256x256,方便分割成n×n网格 img = img.resize((256, 256)) width, height = img.size n = 4 # 设置为4×4网格,对应16个区块 tile_width = width // n tile_height = height // n # 创建空白图像用于存放最终结果 result_img = Image.new("L", (width, height)) # 遍历每个网格区块 for col in range(n): for row in range(n): # 计算当前区块的坐标范围 left = col * tile_width top = row * tile_height right = left + tile_width bottom = top + tile_height # 截取当前区块 tile = img.crop((left, top, right, bottom)) # 计算区块的平均灰度值 tile_arr = np.asarray(tile) mean_gray = math.floor(tile_arr.mean()) # 创建填充后的单色区块 filled_tile = Image.new("L", (tile_width, tile_height), mean_gray) # 将填充后的区块粘贴到结果图像对应位置 result_img.paste(filled_tile, (left, top)) # 保存并显示结果 result_img.save("einstein_grid.jpg") result_img.show()
这个方法全程在内存中处理,不需要生成中间切片文件,步骤更直观,也更容易调试~
内容的提问来源于stack exchange,提问作者user9785589
相关产品推荐
相关产品推荐

