void PointerMapper::compute(HandResolver& hand_resolver, Reprojector& reprojector)
{
	active = false;

	if (calibrated)
	{
		float dist_max = value_store.get_float("dist_max", 0);
		float dist = get_distance(pt_palm, pt_index);
		float ratio = dist / dist_max;

		// COUT << ratio << endl;
	}
	else
	{
		float dist_max = value_store.get_float("dist_max", 0);
		float dist = get_distance(pt_palm, pt_index);
		if (dist > dist_max)
			dist_max = dist;
		
		value_store.set_float("dist_max", dist_max);
	}

	pt_palm = reprojector.reproject_to_3d(hand_resolver.pt_precise_palm0.x, hand_resolver.pt_precise_palm0.y,
										  hand_resolver.pt_precise_palm1.x, hand_resolver.pt_precise_palm1.y);

	compute_cursor_point(index_down, hand_resolver.pt_precise_index0, hand_resolver.pt_precise_index1,
						 pt_index, reprojector, pt_cursor_index, dist_cursor_index_plane, actuate_dist, "compute_index");

	compute_cursor_point(thumb_down, hand_resolver.pt_precise_thumb0, hand_resolver.pt_precise_thumb1,
						 pt_thumb, reprojector, pt_cursor_thumb, dist_cursor_thumb_plane, actuate_dist + 10, "compute_thumb");

	if (pt_cursor_index.y > 1500)
	{
		pose_name = "";
		index_down = false;
	}

	if (calibrated)
	{
		if (!index_down)
			thumb_down = false;

		compute_pinch_to_zoom(hand_resolver);
	}
}
Exemplo n.º 2
0
bool compute()
{
    bool waiting_for_image_set = false;
    updated = false;
    ++frame_count;

    if (image_current_frame.cols == 0)
    {
        console_log("bad frame");
        return false;
    }

    Mat image_flipped;
    flip(image_current_frame, image_flipped, 0);

    Mat image0 = image_flipped(Rect(0, 0, 640, 480));
    Mat image1 = image_flipped(Rect(640, 0, 640, 480));

    if (frame_count == 1)
        setup_on_first_frame();

    if (!play || settings.touch_control != "1")
    {
        if (enable_imshow)
            waitKey(1);

        return false;
    }

    int x_accel;
    int y_accel;
    int z_accel;
    camera->getAccelerometerValues(&x_accel, &y_accel, &z_accel);
    imu.compute(x_accel, y_accel, z_accel);

    //----------------------------------------core algorithm----------------------------------------

    Mat image_small0;
    Mat image_small1;
    resize(image0, image_small0, Size(160, 120), 0, 0, INTER_LINEAR);
    resize(image1, image_small1, Size(160, 120), 0, 0, INTER_LINEAR);

    Mat image_preprocessed0;
    Mat image_preprocessed1;

    static bool exposure_set = false;

    bool normalized = compute_channel_diff_image(image_small0, image_preprocessed0, exposure_set, "image_preprocessed0", true, exposure_set);
                      compute_channel_diff_image(image_small1, image_preprocessed1, exposure_set, "image_preprocessed1");

    GaussianBlur(image_preprocessed0, image_preprocessed0, Size(3, 9), 0, 0);
    GaussianBlur(image_preprocessed1, image_preprocessed1, Size(3, 9), 0, 0);

    if (!CameraInitializerNew::adjust_exposure(camera, image_preprocessed0))
    {
        static int step_count = 0;
        if (step_count == 3)
            surface_computer.init(image0);

        ++step_count;
        return false;
    }

    exposure_set = true;

#if 0
    {
        Mat image_remapped0 = reprojector.remap(&image_small0, 0, true);
        Mat image_remapped1 = reprojector.remap(&image_small1, 1, true);

        reprojector.y_align(image_remapped0, image_remapped1, false);

        GaussianBlur(image_remapped0, image_remapped0, Size(9, 9), 0, 0);
        GaussianBlur(image_remapped1, image_remapped1, Size(9, 9), 0, 0);


        Mat image_disparity;

        static StereoSGBM stereo_sgbm(0, 32, 21, 0, 0, 0, 0, 20, 0, 0, false);
        stereo_sgbm(image_remapped0, image_remapped1, image_disparity);

        Mat image_disparity_8u;
        double minVal, maxVal;
        minMaxLoc(image_disparity, &minVal, &maxVal);
        image_disparity.convertTo(image_disparity_8u, CV_8UC1, 255 / (maxVal - minVal));

        imshow("image_remapped0", image_remapped0);
        imshow("image_remapped1", image_remapped1);
        imshow("image_disparity_8u", image_disparity_8u);
    }
#endif

    /*static bool show_wiggle_sent = false;
    if (!show_wiggle_sent)
    {
        if (child_module_name != "")
          ipc->open_udp_channel(child_module_name);
        
        ipc->send_message("menu_plus", "show window", "");
        ipc->send_message("menu_plus", "show wiggle", "");//todo
    }
    show_wiggle_sent = true;*/

    if (enable_imshow)
    {
        imshow("image_small1", image_small1);
        // imshow("image_preprocessed1", image_preprocessed1);

        // setMouseCallback("image_preprocessed1", left_mouse_cb, NULL);
        // waitKey(1);
        // return false;
    }

    algo_name_vec_old = algo_name_vec;
    algo_name_vec.clear();

    static bool motion_processor_proceed = false;
    static bool construct_background = false;
    static bool first_pass = true;

    bool proceed0;
    bool proceed1;

    if (normalized)
    {
        proceed0 = motion_processor0.compute(image_preprocessed0,  image_small0, surface_computer.y_reflection, imu.pitch,
                                             construct_background, "0",          true);
        proceed1 = motion_processor1.compute(image_preprocessed1,  image_small1, surface_computer.y_reflection, imu.pitch,
                                             construct_background, "1",          false);
    }

    if (first_pass && motion_processor0.both_moving && motion_processor1.both_moving)
    {
        console_log("readjusting exposure");

        first_pass = false;
        exposure_set = false;
        mat_functions_low_pass_filter.reset();

        CameraInitializerNew::adjust_exposure(camera, image_preprocessed0, true);
    }
    else if (!first_pass)
        construct_background = true;

    if (!construct_background)
    {
        proceed0 = false;
        proceed1 = false;            
    }

    if (proceed0 && proceed1)
        motion_processor_proceed = true;

    bool proceed = motion_processor_proceed;

    static bool menu_plus_signal0 = false;
    if (!menu_plus_signal0)
    {
        menu_plus_signal0 = true;
        // ipc->send_message("menu_plus", "hide window", "");
    }

    if (proceed)
    {
        proceed0 = foreground_extractor0.compute(image_preprocessed0, motion_processor0, "0", true);
        proceed1 = foreground_extractor1.compute(image_preprocessed1, motion_processor1, "1", false);
        proceed = proceed0 && proceed1;
    }

    if (proceed)
    {
        proceed0 = hand_splitter0.compute(foreground_extractor0, motion_processor0, "0", false);
        proceed1 = hand_splitter1.compute(foreground_extractor1, motion_processor1, "1", false);
        proceed = proceed0 && proceed1;
    }

    if (proceed)
    {
        waiting_for_image = true;
        waiting_for_image_set = true;

        proceed1 = scopa1.compute_mono0(hand_splitter1, pose_estimator, "1", false);
        proceed0 = scopa0.compute_mono0(hand_splitter0, pose_estimator, "0", false);
        proceed = proceed0 && proceed1;
    }

    if (proceed)
    {
        motion_processor0.target_frame = 10;
        motion_processor1.target_frame = 10;

        SCOPA::compute_stereo();
        scopa1.compute_mono1("1");
        scopa0.compute_mono1("0");
    }

    if (enable_imshow)
        waitKey(1);

    return waiting_for_image_set;
}
Exemplo n.º 3
0
void setup_on_first_frame()
{
    console_log("on first frame");

    ipc->send_message("menu_plus", "set status", "verifying serial number");
    serial_number = camera->getSerialNumber();

    if (serial_number.size() == 10)
    {
        string char_string = "";
        int char_count = 0;
        for (char& c : serial_number)
        {
            char_string += c;

            ++char_count;
            if (char_count == 4)
                break;
        }

        if (char_string == "0101")
            serial_verified = true;
    }

    if (!serial_verified)
        wait_for_device();

    ipc->send_message("menu_plus", "set loading progress", "10");
    console_log("serial number: " + serial_number);

    data_path_current_module = data_path + slash + serial_number;

    int x_accel;
    int y_accel;
    int z_accel;
    camera->getAccelerometerValues(&x_accel, &y_accel, &z_accel);    
    
    Point3f heading = imu.compute_azimuth(x_accel, y_accel, z_accel);

    ipc->send_message("menu_plus", "set status", "loading calibration data");
    reprojector.load(*ipc, true);
    ipc->send_message("menu_plus", "set loading progress", "40");

    ipc->send_message("menu_plus", "set status", "initializing camera");
    CameraInitializerNew::init(camera);

    ipc->send_message("menu_plus", "set status", "loading pose data");
    pose_estimator.init();
    ipc->send_message("menu_plus", "set loading progress", "70");

    ipc->send_message("menu_plus", "set status", "starting cursor subprocess");

#ifdef _WIN32
    child_module_name = "win_cursor_plus";
    
    if (IsWindows8OrGreater())
        child_module_path = executable_path + slash + "win_cursor_plus" + slash + "win_cursor_plus" + extension0;
    else
        child_module_path = executable_path + slash + "win_cursor_plus_fallback" + slash + "win_cursor_plus" + extension0;

#elif __APPLE__
    //todo: port to OSX
#endif

    ipc->map_function("toggle imshow", [](const string message_body)
    {
        if (enable_imshow)
            enable_imshow = false;
        else
            enable_imshow = true;
    });

    ipc->map_function("load settings", [](const string message_body)
    {
        load_settings();
    });

    ipc->send_message("menu_plus", "set loading progress", "100");
}
Exemplo n.º 4
0
void compute()
{
    updated = false;

    if (image_current_frame.cols == 0)
    {
        COUT << "bad frame" << endl;
        return;
    }

    Mat image_flipped;
    flip(image_current_frame, image_flipped, 0);

    Mat image0 = image_flipped(Rect(0, 0, 640, 480));
    Mat image1 = image_flipped(Rect(640, 0, 640, 480));

    if (first_frame)
    {
        on_first_frame();
        first_frame = false;
    }

    if (!play || settings.touch_control != "1")
    {
        hide_cursors();

        if (enable_imshow)
            waitKey(1);

        return;
    }

    int x_accel;
    int y_accel;
    int z_accel;
    camera->getAccelerometerValues(&x_accel, &y_accel, &z_accel);
    imu.compute(x_accel, y_accel, z_accel);

    //----------------------------------------core algorithm----------------------------------------

    Mat image_small0;
    Mat image_small1;
    resize(image0, image_small0, Size(160, 120), 0, 0, INTER_LINEAR);
    resize(image1, image_small1, Size(160, 120), 0, 0, INTER_LINEAR);

    Mat image_preprocessed0;
    Mat image_preprocessed1;

    bool normalized = compute_channel_diff_image(image_small0, image_preprocessed0, exposure_adjusted, "image_preprocessed0", true);
                      compute_channel_diff_image(image_small1, image_preprocessed1, exposure_adjusted, "image_preprocessed1", false);

    GaussianBlur(image_preprocessed0, image_preprocessed0, Size(3, 9), 0, 0);
    GaussianBlur(image_preprocessed1, image_preprocessed1, Size(3, 9), 0, 0);

    if (!CameraInitializerNew::adjust_exposure(camera, image_preprocessed0))
    {
        static int step_count = 0;
        if (step_count == 3)
        {
            surface_computer.init(image0);
        }
        ++step_count;
        return;
    }

    exposure_adjusted = true;

#ifdef false
    {
        Mat image_remapped0 = reprojector.remap(&image_small0, 0, true);
        Mat image_remapped1 = reprojector.remap(&image_small1, 1, true);

        reprojector.y_align(image_remapped0, image_remapped1, false);

        GaussianBlur(image_remapped0, image_remapped0, Size(9, 9), 0, 0);
        GaussianBlur(image_remapped1, image_remapped1, Size(9, 9), 0, 0);


		Mat image_disparity;

		static StereoSGBM stereo_sgbm(0, 32, 21, 0, 0, 0, 0, 20, 0, 0, false);
		stereo_sgbm(image_remapped0, image_remapped1, image_disparity);

        Mat image_disparity_8u;
        double minVal, maxVal;
        minMaxLoc(image_disparity, &minVal, &maxVal);
        image_disparity.convertTo(image_disparity_8u, CV_8UC1, 255 / (maxVal - minVal));

		imshow("image_remapped0", image_remapped0);
		imshow("image_remapped1", image_remapped1);
		imshow("image_disparity_8u", image_disparity_8u);
    }
#endif

	/*static bool show_wiggle_sent = false;
	if (!show_wiggle_sent)
	{
        if (child_module_name != "")
		  ipc->open_udp_channel(child_module_name);
        
		ipc->send_message("menu_plus", "show window", "");
		ipc->send_message("menu_plus", "show wiggle", "");//todo
	}
	show_wiggle_sent = true;*/

    if (enable_imshow)
    {
        imshow("image_small1", image_small1);
        imshow("image_preprocessed1", image_preprocessed1);

        // setMouseCallback("image_preprocessed1", left_mouse_cb, NULL);
        // waitKey(1);
        // return;
    }

    algo_name_vec_old = algo_name_vec;
	algo_name_vec.clear();

    static bool motion_processor_proceed = false;
    static bool construct_background = false;
    static bool first_pass = true;

    bool proceed0;
    bool proceed1;

    if (normalized)
    {
        proceed0 = motion_processor0.compute(image_preprocessed0,  image_small0, surface_computer.y_reflection, imu.pitch,
                                             construct_background, "0",          true);
        proceed1 = motion_processor1.compute(image_preprocessed1,  image_small1, surface_computer.y_reflection, imu.pitch,
                                             construct_background, "1",          true);
    }

    if (first_pass && motion_processor0.both_moving)
    {
        COUT << "readjusting exposure" << endl;

        first_pass = false;
        exposure_adjusted = false;
        CameraInitializerNew::adjust_exposure(camera, image_preprocessed0, true);
    }
    else if (!first_pass)
        construct_background = true;

    if (!construct_background)
    {
        proceed0 = false;
        proceed1 = false;            
    }

    if (proceed0 && proceed1)
        motion_processor_proceed = true;

    bool proceed = motion_processor_proceed;

    if (proceed)
    {
        proceed0 = foreground_extractor0.compute(image_preprocessed0, motion_processor0, "0", false);
        proceed1 = foreground_extractor1.compute(image_preprocessed1, motion_processor1, "1", false);
        proceed = proceed0 && proceed1;
    }

    if (proceed)
    {
        proceed0 = hand_splitter0.compute(foreground_extractor0, motion_processor0, "0");
        proceed1 = hand_splitter1.compute(foreground_extractor1, motion_processor1, "1");
        proceed = proceed0 && proceed1;
    }

    proceed = false;

    if (proceed)
    {
        proceed0 = mono_processor0.compute(hand_splitter0, "0", false);
        proceed1 = mono_processor1.compute(hand_splitter1, "1", false);
        proceed = proceed0 && proceed1;
    }

    if (proceed)
    {
        stereo_processor.compute(mono_processor0, mono_processor1, point_resolver, pointer_mapper, image0, image1);
    }

    ++frame_num;

    if (increment_keypress_count)
    {
        if (keypress_count == calibration_points_count)
        {
            COUT << "step " << calibration_step << " complete" << endl; 

            // ipc->send_message("menu_plus", "show calibration next", "");//todo
            ++calibration_step;
        }
        else if (keypress_count < calibration_points_count)
        {
            float percentage = (keypress_count * 100.0 / calibration_points_count);
            COUT << percentage << endl;

            pointer_mapper.add_calibration_point(calibration_step);
        }

        if (calibration_step == 4)
        {
            pointer_mapper.compute_calibration_points();
            calibrating = false;
            increment_keypress_count = false;

            COUT << "calibration finished" << endl;
        }

        ++keypress_count;
    }

    if (enable_imshow)
        waitKey(1);
}
void PointerMapper::compute_cursor_point(bool& target_down, Point2f& pt_target0, Point2f& pt_target1, Point3f& pt_target,
										 Reprojector& reprojector, Point2f& pt_cursor, float& dist_cursor_target_plane,
										 const float actuation_dist, string name)
{
	LowPassFilter* low_pass_filter = value_store.get_low_pass_filter("low_pass_filter" + name);

	if (do_reset)
	{
		do_reset = false;
		low_pass_filter->reset();
	}

	if (pt_target0.x != -1 && pt_target1.x != -1)
	{
		active = true;
		pt_target = reprojector.reproject_to_3d(pt_target0.x, pt_target0.y, pt_target1.x, pt_target1.y);

		if (calibrated)
		{
			Point3f pt_target_projected;
			float dist_target_plane;
			project_to_plane(pt_target, pt_target_projected, dist_target_plane);

			rect_warper.warp(pt_target_projected.x, pt_target_projected.y, pt_cursor.x, pt_cursor.y);

			if (value_store.has_point2f("pt_cursor" + name))
			{
                Point2f temp = value_store.get_point2f("pt_cursor" + name);
                float alpha = get_distance(pt_cursor, temp) / 1000;
	            if (alpha < 0.05)
	            	alpha = 0.05;
	            else if (alpha > 1)
	            	alpha = 1;

	            // low_pass_filter->compute(alpha, 0.5, "alpha" + name);
	            low_pass_filter->compute(pt_cursor, alpha, "pt_cursor" + name);
	        }
	        value_store.set_point2f("pt_cursor" + name, pt_cursor);

			float hit_dist = compute_hit_dist(pt_target_projected);

			dist_cursor_target_plane = dist_target_plane - hit_dist;
			low_pass_filter->compute(dist_cursor_target_plane, 0.2, "dist_cursor_target_plane");

			float hit_dist_processed = hit_dist;
			// float hit_dist_processed_old = value_store.get_float("hit_dist_processed_old" + name, hit_dist_processed); 
			// hit_dist_processed += ((hit_dist_processed - hit_dist_processed_old) * 0.25);
			// value_store.set_float("hit_dist_processed_old" + name, hit_dist_processed);

			float dist_cursor_target_plane_no_lowpass = dist_target_plane - hit_dist_processed;

			if (dist_cursor_target_plane_no_lowpass <= actuation_dist + 2)
				value_store.set_bool("actuated" + name, true);

			if (value_store.get_bool("actuated" + name))
			{
				target_down = true;
				
				if (dist_cursor_target_plane_no_lowpass > actuation_dist + 5)
				{
					target_down = false;
					value_store.set_bool("actuated" + name, false);
				}
			}
		}
	}
	else
		low_pass_filter->reset();
}
Exemplo n.º 6
0
void on_first_frame()
{
	bool serial_verfied = false;
	serial_number = camera->getSerialNumber();

	if (serial_number.size() == 10)
	{
		string char_string = "";
		int char_count = 0;
		for (char& c : serial_number)
		{
			char_string += c;

			++char_count;
			if (char_count == 4)
				break;
		}

		if (char_string == "0101")
			serial_verfied = true;
	}

	if (!serial_verfied)
	{
		hide_cursors();

		COUT << "please reconnect your Touch+ sensor" << endl;
		COUT << "restarting" << endl;

		wait_for_device();
	}

	data_path_current_module = data_path + "\\" + serial_number;

	int x_accel;
	int y_accel;
	int z_accel;
	camera->getAccelerometerValues(&x_accel, &y_accel, &z_accel);
	
	Point3d heading = imu.compute_azimuth(x_accel, y_accel, z_accel);

	// if (heading.y > 60)
		// mode = "tool";
	// else
		mode = "surface";

	ipc->send_message("menu_plus", "show notification", "Please wait:Initializing Touch+ Software");

	reprojector.load(*ipc);
	CameraInitializerNew::init(camera);
	pose_estimator.init();

	if (mode == "surface")
	{
		child_module_name = "win_cursor_plus";

		if (IsWindows8OrGreater())
			child_module_path = executable_path + "\\win_cursor_plus\\win_cursor_plus.exe";
		else
			child_module_path = executable_path + "\\win_cursor_plus_fallback\\win_cursor_plus.exe";

		ipc->open_udp_channel("win_cursor_plus");
		ipc->send_message("menu_plus", "show window", "");	
		ipc->send_message("menu_plus", "show wiggle", "");
	}
	else
	{
		ipc->open_udp_channel("unity_demo", 3333);
		ipc->send_message("menu_plus", "hide window", "");
	}

	ipc->map_function("toggle imshow", [](const string message_body)
	{
		if (enable_imshow)
		{
			enable_imshow = false;
			destroyAllWindows();
		}
		else
			enable_imshow = true;
	});

	ipc->map_function("load settings", [](const string message_body)
	{
		load_settings();
	});

	increment_wait_count = true;
}