Go to the documentation of this file.00001
00006 #ifndef P_POSE_CV_HH
00007 #define P_POSE_CV_HH
00008
00009 #include <limits.h>
00010 #include <map>
00011
00012
00013 #include <opencv2/opencv.hpp>
00014 #include <iostream>
00015 #include <blort/Recognizer3D/PNamespace.hh>
00016 #include <blort/Recognizer3D/Array.hh>
00017 #include <opencv2/core/core.hpp>
00018
00019 namespace P
00020 {
00021
00022
00023 class PoseCv
00024 {
00025 private:
00026
00027
00028 public:
00029 CvMat *R;
00030 CvMat *t;
00031 CvMat *n;
00032
00033 PoseCv();
00034 PoseCv(cv::Mat translation, cv::Mat rotation);
00035 ~PoseCv();
00036 };
00037
00038 void InitializePoseCv(PoseCv &pose);
00039 void DeletePoseCv(Array<PoseCv*> &ps);
00040
00041 inline void CopyPoseCv(PoseCv &in, PoseCv &out);
00042 inline void Rot2Quat(CvMat *M, double *q);
00043 inline void Rot2Vec3(CvMat *R, double *d);
00044 inline void Quat2Rot(double *q, CvMat *M);
00045 inline void Vec32Rot(double *d, CvMat *R);
00046 inline void InvPoseCv(PoseCv &in, PoseCv &out);
00047
00048
00049
00050
00051
00052 inline void CopyPoseCv(PoseCv &in, PoseCv &out)
00053 {
00054 cvCopy(in.R, out.R);
00055 cvCopy(in.t, out.t);
00056 cvCopy(in.n, out.n);
00057 }
00058
00059 inline void Rot2Quat(CvMat *M, double *q)
00060 {
00061 float *R = M->data.fl;
00062
00063 double tmp[4];
00064 double mag;
00065 unsigned maxpos;
00066 tmp[0]=1.0 + R[0] + R[4] + R[8];
00067 tmp[1]=1.0 + R[0] - R[4] - R[8];
00068 tmp[2]=1.0 - R[0] + R[4] - R[8];
00069 tmp[3]=1.0 - R[0] - R[4] + R[8];
00070
00071 mag=-1.0;
00072 for(unsigned i=0; i<4; i++){
00073 if(tmp[i]>mag){
00074 mag=tmp[i];
00075 maxpos=i;
00076 }
00077 }
00078 if(maxpos==0){
00079 q[0]=sqrt(tmp[0])*0.5;
00080 q[1]=(R[7] - R[5])/(4.0*q[0]);
00081 q[2]=(R[2] - R[6])/(4.0*q[0]);
00082 q[3]=(R[3] - R[1])/(4.0*q[0]);
00083 }
00084 else if(maxpos==1){
00085 q[1]=sqrt(tmp[1])*0.5;
00086 q[0]=(R[7] - R[5])/(4.0*q[1]);
00087 q[2]=(R[3] + R[1])/(4.0*q[1]);
00088 q[3]=(R[2] + R[6])/(4.0*q[1]);
00089 }
00090 else if(maxpos==2){
00091 q[2]=sqrt(tmp[2])*0.5;
00092 q[0]=(R[2] - R[6])/(4.0*q[2]);
00093 q[1]=(R[3] + R[1])/(4.0*q[2]);
00094 q[3]=(R[7] + R[5])/(4.0*q[2]);
00095 }
00096 else if(maxpos==3){
00097 q[3]=sqrt(tmp[3])*0.5;
00098 q[0]=(R[3] - R[1])/(4.0*q[3]);
00099 q[1]=(R[2] + R[6])/(4.0*q[3]);
00100 q[2]=(R[7] + R[5])/(4.0*q[3]);
00101 }
00102 else
00103 {
00104 cout<<"komisch"<<endl;
00105 }
00106
00107 mag=q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3];
00108
00109 if(!IsZero(mag-1.))
00110 {
00111
00112 mag=1.0/sqrt(mag);
00113 q[0]*=mag; q[1]*=mag; q[2]*=mag; q[3]*=mag;
00114 }
00115 }
00116
00117 inline void Rot2Vec3(CvMat *R, double *d)
00118 {
00119 double t[4];
00120 Rot2Quat(R,t);
00121
00122 double mag=sqrt(Sqr(t[0]) + Sqr(t[1]) + Sqr(t[2]) + Sqr(t[3]));
00123 double sg=(t[0]>=0.0)? 1.0 : -1.0;
00124 mag=sg/mag;
00125 d[0] = t[1]*mag;
00126 d[1] = t[2]*mag;
00127 d[2] = t[3]*mag;
00128 }
00129
00130 inline void Quat2Rot(double *q, CvMat *M)
00131 {
00132 float *R = M->data.fl;
00133
00134
00135 double mag = q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3];
00136 if(!IsZero(mag-1.0))
00137 {
00138 mag=1.0/sqrt(mag);
00139 q[0]*=mag; q[1]*=mag; q[2]*=mag; q[3]*=mag;
00140 }
00141
00142 R[0]=q[0]*q[0]+q[1]*q[1]-q[2]*q[2]-q[3]*q[3];
00143 R[1]=2*(q[1]*q[2]-q[0]*q[3]);
00144 R[2]=2*(q[1]*q[3]+q[0]*q[2]);
00145
00146 R[3]=2*(q[1]*q[2]+q[0]*q[3]);
00147 R[4]=q[0]*q[0]+q[2]*q[2]-q[1]*q[1]-q[3]*q[3];
00148 R[5]=2*(q[2]*q[3]-q[0]*q[1]);
00149
00150 R[6]=2*(q[1]*q[3]-q[0]*q[2]);
00151 R[7]=2*(q[2]*q[3]+q[0]*q[1]);
00152 R[8]=q[0]*q[0]+q[3]*q[3]-q[1]*q[1]-q[2]*q[2];
00153 }
00154
00155 inline void Vec32Rot(double *d, CvMat *R)
00156 {
00157 double q[4];
00158 q[0] = sqrt(1.0 - Sqr(d[0]) - Sqr(d[1])- Sqr(d[2]));
00159 q[1] = d[0];
00160 q[2] = d[1];
00161 q[3] = d[2];
00162
00163 Quat2Rot(q,R);
00164 }
00165
00166 inline void InvPoseCv(PoseCv &in, PoseCv &out)
00167 {
00168 cvTranspose( in.R, out.R );
00169 cvGEMM( out.R, in.t, -1, 0, 0, out.t, 0 );
00170 }
00171
00172
00173 }
00174
00175 #endif
00176