2 changed files with 197 additions and 0 deletions
@ -0,0 +1,174 @@ |
|||||
|
/*
|
||||
|
* ofxHomographyHelper.cpp |
||||
|
* Created by Elliot Woods on 26/11/2010. |
||||
|
* |
||||
|
* Based entirely on arturo castro's homography implementation |
||||
|
* Created 08/01/2010, arturo castro |
||||
|
* |
||||
|
* http://www.openframeworks.cc/forum/viewtopic.php?f=9&t=3121
|
||||
|
*/ |
||||
|
|
||||
|
#include "ofxHomographyHelper.h" |
||||
|
|
||||
|
void ofxHomographyHelper::gaussian_elimination(float *input, int n) |
||||
|
{ |
||||
|
// ported to c from pseudocode in
|
||||
|
// http://en.wikipedia.org/wiki/Gaussian_elimination
|
||||
|
|
||||
|
float * A = input; |
||||
|
int i = 0; |
||||
|
int j = 0; |
||||
|
int m = n-1; |
||||
|
while (i < m && j < n){ |
||||
|
// Find pivot in column j, starting in row i:
|
||||
|
int maxi = i; |
||||
|
for(int k = i+1; k<m; k++){ |
||||
|
if(fabs(A[k*n+j]) > fabs(A[maxi*n+j])){ |
||||
|
maxi = k; |
||||
|
} |
||||
|
} |
||||
|
if (A[maxi*n+j] != 0){ |
||||
|
//swap rows i and maxi, but do not change the value of i
|
||||
|
if(i!=maxi) |
||||
|
for(int k=0;k<n;k++){ |
||||
|
float aux = A[i*n+k]; |
||||
|
A[i*n+k]=A[maxi*n+k]; |
||||
|
A[maxi*n+k]=aux; |
||||
|
} |
||||
|
//Now A[i,j] will contain the old value of A[maxi,j].
|
||||
|
//divide each entry in row i by A[i,j]
|
||||
|
float A_ij=A[i*n+j]; |
||||
|
for(int k=0;k<n;k++){ |
||||
|
A[i*n+k]/=A_ij; |
||||
|
} |
||||
|
//Now A[i,j] will have the value 1.
|
||||
|
for(int u = i+1; u< m; u++){ |
||||
|
//subtract A[u,j] * row i from row u
|
||||
|
float A_uj = A[u*n+j]; |
||||
|
for(int k=0;k<n;k++){ |
||||
|
A[u*n+k]-=A_uj*A[i*n+k]; |
||||
|
} |
||||
|
//Now A[u,j] will be 0, since A[u,j] - A[i,j] * A[u,j] = A[u,j] - 1 * A[u,j] = 0.
|
||||
|
} |
||||
|
|
||||
|
i++; |
||||
|
} |
||||
|
j++; |
||||
|
} |
||||
|
|
||||
|
//back substitution
|
||||
|
for(int i=m-2;i>=0;i--){ |
||||
|
for(int j=i+1;j<n-1;j++){ |
||||
|
A[i*n+m]-=A[i*n+j]*A[j*n+m]; |
||||
|
//A[i*n+j]=0;
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void ofxHomographyHelper::findHomography(float src[4][2], float dst[4][2], float homography[16]){ |
||||
|
|
||||
|
// create the equation system to be solved
|
||||
|
//
|
||||
|
// from: Multiple View Geometry in Computer Vision 2ed
|
||||
|
// Hartley R. and Zisserman A.
|
||||
|
//
|
||||
|
// x' = xH
|
||||
|
// where H is the homography: a 3 by 3 matrix
|
||||
|
// that transformed to inhomogeneous coordinates for each point
|
||||
|
// gives the following equations for each point:
|
||||
|
//
|
||||
|
// x' * (h31*x + h32*y + h33) = h11*x + h12*y + h13
|
||||
|
// y' * (h31*x + h32*y + h33) = h21*x + h22*y + h23
|
||||
|
//
|
||||
|
// as the homography is scale independent we can let h33 be 1 (indeed any of the terms)
|
||||
|
// so for 4 points we have 8 equations for 8 terms to solve: h11 - h32
|
||||
|
// after ordering the terms it gives the following matrix
|
||||
|
// that can be solved with gaussian elimination:
|
||||
|
|
||||
|
float P[8][9]={ |
||||
|
{-src[0][0], -src[0][1], -1, 0, 0, 0, src[0][0]*dst[0][0], src[0][1]*dst[0][0], -dst[0][0] }, // h11
|
||||
|
{ 0, 0, 0, -src[0][0], -src[0][1], -1, src[0][0]*dst[0][1], src[0][1]*dst[0][1], -dst[0][1] }, // h12
|
||||
|
|
||||
|
{-src[1][0], -src[1][1], -1, 0, 0, 0, src[1][0]*dst[1][0], src[1][1]*dst[1][0], -dst[1][0] }, // h13
|
||||
|
{ 0, 0, 0, -src[1][0], -src[1][1], -1, src[1][0]*dst[1][1], src[1][1]*dst[1][1], -dst[1][1] }, // h21
|
||||
|
|
||||
|
{-src[2][0], -src[2][1], -1, 0, 0, 0, src[2][0]*dst[2][0], src[2][1]*dst[2][0], -dst[2][0] }, // h22
|
||||
|
{ 0, 0, 0, -src[2][0], -src[2][1], -1, src[2][0]*dst[2][1], src[2][1]*dst[2][1], -dst[2][1] }, // h23
|
||||
|
|
||||
|
{-src[3][0], -src[3][1], -1, 0, 0, 0, src[3][0]*dst[3][0], src[3][1]*dst[3][0], -dst[3][0] }, // h31
|
||||
|
{ 0, 0, 0, -src[3][0], -src[3][1], -1, src[3][0]*dst[3][1], src[3][1]*dst[3][1], -dst[3][1] }, // h32
|
||||
|
}; |
||||
|
|
||||
|
gaussian_elimination(&P[0][0],9); |
||||
|
|
||||
|
// gaussian elimination gives the results of the equation system
|
||||
|
// in the last column of the original matrix.
|
||||
|
// opengl needs the transposed 4x4 matrix:
|
||||
|
float aux_H[]={ P[0][8],P[3][8],0,P[6][8], // h11 h21 0 h31
|
||||
|
P[1][8],P[4][8],0,P[7][8], // h12 h22 0 h32
|
||||
|
0 , 0,0,0, // 0 0 0 0
|
||||
|
P[2][8],P[5][8],0,1}; // h13 h23 0 h33
|
||||
|
|
||||
|
for(int i=0;i<16;i++) homography[i] = aux_H[i]; |
||||
|
} |
||||
|
|
||||
|
ofMatrix4x4 ofxHomographyHelper::findHomography(float src[4][2], float dst[4][2]){ |
||||
|
ofMatrix4x4 matrix; |
||||
|
|
||||
|
// create the equation system to be solved
|
||||
|
//
|
||||
|
// from: Multiple View Geometry in Computer Vision 2ed
|
||||
|
// Hartley R. and Zisserman A.
|
||||
|
//
|
||||
|
// x' = xH
|
||||
|
// where H is the homography: a 3 by 3 matrix
|
||||
|
// that transformed to inhomogeneous coordinates for each point
|
||||
|
// gives the following equations for each point:
|
||||
|
//
|
||||
|
// x' * (h31*x + h32*y + h33) = h11*x + h12*y + h13
|
||||
|
// y' * (h31*x + h32*y + h33) = h21*x + h22*y + h23
|
||||
|
//
|
||||
|
// as the homography is scale independent we can let h33 be 1 (indeed any of the terms)
|
||||
|
// so for 4 points we have 8 equations for 8 terms to solve: h11 - h32
|
||||
|
// after ordering the terms it gives the following matrix
|
||||
|
// that can be solved with gaussian elimination:
|
||||
|
|
||||
|
float P[8][9]={ |
||||
|
{-src[0][0], -src[0][1], -1, 0, 0, 0, src[0][0]*dst[0][0], src[0][1]*dst[0][0], -dst[0][0] }, // h11
|
||||
|
{ 0, 0, 0, -src[0][0], -src[0][1], -1, src[0][0]*dst[0][1], src[0][1]*dst[0][1], -dst[0][1] }, // h12
|
||||
|
|
||||
|
{-src[1][0], -src[1][1], -1, 0, 0, 0, src[1][0]*dst[1][0], src[1][1]*dst[1][0], -dst[1][0] }, // h13
|
||||
|
{ 0, 0, 0, -src[1][0], -src[1][1], -1, src[1][0]*dst[1][1], src[1][1]*dst[1][1], -dst[1][1] }, // h21
|
||||
|
|
||||
|
{-src[2][0], -src[2][1], -1, 0, 0, 0, src[2][0]*dst[2][0], src[2][1]*dst[2][0], -dst[2][0] }, // h22
|
||||
|
{ 0, 0, 0, -src[2][0], -src[2][1], -1, src[2][0]*dst[2][1], src[2][1]*dst[2][1], -dst[2][1] }, // h23
|
||||
|
|
||||
|
{-src[3][0], -src[3][1], -1, 0, 0, 0, src[3][0]*dst[3][0], src[3][1]*dst[3][0], -dst[3][0] }, // h31
|
||||
|
{ 0, 0, 0, -src[3][0], -src[3][1], -1, src[3][0]*dst[3][1], src[3][1]*dst[3][1], -dst[3][1] }, // h32
|
||||
|
}; |
||||
|
|
||||
|
gaussian_elimination(&P[0][0],9); |
||||
|
|
||||
|
matrix(0,0)=P[0][8]; |
||||
|
matrix(0,1)=P[1][8]; |
||||
|
matrix(0,2)=0; |
||||
|
matrix(0,3)=P[2][8]; |
||||
|
|
||||
|
matrix(1,0)=P[3][8]; |
||||
|
matrix(1,1)=P[4][8]; |
||||
|
matrix(1,2)=0; |
||||
|
matrix(1,3)=P[5][8]; |
||||
|
|
||||
|
matrix(2,0)=0; |
||||
|
matrix(2,1)=0; |
||||
|
matrix(2,2)=0; |
||||
|
matrix(2,3)=0; |
||||
|
|
||||
|
matrix(3,0)=P[6][8]; |
||||
|
matrix(3,1)=P[7][8]; |
||||
|
matrix(3,2)=0; |
||||
|
matrix(3,3)=1; |
||||
|
|
||||
|
return matrix; |
||||
|
} |
@ -0,0 +1,23 @@ |
|||||
|
/*
|
||||
|
* ofxHomographyHelper.cpp |
||||
|
* Created by Elliot Woods on 26/11/2010. |
||||
|
* |
||||
|
* Based entirely on arturo castro's homography implementation |
||||
|
* Created 08/01/2010, arturo castro |
||||
|
* |
||||
|
* http://www.openframeworks.cc/forum/viewtopic.php?f=9&t=3121
|
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include "ofMatrix4x4.h" |
||||
|
|
||||
|
class ofxHomographyHelper |
||||
|
{ |
||||
|
public: |
||||
|
static void gaussian_elimination(float *input, int n); |
||||
|
|
||||
|
static void findHomography(float src[4][2], float dst[4][2], float homography[16]); |
||||
|
static ofMatrix4x4 findHomography(float src[4][2], float dst[4][2]); |
||||
|
}; |
||||
|
|
Loading…
Reference in new issue