2004-09-16 00:58:05 +02:00
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright ( C ) 2004 \ / ) \ / *
* Visual Computing Lab / \ / | *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved . *
* *
2008-10-29 01:05:44 +01:00
* This program is free software ; you can redistribute it and / or modify *
2004-09-16 00:58:05 +02:00
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation ; either version 2 of the License , or *
* ( at your option ) any later version . *
* *
* This program is distributed in the hope that it will be useful , *
* but WITHOUT ANY WARRANTY ; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the *
* GNU General Public License ( http : //www.gnu.org/licenses/gpl.txt) *
* for more details . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-11-23 15:18:35 +01:00
2004-09-16 00:58:05 +02:00
2008-10-29 01:05:44 +01:00
/** class Shot
2011-05-19 10:46:38 +02:00
Shot is made of two elements :
* the Instrinsics paramaters , which are stored as a Camera type ( see vcg / math / camera ) and that
2008-10-07 12:57:09 +02:00
determines how a point in the frame of the camera is projected in the 2 D projection plane
2011-05-19 10:46:38 +02:00
* the Extrinsics parameters , which are stored in the class Shot ( type ReferenceFrame )
and that describe viewpoint and view direction .
2008-10-07 12:57:09 +02:00
2011-05-19 10:46:38 +02:00
Some important notes about the usage of this class :
2008-10-07 12:57:09 +02:00
2011-05-19 10:46:38 +02:00
* The World coordinates system is assumed to be RIGHT - HANDED .
* The Shot reference frame is assumed to be RIGHT - HANDED .
* The associated Camera is assumed to point in the negative direction of the Z axis of the Shot coordinates system ( reference frame ) .
As a consequence , the Camera coordinates system is LEFT - HANDED .
* The Extrinsics parameters are kept as a rotation matrix " rot " and a translation vector " tra "
The translation matrix " tra " corresponds to the viewpoint of the Shot while the rotation matrix
" rot " corresponds to the axis of the reference frame by row , i . e .
rot [ 0 ] [ 0 | 1 | 2 ] = = X axis
rot [ 1 ] [ 0 | 1 | 2 ] = = Y axis
rot [ 2 ] [ 0 | 1 | 2 ] = = Z axis
It follows that the matrix made with the upper left 3 x3 equal to rot and the 4 th colum equal to tra
and ( 0 , 0 , 0 , 1 ) in the bottom row transform a point from world coordiantes to the reference frame
of the shot .
2008-10-07 12:57:09 +02:00
* */
2004-09-16 00:58:05 +02:00
# ifndef __VCGLIB_SHOT
# define __VCGLIB_SHOT
2005-01-22 12:20:20 +01:00
# include <vcg/space/point2.h>
# include <vcg/space/point3.h>
2004-09-16 00:58:05 +02:00
# include <vcg/math/similarity.h>
# include <vcg/math/camera.h>
namespace vcg {
2008-09-26 19:07:32 +02:00
template < class S , class RotationType = Matrix44 < S > >
2004-09-16 00:58:05 +02:00
class Shot {
2005-11-23 12:58:52 +01:00
public :
2011-05-27 11:26:52 +02:00
typedef Camera < S > CameraType ;
typedef S ScalarType ;
template < class ScalarType , class RotoType >
class ReferenceFrame {
friend class Shot < ScalarType , RotoType > ;
RotoType rot ; // rotation
Point3 < S > tra ; // viewpoint
public :
2014-08-10 02:30:20 +02:00
ReferenceFrame ( ) { }
2011-05-27 11:26:52 +02:00
void SetIdentity ( ) { rot . SetIdentity ( ) ; tra = Point3 < S > ( 0.0 , 0.0 , 0.0 ) ; }
void SetTra ( const Point3 < S > & tr ) { tra = tr ; }
void SetRot ( const RotoType & rt ) { rot = rt ; }
Point3 < ScalarType > Tra ( ) const { return tra ; }
RotoType Rot ( ) const { return rot ; }
} ;
2014-08-10 02:30:20 +02:00
Camera < S > Intrinsics ; // the camera that made the shot
ReferenceFrame < S , RotationType > Extrinsics ; // the position and orientation of the camera
Shot ( const Camera < S > & i , const ReferenceFrame < S , RotationType > & e )
{
Intrinsics = i ;
Extrinsics = e ;
}
2011-05-27 11:26:52 +02:00
2014-08-10 02:30:20 +02:00
Shot ( const Camera < S > & c )
2011-05-27 11:26:52 +02:00
{
Intrinsics = c ;
Extrinsics . SetIdentity ( ) ;
}
2011-05-19 10:46:38 +02:00
2011-05-27 11:26:52 +02:00
Shot ( )
{
Extrinsics . SetIdentity ( ) ;
}
2011-05-19 10:46:38 +02:00
2014-08-10 02:30:20 +02:00
template < class Q >
static inline Shot Construct ( const Shot < Q > & b )
{
ReferenceFrame < S , RotationType > r ;
r . SetRot ( Matrix44 < S > : : Construct ( b . Extrinsics . Rot ( ) ) ) ;
r . SetTra ( Point3 < S > : : Construct ( b . Extrinsics . Tra ( ) ) ) ;
return Shot ( Camera < S > : : Construct ( b . Intrinsics ) , r ) ;
}
2011-05-19 10:46:38 +02:00
2011-05-27 11:26:52 +02:00
/// GET the i-th axis of the coordinate system of the camera
vcg : : Point3 < S > Axis ( const int & i ) const ;
2004-10-07 16:24:53 +02:00
2011-02-17 10:58:16 +01:00
/// GET the viewdir
const vcg : : Point3 < S > GetViewDir ( ) const ;
/// GET the viewpoint
const vcg : : Point3 < S > GetViewPoint ( ) const ;
/// SET the viewpoint
2011-05-27 11:26:52 +02:00
void SetViewPoint ( const vcg : : Point3 < S > & viewpoint ) ;
2004-10-07 16:24:53 +02:00
2011-05-27 11:26:52 +02:00
/// GET fov from focal
float GetFovFromFocal ( ) ;
2010-07-21 17:54:31 +02:00
2011-05-27 11:26:52 +02:00
/// look at (point+up)
void LookAt ( const vcg : : Point3 < S > & point , const vcg : : Point3 < S > & up ) ;
2004-10-07 16:24:53 +02:00
2011-05-27 11:26:52 +02:00
/// look at (opengl-like)
void LookAt ( const S & eye_x , const S & eye_y , const S & eye_z ,
const S & at_x , const S & at_y , const S & at_z ,
const S & up_x , const S & up_y , const S & up_z ) ;
2004-11-03 10:25:52 +01:00
2011-05-27 11:26:52 +02:00
/// look towards (dir+up)
void LookTowards ( const vcg : : Point3 < S > & z_dir , const vcg : : Point3 < S > & up ) ;
2004-09-16 00:58:05 +02:00
2014-08-09 02:16:50 +02:00
/* Sometimes the focal is given in pixels. In this case, this function can be used to convert it in millimiters
* given the CCD width ( in mm ) . This method should be moved in vcg : : Camera ( ) .
* Equivalent focal length is obtained by setting the ccd width to 35 mm .
2011-05-23 16:09:16 +02:00
*/
2011-10-05 17:04:40 +02:00
void ConvertFocalToMM ( S ccdwidth ) ;
2011-05-23 16:09:16 +02:00
2014-08-09 02:16:50 +02:00
/* Sometimes the 3D World coordinates are known up to a scale factor. This method adjust the camera/shot parameters
* to account for the re - scaling of the World . If the intrisic parameters are just reasonable values
* the cameras need only a re - positioning .
*/
2011-10-05 17:04:40 +02:00
void RescalingWorld ( S scalefactor , bool adjustIntrinsics ) ;
2011-05-19 18:28:51 +02:00
2011-05-24 23:13:05 +02:00
/// Given a pure roto-translation (4-by-4) modifies the reference frame accordingly.
2011-05-27 11:26:52 +02:00
void ApplyRigidTransformation ( const Matrix44 < S > & M ) ;
2011-05-19 18:28:51 +02:00
2011-05-24 23:13:05 +02:00
/// Given a similarity transformation such that p' = s R p + T modifies the reference frame accordingly.
2011-10-05 17:04:40 +02:00
void ApplySimilarity ( Matrix44 < S > M ) ;
2011-05-24 23:13:05 +02:00
/// Given a similarity transformation such that p' = s R p + T modifies the reference frame accordingly.
2011-05-27 11:26:52 +02:00
void ApplySimilarity ( const Similarity < S > & Sim ) ;
2011-05-24 23:13:05 +02:00
2011-05-27 11:26:52 +02:00
/// convert a 3d point from world to camera coordinates (do not confuse with the Shot reference frame)
vcg : : Point3 < S > ConvertWorldToCameraCoordinates ( const vcg : : Point3 < S > & p ) const ;
2004-09-16 00:58:05 +02:00
2011-05-27 11:26:52 +02:00
/// convert a 3d point from camera (do not confuse with the Shot reference frame) to world coordinates
vcg : : Point3 < S > ConvertCameraToWorldCoordinates ( const vcg : : Point3 < S > & p ) const ;
2004-12-15 19:45:50 +01:00
2011-05-27 11:26:52 +02:00
/* convert a 3d point from camera (do not confuse with the Shot reference frame) to world coordinates
* it uses inverse instead of transpose for non - exactly - rigid rotation matrices ( such as calculated by tsai and garcia )
*/
vcg : : Point3 < S > ConvertCameraToWorldCoordinates_Substitute ( const vcg : : Point3 < S > & p ) const ;
2009-09-08 16:05:49 +02:00
2011-05-27 11:26:52 +02:00
/// project a 3d point from world coordinates to 2d camera viewport (the value returned is in pixels)
vcg : : Point2 < S > Project ( const vcg : : Point3 < S > & p ) const ;
2004-09-16 00:58:05 +02:00
2011-05-27 11:26:52 +02:00
/// inverse projection from 2d camera viewport (in pixels) to 3d world coordinates (it requires the original depth of the projected point)
vcg : : Point3 < S > UnProject ( const vcg : : Point2 < S > & p , const S & d ) const ;
2004-12-15 19:45:50 +01:00
2011-05-27 11:26:52 +02:00
/* inverse projection from 2d camera viewport (in pixels) to 3d world coordinates (it requires the original depth of the projected point)
* uses inverse instead of trranspose for non - exactly - rigid rotation matrices ( such as calculated by tsai and garcia )
*/
vcg : : Point3 < S > UnProject_Substitute ( const vcg : : Point2 < S > & p , const S & d ) const ;
2009-09-08 16:05:49 +02:00
2011-05-27 11:26:52 +02:00
/// returns the distance of point p from camera plane (z depth), required for unprojection operation
S Depth ( const vcg : : Point3 < S > & p ) const ;
2004-11-03 10:25:52 +01:00
2007-02-05 15:17:21 +01:00
// accessors
public :
2011-05-27 11:26:52 +02:00
/// Returns the (4-by-4) matrix M such that 3dpoint_in_world_coordinates = M * 3dpoint_in_local_coordinates
Matrix44 < S > GetExtrinsicsToWorldMatrix ( ) const
{
Matrix44 < S > rotM ;
Extrinsics . rot . ToMatrix ( rotM ) ;
return Matrix44 < S > ( ) . SetTranslate ( Extrinsics . tra ) * rotM . transpose ( ) ;
}
/// Returns the (4-by-4) matrix M such that 3dpoint_in_local_coordinates = M * 3dpoint_in_world_coordinates
Matrix44 < S > GetWorldToExtrinsicsMatrix ( ) const
{
Matrix44 < S > rotM ;
Extrinsics . rot . ToMatrix ( rotM ) ;
return rotM * Matrix44 < S > ( ) . SetTranslate ( - Extrinsics . tra ) ;
}
/* multiply the current reference frame for the matrix passed
note : it is up to the caller to check the the matrix passed is a pure rototraslation
*/
2011-04-11 11:39:20 +02:00
void MultMatrix ( vcg : : Matrix44 < S > m44 )
{
Extrinsics . tra = m44 * Extrinsics . tra ;
m44 [ 0 ] [ 3 ] = m44 [ 1 ] [ 3 ] = m44 [ 2 ] [ 3 ] = 0.0 ; //set no translation
const S k = m44 . GetRow3 ( 0 ) . Norm ( ) ; //compute scaling (assumed uniform)
Extrinsics . rot = Extrinsics . rot * m44 . transpose ( ) * ( 1 / k ) ;
}
2007-02-05 15:17:21 +01:00
2011-05-27 11:26:52 +02:00
/* multiply the current reference frame for the similarity passed
note : it is up to the caller to check the the matrix passed is a pure rototraslation
*/
void MultSimilarity ( const Similarity < S > & s ) { MultMatrix ( s . Matrix ( ) ) ; }
bool IsValid ( ) const
{
return Intrinsics . PixelSizeMm [ 0 ] > 0 & & Intrinsics . PixelSizeMm [ 1 ] > 0 ;
}
2008-09-26 19:07:32 +02:00
2006-12-18 10:46:39 +01:00
} ; // end class definition
2005-12-07 11:57:52 +01:00
2004-09-16 00:58:05 +02:00
2011-02-17 10:58:16 +01:00
template < class S , class RotationType >
const vcg : : Point3 < S > Shot < S , RotationType > : : GetViewDir ( ) const
{
return Extrinsics . Rot ( ) . GetRow3 ( 2 ) ;
}
2006-12-18 10:46:39 +01:00
//---
/// GET the viewpoint
2008-09-26 19:07:32 +02:00
template < class S , class RotationType >
2008-10-29 01:05:44 +01:00
const vcg : : Point3 < S > Shot < S , RotationType > : : GetViewPoint ( ) const
2006-12-18 10:46:39 +01:00
{
2011-05-27 11:26:52 +02:00
return Extrinsics . tra ;
2004-10-07 16:24:53 +02:00
}
2006-12-18 10:46:39 +01:00
/// SET the viewpoint
2008-09-26 19:07:32 +02:00
template < class S , class RotationType >
void Shot < S , RotationType > : : SetViewPoint ( const vcg : : Point3 < S > & viewpoint )
2006-12-18 10:46:39 +01:00
{
2011-05-27 11:26:52 +02:00
Extrinsics . SetTra ( viewpoint ) ;
2006-12-18 10:46:39 +01:00
}
//---
2004-10-07 16:24:53 +02:00
2010-07-21 17:54:31 +02:00
/// GET fov from focal
template < class S , class RotationType >
float Shot < S , RotationType > : : GetFovFromFocal ( )
{
2011-05-27 11:26:52 +02:00
double viewportYMm = Intrinsics . PixelSizeMm [ 1 ] * Intrinsics . ViewportPx [ 1 ] ;
return 2 * ( vcg : : math : : ToDeg ( atanf ( viewportYMm / ( 2 * Intrinsics . FocalMm ) ) ) ) ;
2010-07-21 17:54:31 +02:00
}
//---
2006-12-18 10:46:39 +01:00
/// GET the i-th axis of the coordinate system of the camera
2008-09-26 19:07:32 +02:00
template < class S , class RotationType >
2008-10-29 01:05:44 +01:00
vcg : : Point3 < S > Shot < S , RotationType > : : Axis ( const int & i ) const
{
2011-05-27 11:26:52 +02:00
vcg : : Matrix44 < S > m ;
Extrinsics . rot . ToMatrix ( m ) ;
vcg : : Point3 < S > aa = m . GetRow3 ( i ) ;
return aa ;
2004-10-07 16:24:53 +02:00
}
2008-10-24 20:49:40 +02:00
/// look at (point+up)
2008-09-26 19:07:32 +02:00
template < class S , class RotationType >
void Shot < S , RotationType > : : LookAt ( const vcg : : Point3 < S > & z_dir , const vcg : : Point3 < S > & up )
2006-12-18 10:46:39 +01:00
{
2011-05-27 11:26:52 +02:00
LookTowards ( z_dir - GetViewPoint ( ) , up ) ;
2004-10-07 16:24:53 +02:00
}
2006-12-18 10:46:39 +01:00
/// look at (opengl-like)
2008-09-26 19:07:32 +02:00
template < class S , class RotationType >
void Shot < S , RotationType > : : LookAt ( const S & eye_x , const S & eye_y , const S & eye_z ,
2011-05-27 11:26:52 +02:00
const S & at_x , const S & at_y , const S & at_z ,
const S & up_x , const S & up_y , const S & up_z )
2006-12-18 10:46:39 +01:00
{
2011-05-27 11:26:52 +02:00
SetViewPoint ( Point3 < S > ( eye_x , eye_y , eye_z ) ) ;
LookAt ( Point3 < S > ( at_x , at_y , at_z ) , Point3 < S > ( up_x , up_y , up_z ) ) ;
2004-12-15 19:45:50 +01:00
}
2004-11-03 10:25:52 +01:00
2006-12-18 10:46:39 +01:00
/// look towards
2008-09-26 19:07:32 +02:00
template < class S , class RotationType >
void Shot < S , RotationType > : : LookTowards ( const vcg : : Point3 < S > & z_dir , const vcg : : Point3 < S > & up )
2006-12-18 10:46:39 +01:00
{
2011-05-27 11:26:52 +02:00
vcg : : Point3 < S > x_dir = up ^ - z_dir ;
vcg : : Point3 < S > y_dir = - z_dir ^ x_dir ;
2008-10-29 01:05:44 +01:00
2011-05-27 11:26:52 +02:00
Matrix44 < S > m ;
m . SetIdentity ( ) ;
* ( vcg : : Point3 < S > * ) & m [ 0 ] [ 0 ] = x_dir / x_dir . Norm ( ) ;
* ( vcg : : Point3 < S > * ) & m [ 1 ] [ 0 ] = y_dir / y_dir . Norm ( ) ;
* ( vcg : : Point3 < S > * ) & m [ 2 ] [ 0 ] = - z_dir / z_dir . Norm ( ) ;
2004-12-15 19:45:50 +01:00
2011-05-27 11:26:52 +02:00
Extrinsics . rot . FromMatrix ( m ) ;
2004-09-16 00:58:05 +02:00
}
2006-12-18 10:46:39 +01:00
//--- Space transformation methods
2011-05-19 10:46:38 +02:00
/// convert a 3d point from world to camera coordinates (do not confuse with the Shot reference frame)
2008-09-26 19:07:32 +02:00
template < class S , class RotationType >
vcg : : Point3 < S > Shot < S , RotationType > : : ConvertWorldToCameraCoordinates ( const vcg : : Point3 < S > & p ) const
2006-12-18 10:46:39 +01:00
{
2011-05-27 11:26:52 +02:00
Matrix44 < S > rotM ;
Extrinsics . rot . ToMatrix ( rotM ) ;
vcg : : Point3 < S > cp = rotM * ( p - GetViewPoint ( ) ) ;
cp [ 2 ] = - cp [ 2 ] ;
return cp ;
}
2011-05-19 10:46:38 +02:00
/// convert a 3d point from camera coordinates (do not confuse with the Shot reference frame) to world coordinates
2008-09-26 19:07:32 +02:00
template < class S , class RotationType >
vcg : : Point3 < S > Shot < S , RotationType > : : ConvertCameraToWorldCoordinates ( const vcg : : Point3 < S > & p ) const
2006-12-18 10:46:39 +01:00
{
2011-05-27 11:26:52 +02:00
Matrix44 < S > rotM ;
vcg : : Point3 < S > cp = p ;
cp [ 2 ] = - cp [ 2 ] ;
Extrinsics . rot . ToMatrix ( rotM ) ;
cp = rotM . transpose ( ) * cp + GetViewPoint ( ) ;
return cp ;
2004-12-15 19:45:50 +01:00
}
2006-12-18 10:46:39 +01:00
2011-05-19 10:46:38 +02:00
/// convert a 3d point from camera to world coordinates, uses inverse instead of trranspose for non-exactly-rigid rotation matrices (such as calculated by tsai and garcia)
2009-09-08 16:05:49 +02:00
template < class S , class RotationType >
vcg : : Point3 < S > Shot < S , RotationType > : : ConvertCameraToWorldCoordinates_Substitute ( const vcg : : Point3 < S > & p ) const
{
2011-05-27 11:26:52 +02:00
Matrix44 < S > rotM ;
vcg : : Point3 < S > cp = p ;
cp [ 2 ] = - cp [ 2 ] ;
Extrinsics . rot . ToMatrix ( rotM ) ;
cp = Inverse ( rotM ) * cp + GetViewPoint ( ) ;
return cp ;
2009-09-08 16:05:49 +02:00
}
2011-05-19 10:46:38 +02:00
/// project a 3d point from world coordinates to 2d camera viewport (the value returned is in pixel)
2008-09-26 19:07:32 +02:00
template < class S , class RotationType >
vcg : : Point2 < S > Shot < S , RotationType > : : Project ( const vcg : : Point3 < S > & p ) const
2006-12-18 10:46:39 +01:00
{
2011-05-27 11:26:52 +02:00
Point3 < S > cp = ConvertWorldToCameraCoordinates ( p ) ;
Point2 < S > pp = Intrinsics . Project ( cp ) ;
Point2 < S > vp = Intrinsics . LocalToViewportPx ( pp ) ;
return vp ;
2004-12-15 19:45:50 +01:00
}
2006-12-18 10:46:39 +01:00
2011-05-19 10:46:38 +02:00
/// inverse projection from 2d camera viewport (in pixels) to 3d world coordinates (it requires the original depth of the point to unproject)
2008-09-26 19:07:32 +02:00
template < class S , class RotationType >
vcg : : Point3 < S > Shot < S , RotationType > : : UnProject ( const vcg : : Point2 < S > & p , const S & d ) const
2006-12-18 10:46:39 +01:00
{
2011-05-27 11:26:52 +02:00
Point2 < S > lp = Intrinsics . ViewportPxToLocal ( p ) ;
Point3 < S > cp = Intrinsics . UnProject ( lp , d ) ;
Point3 < S > wp = ConvertCameraToWorldCoordinates ( cp ) ;
return wp ;
2004-09-16 00:58:05 +02:00
}
2011-05-27 11:26:52 +02:00
/* inverse projection from 2d camera viewport (in pixels) to 3d world coordinates (it requires the original depth of the projected point)
2011-05-19 10:46:38 +02:00
* uses inverse instead of trranspose for non - exactly - rigid rotation matrices ( such as calculated by tsai and garcia )
*/
2009-09-08 16:05:49 +02:00
template < class S , class RotationType >
vcg : : Point3 < S > Shot < S , RotationType > : : UnProject_Substitute ( const vcg : : Point2 < S > & p , const S & d ) const
{
2011-05-27 11:26:52 +02:00
Point2 < S > lp = Intrinsics . ViewportPxToLocal ( p ) ;
Point3 < S > cp = Intrinsics . UnProject ( lp , d ) ;
Point3 < S > wp = ConvertCameraToWorldCoordinates_Substitute ( cp ) ;
return wp ;
2009-09-08 16:05:49 +02:00
}
2011-05-19 10:46:38 +02:00
/// returns the distance of point p from camera plane (z depth), required for unprojection operation
2008-09-26 19:07:32 +02:00
template < class S , class RotationType >
2008-10-29 01:05:44 +01:00
S Shot < S , RotationType > : : Depth ( const vcg : : Point3 < S > & p ) const
2005-12-07 11:57:52 +01:00
{
2011-05-27 11:26:52 +02:00
return ConvertWorldToCameraCoordinates ( p ) . Z ( ) ;
2005-12-07 11:57:52 +01:00
}
2004-09-16 00:58:05 +02:00
2011-10-05 17:04:40 +02:00
/* Sometimes the focal is given in pixels. In this case, this function can be used to convert it in millimiters
* given the CCD width ( in mm ) . This method should be moved in vcg : : Camera ( ) .
2012-10-08 11:07:50 +02:00
* Equivalent focal length is obtained by setting the ccd width to 35 mm .
2011-05-23 16:09:16 +02:00
*/
template < class S , class RotationType >
2011-10-05 17:04:40 +02:00
void Shot < S , RotationType > : : ConvertFocalToMM ( S ccdwidth )
2011-05-23 16:09:16 +02:00
{
2011-10-05 17:04:40 +02:00
double ccd_width = ccdwidth ; // ccd is assumed conventionally to be 35mm
2011-05-27 11:26:52 +02:00
double ccd_height = ( ccd_width * Intrinsics . ViewportPx [ 1 ] ) / Intrinsics . ViewportPx [ 0 ] ;
Intrinsics . PixelSizeMm [ 0 ] = ( ccd_width / Intrinsics . ViewportPx [ 0 ] ) ;
Intrinsics . PixelSizeMm [ 1 ] = ( ccd_height / Intrinsics . ViewportPx [ 1 ] ) ;
Intrinsics . FocalMm = ( ccd_width * Intrinsics . FocalMm ) / Intrinsics . ViewportPx [ 0 ] ; // NOW FOCAL IS IN MM
2011-05-23 16:09:16 +02:00
}
2011-05-19 18:28:51 +02:00
/* Sometimes the 3D World coordinates are known up to a scale factor. This method adjust the camera/shot parameters
2014-08-09 02:16:50 +02:00
* to account for the re - scaling of the World . If the intrisic parameters are just reasonable values
2011-10-05 17:04:40 +02:00
* the cameras need only a re - positioning .
2011-05-19 18:28:51 +02:00
*/
template < class S , class RotationType >
2011-10-05 17:04:40 +02:00
void Shot < S , RotationType > : : RescalingWorld ( S scalefactor , bool adjustIntrinsics )
2011-05-19 18:28:51 +02:00
{
2011-10-05 17:04:40 +02:00
// adjust INTRINSICS (if required)
2011-05-27 11:26:52 +02:00
2014-08-09 02:16:50 +02:00
if ( adjustIntrinsics )
{
Intrinsics . FocalMm = Intrinsics . FocalMm * scalefactor ;
double ccdwidth = static_cast < double > ( Intrinsics . ViewportPx [ 0 ] * Intrinsics . PixelSizeMm [ 0 ] ) ;
double ccdheight = static_cast < double > ( Intrinsics . ViewportPx [ 1 ] * Intrinsics . PixelSizeMm [ 1 ] ) ;
2011-05-19 18:28:51 +02:00
2014-08-09 02:16:50 +02:00
Intrinsics . PixelSizeMm [ 0 ] = ( ccdwidth * scalefactor ) / Intrinsics . ViewportPx [ 0 ] ;
Intrinsics . PixelSizeMm [ 1 ] = ( ccdheight * scalefactor ) / Intrinsics . ViewportPx [ 1 ] ;
}
2011-05-19 18:28:51 +02:00
2011-05-27 11:26:52 +02:00
// adjust EXTRINSICS
2011-05-19 18:28:51 +02:00
2011-05-27 11:26:52 +02:00
// rotation remains the same (!)
// nothing to do..
2011-05-19 18:28:51 +02:00
2011-05-27 11:26:52 +02:00
// the viewpoint should be modified according to the scale factor
Extrinsics . tra * = scalefactor ;
2011-05-19 18:28:51 +02:00
}
/// Given a pure roto-translation matrix (4-by-4) modify the reference frame accordingly.
template < class S , class RotationType >
2011-05-24 14:13:21 +02:00
void Shot < S , RotationType > : : ApplyRigidTransformation ( const Matrix44 < S > & M )
2011-05-19 18:28:51 +02:00
{
2011-05-27 11:26:52 +02:00
Matrix44 < S > rotM ;
Extrinsics . rot . ToMatrix ( rotM ) ;
// roto-translate the viewpoint
Extrinsics . tra = M * Extrinsics . tra ;
2011-10-05 17:04:40 +02:00
Matrix44 < S > newRot = rotM * M . transpose ( ) ;
2011-10-28 16:20:27 +02:00
newRot [ 3 ] [ 0 ] = newRot [ 3 ] [ 1 ] = newRot [ 3 ] [ 2 ] = 0.0 ;
2011-10-05 17:04:40 +02:00
Extrinsics . SetRot ( newRot ) ;
2011-05-19 18:28:51 +02:00
}
2006-12-18 10:46:39 +01:00
2011-10-05 17:04:40 +02:00
/// Given a similarity transformation modifies the reference frame accordingly.
2011-05-24 23:13:05 +02:00
template < class S , class RotationType >
2011-10-05 17:04:40 +02:00
void Shot < S , RotationType > : : ApplySimilarity ( Matrix44 < S > M )
2011-05-24 23:13:05 +02:00
{
Matrix44 < S > rotM ;
Extrinsics . rot . ToMatrix ( rotM ) ;
2011-10-05 17:04:40 +02:00
// normalize
M = M * ( 1 / M . ElementAt ( 3 , 3 ) ) ;
M [ 3 ] [ 3 ] = 1 ; // just for numeric precision
// compute scale factor
ScalarType scalefactor = 1.0 / pow ( ScalarType ( M . Determinant ( ) ) , 1 / ScalarType ( 3.0 ) ) ;
2011-05-24 23:13:05 +02:00
// roto-translate the viewpoint
Extrinsics . tra = M * Extrinsics . tra ;
vcg : : Matrix44 < S > M2 = M ;
2012-07-09 17:12:56 +02:00
M2 = M2 * scalefactor ; // remove the scaling
2014-08-09 02:16:50 +02:00
M2 [ 3 ] [ 3 ] = 1.0 ;
2011-10-11 17:41:54 +02:00
M2 [ 0 ] [ 3 ] = M2 [ 1 ] [ 3 ] = M2 [ 2 ] [ 3 ] = 0 ; // remove the translation
2011-10-05 17:04:40 +02:00
rotM = rotM * M2 . transpose ( ) ;
Extrinsics . SetRot ( rotM ) ;
2011-05-24 23:13:05 +02:00
}
2011-10-05 17:04:40 +02:00
/// Given a similarity transformation modifies the reference frame accordingly.
2011-05-24 23:13:05 +02:00
template < class S , class RotationType >
2011-05-25 08:58:39 +02:00
void Shot < S , RotationType > : : ApplySimilarity ( const Similarity < S > & Sm )
2011-05-24 23:13:05 +02:00
{
2011-05-25 08:58:39 +02:00
Matrix44 < S > rotM ;
Extrinsics . rot . ToMatrix ( rotM ) ;
// similarity decomposition
vcg : : Matrix44 < S > R ;
Sm . rot . ToMatrix ( R ) ;
vcg : : Matrix44 < S > T ;
T . SetIdentity ( ) ;
T . ElementAt ( 0 , 3 ) = Sm . tra [ 0 ] ;
T . ElementAt ( 1 , 3 ) = Sm . tra [ 1 ] ;
T . ElementAt ( 2 , 3 ) = Sm . tra [ 2 ] ;
vcg : : Matrix44d S44 ;
S44 . SetIdentity ( ) ;
S44 * = Sm . sca ;
S44 . ElementAt ( 3 , 3 ) = 1.0 ;
vcg : : Matrix44 < S > M = T * R * S44 ;
// roto-translate the viewpoint
Extrinsics . tra = M * Extrinsics . tra ;
vcg : : Matrix44 < S > M2 = M ;
M2 = M2 * ( 1.0 / Sm . sca ) ;
Extrinsics . rot = rotM * M2 . transpose ( ) ;
Extrinsics . rot . ElementAt ( 3 , 0 ) = 0 ;
Extrinsics . rot . ElementAt ( 3 , 1 ) = 0 ;
Extrinsics . rot . ElementAt ( 3 , 2 ) = 0 ;
2011-06-15 14:32:19 +02:00
Extrinsics . rot . ElementAt ( 3 , 3 ) = 1 ;
2011-05-24 23:13:05 +02:00
}
2006-12-18 10:46:39 +01:00
//--------------------------------
//--- utility definitions
2010-10-21 15:41:29 +02:00
typedef Shot < float > Shotf ;
typedef Shot < double > Shotd ;
2006-12-18 10:46:39 +01:00
//-----------------------
2004-09-16 00:58:05 +02:00
2005-12-01 02:03:37 +01:00
} // end name space
2005-11-23 12:58:52 +01:00
# endif
2004-09-16 00:58:05 +02:00