1. 程式人生 > >多視幾何:對極幾何的代數表示--基本矩陣F

多視幾何:對極幾何的代數表示--基本矩陣F

對極幾何的基本概念中是對對極幾何的基本形式進行了描述,但並沒有從數學角度對其進行描述,而基本矩陣正是對對極幾何的代數描述

1.總述

這裡寫圖片描述

對極幾何描述的就是點x和它的對極線l’之間的關係:l=Fx,其中,矩陣F稱為基本矩陣

下面,分別從幾何角度和代數角度對上式進行推導

2.幾何推導

從幾何角度推導關於對極幾何方程,如下圖所示
這裡寫圖片描述

  • 影象點x是空間點X在影象1中的投影點,那麼,有
    x=H1X(1)
  • 同理,影象點x’是空間點X在影象1中的投影點,那麼,有
    x=H2X(2)
  • 根據式(1)可以得到
    X=H11x(3)
  • 將式(3)代入式(2)得到

    x
    =H2H11xH2H11=HπHπx(4)
  • 影象點x對應的基線l’是通過點x’和點e’的直線,那麼,有

    l=e×x(5)
    其中的×為叉乘;
  • 將式(4)代入式(5)可以得到

    l=e×Hπxe×Hπ=FFx

結論(來自多視幾何教材):基本矩陣F可以記為F=[e]×Hπ,其中,Hπ是從一幅影象到另一幅影象通過任意平面π的轉移對映,而且,因為[e]×的秩為2,Hπ的秩為3,所以,F的秩為3

3.代數推導

仍舊以下圖為例,假設兩幅影象對應的攝像機矩陣分別為P和P’,光心分別為C和C’

這裡寫圖片描述

影象點x反投影射線的引數形式為X(λ)=P+x+λC

  • λ
    =0
    ,代表該射線上一個特殊的點P+x
  • λ=+,代表該射線上一個特殊的點C

在攝像機2的作用下,這兩個特殊的點分別被投影到影象2中的點x’和e’,即

  • x=PP+x
  • e=PC

從而,影象1中的點x的對極線即為

l=e×x=PC×PP+x=[PC]×PP+x

[PC]×PP+=F,則有l=Fx

4. 對比幾何形式和代數形式的基本矩陣

幾何形式

F=[e]×Hπ
代數形式
F=[PC]×PP+

5. 基本矩陣視覺化

Zisserman的多視幾何教程配套程式碼中,給出了視覺化兩視點基本矩陣的互動介面

  • vgg_ui中的vgg_gui_F.m為視覺化基本矩陣的函式
  • vgg_examples中view_fund_ex.m為呼叫vgg_gui_F.m的程式碼段

原始影象:
這裡寫圖片描述

這裡寫圖片描述

下面是幾幅執行結果:
這裡寫圖片描述

這裡寫圖片描述

view_fund_ex.m內容如下

%%使用vgg_gui_F例子%%

% 讀入兩幅教堂影象
im1 = imread('chapel00.png');
im2 = imread('chapel01.png');

% 讀入基本矩陣F的值(好吧,暫時還不知道如何得來)
F = load('chapel.00.01.F');

% 在GUI中可是化基本矩陣, 利用滑鼠點選影象中某點
% 可以在另一幅影象中顯示該點對應的極線
vgg_gui_F(im1, im2, F')

內容如下

function fig=vgg_gui_F(i1,i2,F)
%
%   fig=vgg_gui_F(i1,i2,F)
%
%
% Visualizes the fundamental matrix of two views
%
%IN:
%   i1 - Matlab image
%   i2 - Matlab image
%   F - Fundamental matrix (p1'*F*p2=0). Assumes that image coordiantes
%       are 1..width where pixel centers are at integer locations. 
%
%OUT:
%   fig - handle to the figure

if nargin==3
   action='start';
else
   action=i1;
   ud = get(gcf, 'UserData');
end

if strcmp(action,'start'),
   if nargin ~= 3
      error('Must give 3 arguments... read the docs.\n');
   end

   h0 = figure('Color',[0.8 0.8 0.8], ...
           'NumberTitle','off', ...
           'Name','Play With Fundamental Matrix', ...
           'ButtonDownFcn', 'disp(''Click on images'')',...
           'WindowButtonUpFcn', 'vgg_gui_F(''none'');',...
           'WindowButtonMotionFcn', 'vgg_gui_F(''move'')', ...
           'Pointer', 'crosshair', ...
           'DoubleBuffer', 'on',...
           'Units','normalized');
   [pointerShape, pointerHotSpot] = CreatePointer;
   set(h0, 'Pointer', 'custom', ...
       'PointerShapeCData', pointerShape, ...
       'PointerShapeHotSpot', pointerHotSpot);

   m0=uimenu('Label', '&Color');
   uimenu(m0, 'Label', 'blac&K', 'ForegroundColor', [0 0 0], ...
      'Accelerator', 'k', 'Callback', 'vgg_gui_F(''ck'');');
   uimenu(m0, 'Label', '&Red', 'ForegroundColor', [1 0 0], ...
      'Accelerator', 'r', 'Callback', 'vgg_gui_F(''cr'');');
   uimenu(m0, 'Label', '&Green', 'ForegroundColor', [0 1 0