OpenCv識別小羅伯特唐尼

一、OpenCV簡單介紹

在實現(xiàn)人臉識別之前截粗,我們先簡單了解一下OpenCv的一些基本操作疫稿。在此之前,我們需要先安裝OpenCv粉臊,我們使用pip安裝:

pip install opencv-python

另外我們還需要另外一個模塊:

pip install opencv-contrib-python

接下來我們就可以學(xué)習(xí)OpenCv了垢夹。

1.1、OpenCv操作圖像

我們來簡單讀取一個圖像维费,并將該圖像顯示:

# 導(dǎo)入模塊
import cv2
# 讀取圖片
im = cv2.imread('1.jpg')
# 顯示圖片果元,該方法只會顯示一瞬間。(第一個參數(shù)為窗口名稱犀盟,第二個參數(shù)為ndarray對象)
cv2.imshow('im', im)
# 等待鍵盤輸入而晒,傳入毫秒值,當傳入0時表示無限等待阅畴。(imshow配合該方法可以讓界面一直顯示)
cv2.waitKey(0)
# 因為OpenCv是用C/C++寫的倡怎,所以需要釋放內(nèi)存
cv2.destroyAllWindows()

上述代碼就實現(xiàn)了最簡單的讀取并顯示圖像的操作了。

1.2贱枣、灰度轉(zhuǎn)換

灰度就是使用黑色調(diào)表示物體监署,即用黑色為基準色,不同的飽和度的黑色來顯示圖像纽哥。 灰度轉(zhuǎn)換就是將圖片轉(zhuǎn)換成黑白圖像钠乏。因為我們在人臉識別時,灰度圖像便于識別春塌,所以我們先來了解一下晓避。用OpenCv實現(xiàn)灰度轉(zhuǎn)換很簡單:

import cv2
# 讀取圖像
im = cv2.imread('1.jpg')
# 灰度轉(zhuǎn)換(第一個參數(shù)為ndarray對象,第二個參數(shù)為cv2中的常量)只壳,返回一個ndarray對象
grey = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
# 將grey保存
cv2.imwrite('grey.jpg', grey)
# 顯示灰度轉(zhuǎn)換后的圖像
cv2.imshow('grey', grey)
# 等待鍵盤輸入
cv2.waitKey(0)
# 銷毀窗口
cv2.destroyAllWindows()

效果如下:

在這里插入圖片描述

1.3俏拱、繪制圖形

我們后續(xù)在檢測人臉的時候,我們會繪制圖形吼句,將人臉框起來锅必。圖形的繪制也非常簡單,我們看如下代碼:

import cv2
# 讀取圖像
im = cv2.imread('1.jpg')
# 在圖像im上繪制矩形
"""
第一個參數(shù)為ndarray對象
第二個參數(shù)為左上角的坐標(x1, y1)
第三個參數(shù)為右下角的坐標(x2, y2)
第四個參數(shù)為顏色值惕艳,其順序不同于我們之前的搞隐,使用的是BGR
第五個參數(shù)為線條寬度
"""
cv2.rectangle(im, (0, 0), (200, 200), (255, 255, 0), 2)
# 顯示圖像
cv2.imshow('im', im)
# 等待輸入
cv2.waitKey(0)
# 銷毀窗口
cv2.destroyAllWindows()

對比圖如下:

在這里插入圖片描述

了解上面知識后分蓖,我們就可以進入下一步的學(xué)習(xí)了。

二尔许、人臉檢測

2.1、獲取特征數(shù)據(jù)

開始人類檢測之前终娃,我們要先獲取一個特征數(shù)據(jù)味廊。我們先去官網(wǎng),看到如下界面:

在這里插入圖片描述

點擊相應(yīng)的下載后棠耕,雙擊安裝就可以了余佛。我們進入D:\CodeField\OpenCv\opencv\sources\data\haarcascades,前面為你opencv的安裝目錄窍荧。進入該文件夾后辉巡,里面全是特征文件,我們一般選用haarcascade_frontalface_default.xml蕊退。

2.1郊楣、檢測人臉

我們可以把特征文件復(fù)制到我們項目下,也可以直接用絕對路徑引用瓤荔。我們檢測人臉需要一個cv2.CascadeClassifier對象净蚤,該對象可以用來檢測人臉。代碼如下:

face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

其中输硝,傳入?yún)?shù)為特征文件的路徑今瀑。我們可以選擇相對路徑,也可以選擇絕對路徑点把。完整人類檢測代碼如下:

import cv2
# 加載特征數(shù)據(jù)
face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# 讀取圖片
im = cv2.imread('1.jpg')
# 檢測人臉橘荠,返回人臉的位置信息
faces = face_detector.detectMultiScale(im)
# 遍歷人臉
for x, y, w, h in faces:
    # 在人臉區(qū)域繪制矩形
    cv2.rectangle(im, (x, y), (x+w, y+h), (255, 255, 0), 2)
# 顯示圖像
cv2.imshow('im', im)
cv2.waitKey(0)
cv2.destroyAllWindows()

其中detectMultiScale方法返回一個ndarray對象,這個對象保存了n張人臉的左上角坐標郎逃、臉的寬哥童、臉的高。檢測效果如下:

在這里插入圖片描述

不過有時會有一些誤差褒翰,大多數(shù)清晰人臉可以正常檢測到如蚜。

三、人臉識別

上面的內(nèi)容我們已經(jīng)說了人臉檢測的實現(xiàn)影暴,那人臉識別和人臉檢測有什么區(qū)別呢错邦?它們的區(qū)別在于,人臉檢測是要確定一張圖像里面有沒有人臉型宙,而人臉識別則是要確定圖像中的人臉是誰撬呢。不過要確定是誰之前,我們需要先見過人臉的主人妆兑,這就需要我們訓(xùn)練數(shù)據(jù)了魂拦。

3.1毛仪、訓(xùn)練數(shù)據(jù)

訓(xùn)練數(shù)據(jù)主要有兩個部分,人臉信息和標簽芯勘,其中標簽為int列表箱靴。我在目錄gtx中準備了50來張鋼鐵俠圖片,為了方便獲取標簽荷愕,我們先編寫如下代碼:

import os

path = "./gtx/"
# 獲取文件列表
paths = os.listdir(path)
i = 0   # 循環(huán)變量
for file in paths:
    i += 1
    # 將文件重命名
    os.rename(path+file, path + str(i) + str(1) + ".jpg")

這段代碼就是遍歷當前目錄下gtx文件夾下的圖片衡怀,將圖片名稱改為數(shù)字+1+.jpg格式。

在這里插入圖片描述

上面是我用爬蟲爬取的一些圖片安疗,我們將這些使用上述代碼轉(zhuǎn)換成數(shù)字+1+.jpg格式抛杨,我們把1做為小羅伯特唐尼的標簽,我們可以繼續(xù)多把其他人的人臉改為數(shù)字+2+.jpg格式荐类,這樣就可以做到區(qū)分怖现。不過上述代碼有一個問題,即當我們遍歷到第四個圖片時玉罐,名稱需要改為41.jpg屈嗤,而在我的文件夾中已經(jīng)存在41.jpg,所以會產(chǎn)生錯誤吊输。我們將代碼改為如下:

import os
path = "./gtx/"
paths = os.listdir(path)
i = 0
for file in paths:
    i += 1
    try:
        os.rename(path + file, path + str(i) + str(1) + ".jpg")
    except Exception as e:
        print(e)
        # 當發(fā)生異常時恢共,直接跳過
        continue

準備好圖像后,我們就可以開始訓(xùn)練數(shù)據(jù)了璧亚,訓(xùn)練數(shù)據(jù)代碼如下:

import cv2
import os
import numpy

root_path = "./gtx/"

def getFacesAndLabels():
    """讀取圖片特征和標簽"""
    global root_path
    faces = []
    lables = []

    # 獲取人臉檢測器
    face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

    # 獲取圖片路徑
    files = os.listdir(root_path)
    for file in files:
        path = root_path + file

        # 讀取圖片
        im = cv2.imread(path)
        # 轉(zhuǎn)換灰度
        grey = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
        # 讀取人臉數(shù)據(jù)
        face = face_detector.detectMultiScale(grey)
        for x, y, w, h in face:
            # 設(shè)置標簽讨韭,分離文件名稱
            lables.append(int(file.split('.')[0]))
            # 設(shè)置人臉數(shù)據(jù)
            faces.append(grey[y:y+h, x:x+w])

    return faces, lables

# 調(diào)用方法獲取人臉信息及標簽
faces, labels = getFacesAndLabels()
# 獲取訓(xùn)練對象
recognizer = cv2.face.LBPHFaceRecognizer_create()
# 訓(xùn)練數(shù)據(jù)
recognizer.train(faces, numpy.array(labels))
# 保存訓(xùn)練數(shù)據(jù)
recognizer.write('./trainer/trainer.yml')

在上面代碼中,我們上面的并沒有對文件名稱中的最后一個數(shù)字1進行區(qū)分癣蟋,后續(xù)會使用到透硝。關(guān)于訓(xùn)練數(shù)據(jù),大家可以多準備一些人物和圖片疯搅。

3.2濒生、人臉識別

我們訓(xùn)練完數(shù)據(jù)后,就可以進行人臉識別了幔欧。在識別之前我們先加載訓(xùn)練數(shù)據(jù)罪治,然后就是基本的人類檢測步驟。最后我們調(diào)用predict方法進行人臉識別礁蔗,在訓(xùn)練數(shù)據(jù)中匹配人物觉义。

import cv2

# 加載訓(xùn)練數(shù)據(jù)集
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('./trainer/trainer.yml')

# 準備識別的圖片
im = cv2.imread('1.jpg')
grey = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)

# 檢測人臉
face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
face = face_detector.detectMultiScale(grey)

for x, y, w, h in face:
    # 返回人臉標簽和可信度,可信度數(shù)值越低浴井,可信度越高(用詞不當晒骇,不要在意)
    label, confidence = recognizer.predict(grey[y:y+h, x:x+w])
    # 這里將60作為界限,當檢測檢測值為60時,我們就確定人物
    if confidence <= 60:
        if label % 10 == 1:
            print('小羅伯特唐尼')
        elif lable % 10 == 2:
            pass
    else:
        print("未匹配到數(shù)據(jù)")
    cv2.imshow('im', im)
    cv2.waitKey(0)
# 銷毀窗口
cv2.destroyAllWindows()

上述代碼中洪囤,我們用標簽label%10徒坡,可以獲得文件最后一個數(shù)字,這樣就可以達到區(qū)分人物的作用瘤缩,我們用如下圖片進行測試喇完。

在這里插入圖片描述

輸出結(jié)果如下:

小羅伯特唐尼

算是成功了,多次測試后剥啤,發(fā)現(xiàn)準備率方面比較中規(guī)中矩锦溪。大家可以嘗試多準備寫圖片用來訓(xùn)練,從而提高準確率铐殃。代碼已上傳GitHub:https://github.com/IronSpiderMan/GtxFaceDetector

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市跨新,隨后出現(xiàn)的幾起案子富腊,更是在濱河造成了極大的恐慌,老刑警劉巖域帐,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赘被,死亡現(xiàn)場離奇詭異,居然都是意外死亡肖揣,警方通過查閱死者的電腦和手機民假,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來龙优,“玉大人羊异,你說我怎么就攤上這事⊥希” “怎么了野舶?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長宰衙。 經(jīng)常有香客問我平道,道長,這世上最難降的妖魔是什么供炼? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任一屋,我火速辦了婚禮,結(jié)果婚禮上袋哼,老公的妹妹穿的比我還像新娘冀墨。我一直安慰自己,他們只是感情好涛贯,可當我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布轧苫。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪含懊。 梳的紋絲不亂的頭發(fā)上身冬,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天,我揣著相機與錄音岔乔,去河邊找鬼酥筝。 笑死,一個胖子當著我的面吹牛雏门,可吹牛的內(nèi)容都是我干的嘿歌。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼茁影,長吁一口氣:“原來是場噩夢啊……” “哼宙帝!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起募闲,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤步脓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后浩螺,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體靴患,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年要出,在試婚紗的時候發(fā)現(xiàn)自己被綠了鸳君。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡患蹂,死狀恐怖或颊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情传于,我是刑警寧澤饭宾,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站格了,受9級特大地震影響看铆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜盛末,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一弹惦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧悄但,春花似錦棠隐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽啰扛。三九已至,卻和暖如春嗡贺,著一層夾襖步出監(jiān)牢的瞬間隐解,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工诫睬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留煞茫,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓摄凡,卻偏偏與公主長得像续徽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子亲澡,可洞房花燭夜當晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容