使用Opencv+樹莓派實現人臉識別(一)圖片人臉檢測和攝像頭人臉捕捉


前置安裝

我的樹莓派是3b,就1G內存,系統為stretch版本,自帶的python為3.5版本
強烈建議在燒寫樹莓派系統時就直接用buster版本,自帶的python版本在3.7及以上
Windows下直接使用PyCharm安裝python-opencv,python-opencv-contrib,pyqt5,pyqt5-tools

樹莓派下編譯安裝OpenCV:十分困難,可能要編譯4-5小時

樹莓派上python3已經可以直接使用pip包管理來直接安裝OpenCV

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install libhdf5-dev libhdf5-serial-dev
sudo apt-get install libqtgui4 libqtwebkit4 libqt4-test python3-pyqt5
sudo apt-get install libatlas-base-dev
sudo apt-get install libjasper-dev
sudo pip3 install --no-cache-dir opencv-contrib-python==3.4.3.18

檢測是否安裝成功:

python3 test.py
import cv2
print(cv2.__version__)

這里我們直接在Windows使用PyCharm寫代碼,然后通過FileZilla傳輸到樹莓派運行

靜態圖片檢測

灰度化

度化處理就是將一幅彩色圖像轉化為灰度圖像的過程

當R=G=B=255時,灰度值達到最高,顯示為白色,反之則顯示為黑色。

圖像灰度化的目的是為了簡化矩陣

彩色圖像中的每個像素顏色由R、G、B三個分量來決定,而每個分量的取值范圍都在0-255之間,這樣對計算機來說,彩色圖像的一個像素點就會有16777216種顏色的變化范圍

而灰度圖像是R、G、B分量相同的一種特殊彩色圖像,對計算機來說,一個像素點的變化范圍只有0-255這256種

使用到的特征分類器

Haar特征分類器,其實就是一個XML文件,用於描述人體各個部位的Haar特征值(眼睛,嘴唇等)

引用一個博客的說法:(42條消息) 機器學習 之 Haar特征_蘇的專欄-CSDN博客

Haar特征是一種反映圖像的灰度變化的,像素分模塊求差值的一種特征。它分為三類:邊緣特征、線性特征、中心特征和對角線特征。用黑白兩種矩形框組合成特征模板,在特征模板內用 黑色矩形像素和 減去 白色矩形像素和來表示這個模版的特征值。例如:臉部的一些特征能由矩形模塊差值特征簡單的描述,如:眼睛要比臉頰顏色要深,鼻梁兩側比鼻梁顏色要深,嘴巴比周圍顏色要深等。但矩形特征只對一些簡單的圖形結構,如邊緣、線段較敏感,所以只能描述在特定方向(水平、垂直、對角)上有明顯像素模塊梯度變化的圖像結構。

在安裝目錄可以找到分類器文件,從文件名就能大致看出其功能

image

#detectMultiScale函數可以檢測處圖片中的所有人臉   ( 識別圖像中的人臉,返回所有人臉的矩形框向量組 )
#且可以使用向量(vector)將所有人臉的坐標大小(矩形表示)保存
# scaleFactor 為了檢測到不同大小的目標,通過scalefactor參數把圖像長寬同時按照一定比例(默認1.1)逐步縮小,
# 然后檢測,這個參數設置的越大,計算速度越快,但可能會錯過了某個大小的人臉。
# minNeighbors 構成檢測目標的相鄰矩形的最小個數,默認值是3
faces = haar_face_cascade.detectMultiScale(gray_img, scaleFactor=1.1,minNeighbors=3)
cv2.rectangle(image, start_point, end_point, color, thickness)

image:它是要在其上繪制矩形的圖像。
start_point:它是矩形的起始坐標。坐標表示為兩個值的元組,即(X坐標值,Y坐標值)。
end_point:它是矩形的結束坐標。坐標表示為兩個值的元組,即(X坐標值ÿ坐標值)。
color:它是要繪制的矩形的邊界線的顏色。對於BGR,我們通過一個元組。例如:(255,0,0)為藍色。
thickness:它是矩形邊框線的粗細像素。厚度-1像素將以指定的顏色填充矩形形狀

靜態檢測代碼

import cv2
import numpy as np

def dection(imagepath):
    image = cv2.imread(imagepath,cv2.IMREAD_COLOR) #讀取圖片
    gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)#圖像灰度化,用於簡化矩陣運算
    face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')  # xml來源於資源文件。
    faces = face_cascade.detectMultiScale(gray,scaleFactor=1.2,minNeighbors=1)
    for (x , y, w, h) in faces:
            image = cv2.rectangle(image, (x, y) , (x+w , y+h) , (0,0,255) , 2)
    cv2.namedWindow('face')
    cv2.imshow('face',image)
    cv2.waitKey(0)  #等待退出鍵
    cv2.destroyAllWindows()


dection('img2.jpg')

用攝像頭做檢測(此時仍然是簡單的檢測,並非識別,大抵上只是將圖像源換為了攝像頭的圖像幀)

.pgm格式

Portable Gray Map

灰度圖像格式中一種最簡單的格式標准。另外兩種與之相近的圖片格式是PBM和PPM。它們分別相應着黑白圖像和彩色圖像

image

camera.read()函數

read()函數返回一個bool類型,表示幀的讀取的正確與否(可以用來檢查視頻文件是否到達結尾)

(read之前可以使用isOpened()來檢測是否成功初始化攝像頭

如果初始化false,則使用open()

read():

參數ret 為True 或者False,代表有沒有讀取到圖片 第二個參數frame表示截取到一幀的圖片

用一個死循環一直讀取攝像頭幀,每讀到一幀就檢測一次

import cv2
import numpy as np

def det(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    face_detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
    faces = face_detector.detectMultiScale(gray, 1.2, 6)
    for x, y, w, h in faces:
        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2)
    cv2.imshow("result", image)
#視頻檢測人臉
def video_detc():
    camera = cv2.VideoCapture(1)#打開攝像頭(插入usb攝像頭后,0為筆記本攝像頭,1為usb攝像頭)
    while(True):
        ret, frame = camera.read()
        frame = cv2.flip(frame, 1)#設置個鏡像(好看一點)
        det(frame)
        c = cv2.waitKey(10)
        if c == 27: # ESC
            break
video_detc()

人臉識別數據集的錄入

使用pgm格式存儲

讓用戶自己輸入id(用於修改文件名,區分不同人的數據集)

例如某一個人錄入的pgm文件名全為:User_1.pam,1即為用戶輸入的id

image

image

#一個id(一個人)錄入50-100張圖片,這里選了100張(可能在檢測的時候精度更高)
#並且保存為pgm格式
#需要去手動設置你的人臉id值
import cv2
import os
def input_face_data():
    camera = cv2.VideoCapture(1)
    #使用默認大小
    face_detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
    id = input("請輸入id,並回車:")
    print("請正視攝像頭,多做幾個表情")
    pic_count = 0 #記錄有多少pgm文件
    while(True):
        ret,frame = camera.read()
        frame = cv2.flip(frame, 1)  # 設置個鏡像(好看一點)
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        faces = face_detector.detectMultiScale(gray, 1.2, 6)
        for (x,y,w,h) in faces:
            pic_count+=1
            cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)
            cv2.imwrite("D:\\py_study\\facedetection\\dataset\\User_"+str(id)+"_"+str(pic_count)+".pgm",gray[y:y+h,x:x+w])
            cv2.imshow('image', frame)
            print("錄入第"+str(pic_count)+"張結束")
            k = cv2.waitKey(100) & 0xff  # Press 'ESC' for exiting video
        c = cv2.waitKey(10)
        if c == 27:  # ESC
            break
        elif pic_count>=100:
            print("結束錄入數據集")
            break

input_face_data()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM