integer motion control

This commit is contained in:
RyanOnTheInside
2024-12-29 15:18:35 +00:00
parent e0aedac501
commit 3e80f43ac2
2 changed files with 77 additions and 3 deletions
+4 -2
View File
@@ -1,7 +1,7 @@
from .controls.value_controls import FloatControl, IntControl, StringControl
from .controls.sequence_controls import FloatSequence, IntSequence, StringSequence
from .controls.utility_controls import FPSMonitor
from .controls.motion_controls import MotionController, ROINode
from .controls.motion_controls import MotionController, ROINode, IntegerMotionController
from .quick_shape_mask import QuickShapeMask
from .tiny_vae import TAESDVaeEncode, TAESDVaeDecode
from .misc_nodes import DTypeConverter
@@ -15,6 +15,7 @@ NODE_CLASS_MAPPINGS = {
"StringSequence": StringSequence,
"FPSMonitor": FPSMonitor,
"MotionController": MotionController,
"IntegerMotionController": IntegerMotionController,
"ROINode": ROINode,
#"IntervalControl": IntervalCo ntrol,
#"DeltaControl": DeltaControl,
@@ -32,8 +33,9 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"IntSequence": "Int Sequence (RyanOnTheInside)",
"StringSequence": "String Sequence (RyanOnTheInside)",
"FPSMonitor": "FPS Monitor (RyanOnTheInside)",
"MotionController": "Motion Controller (RyanOnTheInside)",
"MotionController": "Float Motion Controller (RyanOnTheInside)",
"ROINode": "ROI Node (RyanOnTheInside)",
"IntegerMotionController": "Integer Motion Controller (RyanOnTheInside)",
#"IntervalControl": "Interval Control (RyanOnTheInside)",
#"DeltaControl": "Delta Control (RyanOnTheInside)",
"QuickShapeMask": "Quick Shape Mask (RyanOnTheInside)",
+73 -1
View File
@@ -29,6 +29,7 @@ class ROINode(ControlNodeBase):
"action": (list(action.value for action in ROIAction),),
"value": ("FLOAT", {
"default": 0.1,
"step": 0.01,
"tooltip": "Value to use for mathematical operations"
}),
},
@@ -62,6 +63,9 @@ class ROINode(ControlNodeBase):
}
return (roi_data,)
def update(self, *args, **kwargs):
return self.define_roi(*args, **kwargs)
class MotionController(ControlNodeBase):
"""Processes motion detection for a chain of ROIs and manages their states"""
@@ -209,4 +213,72 @@ class MotionController(ControlNodeBase):
# Convert mask to tensor
mask_tensor = torch.from_numpy(motion_mask).unsqueeze(0)
return (state["current_value"], mask_tensor)
return (state["current_value"], mask_tensor)
def update(self, *args, **kwargs):
return self.process_motion(*args, **kwargs)
class RoundingMode(Enum):
ROUND = "round" # Standard rounding
FLOOR = "floor" # Round down
CEIL = "ceil" # Round up
TRUNCATE = "truncate" # Remove decimal part
class IntegerMotionController(MotionController):
"""Processes motion detection for ROIs and outputs integer values"""
@classmethod
def INPUT_TYPES(cls):
inputs = super().INPUT_TYPES()
# Convert float parameters to int
inputs["required"]["minimum_value"] = ("INT", {
"default": 0,
"tooltip": "Minimum output value"
})
inputs["required"]["maximum_value"] = ("INT", {
"default": 100,
"tooltip": "Maximum output value"
})
inputs["required"]["starting_value"] = ("INT", {
"default": 0,
"tooltip": "Initial output value"
})
# Add rounding mode parameter
inputs["required"]["rounding_mode"] = (
[mode.value for mode in RoundingMode],
{"default": RoundingMode.ROUND.value}
)
return inputs
RETURN_TYPES = ("INT", "MASK")
FUNCTION = "process_motion"
CATEGORY = "real-time/control/motion"
def _apply_rounding(self, value, mode):
"""Apply the specified rounding mode to convert float to int"""
if mode == RoundingMode.ROUND.value:
return int(round(value))
elif mode == RoundingMode.FLOOR.value:
return int(np.floor(value))
elif mode == RoundingMode.CEIL.value:
return int(np.ceil(value))
else: # TRUNCATE
return int(value)
def process_motion(self, image, roi_chain, threshold, blur_size,
minimum_value, maximum_value, starting_value,
rounding_mode, always_execute=True):
# Call parent class method with float conversion of bounds
float_result, mask = super().process_motion(
image, roi_chain, threshold, blur_size,
float(minimum_value), float(maximum_value), float(starting_value),
always_execute
)
# Convert result to integer using specified rounding mode
int_result = self._apply_rounding(float_result, rounding_mode)
# Ensure result stays within bounds
int_result = max(minimum_value, min(maximum_value, int_result))
return (int_result, mask)