@@ -119,6 +119,8 @@ def __init__(self, video):
119119 self .active_polygon_index = 0
120120 self .grid_polygons = [{'points' : [], 'roi_points' : []}]
121121 self .active_grid_index = 0
122+ self .brush_masks = [] # Store brush masks for recomputation
123+ self .brush_points = [] # Store computed brush points separately
122124
123125 # Add status bar for instructions
124126 self .statusBar = self .statusBar ()
@@ -658,7 +660,7 @@ def method_selected(self, id: int):
658660 is_grid = method_name == "Grid"
659661 is_brush = method_name == "Brush"
660662
661- show_spacing = is_along or is_grid
663+ show_spacing = is_along or is_grid or is_brush
662664
663665 self .start_new_line_button .setVisible (is_along or is_grid )
664666 self .polygon_list .setVisible (is_along )
@@ -675,7 +677,7 @@ def method_selected(self, id: int):
675677
676678 # Show context-sensitive instructions
677679 if is_brush :
678- self .show_instruction ("Hold Ctrl and drag to paint selection area." )
680+ self .show_instruction ("Hold Ctrl and drag to paint selection area. Use distance slider to control subset spacing. " )
679681 elif is_along :
680682 self .show_instruction ("Click to add points along the line. Click 'Start new line' to begin a new one." )
681683 elif is_grid :
@@ -736,7 +738,7 @@ def on_mouse_click(self, event):
736738 def update_selected_points (self ):
737739 polygon_points = [pt for poly in self .drawing_polygons for pt in poly ['roi_points' ]]
738740 grid_points = [pt for g in self .grid_polygons for pt in g ['roi_points' ]]
739- self .selected_points = self .manual_points + polygon_points + grid_points
741+ self .selected_points = self .manual_points + polygon_points + grid_points + self . brush_points
740742
741743 if not self .selected_points :
742744 self .scatter .clear ()
@@ -849,6 +851,11 @@ def recompute_roi_points(self):
849851 if len (grid ['points' ]) >= 3 :
850852 grid ['roi_points' ] = rois_inside_polygon (grid ['points' ], subset_size , spacing )
851853
854+ # Update all brush masks
855+ self .brush_points = []
856+ for mask in self .brush_masks :
857+ self .brush_points .extend (rois_inside_mask (mask , subset_size , spacing ))
858+
852859 self .update_selected_points ()
853860
854861 def start_new_line (self ):
@@ -876,6 +883,10 @@ def clear_selection(self):
876883 # Clear manual points
877884 self .manual_points = []
878885
886+ # Clear brush data
887+ self .brush_masks = []
888+ self .brush_points = []
889+
879890 # Clear line-based polygons
880891 self .drawing_polygons = [{'points' : [], 'roi_points' : []}]
881892 self .polygon_list .clear ()
@@ -1108,6 +1119,10 @@ def handle_remove_point(self, event):
11081119 if closest in grid ['roi_points' ]:
11091120 grid ['roi_points' ].remove (closest )
11101121
1122+ # Remove from brush points
1123+ if closest in self .brush_points :
1124+ self .brush_points .remove (closest )
1125+
11111126 self .update_selected_points ()
11121127
11131128 # Automatic filtering
@@ -1336,9 +1351,6 @@ def handle_brush_end(self, ev):
13361351 # Generate (row, col) points inside the painted mask
13371352 brush_rois = rois_inside_mask (self ._paint_mask , subset_size , spacing )
13381353
1339- # Convert to set of tuples for fast comparison
1340- roi_set = set ((int (round (y )), int (round (x ))) for y , x in brush_rois )
1341-
13421354 if self .brush_deselect_mode :
13431355 def point_inside_mask (pt , mask ):
13441356 y , x = int (round (pt [0 ])), int (round (pt [1 ]))
@@ -1359,11 +1371,24 @@ def point_inside_mask(pt, mask):
13591371 for grid in self .grid_polygons :
13601372 grid ['roi_points' ] = [pt for pt in grid ['roi_points' ] if not point_inside_mask (pt , self ._paint_mask )]
13611373
1374+ # Remove from brush points
1375+ self .brush_points = [
1376+ pt for pt in self .brush_points
1377+ if not point_inside_mask (pt , self ._paint_mask )
1378+ ]
1379+
1380+ # Remove brush masks that are covered by the current mask
1381+ self .brush_masks = [mask for mask in self .brush_masks
1382+ if not np .any (mask & self ._paint_mask )]
1383+
13621384 self .brush_deselect_mode = False
13631385 self .brush_deselect_button .setChecked (False )
13641386
13651387 else :
1366- self .manual_points .extend (brush_rois )
1388+ # Store the mask for future recomputation
1389+ self .brush_masks .append (self ._paint_mask .copy ())
1390+ # Add points to brush_points
1391+ self .brush_points .extend (brush_rois )
13671392
13681393 self ._paint_mask = None
13691394 self .update_selected_points ()
0 commit comments