1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| #include <math.h> #include <stdbool.h>
bool homography_compute(float dst[3][3], const float c[4][4]) { float A[] = { c[0][0], c[0][1], 1, 0, 0, 0, -c[0][0]*c[0][2], -c[0][1]*c[0][2], c[0][2], 0, 0, 0, c[0][0], c[0][1], 1, -c[0][0]*c[0][3], -c[0][1]*c[0][3], c[0][3], c[1][0], c[1][1], 1, 0, 0, 0, -c[1][0]*c[1][2], -c[1][1]*c[1][2], c[1][2], 0, 0, 0, c[1][0], c[1][1], 1, -c[1][0]*c[1][3], -c[1][1]*c[1][3], c[1][3], c[2][0], c[2][1], 1, 0, 0, 0, -c[2][0]*c[2][2], -c[2][1]*c[2][2], c[2][2], 0, 0, 0, c[2][0], c[2][1], 1, -c[2][0]*c[2][3], -c[2][1]*c[2][3], c[2][3], c[3][0], c[3][1], 1, 0, 0, 0, -c[3][0]*c[3][2], -c[3][1]*c[3][2], c[3][2], 0, 0, 0, c[3][0], c[3][1], 1, -c[3][0]*c[3][3], -c[3][1]*c[3][3], c[3][3], };
for (int col = 0; col < 8; col++) { float max_val = 0; int max_val_idx = -1; for (int row = col; row < 8; row++) { float val = fabsf(A[row * 9 + col]); if (val > max_val) { max_val = val; max_val_idx = row; } }
if (max_val < 1e-10) return false;
if (max_val_idx != col) { for (int i = col; i < 9; i++) { float tmp = A[col * 9 + i]; A[col * 9 + i] = A[max_val_idx * 9 + i]; A[max_val_idx * 9 + i] = tmp; } }
for (int i = col + 1; i < 8; i++) { float f = A[i * 9 + col] / A[col * 9 + col]; A[i * 9 + col] = 0; for (int j = col + 1; j < 9; j++) A[i * 9 + j] -= f * A[col * 9 + j]; } }
for (int col = 7; col >= 0; col--) { float sum = 0; for (int i = col + 1; i < 8; i++) { sum += A[col * 9 + i] * A[i * 9 + 8]; } A[col * 9 + 8] = (A[col * 9 + 8] - sum) / A[col * 9 + col]; }
dst[0][0] = A[8], dst[0][1] = A[17], dst[0][2] = A[26]; dst[1][0] = A[35], dst[1][1] = A[44], dst[1][2] = A[53]; dst[2][0] = A[62], dst[2][1] = A[71], dst[2][2] = 1;
return true; }
void homography_project(const float H[3][3], float x, float y, float* ox, float* oy) { float xx = H[0][0] * x + H[0][1] * y + H[0][2]; float yy = H[1][0] * x + H[1][1] * y + H[1][2]; float zz = H[2][0] * x + H[2][1] * y + H[2][2]; *ox = xx / zz; *oy = yy / zz; }
|