1. 处理思想: 将两张图像换到频域, 分别保留低频高频信息, 然后合并
2. 过程分析:
先对猫的图片傅里叶变换, 将低频信息偏移到中心 , 然后置0挖孔
def Hybrid(catimg,dogimg,hole=10):
#cat过滤低频
#傅里叶变换
f_catimg=np.fft.fft2(catimg)
f_catimg=np.fft.fftshift(f_catimg)
#取得中孔位置, 挖掉中孔, 过滤低频量
h,w=catimg.shape
f_catimg[int(h/2-hole):int(h/2+hole),int(w/2-hole):int(w/2+hole)]=0
对狗的图片变换, 除中心孔以外, 将其他地方都置0 ,仅保留低频信息
#dog保留低频
#傅里叶变换
f_dogimg=np.fft.fft2(dogimg)
f_dogimg=np.fft.fftshift(f_dogimg)
#仅保留中孔, 过滤高频量
h,w=dogimg.shape
f_dogimg[:int(h/2-hole),:]=0
f_dogimg[int(h/2+hole):,:]=0
f_dogimg[:,:int(w/2-hole)]=0
f_dogimg[:,int(w/2+hole):]=0
最后将两张互补的频域图合并, 但注意简单合并会带来问题:
1. 相加合并的图, 值的范围很可能超过[0,255], 假如就这样逆变换回去的话, 会出现大片的彩色乱码, 即数值溢出造成的损失, 所以需要归一化处理.
2. 此时合并出来的矩阵数据类型是np.ndarray, float64. 如果想要安全的显示图像最好换成np.uint8
float64的时候我用plt.imshow显示没有问题, 但是三通道合并后无法显示
3. 合并需要两张大小相同的图像, 否则会出错, 因此可以考虑做大小图像的兼容.
3. 主程序
if __name__ == "__main__":
catimg=cv2.imread("./cat.jpg")
dogimg=cv2.imread("./dog.jpg")
#彩色猫狗图像分别对三通道进行处理
B_merge=Hybrid(catimg[:,:,0],dogimg[:,:,0])
plt.subplot(221),plt.imshow(B_merge,cmap='gray')
G_merge=Hybrid(catimg[:,:,1],dogimg[:,:,1])
plt.subplot(222),plt.imshow(G_merge,cmap='gray')
R_merge=Hybrid(catimg[:,:,2],dogimg[:,:,2])
plt.subplot(223),plt.imshow(R_merge,cmap='gray')
#合并三通道显示 猫狗
img_merge=cv2.merge([B_merge,G_merge,R_merge])
print(img_merge)
plt.subplot(224),plt.imshow(img_merge)
plt.show()
#人像合成
wholeimg=cv2.imread("./marilyn-einstein-hybrid-collage.png",0)
h,w=wholeimg.shape
first_img=wholeimg[:,:int(w/3)]
second_img=wholeimg[:,int(w/3):int(2*w/3)]
img_hybrid=Hybrid(first_img,second_img,30)
plt.figure(figsize=[12.8,9.6]),plt.imshow(img_hybrid,cmap='gray')
plt.show()
4. 效果图
其中hole参数自己感受感受, 不同的参数有完全不同的效果体现.