bool dng_camera_profile::ValidForwardMatrix (const dng_matrix &m) { const real64 kThreshold = 0.01; if (m.NotEmpty ()) { dng_vector cameraOne; cameraOne.SetIdentity (m.Cols ()); dng_vector xyz = m * cameraOne; dng_vector pcs = PCStoXYZ (); if (Abs_real64 (xyz [0] - pcs [0]) > kThreshold || Abs_real64 (xyz [1] - pcs [1]) > kThreshold || Abs_real64 (xyz [2] - pcs [2]) > kThreshold) { return false; } } return true; }
void dng_camera_profile::NormalizeColorMatrix (dng_matrix &m) { if (m.NotEmpty ()) { // Find scale factor to normalize the matrix. dng_vector coord = m * PCStoXYZ (); real64 maxCoord = coord.MaxEntry (); if (maxCoord > 0.0 && (maxCoord < 0.99 || maxCoord > 1.01)) { m.Scale (1.0 / maxCoord); } // Round to four decimal places. m.Round (10000); } }
dng_vector operator* (const dng_matrix &A, const dng_vector &B) { if (A.Cols () != B.Count ()) { ThrowMatrixMath (); } dng_vector C (A.Rows ()); for (uint32 j = 0; j < C.Count (); j++) { C [j] = 0.0; for (uint32 m = 0; m < A.Cols (); m++) { real64 aa = A [j] [m]; real64 bb = B [m]; C [j] += aa * bb; } } return C; }
dng_matrix operator+ (const dng_matrix &A, const dng_matrix &B) { if (A.Cols () != B.Cols () || A.Rows () != B.Rows ()) { ThrowMatrixMath (); } dng_matrix C (A); for (uint32 j = 0; j < C.Rows (); j++) for (uint32 k = 0; k < C.Cols (); k++) { C [j] [k] += B [j] [k]; } return C; }
bool dng_matrix::operator== (const dng_matrix &m) const { if (Rows () != m.Rows () || Cols () != m.Cols ()) { return false; } for (uint32 j = 0; j < Rows (); j++) for (uint32 k = 0; k < Cols (); k++) { if (fData [j] [k] != m.fData [j] [k]) { return false; } } return true; }
dng_matrix operator* (const dng_matrix &A, const dng_matrix &B) { if (A.Cols () != B.Rows ()) { ThrowMatrixMath (); } dng_matrix C (A.Rows (), B.Cols ()); for (uint32 j = 0; j < C.Rows (); j++) for (uint32 k = 0; k < C.Cols (); k++) { C [j] [k] = 0.0; for (uint32 m = 0; m < A.Cols (); m++) { real64 aa = A [j] [m]; real64 bb = B [m] [k]; C [j] [k] += aa * bb; } } return C; }
void PrintMatrix(const char *title, const dng_matrix &m) { int i, j; if(title) { std::cout << title << "="; } for(i=0; i<m.Rows(); i++) { for(j=0; j<m.Cols(); j++) { std::cout << " " << m[i][j]; } std::cout << std::endl; } if(!m.Rows()) std::cout << std::endl; }
dng_matrix Transpose (const dng_matrix &A) { dng_matrix B (A.Cols (), A.Rows ()); for (uint32 j = 0; j < B.Rows (); j++) for (uint32 k = 0; k < B.Cols (); k++) { B [j] [k] = A [k] [j]; } return B; }
void dng_camera_profile::NormalizeForwardMatrix (dng_matrix &m) { if (m.NotEmpty ()) { dng_vector cameraOne; cameraOne.SetIdentity (m.Cols ()); dng_vector xyz = m * cameraOne; m = PCStoXYZ ().AsDiagonal () * Invert (xyz.AsDiagonal ()) * m; } }
dng_matrix Interpolate(double t1, double t2, double t, const dng_matrix &m1, const dng_matrix &m2) { double r1, r2, r; double t0; double g; int inv; int i, j; if(m1.IsEmpty()) return m2; if(m2.IsEmpty()) return m1; if((m1.Rows() != m2.Rows()) || (m1.Cols() != m2.Cols())) { ThrowMatrixMath("Interpolate of matrices of differerent sizes"); } if(t1 <= 1.0) return m2; if(t2 <= 1.0) return m1; inv=0; if(t2 < t1) { t0=t2; t2=t1; t1=t0; inv=1; } if(t <= t1) { if(inv) return m2; else return m1; } if(t >= t2) { if(inv) return m1; else return m2; } r1=1.0/t1; r2=1.0/t2; r=1.0/t; g=(r2-r)/(r2-r1); if(inv) g=1.0-g; dng_matrix m(m1.Rows(), m1.Cols()); for(i=0; i<m.Rows(); i++) { for(j=0; j<m.Cols(); j++) { m[i][j]=m1[i][j]*g+m2[i][j]*(1.0-g); } } m.Round(10000); return m; }
dng_matrix Invert (const dng_matrix &A, const dng_matrix &hint) { if (A.Rows () == A .Cols () || A.Rows () != hint.Cols () || A.Cols () != hint.Rows ()) { return Invert (A); } else { // Use the specified hint matrix. return Invert (hint * A) * hint; } }
dng_matrix Invert (const dng_matrix &A) { if (A.Rows () < 2 || A.Cols () < 2) { ThrowMatrixMath (); } if (A.Rows () == A.Cols ()) { if (A.Rows () == 3) { return Invert3by3 (A); } return InvertNbyN (A); } else { // Compute the pseudo inverse. dng_matrix B = Transpose (A); return Invert (B * A) * B; } }
/* Возвращает 1, если матрицы равны, иначе - 0 */ int equal(const dng_matrix &m1, const dng_matrix &m2) { int i,j; if(m1.Rows() != m2.Rows()) return 0; if(m1.Cols() != m2.Cols()) return 0; for(i=0; i<m1.Rows(); i++) { for(j=0; j<m1.Cols(); j++) { if(fabs(m1[i][j]-m2[i][j]) > 0.00005) return 0; } } return 1; }
static dng_matrix InvertNbyN (const dng_matrix &A) { uint32 i; uint32 j; uint32 k; uint32 n = A.Rows (); real64 temp [kMaxColorPlanes] [kMaxColorPlanes * 2]; for (i = 0; i < n; i++) for (j = 0; j < n; j++) { temp [i] [j ] = A [i] [j]; temp [i] [j + n] = (i == j ? 1.0 : 0.0); } for (i = 0; i < n; i++) { real64 alpha = temp [i] [i]; if (Abs_real64 (alpha) < kNearZero) { ThrowMatrixMath (); } for (j = 0; j < n * 2; j++) { temp [i] [j] /= alpha; } for (k = 0; k < n; k++) { if (i != k) { real64 beta = temp [k] [i]; for (j = 0; j < n * 2; j++) { temp [k] [j] -= beta * temp [i] [j]; } } } } dng_matrix B (n, n); for (i = 0; i < n; i++) for (j = 0; j < n; j++) { B [i] [j] = temp [i] [j + n]; } return B; }