add face bounding box
This commit is contained in:
@@ -12,6 +12,8 @@ Please read the results as follow:
|
||||
|
||||
Please download the DLIB [Shape Predictor](https://huggingface.co/matt3ounstable/dlib_predictor_recognition/resolve/main/shape_predictor_68_face_landmarks.dat?download=true) and the [Face Recognition](https://huggingface.co/matt3ounstable/dlib_predictor_recognition/resolve/main/dlib_face_recognition_resnet_model_v1.dat?download=true) models and place them into the `dlib` directory.
|
||||
|
||||
Precompiled Dlib for windows can be found [here](https://github.com/z-mahmud22/Dlib_Windows_Python3.x).
|
||||
|
||||
In this repository you also find a workflow that uses IPAdapter to generate a few images and return the distance to the reference face.
|
||||
|
||||

|
||||
|
||||
@@ -59,9 +59,97 @@ class FaceAnalysisModels:
|
||||
"shape_predict": dlib.shape_predictor(os.path.join(DLIB_DIR, "shape_predictor_68_face_landmarks.dat")),
|
||||
"face_recog": dlib.face_recognition_model_v1(os.path.join(DLIB_DIR, "dlib_face_recognition_resnet_model_v1.dat")),
|
||||
}
|
||||
|
||||
|
||||
return (out, )
|
||||
|
||||
def crop_face(image, x, y, w, h, padding=0):
|
||||
x = max(0, x - padding)
|
||||
y = max(0, y - padding)
|
||||
w = min(image.width, w + 2 * padding)
|
||||
h = min(image.height, h + 2 * padding)
|
||||
|
||||
return image.crop((x, y, x + w, y + h))
|
||||
|
||||
class FaceBoundingBox:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"analysis_models": ("ANALYSIS_MODELS", ),
|
||||
"image": ("IMAGE", ),
|
||||
"padding": ("INT", { "default": 0, "min": 0, "max": 4096, "step": 1 }),
|
||||
"index": ("INT", { "default": -1, "min": -1, "max": 4096, "step": 1 }),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("IMAGE", "INT", "INT", "INT", "INT")
|
||||
RETURN_NAMES = ("IMAGE", "x", "y", "width", "height")
|
||||
FUNCTION = "bbox"
|
||||
CATEGORY = "FaceAnalysis"
|
||||
|
||||
def bbox(self, analysis_models, image, padding, index=-1):
|
||||
out_img = []
|
||||
out_x = []
|
||||
out_y = []
|
||||
out_w = []
|
||||
out_h = []
|
||||
|
||||
for i in image:
|
||||
img = T.ToPILImage()(i.permute(2, 0, 1)).convert('RGB')
|
||||
|
||||
if analysis_models["library"] == "insightface":
|
||||
faces = analysis_models["detector"].get(np.array(img))
|
||||
for face in faces:
|
||||
x, y, w, h = face.bbox.astype(int)
|
||||
w = w - x
|
||||
h = h - y
|
||||
x = max(0, x - padding)
|
||||
y = max(0, y - padding)
|
||||
w = min(img.width, w + 2 * padding)
|
||||
h = min(img.height, h + 2 * padding)
|
||||
crop = img.crop((x, y, x + w, y + h))
|
||||
out_img.append(T.ToTensor()(crop).permute(1, 2, 0))
|
||||
out_x.append(x)
|
||||
out_y.append(y)
|
||||
out_w.append(w)
|
||||
out_h.append(h)
|
||||
|
||||
else:
|
||||
faces = analysis_models["detector"](np.array(img), 1)
|
||||
for face in faces:
|
||||
x, y, w, h = face.left(), face.top(), face.width(), face.height()
|
||||
x = max(0, x - padding)
|
||||
y = max(0, y - padding)
|
||||
w = min(img.width, w + 2 * padding)
|
||||
h = min(img.height, h + 2 * padding)
|
||||
crop = img.crop((x, y, x + w, y + h))
|
||||
out_img.append(T.ToTensor()(crop).permute(1, 2, 0))
|
||||
out_x.append(x)
|
||||
out_y.append(y)
|
||||
out_w.append(w)
|
||||
out_h.append(h)
|
||||
|
||||
if not out_img:
|
||||
raise Exception('No face detected in image.')
|
||||
|
||||
out_img = torch.stack(out_img)
|
||||
|
||||
if out_img.shape[0] == 1:
|
||||
index = 0
|
||||
|
||||
if index > out_img.shape[0] - 1:
|
||||
index = out_img.shape[0] - 1
|
||||
|
||||
if index != -1:
|
||||
out_img = out_img[index].unsqueeze(0)
|
||||
out_x = out_x[index]
|
||||
out_y = out_y[index]
|
||||
out_w = out_w[index]
|
||||
out_h = out_h[index]
|
||||
|
||||
return (out_img, out_x, out_y, out_w, out_h,)
|
||||
|
||||
class FaceEmbedDistance:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
@@ -173,9 +261,11 @@ class FaceEmbedDistance:
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"FaceEmbedDistance": FaceEmbedDistance,
|
||||
"FaceAnalysisModels": FaceAnalysisModels,
|
||||
"FaceBoundingBox": FaceBoundingBox,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"FaceEmbedDistance": "Face Embeds Distance",
|
||||
"FaceAnalysisModels": "Face Analysis Models",
|
||||
"FaceBoundingBox": "Face Bounding Box",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user