Skip to content

Commit 2b122d7

Browse files
dunkeronipsychedelicious
authored andcommitted
add: image noise invocation
1 parent ded9213 commit 2b122d7

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

invokeai/app/invocations/image.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from invokeai.app.services.shared.invocation_context import InvocationContext
2626
from invokeai.backend.image_util.invisible_watermark import InvisibleWatermark
2727
from invokeai.backend.image_util.safety_checker import SafetyChecker
28+
from invokeai.app.util.misc import SEED_MAX
2829

2930

3031
@invocation("show_image", title="Show Image", tags=["image"], category="image", version="1.0.1")
@@ -1089,3 +1090,60 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
10891090
image_dto = context.images.save(image=generated_image)
10901091

10911092
return ImageOutput.build(image_dto)
1093+
1094+
1095+
@invocation(
1096+
"image_noise",
1097+
title="Add Image Noise",
1098+
tags=["image", "noise"],
1099+
category="image",
1100+
version="1.0.2",
1101+
)
1102+
class ImageNoiseInvocation(BaseInvocation, WithMetadata, WithBoard):
1103+
"""Add noise to an image"""
1104+
1105+
image: ImageField = InputField(description="The image to add noise to")
1106+
seed: int = InputField(
1107+
default=0,
1108+
ge=0,
1109+
le=SEED_MAX,
1110+
description=FieldDescriptions.seed,
1111+
)
1112+
noise_type: Literal["gaussian", "salt_and_pepper"] = InputField(
1113+
default="gaussian",
1114+
description="The type of noise to add",
1115+
)
1116+
amount: float = InputField(default=0.1, ge=0, le=1, description="The amount of noise to add")
1117+
color: bool = InputField(default=False, description="Whether to add color noise")
1118+
1119+
def invoke(self, context: InvocationContext) -> ImageOutput:
1120+
image = context.images.get_pil(self.image.image_name, mode="RGBA")
1121+
1122+
# Save out the alpha channel
1123+
alpha = image.getchannel("A")
1124+
1125+
# Set the seed for numpy random
1126+
rs = numpy.random.RandomState(numpy.random.MT19937(numpy.random.SeedSequence(self.seed)))
1127+
1128+
if self.noise_type == "gaussian":
1129+
if self.color:
1130+
noise = rs.normal(0, 1, (image.height, image.width, 3)) * 255
1131+
else:
1132+
noise = rs.normal(0, 1, (image.height, image.width)) * 255
1133+
noise = numpy.stack([noise] * 3, axis=-1)
1134+
elif self.noise_type == "salt_and_pepper":
1135+
if self.color:
1136+
noise = rs.choice([0, 255], (image.height, image.width, 3), p=[1 - self.amount, self.amount])
1137+
else:
1138+
noise = rs.choice([0, 255], (image.height, image.width), p=[1 - self.amount, self.amount])
1139+
noise = numpy.stack([noise] * 3, axis=-1)
1140+
1141+
noise = Image.fromarray(noise.astype(numpy.uint8), mode="RGB")
1142+
noisy_image = Image.blend(image.convert("RGB"), noise, self.amount).convert("RGBA")
1143+
1144+
# Paste back the alpha channel
1145+
noisy_image.putalpha(alpha)
1146+
1147+
image_dto = context.images.save(image=noisy_image)
1148+
1149+
return ImageOutput.build(image_dto)

0 commit comments

Comments
 (0)