我通过PIL和numpy处理的图片现在是一个numpy array,我希望它存回png格式,于是查到了scipy.misc.toimage可以做到,但是这里面有一些需要注意的地方。
直接上我的code(包含处理过程,image_pooling()的最后一句是存图):
#-*-coding:utf-8-*-
import os
import random
import shutil
from PIL import Image
import numpy as np
from collections import Counter
from scipy import misc
def image_pooling( ori_dir='gtFine/train/', goal_dir='gtFine_pool/train/' ):
sub_dirs_ori = [f1 for f1 in os.listdir(ori_dir) if os.path.isdir(os.path.abspath(os.path.join(ori_dir,f1)))]
# print sub_dirs_ori
# img_index = 0
# train_files = []
# assert len(sub_dirs_data) == len(sub_dirs_labels)
for sub_dir in sub_dirs_ori:
ori_complete_dir = os.path.join(ori_dir, sub_dir)
goal_complete_dir = os.path.join(goal_dir, sub_dir)
os.mkdir(goal_complete_dir)
for f in os.listdir(ori_complete_dir):
ori_path = os.path.abspath(os.path.join(ori_complete_dir, f))
print "original_path is ", ori_path
goal_path = os.path.abspath(os.path.join(goal_complete_dir, f))
print "goal_path is ", goal_path
if os.path.isfile(ori_path) and 'labelIds' in f:
# shutil.copyfile(ori_path, goal_path)
img = np.array(Image.open(ori_path))
print img.shape
img_goal = np.zeros((img.shape[0]//8, img.shape[1]//8))
pool_h = img.shape[0]//8
pool_w = img.shape[1]//8
for i in range(pool_h):
for j in range(pool_w):
img_goal[i,j] = int( Counter((img[8*i:8*(i+1),8*j:8*(j+1)].flatten())).most_common(1)[0][0] )
# print img_goal
misc.toimage(img_goal, cmin=0, cmax=255).save(goal_path)
if __name__ == '__main__':
image_pooling()
需要注意的是看下misc.toimage文档说明和source code,如果我们不给cmin和cmax参数的话,保存的时候会把图像按照矩阵中的最大最小值在0-255区间进行normalization。这不是我想要的结果,所以要给出cmin和cmax,来确保不会这样做。看misc.toimage源码:
def toimage(arr, high=255, low=0, cmin=None, cmax=None, pal=None,
mode=None, channel_axis=None):
........................
data = (data*1.0 - cmin)*(high - low)/(cmax - cmin) + low
.........................
可以看到如果默认high=255, low=0的话,那cmax和cmin也需要分别等于255和0,这一步的处理才不会影响我们把numpy矩阵完好的存成png图像。