Ubuntu下使用Tobii Eye Tracker 4C眼动仪控制鼠标光标

之前成功在 Ubuntu 下使用了 4C 眼动仪,但是不知道什么原因目前无法使用 TobiiProEyeTrackerManager 软件来进行眼动仪的标定,也就无法使用它的 gaze visualization 功能来查看注视点的位置。虽然程序里可以输出注视点的归一化坐标,但是这样还是不直观,所以尝试了一下用 tobii 检测到的注视点位置来控制鼠标光标的位置。

除了之前那个 github 工程,还参考了这个工程: https://github.com/lhy0403/TobiiMouse.讲道理这个应该可以直接用的,不过调通后怎么也检测不到设备,所以将其中控制鼠标的部分提出来和之前的结合。

其中和鼠标控制有关的部分在 mouse_integrationnoise_cancellation
在主函数一开始添加

MouseIntegration::init();//get the width and height of current screen
MouseIntegration::SetWorkingMode(TOBII_MOUSE_MODE_ABSOLUTE);

gaze_point_callback 中添加

MouseIntegration::OnGaze(gaze_point->position_xy[0], gaze_point->position_xy[1]);

mouse_integration 如下, noise_cancellation 没有改
mouse_integration.h

#ifndef MOUSE_INTEGRATION_H
#define MOUSE_INTEGRATION_H

#include <tuple>
//#include "tobiimouse.h"
#include "noise_cancellation.h"


#include <X11/X.h>
#include "X11/Xlib.h"
#include <X11/extensions/Xrandr.h>


using namespace std;

enum MOUSEWORKINGMODE_E{
    TOBII_MOUSE_MODE_ABSOLUTE,
    TOBII_MOUSE_MODE_MOVE_BY_POSITION,
};

namespace MouseIntegration
{
    void SetWorkingMode(MOUSEWORKINGMODE_E mode);
    void init();
    void MoveMouseTo(int x, int y);
    void MoveMouseOffset(int x, int y);
    tuple<int, int> ProcessGazePosition(float x, float y);
    void OnGaze(float x, float y);


};

#endif // MOUSE_INTEGRATION_H

mouse_integration.cpp

#include "mouse.h"
#include <iostream>
#include <vector>

namespace MouseIntegration
{
    static MOUSEWORKINGMODE_E WorkingMode;
    static int ScreenHeight;
    static int ScreenWidth;

    static int LastX;
    static int LastY;

    static Display* _display;
    static Window _root_window;
}

void MouseIntegration::init()
{
    NoiseCancellation::init();//used to filter the data
    // TODO: Multiple Display supports.
    _display = XOpenDisplay(None);
    _root_window = XRootWindow(_display, 0);
    XRRScreenResources *screens = XRRGetScreenResources(_display, DefaultRootWindow(_display));
    XRRCrtcInfo *info = XRRGetCrtcInfo(_display, screens, screens->crtcs[0]);
    ScreenWidth = info->width;
    ScreenHeight = info->height;
    XRRFreeCrtcInfo(info);
    XRRFreeScreenResources(screens);
}


void MouseIntegration::MoveMouseTo(int x, int y)
{
    XSelectInput(_display, _root_window, KeyReleaseMask);
    XWarpPointer(_display, None, _root_window, 0, 0, 0, 0, x, y);
    XFlush(_display);
}

void MouseIntegration::SetWorkingMode(MOUSEWORKINGMODE_E mode)
{
    WorkingMode = mode;
}

tuple<int, int> MouseIntegration::ProcessGazePosition(float x, float y)
{
    float width = ScreenWidth;
    float height = ScreenHeight;

    auto realGazeX = width * x;
    auto realGazeY = height * y;

    auto filtered = NoiseCancellation::CancelNoise(realGazeX,realGazeY);
    //auto count = ScreenCount(_display); //Get total screen count.
    float gazeX_f = get<0>(filtered);
    float gazeY_f = get<1>(filtered);


    return tuple<int, int>(static_cast<int>(gazeX_f), static_cast<int>(gazeY_f));
}

void MouseIntegration::OnGaze(float x, float y)
{
    auto data = ProcessGazePosition(x,y);
    auto posiX = get<0>(data);
    auto posiY = get<1>(data);

    switch (WorkingMode) {
    case TOBII_MOUSE_MODE_ABSOLUTE:
        MoveMouseTo(posiX, posiY);
        break;
    case TOBII_MOUSE_MODE_MOVE_BY_POSITION:
        MoveMouseOffset(posiX, posiY);
        break;
    }
    LastX = posiX;
    LastY = posiY;
}

使用的 IDE 是 Qt Creator,工程的 pro 文件如下

TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt

SOURCES += main.cpp\
            mouse_integration.cpp\
            noise_cancellation.cpp

HEADERS +=mouse_integration.h\
            noise_cancellation.h


LIBS += -L$$PWD/lib/lib/x64/ -ltobii_stream_engine
LIBS += -L$$/lib/x86_64-linux-gnu/ -lpthread
LIBS += -L$$/usr/lib/x86_64-linux-gnu/ -lX11
LIBS += -L$$/usr/lib/x86_64-linux-gnu/ -lXrandr

开始编译的时候会出现链接库找不到的问题,主要是因为用到了 X11 这个库,但是没有链接,可以通过

locate libX11 libXrandr

找到 libX11libXrandr 的位置,然后在 pro 文件中加上链接库的位置即可。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值