Skip to content

Instantly share code, notes, and snippets.

@anr2me
Forked from sheharyarn/mouse_control.py
Created March 24, 2021 08:16
Show Gist options
  • Save anr2me/57145fca590eb6cf9ea81f97e3b729b3 to your computer and use it in GitHub Desktop.
Save anr2me/57145fca590eb6cf9ea81f97e3b729b3 to your computer and use it in GitHub Desktop.

Revisions

  1. @sheharyarn sheharyarn revised this gist Mar 25, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion readme.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    # Mouse Control
    This is my modification of the [original script](https://gist.github.com/willpatera/7908319#file-stream_gaze_coords-py) so you don't need to enable Marker Tracking or define surfaces. You simply need to start the Coordinates Streaming Server in [Pupil](https://github.com/pupil-labs/pupil/wiki/Pupil-capture#pupil-server) and run this independent script.
    This is my modification of the [original script](https://gist.github.com/willpatera/7908319#file-stream_gaze_coords-py) so you don't need to enable Marker Tracking or define surfaces. You simply need to start the [Coordinates Streaming Server](https://github.com/pupil-labs/pupil/wiki/Pupil-capture#pupil-server) in [Pupil](https://github.com/pupil-labs/pupil/) and run this independent script.

    **Note:** Not using Surfaces and Marker Tracking decreases the accuracy of pointer movement. This won't work well enough because `norm_gaze` data is being used instead of your surface gaze data.

  2. @sheharyarn sheharyarn revised this gist Mar 25, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion readme.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    # Mouse Control
    This is my modification of the [original script](https://gist.github.com/willpatera/7908319#file-stream_gaze_coords-py) so you don't need to enable Marker Tracking or define surfaces. You simply need to start the Coordinates Streaming Server and run this independent script.
    This is my modification of the [original script](https://gist.github.com/willpatera/7908319#file-stream_gaze_coords-py) so you don't need to enable Marker Tracking or define surfaces. You simply need to start the Coordinates Streaming Server in [Pupil](https://github.com/pupil-labs/pupil/wiki/Pupil-capture#pupil-server) and run this independent script.

    **Note:** Not using Surfaces and Marker Tracking decreases the accuracy of pointer movement. This won't work well enough because `norm_gaze` data is being used instead of your surface gaze data.

  3. @sheharyarn sheharyarn renamed this gist Mar 25, 2014. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  4. @sheharyarn sheharyarn renamed this gist Mar 25, 2014. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  5. @sheharyarn sheharyarn renamed this gist Mar 25, 2014. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  6. @sheharyarn sheharyarn renamed this gist Mar 25, 2014. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  7. @sheharyarn sheharyarn revised this gist Mar 25, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion mouse_control.py
    Original file line number Diff line number Diff line change
    @@ -44,4 +44,4 @@
    pass
    else:
    # process non gaze position events from plugins here
    pass
    pass
  8. @sheharyarn sheharyarn revised this gist Mar 25, 2014. 8 changed files with 58 additions and 230 deletions.
    2 changes: 0 additions & 2 deletions Pupil_tools.md
    Original file line number Diff line number Diff line change
    @@ -1,2 +0,0 @@
    # Pupil Tools
    This is a small collection of tools that we use with [Pupil](www.github.com/pupil-labs/pupil "pupil repository"). The tools are not part of the main repository, as they are mostly stand-alone convenience scripts.
    77 changes: 0 additions & 77 deletions make_square_markers.py
    Original file line number Diff line number Diff line change
    @@ -1,77 +0,0 @@
    """
    Make square markers is a helper script that is used to generate 5x5 square marker png files that can be printed.
    """
    import cv2
    import numpy as np

    def encode_marker(mId):
    marker_id_str = "%02d"%mId
    # marker is based on grid of black (0) /white (1) pixels
    # b|b|b|b|b
    # b|o|m|o|b b = black border feature
    # b|m|m|m|b o = orientation feature
    # b|o|m|o|b m = message feature
    # b|b|b|b|b
    grid = 5
    m_with_b = np.zeros((grid,grid),dtype=np.uint8)
    m = m_with_b[1:-1,1:-1]

    #bitdepth = grid-border squared - 3 for orientation (orientation still yields one bit)
    bitdepth = ((5-2)**2)-3

    if mId>=(2**bitdepth):
    raise Exception("ERROR: ID overflow, this marker can only hold %i bits of information" %bitdepth)

    msg = [0]*bitdepth
    for i in range(len(msg))[::-1]:
    msg[i] = mId%2
    mId = mId >>1

    # out first bit is encoded in the orientation corners of the marker:
    # MSB = 0 MSB = 1
    # W|*|*|W ^ B|*|*|B ^
    # *|*|*|* / \ *|*|*|* / \
    # *|*|*|* | UP *|*|*|* | UP
    # B|*|*|W | W|*|*|B |

    msb = msg.pop(0)
    if msb:
    orientation = 0,1,0,0
    else:
    orientation = 1,0,1,1

    m[0,0], m[-1,0], m[-1,-1], m[0,-1] = orientation

    msg_mask = np.ones(m.shape,dtype=np.bool)
    msg_mask[0,0], msg_mask[-1,0], msg_mask[-1,-1], msg_mask[0,-1] = 0,0,0,0
    m[msg_mask] = msg[::-1]

    # print "Marker: \n", m_with_b
    return m_with_b

    def write_marker_png(mId,size):
    marker_id_str = "%02d"%mId
    m = encode_marker(mId)*255
    m = cv2.resize(m,(size,size),interpolation=cv2.INTER_NEAREST)
    m = cv2.cvtColor(m,cv2.COLOR_GRAY2BGR)
    cv2.imwrite('marker '+marker_id_str+'.png',m)


    def write_all_markers_png(size):
    rows,cols,m_size = 8,8,7
    canvas = np.ones((m_size*rows,m_size*cols),dtype=np.uint8)
    for mid in range(64):
    marker_with_padding = np.ones((7,7))
    marker_with_padding[1:-1,1:-1] = encode_marker(mid)
    m_size = marker_with_padding.shape[0]
    r = (mid%rows) * m_size
    c = (mid/cols) * m_size
    canvas[r:r+m_size,c:c+m_size] = marker_with_padding*255
    canvas = cv2.resize(canvas,(size,size),interpolation=cv2.INTER_NEAREST)
    canvas = cv2.cvtColor(canvas,cv2.COLOR_GRAY2BGR)
    cv2.imwrite('all_markers.png',canvas)


    if __name__ == '__main__':
    write_all_markers_png(2000)
    write_marker_png(8,800)
    47 changes: 47 additions & 0 deletions mouse_control.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,47 @@
    import zmq
    from pymouse import PyMouse

    #mouse setup
    m = PyMouse()
    x_dim, y_dim = m.screen_size()

    #network setup
    context = zmq.Context()
    socket = context.socket(zmq.SUB)
    socket.connect("tcp://127.0.0.1:5000")
    #filter by messages by stating string 'STRING'. '' receives all messages
    socket.setsockopt(zmq.SUBSCRIBE, '')
    smooth_x, smooth_y= 0.5, 0.5

    while True:
    msg = socket.recv()
    items = msg.split("\n")
    msg_type = items.pop(0)
    items = dict([i.split(':') for i in items[:-1] ])
    if msg_type == 'Pupil':
    try:
    my_gaze = items['norm_gaze']

    if my_gaze != "None":
    raw_x,raw_y = map(float,my_gaze[1:-1].split(','))

    # smoothing out the gaze so the mouse has smoother movement
    smooth_x += 0.5 * (raw_x-smooth_x)
    smooth_y += 0.5 * (raw_y-smooth_y)

    x = smooth_x
    y = smooth_y

    y = 1-y # inverting y so it shows up correctly on screen
    x *= x_dim
    y *= y_dim
    # PyMouse or MacOS bugfix - can not go to extreme corners because of hot corners?
    x = min(x_dim-10, max(10,x))
    y = min(y_dim-10, max(10,y))

    m.move(x,y)
    except KeyError:
    pass
    else:
    # process non gaze position events from plugins here
    pass
    38 changes: 0 additions & 38 deletions pupil_test_tcp_broadcast.py
    Original file line number Diff line number Diff line change
    @@ -1,38 +0,0 @@
    """
    Broadcast dummy Pupil stream over TCP
    used for debugging and
    """

    import zmq
    from ctypes import create_string_buffer
    from time import sleep
    import random

    def test_msg():
    dummy_data = str((random.random(),random.random()))
    test_msg = "Pupil\nconfidence:0.695435635564\nnorm_gaze:"+dummy_data+"\n"+\
    "apparent_pupil_size:41.609413147\nnorm_pupil:(0.76884605884552, 0.35504735310872393)\ntimestamp:1389761135.56\n"
    return test_msg

    def main():
    port = "5000"
    context = zmq.Context()
    socket = context.socket(zmq.PUB)
    address = create_string_buffer("tcp://127.0.0.1:"+port,512)

    try:
    socket.bind(address.value)
    except zmq.ZMQError:
    print "Could not set Socket."

    for i in range(30):
    # send 30 samples and sleep for half a second
    socket.send( test_msg() )
    sleep(0.5)


    context.destroy()


    if __name__ == '__main__':
    main()
    32 changes: 0 additions & 32 deletions pupil_test_tcp_receiver.py
    Original file line number Diff line number Diff line change
    @@ -1,32 +0,0 @@
    """
    Receive data from Pupil server broadcast over TCP
    test script to see what the stream looks like
    and for debugging
    """
    import zmq

    #network setup
    port = "5000"
    context = zmq.Context()
    socket = context.socket(zmq.SUB)
    socket.connect("tcp://127.0.0.1:"+port)
    #filter by messages by stating string 'STRING'. '' receives all messages
    socket.setsockopt(zmq.SUBSCRIBE, '')

    while True:
    msg = socket.recv()
    print "raw msg:\n", msg

    items = msg.split("\n")
    msg_type = items.pop(0)
    items = dict([i.split(':') for i in items[:-1] ])

    if msg_type == 'Pupil':
    try:
    print "norm_gaze: ", items['norm_gaze']

    except KeyError:
    pass
    else:
    # process non gaze position events from plugins here
    pass
    11 changes: 11 additions & 0 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    # Mouse Control
    This is my modification of the [original script](https://gist.github.com/willpatera/7908319#file-stream_gaze_coords-py) so you don't need to enable Marker Tracking or define surfaces. You simply need to start the Coordinates Streaming Server and run this independent script.

    **Note:** Not using Surfaces and Marker Tracking decreases the accuracy of pointer movement. This won't work well enough because `norm_gaze` data is being used instead of your surface gaze data.

    You need `PyMouse` and `Xlib` installed:

    ```
    $ sudo pip install pymouse
    $ sudo apt-get install python-xlib
    ```
    30 changes: 0 additions & 30 deletions stream_gaze_and_pupil_apparent.py
    Original file line number Diff line number Diff line change
    @@ -1,30 +0,0 @@
    """
    Receive data from Pupil server broadcast over TCP
    test script to see what the stream looks like
    and for debugging
    """
    import zmq

    #network setup
    port = "5000"
    context = zmq.Context()
    socket = context.socket(zmq.SUB)
    socket.connect("tcp://127.0.0.1:"+port)
    #filter by messages by stating string 'STRING'. '' receives all messages
    socket.setsockopt(zmq.SUBSCRIBE, '')

    while True:
    msg = socket.recv()

    items = msg.split("\n")
    msg_type = items.pop(0)
    items = dict([i.split(':') for i in items[:-1] ])

    if msg_type == 'Pupil':
    try:
    print "norm_gaze:\t%s\napparent_pupil_size:\t%s" %(items['norm_gaze'], items['apparent_pupil_size'])
    except KeyError:
    pass
    else:
    # process non gaze position events from plugins here
    pass
    51 changes: 0 additions & 51 deletions stream_gaze_coords.py
    Original file line number Diff line number Diff line change
    @@ -1,51 +0,0 @@
    """
    Stream Pupil gaze coordinate data using zmq to control a mouse with your eye.
    Please note that marker tracking must be enabled, and in this example we have named the surface "screen."
    You can name the surface what you like in Pupil capture and then write the name of the surface you'd like to use on line 17.
    """
    import zmq
    from pymouse import PyMouse

    #mouse setup
    m = PyMouse()
    x_dim, y_dim = m.screen_size()

    #network setup
    context = zmq.Context()
    socket = context.socket(zmq.SUB)
    socket.connect("tcp://127.0.0.1:5000")
    #filter by messages by stating string 'STRING'. '' receives all messages
    socket.setsockopt(zmq.SUBSCRIBE, '')
    smooth_x, smooth_y= 0.5, 0.5

    surface_name = "screen"
    while True:
    msg = socket.recv()
    items = msg.split("\n")
    msg_type = items.pop(0)
    items = dict([i.split(':') for i in items[:-1] ])
    if msg_type == 'Pupil':
    try:
    gaze_on_screen = items["realtime gaze on "+surface_name]
    raw_x,raw_y = map(float,gaze_on_screen[1:-1].split(','))

    # smoothing out the gaze so the mouse has smoother movement
    smooth_x += 0.5 * (raw_x-smooth_x)
    smooth_y += 0.5 * (raw_y-smooth_y)

    x = smooth_x
    y = smooth_y

    y = 1-y # inverting y so it shows up correctly on screen
    x *= x_dim
    y *= y_dim
    # PyMouse or MacOS bugfix - can not go to extreme corners because of hot corners?
    x = min(x_dim-10, max(10,x))
    y = min(y_dim-10, max(10,y))

    m.move(x,y)
    except KeyError:
    pass
    else:
    # process non gaze position events from plugins here
    pass
  9. @willpatera willpatera revised this gist Mar 20, 2014. 1 changed file with 2 additions and 3 deletions.
    5 changes: 2 additions & 3 deletions stream_gaze_and_pupil_apparent.py
    Original file line number Diff line number Diff line change
    @@ -15,15 +15,14 @@

    while True:
    msg = socket.recv()
    print "raw msg:\n", msg


    items = msg.split("\n")
    msg_type = items.pop(0)
    items = dict([i.split(':') for i in items[:-1] ])

    if msg_type == 'Pupil':
    try:
    print "norm_gaze: %03f\napparent_pupil_size: %03f" %(items['norm_gaze'], items['apparent_pupil_size'])
    print "norm_gaze:\t%s\napparent_pupil_size:\t%s" %(items['norm_gaze'], items['apparent_pupil_size'])
    except KeyError:
    pass
    else:
  10. @willpatera willpatera revised this gist Mar 20, 2014. 1 changed file with 31 additions and 0 deletions.
    31 changes: 31 additions & 0 deletions stream_gaze_and_pupil_apparent.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,31 @@
    """
    Receive data from Pupil server broadcast over TCP
    test script to see what the stream looks like
    and for debugging
    """
    import zmq

    #network setup
    port = "5000"
    context = zmq.Context()
    socket = context.socket(zmq.SUB)
    socket.connect("tcp://127.0.0.1:"+port)
    #filter by messages by stating string 'STRING'. '' receives all messages
    socket.setsockopt(zmq.SUBSCRIBE, '')

    while True:
    msg = socket.recv()
    print "raw msg:\n", msg

    items = msg.split("\n")
    msg_type = items.pop(0)
    items = dict([i.split(':') for i in items[:-1] ])

    if msg_type == 'Pupil':
    try:
    print "norm_gaze: %03f\napparent_pupil_size: %03f" %(items['norm_gaze'], items['apparent_pupil_size'])
    except KeyError:
    pass
    else:
    # process non gaze position events from plugins here
    pass
  11. @willpatera willpatera revised this gist Jan 15, 2014. 2 changed files with 70 additions and 0 deletions.
    38 changes: 38 additions & 0 deletions pupil_test_tcp_broadcast.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,38 @@
    """
    Broadcast dummy Pupil stream over TCP
    used for debugging and
    """

    import zmq
    from ctypes import create_string_buffer
    from time import sleep
    import random

    def test_msg():
    dummy_data = str((random.random(),random.random()))
    test_msg = "Pupil\nconfidence:0.695435635564\nnorm_gaze:"+dummy_data+"\n"+\
    "apparent_pupil_size:41.609413147\nnorm_pupil:(0.76884605884552, 0.35504735310872393)\ntimestamp:1389761135.56\n"
    return test_msg

    def main():
    port = "5000"
    context = zmq.Context()
    socket = context.socket(zmq.PUB)
    address = create_string_buffer("tcp://127.0.0.1:"+port,512)

    try:
    socket.bind(address.value)
    except zmq.ZMQError:
    print "Could not set Socket."

    for i in range(30):
    # send 30 samples and sleep for half a second
    socket.send( test_msg() )
    sleep(0.5)


    context.destroy()


    if __name__ == '__main__':
    main()
    32 changes: 32 additions & 0 deletions pupil_test_tcp_receiver.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,32 @@
    """
    Receive data from Pupil server broadcast over TCP
    test script to see what the stream looks like
    and for debugging
    """
    import zmq

    #network setup
    port = "5000"
    context = zmq.Context()
    socket = context.socket(zmq.SUB)
    socket.connect("tcp://127.0.0.1:"+port)
    #filter by messages by stating string 'STRING'. '' receives all messages
    socket.setsockopt(zmq.SUBSCRIBE, '')

    while True:
    msg = socket.recv()
    print "raw msg:\n", msg

    items = msg.split("\n")
    msg_type = items.pop(0)
    items = dict([i.split(':') for i in items[:-1] ])

    if msg_type == 'Pupil':
    try:
    print "norm_gaze: ", items['norm_gaze']

    except KeyError:
    pass
    else:
    # process non gaze position events from plugins here
    pass
  12. @willpatera willpatera revised this gist Dec 11, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion Pupil_tools.md
    Original file line number Diff line number Diff line change
    @@ -1,2 +1,2 @@
    # Pupil Tools
    This is a small collection of tools that we use with [Pupil](www.github.com/pupil-labs/pupil "pupil repository"). The tools are not part of the main repository, as they are mostly stand-alone connivence scripts.
    This is a small collection of tools that we use with [Pupil](www.github.com/pupil-labs/pupil "pupil repository"). The tools are not part of the main repository, as they are mostly stand-alone convenience scripts.
  13. @willpatera willpatera revised this gist Dec 11, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion Pupil_tools.md
    Original file line number Diff line number Diff line change
    @@ -1,2 +1,2 @@
    # Pupil Tools
    This is a small collection of tools that we use with [Pupil](www.github.com/pupil-labs/pupil "pupil repository"). The tools are not part of the main repository, as they are mostly stand-alone convience scripts.
    This is a small collection of tools that we use with [Pupil](www.github.com/pupil-labs/pupil "pupil repository"). The tools are not part of the main repository, as they are mostly stand-alone connivence scripts.
  14. @willpatera willpatera revised this gist Dec 11, 2013. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions make_square_markers.py
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,6 @@
    """
    Make square markers is a helper script that is used to generate 5x5 square marker png files that can be printed.
    """
    import cv2
    import numpy as np

  15. @willpatera willpatera revised this gist Dec 11, 2013. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions stream_gaze_coords.py
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,8 @@
    """
    Stream Pupil gaze coordinate data using zmq to control a mouse with your eye.
    Please note that marker tracking must be enabled, and in this example we have named the surface "screen."
    You can name the surface what you like in Pupil capture and then write the name of the surface you'd like to use on line 17.
    """
    import zmq
    from pymouse import PyMouse

  16. @willpatera willpatera revised this gist Dec 11, 2013. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions Pupil_tools.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,2 @@
    # Pupil Tools
    This is a small collection of tools that we use with [Pupil](www.github.com/pupil-labs/pupil "pupil repository"). The tools are not part of the main repository, as they are mostly stand-alone convience scripts.
  17. @willpatera willpatera revised this gist Dec 11, 2013. 1 changed file with 74 additions and 0 deletions.
    74 changes: 74 additions & 0 deletions make_square_markers.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,74 @@
    import cv2
    import numpy as np

    def encode_marker(mId):
    marker_id_str = "%02d"%mId
    # marker is based on grid of black (0) /white (1) pixels
    # b|b|b|b|b
    # b|o|m|o|b b = black border feature
    # b|m|m|m|b o = orientation feature
    # b|o|m|o|b m = message feature
    # b|b|b|b|b
    grid = 5
    m_with_b = np.zeros((grid,grid),dtype=np.uint8)
    m = m_with_b[1:-1,1:-1]

    #bitdepth = grid-border squared - 3 for orientation (orientation still yields one bit)
    bitdepth = ((5-2)**2)-3

    if mId>=(2**bitdepth):
    raise Exception("ERROR: ID overflow, this marker can only hold %i bits of information" %bitdepth)

    msg = [0]*bitdepth
    for i in range(len(msg))[::-1]:
    msg[i] = mId%2
    mId = mId >>1

    # out first bit is encoded in the orientation corners of the marker:
    # MSB = 0 MSB = 1
    # W|*|*|W ^ B|*|*|B ^
    # *|*|*|* / \ *|*|*|* / \
    # *|*|*|* | UP *|*|*|* | UP
    # B|*|*|W | W|*|*|B |

    msb = msg.pop(0)
    if msb:
    orientation = 0,1,0,0
    else:
    orientation = 1,0,1,1

    m[0,0], m[-1,0], m[-1,-1], m[0,-1] = orientation

    msg_mask = np.ones(m.shape,dtype=np.bool)
    msg_mask[0,0], msg_mask[-1,0], msg_mask[-1,-1], msg_mask[0,-1] = 0,0,0,0
    m[msg_mask] = msg[::-1]

    # print "Marker: \n", m_with_b
    return m_with_b

    def write_marker_png(mId,size):
    marker_id_str = "%02d"%mId
    m = encode_marker(mId)*255
    m = cv2.resize(m,(size,size),interpolation=cv2.INTER_NEAREST)
    m = cv2.cvtColor(m,cv2.COLOR_GRAY2BGR)
    cv2.imwrite('marker '+marker_id_str+'.png',m)


    def write_all_markers_png(size):
    rows,cols,m_size = 8,8,7
    canvas = np.ones((m_size*rows,m_size*cols),dtype=np.uint8)
    for mid in range(64):
    marker_with_padding = np.ones((7,7))
    marker_with_padding[1:-1,1:-1] = encode_marker(mid)
    m_size = marker_with_padding.shape[0]
    r = (mid%rows) * m_size
    c = (mid/cols) * m_size
    canvas[r:r+m_size,c:c+m_size] = marker_with_padding*255
    canvas = cv2.resize(canvas,(size,size),interpolation=cv2.INTER_NEAREST)
    canvas = cv2.cvtColor(canvas,cv2.COLOR_GRAY2BGR)
    cv2.imwrite('all_markers.png',canvas)


    if __name__ == '__main__':
    write_all_markers_png(2000)
    write_marker_png(8,800)
  18. @willpatera willpatera revised this gist Dec 11, 2013. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion stream_gaze_coords.py
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,5 @@
    import zmq
    from pymouse import PyMouse
    from time import sleep

    #mouse setup
    m = PyMouse()
  19. @willpatera willpatera created this gist Dec 11, 2013.
    47 changes: 47 additions & 0 deletions stream_gaze_coords.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,47 @@
    import zmq
    from pymouse import PyMouse
    from time import sleep

    #mouse setup
    m = PyMouse()
    x_dim, y_dim = m.screen_size()

    #network setup
    context = zmq.Context()
    socket = context.socket(zmq.SUB)
    socket.connect("tcp://127.0.0.1:5000")
    #filter by messages by stating string 'STRING'. '' receives all messages
    socket.setsockopt(zmq.SUBSCRIBE, '')
    smooth_x, smooth_y= 0.5, 0.5

    surface_name = "screen"
    while True:
    msg = socket.recv()
    items = msg.split("\n")
    msg_type = items.pop(0)
    items = dict([i.split(':') for i in items[:-1] ])
    if msg_type == 'Pupil':
    try:
    gaze_on_screen = items["realtime gaze on "+surface_name]
    raw_x,raw_y = map(float,gaze_on_screen[1:-1].split(','))

    # smoothing out the gaze so the mouse has smoother movement
    smooth_x += 0.5 * (raw_x-smooth_x)
    smooth_y += 0.5 * (raw_y-smooth_y)

    x = smooth_x
    y = smooth_y

    y = 1-y # inverting y so it shows up correctly on screen
    x *= x_dim
    y *= y_dim
    # PyMouse or MacOS bugfix - can not go to extreme corners because of hot corners?
    x = min(x_dim-10, max(10,x))
    y = min(y_dim-10, max(10,y))

    m.move(x,y)
    except KeyError:
    pass
    else:
    # process non gaze position events from plugins here
    pass