int main(void) { int i, j, n; matrix a, b; double s; printf("n = "); scanf("%d", &n); a = new_matrix(n, n + 1); b = new_matrix(n, n + 1); for (i = 0; i < n; i++) for (j = 0; j < n; j++) a[i][j] = b[i][j] = rnd() - rnd(); for (i = 0; i < n; i++) a[i][n] = b[i][n] = rnd() - rnd(); printf("係数行列 (右辺も含む)\n"); matprint(a, n + 1, 10, "%7.3f"); gaussjordan(n, a); printf("解と, 解を代入したときの両辺の差\n"); for (i = 0; i < n; i++) { s = b[i][n]; for (j = 0; j < n; j++) s -= b[i][j] * a[j][n]; printf("%4d: %12.7f %12.7f\n", i, a[i][n], s); } return EXIT_SUCCESS; }
int main() { int n, i; printf("(n) Numarul de linii si coloane: "); scanf("%d", &n); double **a=(double **) malloc (n * sizeof(double*)); for (i=0; i<n; i++) a[i]=(double *) malloc(n * sizeof(double)); citire(a, n); gaussjordan(a, n); return 0; }
/* 計算矩陣的逆矩陣 srcMatrix: 輸入源矩陣,最終求得的逆矩陣也存放於此 D; 矩陣寬度 */ int inverse(double **srcMatrix, int D) { int ret; double **iMatrix ; //計算相應的單位矩陣 mem2D_alloc_double(&iMatrix, D, D); identity(iMatrix, D); //GJ求解 ret = gaussjordan(srcMatrix, iMatrix, D, D); mem2D_free_double(iMatrix); return ret; }
/*! * getProjectiveXformCoeffs() * * Input: ptas (source 4 points; unprimed) * ptad (transformed 4 points; primed) * &vc (<return> vector of coefficients of transform) * Return: 0 if OK; 1 on error * * We have a set of 8 equations, describing the projective * transformation that takes 4 points (ptas) into 4 other * points (ptad). These equations are: * * x1' = (c[0]*x1 + c[1]*y1 + c[2]) / (c[6]*x1 + c[7]*y1 + 1) * y1' = (c[3]*x1 + c[4]*y1 + c[5]) / (c[6]*x1 + c[7]*y1 + 1) * x2' = (c[0]*x2 + c[1]*y2 + c[2]) / (c[6]*x2 + c[7]*y2 + 1) * y2' = (c[3]*x2 + c[4]*y2 + c[5]) / (c[6]*x2 + c[7]*y2 + 1) * x3' = (c[0]*x3 + c[1]*y3 + c[2]) / (c[6]*x3 + c[7]*y3 + 1) * y3' = (c[3]*x3 + c[4]*y3 + c[5]) / (c[6]*x3 + c[7]*y3 + 1) * x4' = (c[0]*x4 + c[1]*y4 + c[2]) / (c[6]*x4 + c[7]*y4 + 1) * y4' = (c[3]*x4 + c[4]*y4 + c[5]) / (c[6]*x4 + c[7]*y4 + 1) * * Multiplying both sides of each eqn by the denominator, we get * * AC = B * * where B and C are column vectors * * B = [ x1' y1' x2' y2' x3' y3' x4' y4' ] * C = [ c[0] c[1] c[2] c[3] c[4] c[5] c[6] c[7] ] * * and A is the 8x8 matrix * * x1 y1 1 0 0 0 -x1*x1' -y1*x1' * 0 0 0 x1 y1 1 -x1*y1' -y1*y1' * x2 y2 1 0 0 0 -x2*x2' -y2*x2' * 0 0 0 x2 y2 1 -x2*y2' -y2*y2' * x3 y3 1 0 0 0 -x3*x3' -y3*x3' * 0 0 0 x3 y3 1 -x3*y3' -y3*y3' * x4 y4 1 0 0 0 -x4*x4' -y4*x4' * 0 0 0 x4 y4 1 -x4*y4' -y4*y4' * * These eight equations are solved here for the coefficients C. * * These eight coefficients can then be used to find the mapping * (x,y) --> (x',y'): * * x' = (c[0]x + c[1]y + c[2]) / (c[6]x + c[7]y + 1) * y' = (c[3]x + c[4]y + c[5]) / (c[6]x + c[7]y + 1) * * that is implemented in projectiveXformSampled() and * projectiveXFormInterpolated(). */ l_int32 getProjectiveXformCoeffs(PTA *ptas, PTA *ptad, l_float32 **pvc) { l_int32 i; l_float32 x1, y1, x2, y2, x3, y3, x4, y4; l_float32 *b; /* rhs vector of primed coords X'; coeffs returned in *pvc */ l_float32 *a[8]; /* 8x8 matrix A */ PROCNAME("getProjectiveXformCoeffs"); if (!ptas) return ERROR_INT("ptas not defined", procName, 1); if (!ptad) return ERROR_INT("ptad not defined", procName, 1); if (!pvc) return ERROR_INT("&vc not defined", procName, 1); if ((b = (l_float32 *)CALLOC(8, sizeof(l_float32))) == NULL) return ERROR_INT("b not made", procName, 1); *pvc = b; ptaGetPt(ptas, 0, &x1, &y1); ptaGetPt(ptas, 1, &x2, &y2); ptaGetPt(ptas, 2, &x3, &y3); ptaGetPt(ptas, 3, &x4, &y4); ptaGetPt(ptad, 0, &b[0], &b[1]); ptaGetPt(ptad, 1, &b[2], &b[3]); ptaGetPt(ptad, 2, &b[4], &b[5]); ptaGetPt(ptad, 3, &b[6], &b[7]); for (i = 0; i < 8; i++) { if ((a[i] = (l_float32 *)CALLOC(8, sizeof(l_float32))) == NULL) return ERROR_INT("a[i] not made", procName, 1); } a[0][0] = x1; a[0][1] = y1; a[0][2] = 1.; a[0][6] = -x1 * b[0]; a[0][7] = -y1 * b[0]; a[1][3] = x1; a[1][4] = y1; a[1][5] = 1; a[1][6] = -x1 * b[1]; a[1][7] = -y1 * b[1]; a[2][0] = x2; a[2][1] = y2; a[2][2] = 1.; a[2][6] = -x2 * b[2]; a[2][7] = -y2 * b[2]; a[3][3] = x2; a[3][4] = y2; a[3][5] = 1; a[3][6] = -x2 * b[3]; a[3][7] = -y2 * b[3]; a[4][0] = x3; a[4][1] = y3; a[4][2] = 1.; a[4][6] = -x3 * b[4]; a[4][7] = -y3 * b[4]; a[5][3] = x3; a[5][4] = y3; a[5][5] = 1; a[5][6] = -x3 * b[5]; a[5][7] = -y3 * b[5]; a[6][0] = x4; a[6][1] = y4; a[6][2] = 1.; a[6][6] = -x4 * b[6]; a[6][7] = -y4 * b[6]; a[7][3] = x4; a[7][4] = y4; a[7][5] = 1; a[7][6] = -x4 * b[7]; a[7][7] = -y4 * b[7]; gaussjordan(a, b, 8); for (i = 0; i < 8; i++) FREE(a[i]); return 0; }
l_int32 main(int argc, char **argv) { l_int32 size, i, rval, gval, bval, yval, uval, vval; l_float32 *a[3], b[3]; L_BMF *bmf; PIX *pixd; PIXA *pixa; /* Explore the range of rgb --> yuv transforms. All rgb * values transform to a valid value of yuv, so when transforming * back we get the same rgb values that we started with. */ pixa = pixaCreate(0); bmf = bmfCreate("fonts", 6); for (gval = 0; gval <= 255; gval += 20) AddTransformsRGB(pixa, bmf, gval); pixd = pixaDisplayTiledAndScaled(pixa, 32, 755, 1, 0, 20, 2); pixDisplay(pixd, 100, 0); pixWrite("/tmp/yuv1.png", pixd, IFF_PNG); pixDestroy(&pixd); pixaDestroy(&pixa); /* Now start with all "valid" yuv values, not all of which are * related to a valid rgb value. Our yuv --> rgb transform * clips the rgb components to [0 ... 255], so when transforming * back we get different values whenever the initial yuv * value is out of the rgb gamut. */ pixa = pixaCreate(0); for (yval = 16; yval <= 235; yval += 16) AddTransformsYUV(pixa, bmf, yval); pixd = pixaDisplayTiledAndScaled(pixa, 32, 755, 1, 0, 20, 2); pixDisplay(pixd, 600, 0); pixWrite("/tmp/yuv2.png", pixd, IFF_PNG); pixDestroy(&pixd); pixaDestroy(&pixa); bmfDestroy(&bmf); /* --------- Try out a special case by hand, and show that --------- * * ------- the transform matrices we are using are inverses ---------*/ /* First, use our functions for the transform */ fprintf(stderr, "Start with: yval = 143, uval = 79, vval = 103\n"); convertYUVToRGB(143, 79, 103, &rval, &gval, &bval); fprintf(stderr, " ==> rval = %d, gval = %d, bval = %d\n", rval, gval, bval); convertRGBToYUV(rval, gval, bval, &yval, &uval, &vval); fprintf(stderr, " ==> yval = %d, uval = %d, vval = %d\n", yval, uval, vval); /* Next, convert yuv --> rbg by solving for rgb --> yuv transform. * [ a00 a01 a02 ] r = b0 (y - 16) * [ a10 a11 a12 ] * g = b1 (u - 128) * [ a20 a21 a22 ] b = b2 (v - 128) */ b[0] = 143.0 - 16.0; /* y - 16 */ b[1] = 79.0 - 128.0; /* u - 128 */ b[2] = 103.0 - 128.0; /* v - 128 */ for (i = 0; i < 3; i++) a[i] = (l_float32 *)lept_calloc(3, sizeof(l_float32)); a[0][0] = 65.738 / 256.0; a[0][1] = 129.057 / 256.0; a[0][2] = 25.064 / 256.0; a[1][0] = -37.945 / 256.0; a[1][1] = -74.494 / 256.0; a[1][2] = 112.439 / 256.0; a[2][0] = 112.439 / 256.0; a[2][1] = -94.154 / 256.0; a[2][2] = -18.285 / 256.0; fprintf(stderr, "Here's the original matrix: yuv --> rgb:\n"); for (i = 0; i < 3; i++) fprintf(stderr, " %7.3f %7.3f %7.3f\n", 256.0 * a[i][0], 256.0 * a[i][1], 256.0 * a[i][2]); gaussjordan(a, b, 3); fprintf(stderr, "\nInput (yuv) = (143,79,103); solve for rgb:\n" "rval = %7.3f, gval = %7.3f, bval = %7.3f\n", b[0], b[1], b[2]); fprintf(stderr, "Here's the inverse matrix: rgb --> yuv:\n"); for (i = 0; i < 3; i++) fprintf(stderr, " %7.3f %7.3f %7.3f\n", 256.0 * a[i][0], 256.0 * a[i][1], 256.0 * a[i][2]); /* Now, convert back: rgb --> yuv; * Do this by solving for yuv --> rgb transform. * Use the b[] found previously (the rgb values), and * the a[][] which now holds the rgb --> yuv transform. */ gaussjordan(a, b, 3); fprintf(stderr, "\nInput rgb; solve for yuv:\n" "yval = %7.3f, uval = %7.3f, vval = %7.3f\n", b[0] + 16.0, b[1] + 128.0, b[2] + 128.0); fprintf(stderr, "Inverting the matrix again: yuv --> rgb:\n"); for (i = 0; i < 3; i++) fprintf(stderr, " %7.3f %7.3f %7.3f\n", 256.0 * a[i][0], 256.0 * a[i][1], 256.0 * a[i][2]); for (i = 0; i < 3; i++) lept_free(a[i]); return 0; }