一、核心代码
新建 zifupic.py 文件
import cv2
import glob
import argparse
import numpy as np
from tqdm import tqdm # 进度条
from itertools import product # 迭代器
def readSourceImages(sourcepath,blocksize):
print('开始读取图像')
# 合法图像列表
sourceimages = []
# 平均颜色列表
avgcolors = []
for path in tqdm(glob.glob("{}/*.jpg".format(sourcepath))):
image = cv2.imread(path, cv2.IMREAD_COLOR)
#if image.shape[-1] != 3:
# continue
image = cv2.resize(image, (blocksize, blocksize))
avgcolor = np.sum(np.sum(image, axis=0), axis=0) / (blocksize * blocksize)
sourceimages.append(image)
avgcolors.append(avgcolor)
print('结束读取')
return sourceimages,np.array(avgcolors)
def picpin_fun(instance):
parser = argparse.ArgumentParser('拼接马赛克图片')
parser.add_argument('--targetpath', type=str, default=instance.m_image, help='目标图像路径')
parser.add_argument('--outputpath', type=str, default='output.jpg', help='输出图像路径')
parser.add_argument('--sourcepath', type=str, default=instance.style_file_picpin, help='用于拼接图像的所有源图像文件夹路径')
parser.add_argument('--blocksize', type=int, default=5, help='马赛克块大小')
args = parser.parse_args()
targetimage = args.targetpath
outputimage = targetimage # int8 int16 int32 int64
sourceimages,avgcolors = readSourceImages(args.sourcepath,args.blocksize)
print('开始制作')
for i, j in tqdm(product(range(int(targetimage.shape[1]/args.blocksize)), range(int(targetimage.shape[0]/args.blocksize)))):
block = targetimage[j * args.blocksize: (j + 1) * args.blocksize, i * args.blocksize: (i + 1) * args.blocksize,:]
avgcolor = np.sum(np.sum(block, axis=0), axis=0) / (args.blocksize * args.blocksize)
distances = np.linalg.norm(avgcolor - avgcolors, axis=1)
idx = np.argmin(distances)
outputimage[j * args.blocksize: (j + 1) * args.blocksize, i * args.blocksize: (i + 1) * args.blocksize, :] = \
sourceimages[idx]
#cv2.imwrite(args.outputpath, outputimage)
instance.m_image = outputimage
instance.updata_image()
print('制作完成')
二、UI界面
需要实现可以自定义选择图片库
# 创建一个窗口,定义位置,标题等属性
instance.widget_picpin=QWidget()
instance.widget_picpin.setGeometry(300, 300, 280, 170)
instance.widget_picpin.setWindowTitle('多照片合成')
# 创建一个按钮,该按钮的父对象为instance.widget_neural_style_transfer
# 当该按钮被点击时执行信号发射函数
instance.button_picpin=QPushButton("开始",instance.widget_picpin)
instance.button_picpin.setGeometry(30, 50, 50, 50)
instance.button_picpin.clicked.connect(instance.picpin_emit)
# 创建一个action,当该action被触发时显示字符画
action_zifu_show = QAction('&照片转字符图画', instance)
action_zifu_show.triggered.connect(instance.zifupic_emit)
# 艺术风格迁移选项新增一个action:照片转字符画
tempMenu.addAction(action_zifu_show)
# 合成的图片库路径
instance.style_file_picpin = ""
instance.button_choose_style_image = QPushButton("选择图片库路径", instance.widget_picpin)
instance.button_choose_style_image.clicked.connect(instance.open_file_and_change_name2)
instance.label_picpin_file = QLabel(instance.widget_picpin)
instance.label_picpin_file.setGeometry(30, 100, 500, 50)
instance.label_picpin_file.setText("合成图片库路径")
更改m_ui.py
def open_file_and_change_name2(self):
#self.style_file_transfer=QFileDialog.getOpenFileName(self, '选择文件',self.root_path+"/part3/images")
self.style_file_picpin =QFileDialog.getExistingDirectory(self,'选择文件夹',self.root_path)
self.label_picpin_file.setText(self.style_file_picpin)
def picpin_emit(self):
pic_pin.picpin_fun(self)
三、效果
以下图片是从96张图片库中挑选合适的图片组合而来的。
有一种马赛克 / 十字绣的效果。
四、参考链接
参考链接:2万8千张图片组合成一张