如今美顔相機非常流行,作為鋼鐵直男,我不關注如何讓自己美顔更加好看,我更加關注如何實作這個功能呢?
在這裡我們不計劃使用複雜的深度學習等人工智能的算法實作(其實使用了),我們這裡使用python+opencv來實作此功能,直接開始:
一、環境需求
1、python
2、opencv
3、pillow
二、具體實作
為了實作這個方法,初步構造我計劃使用3步實作此功能,簡單直接實時捕捉視訊,人臉識别,添加頭像
1、實時捕捉攝像頭
opencv已經提供了很好的方法可以實作錄像功能,直接上代碼:
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
videoWriter = cv2.VideoWriter('output.avi',cv2.VideoWriter_fourcc(*'MJPG'), 15, (640,480))
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
frame = cv2.flip(frame,0)
videoWriter.write(frame)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
# Release everything if job is finished
cap.release()
videoWriter.release()
cv2.destroyAllWindows()
如上代碼每秒擷取15張圖檔儲存為視訊。
2、人臉識别
懂視訊的人都知道,視訊是按照每幀圖檔合成在一起的,是以我的構思就是要實作視訊人臉識别,就對每張圖檔進行識别。
import numpy as np
import cv2
img = cv2.imread('sachin.jpg')
# 人臉識别資料
face_cascade = cv2.CascadeClassifier('/usr/local/Cellar/opencv/4.0.1/share/opencv4/haarcascades/haarcascade_frontalface_default.xml')
# 人眼識别資料
eye_cascade = cv2.CascadeClassifier('/usr/local/Cellar/opencv/4.0.1/share/opencv4/haarcascades/haarcascade_eye.xml')
# 二值化,變為灰階圖
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 擷取人臉識别資料
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
# 繪畫人臉識别資料
img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]
eyes = eye_cascade.detectMultiScale(roi_gray)
for (ex,ey,ew,eh) in eyes:
cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
如上代碼我們進行了單張圖檔進行人臉識别,最終繪制人臉範圍,大家可以修改自己的人臉識别資料檔案位址和眼睛資料位址。
3、python+opencv實作添加貼紙
具體這個叫啥名字我也不清楚了,就是在視訊中添加帽子啊,雪糕啊啥的,然後我的實作方式是:根據人臉識别資料,在頭的上方添加貼紙 ,就是這麼簡單,其實就是一個添加水印的功能。
我們這裡使用pillow進行水印的添加,當然也可以隻使用opencv添加,不過我在實作時效果不是很好,如下是python添加圖檔水印的方法。
from PIL import Image
im = Image.open("1.jpg")
mark=Image.open("2.jpg")
layer=Image.new('RGBA', im.size, (0,0,0,0))
layer.paste(mark, (0,0))
out=Image.composite(layer,im,layer)
out.show()
三、最終代碼與效果
import numpy as np
import cv2
import time
import datetime
from PIL import Image
cap = cv2.VideoCapture(0)
''' 人臉識别 '''
def getface(img):
# 人臉識别資料
face_cascade = cv2.CascadeClassifier('/usr/local/Cellar/opencv/4.0.1/share/opencv4/haarcascades/haarcascade_frontalface_default.xml')
# 人眼識别資料
eye_cascade = cv2.CascadeClassifier('/usr/local/Cellar/opencv/4.0.1/share/opencv4/haarcascades/haarcascade_eye.xml')
# 二值化,變為灰階圖
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 擷取人臉識别資料
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
# 繪畫人臉識别資料
img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
# 根據人臉識别資料添加頭像
img = christmas(img,x,y,w,h)
return img
def christmas(img,x,y,w,h):
im = Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))
# 你的貼紙位址
mark=Image.open("hat/2.png")
height = int(w*987/1024)
mark = mark.resize((w, height))
layer=Image.new('RGBA', im.size, (0,0,0,0))
layer.paste(mark, (x,y-height))
out=Image.composite(layer,im,layer)
img = cv2.cvtColor(np.asarray(out),cv2.COLOR_RGB2BGR)
return img
videoWriter = cv2.VideoWriter('testwrite.avi', cv2.VideoWriter_fourcc(*'MJPG'), 15, (1000,563))
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
# 從新定義圖檔大小
img = cv2.resize(frame,(1000,563))
# 添加錄像時間
# img = addtime(img)
# 實時識别
img = getface(img)
# 視訊顯示
cv2.imshow('frame',img)
# 儲存視訊
videoWriter.write(img)
if cv2.waitKey(10) & 0xFF == ord('q'):
print("退出視訊")
break
else:
break
cap.release()
videoWriter.release()
cv2.destroyAllWindows()
如上我們實作效果如下圖,單張圖添加貼紙就更簡單的,大家改改代碼就可以了。
圖檔素材來自百度。
原創文章,轉載請注明 :[python美顔系列一] python使用opencv給視訊/圖檔添加萌萌哒貼紙 - pytorch中文網
原文出處: https://www.ptorch.com/news/242.html
問題交流群 :168117787