OpenCv人臉檢測技術-(實現抖音特效-給人臉戴上墨鏡)

貓吃耗子發表於2023-04-21

OpenCv人臉檢測技術-(實現抖音特效-給人臉戴上墨鏡)

本文章用的是Python庫裡的OpenCv。

OpenCv相關函式說明

import cv2 # 匯入OpenCv庫
cv2.imread(filename) # 讀取影像
object = cv2.CascadeClassifier() # 括號裡面填Haar級聯分類器
"""
CascadeClassifier,是Opencv中做人臉檢測的時候的一個級聯分類器。並且既可以使用Haar,也可以使用LBP特徵。Haar特徵是一種反映影像的灰度變化的,畫素分模組求差值的一種特徵。
"""
object.detectMultiScale(image, scaleFactor, minNeighbors)
"""
detectMultiScale是CascadeClassifier的子類;
image:待分析的影像。
scaleFactor:掃描影像時縮放的比例。
minNeighbors:保留多少檢測結果,該值越大誤差越小。
etc...
"""
cv2.waitKey(delay) # 等待使用者按下鍵盤後等待delay毫秒
cv2.destroyAllWindows() # 銷燬所有視窗

分析人臉位置

人臉檢測,把影像分成一個個小塊,對每一個小塊判斷是否是人臉,假如一張圖被分成了5000塊,則速度非常慢。
為了提高效率,OpenCV 提供 cascades 來避免這種情況。提供了一系列的xml檔案
cascades :翻譯 :小瀑布 級聯
cascade 對於每個資料塊,它都進行一個簡單快速的檢測。若過,會再進行一個更仔細的檢測。該演算法有 30 到 50 個這樣的階段,或者說 cascade。只有透過全部階段,cascade才會判斷檢測到人臉。這樣做的好處是:大多數小塊都會在前幾步就產生否定反饋,節約時間。
資源連結,該資源不僅僅包括人臉xml,還有其他眼睛等。賺取點積分吧。
OpenCV人臉識別xml檔案.zip或者從官網Sources裡找資源,data資料夾中有是特徵檔案,我們一般選用haarcascade_frontalface_default.xml

資料來源於網路,侵刪。

import cv2
img = cv2.imread("/Users/duanhao/Desktop/photo/liukun.jpg")
# 載入識別人臉的級聯分析器
faceCascade = cv2.CascadeClassifier("/Applications/anaconda/anaconda3/lib/python3.9/site-packages/cv2/data/haarcascade_frontalface_default.xml")
faces = faceCascade.detectMultiScale(img, 1.15, 5)
for (x, y, w, h) in faces:
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 5)
cv2.imshow("image", img)
cv2.waitKey()
cv2.destroyAllWindows()

給人臉戴上墨鏡

準備階段:我們可以讀取影片,也可以讀取人臉,這裡我準備了一張含有人臉的照片;

如果要讀取影片需要用:VideoCapture類方法。

素材:一張墨鏡?️的圖片,用於後期覆蓋原始影像。

程式碼:

import cv2
def over_img(img, img_over, over_x, over_y):
    img_h, img_w, c = img.shape
    img_over_h, img_over_w, over_c = img_over.shape
    if over_c == 3:
        img_over = cv2.cvtColor(img_over, cv2.COLOR_BGR2BGRA)
    for w in range(0, img_over_w):
        for h in range(0, img_over_h):
            # 透明畫素不能覆蓋影像
            if img_over[h, w, 3] != 0:
                for c in range(0, 3):
                    x = over_x + w
                    y = over_y + h
                    if x >= img_w or y >= img_h:
                        break
                    img[y, x, c] = img_over[h, w, c]
    return img

img = cv2.imread("/Users/duanhao/Desktop/photo/liukun.jpg")
glass = cv2.imread("/Users/duanhao/Desktop/photo/glass.png", cv2.IMREAD_UNCHANGED) # 保留影像型別
height, weight, channel = glass.shape
# 載入人臉識別聯結器
faceCascade = cv2.CascadeClassifier("/Applications/anaconda/anaconda3/lib/python3.9/site-packages/cv2/data/haarcascade_frontalface_default.xml")
face = faceCascade.detectMultiScale(img, 1.15, 4)
for (x, y, w, h) in face:
    gw = w
    gh = int(height * gw/weight)
    img_over_new = cv2.resize(glass, (gw, gh))
    img = over_img(img, img_over_new, x, y+int(h*1/3))
    # cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 5)
cv2.imshow("screen", img)
cv2.waitKey()
cv2.destroyAllWindows()

效果圖:

結束語:

上面是我五個室友的合照。當時因為有一個演算法比賽,我在寢室裡備戰演算法競賽,所以沒和室友一起出去,所以上面的合照沒有我。後面我有時間,一定要把我自己P上去!!

最後,祝所有奮鬥的人都能收穫到好的結果。

相關文章