28#67
Open
OmidChaghaneh wants to merge 38 commits into
Open
Conversation
pyradiomics fix + docs update
…sidebar-label-to-QUS-analysis 17 change rf analysis sidebar label to qus analysis
…image-quality-issue
…ith UI refinements
…ing on UltrasoundImage objects
…election side-by-side
…ring feature branch
There was a problem hiding this comment.
Pull request overview
This PR extends the CEUS GUI workflow to optionally load a B-mode scan alongside the CEUS scan, display it as an overlay in the VOI drawing view, and add a “Export Video” feature. It also updates some Qt Designer .ui layouts (including the QUS ROI drawing UI).
Changes:
- Add optional B-mode path selection during CEUS image loading and load B-mode in parallel in the model.
- Pass B-mode data into VOI drawing and render a B-mode overlay with an adjustable alpha slider.
- Add an MP4 export path that composites CEUS (and optionally B-mode) with VOI border overlays.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/qus/seg_loading/ui/roi_drawing.ui | Updates QUS ROI drawing UI layout/enums; currently removes several widgets used by the view logic. |
| src/ceus/seg_loading/views/draw_voi_widget.py | Adds B-mode overlay rendering, new enhancement controls, and an MP4 export worker/path. |
| src/ceus/seg_loading/seg_loading_view_coordinator.py | Threads optional B-mode data into the VOI widget and routes new noise-floor/enhancement actions. |
| src/ceus/seg_loading/seg_loading_controller.py | Handles new user actions for noise-floor computation and enhancement requests. |
| src/ceus/image_loading/views/file_selection_widget.py | Adds optional B-mode file/folder selection and includes it in emitted load data. |
| src/ceus/image_loading/ui/file_selection.ui | Adds UI controls for optional B-mode path selection. |
| src/ceus/image_loading/image_loading_controller.py | Invokes model B-mode loading when a B-mode path is provided. |
| src/ceus/application_model.py | Stores B-mode state, loads B-mode via a worker, and adds a CEUS noise-floor computation helper. |
Comments suppressed due to low confidence (2)
src/ceus/seg_loading/seg_loading_view_coordinator.py:221
- preview_modified_image() calls self._voi_drawing_widget.update_enhancement_cache(...), but DrawVOIWidget no longer defines update_enhancement_cache (it’s commented out). This will crash when preprocessing preview is invoked. Either reintroduce update_enhancement_cache on DrawVOIWidget or remove/replace this preview path end-to-end (including controller handling).
def preview_modified_image(self, modified_image: UltrasoundImage, frame: int) -> None:
"""Show the preprocessed data in the VOI drawing widget."""
if self._voi_drawing_widget:
self._voi_drawing_widget.update_enhancement_cache(modified_image.pixel_data, frame)
else:
src/ceus/application_model.py:253
- load_image() resets _bmode_image_data/_pending_bmode_load for a new load cycle, but it doesn’t stop an in-flight _bmode_scan_worker from a previous request. If a previous B-mode worker finishes after a new CEUS load starts, it can overwrite _bmode_image_data and even trigger image_loaded for the wrong pairing. Consider quitting/waiting the _bmode_scan_worker here as well (or tagging requests with a load-id and ignoring stale worker completions).
# Reset state for new load cycle
self._image_data = None
self._bmode_image_data = None
self._pending_bmode_load = False
if scan_loader_kwargs is None:
scan_loader_kwargs = {}
input_data = {
'scan_type': self._selected_scan_type,
'image_path': image_path,
'scan_loader_kwargs': scan_loader_kwargs
}
if not self._validate_image_input(input_data):
return
# Stop any existing worker
if self._scan_worker and self._scan_worker.isRunning():
self._scan_worker.quit()
self._scan_worker.wait()
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # B-mode/CEUS Toggle & Paramap Signals | ||
| apply_preprocs_preview = pyqtSignal(list) # List of dicts with 'name' and 'kwargs' keys | ||
| compute_noise_floor_requested = pyqtSignal(object, int, float) # image_data, n_ref, std_mult | ||
| enhance_image_requested = pyqtSignal(object, list) # image_data, func_configs |
|
|
||
| def set_noise_floor(self, value: float) -> None: | ||
| """Callback from controller to set the computed noise floor.""" | ||
| self._last_noise_floor = value |
| # The enhanced image is returned; the view caller should handle usage | ||
| # This is primarily for the export worker which calls it synchronously | ||
| # through the coordinator's routed action. | ||
| data['callback'](enhanced) |
Comment on lines
+127
to
+134
|
|
||
| def __init__(self, parent_widget): | ||
| super().__init__() | ||
| self.parent_widget = parent_widget | ||
|
|
||
| def run(self): | ||
| try: | ||
| self.parent_widget._export_video(self.progress) |
Comment on lines
+1194
to
+1206
| # Use controller to enhance via signals | ||
| self._temp_enhanced = None | ||
| self.enhance_image_requested.emit(temp_im, [ | ||
| {'name': 'enhance_ceus_noise_norm', 'kwargs': { | ||
| 'p_low': self._ceus_p_low, | ||
| 'p_high_percentile': self._ceus_p_high_percentile | ||
| }} | ||
| ], lambda img: setattr(self, '_temp_enhanced', img)) | ||
|
|
||
| # Wait for callback (this is synchronous because the action handler calls callback immediately) | ||
| if self._temp_enhanced: | ||
| return self._temp_enhanced.pixel_data[:, :, :, 0] | ||
| return raw_3d |
Comment on lines
+884
to
+889
| <item> | ||
| <layout class="QHBoxLayout" name="horizontalLayout_4"> | ||
| <item> | ||
| <widget class="QPushButton" name="back_from_drag_button"> | ||
| <property name="minimumSize"> | ||
| <size> |
Comment on lines
+186
to
+188
| self._pix_data = image_data.pixel_data # keep raw data untouched | ||
| self._ceus_p_low = self._compute_noise_floor(image_data) # single scalar | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.