【題外話】php
Eyelink眼動儀是SR Research推出的一款眼動儀,不少高校都在使用其作實驗。其官方提供了COM的接口,因此支持COM接口的開發平臺均可以開發使用。官方甚至提供了一個C#的樣例供參考,不過這個樣例相比起其餘的VC++的樣例而言功能過於簡單,程序自己也比較亂,再加上國內關於EyeLink的資料又比較少,因此這裏我簡要寫下我使用EyeLink眼動儀的開發框架,方便你們開發。html
本文地址:http://www.cnblogs.com/mayswind/p/3417211.html程序員
【文章索引】框架
雖然SR Research提供的大多數樣例都是基於VC++的,但因爲C#開發快速高效,同時在實現複雜功能時C#更容易開發,因此我仍是選擇了使用C#開發實驗程序,而不是VC++。SR Research比較有意思的是,官方雖然提供了全部的說明文檔以及開發工具包,可是這些都須要從官網的論壇才能夠下載,並且官網論壇的註冊是須要人工審覈的,因此註冊必定千萬不要着急。好在審覈也不會慢,去除時差的緣由沒有多久就能經過審覈。工具
註冊完成之後,首先須要下載開發工具包,該工具包裏包括了SDK文件以及幾個說明文檔還有幾個示例程序。地址見下:開發工具
https://www.sr-support.com/showthread.php?6-Windows-Display-Software測試
程序員開發手冊(EyeLink Programmers Guide.pdf)就在安裝後的目錄中的Docs中,雖然是C語言版本的並且也不是使用的COM接口,但對於瞭解SDK仍是有幫助的。固然也能夠單獨下載,地址見下:ui
https://www.sr-support.com/showthread.php?4-EyeLink-C-Programmers-Guidesthis
全部的自帶樣例程序都在安裝目錄下的SampleExperiments目錄,COM接口的都在com目錄下,其中還有一個C#的樣例程序。而EyeLink提供的COM接口文件位於Libs目錄下,文件名爲「SREyeLink.dll」,直接在C#裏引用便可。
通常使用EyeLink進行實驗的都要遵循如下的流程:
一、程序開始界面,可能介紹本實驗的狀況及提示接下來按什麼鍵進入實驗等等。
二、通常正式進入實驗流程後首先按C鍵進入Calibration界面進行眼睛的校準,通常爲9點校準(能夠自行設置),若是一個點校準失敗會在全部點校準後從新校準。
三、眼睛校準成功後按V鍵進入Validation界面進行剛纔校準結果的驗證。
四、驗證成功後開始實驗,一個實驗可能有多個Trail組成,在全部Trial以前或每一個Trial以前可能須要Drift使受試者注視屏幕中心(位置可自定義)以繼續。
五、若是有多個Trial將依次執行。
EyeLink提供的COM接口整體仍是很友好的,常見的有如下幾個類:
一、EyeLink:與EyeLink操做主要的類,提供鏈接Host PC、建立EDF文件、向Host PC發送命令和向EDF中記錄信息等等,常見的方法以下:
方法名 | 含義 |
void open("Host PC IP", 0); | 鏈接到指定Host PC,Host PC IP一般爲100.1.1.1 |
void close(); | 關閉指定鏈接 |
void openDataFile("fileName"); | 在Host PC建立指定文件名的EDF文件以供記錄 |
void receiveDataFile("fileName", "localPath"); | 將Host PC記錄的指定文件名的EDF傳回到本地路徑 |
void startRecording(true, true, true, true); | 開始記錄注視點信息(四個選項能夠設置是否記錄指定內容) |
void stopRecording(); | 結束記錄注視點信息 |
bool isRecording(); | 獲取是否正在記錄注視點信息 |
void sendCommand("command"); | 向Host PC發送指定的指令 |
void sendMessage("message"); | 向Host PC發送指定的信息,記錄在EDF文件中 |
void doTrackerSetup(); | 進入實驗流程,容許用戶按C和V執行相應操做或按Enter顯示鏡頭內容 |
void doDriftCorrect(x, y, true, true); | 要求受試者看住指定的(x, y)點以繼續 |
void setOfflineMode(); | Host PC進入Offline Mode,一般實驗結束後要執行該操做 |
short eyeAvailable(); | 獲取攝像頭跟蹤到的眼睛(能夠轉換爲EL_EYE枚舉) |
short getLastButtonPress(out pressTime); | 獲取按鍵信息(好比能夠獲取鏈接在Host PC上的手柄的按鍵) |
Sample getNewestSample(); | 獲取注視點信息 |
二、EyeLinkUtil:提供了幾個經常使用工具方法,如提供當前時間、進入實時模式等等。
方法名 | 含義 |
void beginRealTimeMode(time); | 開始指定時間(毫秒)的實時模式 |
void endRealTimeMode(); | 結束實時模式 |
double currentTime(); | 獲取當前時間(毫秒) |
ELGDICal getGDICal(); | 獲取EyeLink GDICal |
三、ELGDICal:經過將窗口的Handle傳給該類,實現由EyeLink SDK控制直接在界面上繪製Calibration、Validation以及Drift等界面,同時開發者也能夠直接在界面線程上執行邏輯或繪製相應內容,而無需擔憂界面無響應而建立子線程等等。
方法名 | 含義 |
void setCalibrationColors(foreColor, backColor); | 設置Calibration、Validation、Drift等界面的前景色和背景色 |
void setCalibrationWindow(hWnd); | 設置上述界面的窗口Handle |
void enableKeyCollection(true/false); | 設置是否容許經過鍵盤控制EyeLink SDK操做(如C、V、Enter) |
EyeLink基本使用很是簡單,就如同給出的C#的樣例同樣,在這裏給出一個簡單的使用,好比直接在界面線程上執行代碼(this這裏就是指當前窗體):
1 EyeLink eyeLink = new EyeLink();//建立EyeLink對象 2 eyeLink.open("100.1.1.1", 0);//鏈接到Host PC 3 eyeLink.openDataFile("test.edf");//在Host PC建立指定文件名的EDF以供記錄 4 eyeLink.sendCommand("file_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,MESSAGE,BUTTON");//設置事件或記錄的內容,下同 5 eyeLink.sendCommand("file_sample_data = LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS"); 6 eyeLink.sendCommand("link_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,BUTTON"); 7 eyeLink.sendCommand("link_sample_data = LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS"); 8 eyeLink.sendMessage(String.Format("DISPLAY_COORDS {0} {1} {2} {3}", this.Left, this.Top, this.Width, this.Height));//設置窗口的範圍 9 10 EyeLinkUtil eyeLinkUtil = new EyeLinkUtil();//建立EyeLinkUtil對象 11 ELGDICal gdiCal = eyeLinkUtil.getGDICal();//建立EyeLinkGDICal對象 12 13 gdiCal.setCalibrationWindow(this.Handle.ToInt32());//將窗體句柄傳給EyeLink SDK 14 gdiCal.enableKeyCollection(true); 15 eyeLink.doTrackerSetup();//開始進行設置階段(Calibration、Vadation等) 16 gdiCal.enableKeyCollection(false); 17 18 gdiCal.enableKeyCollection(true); 19 eyeLink.doDriftCorrect((Int16)(this.Width / 2), (Int16)(this.Height / 2), true, true);//全部Trial前或每一個Trial前讓受試者注視指定位置以開始Trial 20 gdiCal.enableKeyCollection(false); 21 22 eyeLink.startRecording(true, true, true, true);//開始記錄EDF文件 23 Double st = eyeLinkUtil.currentTime(); 24 25 while ((st + 20000) > eyeLinkUtil.currentTime())//循環20秒程序結束 26 { 27 EL_EYE eyeUsed = (EL_EYE)eyeLink.eyeAvailable();//獲取當前眼睛使用狀況 28 Sample sample = eyeLink.getNewestSample();//獲取當前注視點 29 30 if (sample == null || eyeUsed == EL_EYE.EL_EYE_NONE) 31 { 32 continue; 33 } 34 35 if (eyeUsed == EL_EYE.EL_BINOCULAR) 36 { 37 eyeUsed = EL_EYE.EL_LEFT;//若是兩隻眼睛同時被捕捉到則使用左眼 38 } 39 40 Single x = sample.get_gx(eyeUsed);//獲取注視點相對窗口的橫座標 41 Single y = sample.get_gy(eyeUsed);//獲取注視點相對窗口的縱座標 42 Single pa = sample.get_pa(eyeUsed);//獲取瞳孔大小 43 44 if (x == (Single)EL_CONSTANT.EL_MISSING_DATA || y == (Single)EL_CONSTANT.EL_MISSING_DATA || pa <= 0) 45 { 46 continue; 47 } 48 49 //TODO: 在這裏處理x、y座標等 50 } 51 52 eyeLink.sendCommand("close_data_file");//關閉Host PC上的EDF文件 53 eyeLink.receiveDataFile("test.edf", "本機文件路徑");//將Host PC上的EDF文件傳回到測試機 54 55 eyeLink.setOfflineMode();//將Host PC設置爲離線狀態(非實驗進行狀態) 56 eyeLink.stopRecording();//結束記錄EDF文件 57 eyeLink.close();//關閉與Host PC的鏈接 58 59 eyeLink = null; 60 eyeLinkUtil = null;
有了上述這些還不夠,好比:
一、雖然上述咱們能記錄EDF文件,可是若是有多個Trial的話咱們還但願能在EDF文件中予以區分。因此在每一個Trial先後咱們還須要這樣去作:
1 eyeLink.sendCommand(String.Format("record_status_message 'TRIAL {0}'", trialIndex)); 2 eyeLink.sendMessage(String.Format("TRIALID {0}", trialIndex)); 3 eyeLink.startRecording(true, true, true, true); 4 5 //Trial邏輯 6 7 eyeLink.stopRecording();
二、若是咱們在Trial中顯示了圖片,同時咱們但願EDF Viewer在查看時也能將對應的圖片顯示出來,那麼咱們還須要在startRecording以前執行這樣一句話,去讓EDF Viewer打開指定路徑下的圖片。
1 eyeLink.sendMessage(String.Format("!V IMGLOAD FILL {0}", imagePath));
三、若是咱們但願受測者可以使用按鍵進行Trial的操做(好比按某鍵表示完成或跳過該Trial之類的),咱們還須要獲取按鍵的信息,其中若是咱們還須要在EDF文件中顯示出按鍵的狀況,咱們還須要向Host PC發送一條信息(下列代碼中第6行)。
1 Double pressTime = 0; 2 Int16 buttonCode = eyeLink.getLastButtonPress(out pressTime); 3 4 if (buttonCode != 0) 5 { 6 eyeLink.sendMessage(String.Format("ENDBUTTON {0}", buttonCode)); 7 //TODO: 執行相關按鍵的邏輯 8 }
四、若是咱們但願在Drift的過程當中,受測者在將眼睛注視到指定的點後還須要按指定的鍵才能繼續的話,咱們還須要在開始的配置過程當中寫以下的代碼(這裏使用的是按鍵5):
1 eyeLink.sendCommand("button_function 5 'accept_target_fixation'");
附一個我寫的C#上使用EyeLink的框架(MIT LICENSE):http://files.cnblogs.com/mayswind/DotMaysWind.EyeLink.rar
【相關連接】
一、SR Research Support Site:https://www.sr-support.com/forums/