前言
昨天是腊八,大家喝腊八粥了吗?反正我是忘了
开始
献上代码
from PIL import Image
import numpy as np
import os
def make(imgMat):
img = Image.new("RGB",(64 * len(imgMat),64 * len(imgMat[0])))
for i in range(len(imgMat)):
for j in range(len(imgMat[i])):
imgMat[i][j] = imgMat[i][j].resize((64,64))
img.paste(imgMat[i][j],(64 * i,64 * j))
return img
def split(img,w,h):
mat = []
for i in range(h):
l = []
for j in range(w):
box = (64 * i,64 * j,64 * i + 64,64 * j + 64)
l.append(img.crop(box))
mat.append(l)
return mat
def mean_color(img):
r,g,b,*_ = img.split()
r = np.array(r)
g = np.array(g)
b = np.array(b)
r = np.mean(r.flatten())
g = np.mean(g.flatten())
b = np.mean(b.flatten())
return r,g,b
def distance(img1,img2):
r,g,b = mean_color(img1)
R,G,B = mean_color(img2)
dr,dg,db = R - r,G - g,B - b
return np.sqrt(dr ** 2 + dg ** 2 + db ** 2)
def choose(imglist,img):
mindist = 500
minImage = None
for i in imglist:
dist = distance(i,img)
if(dist < mindist):
mindist = dist
minImage = i
return minImage
def process(imgList,img,w,h):
mat = split(img,w,h)
res = []
for i in mat:
l = []
for j in i:
l.append(choose(imgList,j))
res.append(l)
return make(res)
def main():
wh = input('how many images you want to fill the width and height?(w h):').strip()
path = input('please input the directory you save the filling images:').strip()
path_ori = input('please input the original image path:').strip()
path_save = input('please input the path you want to save the image:').strip()
h,w = wh.split(' ')
w,h = int(w),int(h)
imgList = []
for i in os.listdir(path):
try:
i = os.path.join(path,i)
img = Image.open(i)
imgList.append(img)
except:
pass
img = Image.open(path_ori)
img = img.resize((64 * h,64 * w))
res = process(imgList,img,w,h)
res.save(path_save)
if(__name__ == '__main__'):
main()
代码剖析
from PIL import Image
import numpy as np
import os
导入库
def make(imgMat):
img = Image.new("RGB",(64 * len(imgMat),64 * len(imgMat[0])))
for i in range(len(imgMat)):
for j in range(len(imgMat[i])):
imgMat[i][j] = imgMat[i][j].resize((64,64))
img.paste(imgMat[i][j],(64 * i,64 * j))
return img
将imgMat
中的图片拼成一张大图片,主要分以下几个步骤
↓
\downarrow
↓
- 创建新的图片
- 一张一张粘贴(paste)在这张图片上
def split(img,w,h):
mat = []
for i in range(h):
l = []
for j in range(w):
box = (64 * i,64 * j,64 * i + 64,64 * j + 64)
l.append(img.crop(box))
mat.append(l)
return mat
将img
分割成h
行w
列的小图片,主要分以下几个步骤
↓
\downarrow
↓
- 创建一个存放结果的图片矩阵
- 从大图片上一张一张的剪(crop)下来
def mean_color(img):
r,g,b,*_ = img.split()
r = np.array(r)
g = np.array(g)
b = np.array(b)
r = np.mean(r.flatten())
g = np.mean(g.flatten())
b = np.mean(b.flatten())
return r,g,b
求图片的平均颜色,即求图片红的平均值,绿的平均值和蓝的平均值
def distance(img1,img2):
r,g,b = mean_color(img1)
R,G,B = mean_color(img2)
dr,dg,db = R - r,G - g,B - b
return np.sqrt(dr ** 2 + dg ** 2 + db ** 2)
求两张图片的欧几里得距离,可以形象的理解为一个 n n n维的勾股定理。
def choose(imglist,img):
mindist = 500
minImage = None
for i in imglist:
dist = distance(i,img)
if(dist < mindist):
mindist = dist
minImage = i
return minImage
从一堆图片里取出一个与img
最相似的距离,即求一堆图片中与img
欧几里得距离最短的一个
def process(imgList,img,w,h):
mat = split(img,w,h)
res = []
for i in mat:
l = []
for j in i:
l.append(choose(imgList,j))
res.append(l)
return make(res)
将一个图片分割后去imgList
中与其最相近(欧几里得距离最短)的一个,然后再拼接起来
def main():
wh = input('how many images you want to fill the width and height?(w h):').strip()
path = input('please input the directory you save the filling images:').strip()
path_ori = input('please input the original image path:').strip()
path_save = input('please input the path you want to save the image:').strip()
h,w = wh.split(' ')
w,h = int(w),int(h)
imgList = []
for i in os.listdir(path):
try:
i = os.path.join(path,i)
img = Image.open(i)
imgList.append(img)
except:
pass
img = Image.open(path_ori)
img = img.resize((64 * h,64 * w))
res = process(imgList,img,w,h)
res.save(path_save)
输入数据,处理数据,并调用process
(点击跳转)函数。
项目github
作者
hit-road
拜拜,下课!
回到顶部