|
| 1 | +# Multichannel Processing with Channel Selection |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +The napari-tmidas batch processing system now supports automatic detection of multichannel images (especially from zarr files) and allows users to select which channel(s) to process. |
| 6 | + |
| 7 | +## Features |
| 8 | + |
| 9 | +### 1. Automatic Channel Detection |
| 10 | +When loading multichannel zarr files or other image formats, the system automatically detects: |
| 11 | +- Number of channels in the image |
| 12 | +- The axis where channels are located (C axis) |
| 13 | +- Common patterns: CYX, CZYX, TCYX, TCZYX |
| 14 | + |
| 15 | +### 2. Channel Selection UI |
| 16 | +Processing functions can add a `channel` parameter with `widget_type: "channel_selector"` to enable channel selection in the UI: |
| 17 | + |
| 18 | +```python |
| 19 | +@BatchProcessingRegistry.register( |
| 20 | + name="My Processing Function", |
| 21 | + suffix="_processed", |
| 22 | + description="Process images with channel selection", |
| 23 | + parameters={ |
| 24 | + "channel": { |
| 25 | + "type": str, |
| 26 | + "default": "all", |
| 27 | + "widget_type": "channel_selector", |
| 28 | + "description": "Select which channel to process", |
| 29 | + }, |
| 30 | + # ... other parameters |
| 31 | + }, |
| 32 | +) |
| 33 | +def my_function(image: np.ndarray, channel: str = "all") -> np.ndarray: |
| 34 | + # The processing worker handles channel extraction automatically |
| 35 | + # You receive the selected channel as input |
| 36 | + return processed_image |
| 37 | +``` |
| 38 | + |
| 39 | +### 3. Channel Selection Options |
| 40 | +Users can select: |
| 41 | +- **All channels**: Process all channels separately, creating one output file per channel |
| 42 | +- **Channel 0, 1, 2, ...**: Process only a specific channel |
| 43 | + |
| 44 | +## How It Works |
| 45 | + |
| 46 | +### Detection Phase |
| 47 | +1. When files are selected, the first file is loaded |
| 48 | +2. `detect_channels_in_image()` analyzes the image shape |
| 49 | +3. Channels are detected based on common patterns (small dimension: 2-10 values) |
| 50 | + |
| 51 | +### Processing Phase |
| 52 | +1. User selects which channel(s) to process via the dropdown |
| 53 | +2. `ProcessingWorker` extracts the selected channel(s) before processing |
| 54 | +3. The processing function receives the extracted channel data |
| 55 | +4. Results are saved with appropriate channel suffixes |
| 56 | + |
| 57 | +### Output Files |
| 58 | +- **Single channel selected**: `filename_suffix.tif` |
| 59 | +- **All channels selected**: `filename_ch0_suffix.tif`, `filename_ch1_suffix.tif`, etc. |
| 60 | + |
| 61 | +## Example Usage |
| 62 | + |
| 63 | +### Adding Channel Selection to Your Function |
| 64 | + |
| 65 | +```python |
| 66 | +from napari_tmidas._registry import BatchProcessingRegistry |
| 67 | + |
| 68 | +@BatchProcessingRegistry.register( |
| 69 | + name="Gaussian Blur with Channel Selection", |
| 70 | + suffix="_blurred", |
| 71 | + description="Apply Gaussian blur to selected channel(s)", |
| 72 | + parameters={ |
| 73 | + "sigma": { |
| 74 | + "type": float, |
| 75 | + "default": 1.0, |
| 76 | + "min": 0.1, |
| 77 | + "max": 10.0, |
| 78 | + "description": "Blur strength", |
| 79 | + }, |
| 80 | + "channel": { |
| 81 | + "type": str, |
| 82 | + "default": "all", |
| 83 | + "widget_type": "channel_selector", |
| 84 | + "description": "Select channel to process", |
| 85 | + }, |
| 86 | + }, |
| 87 | +) |
| 88 | +def gaussian_blur_multichannel(image: np.ndarray, sigma: float = 1.0, channel: str = "all") -> np.ndarray: |
| 89 | + from scipy import ndimage |
| 90 | + # Note: channel parameter is handled by the processing worker |
| 91 | + # You receive the already-extracted channel data |
| 92 | + return ndimage.gaussian_filter(image, sigma=sigma) |
| 93 | +``` |
| 94 | + |
| 95 | +## Implementation Details |
| 96 | + |
| 97 | +### Key Components |
| 98 | + |
| 99 | +1. **`detect_channels_in_image()`** ([_file_selector.py](../src/napari_tmidas/_file_selector.py)) |
| 100 | + - Detects channels in numpy arrays or OME-Zarr layer data |
| 101 | + - Returns (num_channels, channel_axis) |
| 102 | + - Handles common patterns: CYX, CZYX, TCYX, TCZYX |
| 103 | + |
| 104 | +2. **`ParameterWidget.update_channel_selector()`** ([_file_selector.py](../src/napari_tmidas/_file_selector.py)) |
| 105 | + - Populates the channel selector dropdown |
| 106 | + - Called when processing function is selected |
| 107 | + - Analyzes first file in the batch |
| 108 | + |
| 109 | +3. **`ProcessingWorker.process_file()`** ([_processing_worker.py](../src/napari_tmidas/_processing_worker.py)) |
| 110 | + - Extracts selected channel(s) before processing |
| 111 | + - Handles "all" channels by processing each separately |
| 112 | + - Manages output file naming with channel suffixes |
| 113 | + |
| 114 | +### Supported Image Formats |
| 115 | +- **Zarr files** (`.zarr`): Full OME-Zarr support with metadata |
| 116 | +- **TIFF files** (`.tif`, `.tiff`): Multichannel TIFF stacks |
| 117 | +- **Other formats**: Any format loadable by napari |
| 118 | + |
| 119 | +### Channel Detection Patterns |
| 120 | +The system detects channels when: |
| 121 | +- First dimension is 2-10 in size (CYX, CZYX patterns) |
| 122 | +- Second dimension is 2-10 in size (TCYX, TCZYX patterns) |
| 123 | +- Dimension is clearly smaller than spatial dimensions (Y, X) |
| 124 | + |
| 125 | +## Benefits |
| 126 | + |
| 127 | +1. **Flexibility**: Process all channels or just one |
| 128 | +2. **Efficiency**: Avoid processing unwanted channels |
| 129 | +3. **Clarity**: Clear output files with channel information |
| 130 | +4. **Automation**: No manual channel splitting needed |
| 131 | + |
| 132 | +## Example Functions Using Channel Selection |
| 133 | + |
| 134 | +- **Gaussian Blur**: Blur specific channels in multichannel images |
| 135 | +- _(Add your functions here)_ |
| 136 | + |
| 137 | +## Future Enhancements |
| 138 | + |
| 139 | +Potential improvements: |
| 140 | +- Support for selecting multiple specific channels (e.g., channels 0 and 2) |
| 141 | +- Channel merging after processing |
| 142 | +- Preview of channel selection before batch processing |
| 143 | +- Custom channel naming/labeling |
0 commit comments