1
In [1]:
import cv2
import sys
import numpy as np
import datetime
import os
import glob
from retinaface import RetinaFace
In [2]:
thresh = 0.8
scales = [1024, 1980]
count = 1
gpuid = 0
detector = RetinaFace('./model/R50', 0, gpuid, 'net3')
In [3]:
img = cv2.imread('t1.jpg')
print(img.shape)
im_shape = img.shape
target_size = scales[0]
max_size = scales[1]
im_size_min = np.min(im_shape[0:2])
im_size_max = np.max(im_shape[0:2])
#im_scale = 1.0
#if im_size_min>target_size or im_size_max>max_size:
im_scale = float(target_size) / float(im_size_min)
# prevent bigger axis from being more than max_size:
if np.round(im_scale * im_size_max) > max_size:
im_scale = float(max_size) / float(im_size_max)
print('im_scale', im_scale)
In [4]:
scales = [im_scale]
flip = False
In [5]:
scales
Out[5]:
In [6]:
for c in range(count):
faces, landmarks = detector.detect(img, thresh, scales=scales, do_flip=flip)
print(c, faces.shape, landmarks.shape)
In [7]:
c
Out[7]:
In [8]:
faces
Out[8]:
In [9]:
bbox = faces[0].astype(np.int)
In [10]:
bbox
Out[10]:
In [11]:
landmarks
Out[11]:
In [12]:
landmark5 = landmarks[0].astype(np.int)
In [13]:
landmark5
Out[13]:
In [14]:
cropImg = img[bbox[0]:bbox[2], bbox[1]:bbox[3]]
filename = './cropImg.jpg'
In [15]:
from matplotlib import pyplot as plt
# draw a cvMat using plt.
def draw(image):
plt.figure(figsize=(15,10)) # 设置画布
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.show()
draw(img)
In [16]:
cv2.imwrite(filename, cropImg)
Out[16]:
In [17]:
color = (0,0,255)
box = bbox
参数解释
第一个参数:img是原图
第二个参数:(x,y)是矩阵的左上点坐标
第三个参数:(x+w,y+h)是矩阵的右下点坐标
第四个参数:(0,255,0)是画线对应的rgb颜色
第五个参数:2是所画的线的宽度
In [18]:
img2 = img.copy() # cpy a new img
cv2.rectangle(img2, (box[0], box[1]), (box[2], box[3]), color, 2)
for l in range(landmark5.shape[0]):
color = (0,0,255)
if l==0 or l==3:
color = (0,255,0)
cv2.circle(img2, (landmark5[l][0], landmark5[l][1]), 1, color, 2)
draw(img2)
In [19]:
draw(img)
In [20]:
cropImg = img[bbox[1]:bbox[3], bbox[0]:bbox[2]] # 裁剪坐标为[y0:y1, x0:x1]
draw(cropImg)
In [21]:
cropImg.shape
Out[21]:
In [22]:
# 设置目标长宽
width,height = [112, 112]
dim = (width, height)
In [23]:
# 进行缩放
resized = cv2.resize(cropImg, dim, interpolation=cv2.INTER_AREA)
draw(resized)
In [24]:
import cv2
import numpy as np
from skimage import transform as trans
src1 = np.array([
[51.642,50.115],
[57.617,49.990],
[35.740,69.007],
[51.157,89.050],
[57.025,89.702]], dtype=np.float32)
#<--left
src2 = np.array([
[45.031,50.118],
[65.568,50.872],
[39.677,68.111],
[45.177,86.190],
[64.246,86.758]], dtype=np.float32)
#---frontal
src3 = np.array([
[39.730,51.138],
[72.270,51.138],
[56.000,68.493],
[42.463,87.010],
[69.537,87.010]], dtype=np.float32)
#-->right
src4 = np.array([
[46.845,50.872],
[67.382,50.118],
[72.737,68.111],
[48.167,86.758],
[67.236,86.190]], dtype=np.float32)
#-->right profile
src5 = np.array([
[54.796,49.990],
[60.771,50.115],
[76.673,69.007],
[55.388,89.702],
[61.257,89.050]], dtype=np.float32)
src = np.array([src1,src2,src3,src4,src5])
src_map = {112 : src, 224 : src*2}
arcface_src = np.array([
[38.2946, 51.6963],
[73.5318, 51.5014],
[56.0252, 71.7366],
[41.5493, 92.3655],
[70.7299, 92.2041] ], dtype=np.float32 )
arcface_src = np.expand_dims(arcface_src, axis=0)
# In[66]:
# lmk is prediction; src is template
def estimate_norm(lmk, image_size = 112, mode='arcface'):
assert lmk.shape==(5,2)
tform = trans.SimilarityTransform()
lmk_tran = np.insert(lmk, 2, values=np.ones(5), axis=1)
min_M = []
min_index = []
min_error = float('inf')
if mode=='arcface':
assert image_size==112
src = arcface_src
else:
src = src_map[image_size]
for i in np.arange(src.shape[0]):
tform.estimate(lmk, src[i])
M = tform.params[0:2,:]
results = np.dot(M, lmk_tran.T)
results = results.T
error = np.sum(np.sqrt(np.sum((results - src[i]) ** 2,axis=1)))
# print(error)
if error< min_error:
min_error = error
min_M = M
min_index = i
return min_M, min_index
def norm_crop(img, landmark, image_size=112, mode='arcface'):
M, pose_index = estimate_norm(landmark, image_size, mode)
warped = cv2.warpAffine(img, M, (image_size, image_size), borderValue = 0.0)
return warped
In [25]:
# 人脸校正
warped_img = norm_crop(img, landmark5, image_size=112, mode='arcface') # img 为原大图像, 利用绝对坐标
draw(cropImg)
draw(warped_img)
In [26]:
import cv2
import requests
import time
from PIL import Image
from io import BytesIO
import numpy as np
from matplotlib import pyplot as plt
%matplotlib inline
# set None proxy设置成没有代理,因为ubuntu终端和浏览器切换代理,老是报错。采取此粗暴的方法。
import os
os.environ['no_proxy'] = '*'
In [27]:
# get file(of Internet picture)
class InternetPicture:
def __init__(self, url):
# attribute
self.url = url
self.img = None
# initial method
self.get() # self代表类的实例, 而非类本身,所以self.get(self)--> self.get()
self.show()
self.info()
# get Internet Picture
def get(self):
for i in range(5): # 多获取几次,增加成功率
start=time.time()
file = requests.get(self.url)
img = cv2.imdecode(np.fromstring(file.content, np.uint8), 1) #file.content 是读取的远程文件的字节流
print(i + 1, ' time of Requesting Time:', time.time()-start)
self.img = img
print('get a file of:', type(img))
# show image
def show(self):
#using plt draw picture
plt.figure() # 设置画布
plt.imshow(cv2.cvtColor(self.img, cv2.COLOR_BGR2RGB))
plt.show()
def info(self):
# using cv2 to read Internet file of picture
color_img = self.img
gray_img = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
# 获取信息:行,列,通道,像素数目,图像数据类型
print('获取信息:行,列,通道,像素数目,图像数据类型')
print(color_img.shape, color_img.size, color_img.dtype)
print(gray_img.shape, gray_img.size, gray_img.dtype)
print('self.img: get a numpy image')
print('self.show(): show a numpy image using plt')
# using PIL.Image to read Internet file of picture
## image = Image.open(BytesIO(file.content))
## image.show()
# draw a cvMat using plt.
def draw(image):
plt.figure() # 设置画布
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.show()
In [28]:
# 实例化类,并获取一个网络图像
url = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1565251010&di=6420fef2a0e34245435d32e74ff17efd&imgtype=jpg&er=1&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201706%2F11%2F20170611163626_8wmsc.jpeg'
instance = InternetPicture(url)
In [29]:
img = instance.img
for c in range(count):
faces, landmarks = detector.detect(img, thresh, scales=scales, do_flip=flip)
print(c, faces.shape, landmarks.shape)
In [30]:
# 人脸校正
warped_img = norm_crop(img, landmarks[0], image_size=112, mode='arcface') # img 为原大图像, 利用绝对坐标
bbox = faces[0].astype(np.int)
cropImg = img[bbox[1]:bbox[3], bbox[0]:bbox[2]] # 裁剪坐标为[y0:y1, x0:x1]
draw(cropImg)
draw(warped_img)
In [ ]: