Index: liacs/mms/project/README
===================================================================
--- liacs/mms/project/README	(revision 23)
+++ liacs/mms/project/README	(revision 23)
@@ -0,0 +1,90 @@
+MotionMouse, Rick van der Zwet - 0433373 <hvdzwet@liacs.nl>
+
+= Abstract =
+'Enhanced' presentation utility. Mouse interaction device using gestures or a
+laser pointer and a WiiRemote controllor.
+
+= Introduction =
+Current presentation devices only have a few forward/backward buttons and a
+laser pointer, this is not suffient when presenting interactive media (e.g.
+switching between many diffent input sources.). As now-a-days almost all
+laptops has a high quality webcam included and are powerful devices. Using
+commodity tools there needs to make a much better use of the resources
+available.
+
+= Background =
+Alternative available devices 'emulate' the mouse using gyrosensors or a
+trackball. The combination with laser tracking has been tried already in a
+different form with a more fixed setup [1]. Laser pointer tracking has also
+been done, but most of the times not in lively envirionments. Gesture tracking
+has been done in a fixed setup with a easy distinguable object like a dark
+background [2], or a well coloured glove [3] or in a more advanced but static
+setup [4]. Also using high-tech equipment [5].
+
+= Implementation =
+The system is build on a Macbook Pro (model:4,1) running Ubuntu 9.10 amd64. The
+Webcam used for tracking is an USB Trust WB-6250X Webcam (145f:0142). The
+OpenCV package (2.0.0) is compiled from source. The WiiRemote is an model from
+late 2008. The laser pointer used is a green laser pointer with high density
+(50mW, WARNING: use in protected envirionments with IR safety eye wear).
+
+The Beamer used had an resolution of 800x600 and was projecting on a white
+stone wall. The webcam was placed on top of the beamer.
+
+= Description =
+The system consists of 3 components. The buttons and it's handeling are done
+using the WiiRemote which connects to the laptop using bluetooth and the Open
+Source program cwiid [6].
+
+The second component is build on the OpenCV [7] package. It detect the laser
+pointer using a difference-algoritm. 1) Blurring is applied to get rid of the
+webcam detections errors (.e.g wrong pictures). 2) The current frame values are
+subtracted by the previous frame. 3) The spot of X times Y with the highest Red
+and Green density is detected as the current laser pointer position, if the
+threshold is above a certain value. The C source code is found at [8].
+
+The mouse location is updated to it's right location taking into count
+transformation from the virtual to the real screen. The UNIX X11 implementation
+is done using parts of the xdotool [9] package.
+
+= Discussion and Conclusions =
+The status of the project could be marked as an early alpha. Mouse updates and
+clicking works fine, altough the initialisation phase (the so called pairing)
+could use some improvement. The tracking works if the image is static and there
+is not many distorting with regards to movement.
+
+The laser to mouse pointer caliberation is not yet working has has to be done
+by hand, the checkerboard image (in the source [8]) also needs to be done
+automatically.
+
+Brightness control is a part to focus on further research. The Webcam
+now tries to optimize for the whole screen, causing the laser pointer to
+disappear in a bright light blob.
+
+The tracking algoritm now has trouble using moving images. As the picture send
+to the output could be 'snooped' as well. There should be some more smarter
+detection posible of the laser pointer.
+
+= References =
+[1] Christopher Armenio, Design of a Laser Controlled Mouse Using OpenCV, 2008
+
+[2] Cristina Manresa, Javier Varona, Ramon Mas and Francisco J. Perales, Real
+    âTime Hand Tracking and Gesture Recognition for Human-Computer Interaction,
+    Electronic Letters on Computer Vision and Image Analysis 0(0):1-7, 2000
+
+[3] Robert Y. Wan, Jovan Popovi, Real-Time Hand-Tracking with a Color Glove,
+    2009
+
+[4] Shahzad Malik, Real-time Hand Tracking and Finger Tracking for Interaction,
+    2003 
+
+[5] Daniel Kurz, et al., Laser Pointer Tracking in Projector-Augmented
+    Architectural Environments, 2007
+
+[6] cwiid, http://github.com/abstrakraft/cwiid
+
+[7] OpenCV, http://opencv.willowgarage.com
+
+[8] Detection software, http://rickvanderzwet.nl/svn/personal/liacs/mms/project/
+
+[9] xdotool, http://www.semicomplete.com/projects/xdotool/
Index: liacs/mms/project/chessboard.pl
===================================================================
--- liacs/mms/project/chessboard.pl	(revision 22)
+++ liacs/mms/project/chessboard.pl	(revision 23)
@@ -6,4 +6,7 @@
 ($WIDTH, $HEIGHT) = split(' ',`xrandr  | awk '/\\*/ {print $$1}' | tr 'x' ' '`);
 print "Screen: ". $WIDTH . "x" . $HEIGHT . "\n";
+
+$HEIGHT=600;
+$WIDTH=800;
 
 $X_NUM=$HEIGHT/$BLOCK_SIZE;
@@ -58,4 +61,2 @@
 print $CMD;
 `$CMD`;
-`display gif:$FILE`;
-
Index: liacs/mms/project/colour-tracking.c
===================================================================
--- liacs/mms/project/colour-tracking.c	(revision 22)
+++ liacs/mms/project/colour-tracking.c	(revision 23)
@@ -85,12 +85,19 @@
     int r, g, b;
     int q;
+    int x_move, y_move;
+
     int retval;
     char arg1[4], arg2[4];
     int keycode;
     // Actually move the pointer to it's location
-    int mouse_flag = 1;
+    int mouse_flag = 0;
+    int r_window_flag = 1;
+    int g_window_flag = 1;
+    int b_window_flag = 1;
     // XXX: Hack to have the pointer posted on the second screen.
     int ex_screen_flag = 0;
-	
+    int x_ajust = -114;
+    int y_ajust = -95;
+
     
     int cvalue = 0;
@@ -112,6 +119,6 @@
 
         //cvCopy(image, output, NULL);
-	//Remove Noise from images
-	cvSmooth(image,output,CV_BLUR, 3, 3, 3,3);
+        //Remove Noise from images
+	    cvSmooth(image,output,CV_BLUR, 3, 3, 3,3);
         cvCopy(image, routput, NULL);
         cvCopy(image, goutput, NULL);
@@ -175,12 +182,12 @@
         cvCircle(target, cvPoint(xmax, ymax), 10, CV_RGB(255,0,0),4, 8, 0);
         // Set to pointer to new location
+        // Some Hacking to get the pointer synced
         if (mouse_flag) {
+            x_move = ratio(xmax + x_ajust,width,screen_width);
+            y_move = ratio(ymax + y_ajust,height,screen_height);
             if (ex_screen_flag) {
-                xdo_mousemove(xdo, ratio(xmax,width,screen_width) + screen_width - 250, 
-                    ratio(ymax,height,screen_height));
-            } else {
-                xdo_mousemove(xdo, ratio(xmax,width,screen_width), 
-                    ratio(ymax,height,screen_height));
+                x_move += screen_width;
             }
+            xdo_mousemove(xdo, x_move, y_move);
         }
                         
@@ -188,7 +195,10 @@
         // Show all the images
         cvShowImage("RGB_Image", output);
-        cvShowImage("R_Image", routput);
-        cvShowImage("B_Image", boutput);       
-        cvShowImage("G_Image", goutput);       
+        if (r_window_flag)
+            cvShowImage("R_Image", routput);
+        if (b_window_flag)
+            cvShowImage("B_Image", boutput);       
+        if (g_window_flag)
+            cvShowImage("G_Image", goutput);       
         cvShowImage("F_Image", target);       
                     
@@ -202,10 +212,31 @@
 		        break;
             } else if (keycode == 'm') {
-                mouse_flag =  (mouse_flag == 1) ? 0 : 1;
+                mouse_flag ^= 1;
             } else if (keycode == 'e') {
-                ex_screen_flag =  (ex_screen_flag == 1) ? 0 : 1;
-
+                ex_screen_flag ^= 1;
+            // Hack to manually sync mouse pointer with laser pointer
+            } else if (keycode == 'w' || keycode == 's' || keycode == 'a' || \
+                keycode == 'd') { 
+                if (keycode == 'w') {
+                    y_ajust--;
+                } else if (keycode == 's') {
+                    y_ajust++;
+                } else if (keycode == 'a') {
+                    x_ajust--;
+                } else if (keycode == 'd') {
+                    x_ajust++;
+                }
+                printf("New x,y ajust: %i,%i\n",x_ajust,y_ajust);
+            } else if (keycode == 'r' || keycode == 'g' || keycode == 'b') {
+                printf("Toggle window: %c\n", keycode);
+                if (keycode == 'r') {
+                    r_window_flag ^= 1;
+                } else if (keycode == 'g') {
+                    g_window_flag ^= 1;
+                } else if (keycode == 'b') {
+                    b_window_flag ^= 1;
+                }
             }
-	    }
+        }
     } //for each frame ...
 
@@ -226,4 +257,15 @@
 int main(int argc, char *argv[]) {
    int retval;
+   printf("=== INSTRUCTION == \n\
+Keybindings:\n\
+e = toggle mouse on external screen mouse pointer\n\
+m = toggle mouse tracking\n\
+q = quit\n\
+Mouse/laser pointer syncer:\n\
+w = up\n\
+s = down\n\
+a = left\n\
+f = right\n\
+");
    xdo = xdo_new(getenv("DISPLAY"));
    retval = InitSystem(argc, argv);
Index: liacs/mms/project/xdo_util.h
===================================================================
--- liacs/mms/project/xdo_util.h	(revision 23)
+++ liacs/mms/project/xdo_util.h	(revision 23)
@@ -0,0 +1,55 @@
+/* xdo utility pieces 
+ *
+ * $Id: xdo_util.h 1854 2008-05-21 07:23:29Z jordansissel $
+ */
+
+/* human to Keysym string mapping */
+const char *symbol_map[] = {
+  "alt", "Alt_L",
+  "ctrl", "Control_L",
+  "control", "Control_L",
+  "meta", "Meta_L",
+  "super", "Super_L",
+  "shift", "Shift_L",
+  NULL, NULL,
+};
+
+keysymcharmap_t keysymcharmap[] = {
+  { "Return", '\n', },
+  { "ampersand", '&', },
+  { "apostrophe", '\'', },
+  { "asciicircum", '^', },
+  { "asciitilde", '~', },
+  { "asterisk", '*', },
+  { "at", '@', },
+  { "backslash", '\\', },
+  { "bar", '|', },
+  { "braceleft", '{', },
+  { "braceright", '}', },
+  { "bracketleft", '[', },
+  { "bracketright", ']', },
+  { "colon", ':', },
+  { "comma", ',', },
+  { "dollar", '$', },
+  { "equal", '=', },
+  { "exclam", '!', },
+  { "grave", '`', },
+  { "greater", '>', },
+  { "less", '<', },
+  { "minus", '-', },
+  { "numbersign", '#', },
+  { "parenleft", '(', },
+  { "parenright", ')', },
+  { "percent", '%', },
+  { "period", '.', },
+  { "plus", '+', },
+  { "question", '?', },
+  { "quotedbl", '"', },
+  { "semicolon", ';', },
+  { "slash", '/', },
+  { "space", ' ', },
+  { "tab", '\t', },
+  { "underscore", '_', },
+  { NULL, 0, },
+};
+
