I cam up with this when I seen what Johnny Lee can do with a wiimote. Youtube it to check it out, pretty amazing.
I realized not everybody has a wiimote or a bluetooth dongle to connect it to the PC, so I used my webcam and python.
The webcam needs to have a filter on it to rid everything but the IRLED. A few layers of film negative, the black ends of them, is placed over the lens of the webcam to only allow IR light to come through. I don't have a way to click with the mouse, but use voice recognition instead to do that.
You will need VideoCapture and PIL.

Most camera shops will give you waste negatives.
Hope this helps someone.

#Webcam IR mouse control
#K.B. Carte 07/27/2009
#Works only with an IR filter on the webcam.
#To do this simply cut out the black part of a film
#negitave, and place two or three layers over the lens
#of the webcam. 



from VideoCapture import Device
import Image
from ctypes import *

cam = Device()
user = windll.user32
res = (1440,900)      #set to the resolution of the screen

def xy(im):
  imxy = im.getprojection()
  imx = imxy[0]
  imy = imxy[1]
  x = imx.index(1)
  y = imy.index(1)
  return (x,y)


while 1:
  try:
    im = cam.getImage()
    im = im.resize(res)
    x,y = xy(im)
    user.SetCursorPos(x,y)
  except ValueError:   #A value error is raised when it can't see 
    pass               #the IRLED

I don't know how to edit a post after I posted it, but i mirrored the image instance with ImageOps module so the X axis would no longer be inverted. And I also found out I can use a lighter instead of an IRLED. It amazed me and my wife's family =)

I wanted to see what the webcam was seeing, so i used pygame.

#Webcam IR mouse control 1.0
#K.B. Carte Aug. 10, 2009
#Works only with an IR filter on the webcam.
#To do this simply cut out the black part of a film
#negitave, and place two or three layers over the lens
#of the webcam.
######################################################



#----------imports and global variabl assignment------
######################################################
from VideoCapture import Device
import Image, sys, pygame
from ctypes import *
import ImageOps
from PIL import ImageEnhance
from pygame.locals import *
cam = Device()
user = windll.user32
res = (1440,900) #set to the resolution of the screen
pygame.init()
screen = pygame.display.set_mode((640,480))
pygame.display.set_caption('IR Mouse Control')
font = pygame.font.SysFont("Curier",26)

#---------------functions-----------------------
################################################
#Returns the xy cordinets of the ir dot.
#Doesn't return exact dot, only the first TRUE pixel value
def xy(im):
  imxy = im.getprojection()
  imx = imxy[0]
  imy = imxy[1]
  x = imx.index(1)
  y = imy.index(1)
  return (x,y)

#Decides if a 'click' was called.
#Returns 1 or 0 and size in pixels of the ir dot
#Still in testing stage =/
def irclk(im):
  yn = 0
  xi = 0
  yi = 0
  irxy = im.getprojection()
  irx = irxy[0]
  iry = irxy[1]

  for i in irx:
    if i == 1:
      xi +=1
  for i in iry:
    if i == 1:
      yi += 1
  xyi = xi + yi
  if xyi >= 100:#***
    yn = 1
  else: yn = 0
  return (yn,xyi)


#-----------Main loop--------------------
#########################################
while 1:
  
  for event in pygame.event.get():
    if event.type == pygame.QUIT: sys.exit()
    
  try:
    imt = cam.getImage()
    im = imt.resize(res)
    im = ImageOps.mirror(im)
    im1 = ImageEnhance.Contrast(imt).enhance(1.0)
    im1 = ImageEnhance.Brightness(imt).enhance(1.5)
    x,y = xy(im)
    user.SetCursorPos(x,y)
    name = font.render('By K.B. Carte', True, (250,250,250))
    web = font.render('Webcam IR mouse control : 1.0.1', True, (250,250,250))
    fil = font.render('Works only with an IR filter on the webcam lens', True, (250,250,250))
    yn = irclk(im1)
    xyi = yn[1]
    num = font.render("IR intensity:" + str(xyi), True, (250,250,250))
    if yn[0] ==1:
      cl = 'click'
    else: cl = '' 
    clik = font.render(cl, True, (250,250,250))
    im1 = pygame.image.frombuffer(im1.tostring(), (640,480), "RGB")
    
    screen.blit(im1, (0,0))
    screen.blit(name,(0,26))
    screen.blit(web,(0,0))
    screen.blit(fil,(0,52))
    screen.blit(clik,(0,104))
    screen.blit(num, (0,78))
    pygame.display.flip()
                      
  except ValueError:   #A value error is raised when it can't see the IRLED.
    pass               #So we ignor it.
                       #I'm trying to maybe control the 'click' with the except
                       #So the click will be a lack of the ir light
                       #Still testing...

This code has the click event.

#Webcam IR mouse control 1.6
#K.B. Carte Sept. 9, 2009
#Works only with an IR filter on the webcam.
#To do this simply cut out the black part of a film
#negitave, and place two or three layers over the lens
#of the webcam.
######################################################



#----------imports and global variabl assignment------
######################################################
from VideoCapture import Device
import Image, sys, pygame
from ctypes import *
import ImageOps
from PIL import ImageEnhance
from pygame.locals import *
cam = Device()
user = windll.user32
res = (1440,900) #set to the resolution of the screen
pygame.init()
screen = pygame.display.set_mode((640,480))
pygame.display.set_caption('IR Mouse Control')
font = pygame.font.SysFont("Curier",26)

#---------------functions-----------------------
################################################
#Returns the xy cordinets of the ir dot.
#Doesn't return exact dot, only the first TRUE pixel value
def xy(im):
  imxy = im.getprojection()
  imx = imxy[0]
  imy = imxy[1]
  x = imx.index(1)
  y = imy.index(1)
  return (x,y)

#Returns size in pixels of the ir dot
#Was going to be used for click event
#No longer needed, but I think its a cool feature =]
def irint(im):
  xyi = 0
  irxy = im.getprojection()
  irx = irxy[0]
  iry = irxy[1]

  for i in irx:
    if i == 1:
      xyi +=1
  for i in iry:
    if i == 1:
      xyi += 1
  return xyi

################################################################################
#Used for "click" event
################################################################################
#from ctypes import *
user32 = windll.user32
import time

PUL = POINTER(c_ulong)
class KeyBdInput(Structure):
    _fields_ = [("wVk", c_ushort),
             ("wScan", c_ushort),
             ("dwFlags", c_ulong),
             ("time", c_ulong),
             ("dwExtraInfo", PUL)]

class HardwareInput(Structure):
    _fields_ = [("uMsg", c_ulong),
             ("wParamL", c_short),
             ("wParamH", c_ushort)]

class MouseInput(Structure):
    _fields_ = [("dx", c_long),
             ("dy", c_long),
             ("mouseData", c_ulong),
             ("dwFlags", c_ulong),
             ("time",c_ulong),
             ("dwExtraInfo", PUL)]

class Input_I(Union):
    _fields_ = [("ki", KeyBdInput),
              ("mi", MouseInput),
              ("hi", HardwareInput)]

class Input(Structure):
    _fields_ = [("type", c_ulong),
             ("ii", Input_I)]

class POINT(Structure):
    _fields_ = [("x", c_ulong),
             ("y", c_ulong)]
# END SENDINPUT TYPE DECLARATIONS

FInputs = Input * 2
extra = c_ulong(0)

click = Input_I()
click.mi = MouseInput(0, 0, 0, 2, 0, pointer(extra))
release = Input_I()
release.mi = MouseInput(0, 0, 0, 4, 0, pointer(extra))

#x = FInputs( (0, click), (0, release) )
#user32.SendInput(2, pointer(x), sizeof(x[0]))

###################################################################
#Work cited: Case Nelson                                          # 
#http://mail.python.org/pipermail/python-list/2005-May/320761.html#
###################################################################


def clk():
  x = FInputs((0, click))
  user32.SendInput(2, pointer(x), sizeof(x[0]))
def rel():
  a = FInputs((0, release))
  user32.SendInput(2, pointer(a), sizeof(a[0]))



#-----------Main loop--------------------
#########################################
while 1:
  
  for event in pygame.event.get():
    if event.type == pygame.QUIT: sys.exit()
    
  try:
    rel()
    imt = cam.getImage()
    im = imt.resize(res)
    im = ImageOps.mirror(im)
    im1 = ImageEnhance.Contrast(imt).enhance(1.0)
    im1 = ImageEnhance.Brightness(imt).enhance(1.5)
    x,y = xy(im)
    xyi = irint(im1)
    user.SetCursorPos(x,y)
    irpix = font.render("IR intensity in pixels:" + str(xyi), True, (250,250,250))
    name = font.render('By K.B. Carte', True, (250,250,250))
    web = font.render('Webcam IR mouse control : 1.0.1', True, (250,250,250))
    fil = font.render('Works only with an IR filter on the webcam lens', True, (250,250,250))
    im1 = pygame.image.frombuffer(im1.tostring(), (640,480), "RGB") 
    screen.blit(im1, (0,0))
    screen.blit(name,(0,26))
    screen.blit(web,(0,0))
    screen.blit(fil,(0,52))
    screen.blit(irpix,(0,78))
    pygame.display.flip()
                      
  except ValueError:   #A value error is raised when it can't see the IRLED.
    clk()             #I use it to register a click.
    pass               #Not practical, thinking just hack a mouse to mount on head
                       #and click with an momentary swtich or something.

After I got this working, I wanted to map two IR dots to mimic the WII Mote a little better. http://www.daniweb.com/forums/thread240812.html

The mouse movement will be mapped to the slope of the line.
And the whole click thing doesn't work as smoothly, so I have rigged a mouse to a hat and extended the buttons to run down to the mouth.
It seems to work ALLOT better.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.