предисловие
Сразу после «Double Eleven», в этот период, когда все люди едят грязь, Сяньюй очень близко запустил деятельность пакетов выражения со вкусом земли.Вы можете настроить набор выражений, чтобы жаловаться и делиться чувствами каждого о еде земли.Эта статья познакомит Как быстро создать такой проект активности на основе распознавания лиц с помощью Python и weex.
Ключевые слова: weex, Python, распознавание лиц
1. Фронтальная конструкция
Страница интерфейса в основном состоит из двух частей: фотографирования и создания выражений.
1.1 Фотосъемка
Модуль камеры Windvane используется для съемки изображений. В настоящее время он может поддерживать только среду weex. В настоящее время среда h5 может направлять пользователей только к Xianyu или Hand Tao для создания приземленных выражений с помощью подсказок и тяг. В последней версии 8.1.0 Shoutao могут быть проблемы со съемкой и загрузкой картинок напрямую с WVCamera.takePhoto, поэтому нужно вызывать картинки и загружать картинки отдельно, а для загрузки картинок использовать интерфейс WVCamera.confirmUploadPhoto.
var params = {
type: '0',
};
window.WindVane.call('WVCamera', 'takePhoto', params, function(e) {
var uploadParams = {
// 需要上传的照片的路径
path: e.localPath,
// 上传方式
v: '2.0',
// 业务代码
bizCode: 'mtopupload'
};
setTimeout(function() {
window.WindVane.call('WVCamera', 'confirmUploadPhoto', uploadParams, function(e) {
alert('upload success: ' + JSON.stringify(e));
}, function(e) {
alert('upload failure: ' + JSON.stringify(e));
});
}, 20);
}, function(e) {
alert('takePhoto failure: ' + JSON.stringify(e));
});
скопировать код
1.2 Создание выражений
Вызывая фоновый интерфейс, передавая адрес фотографии и номер шаблона выражения, после создания выражения интерфейс вернет адрес выражения, а затем отобразит его. Эффект следующий
2. Строительство сервера
Инженерный сервер построен на чистом Python, который может удовлетворить потребности быстрого создания и развертывания онлайн-активностей.Он использует Http-сервер, созданный двумя библиотеками: SocketServer и BaseHTTPServer:
socketserver — это высокоуровневый модуль стандартной библиотеки для реализации сетевых клиентов и серверов. В модуле реализованы некоторые доступные классы.Модуль socketserver включает в себя множество классов, которые могут упростить реализацию серверов сокетов домена TCP, UDP и UNIX;
Модуль BaseHTTPServer создает базовый класс обработки HTTP-запросов BaseHTTPRequestHandler, который наследуется от класса StreamRequestHandler в модуле SocketServer;
Пользоваться очень удобно, а вызов выглядит следующим образом:
import BaseHTTPServer as webservice
from SocketServer import ThreadingMixIn
from BaseHTTPServer import HTTPServer,BaseHTTPRequestHandler
if __name__ == '__main__':
serverAddress = ('', PORT)
server = ThreadingHttpServer(serverAddress, RequestHandler)
server.serve_forever()
скопировать код
Когда есть HTTP-запрос, будет запущен обратный вызов do_GET RequestHandler, и бизнес-код внутри будет выполнен.
class RequestHandler(webservice.BaseHTTPRequestHandler):
def do_GET(self):
скопировать код
После реализации базового вызова следующая работа — использовать ThreadingHttpServer для реализации многопоточного веб-сервера, выполнения проверки подписи параметров, использования Nginx для раздачи и т. д. Не буду вдаваться в подробности.
3. Выбор алгоритма
Процесс интеграции лица в пакет экспрессии можно разделить на четыре этапа:
-
Распознавание лиц
-
выравнивание лица
-
Извлекайте черты лица и синтезируйте их в наборы выражений
-
Скорректировать тон лица
3.1 В части распознавания лиц, мы используем библиотеку dlib, которая может легко и быстро определить 68 точек на лице.Распределение позиций точек показано на рисунке:
Это просто в использовании:
# 初始化dlib
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(PREDICTOR_PATH)
# 获取脸部特征点
def get_landmarks(im):
rects = detector(im, 1)
if len(rects) > 1:
raise TooManyFaces
if len(rects) == 0:
raise NoFaces
return numpy.matrix([[p.x, p.y] for p in predictor(im, rects[0]).parts()])
скопировать код
3.2 Выравнивание положения лица, после того как мы получим матрицу меток двух граней, вычислим поворот с помощью разложения по сингулярным числам, а затем используем матрицу аффинного преобразования для преобразования:
def warp_im(im, M, dshape):
output_im = numpy.zeros(dshape, dtype=im.dtype)
cv2.warpAffine(im,
M[:2],
(dshape[1], dshape[0]),
dst=output_im,
borderMode=cv2.BORDER_TRANSPARENT,
flags=cv2.WARP_INVERSE_MAP)
return output_im
скопировать код
3.3 Извлечение промежуточных черт лицаВключая глаза, брови, нос, рот, ключевую область этой Т-образной формы, вам нужно соединить функции в выпуклый многоугольник, а затем использовать cv.fillConvexPoly для заполнения, чтобы сгенерировать маску-маску, внешний край маска растушевывается и расширяется, а прерывность скрыта. Базовая карта пакета смайликов должна сначала стереть исходное выражение, чтобы исходные черты не повлияли на рисунок фотографии, а затем выровнять маску с матрицей черт лица на изображении. базовая карта пакета emoji для получения смешанного рисунка.
3.4 Настройка тона лицаЭто последний шаг. Лицо, синтезированное на предыдущем шаге, по-прежнему имеет исходное значение цвета. Его необходимо преобразовать в черно-белое изображение. Сначала удалите цвет, а затем используйте гамма-кривую для настройки контраста, поэтому что черная часть лица темнее, белая часть белее, а черты более очевидны. , способ регулировки контрастности следующий:
# 传入参数越大对比度越高
def gamma_trans(img,gamma):
gamma_table = [numpy.power(x/255.0,gamma)*255.0 for x in range(256)]
gamma_table = numpy.round(numpy.array(gamma_table)).astype(numpy.uint8)
return cv2.LUT(img,gamma_table)
скопировать код
4. Оптимизация алгоритма
Мы сделали простую оптимизацию алгоритма с двух сторон:
Один из них - использоватьМногопроцессная оптимизация, на этом шаге используется реализация библиотеки loky:
import loky
from loky import get_reusable_executor
скопировать код
Исполнительная часть:
# work_thread为机器能使用的最大进程数
executor = get_reusable_executor(max_workers=work_thread, timeout=60)
params = []
# 传入需要多进程执行的方法名和参数,多个参数需要合成一个传入
result = executor.map(do_func, params)
try:
while 1:
re = result.next()
скопировать код
Следует отметить, что инициализирующую часть dlib необходимо поместить в функцию, оптимизированную для нескольких процессов. process, она будет вызываться один раз для каждой инициализации. , что также является трудоемким моментом, и его необходимо взвешивать и оптимизировать при использовании.
Еще один момент, на который стоит обратить внимание, это то, что если ваша функция реализована на Python2, нельзя использовать другую более популярную и удобную многопроцессорную библиотеку Process, которая будет конфликтовать с dlib.
два этоЗона обнаружения сжатия, вы можете сделать копию исходного изображения, а затем сжать копию до 1/4, затем передать ее в dlib для идентификации, а затем умножить идентифицированный массив объектов ориентиров на 4, чтобы получить исходное положение объекта, а затем обработать оригинал изображение и восстановление Последний набор точек функции. Помимо сжатия, количество вычислений dlib также можно уменьшить за счет кадрирования, перехвата области ROI, вырезания области лица пакета эмодзи и передачи его в dlib при распознавании, фокусировки на среднем положении картинки, или может сотрудничать с удалением фона OpenCV, чтобы уменьшить область распознавания.
Суммировать
Выше приведен весь процесс реализации пакета выражений.Есть еще много моментов, которые можно оптимизировать с точки зрения производительности и эффекта.Вы можете попробовать «Спасите Тузу» в Xianyu или Hand Tao, чтобы настроить пакет выражений и внести предложения. и отзывы~
Обратите внимание на официальный аккаунт и освойте передовые технологии.