face_blur / app.py
Kroy's picture
Upload 3 files
63b4b93
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
@app.get("/generate")
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}