Exemplo n.º 1
0
bool CalibrationArea::on_button_press_event(GdkEventButton *event)
{
    // Handle click
    time_elapsed = 0;
    bool success = calibrator->add_click((int)event->x_root, (int)event->y_root);

    if (!success && calibrator->get_numclicks() == 0) {
        draw_message("Mis-click detected, restarting...");
    } else {
        draw_message(NULL);
    }

    // Are we done yet?
    if (calibrator->get_numclicks() >= 4) {
        // Recalibrate
        success = calibrator->finish(display_width, display_height);

        if (success) {
            exit(0);
        } else {
            // TODO, in GUI ?
            fprintf(stderr, "Error: unable to apply or save configuration values");
            exit(1);
        }
    }

    // Force a redraw
    redraw();

    return true;
}
Exemplo n.º 2
0
bool GuiCalibratorX11::on_button_press_event(int x, int y)
{
    // Clear window, maybe a bit overdone, but easiest for me atm.
    // (goal is to clear possible message and other clicks)
    XClearWindow(display, win);

    // Handle click
    time_elapsed = 0;
    bool success = calibrator->add_click(x, y);

    if (!success && calibrator->get_numclicks() == 0) {
        draw_message("Mis-click detected, restarting...");
    }

    // Are we done yet?
    if (calibrator->get_numclicks() >= 4) {
        // Recalibrate
        success = calibrator->finish();

        if (success) {
            exit(0);
        } else {
            // TODO, in GUI ?
            fprintf(stderr, "Error: unable to apply or save configuration values");
            exit(1);
        }
    }

    // Force a redraw
    redraw();

    return true;
}
Exemplo n.º 3
0
int main(int argc, char** argv)
{
	dataLog.makeFile();

	p.connect();				//connect our publisher

	c.setLogger(dataLog);		//set the log
	c.setPub(p);			//set the publisher

	int counter = 0;			//count how many calibration points received

	connect();

		while (1)
		{

			subscribe(c);		//listen for a calibration point
			counter++;			

			if (counter >= 9)	//if all points received
			{
				c.calibrate();				//calculate calibration matrix
				calibrated = true;			//calibration is complete
				counter = 0;				//reset counter in case of recalibration
				thread t1(runMapper, c);	//start sending the screen points to the oculus
				t1.detach();				//detach the thread
			}
		}
	
	return 0;
}
Exemplo n.º 4
0
void GuiCalibratorX11::redraw()
{
#ifdef HAVE_X11_XRANDR
    // check that screensize did not change
    int nsizes;
    XRRScreenSize* randrsize = XRRSizes(display, screen_num, &nsizes);
    if (nsizes != 0 && (display_width != randrsize->width ||
                        display_height != randrsize->height)) {
        set_display_size(randrsize->width, randrsize->height);
    }
#endif

    // Print the text
    int text_height = font_info->ascent + font_info->descent;
    int text_width = -1;
    for (int i = 0; i != help_lines; i++) {
        text_width = std::max(text_width, XTextWidth(font_info,
            help_text[i].c_str(), help_text[i].length()));
    }

    int x = (display_width - text_width) / 2;
    int y = (display_height - text_height) / 2 - 60;
    XSetForeground(display, gc, pixel[BLACK]);
    XSetLineAttributes(display, gc, 2, LineSolid, CapRound, JoinRound);
    XDrawRectangle(display, win, gc, x - 10, y - (help_lines*text_height) - 10,
                text_width + 20, (help_lines*text_height) + 20);

    // Print help lines
    y -= 3;
    for (int i = help_lines-1; i != -1; i--) {
        int w = XTextWidth(font_info, help_text[i].c_str(), help_text[i].length());
        XDrawString(display, win, gc, x + (text_width-w)/2, y,
                help_text[i].c_str(), help_text[i].length());
        y -= text_height;
    }

    // Draw the points
    for (int i = 0; i <= calibrator->get_numclicks(); i++) {
        // set color: already clicked or not
        if (i < calibrator->get_numclicks())
            XSetForeground(display, gc, pixel[WHITE]);
        else
            XSetForeground(display, gc, pixel[RED]);
        XSetLineAttributes(display, gc, 1, LineSolid, CapRound, JoinRound);

        XDrawLine(display, win, gc, X[i] - cross_lines, Y[i],
                X[i] + cross_lines, Y[i]);
        XDrawLine(display, win, gc, X[i], Y[i] - cross_lines,
                X[i], Y[i] + cross_lines);
        XDrawArc(display, win, gc, X[i] - cross_circle, Y[i] - cross_circle,
                (2 * cross_circle), (2 * cross_circle), 0, 360 * 64);
    }

    // Draw the clock background
    XSetForeground(display, gc, pixel[DIMGRAY]);
    XSetLineAttributes(display, gc, 0, LineSolid, CapRound, JoinRound);
    XFillArc(display, win, gc, (display_width-clock_radius)/2, (display_height - clock_radius)/2,
                clock_radius, clock_radius, 0, 360 * 64);
}
Exemplo n.º 5
0
void subscribe(Calibrator c)
{
	
		//Listen for calibration signal from Oculus
		string msg = s_recv(subscriber4);
		cout << "got " << msg << endl;
		dataLog.log("got " + msg + "\n");

		//Check if already calibrated
		if (calibrated)
		{
			//If already calibrated then begin a new calibration
			cout << "New Calibration" << endl;
			dataLog.log("Beginning new calibration\n");
			calibrated = false;
			//Set the counter in Calibrator back to zero
			c.recalibrate();
			
		}

		string msg2 = "";
		string msg3 = "";
		string msg4 = "";

		int b = 1;

		//Receive pupil coordinates from tracker
		while (b)
		{
			msg2 = s_recv(subscriber3);
			cout << "got " << msg2 << endl;
			msg3 = s_recv(subscriber3);
			cout << "got " << msg3 << endl;
			msg4 = s_recv(subscriber3);
			cout << "got " << msg4 << endl;

			//Reject if a zero value is received
			if (atof(msg3.c_str()) != 0.0 && atof(msg4.c_str()) != 0.0) 
			{
				b = 0; //Accept if no zeros
			}
		}

		cout << "Trying to add x: " << msg3.c_str() << endl;
		dataLog.log("Trying to add x : " + msg3 + "\n");

		//Send to the Calibrator
		c.setX(atof(msg3.c_str()));

		cout << "Trying to add y: " << msg4.c_str() << endl;
		dataLog.log("Trying to add x : " + msg4 + "\n");

		c.setY(atof(msg4.c_str()));

}
Exemplo n.º 6
0
int main (int argc, char ** argv)
{
//  if(pcl::console::find_switch(argc, argv, "-h") || pcl::console::find_switch(argc, argv, "--help"))
//    print_help(argv);

cout << "Calibrate RGBD360 multisensor\n";
  Calibrator calibrator;
  calibrator.run();

cout << "EXIT\n";
  return (0);
}
Exemplo n.º 7
0
void runMapper(Calibrator c)
{

	//Stop if recalibration is in progress
	while(calibrated)
	{
		std::string msg2 = "";
		std::string msg3 = "";
		std::string msg4 = "";
		int b = 1;
		while (b)
		{
			msg2 = s_recv(subscriber5);
			std::cout << "got " << msg2 << std::endl;
			msg3 = s_recv(subscriber5);
			std::cout << "got " << msg3 << std::endl;
			msg4 = s_recv(subscriber5);
			std::cout << "got " << msg4 << std::endl;
			if (atof(msg3.c_str()) != 0.0 && atof(msg4.c_str()) != 0.0) {
				b = 0;
			}
		}

		cout << "To be mapped: " << msg3 << ", " << msg4 << endl;
		dataLog.log("To be mapped: " + msg3 + ", " + msg4 + "\n");

		//Send to the mapper to map to screen points
		c.homography_map_point(atof(msg3.c_str()), atof(msg4.c_str()));
	}
}
void setup() {
    useInputStream(iStream);
    useOutputStream(oStream);

    calibrator.setCalibrateFunction(processAccelerometerData);
    calibrator.addCalibrateProcess("Resting",
        "Rest accelerometer on flat surface.", restingDataCollected);
    useCalibrator(calibrator);
  
    DTW dtw(false, true, null_rej);

    pipeline.setClassifier(dtw);
    usePipeline(pipeline);

    registerTuneable(null_rej, 0.1, 5.0, "Variability",
         "How different from the training data a new gesture can be and "
         "still be considered the same gesture. The higher the number, the "
         "more different it can be.", updateVariability);

    useTrainingSampleChecker(checkTrainingSample);
}
void setup()
{
    stream.setLabelsForAllDimensions({"x", "y", "z"});
    useStream(stream);
    useOutputStream(oStream);

    calibrator.setCalibrateFunction(processAccelerometerData);
    calibrator.addCalibrateProcess("Resting",
        "Rest accelerometer on flat surface.", restingDataCollected);
    useCalibrator(calibrator);

    pipeline.addFeatureExtractionModule(FeatureApply(3, 1, dotProduct));
    pipeline.addFeatureExtractionModule(TimeseriesBuffer(80, 1));
    pipeline.addFeatureExtractionModule(FeatureApply(80, 1, stddev));
    pipeline.addFeatureExtractionModule(FeatureApply(1, 1, threshold));
    usePipeline(pipeline);
    
    registerTuneable(t, 0, 1.0, "Walking Threshold",
        "How much the accelerometer data needs to be "
        "changing to be considered walking.");
}
Exemplo n.º 10
0
void CalibrationArea::set_display_size(int width, int height) {
    display_width = width;
    display_height = height;

    // Compute absolute circle centers
    const int delta_x = display_width/num_blocks;
    const int delta_y = display_height/num_blocks;
    X[UL] = delta_x;                     Y[UL] = delta_y;
    X[UR] = display_width - delta_x - 1; Y[UR] = delta_y;
    X[LL] = delta_x;                     Y[LL] = display_height - delta_y - 1;
    X[LR] = display_width - delta_x - 1; Y[LR] = display_height - delta_y - 1;

    // reset calibration if already started
    calibrator->reset();
}
Exemplo n.º 11
0
int main(int argc, char** argv)
{
    ////////////////////////////////////////////////////////////////////
    // Create command line options. Check if we should print usage.

    GetPot cl(argc,argv);

    if(cl.search(3, "-help", "-h", "?") || argc < 2) {
        std::cout << sUriInfo << std::endl;
        return -1;
    }

    ////////////////////////////////////////////////////////////////////
    // Default configuration values

    // Default grid printed on US Letter
    int grid_preset = GridPresetGWUSmall;
    double grid_spacing;
    int grid_rows;
    int grid_cols;
    uint32_t grid_seed;
    double grid_large_rad;
    double grid_small_rad;
    std::string save_grid;

    // Use no input cameras by default
    std::vector<calibu::CameraAndPose > input_cameras;

    // Fix cameras intrinsic parameters during optimisation, changing
    // only their relative poses.
    bool fix_intrinsics = false;

    // Require user to start playing the video
    bool start_paused = false;

    // Output file for camera rig
    std::string output_filename = "cameras.xml";

    ////////////////////////////////////////////////////////////////////
    // Parse command line

    grid_preset = cl.follow(grid_preset, "-grid-preset");
    switch(grid_preset)
    {
      case GridPresetGWUSmall:
        grid_spacing = 0.254 / 18;  // meters
        grid_large_rad = 0.00423; // m
        grid_small_rad = 0.00283; // m
        grid_rows = 10; // grid dots
        grid_cols = 19; // grid dots
        grid_seed = 71;
        break;
      case GridPresetGoogleLarge:
        grid_spacing = 0.03156;  // meters
        grid_large_rad = 0.00889; // m
        grid_small_rad = 0.00635; // m
        grid_rows = 36; // grid dots
        grid_cols = 25; // grid dots
        grid_seed = 71;
        break;
    }

    grid_spacing = cl.follow(grid_spacing,"-grid-spacing");
    grid_seed = cl.follow((int)grid_seed,"-grid-seed");
    grid_cols = cl.follow((int)grid_cols,"-grid-cols");
    grid_rows = cl.follow((int)grid_rows,"-grid-rows");
    grid_large_rad = cl.follow(grid_large_rad,"-grid-large-rad");
    grid_small_rad = cl.follow(grid_small_rad,"-grid-small-rad");
    fix_intrinsics = cl.search(2, "-fix-intrinsics", "-f");
    start_paused = cl.search(2, "-paused", "-p");
    output_filename = cl.follow(output_filename.c_str(), 2, "-output", "-o");
    save_grid = cl.follow("", "-save-grid");
    const Eigen::Vector2i grid_size(grid_cols, grid_rows);

    ////////////////////////////////////////////////////////////////////
    // Setup Grid pattern

    ConicFinder conic_finder;
    conic_finder.Params().conic_min_area = 4.0;
    conic_finder.Params().conic_min_density = 0.6;
    conic_finder.Params().conic_min_aspect = 0.2;

    std::unique_ptr<TargetGridDot> target;
    if(grid_preset == GridPresetGoogleLarge)
        target.reset(new TargetGridDot(grid_spacing, GoogleLargeGrid()));
    else if(grid_preset == GridPresetGWUSmall)
        target.reset(new TargetGridDot(grid_spacing, GWUSmallGrid()));
    else
        target.reset(new TargetGridDot(grid_spacing, grid_size, grid_seed));

    // Save grid and exit if required
    if(!save_grid.empty()) {
        saveGrid(*target, save_grid, grid_large_rad, grid_small_rad);
        return 0;
    }

    ////////////////////////////////////////////////////////////////////
    // Setup Video Source

    // Last argument or parameter - Video URI
    std::string cam_param = cl.follow("", 2, "-video_url", "-cam");
    std::string uri = cam_param.empty() ? argv[argc-1] : cam_param;

    hal::Camera  cam;
    try {
      cam = hal::Camera( uri );
    } catch (...) {
        if(!cam_param.empty())
          std::cerr << "Could not create camera from URI: " << uri
                    << std::endl;
        return -1;
    }
    if(cam.Empty()) return -1;

    // For the moment, assume all N cameras have same resolution
    const size_t N = cam.NumChannels();
    const size_t w = cam.Width();
    const size_t h = cam.Height();

    std::shared_ptr<pb::ImageArray> imageArray = pb::ImageArray::Create();
    cam.Capture(*imageArray);

    std::vector<cv::Mat> vImages;
    std::vector<uint64_t> vSerialNos;
    vImages.reserve(imageArray->Size());
    vSerialNos.reserve(imageArray->Size());
    for( int i = 0; i < imageArray->Size(); ++i ){
        pb::Image& image = *(*imageArray)[i];
        cv::Mat im = image.Mat();
        if( im.type() != CV_8UC1 ){
           std::cerr << "Input channels must be GRAY8 format. Use "
               "Convert:[fmt=MONO8]// video scheme." << std::endl;
        } else {
            vImages.emplace_back(im);
            vSerialNos.emplace_back(image.SerialNumber());
        }
    }

    // Load camera hints from command line
    cl.disable_loop();
    cl.reset_cursor();
    for(std::string filename = cl.follow("",2,"-cameras","-c");
        !filename.empty(); filename = cl.follow("",2,"-cameras","-c") ) {
        const size_t i = input_cameras.size();
        if(i < N) {
            if(filename == "fov") {
                CameraModelT<Fov> starting_cam(w, h);
                starting_cam.Params()  << 300, 300, w/2.0, h/2.0, 0.2;
                input_cameras.push_back( CameraAndPose(CameraModel(starting_cam), Sophus::SE3d() ) );
            }else if(filename == "poly2") {
                CameraModelT<Poly2> starting_cam(w, h);
                starting_cam.Params()  << 300, 300, w/2.0, h/2.0, 0.0, 0.0;
                input_cameras.push_back( CameraAndPose(CameraModel(starting_cam), Sophus::SE3d() ) );
            }else if(filename == "poly3" || filename =="poly") {
                CameraModelT<Poly3> starting_cam(w, h);
                starting_cam.Params()  << 300, 300, w/2.0, h/2.0, 0.0, 0.0, 0.0;
                input_cameras.push_back( CameraAndPose(CameraModel(starting_cam), Sophus::SE3d() ) );
            }else if(filename == "kb4") {
                CameraModelT<ProjectionKannalaBrandt> starting_cam(w, h);
                starting_cam.Params()  << 300, 300, w/2.0, h/2.0, 0.0, 0.0, 0.0, 0.0;
                input_cameras.push_back( CameraAndPose(CameraModel(starting_cam), Sophus::SE3d() ) );
            }else{
                const CameraRig rig = ReadXmlRig(filename);
                for(const CameraModelAndTransform& cop : rig.cameras ) {
                    input_cameras.push_back( CameraAndPose(cop.camera, cop.T_wc.inverse()) );
                }
            }
        }else{
            throw std::runtime_error("Too many camera files provided.");
        }
    }


    if(input_cameras.size() > 0 && input_cameras.size() != N) {
        std::cerr << "Number of cameras specified in files does not match video source" << std::endl;
        return -1;
    }

    ////////////////////////////////////////////////////////////////////
    // Setup image processing pipeline

    ImageProcessing image_processing(w,h);
    image_processing.Params().black_on_white = true;
    image_processing.Params().at_threshold = 0.9;
    image_processing.Params().at_window_ratio = 30.0;

    CVarUtils::AttachCVar("proc.adaptive.threshold", &image_processing.Params().at_threshold);
    CVarUtils::AttachCVar("proc.adaptive.window_ratio", &image_processing.Params().at_window_ratio);
    CVarUtils::AttachCVar("proc.black_on_white", &image_processing.Params().black_on_white);

    ////////////////////////////////////////////////////////////////////
    // Initialize Calibration object and tracking params

    Calibrator calibrator;
    calibrator.FixCameraIntrinsics(fix_intrinsics);

    int calib_cams[N];
    bool tracking_good[N];
    std::vector<Sophus::SE3d> T_hw;
    T_hw.resize(N);

    for(size_t i=0; i<N; ++i) {
        const int w_i = cam.Width();
        const int h_i = cam.Height();
        if(i < input_cameras.size() ) {
            input_cameras[i].camera.SetSerialNumber(vSerialNos[i]);
            calib_cams[i] = calibrator.AddCamera(
                        input_cameras[i].camera, input_cameras[i].T_ck
                        );
        }else{
            // Generic starting set of parameters.
            CameraModelT<Fov> starting_cam(w_i, h_i);
            starting_cam.Params()  << 300, 300, w_i/2.0, h_i/2.0, 0.2;
            starting_cam.SetSerialNumber(vSerialNos[i]);

            calib_cams[i] = calibrator.AddCamera(
                        CameraModel(starting_cam),
                        Sophus::SE3d()
                        );
        }
    }

    ////////////////////////////////////////////////////////////////////
    // Setup GUI

    const int PANEL_WIDTH = 150;
    pangolin::CreateWindowAndBind("Main",(N+1)*w/2.0+PANEL_WIDTH,h/2.0);

    // Make things look prettier...
    glEnable(GL_LINE_SMOOTH);
    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
    glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
    glEnable (GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDepthFunc( GL_LEQUAL );
    glEnable( GL_DEPTH_TEST );
    glLineWidth(1.7);

    // Pangolin 3D Render state
    pangolin::OpenGlRenderState stacks;
    stacks.SetProjectionMatrix(pangolin::ProjectionMatrixRDF_TopLeft(640,480,420,420,320,240,0.01,1E6));
    stacks.SetModelViewMatrix(pangolin::ModelViewLookAtRDF(0,0,-0.5, 0,0,0, 0, -1, 0) );

    // Create viewport for video with fixed aspect
    pangolin::CreatePanel("ui").SetBounds(1.0,0.0,0,pangolin::Attach::Pix(PANEL_WIDTH));

    pangolin::View& container = pangolin::CreateDisplay()
            .SetBounds(1.0,0.0, pangolin::Attach::Pix(PANEL_WIDTH),1.0)
            .SetLayout(pangolin::LayoutEqual);

    // Add view for each camera stream
    for(size_t c=0; c < N; ++c) {
        container.AddDisplay( pangolin::CreateDisplay().SetAspect(w/(float)h) );
    }

    // Add 3d view, attach input handler
    pangolin::Handler3D handler(stacks);
    pangolin::View& v3D = pangolin::CreateDisplay().SetAspect((float)w/h).SetHandler(&handler);
    container.AddDisplay(v3D);

    // OpenGl Texture for video frame
    pangolin::GlTexture tex(w,h,GL_LUMINANCE8);

    ////////////////////////////////////////////////////////////////////
    // Display Variables

    pangolin::Var<bool> run("ui.Play video", !start_paused, true);

    pangolin::Var<double> disp_mse("ui.MSE");
    pangolin::Var<int> disp_frame("ui.frame");

    pangolin::Var<bool> add("ui.Add Frames", true, true);

    pangolin::Var<bool> disp_thresh("ui.Display Thresh",false);
    pangolin::Var<bool> disp_lines("ui.Display Lines",true);
    pangolin::Var<bool> disp_cross("ui.Display crosses",true);
    pangolin::Var<bool> disp_bbox("ui.Display bbox",true);

    ////////////////////////////////////////////////////////////////////
    // Key shortcuts

    // 1,2,3,... keys hide and show viewports
    for(size_t i=0; i<container.NumChildren(); ++i) {
        pangolin::RegisterKeyPressCallback('1'+i, [&container,i](){container[i].ToggleShow();} );
    }

    pangolin::RegisterKeyPressCallback('[', [&](){calibrator.Start();} );
    pangolin::RegisterKeyPressCallback(']', [&](){calibrator.Stop();} );

    bool step = false;
    pangolin::RegisterKeyPressCallback(pangolin::PANGO_SPECIAL+ pangolin::PANGO_KEY_RIGHT, [&](){step = true;} );
    pangolin::RegisterKeyPressCallback(' ', [&](){run = !run;} );

    pangolin::RegisterKeyPressCallback('r', [&](){calibrator.PrintResults();} );
    pangolin::RegisterKeyPressCallback('q', &pangolin::Quit);

    ////////////////////////////////////////////////////////////////////
    // Main event loop

    for(int frame=0; !pangolin::ShouldQuit();){
        const bool go = (frame==0) || run || pangolin::Pushed(step);

        int calib_frame = -1;

        if( go ) {
            if( cam.Capture( vImages ) ){
                if(add) {
                    calib_frame = calibrator.AddFrame(Sophus::SE3d(Sophus::SO3d(), Eigen::Vector3d(0,0,1000)) );
                }
                ++frame;
            }else{
                run = false;
            }
        }

        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

        for(size_t iI = 0; iI < N; ++iI)
        {
            if (vImages.size() != N) break;

            image_processing.Process( vImages[iI].data, vImages[iI].cols, vImages[iI].rows, vImages[iI].cols );
            conic_finder.Find( image_processing );

            const std::vector<Conic, Eigen::aligned_allocator<Conic> >& conics =
                conic_finder.Conics();
            std::vector<int> ellipse_target_map;

            tracking_good[iI] = target->FindTarget(
                        image_processing, conic_finder.Conics(),
                        ellipse_target_map
                        );

            if(tracking_good[iI]) {
                // Generate map and point structures
              std::vector<Eigen::Vector2d,
                          Eigen::aligned_allocator<Eigen::Vector2d> > ellipses;
                for( size_t i=0; i < conics.size(); ++i ) {
                    ellipses.push_back(conics[i].center);
                }

                // find camera pose given intrinsics
                PosePnPRansac(
                    calibrator.GetCamera(iI).camera, ellipses, target->Circles3D(),
                    ellipse_target_map,
                    0, 0, &T_hw[iI]
                );

                if(calib_frame >= 0) {
                    if(iI==0 || !tracking_good[0]) {
                        // Initialize pose of frame for least squares optimisation
                        calibrator.GetFrame(calib_frame) = T_hw[iI];
                    }

                    for(size_t p=0; p < ellipses.size(); ++p) {
                        const Eigen::Vector2d pc = ellipses[p];
                        const Eigen::Vector2i pg = target->Map()[p].pg;

                        if( 0<= pg(0) && pg(0) < grid_size(0) &&  0<= pg(1) && pg(1) < grid_size(1) )
                        {
                            const Eigen::Vector3d pg3d = grid_spacing * Eigen::Vector3d(pg(0), pg(1), 0);
                            // TODO: Add these correspondences in bulk to avoid
                            //       hitting mutex each time.
                            calibrator.AddObservation(calib_frame, calib_cams[iI], pg3d, pc );
                        }
                    }
                }
            }

            if(container[iI].IsShown()) {
                container[iI].ActivateScissorAndClear();
                glColor3f(1,1,1);

                // Display camera image
                if(!disp_thresh) {
                    tex.Upload(image_processing.Img(),GL_LUMINANCE,GL_UNSIGNED_BYTE);
                    tex.RenderToViewportFlipY();
                }else{
                    tex.Upload(image_processing.ImgThresh(),GL_LUMINANCE,GL_UNSIGNED_BYTE);
                    tex.RenderToViewportFlipY();
                }

                // Setup orthographic pixel drawing
                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                glOrtho(-0.5,w-0.5,h-0.5,-0.5,0,1.0);
                glMatrixMode(GL_MODELVIEW);

                if(disp_lines) {
                    for(std::list<LineGroup>::const_iterator i = target->LineGroups().begin(); i != target->LineGroups().end(); ++i)
                    {
                        glColor3f(0.5,0.5,0.5);
                        glBegin(GL_LINE_STRIP);
                        for(std::list<size_t>::const_iterator el = i->ops.begin(); el != i->ops.end(); ++el)
                        {
                            const Eigen::Vector2d p = conics[*el].center;
                            glVertex2d(p(0), p(1));
                        }
                        glEnd();
                    }
                }

                if(disp_cross) {
                    for( size_t i=0; i < conics.size(); ++i ) {
                        const Eigen::Vector2d pc = conics[i].center;
                        pangolin::glColorBin( target->Map()[i].value, 2);
                        pangolin::glDrawCross(pc, conics[i].bbox.Width()*0.75 );
                    }
                }

                if(disp_bbox) {
                    for( size_t i=0; i < conics.size(); ++i ) {
                        const Eigen::Vector2i pg = tracking_good[iI] ? target->Map()[i].pg : Eigen::Vector2i(0,0);
                        if( 0<= pg(0) && pg(0) < grid_size(0) &&  0<= pg(1) && pg(1) < grid_size(1) ) {
                            pangolin::glColorBin(pg(1)*grid_size(0)+pg(0), grid_size(0)*grid_size(1));
                            glDrawRectPerimeter(conics[i].bbox);
                        }
                    }
                }
            }
        }

        if(v3D.IsShown()) {
            v3D.ActivateScissorAndClear(stacks);

            calibu::glDrawTarget(*target, Eigen::Vector2d(0,0), 1.0, 0.8, 1.0);

            for(size_t c=0; c< calibrator.NumCameras(); ++c) {
                const Eigen::Matrix3d Kinv = calibrator.GetCamera(c).camera.Kinv();

                const CameraAndPose cap = calibrator.GetCamera(c);
                const Sophus::SE3d T_ck = cap.T_ck;

                // Draw keyframes
                pangolin::glColorBin(c, 2, 0.2);
                for(size_t k=0; k< calibrator.NumFrames(); ++k) {
                    pangolin::glDrawAxis((T_ck * calibrator.GetFrame(k)).inverse().matrix(), 0.01);
                }

                // Draw current camera
                if(tracking_good[c]) {
                    pangolin::glColorBin(c, 2, 0.5);
                    pangolin::glDrawFrustrum(Kinv,w,h,T_hw[c].inverse().matrix(),0.05);
                }
            }
        }

        disp_mse = calibrator.MeanSquareError();
        disp_frame = frame;

        // Process window events via GLUT
        pangolin::FinishFrame();
    }

    calibrator.Stop();
    calibrator.PrintResults();
    calibrator.WriteCameraModels(output_filename);

}
Exemplo n.º 12
0
bool CalibrationArea::on_expose_event(GdkEventExpose *event)
{
    // check that screensize did not change
    if (display_width != get_width() ||
         display_height != get_height()) {
        set_display_size(get_width(), get_height());
    }

    Glib::RefPtr<Gdk::Window> window = get_window();
    if (window) {
        Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
        cr->save();

        cr->rectangle(event->area.x, event->area.y, event->area.width, event->area.height);
        cr->clip();

        // Print the text
        cr->set_font_size(font_size);
        double text_height = -1;
        double text_width = -1;
        Cairo::TextExtents extent;
        for (int i = 0; i != help_lines; i++) {
            cr->get_text_extents(help_text[i], extent);
            text_width = std::max(text_width, extent.width);
            text_height = std::max(text_height, extent.height);
        }
        text_height += 2;

        double x = (display_width - text_width) / 2;
        double y = (display_height - text_height) / 2 - 60;
        cr->set_line_width(2);
        cr->rectangle(x - 10, y - (help_lines*text_height) - 10,
                text_width + 20, (help_lines*text_height) + 20);

        // Print help lines
        y -= 3;
        for (int i = help_lines-1; i != -1; i--) {
            cr->get_text_extents(help_text[i], extent);
            cr->move_to(x + (text_width-extent.width)/2, y);
            cr->show_text(help_text[i]);
            y -= text_height;
        }
        cr->stroke();

        // Draw the points
        for (int i = 0; i <= calibrator->get_numclicks(); i++) {
            // set color: already clicked or not
            if (i < calibrator->get_numclicks())
                cr->set_source_rgb(1.0, 1.0, 1.0);
            else
                cr->set_source_rgb(0.8, 0.0, 0.0);

            cr->set_line_width(1);
            cr->move_to(X[i] - cross_lines, Y[i]);
            cr->rel_line_to(cross_lines*2, 0);
            cr->move_to(X[i], Y[i] - cross_lines);
            cr->rel_line_to(0, cross_lines*2);
            cr->stroke();

            cr->arc(X[i], Y[i], cross_circle, 0.0, 2.0 * M_PI);
            cr->stroke();
        }

        // Draw the clock background
        cr->arc(display_width/2, display_height/2, clock_radius/2, 0.0, 2.0 * M_PI);
        cr->set_source_rgb(0.5, 0.5, 0.5);
        cr->fill_preserve();
        cr->stroke();

        cr->set_line_width(clock_line_width);
        cr->arc(display_width/2, display_height/2, (clock_radius - clock_line_width)/2,
             3/2.0*M_PI, (3/2.0*M_PI) + ((double)time_elapsed/(double)max_time) * 2*M_PI);
        cr->set_source_rgb(0.0, 0.0, 0.0);
        cr->stroke();


        // Draw the message (if any)
        if (message != NULL) {
            // Frame the message
            cr->set_font_size(font_size);
            Cairo::TextExtents extent;
            cr->get_text_extents(this->message, extent);
            text_width = extent.width;
            text_height = extent.height;

            x = (display_width - text_width) / 2;
            y = (display_height - text_height + clock_radius) / 2 + 60;
            cr->set_line_width(2);
            cr->rectangle(x - 10, y - text_height - 10,
                    text_width + 20, text_height + 25);

            // Print the message
            cr->move_to(x, y);
            cr->show_text(this->message);
            cr->stroke();
        }

        cr->restore();
    }

    return true;
}
Exemplo n.º 13
0
void CalibratorLogImpl::outputState()
{
    osOutput_ << "\nCalibrator iterations completed: " << calibrator_->iterationCount() << endl << endl;

    const CalibrationParameters& p = calibrator_->parameters();
    osOutput_ << "A: " << p.A << endl;
    osOutput_ << "B: " << p.B << endl << endl;

    osOutput_ <<
              setw(columnWidth_) <<  "mass_true" <<
              setw(3) <<  "z" <<
              setw(columnWidth_) << "f_obs" <<
              setw(columnWidth_) << "mass_calc" <<
              setw(columnWidth_) << "error (ppm)" <<
              setw(3) << "id" <<
              "  distribution" << endl;

    double totalSquaredMassError = 0;
    double totalSquaredCalibrationError = 0;
    int totalCorrect = 0;
    int totalConfident = 0;

    int N = calibrator_->measurementCount();
    for (int i=0; i<N; i++)
    {
        // calculations

        double f = calibrator_->measurement(i)->frequency;
        int z = calibrator_->measurement(i)->charge;
        double mz = p.mz(f);
        double massCalculated = Ion::neutralMass(mz, z);

        double massTrue = 0;
        double error = 0;
        bool correct = false;
        bool confident = false;

        if (trueMasses_)
        {
            // error calculations
            massTrue = trueMasses_->at(i);
            error = (massCalculated - massTrue)/massTrue;
            totalSquaredMassError += error*error;

            if (trueParameters_)
            {
                double term1 = fabs(p.A - trueParameters_->A)/f;
                double term2 = fabs(p.B - trueParameters_->B)/(f*f);
                double deviation = (term1 + term2)/massTrue;
                totalSquaredCalibrationError += deviation*deviation;
            }

            // id verification
            if (calibrator_->massSpread(i) && !calibrator_->massSpread(i)->distribution().empty())
            {
                const MassSpread::Pair& id = calibrator_->massSpread(i)->distribution()[0];
                if (fabs(id.mass-massTrue) < 1e-8)
                {
                    correct = true;
                    totalCorrect++;
                    if (id.probability > .95)
                    {
                        confident = true;
                        totalConfident++;
                    }
                }
            }
        }

        // output

        osOutput_ <<
                  setw(columnWidth_) << massTrue <<
                  setw(3) << z <<
                  setw(columnWidth_) << f <<
                  setw(columnWidth_) << massCalculated <<
                  setw(columnWidth_) << error * 1e6 <<
                  setw(2) << (correct ? "*" : " ") <<
                  (confident ? "!" : " ") << "  ";

        if (calibrator_->massSpread(i))
            calibrator_->massSpread(i)->output(osOutput_);
        osOutput_ << endl;
    }

    double rmsMassError = sqrt(totalSquaredMassError / N);
    double rmsCalibrationError = sqrt(totalSquaredCalibrationError / N);

    osOutput_ << "\nTotal error: " << calibrator_->error() * 1e6 << " ppm\n\n";

    // update summary
    osSummary_ << calibrator_->iterationCount() << " " <<
               p.A << " " <<
               p.B << " " <<
               rmsMassError * 1e6 << " " <<
               calibrator_->error() * 1e6 << " " <<
               rmsCalibrationError * 1e6 << " " <<
               (double)totalCorrect/N << " " <<
               (double)totalConfident/N << endl;
}
Exemplo n.º 14
0
Calibrator* Calibrator::make_calibrator(int argc, char** argv)
{
    Calibrator *calibrator;
    bool list_devices = false;
    bool fake = false;
    bool precalib = false;
    bool reset = false;
    XYinfo pre_axys;
    const char* pre_device = NULL;
    const char* geometry = NULL;
    unsigned thr_misclick = 15;
    unsigned thr_doubleclick = 7;
    OutputType output_type = OUTYPE_AUTO;

    // parse input
    if (argc > 1) {
        for (int i=1; i!=argc; i++) {
            // Display help ?
            if (strcmp("-h", argv[i]) == 0 ||
                strcmp("--help", argv[i]) == 0) {
                fprintf(stderr, "xinput_calibrator, v%s\n\n", VERSION);
                usage(argv[0], thr_misclick);
                exit(0);
            } else

            // Verbose output ?
            if (strcmp("-v", argv[i]) == 0 ||
                strcmp("--verbose", argv[i]) == 0) {
                verbose = true;
            } else

            // Just list devices ?
            if (strcmp("--list", argv[i]) == 0) {
                list_devices = true;
            } else

            // Select specific device ?
            if (strcmp("--device", argv[i]) == 0) {
                if (argc > i+1)
                    pre_device = argv[++i];
                else {
                    fprintf(stderr, "Error: --device needs a device name or id as argument; use --list to list the calibratable input devices.\n\n");
                    usage(argv[0], thr_misclick);
                    exit(1);
                }
            } else

            // Get pre-calibration ?
            if (strcmp("--precalib", argv[i]) == 0) {
                precalib = true;
                if (argc > i+1)
                    pre_axys.x.min = atoi(argv[++i]);
                if (argc > i+1)
                    pre_axys.x.max = atoi(argv[++i]);
                if (argc > i+1)
                    pre_axys.y.min = atoi(argv[++i]);
                if (argc > i+1)
                    pre_axys.y.max = atoi(argv[++i]);
            } else

            // Get pre-calibration ?
            if (strcmp("--reset", argv[i]) == 0) {
                reset = true;
            } else

            // Get mis-click threshold ?
            if (strcmp("--misclick", argv[i]) == 0) {
                if (argc > i+1)
                    thr_misclick = atoi(argv[++i]);
                else {
                    fprintf(stderr, "Error: --misclick needs a number (the pixel threshold) as argument. Set to 0 to disable mis-click detection.\n\n");
                    usage(argv[0], thr_misclick);
                    exit(1);
                }
            } else

            // Get output type ?
            if (strcmp("--output-type", argv[i]) == 0) {
                if (argc > i+1) {
                    i++; // eat it or exit
                    if (strcmp("auto", argv[i]) == 0)
                        output_type = OUTYPE_AUTO;
                    else if (strcmp("xorg.conf.d", argv[i]) == 0)
                        output_type = OUTYPE_XORGCONFD;
                    else if (strcmp("hal", argv[i]) == 0)
                        output_type = OUTYPE_HAL;
                    else if (strcmp("xinput", argv[i]) == 0)
                        output_type = OUTYPE_XINPUT;
                    else {
                        fprintf(stderr, "Error: --output-type needs one of auto|xorg.conf.d|hal|xinput.\n\n");
                        usage(argv[0], thr_misclick);
                        exit(1);
                    }
                } else {
                    fprintf(stderr, "Error: --output-type needs one argument.\n\n");
                    usage(argv[0], thr_misclick);
                    exit(1);
                }
            } else

            // specify window geometry?
            if (strcmp("--geometry", argv[i]) == 0) {
                geometry = argv[++i];
            } else

            // Fake calibratable device ?
            if (strcmp("--fake", argv[i]) == 0) {
                fake = true;
            }

            // unknown option
            else {
                fprintf(stderr, "Unknown option: %s\n\n", argv[i]);
                usage(argv[0], thr_misclick);
                exit(0);
            }
        }
    }


    /// Choose the device to calibrate
    XID         device_id   = (XID) -1;
    const char* device_name = NULL;
    XYinfo      device_axys;
    if (fake) {
        // Fake a calibratable device
        device_name = "Fake_device";
        device_axys = XYinfo(0,1000,0,1000);

        if (verbose) {
            printf("DEBUG: Faking device: %s\n", device_name);
        }
    } else {
        // Find the right device
        int nr_found = find_device(pre_device, list_devices, device_id, device_name, device_axys);

        if (list_devices) {
            // printed the list in find_device
            if (nr_found == 0)
                printf("No calibratable devices found.\n");
            exit(2);
        }

        if (nr_found == 0) {
            if (pre_device == NULL)
                fprintf (stderr, "Error: No calibratable devices found.\n");
            else
                fprintf (stderr, "Error: Device \"%s\" not found; use --list to list the calibratable input devices.\n", pre_device);
            exit(1);

        } else if (nr_found > 1) {
            printf ("Warning: multiple calibratable devices found, calibrating last one (%s)\n\tuse --device to select another one.\n", device_name);
        }

        if (verbose) {
            printf("DEBUG: Selected device: %s\n", device_name);
        }
    }


    // Different device/driver, different ways to apply the calibration values
    try {
        // try Usbtouchscreen driver
        calibrator = new CalibratorUsbtouchscreen(device_name, device_axys,
            thr_misclick, thr_doubleclick, output_type, geometry);

    } catch(WrongCalibratorException& x) {
        if (verbose)
            printf("DEBUG: Not usbtouchscreen calibrator: %s\n", x.what());
    }

    if (calibrator == NULL) {
        try {
            // next, try Evdev driver (with XID)
            calibrator = new CalibratorEvdev(device_name, device_axys, device_id,
                thr_misclick, thr_doubleclick, output_type, geometry);
    
        } catch(WrongCalibratorException& x) {
            if (verbose)
                printf("DEBUG: Not evdev calibrator: %s\n", x.what());
        }
    }

    // lastly, presume a standard Xorg driver (evtouch, mutouch, ...)
    if (calibrator == NULL) {
        calibrator = new CalibratorXorgPrint(device_name, device_axys,
                thr_misclick, thr_doubleclick, output_type, geometry);
    }

    if (calibrator != NULL) {
        // override min/max XY from command line ?
        if (precalib) {
            if (verbose) {
                printf("DEBUG: Setting precalibration: %i, %i, %i, %i\n",
                    pre_axys.x.min, pre_axys.x.max,
                    pre_axys.y.min, pre_axys.y.max);
            }
            calibrator->set_old_axys(pre_axys);
        } else {
            calibrator->detect_axys();
        }

        if (reset) {
            if (verbose)
                printf("DEBUG: Resetting calibration parameters:\n");
            if (calibrator->apply(device_axys))
                calibrator->set_old_axys(device_axys);
            else
                fprintf(stderr, "Error: failed to reset calibration parameters.\n");
        }
    }

    return calibrator;
}
//int _tmain(int argc, _TCHAR* argv[])
uint main(uint argc, cstr argv[])
{
	printf("Random number from 0 to 1 == %lf\n", LRandomFromTo(0., 1.));
	LString typeOfCalc;
	Calibrator *pC = getCalibrator();
	Voltmeter *pV = getVoltmeter(Voltmeter::REFERENCE);
	Voltmeter *pVver = getVoltmeter(Voltmeter::VERIFIED);
	double Umax = 0., U = 0., step = 0., E1 = 0., E2 = 0., k = 0.1;
	const double minThreshold = 0.0000001;
	uint F = 0, i = 0, j = 0, ccount = 0;
	//char *command[4] = {"Umax","U","F","Eref"};
	// Umax = 0 volt U = 0 volt F = 0 Hz Eref = 0.0 volt
	// Umax=0 - обязательны параметр нужен для того, чтобы мы не установили напряжение больше порога
	// если передается параметр Eref - то устанавливаем эдс, возвращаем U
	// елси не передается параметр Eref - то устанавливаем U и возвращаем эдс
	// for example fix(equ) U=10 F=1000 Umax=20 Eref=0.508185
	typeOfCalc = argv[1];
	if (typeOfCalc == "fix") { // установить напряжение
		arg[3].seen = true;
	}
	else if (typeOfCalc == "equ") { // подобрать напряжение
		arg[3].req = true;
	}
	else if(typeOfCalc == "res") { // сбросить напряжение на 0 закрыть выход
		arg[0].req = false;
		arg[1].req = false;
		arg[2].req = false;
	}
	else if(typeOfCalc == "ref") { // вернуть эдс эталона
		arg[0].req = false;
		arg[1].req = false;
		arg[2].req = false;
	}
	else if(typeOfCalc == "ver") { // вернуть эдс тестируемого преобразователя
		arg[0].req = false;
		arg[1].req = false;
		arg[2].req = false;
	}
	else {
		fprintf(stderr, "Wrong command: %s\n", argv[1]);
		exit(1);
	}
	for (i = 2; i < argc; i++) {
		bool good = false;
		for (j = 0; j < countof(arg); j++) {
			LString res = getValue(arg[j].key, argv[i]);
			if (res == " ") continue;
			good = true;
			if (arg[j].seen) {
				fprintf(stderr, "Duplicate or prohibited: %s\n", arg[j].key);
				exit(1);
			}
			switch (j) {
			case 0:  Umax = LParseDbl(res); break;
			case 1:  U = LParseDbl(res); break;
			case 2:  F = LParseInt(res); break;
			case 3:  E1 = LParseDbl(res); break;
			}
			printf("%d=%s\n", j, (cstr)res);
			arg[j].seen = true;
		}
		if (!good) {
			fprintf(stderr, "Unexpected: %s\n", argv[i]);
			exit(1);
		}
	}
	for (j = 0; j < countof(arg); j++) {
		if (arg[j].req) if (!arg[j].seen) {
			fprintf(stderr, "Required but not seen: %s\n", arg[j].key);
			exit(1);
		}
	}
	if (Umax <= 0. && typeOfCalc != "res" && typeOfCalc != "ver" && typeOfCalc != "ref") {
		fprintf(stderr, "Invalid Umax: %lf\n", Umax);
		exit(1);
	}
	if (typeOfCalc == "fix") if (fabs(U) < EPSILON) {
		fprintf(stderr, "Invalid U: %lf\n", Umax);
		exit(1);
	}
	printf("Umax=%lf U=%lf F=%d Eref=%lf\n", Umax, U, F, E1);
	pC->setBarrier(Umax);
	if (typeOfCalc == "fix") {
		pC->setOutput(0);
		pC->setVoltage(0);
		runUpExact(U, F, pC);
		E1 = pV->getVoltage();
		printf("set voltage -> %2f V | set frequency -> %d Hz | thermo EMF -> %1f\n", U, F, E1);
		fprintf(stderr, "Eref=%f", E1);
	}
	if (typeOfCalc == "equ") {
		E2 = pV->getVoltage();
		if (E1 < E2) {
			step = U*k;
		}
		else{
			step = U*(-k);
		}
		while (fabs(step) > minThreshold) {
			if (Umax <= U) {
				fprintf(stderr, "U is greater than Umax\n");
				exit(1);
			}
			runUpExact(U, F, pC);
			E2 = pV->getVoltage();
			printf("set voltage -> %2f V | set frequency -> %d Hz | thermo EMF -> %1f\n", U, F, E2);

			U += step; // этот способ нахождения оказался быстрее всех
			if (((E1 < E2) && (step > 0)) || ((E1 > E2) && (step < 0))) {
				step *= (-k);
			}
		}
		fprintf(stderr, "Eref=%1f", pV->getVoltage());
	}
	if (typeOfCalc == "res"){
		printf("reset\n");
		pC->setOutput(0);
		pC->setVoltage(0);
	}
	if (typeOfCalc == "ref"){
		printf("pV->getVoltage=%1f\n", pV->getVoltage());
		fprintf(stderr, "Eref=%1f", pV->getVoltage());
		
	}
	if (typeOfCalc == "ver"){
		printf("pVver->getVoltage=%1f\n", pVver->getVoltage());
		fprintf(stderr, "Ever=%1f", pVver->getVoltage());
	}
	return 0;
}
Exemplo n.º 16
0
int main(int argc, char* argv[]){

  std::string pose_offset_filename = "./poseoffset";
  unsigned cv_width  = 128;
  unsigned cv_height = 128;
  unsigned cv_depth  = 128;
  float    cv_min_d  = 0.5;
  float    cv_max_d  = 3.0;
  bool undistort = false;

  unsigned idwneighbours = 10;
  bool using_nni = false;

  CMDParser p("basefilename samplesfilename checkerboardviewinitfilename");

  p.addOpt("p",1,"poseoffetfilename", "specify the filename of the poseoffset on disk, default: " + pose_offset_filename);
  p.addOpt("s",3,"size", "use this calibration volume size (width x height x depth), default: 128 128 256");
  p.addOpt("d",2,"depthrange", "use this depth range: 0.5 4.5");
p.addOpt("u", -1, "undistort", "enable undistortion of images before chessboardsampling, default: false");

  p.addOpt("n",1,"numneighbours", "the number of neighbours that should be used for IDW inverse distance weighting, default: 10");

  p.addOpt("i",-1,"nni", "do use natural neighbor interpolation if possible, default: false");

  p.init(argc,argv);

  if(p.getArgs().size() != 3)
    p.showHelp();

  if(p.isOptSet("p")){
    pose_offset_filename = p.getOptsString("p")[0];
    std::cout << "setting poseoffetfilename to " << pose_offset_filename << std::endl;
  }


  if(p.isOptSet("s")){
    cv_width = p.getOptsInt("s")[0];
    cv_height = p.getOptsInt("s")[1];
    cv_depth = p.getOptsInt("s")[2];
  }

  if(p.isOptSet("d")){
    cv_min_d = p.getOptsInt("d")[0];
    cv_max_d = p.getOptsInt("d")[1];
  }
  if(p.isOptSet("u")){
    undistort = true;
}


  if(p.isOptSet("n")){
    idwneighbours = p.getOptsInt("n")[0];
    std::cout << "setting to numneighbours " << idwneighbours << std::endl;
  }


  if(p.isOptSet("i")){
    using_nni = true;
  }



  std::string basefilename = p.getArgs()[0];
  std::string filename_xyz(basefilename + "_xyz");
  std::string filename_uv(basefilename + "_uv");
  const std::string filename_yml(basefilename + "_yml");
  std::string filename_samples(p.getArgs()[1]);


  CalibVolume cv(cv_width, cv_height, cv_depth, cv_min_d, cv_max_d);

  RGBDConfig cfg;
  cfg.read(filename_yml.c_str());

  RGBDSensor sensor(cfg);

  Checkerboard cb;
  cb.load_pose_offset(pose_offset_filename.c_str());


  ChessboardSampling cbs(p.getArgs()[2].c_str(), cfg, undistort);
  cbs.init();

  glm::mat4 eye_d_to_world = sensor.guess_eye_d_to_world_static(cbs, cb);
  std::cerr << "extrinsic of sensor is: " << eye_d_to_world << std::endl;
  std::cerr << "PLEASE note, the extrinsic guess can be improved by averaging" << std::endl;

  for(unsigned z = 0; z < cv.depth; ++z){
    for(unsigned y = 0; y < cv.height; ++y){
      for(unsigned x = 0; x < cv.width; ++x){

	const unsigned cv_index = (z * cv.width * cv.height) + (y * cv.width) + x;

	const float depth = (z + 0.5) * (cv.max_d - cv.min_d)/cv.depth + cv.min_d;
	const float xd = (x + 0.5) * sensor.config.size_d.x * 1.0/cv.width;
	const float yd = (y + 0.5) * sensor.config.size_d.y * 1.0/cv.height;

	glm::vec3 pos3D_local = sensor.calc_pos_d(xd, yd, depth);
	glm::vec2 pos2D_rgb   = sensor.calc_pos_rgb(pos3D_local);
	pos2D_rgb.x /= sensor.config.size_rgb.x;
	pos2D_rgb.y /= sensor.config.size_rgb.y;

	glm::vec4 pos3D_world = eye_d_to_world * glm::vec4(pos3D_local.x, pos3D_local.y, pos3D_local.z, 1.0);

	xyz pos3D;
	pos3D.x = pos3D_world.x;
	pos3D.y = pos3D_world.y;
	pos3D.z = pos3D_world.z;
	cv.cv_xyz[cv_index] = pos3D;

	uv posUV;
	posUV.u = pos2D_rgb.x;
	posUV.v = pos2D_rgb.y;
	cv.cv_uv[cv_index] = posUV;
      }
    }
  }


  // load samples from filename
  std::vector<samplePoint> sps;

  std::ifstream iff(filename_samples.c_str(), std::ifstream::binary);
  const unsigned num_samples_in_file = calcNumFrames(iff,
						     sizeof(float) +
						     sizeof(uv) +
						     sizeof(uv) +
						     sizeof(xyz) +
						     sizeof(uv) +
						     sizeof(glm::vec3) +
						     sizeof(float));
  for(unsigned i = 0; i < num_samples_in_file; ++i){
    samplePoint s;
    iff.read((char*) &s.depth, sizeof(float));
    iff.read((char*) &s.tex_color, sizeof(uv));
    iff.read((char*) &s.tex_depth, sizeof(uv));
    iff.read((char*) &s.pos_offset, sizeof(xyz));
    iff.read((char*) &s.tex_offset, sizeof(uv));
    iff.read((char*) glm::value_ptr(s.pos_real), sizeof(glm::vec3));
    iff.read((char*) &s.quality, sizeof(float));
    sps.push_back(s);
  }
  iff.close();  


  // reapply correction offsets
  for(unsigned i = 0; i < sps.size(); ++i){
    const unsigned cv_width = cv.width;
    const unsigned cv_height = cv.height;
    const unsigned cv_depth = cv.depth;

    const float x = cv_width  *  ( sps[i].tex_depth.u) / cfg.size_d.x;
    const float y = cv_height *  ( sps[i].tex_depth.v)/ cfg.size_d.y;
    const float z = cv_depth  *  ( sps[i].depth - cv.min_d)/(cv.max_d - cv.min_d);

    xyz pos = getTrilinear(cv.cv_xyz, cv_width, cv_height, cv_depth, x , y , z );
    uv  tex = getTrilinear(cv.cv_uv,  cv_width, cv_height, cv_depth, x , y , z );


    sps[i].pos_offset.x = sps[i].pos_real[0] - pos.x;
    sps[i].pos_offset.y = sps[i].pos_real[1] - pos.y;
    sps[i].pos_offset.z = sps[i].pos_real[2] - pos.z;
      
    sps[i].tex_offset.u = sps[i].tex_color.u/cfg.size_rgb.x - tex.u;
    sps[i].tex_offset.v = sps[i].tex_color.v/cfg.size_rgb.y - tex.v;

    sps[i].quality = 1.0f;
      
  }


  
  Calibrator   c;
  c.using_nni = using_nni;
  c.applySamples(&cv, sps, cfg, idwneighbours, basefilename.c_str());
  cv.save(filename_xyz.c_str(), filename_uv.c_str());


  return 0;
}