ychenhq's picture
Upload folder using huggingface_hub
04fbff5 verified
raw
history blame
4.83 kB
import os
import math
import cv2
import numpy as np
import onnxruntime
from onnxruntime.capi import _pybind_state as C
__labels = [
"FEMALE_GENITALIA_COVERED",
"FACE_FEMALE",
"BUTTOCKS_EXPOSED",
"FEMALE_BREAST_EXPOSED",
"FEMALE_GENITALIA_EXPOSED",
"MALE_BREAST_EXPOSED",
"ANUS_EXPOSED",
"FEET_EXPOSED",
"BELLY_COVERED",
"FEET_COVERED",
"ARMPITS_COVERED",
"ARMPITS_EXPOSED",
"FACE_MALE",
"BELLY_EXPOSED",
"MALE_GENITALIA_EXPOSED",
"ANUS_COVERED",
"FEMALE_BREAST_COVERED",
"BUTTOCKS_COVERED",
]
def _read_image(image_path, target_size=320):
# img = cv2.imread(image_path)
# img_height, img_width = img.shape[:2]
# img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = image_path # NOTE numpy array (H, W, 3)
img_height, img_width = img.shape[:2]
aspect = img_width / img_height
if img_height > img_width:
new_height = target_size
new_width = int(round(target_size * aspect))
else:
new_width = target_size
new_height = int(round(target_size / aspect))
resize_factor = math.sqrt(
(img_width**2 + img_height**2) / (new_width**2 + new_height**2)
)
img = cv2.resize(img, (new_width, new_height))
pad_x = target_size - new_width
pad_y = target_size - new_height
pad_top, pad_bottom = [int(i) for i in np.floor([pad_y, pad_y]) / 2]
pad_left, pad_right = [int(i) for i in np.floor([pad_x, pad_x]) / 2]
img = cv2.copyMakeBorder(
img,
pad_top,
pad_bottom,
pad_left,
pad_right,
cv2.BORDER_CONSTANT,
value=[0, 0, 0],
)
img = cv2.resize(img, (target_size, target_size))
image_data = img.astype("float32") / 255.0 # normalize
image_data = np.transpose(image_data, (2, 0, 1))
image_data = np.expand_dims(image_data, axis=0)
return image_data, resize_factor, pad_left, pad_top
def _postprocess(output, resize_factor, pad_left, pad_top):
outputs = np.transpose(np.squeeze(output[0]))
rows = outputs.shape[0]
boxes = []
scores = []
class_ids = []
for i in range(rows):
classes_scores = outputs[i][4:]
max_score = np.amax(classes_scores)
if max_score >= 0.2:
class_id = np.argmax(classes_scores)
x, y, w, h = outputs[i][0], outputs[i][1], outputs[i][2], outputs[i][3]
left = int(round((x - w * 0.5 - pad_left) * resize_factor))
top = int(round((y - h * 0.5 - pad_top) * resize_factor))
width = int(round(w * resize_factor))
height = int(round(h * resize_factor))
class_ids.append(class_id)
scores.append(max_score)
boxes.append([left, top, width, height])
indices = cv2.dnn.NMSBoxes(boxes, scores, 0.25, 0.45)
detections = []
for i in indices:
box = boxes[i]
score = scores[i]
class_id = class_ids[i]
detections.append(
{"class": __labels[class_id], "score": float(score), "box": box}
)
return detections
class NudeDetector:
def __init__(self, providers=None):
self.onnx_session = onnxruntime.InferenceSession(
os.path.join(os.path.dirname(__file__), "best.onnx"),
providers=C.get_available_providers() if not providers else providers,
)
model_inputs = self.onnx_session.get_inputs()
input_shape = model_inputs[0].shape
self.input_width = input_shape[2] # 320
self.input_height = input_shape[3] # 320
self.input_name = model_inputs[0].name
def detect(self, image_path):
preprocessed_image, resize_factor, pad_left, pad_top = _read_image(
image_path, self.input_width
)
outputs = self.onnx_session.run(None, {self.input_name: preprocessed_image})
detections = _postprocess(outputs, resize_factor, pad_left, pad_top)
return detections
def censor(self, image_path, classes=[], output_path=None):
detections = self.detect(image_path)
if classes:
detections = [
detection for detection in detections if detection["class"] in classes
]
img = cv2.imread(image_path)
for detection in detections:
box = detection["box"]
x, y, w, h = box[0], box[1], box[2], box[3]
# change these pixels to pure black
img[y : y + h, x : x + w] = (0, 0, 0)
if not output_path:
image_path, ext = os.path.splitext(image_path)
output_path = f"{image_path}_censored{ext}"
cv2.imwrite(output_path, img)
return output_path
if __name__ == "__main__":
detector = NudeDetector()
detections = detector.detect("/Users/praneeth.bedapudi/Desktop/images.jpeg")