主要部分
import cv2
from face_detector.detect_engine import FaceDetectionEngine
detector = FaceDetectionEngine(weights_path="face_detector/s3fd_convert.pth")
img = cv2.imread("pic_3.jpg")
preds = detector.predict(img, dilate_bbox=True)#人脸框,小数
crops = [detector.crop(img, i) for i in preds]
print(len(crops))
for i in range(len(crops)):
cv2.imwrite(str(i)+'.png',crops[i])
#画人脸框
for index, bbox in enumerate(preds):
if bbox is not None:
ymin, xmin, ymax ,xmax = [int(i) for i in bbox]#取整
cv2.rectangle(img, (ymin, xmin), (ymax, xmax), (0, 0, 255), 2) # 画图
cv2.imwrite('mul_rec.jpg', img) # 保存
样例展示:
结果展示:
画人脸框:
代码部分使用的是:
https://github.com/kiselev1189/face-detector-s3fd
里面也有权重
detect_engine.py部分
import os
import torch
import torch.nn.functional as F
import face_recognition
import numpy as np
from .net_s3fd import s3fd
from .bbox import decode, nms
from .image import Image
class FaceDetectionEngine:
def __init__(self, **kwargs):
weights_path = kwargs.get(
'weights_path',
os.path.join(
os.path.dirname(os.path.realpath(__file__)),
's3fd_convert.pth'
),
)
self._net = s3fd()
self._net.load_state_dict(torch.load(weights_path))
if torch.cuda.is_available():
self._net.cuda()
self._net.eval()
@staticmethod
def dilate_bbox(bbox, dilate_pixels):
#0, 1 upper left
#2, 3 lower right
bbox[0] = bbox[0] - dilate_pixels
bbox[1] = bbox[1] - dilate_pixels
bbox[2] = bbox[2] + dilate_pixels
bbox[3] = bbox[3] + dilate_pixels
bbox = np.clip(bbox, 0, 4000)
return bbox
def predict(self, img, dilate_bbox=True, dilate_pixels=10):
img = Image(img)
bboxlist = self._detect(img)
keep = nms(bboxlist, 0.3)
bboxlist = bboxlist[keep, :]
bboxlist = [x[:-1] for x in bboxlist if x[-1] > 0.5]
if dilate_bbox:
return [self.dilate_bbox(box, dilate_pixels) for box in bboxlist]
return bboxlist
@staticmethod
def crop(img, bbox):
bbox = [int(i) for i in bbox]
return img[bbox[1]:bbox[3], bbox[0]:bbox[2], :]
def _detect(self, img):
net = self._net
img = img - np.array([104, 117, 123])
img = img.transpose(2, 0, 1)
img = img.reshape((1,) + img.shape)
img = torch.from_numpy(img).float()
if torch.cuda.is_available():
img = img.cuda()
# BB, CC, HH, WW = img.size()
with torch.no_grad():
olist = net(img)
bboxlist = []
for i in range(len(olist) // 2):
olist[i * 2] = F.softmax(olist[i * 2], dim=1)
olist = [oelem.data.cpu() for oelem in olist]
for i in range(len(olist) // 2):
ocls, oreg = olist[i * 2