使用仿射变换将一幅图像放置到另一幅图像中
一,原理分析
? ? ? ?仿射變換,又稱仿射映射,是指在幾何中,一個向量空間進行一次二維坐標(biāo)到二維坐標(biāo)的線性變換。仿射變換可以來表示:旋轉(zhuǎn) (線性變換),平移 (向量加),縮放操作 (線性變換),仿射變換代表的是兩幅圖之間的位置關(guān)系。
? ? ? 在本案例中,實現(xiàn)了仿射變換的簡單例子,即將一幅圖像放置到另一幅圖像中,使其能夠和指定區(qū)域或標(biāo)記物對齊。
? ? ? 1.讀取兩張圖像,分別將兩張圖像的每個像素的位置坐標(biāo),以矩陣的形式存儲在數(shù)組中。然后插入到第二張圖像的指定位置,即目標(biāo)點。
這些目標(biāo)點的坐標(biāo)值可通過查看繪制的圖像(在pylab圖像中,鼠標(biāo)的坐標(biāo)顯示在圖像底部附近)手工確定的。
? ? ? 2.調(diào)用warp.py的image_in_image()函數(shù),獲取要變換的第一幅圖像的角點坐標(biāo)
? ? ?3.調(diào)用homography.py的Haffine_from_points(tp,fp)函數(shù),計算仿射變換矩陣,使得tp是fp經(jīng)過仿射變換H得到的。以平移為例,H就是那個平移量,原始坐標(biāo)(x,y),通過(x+H,y+H)得到的就是變換后的圖像坐標(biāo)點。
? ? ?4.調(diào)用Scipy工具包中的ndimage包進行扭曲操作,對圖像塊進行仿射變換。ndimage.affine_transform(im1,H[:2,:2],
? ? ? ? ? ? ? ? ? ? (H[0,2],H[1,2]),im2.shape[:2]),對應(yīng)的第一個參數(shù)為要處理的圖片,參數(shù)二為線性變換的尺度,參數(shù)三為平移向量,參數(shù)四為支付那個輸出圖像的大小。
? ? ?5. 將扭曲的圖像和第二幅圖像融合,創(chuàng)建alpha圖像。扭曲區(qū)域邊界之外以0來填充圖像,然后通過計算(1-alpha)*im2 + alpha*im1_t? ,處理這些像素,得到最后的變換圖像。
二,代碼
# -*- coding: utf-8 -*- from PCV.geometry import warp, homography from PIL import Image from pylab import * from scipy import ndimage# 將im1仿射扭曲到im2的指定位置 im1 = array(Image.open('b_meitu_2.jpg').convert('L')) im2 = array(Image.open('a_meitu_1.jpg').convert('L')) # 選定指定的位置,即目標(biāo)點 tp = array([[324,442,448,324],[453,453,272,270],[1,1,1,1]]) #調(diào)用的warp.py的image_in_image函數(shù),從而實現(xiàn)仿射變換 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) axis('off') show() # -*- coding: cp936 -*- import matplotlib.delaunay as md from scipy import ndimage from pylab import * from numpy import *from PCV.geometry import homographydef image_in_image(im1,im2,tp):# 使用仿射變換將im1放置在im2上,使im1圖像的四個坐標(biāo)角點與tp盡可能靠近, #tp為將第一幅圖像放置到第二幅圖像中的角點坐標(biāo),且是從左上角逆時針的 # 扭曲的點m,n = im1.shape[:2] # 讀取矩陣的行和列,即圖像一的長和寬fp = array([[0,m,m,0],[0,0,n,n],[1,1,1,1]]) #標(biāo)記要變換的第一幅圖像im1的角點坐標(biāo)# 計算仿射變換,并且將其應(yīng)用于圖像im1H = homography.Haffine_from_points(tp,fp)#計算H,仿射變換,使得tp是fp經(jīng)過仿射變換H得到的im1_t = ndimage.affine_transform(im1,H[:2,:2], # 使用Scipy工具包中的ndimage包進行扭曲操作,對圖像塊進行仿射變換(H[0,2],H[1,2]),im2.shape[:2]) alpha = (im1_t > 0) # 創(chuàng)建alpha圖像,扭曲邊界以外的用0來填充圖像,以內(nèi)就是扭曲圖像的像素return (1-alpha)*im2 + alpha*im1_t # 最后計算得到仿射變換后的圖像 def Haffine_from_points(fp,tp): #計算H,仿射變換,使得tp和fp經(jīng)過仿射變換H得到if fp.shape != tp.shape:raise RuntimeError('number of points do not match')# 對點進行歸一化# --映射起始點--m = mean(fp[:2], axis=1)maxstd = max(std(fp[:2], axis=1)) + 1e-9C1 = diag([1/maxstd, 1/maxstd, 1]) C1[0][2] = -m[0]/maxstdC1[1][2] = -m[1]/maxstdfp_cond = dot(C1,fp)# --映射對應(yīng)點--m = mean(tp[:2], axis=1)C2 = C1.copy() #兩個點集,必須都進行相同的縮放C2[0][2] = -m[0]/maxstdC2[1][2] = -m[1]/maxstdtp_cond = dot(C2,tp)# 因為歸一化后的點均值為0,所以平移量為0A = concatenate((fp_cond[:2],tp_cond[:2]), axis=0)U,S,V = linalg.svd(A.T)# 創(chuàng)建矩陣B和Ctmp = V[:2].TB = tmp[:2]C = tmp[2:4]tmp2 = concatenate((dot(C,linalg.pinv(B)),zeros((2,1))), axis=1) H = vstack((tmp2,[0,0,1]))# 反歸一化H = dot(linalg.inv(C2),dot(H,C1))return H / H[2,2]三,運行結(jié)果
以下圖片均拍攝于集美大學(xué)
總結(jié)
以上是生活随笔為你收集整理的使用仿射变换将一幅图像放置到另一幅图像中的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 坐标正算和坐标反算的c语言,坐标正算程序
- 下一篇: Day14-HTTP协议 web开发概