用python制作马赛克式/蒙太奇拼图(小图片作为像素拼成大图片)

小时候看见课本上有用人的照片作为基本元素拼出来的人脸,感觉特别有趣,后来学了ps发现ps做不出来这个效果(其实可以,但是人工很重,效果也不好。具体见:https://www.zhihu.com/question/23820935)后来学了算法后接触了一下图像处理,感觉其实这个东西不难做,把图片当作像素处理就好了,然后就想做一个玩玩。

原理其实很简单,把目标图像划分成许多区域,然后从给定的图库里寻找一张和本区域最相似的图片,将找到的图片贴到对应区域上,重复这一过程,然后就得到了目标图片。寻找相似图片的算法有很多,我这里直接套用了我以前的代码--计算图片三个通道的平均值,和目标做差,在图库中比较差的大小。寻找相似图片的算法还有很多,具体可以参考https://blog.csdn.net/u011397539/article/details/82982499哈希类算法和https://blog.csdn.net/weixin_39121325/article/details/84187453

选取不同算法有不同的考虑,虽然在相似度的比较上平均值法不好用,但取平均值只需计算一次,而直方图和余弦算法需要一次次计算和对比。(我的代码里算平均值没有对图片缩放,导致第一次算耗时特别长。)其次我觉得当图片缩小到一个接近于像素的小区域内时,直接对通道取平均值也许更接近原来像素的通道水平。

接下来就是代码了,第一部分是我之前写的相似度算法:

import os, sys
from PIL import Image
from PIL import ImageFilter
import numpy as np
import logging
import json

def act(di):
    for i in di.keys():
        di[i]=di[i][0]
    return None



def CalWeight(str):
    """
    what is the differ?
    well, it is the index of this function is filename rather not the file pointer
    """
    pos=0.0
    temp=[]
    img=Image.open(str)
    #r, g, b = img.split()
    for m in img.split():
        total=0
        m=np.array(m)
        for n in m:
            for i in n:
                total+=i
        pos=total/m.size
        temp.append(pos)
    return temp


class similar:
    """
self.input=args[1]
self.TargetFolder=args[2]
    """


    def __init__(self, *args, **kwargs):
        if len(args)==3:    #or 3?
            self.log=None
            self.out={}  #nmae:[weight_point]
            self.standard=[]
            self.Best_Match=  ""
            self.input=args[0]
            self.TargetFolder=args[1]
            self.log=args[2]
        elif len(args)==2 and args[0]=="load":
            self.load()
            self.log=args[1]
        else:
            self.out={}  #nmae:[weight_point]
            self.input=""
            self.TargetFolder=""
            self.Best_Match=""   #name
            self.standard=[]
            self.log=args[0]
        return None

    def _CalWeight(self,img):
        pos=0.0
        temp=[]
        #r, g, b = img.split()
        for m in img.split():
            total=0
            m=np.array(m)
  
  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值