前言:所谓的蒙太奇效果,就是指用很多张小图片「拼组」成一张全新的图片。当然,也有人把他叫做马赛克拼图。这种图片看起来感觉非常特别,非常神奇!你是否也想自己做一张像这样的照片呢?可别以为真的要用PS手工一张一张去拼凑哦,那可会累死人的。本文展示利用python+opencv来完成马赛克图的制作,效果图如下:
# 预处理填充图片
def before_handle_imgs():
print("正在预处理填充图片:")
readPath = "C:\\Users\\ASUS\\Desktop\\data0"
savePath = "C:\\Users\\ASUS\\Desktop\\data1"
files = os.listdir(readPath)
for file in files:
imgPath = readPath + "\\" + file
img = cv.imread(imgPath)
img = cv.resize(img, (size, size))
cv.imwrite(savePath + "\\" + file, img)
print("预处理填充图片已完成!")
# 预处理待填充图片
def before_handle_img():
print("正在预处理待填充图片:")
width, height = 10800*n, 13900*n
readPath = "C:\\Users\\ASUS\\Desktop\\girl_0.jpg"
savePath = "C:\\Users\\ASUS\\Desktop\\girl_1.jpg"
img = cv.imread(readPath)
img = cv.resize(img, (width, height))
cv.imwrite(savePath, img)
print("预处理待填充图片已完成!")
# 用字典存储每一图及其直方图
def build_index():
print("正在计算各图片直方图:")
readPath = "C:\\Users\\ASUS\\Desktop\\data1"
files = os.listdir(readPath)
dist = {
}
for file in files:
imgPath = readPath + "\\" + file
img = cv.imread(imgPath)
hist = []
for i in range(3):
ht = cv.calcHist([img], [i], None, [256], [0, 256])
hist.append(ht)
dist[file] = hist
print("各图片直方图计算已完成!")
return dist
# 用最相近的图代替原图
def match_replace(dist):
print("正在替换图片:")
width, height = 10800 * n, 13900 * n
image = cv.imread("C:\\Users\\ASUS\\Desktop\\girl_1.jpg")
for i in range(0, height, size):
for j in range(0, width, size):
img = image[i:i+size, j:j+size, 0:3]
hist = []
for k in range(3):
ht = cv.calcHist([img], [k], None, [256], [0, 256])
hist.append(ht)
sim = 0.0
for key in dist:
match0 = cv.compareHist(hist[0], dist[key][0], cv.HISTCMP_CORREL)
match1 = cv.compareHist(hist[1], dist[key][1], cv.HISTCMP_CORREL)
match2 = cv.compareHist(hist[2], dist[key][2], cv.HISTCMP_CORREL)
match = match0 + match1 + match2
if match > sim:
sim = match
rename = key
image[i:i+size, j:j+size, 0:3] = cv.imread("C:\\Users\\ASUS\\Desktop\\data1\\" + rename)
cv.imwrite("C:\\Users\\ASUS\\Desktop\\girls_0.jpg", image)
print("图片替换已完成!")
# 混合图片
def mix_image():
print("正在融合图片:")
image1 = cv.imread("C:\\Users\\ASUS\\Desktop\\girls_0.jpg")
image2 = cv.imread("C:\\Users\\ASUS\\Desktop\\girl_1.jpg")
dst = cv.addWeighted(image1, 0.2, image2, 0.8, 3)
cv.imwrite("C:\\Users\\ASUS\\Desktop\\girls_1.jpg", dst)
print("图片融合已完成!")
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import cv2 as cv
import os
n = 1
# 预处理填充图片
def before_handle_imgs():
print("正在预处理填充图片:")
readPath = "C:\\Users\\ASUS\\Desktop\\data0"
savePath = "C:\\Users\\ASUS\\Desktop\\data1"
files = os.listdir(readPath)
for file in files:
imgPath = readPath + "\\" + file
img = cv.imread(imgPath)
img = cv.resize(img, (160, 90))
cv.imwrite(savePath + "\\" + file, img)
print("预处理填充图片已完成!")
# 预处理待填充图片
def before_handle_img():
print("正在预处理待填充图片:")
width, height = 25600*n, 14400*n
readPath = "C:\\Users\\ASUS\\Desktop\\img1.jpg"
savePath = "C:\\Users\\ASUS\\Desktop\\img2.jpg"
img = cv.imread(readPath)
img = cv.resize(img, (width, height))
cv.imwrite(savePath, img)
print("预处理待填充图片已完成!")
# 用字典存储每一图及其直方图
def build_index():
print("正在计算各图片直方图:")
readPath = "C:\\Users\\ASUS\\Desktop\\data1"
files = os.listdir(readPath)
dist = {
}
for file in files:
imgPath = readPath + "\\" + file
img = cv.imread(imgPath)
hist = []
for i in range(3):
ht = cv.calcHist([img], [i], None, [256], [0, 256])
hist.append(ht)
dist[file] = hist
print("各图片直方图计算已完成!")
return dist
# 用最相近的图代替原图
def match_replace(dist):
print("正在替换图片:")
width, height = 25600 * n, 14400 * n
image = cv.imread("C:\\Users\\ASUS\\Desktop\\img2.jpg")
for i in range(0, height, 90):
for j in range(0, width, 160):
img = image[i:i+90, j:j+160, 0:3]
hist = []
for k in range(3):
ht = cv.calcHist([img], [k], None, [256], [0, 256])
hist.append(ht)
sim = 0.0
for key in dist:
match0 = cv.compareHist(hist[0], dist[key][0], cv.HISTCMP_CORREL)
match1 = cv.compareHist(hist[1], dist[key][1], cv.HISTCMP_CORREL)
match2 = cv.compareHist(hist[2], dist[key][2], cv.HISTCMP_CORREL)
match = match0 + match1 + match2
if match > sim:
sim = match
rename = key
image[i:i+90, j:j+160, 0:3] = cv.imread("C:\\Users\\ASUS\\Desktop\\data1\\" + rename)
cv.imwrite("C:\\Users\\ASUS\\Desktop\\img3.jpg", image)
print("图片替换已完成!")
# 混合图片
def mix_image():
print("正在融合图片:")
image1 = cv.imread("C:\\Users\\ASUS\\Desktop\\img3.jpg")
image2 = cv.imread("C:\\Users\\ASUS\\Desktop\\img2.jpg")
dst = cv.addWeighted(image1, 0.2, image2, 0.8, 3)
cv.imwrite("C:\\Users\\ASUS\\Desktop\\img4.jpg", dst)
print("图片融合已完成!")
if __name__ == "__main__":
before_handle_imgs()
before_handle_img()
dist = build_index()
match_replace(dist)
mix_image()
原图:
替代后:
混合后:
细节:
码文不易,如果觉得对你有用的话,点个赞再走吧,谢谢宁!
(才疏学浅,如果有什么说的不对的地方,欢迎大家在评论区或者私信进行指正。)