| | from io import BytesIO, StringIO |
| | import cv2 |
| | from anime_face_detector import create_detector |
| | from werkzeug.wsgi import FileWrapper |
| | from flask import Flask, request, Response, send_file |
| | import math |
| | import numpy as np |
| |
|
| | def get_deg(arr): |
| | rad = math.atan2(arr[3]-arr[1],arr[2]-arr[0]) |
| | PI = math.pi |
| | deg = (rad*180)/PI |
| | return deg |
| |
|
| | detector = create_detector('yolov3', device='cpu') |
| |
|
| | gg = cv2.imread('gg.png', cv2.IMREAD_UNCHANGED) |
| | gg = cv2.cvtColor(gg, cv2.COLOR_BGRA2RGBA) |
| |
|
| | def generate(image_file: BytesIO) -> bytes: |
| | encoded = np.asarray(bytearray(image_file.read()), dtype=np.uint8) |
| | img = cv2.imdecode(encoded, cv2.IMREAD_COLOR) |
| | preds = detector(img) |
| | img = cv2.cvtColor(img, cv2.COLOR_BGR2RGBA) |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | if len(preds) == 0: |
| | return False |
| |
|
| | for face in preds: |
| | points = face['keypoints'] |
| | color = img[int(points[27][1]), int(points[27][0])+10] |
| | polygon = np.array([ |
| | [points[0][0], points[0][1]], |
| | [points[1][0], points[1][1]], |
| | [points[2][0], points[2][1]], |
| | [points[3][0], points[4][1]], |
| | [points[4][0], points[4][1]], |
| | [points[10][0], points[10][1]], |
| | [points[9][0], points[9][1]], |
| | [points[8][0], points[8][1]], |
| | [points[7][0], points[7][1]], |
| | [points[6][0], points[6][1]], |
| | [points[5][0], points[5][1]] |
| | ], np.int32) |
| | cv2.fillConvexPoly(img, polygon, color=(int(color[0]), int(color[1]), int(color[2]), 255)) |
| | deg = get_deg([points[0][0], points[0][1], points[4][0], points[4][1]]) |
| | rotated = gg.copy() |
| | resize = math.sqrt((points[10][0] - points[5][0])**2 + (points[10][1] - points[5][1])**2) |
| | rotated = cv2.resize(rotated, (int(resize), int(resize*1.12))) |
| | matrix = cv2.getPerspectiveTransform( |
| | np.float32([[0, 0], [rotated.shape[0],0], [0, rotated.shape[1]], [rotated.shape[0],rotated.shape[1]]]), |
| | np.float32([[points[5][0], points[5][1]], [points[10][0], points[10][1]], [points[1][0], points[1][1]], [points[3][0], points[3][1]]])) |
| | rotated = cv2.warpPerspective(rotated, matrix, (img.shape[1], img.shape[0])) |
| |
|
| | alpha = rotated[:, :, 3] / 255. |
| | for i in range(3): |
| | pointx, pointy = points[5][:2] |
| | pointx, pointy = int(pointx), int(pointy) |
| | img[:, :, i] = (1. - alpha) * img[0:, 0:, i] + alpha * rotated[:, :, i] |
| | |
| | |
| | |
| | buffer = cv2.imencode('.png', cv2.cvtColor(img, cv2.COLOR_RGBA2BGRA))[1] |
| | |
| | return buffer.tobytes() |
| | |
| |
|
| | app = Flask(__name__) |
| |
|
| | @app.post('/generate') |
| | def index(): |
| | if request.files.get('file') is None: |
| | return "no file", 400 |
| | file = request.files.get('file') |
| | dst = BytesIO() |
| | file.save(dst) |
| | dst.seek(0) |
| | result = generate(dst) |
| | if not result: |
| | return {"status": 400}, 400 |
| | return Response(result, mimetype='image/png', direct_passthrough=True) |
| | |
| | if __name__ == "__main__": |
| | app.run("0.0.0.0", 8080, debug=False) |