00001 /*
00002 File: MatUtil.cc
00003
00004 Function: Provides useful matrix utilities
00005
00006 Author: Andrew Willmott
00007
00008 Notes:
00009 */
00010
00011 #include "gcl/MatUtil.h"
00012
00013 // --- image/matrix routines --------------------------------------------------
00014
00015 Void ImageToMat(const Image &img, Matf &mat, ImgChannel chn)
00016 {
00017 Int i;
00018
00019 mat.SetSize(img.Height(), img.Width());
00020
00021 for (i = 0; i < mat.Rows(); i++)
00022 img.GetRealSpan(i, 0, mat.Cols(), mat[i].Ref(), chn);
00023 }
00024
00025 Void MatToImage(const Matf &mat, Image &img, ImgChannel chn)
00026 {
00027 Int i;
00028
00029 if (img.Height() != mat.Rows() || img.Width() != mat.Cols())
00030 img.SetSize(mat.Cols(), mat.Rows());
00031
00032 for (i = 0; i < mat.Rows(); i++)
00033 img.SetRealSpan(i, 0, mat.Cols(), mat[i].Ref(), chn);
00034 }
00035
00036 Void MakeAbs(Matf &mat)
00037 {
00038 Int i, j;
00039
00040 for (i = 0; i < mat.Rows(); i++)
00041 for (j = 0; j < mat.Cols(); j++)
00042 mat[i][j] = abs(mat[i][j]);
00043 }
00044
00045 Void ClipToZeroOne(Matf &mat)
00046 {
00047 Int i, j;
00048
00049 for (i = 0; i < mat.Rows(); i++)
00050 for (j = 0; j < mat.Cols(); j++)
00051 if (mat[i][j] < 0.0)
00052 mat[i][j] = 0.0;
00053 else if (mat[i][j] > 1.0)
00054 mat[i][j] = 1.0;
00055 }
00056
00057 Void MakeRandomRotation(Vector x, Mat3d &M)
00059 {
00060 Double a, b, c, d, s;
00061 Double z, r, theta, omega;
00062 Double bb, cc, dd;
00063 Double ab, ac, ad;
00064 Double bc, bd, cd;
00065
00066 /* Use the random variables x[0] and x[1] to determine the axis of */
00067 /* rotation in cylindrical coordinates and the random variable x[2] */
00068 /* to determine the amount of rotation, omega, about this axis. */
00069
00070 z = x[0];
00071 r = sqrt(1.0 - z * z);
00072 theta = 2.0 * vl_pi * x[1];
00073 omega = vl_pi * x[2];
00074
00075 /* Compute the unit quaternion (a,b,c,d) where a is the cosine of */
00076 /* half the rotation angle and the axis vector (b,c,d) is determined */
00077 /* by "r", "theta" and "z" computed above. */
00078
00079 s = sin(omega);
00080 a = cos(omega);
00081 b = s * cos(theta) * r;
00082 c = s * sin(theta) * r;
00083 d = s * z;
00084
00085 /* Compute all the pairwise products of a, b, c, and d, except a * a. */
00086
00087 bb = b * b; cc = c * c; dd = d * d;
00088 ab = a * b; ac = a * c; ad = a * d;
00089 bc = b * c; bd = b * d; cd = c * d;
00090
00091 /* Construct an orthogonal matrix corresponding to */
00092 /* the unit quaternion (a,b,c,d). */
00093
00094 M[0][0] = 1.0 - 2.0 * (cc + dd);
00095 M[0][1] = 2.0 * (bc + ad);
00096 M[0][2] = 2.0 * (bd - ac);
00097
00098 M[1][0] = 2.0 * (bc - ad);
00099 M[1][1] = 1.0 - 2.0 * (bb + dd);
00100 M[1][2] = 2.0 * (cd + ab);
00101
00102 M[2][0] = 2.0 * (bd + ac);
00103 M[2][1] = 2.0 * (cd - ab);
00104 M[2][2] = 1.0 - 2.0 * (bb + cc);
00105 }