1.4. 人臉檢測
人臉檢測的任務是從一個圖像中尋找出人臉所在的位置和大小。0penCV提供了級聯分類器(CascadeClassifier) 和人臉特徵數據,只用少量代碼就能實現人臉檢測功能。
在本小節中,將學習編寫幾個簡單的人臉檢測程序,以此掌握在0penCV中操作圖像、視頻和攝像頭的方法。
1.準備工作
在本地磁盤新建目錄“BaseOpenCV”作爲項目目錄,從原書提供的“資源包/第32課/”中把“人臉檢測”文件夾中的子目錄和文件拷貝到新建的項目目錄中,這是準備好的用於檢測的人臉圖像、視頻和人臉(正臉)特徵數據文件。 下面編寫的人臉檢測程序也存放在這個文件夾中。
2.檢測圖像中的人臉
在VSCode環境中,打開項目目錄,新建一個空白源文件 ,以detect_image.jl作爲文件名保存到“BaseOpenCV”中,然後編寫程序檢測圖像中的人臉(正臉),具體過程如下。
(1) 導入 cv2 庫。
using PyCall cv2=pyimport("cv2") |
(2) 從文件中加載一個含有人臉的圖像,並轉換得到一個灰度圖像。
img = cv2.imread("images/face1.jpg") gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) |
說明:OpenCV提供的cvtColor()方法是用於轉換圖像的色彩空間,使用cv2.OLOR_BGR2GRAY參數可以將一個彩色圖像轉換爲灰度圖像。
(3) 利用人臉特徵數據創建一個人臉檢測器(CascadeClassifier類的實例),然後調用該實例的detectMultiScale()方法檢測圖像中的人臉區域,將檢測結果返回給變量faces。
file = "haarcascade_frontalface_default.xml" face_cascade = cv2.CascadeClassifier(file) faces = face_cascade.detectMultiScale(gray, 1.3, 5) |
說明:在調用detectMultiScale( )方法的參數中,第1個參數是一個灰度圖像;第2個參數表示在前後兩次相繼的掃描中,搜索窗口的比例係數(默認爲l.1,即每次搜索窗口依次擴大1的0;第3個參數表示構成檢測目標的相鄰矩形的最小個數(默認爲3個)。
(4) 在檢測圖像中的每一個人臉區域畫上矩形框。
#Julia數組是列主數組,而cv需要行主數組。 #反轉維度,然後使用PyReverseDims數組 rimg = permutedims(img, ndims(img):-1:1) pyimg = PyReverseDims(rimg) for i in 1:size(faces)[1] x=faces[i,1] y=faces[i,2] w=faces[i,3] h=faces[i,4] cv2.rectangle(pyimg, (x, y), (x+w, y+h), (255, 0, 0), 3) end |
說明:檢測出的人臉區域是一個矩形,由左上角座標(x,y)和矩形的寬度w和高度h來確定。利用cv2.rectangle()方法可以在圖像上畫出一個矩形,該方法的第1個參數是圖像,第2個參數是矩形的左上角座標(x,y),第3個參數是矩形的右下角座標(x+w,y+h),第4個參數是線條的顏色,第5個參數是線條的寬度。
注:以上代碼中的for循環,python代碼是這樣寫的
for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 3) |
爲什麼這樣遍歷faces中的元素?我們首先看一下faces是什麼。通過type(faces)方法,我們可以獲得faces的類型是”numpy.ndarray“, 這個ndarray(全稱The N-dimensional array)是存儲着相同類型和大小的元素的多維數組,再通過faces.shape,可知其是一個(3,4)的數組,for (x, y, w, h) in faces的結果,是遍歷faces的每行,並將每行的4個元素值分別賦值給x, y, w, h四個變量。
我們再來看在julia中,faces是什麼。通過前面我們提到過typeof(faces),我們可以獲得faces的類型是“Matrix{Int32} “,是一個元素爲Int32類型的矩陣。但是julia的矩陣是列主存儲的,因此無法默認以 “行“遍歷的方式訪問,因此人臉檢測的juli代碼中,對這一處進行了改寫。其中size()方法與python的shape一樣,可以獲得數組的真實維度值,而維度值是一個元組類型,然後可以循環訪問維度值的第一維,即矩陣的”行“,再將每行的元素值賦值給x,y,w,h四個遍歷。
- 拓展知識:
關於在juia中以循環方式對矩陣元素的訪問(也稱迭代),這裏再做進一步的拓展說明。
首先我們構造一個3x4的矩陣
julia> m = [10i+j for i=1:3, j=1:4] 3×4 Matrix{Int64}: 11 12 13 14 21 22 23 24 31 32 33 34 |
按照人臉檢測的代碼方式,我們可以這樣遍歷這個矩陣:
julia> for i=1:size(m)[1] x= m[i,1] y= m[i,2] w= m[i,3] h= m[i,4] println(x+1," ",y+1," ",w+1," ",h+1) end 輸出結果: 12 13 14 15 22 23 24 25 32 33 34 35 |
當然我們還可以這樣寫:
julia> for i=1:size(m)[1] x,y,w,h=m[i,1:4] println(x+1," ",y+1," ",w+1," ",h+1) end |
我們還可以這樣寫:
julia> for i=1:size(m,1) x,y,w,h=m[i,1:4] println(x+1," ",y+1," ",w+1," ",h+1) end |
我們還可以這樣寫:
julia> for i=1:size(m,1) x,y,w,h=m[i,:] println(x+1," ",y+1," ",w+1," ",h+1) end |
還有更花式的寫法:
julia> for row in eachrow(m) x,y,w,h=row println(x+1," ",y+1," ",w+1," ",h+1) end |
以上各種寫法,哪個是性能最好的寫法?大家可以研究一下。
(5) 把標註矩形框後的圖像顯示到窗口。
cv2.imshow("Image", pyimg) |
(6) 等待用戶按下任意按鍵,之後銷燬所有窗口。
cv2.waitKey(0) cv2.destroyAllWindows() |
至此,人臉檢測程序編寫完畢。運行程序,結果如圖所示 。
wwan
完整代碼下載::https://files.cnblogs.com/files/zjzkiss/face_detect1.rar