蒙太奇照片制作(Opencv+Python)

先看一下效果展示吧:

  • 原图(1350x1800):
    蒙太奇照片制作(Opencv+Python)_第1张图片
  • 替代后(45x72的图片,共计62500张,拼成13500x18000的效果图):
  • 和原图融合后的最终效果(可以增加一些清晰度):
  • 细节图:

算法思路:

  1. 修改那些提前准备的一堆图片的大小到马赛克般大小。(根据你自己准备的图片修改尺寸,我的原图是1080x1440的,为了修改之后不失真,我把图片resize成了45x72,刚好是20倍)
  2. 放大目标图片的长宽,使之长宽都是马赛克大小的整数倍.(我的原图是1350x1800,放大到13500x18000,这个刚好是马赛克图片的62500倍)
  3. 计算每一张图片的直方图,建立索引字典。
  4. 以马赛克大小为单位遍历目标图片同时计算这个区域的直方图,然后和提前准备的用于替换的马赛克图片的直方图的相关性进行比较,用直方图相关性最大的替换目标图片。
  5. 用全替换好的图片和2. 产生的图片做一个融合,效果更加逼真。

下面看代码:
建议大家分步实现各个功能。

import cv2
import os

# 1.预处理填充图片
def before_handle_imgs():
    print('正在预处理填充图片:')
    readPath = 'C:/Users/Project_FuHuan/1'
    savePath = "C:/Users/myJupyter/romantic_data2"
    
    files = os.listdir(readPath)
    
    for file in files:
        imgPath = readPath + "/" +file
        img = cv2.imread(imgPath)
        img = cv2.resize(img,(54,72))
        cv2.imwrite(savePath + '/' + file,img)
    print ('预处理填充图片已完成!')
    
# 2.预处理待填充图片
def before_handle_img():
    print('正在处理待填充图片:')
    width,height = 13500,18000
    readPath = 'v.jpg'
    img = cv2.imread(readPath)
    img = cv2.resize(img,(width,height))
    cv2.imwrite('v_2.jpg',img)
    print('预处理待填充图片已完成!')
    
# 3.用字典存储每一张图及直方图
def build_index():
    print('正在计算各图片直方图')
    readPath = "C:/Users/myJupyter/romantic_data2"
    files = os.listdir(readPath)
    dist = {}
    
    for file in files:
        imgPath = readPath + '/' + file
        img = cv2.imread(imgPath)
        hist = []
        
        for i in range(3):
            ht = cv2.calcHist([img],[i],None,[256],[0,256])
            hist.append(ht)
        dist[file] = hist
    
    print ('各图片直方图计算已完成!')
    return dist
    
# 4.用相近的图代替原图
def match_replace(dist):
    print ('正在替换图片:')
    width,height = 13500,18000
    image = cv2.imread('v_2.jpg')
    
    for i in range(0,height,72):
        for j in range(0,width,54):
            img = image[i:i+72,j:j+54,0:3]
            
            hist = []
            for k in range(3):
                ht = cv2.calcHist([img],[k],None,[256],[0,256])
                hist.append(ht)
                
            sim = 0.0
            for key in dist:
                match0 = cv2.compareHist(hist[0],dist[key][0],cv2.HISTCMP_CORREL)
                match1 = cv2.compareHist(hist[1],dist[key][1],cv2.HISTCMP_CORREL)
                match2 = cv2.compareHist(hist[2],dist[key][2],cv2.HISTCMP_CORREL)
                match = match0 + match1 + match2
                
                if match > sim:
                    sim = match
                    rename = key
            image[i:i+72,j:j+54,0:3] = cv2.imread('C:/Users/myJupyter/romantic_data2/'+rename)
    cv2.imwrite('v_3.jpg',image)
    print ('图片替换已完成!')
    
# 5.混合图片
def mix_image():
    print('正在融合图片:')
    image1 = cv2.imread('v_2.jpg')
    image2 = cv2.imread('v_3.jpg')
    dst = cv2.addWeighted(image1,0.2,image2,0.8,3)
    cv2.imwrite('v_mix.jpg',dst)
    print ('图片融合已完成!')
    
if __name__ == "__main__":
    before_handle_imgs()
    before_handle_img()
    dist = build_index()
    match_replace(dist)
    mix_image()

参考链接:
https://zhuanlan.zhihu.com/p/168667043
https://blog.csdn.net/shuiyixin/article/details/80257822

你可能感兴趣的:(Opencv)