/******************************************************************** ** Image Component Library (ICL) ** ** ** ** Copyright (C) 2006-2012 CITEC, University of Bielefeld ** ** Neuroinformatics Group ** ** Website: www.iclcv.org and ** ** http://opensource.cit-ec.de/projects/icl ** ** ** ** File : ICLGeom/test/test-camera.cpp ** ** Module : ICLGeom ** ** Authors: Erik Weitnauer ** ** ** ** ** ** Commercial License ** ** ICL can be used commercially, please refer to our website ** ** www.iclcv.org for more details. ** ** ** ** GNU General Public License Usage ** ** Alternatively, this file may be used under the terms of the ** ** GNU General Public License version 3.0 as published by the ** ** Free Software Foundation and appearing in the file LICENSE.GPL ** ** included in the packaging of this file. Please review the ** ** following information to ensure the GNU General Public License ** ** version 3.0 requirements will be met: ** ** http://www.gnu.org/copyleft/gpl.html. ** ** ** ** The development of this software was supported by the ** ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** ** Forschungsgemeinschaft (DFG) in the context of the German ** ** Excellence Initiative. ** ** ** *********************************************************************/ #include #include #include #include #include #include #include using namespace icl; using namespace std; using namespace testing; class CameraTest : public Test { protected: virtual void SetUp() { // initialize camera cam.setName("Example Camera"); cam.setPosition(Vec(0,50,50,1)); cam.setRotation(Vec(40.*M_PI/180.,-10.*M_PI/180.,0.)); cam.setFocalLength(3); cam.setPrincipalPointOffset(Point32f(320,240)); cam.setSamplingResolution(200,200); cam.setSkew(0); cam.getRenderParams().viewport = Rect(0,0,640,480); cam.getRenderParams().chipSize = Size(640,480); // initialize example world points Xs.push_back(Vec(406,941,1183,1)); Xs.push_back(Vec(266,937,1062,1)); Xs.push_back(Vec(-1,795,814,1)); Xs.push_back(Vec(89,890,1139,1)); Xs.push_back(Vec(223,692,1174,1)); Xs.push_back(Vec(428,776,1072,1)); Xs.push_back(Vec(432,924,1103,1)); Xs.push_back(Vec(29,887,1097,1)); // initialize corresponding image points xs_correct.push_back(Point32f(402.2513,207.6056)); xs_correct.push_back(Point32f(357.7913,244.0200)); xs_correct.push_back(Point32f(243.9973,289.5791)); xs_correct.push_back(Point32f(275.6749,215.6134)); xs_correct.push_back(Point32f(331.3610,126.2544)); xs_correct.push_back(Point32f(433.0986,175.7763)); xs_correct.push_back(Point32f(422.9612,220.7864)); xs_correct.push_back(Point32f(250.9546,228.8122)); } // virtual void TearDown() {} Camera cam; vector Xs; vector xs_correct; }; float get_distance_point_line(Vec x, ViewRay l) { Vec result = cross(l.offset-x,normalize3(l.direction)); result[3] = 0; return result.length(); } TEST(Camera, set_rotation) { Camera c; c.setPosition(Vec(1,2,3,0)); c.setRotation(Vec(40.*M_PI/180.,-10.*M_PI/180.,5.*M_PI/180.)); Mat T_corr( 0.9811,-0.0858,-0.1736,-0.2885, -0.0444, 0.7729,-0.6330, 0.3978, 0.1885, 0.6287, 0.7544,-3.7093, 0, 0, 0, 1); Mat T_cam = c.getCSTransformationMatrix(); EXPECT_TRUE(isNear(T_corr, T_cam, 0.001f)); } TEST_F(CameraTest, project_points) { // calculate the image points by using the camera object vector xs_camera = cam.project(Xs); ASSERT_EQ(xs_correct.size(), xs_camera.size()); for (unsigned int i=0; i xs = cam.project(Xs); // now check whether the viewray for each image point runs through the world point for (unsigned int i=0; i &world, vector &image) { std::ifstream fs(filename.c_str()); if(!fs) throw ICLException("wrong filename: " + filename); world.resize(40); image.resize(40); for (int i=0; i<40; i++) { fs >> image[i] >> world[i]; //image.push_back(Point32f(800-p.x,600-p.y)); } } TEST_F(CameraTest, IO) { // fixture provides a camera 'cam' and 8 world points 'Xs' stringstream s; s << cam; Camera cam_from_stream(s); expectCameraSimilar(cam, cam_from_stream,true); EXPECT_EQ(cam.getName(), cam_from_stream.getName()); } TEST_F(CameraTest, calibration_SVD) { // fixture provides a camera 'cam' and 8 world points 'Xs' cam.setSkew(10); cam.setSamplingResolutionY(160); vector xs = cam.project(Xs); // try to compute the camera from the corresponding points Camera cam_est = Camera::calibrate(Xs, xs); expectCameraSimilar(cam, cam_est); vector xs_est = cam_est.project(Xs); for (unsigned int i=0; i xs = cam.project(Xs); // try to compute the camera from the corresponding points Camera cam_est = Camera::calibrate_pinv(Xs, xs); expectCameraSimilar(cam, cam_est); vector xs_est = cam_est.project(Xs); for (unsigned int i=0; i Xs; std::vector xs; readPoints("points.txt",Xs,xs); Camera cam_est = Camera::calibrate(Xs, xs); Camera cam_est2 = Camera::calibrate_pinv(Xs, xs); vector xs_est = cam_est.project(Xs); vector xs_est2 = cam_est2.project(Xs); for (unsigned int i=0; i Xws; Xws.push_back(Vec(0,0,0,1)); Xws.push_back(Vec(50,0,0,1)); Xws.push_back(Vec(0,50,0,1)); Xws.push_back(Vec(0,0,50,1)); // project and test vector xis = cam.projectGL(Xws); EXPECT_NEAR(xis[0][0],320,1e-4); EXPECT_NEAR(xis[0][1],240,1e-4); EXPECT_GT(xis[1][0], 320); EXPECT_NEAR(xis[1][1],240,1e-4); EXPECT_NEAR(xis[2][0],320,1e-4); EXPECT_LT(xis[2][1], 240); EXPECT_NEAR(xis[3][0],320,1e-4); EXPECT_NEAR(xis[3][1],240,1e-4); } TEST(Camera, projectGL) { // get example camera, 8 world points and the corresponding image points Camera cam; cam.setPosition(Vec(0,0,150,1)); cam.setNorm(Vec(0,0,-1,1)); cam.setUp(Vec(0,1,0,1)); vector Xs; Xs.push_back(Vec(0,0,0,1)); Xs.push_back(Vec(100,0,0,1)); Xs.push_back(Vec(0,100,0,1)); Xs.push_back(Vec(0,0,100,1)); cam.setPrincipalPointOffset(300,200); cam.setSkew(-10); //Mat T = cam.getCSTransformationMatrix(); //Mat P = cam.getProjectionMatrix(); //Mat Tgl = cam.getCSTransformationMatrixGL(); //Mat Pgl = cam.getProjectionMatrixGL(); //Mat V = cam.getViewportMatrixGL(); //DEBUG_LOG("Rot. matrix (Std): " << T); //DEBUG_LOG("Rot. matrix (OGL): " << Tgl); for (unsigned int i=0; i CAMS(N); std::vector projections(N); URand r(0,0.1); float nAll = 0; float nWrong = 0; for(int x=-10;x<10;x+=3){ for(int y=-10;y<10;y+=3){ for(int z=-10;z<10;z+=3){ Vec pOrig(x,y,z,1); for(int i=0;iproject(pOrig); } try{ Vec pEst = Camera::estimate_3D_svd(CAMS,projections); nAll++; if((pOrig-pEst).length() > 0.001) nWrong++; }catch(...){ nWrong++; } for(int i=0;i 0.1){ SHOW(nWrong); SHOW(nAll); } EXPECT_LT(nWrong/nAll,0.1); }