效果
话不多说,先看实际效果。
熊猫为主图,苹果为融入源。
保留熊猫的边缘信息与部分颜色信息,融入苹果的部分色彩信息
融入的比例可以动态调整
原理
这里就简单介绍下,详细内容请自行查阅资料
参考链接1
高斯金字塔
对整个图像不断高斯滤波以及下采样,构成的所有图像集合才构成了图像的高斯金字塔。
差分金字塔(拉普拉斯金字塔)
对高斯金字塔逐层作差,得到损失信息。
Q: 损失信息是什么?
A: 高斯滤波会损失高频信息,高频信息一般是边缘等变化强烈的信息。
重构与融合
将差分金字塔里的顶层(即最小的边缘信息)加到高斯金字塔里的相应层数去(可以看做颜色信息,可以对颜色信息进行修改,比如将原颜色信息替换成融入源的),再进行上采样,然后继续加上差分金字塔里的相应层数的信息…如此往复
注意:本篇文章在选择底层颜色信息时只是随机选择的,当然有更好的方法。
代码
import cv2
import numpy as np
import random
def Preview(src_1,src_2):
img1 = cv2.imread(src_1)
img2 = cv2.imread(src_2)
#创建高斯金字塔
gaussian_py_1 = [img1]
gaussian_py_2 = [img2]
#创建拉普拉斯金字塔
lapalace_py_1 = []
lapalace_py_2 = []
layers = 5
#高斯金字塔
for i in range(5):
tmp_1 = cv2.pyrDown(gaussian_py_1[i])
tmp_2 = cv2.pyrDown(gaussian_py_2[i])
gaussian_py_1.append(tmp_1)
gaussian_py_2.append(tmp_2)
##拉普拉斯金字塔
for i in range(5,0,-1):
rows_1,cols_1 = gaussian_py_1[i-1].shape[:2]
tmp_1 = cv2.pyrUp(src = gaussian_py_1[i],dstsize = (cols_1,rows_1))
tmp_1 = cv2.subtract(gaussian_py_1[i-1],tmp_1)
lapalace_py_1.append(tmp_1)
rows_2,cols_2 = gaussian_py_2[i-1].shape[:2]
tmp_2 = cv2.pyrUp(src = gaussian_py_2[i],dstsize = (cols_2,rows_2))
tmp_2 = cv2.subtract(gaussian_py_2[i-1],tmp_2)
lapalace_py_2.append(tmp_2)
cv2.namedWindow("Preview",cv2.WINDOW_NORMAL)
cv2.createTrackbar("Percent","Preview",0,100,nothing)
while(1):
percent = cv2.getTrackbarPos("Percent","Preview")
a=fusion_func(gaussian_py_1[5].copy(),gaussian_py_2[5].copy(),percent,lapalace_py_1)
cv2.imshow("Result",a)
k = cv2.waitKey(1000) & 0xff
if k == 27:
break
cv2.destroyAllWindows()
def fusion_func(img1,img2,percent,lapalace_py_1):
ori_fusion_pyramid = []
src_1 = img1
src_2 = img2
rows,cols = img1.shape[:2]
total_size = rows*cols
src_2 = cv2.resize(src_2,(cols,rows))
history = []
#颜色融合
for i in range(int(total_size*percent/100)):
random_row = random.randint(0,rows-1)
random_col = random.randint(0,cols-1)
while((random_row,random_col) in history):
random_row = random.randint(0,rows-1)
random_col = random.randint(0,cols-1)
src_1[random_row][random_col] = src_2[random_row][random_col]
history.append((random_row,random_col))
ori_fusion_pyramid.append(src_1)
#重构
for i in range(5):
tmp = cv2.pyrUp(ori_fusion_pyramid[i])
rows,cols,_ = lapalace_py_1[i].shape
tmp = cv2.resize(tmp,(cols,rows))
tmp = cv2.add(tmp,lapalace_py_1[i])
ori_fusion_pyramid.append(tmp)
return ori_fusion_pyramid[-1]
def nothing(whatever):
pass
# 按Esc退出
img1_Path = 'Panda.jpg'
img2_Path = 'apple.png'
Preview(img1_Path,img2_Path)