diff --git a/invokeai/backend/image_util/lineart.py b/invokeai/backend/image_util/lineart.py index 524ebf3adf..8fcca24b0e 100644 --- a/invokeai/backend/image_util/lineart.py +++ b/invokeai/backend/image_util/lineart.py @@ -214,8 +214,14 @@ class LineartEdgeDetector: line = line.cpu().numpy() line = (line * 255.0).clip(0, 255).astype(np.uint8) - detected_map = line + detected_map = 255 - line - detected_map = 255 - detected_map + # The lineart model often outputs a lot of almost-black noise. SD1.5 ControlNets seem to be OK with this, but + # SDXL ControlNets are not - they need a cleaner map. 12 was experimentally determined to be a good threshold, + # eliminating all the noise while keeping the actual edges. Other approaches to thresholding may be better, + # for example stretching the contrast or removing noise. + detected_map[detected_map < 12] = 0 - return np_to_pil(detected_map) + output = np_to_pil(detected_map) + + return output diff --git a/invokeai/backend/image_util/lineart_anime.py b/invokeai/backend/image_util/lineart_anime.py index 8e7e0e5807..09dcb6655e 100644 --- a/invokeai/backend/image_util/lineart_anime.py +++ b/invokeai/backend/image_util/lineart_anime.py @@ -260,8 +260,14 @@ class LineartAnimeEdgeDetector: line = cv2.resize(line, (width, height), interpolation=cv2.INTER_CUBIC) line = line.clip(0, 255).astype(np.uint8) - detected_map = line - detected_map = 255 - detected_map + detected_map = 255 - line + + # The lineart model often outputs a lot of almost-black noise. SD1.5 ControlNets seem to be OK with this, but + # SDXL ControlNets are not - they need a cleaner map. 12 was experimentally determined to be a good threshold, + # eliminating all the noise while keeping the actual edges. Other approaches to thresholding may be better, + # for example stretching the contrast or removing noise. + detected_map[detected_map < 12] = 0 + output = np_to_pil(detected_map) return output