未验证 提交 3b20f676 编写于 作者: jm_12138's avatar jm_12138 提交者: GitHub

update pyramidbox_lite_server_mask (#2180)

上级 3cecfdb7
......@@ -179,6 +179,11 @@
# 打印预测结果
print(r.json()["results"])
```
- ### gradio app 支持
从 PaddleHub 2.3.1 开始支持使用链接 http://127.0.0.1:8866/gradio/pyramidbox_lite_server_mask 在浏览器中访问 pyramidbox_lite_server_mask 的 Gradio APP。
## 五、Paddle Lite部署
- ### 通过python执行以下代码,保存模型
- ```python
......@@ -209,6 +214,10 @@
修复无法导出推理模型的问题
* 1.5.0
添加 Gradio APP 的支持
- ```shell
$ hub install pyramidbox_lite_server_mask==1.4.0
$ hub install pyramidbox_lite_server_mask==1.5.0
```
......@@ -155,6 +155,10 @@
# print prediction results
print(r.json()["results"])
```
- ### Gradio APP support
Starting with PaddleHub 2.3.1, the Gradio APP for pyramidbox_lite_server_mask is supported to be accessed in the browser using the link http://127.0.0.1:8866/gradio/pyramidbox_lite_server_mask.
## V.Paddle Lite Deployment
- ### Save model demo
- ```python
......@@ -187,6 +191,10 @@
Fix a bug of save_inference_model
* 1.5.0
Add Gradio APP support.
- ```shell
$ hub install pyramidbox_lite_server_mask==1.4.0
$ hub install pyramidbox_lite_server_mask==1.5.0
```
# coding=utf-8
import os
import math
import os
import time
from collections import OrderedDict
......@@ -43,8 +43,7 @@ def bbox_vote(det):
det_accu[:, 0:4] = det_accu[:, 0:4] * np.tile(det_accu[:, -1:], (1, 4))
max_score = np.max(det_accu[:, 4])
det_accu_sum = np.zeros((1, 5))
det_accu_sum[:, 0:4] = np.sum(
det_accu[:, 0:4], axis=0) / np.sum(det_accu[:, -1:])
det_accu_sum[:, 0:4] = np.sum(det_accu[:, 0:4], axis=0) / np.sum(det_accu[:, -1:])
det_accu_sum[:, 4] = max_score
try:
dets = np.row_stack((dets, det_accu_sum))
......@@ -54,38 +53,26 @@ def bbox_vote(det):
return dets
def crop(image,
pts,
shift=0,
scale=1.5,
rotate=0,
res_width=128,
res_height=128):
def crop(image, pts, shift=0, scale=1.5, rotate=0, res_width=128, res_height=128):
res = (res_width, res_height)
idx1 = 0
idx2 = 1
# angle
alpha = 0
if pts[idx2, 0] != -1 and pts[idx2, 1] != -1 and pts[idx1, 0] != -1 and pts[
idx1, 1] != -1:
alpha = math.atan2(pts[idx2, 1] - pts[idx1, 1],
pts[idx2, 0] - pts[idx1, 0]) * 180 / math.pi
if pts[idx2, 0] != -1 and pts[idx2, 1] != -1 and pts[idx1, 0] != -1 and pts[idx1, 1] != -1:
alpha = math.atan2(pts[idx2, 1] - pts[idx1, 1], pts[idx2, 0] - pts[idx1, 0]) * 180 / math.pi
pts[pts == -1] = np.inf
coord_min = np.min(pts, 0)
pts[pts == np.inf] = -1
coord_max = np.max(pts, 0)
# coordinates of center point
c = np.array([
coord_max[0] - (coord_max[0] - coord_min[0]) / 2,
coord_max[1] - (coord_max[1] - coord_min[1]) / 2
]) # center
max_wh = max((coord_max[0] - coord_min[0]) / 2,
(coord_max[1] - coord_min[1]) / 2)
c = np.array([coord_max[0] - (coord_max[0] - coord_min[0]) / 2,
coord_max[1] - (coord_max[1] - coord_min[1]) / 2]) # center
max_wh = max((coord_max[0] - coord_min[0]) / 2, (coord_max[1] - coord_min[1]) / 2)
# Shift the center point, rot add eyes angle
c = c + shift * max_wh
rotate = rotate + alpha
M = cv2.getRotationMatrix2D((c[0], c[1]), rotate,
res[0] / (2 * max_wh * scale))
M = cv2.getRotationMatrix2D((c[0], c[1]), rotate, res[0] / (2 * max_wh * scale))
M[0, 2] = M[0, 2] - (c[0] - res[0] / 2.0)
M[1, 2] = M[1, 2] - (c[1] - res[0] / 2.0)
image_out = cv2.warpAffine(image, M, res)
......@@ -97,27 +84,24 @@ def color_normalize(image, mean, std=None):
image = np.repeat(image, axis=2)
h, w, c = image.shape
image = np.transpose(image, (2, 0, 1))
image = np.subtract(image.reshape(c, -1), mean[:, np.newaxis]).reshape(
-1, h, w)
image = np.subtract(image.reshape(c, -1), mean[:, np.newaxis]).reshape(-1, h, w)
image = np.transpose(image, (1, 2, 0))
return image
def process_image(org_im, face):
pts = np.array([
face['left'], face['top'], face['right'], face['top'], face['left'],
face['bottom'], face['right'], face['bottom']
face['left'], face['top'], face['right'], face['top'], face['left'], face['bottom'], face['right'],
face['bottom']
]).reshape(4, 2).astype(np.float32)
image_in, M = crop(org_im, pts)
image_in = image_in / 256.0
image_in = color_normalize(image_in, mean=np.array([0.5, 0.5, 0.5]))
image_in = image_in.astype(np.float32).transpose([2, 0, 1]).reshape(
-1, 3, 128, 128)
image_in = image_in.astype(np.float32).transpose([2, 0, 1]).reshape(-1, 3, 128, 128)
return image_in
def reader(face_detector, shrink, confs_threshold, images, paths, use_gpu,
use_multi_scale):
def reader(face_detector, shrink, confs_threshold, images, paths, use_gpu, use_multi_scale):
"""
Preprocess to yield image.
......@@ -142,8 +126,7 @@ def reader(face_detector, shrink, confs_threshold, images, paths, use_gpu,
assert type(paths) is list, "paths should be a list."
for im_path in paths:
each = OrderedDict()
assert os.path.isfile(
im_path), "The {} isn't a valid file path.".format(im_path)
assert os.path.isfile(im_path), "The {} isn't a valid file path.".format(im_path)
im = cv2.imread(im_path)
each['org_im'] = im
each['org_im_path'] = im_path
......@@ -153,8 +136,7 @@ def reader(face_detector, shrink, confs_threshold, images, paths, use_gpu,
for im in images:
each = OrderedDict()
each['org_im'] = im
each['org_im_path'] = 'ndarray_time={}'.format(
round(time.time(), 6) * 1e6)
each['org_im_path'] = 'ndarray_time={}'.format(round(time.time(), 6) * 1e6)
component.append(each)
for element in component:
......@@ -162,19 +144,15 @@ def reader(face_detector, shrink, confs_threshold, images, paths, use_gpu,
scale_res = list()
detect_faces = list()
for scale in multi_scales:
_detect_res = face_detector.face_detection(
images=[element['org_im']],
use_gpu=use_gpu,
visualization=False,
shrink=scale,
confs_threshold=confs_threshold)
_detect_res = face_detector.face_detection(images=[element['org_im']],
use_gpu=use_gpu,
visualization=False,
shrink=scale,
confs_threshold=confs_threshold)
_s = list()
for _face in _detect_res[0]['data']:
_face_list = [
_face['left'], _face['top'], _face['right'],
_face['bottom'], _face['confidence']
]
_face_list = [_face['left'], _face['top'], _face['right'], _face['bottom'], _face['confidence']]
_s.append(_face_list)
if _s:
......@@ -185,23 +163,16 @@ def reader(face_detector, shrink, confs_threshold, images, paths, use_gpu,
keep_index = np.where(scale_res[:, 4] >= confs_threshold)[0]
scale_res = scale_res[keep_index, :]
for data in scale_res:
face = {
'left': data[0],
'top': data[1],
'right': data[2],
'bottom': data[3],
'confidence': data[4]
}
face = {'left': data[0], 'top': data[1], 'right': data[2], 'bottom': data[3], 'confidence': data[4]}
detect_faces.append(face)
else:
detect_faces = []
else:
_detect_res = face_detector.face_detection(
images=[element['org_im']],
use_gpu=use_gpu,
visualization=False,
shrink=shrink,
confs_threshold=confs_threshold)
_detect_res = face_detector.face_detection(images=[element['org_im']],
use_gpu=use_gpu,
visualization=False,
shrink=shrink,
confs_threshold=confs_threshold)
detect_faces = _detect_res[0]['data']
element['preprocessed'] = list()
......
......@@ -10,11 +10,11 @@ import numpy as np
import paddle
from paddle.inference import Config
from paddle.inference import create_predictor
import paddlehub as hub
from .data_feed import reader
from .processor import base64_to_cv2
from .processor import postprocess
import paddlehub as hub
from paddlehub.module.module import moduleinfo
from paddlehub.module.module import runnable
from paddlehub.module.module import serving
......@@ -29,6 +29,7 @@ from paddlehub.module.module import serving
"PyramidBox-Lite-Server-Mask is a high-performance face detection model used to detect whether people wear masks.",
version="1.4.0")
class PyramidBoxLiteServerMask:
def __init__(self, face_detector_module=None):
"""
Args:
......@@ -46,8 +47,8 @@ class PyramidBoxLiteServerMask:
"""
predictor config setting
"""
model = self.default_pretrained_model_path+'.pdmodel'
params = self.default_pretrained_model_path+'.pdiparams'
model = self.default_pretrained_model_path + '.pdmodel'
params = self.default_pretrained_model_path + '.pdiparams'
cpu_config = Config(model, params)
cpu_config.disable_glog_info()
cpu_config.disable_gpu()
......@@ -243,3 +244,28 @@ class PyramidBoxLiteServerMask:
type=ast.literal_eval,
default=0.6,
help="confidence threshold.")
def create_gradio_app(self):
import gradio as gr
import tempfile
import os
from PIL import Image
def inference(image, shrink, confs_threshold):
with tempfile.TemporaryDirectory() as temp_dir:
self.face_detection(paths=[image],
use_gpu=False,
visualization=True,
output_dir=temp_dir,
shrink=shrink,
confs_threshold=confs_threshold)
return Image.open(os.path.join(temp_dir, os.listdir(temp_dir)[0]))
interface = gr.Interface(inference, [
gr.inputs.Image(type="filepath"),
gr.Slider(0.0, 1.0, 0.5, step=0.01),
gr.Slider(0.0, 1.0, 0.6, step=0.01)
],
gr.outputs.Image(type="ndarray"),
title='pyramidbox_lite_server_mask')
return interface
......@@ -3,13 +3,14 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import base64
import os
import time
import base64
import cv2
import numpy as np
from PIL import Image, ImageDraw
from PIL import Image
from PIL import ImageDraw
__all__ = ['base64_to_cv2', 'postprocess']
......@@ -56,8 +57,7 @@ def get_save_image_name(org_im, org_im_path, output_dir):
# save image path
save_im_path = os.path.join(output_dir, im_prefix + ext)
if os.path.exists(save_im_path):
save_im_path = os.path.join(
output_dir, im_prefix + 'time={}'.format(int(time.time())) + ext)
save_im_path = os.path.join(output_dir, im_prefix + 'time={}'.format(int(time.time())) + ext)
return save_im_path
......@@ -68,19 +68,13 @@ def draw_bounding_box_on_image(save_im_path, output_data):
for bbox in output_data:
# draw bouding box
if bbox['label'] == "MASK":
draw.line([(bbox['left'], bbox['top']),
(bbox['left'], bbox['bottom']),
(bbox['right'], bbox['bottom']),
(bbox['right'], bbox['top']),
(bbox['left'], bbox['top'])],
draw.line([(bbox['left'], bbox['top']), (bbox['left'], bbox['bottom']), (bbox['right'], bbox['bottom']),
(bbox['right'], bbox['top']), (bbox['left'], bbox['top'])],
width=2,
fill='green')
else:
draw.line([(bbox['left'], bbox['top']),
(bbox['left'], bbox['bottom']),
(bbox['right'], bbox['bottom']),
(bbox['right'], bbox['top']),
(bbox['left'], bbox['top'])],
draw.line([(bbox['left'], bbox['top']), (bbox['left'], bbox['bottom']), (bbox['right'], bbox['bottom']),
(bbox['right'], bbox['top']), (bbox['left'], bbox['top'])],
width=2,
fill='red')
# draw label
......@@ -93,17 +87,14 @@ def draw_bounding_box_on_image(save_im_path, output_data):
box_fill = (255)
text_fill = (0)
draw.rectangle(
xy=(bbox['left'], bbox['top'] - (textsize_height + 5),
bbox['left'] + textsize_width + 10, bbox['top'] - 3),
fill=box_fill)
draw.text(
xy=(bbox['left'], bbox['top'] - 15), text=text, fill=text_fill)
draw.rectangle(xy=(bbox['left'], bbox['top'] - (textsize_height + 5), bbox['left'] + textsize_width + 10,
bbox['top'] - 3),
fill=box_fill)
draw.text(xy=(bbox['left'], bbox['top'] - 15), text=text, fill=text_fill)
image.save(save_im_path)
def postprocess(confidence_out, org_im, org_im_path, detected_faces, output_dir,
visualization):
def postprocess(confidence_out, org_im, org_im_path, detected_faces, output_dir, visualization):
"""
Postprocess output of network. one element at a time.
......
......@@ -4,13 +4,14 @@ import unittest
import cv2
import requests
import paddlehub as hub
import paddlehub as hub
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
class TestHubModule(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
img_url = 'https://unsplash.com/photos/iFgRcqHznqg/download?ixid=MnwxMjA3fDB8MXxzZWFyY2h8MXx8ZmFjZXxlbnwwfHx8fDE2NjE5ODAyMTc&force=true&w=640'
......@@ -29,11 +30,7 @@ class TestHubModule(unittest.TestCase):
shutil.rmtree('detection_result')
def test_face_detection1(self):
results = self.module.face_detection(
paths=['tests/test.jpg'],
use_gpu=False,
visualization=False
)
results = self.module.face_detection(paths=['tests/test.jpg'], use_gpu=False, visualization=False)
bbox = results[0]['data'][0]
label = bbox['label']
......@@ -42,7 +39,7 @@ class TestHubModule(unittest.TestCase):
right = bbox['right']
top = bbox['top']
bottom = bbox['bottom']
self.assertEqual(label, 'NO MASK')
self.assertTrue(confidence > 0.5)
self.assertTrue(0 < left < 2000)
......@@ -51,11 +48,7 @@ class TestHubModule(unittest.TestCase):
self.assertTrue(0 < bottom < 2000)
def test_face_detection2(self):
results = self.module.face_detection(
images=[cv2.imread('tests/test.jpg')],
use_gpu=False,
visualization=False
)
results = self.module.face_detection(images=[cv2.imread('tests/test.jpg')], use_gpu=False, visualization=False)
bbox = results[0]['data'][0]
label = bbox['label']
......@@ -64,7 +57,7 @@ class TestHubModule(unittest.TestCase):
right = bbox['right']
top = bbox['top']
bottom = bbox['bottom']
self.assertEqual(label, 'NO MASK')
self.assertTrue(confidence > 0.5)
self.assertTrue(0 < left < 2000)
......@@ -73,11 +66,7 @@ class TestHubModule(unittest.TestCase):
self.assertTrue(0 < bottom < 2000)
def test_face_detection3(self):
results = self.module.face_detection(
images=[cv2.imread('tests/test.jpg')],
use_gpu=False,
visualization=True
)
results = self.module.face_detection(images=[cv2.imread('tests/test.jpg')], use_gpu=False, visualization=True)
bbox = results[0]['data'][0]
label = bbox['label']
......@@ -86,7 +75,7 @@ class TestHubModule(unittest.TestCase):
right = bbox['right']
top = bbox['top']
bottom = bbox['bottom']
self.assertEqual(label, 'NO MASK')
self.assertTrue(confidence > 0.5)
self.assertTrue(0 < left < 2000)
......@@ -95,11 +84,7 @@ class TestHubModule(unittest.TestCase):
self.assertTrue(0 < bottom < 2000)
def test_face_detection4(self):
results = self.module.face_detection(
images=[cv2.imread('tests/test.jpg')],
use_gpu=True,
visualization=False
)
results = self.module.face_detection(images=[cv2.imread('tests/test.jpg')], use_gpu=True, visualization=False)
bbox = results[0]['data'][0]
label = bbox['label']
......@@ -108,7 +93,7 @@ class TestHubModule(unittest.TestCase):
right = bbox['right']
top = bbox['top']
bottom = bbox['bottom']
self.assertEqual(label, 'NO MASK')
self.assertTrue(confidence > 0.5)
self.assertTrue(0 < left < 2000)
......@@ -117,18 +102,10 @@ class TestHubModule(unittest.TestCase):
self.assertTrue(0 < bottom < 2000)
def test_face_detection5(self):
self.assertRaises(
AssertionError,
self.module.face_detection,
paths=['no.jpg']
)
self.assertRaises(AssertionError, self.module.face_detection, paths=['no.jpg'])
def test_face_detection6(self):
self.assertRaises(
AttributeError,
self.module.face_detection,
images=['test.jpg']
)
self.assertRaises(AttributeError, self.module.face_detection, images=['test.jpg'])
def test_save_inference_model(self):
self.module.save_inference_model('./inference/model')
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册