計算機視覺——參數矩陣與八點法的運用

1基礎矩陣

1.1原理

在這裏插入圖片描述
對於一幅圖像上的點x(圖上p1),在另一幅圖像上存在對極線l’,並且在第二幅圖像上,與x匹配的點x’(點p2)必然在l’上。爲了表示x與l’關係,我們令基礎矩陣F定義爲: l′=Fx。

假設第一幅圖到第二幅圖之間存在單應性變換H,則 x′=Hx。

又因爲l’是表示過對極點e2和圖像點x’的直線,可以表示爲: l′=e2×x′=[e2]xx′=[e2]xHx。

所以可得 F=[e2]xH。

1.2.基礎矩陣性質

(1) 基礎矩陣是秩爲2、自由度爲7的齊次矩陣。
(2)若x與x’是兩幅圖上的對應點,那麼x′TFx=0。
(3)l’是對應於x的對極線,l′=Fx。
(4)若e是第二個攝像機光心在第一幅圖像上的極點,那麼Fe=0 。

1.3計算F:八點法

八點法是通過對應點來計算基礎矩陣的算法。

八點算法的原理:
由於基礎矩陣F 定義爲:
在這裏插入圖片描述
任給兩幅圖像中的匹配點 x xx 與 x′ x’x
x=(u,v,1)Tx=(u,v,1)T x=(u,v,1)T ,x’=(u’,v’,1)^T
基礎矩陣F是一個3×3的秩爲2的矩陣,一般記基礎矩陣F爲:
在這裏插入圖片描述
有相應方程:
在這裏插入圖片描述

1.4八點算法的基本步驟

(1)求線性解 由係數矩陣A AA最小奇異值對應的奇異矢量f 求的F 。
(2)奇異性約束 是最小化Frobenius範數∥F−F’∥的F′ 代替F

1.5八點算法優缺點

八點算法的優點:
線性求解,容易實現,運行速度快 。
八點算法的缺點:
對噪聲敏感。

2.代碼

2.1八點法

# coding: utf-8
from PIL import Image
from numpy import *
from pylab import *
import numpy as np
from PCV.geometry import homography, camera, sfm
from PCV.localdescriptors import sift

camera = reload(camera)
homography = reload(homography)
sfm = reload(sfm)
sift = reload(sift)

# 提取特徵
im1 = array(Image.open('C:\Python\Pictrue/badian/badian_nodify/zuoyou2.jpg'))
sift.process_image('C:\Python\Pictrue/badian/badian_nodify/zuoyou2.jpg', 'im1.sift')

im2 = array(Image.open('C:\Python\Pictrue/badian/badian_nodify/zuoyou1.jpg'))
sift.process_image('C:\Python\Pictrue/badian/badian_nodify/zuoyou1.jpg', 'im2.sift')

l1, d1 = sift.read_features_from_file('im1.sift')
l2, d2 = sift.read_features_from_file('im2.sift')

matches = sift.match_twosided(d1, d2)

ndx = matches.nonzero()[0]
x1 = homography.make_homog(l1[ndx, :2].T)  # 將點集轉化爲齊次座標表示
ndx2 = [int(matches[i]) for i in ndx]
x2 = homography.make_homog(l2[ndx2, :2].T)  # 將點集轉化爲齊次座標表示

d1n = d1[ndx]
d2n = d2[ndx2]
x1n = x1.copy()
x2n = x2.copy()

figure(figsize=(16, 16))
sift.plot_matches(im1, im2, l1, l2, matches, True)  # 可視化
show()


def F_from_ransac(x1, x2, model, maxiter=5000, match_threshold=1e-6):
    """
    使用RANSAC從點對應中穩健估計基本矩陣F.
  (來自http://www.scipy.org/Cookbook/RANSAC的ransac.py)。
    input: x1, x2 (3*n arrays) points in hom. coordinates. """

    from PCV.tools import ransac
    data = np.vstack((x1, x2))
    d = 10  # 20 is the original
    # 計算F並返回inlier索引
    F, ransac_data = ransac.ransac(data.T, model,
                                   8, maxiter, match_threshold, d, return_all=True)
    return F, ransac_data['inliers']


# 通過RANSAC找到F.
model = sfm.RansacModel()
F, inliers = F_from_ransac(x1n, x2n, model, maxiter=5000, match_threshold=1e-3)

P1 = array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]])
P2 = sfm.compute_P_from_fundamental(F)  # 計算第二個相機矩陣

# print P2
print 'F is'
print F

X = sfm.triangulate(x1n[:, inliers], x2n[:, inliers], P1, P2)

# 繪製X的投影
cam1 = camera.Camera(P1)
cam2 = camera.Camera(P2)
x1p = cam1.project(X)
x2p = cam2.project(X)

figure(figsize=(16, 16))
imj = sift.appendimages(im1, im2)
imj = vstack((imj, imj))

imshow(imj)

cols1 = im1.shape[1]
rows1 = im1.shape[0]
for i in range(len(x1p[0])):
    if (0 <= x1p[0][i] < cols1) and (0 <= x2p[0][i] < cols1) and (0 <= x1p[1][i] < rows1) and (0 <= x2p[1][i] < rows1):
        plot([x1p[0][i], x2p[0][i] + cols1], [x1p[1][i], x2p[1][i]], 'c')
axis('off')
show()

d1p = d1n[inliers]
d2p = d2n[inliers]

3.結果和分析

3.1前後拍攝

在這裏插入圖片描述
參數矩陣爲:
在這裏插入圖片描述
在這裏插入圖片描述
極線圖:
在這裏插入圖片描述
極點圖

3.2平行拍攝

在這裏插入圖片描述
參數矩陣爲:
在這裏插入圖片描述

極線圖:
在這裏插入圖片描述
極點圖:
在這裏插入圖片描述

3.3左右拍攝

在這裏插入圖片描述
參數矩陣爲:
在這裏插入圖片描述
極點圖:
在這裏插入圖片描述
極線圖:
在這裏插入圖片描述

3.4匹配點不同時的參數矩陣

在左右拍攝場景中

7點時
在這裏插入圖片描述
8點時
在這裏插入圖片描述
10點時
在這裏插入圖片描述

3.5總結

在三組場景中,前後拍攝的場景和左右拍攝的場景極線能夠很好的相交於一點,且極線間角度足夠大,極點在平面內。
在平移場景中的極線不能相交於一點,且其中大部分極線接近平行,也能很好的印證拍攝的平行程度。
在左右拍攝的場景中,由於角度較小,所以交於一點的極線角度也偏小,有平行的趨勢。不選擇大角度的圖片的原因是拍攝角度偏大一些代碼就會報錯,找不到匹配特徵,在嘗試了十多組數據以後發現此規律。

4.遇到的問題及解決方法

4.1.did not meet fit acceptance criteria
在運行拍攝左右組圖時出現了好幾次以下錯誤:
在這裏插入圖片描述
經過多次試驗發現問題在於選取的圖片不符合要求,需重新選取一組圖片。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章