first commit
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
_test_*.*
|
||||
__pycache__
|
||||
.venv
|
||||
.idea
|
||||
*.pth
|
||||
*.ini
|
||||
@@ -0,0 +1,37 @@
|
||||
# ComfyUI Face Similarity
|
||||
|
||||
|
||||
A custom node for ComfyUI. It compare two images to rate facial similarity.
|
||||
|
||||
|
||||
### Node Description:
|
||||
Input: Two images
|
||||
Output: A float value, range from 0 to 100, and the larger the value means higher the similarity. usually, exceeding 50 is considered very similar.
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## How to install
|
||||
|
||||
|
||||
* Open the cmd window in the plugin directory of ComfyUI, like ```ComfyUI\custom_nodes```,type
|
||||
```
|
||||
git clone https://github.com/chflame163/ComfyUI_FaceSimilarity.git
|
||||
```
|
||||
* Or download the zip file and extracted, copy the resulting folder to ```ComfyUI\custom_ Nodes```
|
||||
|
||||
* Install ```dlib``` dependency package. Open the cmd window in the ComfyUI_LayerStyle plugin directory like
|
||||
```ComfyUI\custom_ Nodes\ComfyUI_LayerStyle```, If it is the latest official ComfyUI portable package, please enter:
|
||||
```
|
||||
..\..\..\python_embeded\python.exe -m pip install .\whl\dlib-19.24.1-cp311-cp311-win_amd64.whl
|
||||
```
|
||||
* Also provides ```dlib-19.22.99-cp310-cp310-win_amd64.whl``` in whl folder that is compatible with Python 3.10.x if your need.
|
||||
|
||||
* Next, enter the following command to install other dependency packages
|
||||
```
|
||||
..\..\..\python_embeded\python.exe -m pip install -r requirements.txt
|
||||
```
|
||||
|
||||
* Restart ComfyUI.
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
import importlib.util
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
import __main__
|
||||
import filecmp
|
||||
import shutil
|
||||
|
||||
NODE_CLASS_MAPPINGS = {}
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {}
|
||||
|
||||
def get_ext_dir(subpath=None, mkdir=False):
|
||||
dir = os.path.dirname(__file__)
|
||||
if subpath is not None:
|
||||
dir = os.path.join(dir, subpath)
|
||||
|
||||
dir = os.path.abspath(dir)
|
||||
|
||||
if mkdir and not os.path.exists(dir):
|
||||
os.makedirs(dir)
|
||||
return dir
|
||||
|
||||
py = get_ext_dir("py")
|
||||
files = os.listdir(py)
|
||||
for file in files:
|
||||
if not file.endswith(".py"):
|
||||
continue
|
||||
name = os.path.splitext(file)[0]
|
||||
imported_module = importlib.import_module(".py.{}".format(name), __name__)
|
||||
try:
|
||||
NODE_CLASS_MAPPINGS = {**NODE_CLASS_MAPPINGS, **imported_module.NODE_CLASS_MAPPINGS}
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {**NODE_DISPLAY_NAME_MAPPINGS, **imported_module.NODE_DISPLAY_NAME_MAPPINGS}
|
||||
except:
|
||||
pass
|
||||
|
||||
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"]
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 635 KiB |
@@ -0,0 +1,61 @@
|
||||
import torch
|
||||
import numpy as np
|
||||
import cv2
|
||||
|
||||
NODE_NAME = 'FaceSimilarity'
|
||||
|
||||
def tensor2cv2(image:torch.Tensor) -> np.array:
|
||||
if image.dim()==4:
|
||||
image = image.squeeze()
|
||||
npimage = image.numpy()
|
||||
cv2image = np.uint8(npimage * 255 / npimage.max())
|
||||
return cv2.cvtColor(cv2image, cv2.COLOR_RGB2BGR)
|
||||
|
||||
class FaceSimilarity:
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(self):
|
||||
detect_mode = ['face_recognition']
|
||||
return {
|
||||
"required": {
|
||||
"image1": ("IMAGE", ), #
|
||||
"image2": ("IMAGE",), #
|
||||
"detect_method": (detect_mode,),
|
||||
},
|
||||
"optional": {
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
RETURN_NAMES = ("similarity",)
|
||||
FUNCTION = 'face_similarity'
|
||||
CATEGORY = '😺dzNodes/FaceSimilarity'
|
||||
OUTPUT_NODE = True
|
||||
|
||||
def face_similarity(self, image1, image2, detect_method
|
||||
):
|
||||
|
||||
cvimage1 = tensor2cv2(image1)
|
||||
cvimage2 = tensor2cv2(image2)
|
||||
if detect_method == 'face_recognition':
|
||||
import face_recognition
|
||||
face1 = face_recognition.face_locations(cvimage1)
|
||||
face2 = face_recognition.face_locations(cvimage2)
|
||||
face_encoder1 = face_recognition.face_encodings(cvimage1, face1)[0]
|
||||
face_encoder2 = face_recognition.face_encodings(cvimage2, face2)[0]
|
||||
similarity = face_recognition.face_distance([face_encoder1], face_encoder2)[0]
|
||||
|
||||
similarity = (1 - similarity) * 100
|
||||
similarity = round(similarity, 2)
|
||||
return (similarity,)
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"Face Similarity": FaceSimilarity
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"Face Similarity": "Face Similarity"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
torch
|
||||
numpy
|
||||
opencv-contrib-python
|
||||
face-recognition
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user