對比python學julia(第四章:人工智能)--(第一節)OpenCV編程初步(2)

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章