mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Compare commits
5 Commits
test/node-
...
inpaint_br
Author | SHA1 | Date | |
---|---|---|---|
875a2efc13 | |||
d5ad91964c | |||
ae09fc9599 | |||
6207a2c7d8 | |||
31fbb64b63 |
@ -15,6 +15,7 @@ from .baseinvocation import (
|
||||
InvocationConfig,
|
||||
)
|
||||
|
||||
import cv2
|
||||
|
||||
class PILInvocationConfig(BaseModel):
|
||||
"""Helper class to provide all PIL invocations with additional config"""
|
||||
@ -650,3 +651,55 @@ class ImageInverseLerpInvocation(BaseInvocation, PILInvocationConfig):
|
||||
width=image_dto.width,
|
||||
height=image_dto.height,
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
class MaskEdgeInvocation(BaseInvocation, PILInvocationConfig):
|
||||
"""Applies an edge mask to an image"""
|
||||
|
||||
# fmt: off
|
||||
type: Literal["mask_edge"] = "mask_edge"
|
||||
|
||||
# Inputs
|
||||
image: Optional[ImageField] = Field(default=None, description="The image to apply the mask to")
|
||||
edge_size: int = Field(description="The size of the edge")
|
||||
edge_blur: int = Field(description="The amount of blur on the edge")
|
||||
low_threshold: int = Field(description="First threshold for the hysteresis procedure in Canny edge detection")
|
||||
high_threshold: int = Field(description="Second threshold for the hysteresis procedure in Canny edge detection")
|
||||
# fmt: on
|
||||
|
||||
def invoke(self, context: InvocationContext) -> MaskOutput:
|
||||
mask = context.services.images.get_pil_image(self.image.image_name)
|
||||
|
||||
npimg = numpy.asarray(mask, dtype=np.uint8)
|
||||
npgradient = numpy.uint8(
|
||||
255 * (1.0 - numpy.floor(numpy.abs(0.5 - numpy.float32(npimg) / 255.0) * 2.0))
|
||||
)
|
||||
npedge = cv2.Canny(npimg, threshold1=self.low_threshold, threshold2=self.high_threshold)
|
||||
npmask = npgradient + npedge
|
||||
npmask = cv2.dilate(
|
||||
npmask, numpy.ones((3, 3), numpy.uint8), iterations=int(self.edge_size / 2)
|
||||
)
|
||||
|
||||
new_mask = Image.fromarray(npmask)
|
||||
|
||||
if self.edge_blur > 0:
|
||||
new_mask = new_mask.filter(ImageFilter.BoxBlur(self.edge_blur))
|
||||
|
||||
new_mask = ImageOps.invert(new_mask)
|
||||
|
||||
image_dto = context.services.images.create(
|
||||
image=new_mask,
|
||||
image_origin=ResourceOrigin.INTERNAL,
|
||||
image_category=ImageCategory.MASK,
|
||||
node_id=self.id,
|
||||
session_id=context.graph_execution_state_id,
|
||||
is_intermediate=self.is_intermediate,
|
||||
)
|
||||
|
||||
return MaskOutput(
|
||||
mask=ImageField(image_name=image_dto.image_name),
|
||||
width=image_dto.width,
|
||||
height=image_dto.height,
|
||||
)
|
||||
|
@ -771,3 +771,29 @@ class ImageToLatentsInvocation(BaseInvocation):
|
||||
latents = latents.to("cpu")
|
||||
context.services.latents.save(name, latents)
|
||||
return build_latents_output(latents_name=name, latents=latents)
|
||||
|
||||
class LatentsAlphaBlendingInvocation(BaseInvocation):
|
||||
"""Blends two Latents objects using an alpha/mask"""
|
||||
|
||||
# fmt: off
|
||||
type: Literal["latents_alpha_blending"] = "latents_alpha_blending"
|
||||
|
||||
# Inputs
|
||||
latents1: Optional[LatentsField] = Field(description="The first Latents object to blend")
|
||||
latents2: Optional[LatentsField] = Field(description="The second Latents object to blend")
|
||||
alphaLatents: Optional[LatentsField] = Field(description="The alpha/mask to use for blending in latents form")
|
||||
# fmt: on
|
||||
|
||||
def invoke(self, context: InvocationContext) -> LatentsOutput:
|
||||
latents1 = context.services.latents.get(self.latents1.latents_name)
|
||||
latents2 = context.services.latents.get(self.latents2.latents_name)
|
||||
alpha = context.services.latents.get(self.alpha.latents_name)
|
||||
# Perform the alpha-blending
|
||||
blended_latents = alpha * latents1 + (1 - alpha) * latents2
|
||||
|
||||
# Save the blended Latents object
|
||||
name = f"{context.graph_execution_state_id}__{self.id}"
|
||||
context.services.latents.save(name, blended_latents)
|
||||
|
||||
return build_latents_output(latents_name=name, latents=blended_latents)
|
||||
|
||||
|
Reference in New Issue
Block a user