- 简述:
基于OpenCV中的基本方法,进行人脸区域的矫正切割,采用了68个定位点中的左眼,右眼,嘴巴中心这三个定位点进行提取,使用输入,输出图像构成的三组点对,利用仿射变换,实现最终图像的输出。
import cv2
import glob
import os
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['simhei'] # 添加中文字体为简黑
plt.rcParams['axes.unicode_minus'] =False
point_in = list()
#导入照片文件列表
def load_image(path_in):
type_list = ['*.png','*.jpg','*.jpeg']
img_list = list()
for i in type_list:img_list+=glob.glob(path_in+i)
return img_list
#点击事件的回调函数
def on_EVENT_LBUTTONDOWN(event,x,y,flags,param):
global point_in
imgIn0= param
a = len(point_in)
if a<3:
if event == cv2.EVENT_LBUTTONDOWN:
point_in.append([x,y])
cv2.circle(imgIn0,(x,y),3, (255, 0, 0), thickness = -1) #画圆半径为3,并填充
cv2.putText(imgIn0, str(a + 1), (x, y), cv2.FONT_HERSHEY_PLAIN,
1.0, (0, 255, 0), thickness=1) #加入文字,位置,字体,尺度因子,颜色,粗细
cv2.imshow("window 2", imgIn0)
def show_image(img_list,path_out,point_in):
for i,img_path in enumerate(img_list):
point_in.clear()
# A.以灰度模式读取原始图像、可视化
# cv2.IMREAD_COLOR:加载彩色图片,这个是默认参数,可以直接写1。
# cv2.IMREAD_GRAYSCALE:以灰度模式加载图片,可以直接写0。
# cv2.IMREAD_UNCHANGED:包括alpha,可以直接写-1
imgIn = cv2.imread(img_path,1)
imgIn0= imgIn.copy() #形成image对象
rows, cols, channels = imgIn0.shape #d读取输入图像行数,列数,颜色通道
print('第%d幅图:'%i,rows, cols, channels)
cv2.namedWindow("window 1", flags=cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO)#窗口命名,并大小可变
cv2.imshow("window 1", imgIn)
cv2.namedWindow("window 2", flags=cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO)
cv2.imshow("window 2", imgIn0)
cv2.setMouseCallback("window 2", on_EVENT_LBUTTONDOWN,imgIn0)#手动点击进行特征点的提取
cv2.waitKey(0) #等待键盘点击事件来结束阻塞
print(point_in)
point_out = np.float32([[25, 30], [75, 30], [50, 75]])#左眼,右眼,嘴巴中心的特征点的坐标
# 估计由输出坐标到输入坐标的放射变换模型
M = cv2.getAffineTransform(np.float32(point_in), point_out)
print(M)
rows2,cols2 = 100,100 #指定输出图像的大小
#利用仿射变换模型,将输入图像仿射变换,产生输出图像
imgOut = cv2.warpAffine(imgIn, M, (cols2, rows2))
b, g, r = cv2.split(imgOut) #opencv 颜色读取方式为bgr
img2 = cv2.merge([r, g, b]) #plt则是rgb
plt.imshow(img2)
plt.show()
image_name = os.path.splitext(os.path.split(img_path)[1])[0] #获取文件名
cv2.imwrite(path_out+image_name+'_out.jpg',imgOut) #保存矫正后的人脸图片
print('*'*20 )
cv2.destroyAllWindows() #销毁所有窗口
if __name__ == '__main__':
path_in = r'imageIN/'
path_out = r'imageOUT/'
img_list=load_image(path_in)
show_image(img_list,path_out,point_in)
输入图像
输出图像:
代码执行结果
第0幅图: 373 360 3
[[358, 25], [170, 170], [215, 221]]
[[-3.83230932e-01 -1.52051139e-01 1.65997952e+02]
[ 4.04952523e-01 5.25041892e-01 -1.28099050e+02]]
********************