一、最小二乘法求解單應性變換矩陣
1、單應性:
在計算機視覺中:對單應性最感興趣的部分只是其他意義的一個子集。平面的單應性被定義為從一個平面到另一個平面的投影映射。比如,一個二維平面上的點映射到攝像機成像儀上的映射就是平面單應性的例子。
考慮圖1中所示的平面的兩個圖像(書的頂部)。紅點表示兩個圖像中的相同物理點。在計算機視覺術語中,我們稱這些對應點。圖1.用四種不同的顏色(紅色,綠色,黃色和橙色)顯示了四個對應的點。甲單應的是,在一個圖像中的點映射到另一圖像中的對應點的變換(3×3矩陣)。
現在,由於單應性是一個3×3矩陣,我們可以將其寫為
讓我們考慮第一組對應點- 在第一張圖片中
在第二張圖片中。然后,同形異義詞
按照以下方式映射它們
使用單應影像進行圖像對齊
對於所有對應點集,只要它們位於現實世界中的同一平面上,上述方程式就是正確的。換句話說,您可以將單應性應用於第一個圖像,第一個圖像中的書將與第二個圖像中的書對齊!

直接使用cv2中的Homography函數:
import cv2 from matplotlib.pyplot import * if __name__ == '__main__': # Read source image. im_src = cv2.imread('IMG_03.jpg') # Four corners of the book in source image pts_src = np.array([[141, 131], [480, 159], [493, 630], [64, 601]]) # Read destination image. im_dst = cv2.imread('IMG_04.jpg') # Four corners of the book in destination image. pts_dst = np.array([[318, 256], [534, 372], [316, 670], [73, 473]]) # Calculate Homography h, status = cv2.findHomography(pts_src, pts_dst) # Warp source image to destination based on homography im_out = cv2.warpPerspective(im_src, h, (im_dst.shape[1], im_dst.shape[0])) # Display images figure() subplot(1, 3, 1) axis('off') title(u'Source Image') imshow(im_src) subplot(1, 3, 2) axis('off') title(u'Destination Image') imshow(im_dst) subplot(1, 3, 3) axis('off') title(u'Warped Source Image') imshow(im_out) show()
3、運行結果
是指在幾何中,一個向量空間進行一次線性變換並接上一個平移,變換為另一個向量空間。
仿射變換可以由以下基本變換復合而成:平移(Translation)、縮放(Scale)、翻轉(Flip)、旋轉(Rotation)和錯切(Shear),這些基本的變換可由下圖表示:
下圖中變換矩陣將原坐標(x, y)變換為新坐標(x', y')
2、仿射變換最小二乘法
景物在成像過程中產生的扭曲,會使圖像的比例失調,可用仿射變換來校正各種畸變。而仿射變換的參數可以用最小二乘法進行估算。
設原圖像為f(x,y),畸變后的圖像為F(X',Y'),要將F(X',Y')恢復為f(x,y),就是要找到(X',Y')坐標與(x,y)坐標的轉換關系,這個轉換關系稱為坐標變換,表示為(x,y)=T(X',Y')。
景物在成像過程中產生的扭曲,會使圖像的比例失調,可用仿射變換來校正各種畸變。先計算出坐標變換的系數,仿射變換的表達式為:R(x)=Px+Q, x=(x,y)是像素的平面位置,P是2*2的旋轉矩陣,Q是2*1的平移向量,P、Q即為仿射變換參數,即:
x= AX' + BY' + C
y= DX' + EY' + F
因此,幾何畸變的校正歸根結底為坐標轉換系數A,B,C,D,E,F的求解。
為了防止出現空像素,一般采用反向映射,由最小二乘法得(matlab):
vec1 = inv([X Y I]'*[X Y I])*[X Y I]'*U;
vec2 = inv([X Y I]'*[X Y I])*[X Y I]'*V;
其中vec1=[A B C]'; vec2 =[D E F]'; X Y U V I分別是x,y,X', Y', 1構成的向量。
最小二乘法估計就是估計原始坐標點與經過變換后的坐標點之間的關系,從通過這種關系進行矯正圖像,大體步驟如下:
3、算法代碼:Haffine_form_points(fp,tp)函數
三、圖像扭曲
1.定義及原理
對圖像塊應用仿射變換,我們將其稱為圖像扭曲(或者仿射扭曲)。
仿射變換能夠保持圖像的“平直性”,包括旋轉,縮放,平移,錯切操作。對於三個點,仿射變換可以將一副圖像進行扭曲,使得三對對應點對可以完美地匹配上。仿射變換具有6個自由度,有三個對應點對可以給出6個約束條件(對於這三個對應點對,x和y坐標必須都要匹配)
仿射變換是在幾何上定義為兩個向量空間之間的一個仿射變換或者仿射映射。由一個非奇異的線性變換(運用一次函數進行的變換)接上一個平移變換組成。在有限維的情況,每個仿射變換可以由一個矩陣A和一個向量b給出,它可以寫作A和一個附加的列b。一個仿射變換對應於一個矩陣和一個向量的乘法,而仿射變換的復合對應於普通的矩陣乘法,只要加入一個額外的行到矩陣的底下,這一行全部是0除了最右邊是一個1,而列向量的底下要加上一個1。
2、代碼
from array import array from scipy import ndimage from PIL import Image from pylab import * im = array(Image.open('..//images//02.jpg').convert('L')) H = array([[1.4,0.05,-100],[0.05,1.5,-100],[0,0,1]]) im2 = ndimage.affine_transform(im,H[:2,:2],(H[0,2],H[1,2])) figure() gray() subplot(121) axis('off') imshow(im) subplot(122) axis('off') imshow(im2) show()
3.運行結果
四、圖像的映射融合(圖像中的圖像)
仿射扭曲的一個簡單例子是將圖像或者圖像的一部分放置在另一幅圖像中,使得他們能夠和指定的區域或者標記物對齊。
以下函數的輸入參數為兩幅圖像和一個坐標。該坐標為將一副圖像放置到第二幅圖象中的角點位置:
• 流程
① 針對兩張/多張圖像提取特征
② 特征匹配
③ 根據圖像變換特點,選取合適的變換結構
④ 根據DLT等方法計算變換結構
⑤ 采用正向/逆向映射,利用插值方式實現圖像映射變換
1.代碼
from array import array from PCV.geometry import warp, homography from PIL import Image from pylab import * from scipy import ndimage # example of affine warp of im1 onto im2 im1 = array(Image.open('../images/01.jpg').convert('L')) im2 = array(Image.open('../images/02.jpg').convert('L')) # set to points tp = array([[164,538,540,264],[40,36,405,405],[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) # set from points to corners of im1 m,n = im1.shape[:2] fp = array([[0,m,m,0],[0,0,n,n],[1,1,1,1]]) # first triangle tp2 = tp[:,:3] fp2 = fp[:,:3] # compute H H = homography.Haffine_from_points(tp2,fp2) im1_t = ndimage.affine_transform(im1,H[:2,:2], (H[0,2],H[1,2]),im2.shape[:2]) # alpha for triangle alpha = warp.alpha_for_triangle(tp2,im2.shape[0],im2.shape[1]) im3 = (1-alpha)*im2 + alpha*im1_t # second triangle tp2 = tp[:,[0,2,3]] fp2 = fp[:,[0,2,3]] # compute H H = homography.Haffine_from_points(tp2,fp2) im1_t = ndimage.affine_transform(im1,H[:2,:2], (H[0,2],H[1,2]),im2.shape[:2]) # alpha for triangle alpha = warp.alpha_for_triangle(tp2,im2.shape[0],im2.shape[1]) im4 = (1-alpha)*im3 + alpha*im1_t subplot(144) imshow(im4) axis('off') show()
2.運行結果:
實驗用了仿射變換在圖像的使用,使原圖像通過仿射變換放置到目標圖像中,因為在Python中關於仿射變換的具體代碼已經集合封裝到warp.py和homography.py中,只需要導入直接使用里面的函數,就可以跑出結果。
參考:
https://www.cnblogs.com/bingdaocaihong/p/7003581.html
https://blog.csdn.net/yf_0707/article/details/88668171