目前有幾個方案,在下面:
1.電極式眼動追蹤:這種技術通過在眼球周圍放置電極來測量眼睛的運動。它可以提供非常高的準確性和分辨率,但需要接觸眼球,因此不太適合長時間使用或需要無接觸測量的應用場景。2.紅外線眼動追蹤:這種技術使用紅外線攝像機來觀察眼睛的位置和運動。由于它不需要接觸眼球,因此非常適合長時間使用和需要無接觸測量的應用場景。它的準確性和分辨率通常比電極式眼動追蹤低。3.磁共振眼動追蹤:這種技術使用磁共振成像來測量眼球的位置和運動。它可以提供非常高的空間分辨率,但時間分辨率較低,因此不太適合研究快速眼動的過程。4.可穿戴式眼動追蹤:這種技術使用小型傳感器或攝像頭,可以放置在眼鏡或頭盔上,可以隨身攜帶,適用于移動應用場景。但是由于可穿戴設備的尺寸和重量限制,其準確性和分辨率通常較低。5.視網(wǎng)膜追蹤:這種技術利用視網(wǎng)膜圖像來跟蹤眼球的位置和運動。它可以提供非常高的準確性和分辨率,但只能在特定的實驗條件下使用,例如黑暗環(huán)境下觀察單一的點光源。以我目前念的這個書,我還是用視覺方案來實現(xiàn):
1.特征提?。哼x擇適當?shù)奶卣鱽砻枋鲅劬Φ男螤睢㈩伾?、紋理等信息。例如,可以使用Haar級聯(lián)檢測器來提取眼睛的輪廓特征,或者使用顏色分布模型來提取眼球的顏色特征。這步主要是傳統(tǒng)的2.目標檢測:使用機器學習或計算機視覺技術來檢測眼睛的位置和方向。因為直接目標檢測是識別不準的,現(xiàn)實太復雜了。可以使用級聯(lián)分類器或支持向量機(SVM)來識別眼睛的位置和方向,或者使用卷積神經(jīng)網(wǎng)絡(CNN)來分類眼動類型。3.跟蹤和估計:根據(jù)檢測結果,使用跟蹤和估計算法來跟蹤眼睛的位置和運動軌跡。在捕捉的基礎上開始進行跟蹤,持續(xù)的來捕獲。使用卡爾曼濾波器或粒子濾波器來估計眼睛的位置和速度,或者使用光流算法來估計眼球的運動軌跡。4.數(shù)據(jù)分析:根據(jù)眼動追蹤的結果,進行數(shù)據(jù)分析和可視化??梢杂嬎阕⒁朁c的位置、持續(xù)時間和注視次數(shù)等統(tǒng)計信息,或者使用熱力圖和軌跡圖來可視化眼動數(shù)據(jù)。這個也是這次要寫的一個點。我們在這里主要是直接給出ROI的區(qū)域減少算力。
在預處理步驟中,使用了高斯平滑和邊緣檢測來增強圖像特征
在特征提取步驟中,使用了霍夫圓變換來檢測圓形區(qū)域
在目標檢測步驟中,找到最大的圓形區(qū)域作為眼球,并在圖像中標記出來
太簡單了家人們!
但是這個程序太簡單了,就是一個找特征啥的,有點傻。這次換個庫:
Dlib是一個C++編寫的機器學習庫,提供了用于人臉檢測、關鍵點檢測、姿態(tài)估計等任務的算法,其中也包括用于眼動追蹤的算法。Dlib同樣也提供了Python接口,可以在Python中使用Dlib的算法實現(xiàn)眼動追蹤。dlib提供一個方法可將人臉圖片數(shù)據(jù)映射到128維度的空間向量,如果兩張圖片來源于同一個人,那么兩個圖片所映射的空間向量距離就很近,否則就會很遠。因此,可以通過提取圖片并映射到128維空間向量再度量它們的歐氏距離(Euclidean distance)是否足夠小來判定是否為同一個人。我不要人我就要眼睛。
上次覺得CMake礙眼,卸載了
稍等不知道多久,反正我吃了個橘子
python.exe -m pip install --upgrade pip
更新一下
安裝成功了
這個就是里面的dat文件,68個關鍵點
先找臉,再找眼,合理!
簡單的轉(zhuǎn)下顏色,然后直接找
dlib 庫提供了兩個用于人臉檢測的功能。
第一個是HOG+線性SVM人臉檢測器,另一個是深度學習MMOD CNN人臉檢測器。
反正就是找一下面部的區(qū)域:
這些代碼是再找眼部的位置
在范圍之內(nèi)就可以了
有極值坐標嘎嘎算
接著進一步給出瞳孔的坐標
2.0~8.0mm之間瞳孔大小是指虹膜中央的一圓孔的直徑,受光線、年齡、人種、屈光狀態(tài)、目標遠近和情緒等因素影響,正常范圍在2.0~8.0mm之間。瞳孔在強光下縮小,在黑暗下擴大,這是人體的正常生理反應。瞳孔大小不一致或?qū)夥磻惓?赡苁悄X部或眼部疾病的征兆。
我考你,你遇到這種情況怎么寫?
先給外圈的大圓套上
再處理瞳孔
多數(shù)情況下,我們是要實時的檢測的:
來一段從攝像頭捕獲的代碼
祖?zhèn)鞔a不能丟
更實用性的是兩個攝像頭來捕捉眼動:
這個寫的比較呆逼,不過我在后面會有進行封裝
現(xiàn)在是彈出兩個框來輸出圖像,趕緊不好看捏!我們來讓他并排排列!
使用OpenCV中的cv2.hconcat()函數(shù)將兩個視頻幀水平合并在一起,并使用cv2.imshow()函數(shù)將合并后的視頻幀顯示出來。
就很簡單,其實這里就變成一個合并橫向排列的視頻組,但是在處理流程上面有問題,應該先單一處理,最后合并結果。
封裝好啦?。ㄓ悬c傻逼哦~)
繼續(xù)封裝,注意視頻流
工程問題的話,上面的代碼還是太慢了,讓我來加一點多線程的魔法!
設計兩個線程分別處理左右眼視頻幀的讀取和合并:
隊列無疑是最合適的數(shù)據(jù)結構
合并函數(shù)也是如此,因為圖像這種處理的方式就適合隊列
這個是提前設置好的
標準的流程
這個就是線程的啟動了,然后一個循環(huán)不停的合并
也可以加一個日志的功能,直接寫到最上面就行
現(xiàn)在的程序一點也不裝逼,如果可以加一些文字什么的,就更好啦!
要把視頻流封裝成一個類,然后里面也是多線程處理
在下面調(diào)用的時候,就是實例化代碼
這里就顯示一個左眼的FPS信息疊加
代碼中,putText函數(shù)用于將幀率信息添加到視頻幀的左上角。其中,cv2.FONT_HERSHEY_SIMPLEX指定了字體類型,1指定了字體大小,(255, 255, 255)指定了字體顏色,2指定了字體線寬。
一方面顯示是可視化,另一方面我們需要保存具體的眼動數(shù)據(jù)來后處理。可以在程序中添加一個函數(shù)來提取圓形框的坐標信息,并將它們保存到一個文件中。
這個是簡單版本
eye_data 是一個包含眼動信息的列表,每個元素都是一個二元組,表示眼睛的坐標。在循環(huán)中,將每個元素寫入文件中,每個坐標之間用逗號分隔,每行結束后添加一個換行符。
假設圓形框的半徑為 r,圓心坐標為 (x, y),那么可以使用 OpenCV 中的 circle 函數(shù)來繪制圓形框。在繪制圓形框時,同時將圓心坐標和半徑信息保存到一個列表中:在每次繪制圓形框時,將圓心坐標和半徑信息添加到 eye_data 列表中。最后,可以將 eye_data 中的信息保存到一個文本文件中:
現(xiàn)在就是一個較為完善的函數(shù)了
再讓我封裝一下:
在視頻幀上繪制眼球圓形框,并返回圓形框的坐標信息
這個是信息保存的函數(shù)
目前實現(xiàn)的功能挺多的了,現(xiàn)在來寫一個GUI吧!
就兩個線程就行
初始化是捕獲線程,在run函數(shù)里面進行了顏色的轉(zhuǎn)換
使用定時器來更新幀率信息
這些都簡單
都比較簡單吧?
完整代碼我放在Github上面了。
我們拿到了保存的數(shù)據(jù),想重新把他們展示出來。假設眼動數(shù)據(jù)文件是一個文本文件,每行包含兩個數(shù)字,分別代表左右眼的坐標。
使用matplotlib庫中的plot函數(shù)來繪制左右眼的坐標。下面是一個簡單的示例代碼,繪制左眼的x坐標和y坐標:
來封裝一下
好啦!
再實現(xiàn)一個功能吧!
在播放的時候點按鼠標就可以捕捉當前播放的數(shù)據(jù)而且在圖片上面標注時間戳。
程序應該這樣寫:
1.讀取眼動數(shù)據(jù)文本文件,將數(shù)據(jù)存儲到一個列表中。2打開視頻文件,并讀取第一幀。3.在窗口上顯示第一幀圖像。4.進入循環(huán),依次讀取眼動數(shù)據(jù)列表中的每個數(shù)據(jù)。5.當用戶按下鼠標時,記錄當前的時間戳,并在圖像上繪制一個圓形或者其他標記,標記當前時間戳。6.在窗口上顯示標記后的圖像。
讀取
后面的功能分開寫不好,這里合在一起寫。
先讀取視頻幀,然后就是獲取幀率,創(chuàng)建一個窗口
能看懂吧?
這個就是繪制標記
許久不用Python,然后壞了,各種運行出錯,VSCode都撲街了,哭死,不知道咋辦了。
解決不了
重新安裝就好啦!
嚶嚶嚶,沒看上
c:/Users/yunswj/AppData/Local/Programs/Python/Python310/python.exe -m
pip install ipykernel -U --user --force-reinstall
pip install opencv-python
https://cmake.org/download/
import cv2
import threading
class VideoStream:
def __init__(self, src=0, width=640, height=480, fps=30):
self.stream = cv2.VideoCapture(src)
self.stream.set(cv2.CAP_PROP_FRAME_WIDTH, width)
self.stream.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
self.stream.set(cv2.CAP_PROP_FPS, fps)
self.width = int(self.stream.get(cv2.CAP_PROP_FRAME_WIDTH))
self.height = int(self.stream.get(cv2.CAP_PROP_FRAME_HEIGHT))
self.fps = int(self.stream.get(cv2.CAP_PROP_FPS))
self.status = False
self.frame = None
def start(self):
if self.status:
return None
self.status = True
threading.Thread(target=self.update, args=()).start()
def update(self):
while self.status:
_, self.frame = self.stream.read()
def read(self):
return self.frame
def stop(self):
self.status = False
def main():
# 創(chuàng)建兩個VideoStream對象,用于捕獲左右眼視頻流
left_cam = VideoStream(0)
right_cam = VideoStream(1)
# 開始捕獲視頻流
left_cam.start()
right_cam.start()
# 創(chuàng)建OpenCV窗口用于顯示視頻流
cv2.namedWindow("Video Stream", cv2.WINDOW_NORMAL)
while True:
# 讀取左右眼視頻流
left_frame = left_cam.read()
right_frame = right_cam.read()
# 在視頻流上添加幀率信息
left_fps_text = f"FPS: {left_cam.fps}"
right_fps_text = f"FPS: {right_cam.fps}"
cv2.putText(
left_frame,
left_fps_text,
(10, 30),
cv2.FONT_HERSHEY_SIMPLEX,
1,
(255, 255, 255),
2,
)
cv2.putText(
right_frame,
right_fps_text,
(10, 30),
cv2.FONT_HERSHEY_SIMPLEX,
1,
(255, 255, 255),
2,
)
# 合并左右眼視頻流并顯示
merged_frame = cv2.hconcat([left_frame, right_frame])
cv2.imshow("Video Stream", merged_frame)
# 按'q'鍵退出
if cv2.waitKey(1) & 0xFF == ord("q"):
break
# 停止視頻流捕獲
left_cam.stop()
right_cam.stop()
# 關閉OpenCV窗口
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
審核編輯 :李倩
-
傳感器
+關注
關注
2550文章
51035瀏覽量
753059 -
檢測器
+關注
關注
1文章
863瀏覽量
47676 -
機器學習
+關注
關注
66文章
8406瀏覽量
132558 -
眼動追蹤
+關注
關注
0文章
18瀏覽量
6742
原文標題:開發(fā)一個完整的眼動追蹤應用-Python版
文章出處:【微信號:TT1827652464,微信公眾號:云深之無跡】歡迎添加關注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論