Download app.py from Kroy/face_blur: direct link, hf CLI and curl.
- Browser
- Download file 5.02 kB
-
https://huggingface.co/spaces/Kroy/face_blur/resolve/main/app.py
- Command line
-
hf download hf://spaces/Kroy/face_blur/app.py
-
curl -L -o app.py https://huggingface.co/spaces/Kroy/face_blur/resolve/main/app.py
5.02 kB
| from fastapi import FastAPI | |
| import os | |
| from typing import Any, Union,Dict, List | |
| import numpy as np | |
| import io | |
| import base64 | |
| import requests | |
| import cv2 | |
| from PIL import Image | |
| # Create a new FastAPI app instance | |
| app = FastAPI() | |
| # Initialize the text generation pipeline | |
| # This function will be able to generate text | |
| # given an input. | |
| prototxtPath = os.path.sep.join(["face_detector", "deploy.prototxt"]) | |
| weightsPath = os.path.sep.join(["face_detector", | |
| "res10_300x300_ssd_iter_140000.caffemodel"]) | |
| net = cv2.dnn.readNet(prototxtPath, weightsPath) | |
| # Define a function to handle the GET request at `/generate` | |
| # The generate() function is defined as a FastAPI route that takes a | |
| # string parameter called text. The function generates text based on the # input using the pipeline() object, and returns a JSON response | |
| # containing the generated text under the key "output" | |
| args = { | |
| "method": "simple", | |
| "blocks": 20, | |
| "confidence": 0.5 | |
| } | |
| def anonymize_face_simple(image, factor=3.0): | |
| # automatically determine the size of the blurring kernel based | |
| # on the spatial dimensions of the input image | |
| (h, w) = image.shape[:2] | |
| kW = int(w / factor) | |
| kH = int(h / factor) | |
| # ensure the width of the kernel is odd | |
| if kW % 2 == 0: | |
| kW -= 1 | |
| # ensure the height of the kernel is odd | |
| if kH % 2 == 0: | |
| kH -= 1 | |
| # apply a Gaussian blur to the input image using our computed | |
| # kernel size | |
| return cv2.GaussianBlur(image, (kW, kH), 0) | |
| def anonymize_face_pixelate(image, blocks=3): | |
| # divide the input image into NxN blocks | |
| (h, w) = image.shape[:2] | |
| xSteps = np.linspace(0, w, blocks + 1, dtype="int") | |
| ySteps = np.linspace(0, h, blocks + 1, dtype="int") | |
| # loop over the blocks in both the x and y direction | |
| for i in range(1, len(ySteps)): | |
| for j in range(1, len(xSteps)): | |
| # compute the starting and ending (x, y)-coordinates | |
| # for the current block | |
| startX = xSteps[j - 1] | |
| startY = ySteps[i - 1] | |
| endX = xSteps[j] | |
| endY = ySteps[i] | |
| # extract the ROI using NumPy array slicing, compute the | |
| # mean of the ROI, and then draw a rectangle with the | |
| # mean RGB values over the ROI in the original image | |
| roi = image[startY:endY, startX:endX] | |
| (B, G, R) = [int(x) for x in cv2.mean(roi)[:3]] | |
| cv2.rectangle(image, (startX, startY), (endX, endY), | |
| (B, G, R), -1) | |
| # return the pixelated blurred image | |
| return image | |
| def generate(path: str): | |
| """ | |
| Using the text summarization pipeline from `transformers`, summerize text | |
| from the given input text. The model used is `philschmid/bart-large-cnn-samsum`, which | |
| can be found [here](<https://huggingface.co/philschmid/bart-large-cnn-samsum>). | |
| """ | |
| r = requests.get(path, stream=True) | |
| img = Image.open(io.BytesIO(r.content)).convert('RGB') | |
| open_cv_image = np.array(img) | |
| # Convert RGB to BGR | |
| open_cv_image = open_cv_image[:, :, ::-1].copy() # numpy array (width, hight, 3) | |
| image = open_cv_image # numpy array (width, hight, 3) | |
| orig = image.copy() | |
| (h, w) = image.shape[:2] | |
| # construct a blob from the image | |
| blob = cv2.dnn.blobFromImage(image, 1.0, (300, 300),(104.0, 177.0, 123.0)) | |
| # pass the blob through the network and obtain the face detections | |
| logger.info("computing face detections...") | |
| net.setInput(blob) | |
| detections = net.forward() | |
| # loop over the detections | |
| for i in range(0, detections.shape[2]): | |
| # extract the confidence (i.e., probability) associated with the | |
| # detection | |
| confidence = detections[0, 0, i, 2] | |
| # filter out weak detections by ensuring the confidence is greater | |
| # than the minimum confidence | |
| if confidence > args["confidence"]: | |
| # compute the (x, y)-coordinates of the bounding box for the | |
| # object | |
| box = detections[0, 0, i, 3:7] * np.array([w, h, w, h]) | |
| (startX, startY, endX, endY) = box.astype("int") | |
| # extract the face ROI | |
| face = image[startY:endY, startX:endX] | |
| # check to see if we are applying the "simple" face blurring | |
| # method | |
| if args["method"] == "simple": | |
| face = anonymize_face_simple(face, factor=3.0) | |
| # otherwise, we must be applying the "pixelated" face | |
| # anonymization method | |
| else: | |
| face = anonymize_face_pixelate(face,blocks=args["blocks"]) | |
| # store the blurred face in the output image | |
| image[startY:endY, startX:endX] = face | |
| image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) | |
| img = Image.fromarray(image) | |
| im_file = io.BytesIO() | |
| img.save(im_file, format="PNG") | |
| im_bytes = base64.b64encode(im_file.getvalue()).decode("utf-8") | |
| # Return the generated text in a JSON response | |
| return {"output": im_bytes} | |