萬聖節那天下班回家在地鐵口碰到公司一全棧高手(前端人員寫CS結構程序),固然天然而然就順便聊了一下技術,期間就說到了滑動驗證碼,首先聲明我不是作計算機圖形的,只是之前作過簡單的驗證碼識別和遠控,都是基於圖像處理的,能夠說對於圖像處理我只會點皮毛,和一點基礎算法吧。當時聽同事稍微了說了下感受有必定的難度,還據說公司裏面有一個「同事」用python寫成了開源組件,在這給大佬們點個大大的贊。惋惜就只聊了那麼幾分鐘吧,同事到站了,就留我一我的在地鐵上看着抖音。
晚上回到家想了下,決定試試,打開瀏覽器訪問京東官網,經過DOM元素簡單的看了下京東的滑動驗證碼。無獨有偶恰巧週六小孩學校活動登山,孩子她媽問我去不去,我想了下,當時就果斷決定了不去,內心在想明天好好碼一天code,看能不能解決滑動驗證碼識別的問題。
次日一大早起來,坐電腦旁邊巴拉巴拉了一堆代碼,不用說你們應該知道,就是採用一些基礎算法把彩色絢麗的原圖灰度化、二值化、降糙等等。求灰度值有專門的公式,不須要咱們補腦RGB三元組,二值化也很簡單,所謂二值就是0 1,不是黑就是白,可是須要本身結合圖片設定閾值。非專業的話,仍是建議作圖片處理的朋友,首先仍是先了解熟悉Color ARGB BitMap位圖 像素 位深 跨距 PNG JPG等等,百度一堆。下面看看我這邊處理的效果。
基本處理
原圖:
灰度化:
二值化:
可能中間還有去糙的操做,結合實際狀況吧,這些基礎的圖像處理,其實很簡單。二值化以後,圖片上紅色箭頭部分就是我要找的部分,怎麼找呢?其實就算是橫豎遍歷時間複雜度也還好,由於圖片像素小啊,指針處理法仍是很快的(主要這種遍歷橫豎不適合)。具體怎麼找,這裏我簡單說下個人看法,對於咱們這些不是作圖形學的朋友來講,看到這麼一張圖片若是按照程序的邏輯去思考還真比較呆板和麻煩。那怎麼辦?個人處理方式,站在個人角度,我眼睛識別的角度,我眼睛看到哪一個區域再傳給我大腦比較,若是不是再隨機掃這幅圖片的另一個區域。說的很簡單,那麼問題來了,代碼怎麼寫?這個算法怎麼寫?
查找我先說下我第一種吧
1.對這副圖片隨機撒點1000個,具體多少個結合圖片像素大小吧,而後遍歷這1000個點,若是這個點的顏色值&255=255,我就向左邊掃描,直到不能掃爲止,也就是色塊不一樣,而後沿周邊掃描,最後發現邏輯很差控制,若是被掃圖片部分很是不規整和複雜的話,覆蓋率不是很可觀,果斷放棄,考慮另一種方法。
2.對這副圖片隨機撒點1000個,而後遍歷這1000個點,若是這個點的顏色值&255=255,那麼一這個點爲中心造成相似九宮格的排列,向4周8個像素點擴散,直到每一個像素點不能擴散爲止,也就是色塊值不一樣了,這種作法代碼簡單邏輯清楚,覆蓋率100%,也就是說二值以後的圖片能把全部要找的部分找出來。細心的朋友可能以爲隨機撒點不靠譜?確實不靠譜,因而我在撒點算法上改進了一下。
3.我要找的圖片部分寬高各50,實際上我只要一個像素點命中我要找的圖片部分,經過擴散查找算法,它就能幫我找出來,因此在隨機撒點算法裏面我改爲跳躍式的撒點,只要被找部分在裏面就逃不掉。這樣撒點和查找結合就能大大提升查找的效率。接下來看圖:
可能有些朋友會說,怎麼前面有些沒查出來?那是由於我跳躍撒點的間距比較大而已。
識別
找是找到了,怎麼識別呢?有了前面查找提供的基礎數據,識別就變的簡單了。上圖每查找出一個圖片軌跡,我就會把它的軌跡像素點存儲在一個多維列表裏面,經過多張驗證碼圖片比對發現填充的位置部分和填充的圖片對象像素點大小不超過50,這樣就很容易找到填充位置座標在哪裏。退一步說即使我不用這種方法,我能夠根據幾何圖像類似度也能夠處理這個問題,我能夠根據邊,高,寬,長等特性按比例計算類似度。最後拿到了填充位置計算一下填充圖片和填充位置的座標距離,而後觸發js拉動填充圖片便可,固然最後一部我就沒作了,理論上這麼能夠作吧。
好了就說這麼多吧,本人不是作圖像識別的,說的不對或者哪裏有錯誤,但願看官指出,最後謝謝吧。