需求说明
最近孩子很迷奥特曼,想尝试拿他的照片跟奥特曼合并下做个帅酷变身。我想一般的PS跟现在流行的AI工具应该都可以实现,但是咱是程序员可以尝试用Python来做一下嘛。
实现思路
Python图片处理离不开CV2库,这个实现思路很清晰。先根据孩子照片识别出人脸,然后进行人脸切割。为了保证拟合比较好,再将切割后的人脸进行尺寸固定化,然后两张图片贴合就行了。
环境准备
Python的windows环境加CV2的库安装。
我一开始尝试在windows的WSL上操作,无奈图片操作通过WSL有各种报错所以还是转回Windows。
SHOW ME THE CODE
import cv2
usrFilePath = "test.jpg"
atmFilePath = "atm2.jpg"
img = cv2.imread(usrFilePath)
atmimg = cv2.imread(atmFilePath)
fixsize = 128 # declare fix size
print(atmimg.shape)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # convert to grey
print("read file success")
# laod opencv schema
classifier = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
color = (0, 255, 0)
# begin to identify face
faceRects = classifier.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=3, minSize=(32, 32))
print(faceRects)
if len(faceRects): # get faces if above zero
for faceRect in faceRects: # loop each face
x, y, w, h = faceRect
cv2.rectangle(img, (x, y), (x + h, y + w), color, 1)
cropped = img[y:y+w, x:x+h] # cropped to get face
print("get avatar success")
# shrink face to fix size
shrink = cv2.resize(cropped, (fixsize,fixsize), interpolation = cv2.INTER_AREA)
print("saved avatar success")
# decalre target position in new picture
nx = 130
ny = 105
atmimg[ny:ny+fixsize, nx:nx+fixsize] = shrink
cv2.imshow("result", atmimg)
cv2.imwrite("newpic.jpg", atmimg)
cv2.waitKey(0)
cv2.destroyAllWindows()
融合后的效果
待优化
可以看到图片是贴进去了,但是拟合效果不太好,边界线很严重。后面可以研究下如何让边界更柔和。