上篇文章我們看到了效果,這篇文章來回答怎么實現的,也學一下通用的CV編程。

文件不多,工作量不大

init是包的入口,使用點號絕對路徑導入

在上層目錄里面串聯著要使用的所有庫

在看一眼效果,倆鼻孔真好看
庫使用了精確的除法:
from __future__ import division導入Python未來支持的語言特征division(精確除法),當我們沒有在程序中導入該特征時,"/"操作符執行的是截斷除法(Truncating Division),當我們導入精確除法之后,"/"執行的是精確除法,如下所示:
> 3/40> from __future__ import division> 3/40.75
導入精確除法后,若要執行截斷除法,可以使用"http://"操作符:

接下來讀pupil的源碼
一定要找到依賴庫最少相對獨立的文件,這樣的實現很重要,大家都依賴。

接著看結構,只有一個類

init方法
事實上初始化的方法會確定很多東西,保證我們的程序按照一個可控的情況取運行。
最后的函數在下面有實現。

把虹膜摳出來
先說使用的裝飾器:
既然@staticmethod和@classmethod都可以直接類名.方法名()來調用,那他們有什么區別呢?從它們的使用上來看:
@staticmethod不需要表示自身對象的self和自身類的cls參數,就跟使用函數一樣。
@classmethod也不需要self參數,但第一個參數需要是表示自身類的cls參數。
如果在@staticmethod中要調用到這個類的一些屬性方法,只能直接類名.屬性名或類名.方法名。
而@classmethod因為持有cls參數,可以來調用類的屬性,類的方法,實例化對象等,避免硬編碼。
好處就是避免亂拉屎的情況。
CV是,先搞一個小的像素點,接著雙邊濾波一下,那么什么是雙邊略波?
雙邊濾波(Bilateral filter)是一種非線性的濾波方法,是結合圖像的空間鄰近度和像素值相似度的一種折衷處理,同時考慮空域信息和灰度相似性,達到保邊去噪的目的。均值濾波、中值濾波和高斯濾波,都屬于各向同性濾波,它們對待噪聲和圖像的邊緣信息都采取一樣的態度,結果,噪聲被磨平的同時,圖像中具有重要地位的邊緣、紋理和細節也同時被抹平了,這是我們所不希望看到的。具有簡單、非迭代、局部的特點。雙邊濾波器的好處是可以做邊緣保存(edge preserving),一般過去用的維納濾波或者高斯濾波去降噪,都會較明顯地模糊邊緣,對于高頻細節的保護效果并不明顯,為了解決這個問題,人們陸續提出了一些算法來把圖像邊緣和噪聲區別對待,比如雙邊濾波和導向濾波。
變得清晰了一些,然后腐蝕一下,變得大一點,二值化,最后把值返回。

檢測虹膜并且找到對應得位置。

函數一開始沒有說得,這里是尋找輪廓,以樹形結構輸出信息,儲存所有點得信息。
輸出是:
Python3里返回三個值:image,contours,hierarchy
image:可能是跟輸入contour類似的一張二值圖;
contours:list結構,列表中每個元素代表一個邊沿信息。每個元素是(x,1,2)的三維向量,x表示該條邊沿里共有多少個像素點,第三維的那個“2”表示每個點的橫、縱坐標;
注意:如果輸入選擇cv2.CHAIN_APPROX_SIMPLE,則contours中一個list元素所包含的x點之間應該用直線連接起來,這個可以用cv2.drawContours()函數觀察一下效果。
hierarchy:返回類型是(x,4)的二維ndarray。x和contours里的x是一樣的意思。如果輸入選擇cv2.RETR_TREE,則以樹形結構組織輸出,hierarchy的四列分別對應下一個輪廓編號、上一個輪廓編號、父輪廓編號、子輪廓編號,該值為負數表示沒有對應項。

使用了:

這樣得處理辦法,提取了我要的東西
下面是排序了一下,按照輪廓的面積排布。

排序是從小到大,現在又取了最后兩個,兩個最大的眼孔。

接下來看這個

就是幾個函數而已

接著初始化

左右眼要同時滿足才算矯正

閾值是左右眼都有,求和除以長度,有點面密度的味道

虹膜占多大

這個圖清晰吧

先取中間的RIO區域,把圖像抽取出來,X完以后就是一個面積,之后-不為黑色位置,不就是白色圈。最后一比

開始使用遍歷的方法來找到二值化的閾值是多少
先計算一下平均的虹膜大小,創建一個數據容器,按照5的step計算20次。
這里注意,二值化的函數返回值有兩個,需要[1],讀取的是第二個參數的內容,是一張圖。
接著計算這圖的比值,將內容放到字典里面。
最后把20次的內容,做計算,事實上,使用的內置的min函數:
語法:min(iterable, *[, key, default])
參數:iterable是可迭代的對象,key指定尋找最小值的關鍵字,若key不指定則采用默認位置,與內置函數sorted類似
返回值:返回值是iterable中尋找到的最小值
我們要的是瞳孔的位置,所以比值要小,這里取小。


如圖所示

這里就是可以一個眼睛一個眼睛的校準,存到字典里面

校準20次就可以了

最后一個

上面那么多內容都是給它做準備

初始化

先用dlib找到人臉,接著是把要尋找的特征文件準備好,下面一個函數把姿態點計算出來。
@property的作用:
廣泛用于類的定義中,把方法變成屬性,保證對參數進行必要的檢查,減少程序運行時出錯的可能性。

是否定位的函數

在我們上面分析的代碼里面
漏了一個函數,補全:

讀這個

初始化的內容

內置的工具函數,下劃線為了訪問限制

這個函數比較復雜

把里面的點解出來,放一個數組里面,轉換數據類型,放在新的數組里面

寫挺明白的了

轉換過的點在這里

把眼睛割出來
X[:,0]是numpy中數組的一種寫法,表示對一個二維數組,取該二維數組第一維中的所有數據,第二維中取第0個數據,直觀來說,X[:,0]就是取所有行的第0個數據, X[:,1] 就是取所有行的第1個數據。

然后

大概就這樣把

?前面4個取點,后面兩個算東西,接著算比值

如圖
寫不動了。。。我之后出個補篇,把屁股擦了。
