Add the image segmentation node (#1122)

* Add image segmentation node

This is a node which receives as input:
- An image.
- A mask, which consists of colors that define the image segments.

Each unique color in the mask defines an area where a segmen resides.
The node generates a `Vec<ImageFrame>` where the length of the result
is the number of unique colors in the mask.

Signed-off-by: Ică Alexandru-Gabriel <alexandru@seyhanlee.com>

* Add the Index node for image segments

Since the output of the image segmentation node is a `Vec<ImageFrame>`,
we want a way to access the segments individually. The Index node receives
a `Vec<ImageFrame>` as input and an index, and returns the image found
at that index in the vec.

Signed-off-by: Ică Alexandru-Gabriel <alexandru@seyhanlee.com>

* Integrate the image segmentation and index nodes into the editor

Signed-off-by: Ică Alexandru-Gabriel <alexandru@seyhanlee.com>

* Initialize the input of the index node with an empty image frame

Signed-off-by: Ică Alexandru-Gabriel <alexandru@seyhanlee.com>

* Don't expose the parameter for the index node

Signed-off-by: Ică Alexandru-Gabriel <alexandru@seyhanlee.com>

* Don't crash the editor when the number of segments exceeds the accepted limit

Signed-off-by: Ică Alexandru-Gabriel <alexandru@seyhanlee.com>

* Print a warning in the console when the number of segments exceeds the accepted limit

Signed-off-by: Ică Alexandru-Gabriel <alexandru@seyhanlee.com>

* Add a few more checks so that the editor doesn't crash on invalid input

Signed-off-by: Ică Alexandru-Gabriel <alexandru@seyhanlee.com>

* Replace the tagged value for the index node

Signed-off-by: Ică Alexandru-Gabriel <alexandru@seyhanlee.com>

* Fix merge conflicts

---------

Signed-off-by: Ică Alexandru-Gabriel <alexandru@seyhanlee.com>
Co-authored-by: Dennis Kobert <dennis@kobert.dev>
This commit is contained in:
Alexandru Ică
2023-04-16 14:51:33 +03:00
committed by GitHub
parent e84a81ca56
commit 8fb663bad1
7 changed files with 182 additions and 0 deletions

View File

@@ -793,6 +793,28 @@ fn static_nodes() -> Vec<DocumentNodeType> {
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
properties: node_properties::stroke_properties,
},
DocumentNodeType {
name: "Image Segmentation",
category: "Image Adjustments",
identifier: NodeImplementation::proto("graphene_std::image_segmentation::ImageSegmentationNode<_>"),
inputs: vec![
DocumentInputType::value("Image", TaggedValue::ImageFrame(ImageFrame::empty()), true),
DocumentInputType::value("Mask", TaggedValue::ImageFrame(ImageFrame::empty()), true),
],
outputs: vec![DocumentOutputType::new("Segments", FrontendGraphDataType::Raster)],
properties: node_properties::no_properties,
},
DocumentNodeType {
name: "Index",
category: "Image Adjustments",
identifier: NodeImplementation::proto("graphene_core::raster::IndexNode<_>"),
inputs: vec![
DocumentInputType::value("Segmentation", TaggedValue::Segments(vec![ImageFrame::empty()]), true),
DocumentInputType::value("Index", TaggedValue::U32(0), false),
],
outputs: vec![DocumentOutputType::new("Image", FrontendGraphDataType::Raster)],
properties: node_properties::index_node_properties,
},
]
}

View File

@@ -1264,6 +1264,12 @@ pub fn no_properties(_document_node: &DocumentNode, _node_id: NodeId, _context:
string_properties("Node has no properties")
}
pub fn index_node_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let index = number_widget(document_node, node_id, 1, "Index", NumberInput::default().min(0.), true);
vec![LayoutGroup::Row { widgets: index }]
}
pub fn generate_node_properties(document_node: &DocumentNode, node_id: NodeId, context: &mut NodePropertiesContext) -> LayoutGroup {
let name = document_node.name.clone();
let layout = match super::document_node_types::resolve_document_node_type(&name) {