本次学习将图像或者图像的一部分放置在另一幅图像中,使得它们能够和指定的区域或标记物对齐,以集美大学的建筑为实验对象,本次实验将图一放置到图二中。
图一:
图二:
使用一个函数image_in_image(),输入两幅图像和一个坐标,通过仿射变换,将图像扭曲至与粘贴对象相近,再将扭曲的图像与粘贴对象融合,创建成alpha图像。
1.仿射变换原理:仿射变换(Affine Transformation 或Affine Map)是一种二维坐标(x, y)到二维坐标(u, v)的线性变换,也就是对图像的旋转拉伸,其数学表达式形式如下:
对应的齐次坐标矩阵表示形式为:
在图像处理中,可以通过一系列原子变换复合实现图片的平移、缩放、旋转、翻转和错切,从而实现仿射变换。
2.alpha通道原理:
对于一张图片而言,其具有透明度是因为它除了具有RGB三个颜色通道以外还拥有一个alpha通道,其值范围为0-255,越靠近0越透明,反之越靠近255越不透明,0为完全透明,255为完全不透明。
alpha混色是将源像素和背景像素的颜色进行混合,最终显示的颜色取决于其RGB颜色分量和Alpha值。它们之间的关系可用下列公式来表示:
显示颜色 = 源像素颜色 X alpha / 255 + 背景颜色 X (255 - alpha) / 255
3.代码实现:
使用狄洛克三角剖分方法时提示错误
即,matplotlib库中已经不再支持delaunay模块了。所以我们需要寻找一个别的模块来代替它。在开始之前,我们需要进入到warp.py里,首先修改一下其头文件为:
from scipy.spatial import Delaunay
from scipy import ndimage
from pylab import *
from numpy import *
from PCV.geometry import homography
实现代码为:
def image_in_image(im1,im2,tp):
# points to warp from
m,n = im1.shape[:2]
fp = array([[0,m,m,0],[0,0,n,n],[1,1,1,1]])
# compute affine transform and apply
H = homography.Haffine_from_points(tp,fp)
im1_t = ndimage.affine_transform(im1,H[:2,:2],
(H[0,2],H[1,2]),im2.shape[:2])
alpha = (im1_t > 0)
return (1-alpha)*im2 + alpha*im1_t
im1 = array(Image.open('../data/beatles.jpg').convert('L'))
im2 = array(Image.open('../data/billboard_for_rent.jpg').convert('L'))
# set to points
tp = array([[120,260,260,120],[16,16,305,305],[1,1,1,1]])
#tp = array([[675,826,826,677],[55,52,281,277],[1,1,1,1]])
im3 = warp.image_in_image(im1,im2,tp)
figure()
gray()
subplot(141)
axis('off')
imshow(im1)
subplot(142)
axis('off')
imshow(im2)
subplot(143)
axis('off')
imshow(im3)
使用坐标值为(430,426),(426,516),(589,522),(596,438)时:
使用坐标值为:(429,384),(431,478),(793,486),(792,386)时
备注:使用ginput函数时获得的坐标遵循从左上角逆时针,纵坐标在前横坐标在后的位置放进数组中。
附录:抓坐标工具:
# coding: utf-8
import cv2
img = cv2.imread("D:/python2019/code/warp/zhuang.jpg")
# print img.shape
def on_EVENT_LBUTTONDOWN(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
xy = "%d,%d" % (x, y)
cv2.circle(img, (x, y), 1, (255, 0, 0), thickness=-1)
cv2.putText(img, xy, (x, y), cv2.FONT_HERSHEY_PLAIN,
1.0, (0, 0, 0), thickness=1)
cv2.imshow("image", img)
cv2.namedWindow("image")
cv2.setMouseCallback("image", on_EVENT_LBUTTONDOWN)
cv2.imshow("image", img)
while (True):
try:
cv2.waitKey(100)
except Exception:
cv2.destroyAllWindows()
break
cv2.waitKey(0)
cv2.destroyAllWindows()