Project-MONAI / Project-MONAI/MONAILabel
Add ability to load different label to current image
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 891
- Forks
- 269
- Avg merge
- 15h 41m
- Merged PRs (30d)
- 1
Description
Describe the solution you'd like
clicking next image would load 'orignal' label when that setting is enabled. If would be nice to have a user select the tag in the active learning strategy options, then slicer would only call server to get the label with that tag.
Describe alternatives you've considered
I managed to get it to work after modifying slicer code. It may be a bit hacky as I assume a cmd name in the strategy to skip calling the main image
def onNextSampleButton(self):
if not self.logic:
return
curr_image_id = self.ui.inputSelector.currentText # aeh avoid unneeded reload
curr_image_id = curr_image_id[:curr_image_id.find(".nii")] if curr_image_id else ""
print(f"========{curr_image_id}")
loadNewImage=True
try: ## moved code up duplicate to check command and keep same image
# qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor)
#self.updateServerSettings()
strategy = self.ui.strategyBox.currentText
if not strategy:
slicer.util.errorDisplay("No Strategy Found/Selected\t")
return
strategyParams=self.getParamsFromConfig("activelearning", strategy)
label_tag2get = strategyParams.get('label_tag',"original")
cmd=strategyParams.get("cmd", None)
if cmd=="LoadLabelTag" and len(curr_image_id)>0:
loadNewImage=False
except BaseException as e:
msg = f" aeh new code Message:: {e.msg}" if hasattr(e, "msg") else ""
slicer.util.errorDisplay(
f"Failed to fetch Sample from MONAI Label Server.\n{msg}",
detailedText=traceback.format_exc(),
)
print(f"========{curr_image_id} {loadNewImage=}")
if loadNewImage and (self._volumeNode or len(slicer.util.getNodesByClass("vtkMRMLScalarVolumeNode")) ):
if not slicer.util.confirmOkCancelDisplay(
"This will close current scene. Please make sure you have saved your current work.\n"
"Are you sure to continue?"
):
return
self.onResetScribbles()
slicer.mrmlScene.Clear(0)
start = time.time()
try:
qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor)
self.updateServerSettings()
#strategy = self.ui.strategyBox.currentText # moved up
#if not strategy:
# slicer.util.errorDisplay("No Strategy Found/Selected\t")
# return
#strategyParams=self.getParamsFromConfig("activelearning", strategy) #moved up
#strategyParams["current_loaded_image_id"] = curr_image_id ## will use this id when asking to compare models
if not loadNewImage: #aeh avoid un needed reload
image_id = curr_image_id
print(f" keeping same sample {image_id}")
else:
sample = self.logic.next_sample(strategy, strategyParams )
logging.debug(sample)
if not sample.get("id"):
slicer.util.warningDisplay(
"Unlabled Samples/Images Not Found at server. Instead you can load your own image."
)
return
if loadNewImage and self.samples.get(sample["id"]) is not None:
self.current_sample = self.samples[sample["id"]]
name = self.current_sample["VolumeNodeName"]
index = self.ui.inputSelector.findText(name)
self.ui.inputSelector.setCurrentIndex(index)
return
logging.info(sample)
image_id = sample["id"]
image_file = sample.get("path")
image_name = sample.get("name", image_id)
node_name = sample.get("PatientID", sample.get("name", image_id))
checksum = sample.get("checksum")
local_exists = image_file and os.path.exists(image_file)
print(f"------- aeh next sample id is {image_id} labeltag= {label_tag2get} ")
logging.info(f"Check if file exists/shared locally: {image_file} => {local_exists}")
if local_exists:
self._volumeNode = slicer.util.loadVolume(image_file)
self._volumeNode.SetName(node_name)
else:
download_uri = f"{self.serverUrl()}/datastore/image?image={quote_plus(image_id)}"
logging.info(download_uri)
sampleDataLogic = SampleData.SampleDataLogic()
self._volumeNode = sampleDataLogic.downloadFromURL(
nodeNames=node_name, fileNames=image_name, uris=download_uri, checksums=checksum
)[0]
if slicer.util.settingsValue("MONAILabel/originalLabel", True, converter=slicer.util.toBool):
try:
datastore = self.logic.datastore()
label_info = datastore["objects"][image_id]["labels"][label_tag2get]["info"]
labels = label_info.get("params", {}).get("label_names", {})
if labels:
# labels are available in original label info
labels = labels.keys()
else:
# labels not available
# assume labels in app info are valid for original label file
labels = self.logic.info().get("labels")
# ext = datastore['objects'][image_id]['labels']['original']['ext']
maskFile = self.logic.download_label(image_id, label_tag2get)
self.updateSegmentationMask(maskFile, list(labels)) ## aeh copied above
print(f"label tag {label_tag2get} label loaded! ")
except:
print(f"label tag {label_tag2get} label not found /errors ... ")
if loadNewImage: ## aeh added condition
self.initSample(sample)
except BaseException as e:
msg = f"Message:: {e.msg}" if hasattr(e, "msg") else ""
slicer.util.errorDisplay(f"Failed to fetch Sample from MONAI Label Server.\n{msg}",detailedText=traceback.format_exc(), )
finally:
qt.QApplication.restoreOverrideCursor()
self.updateGUIFromParameterNode()
logging.info(f"Time consumed by next_sample: {time.time() - start:3.1f}")
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the Slicer-side onNextSampleButton entry point and trace its calls to next_sample, datastore, download_label, and updateSegmentationMask. Review how active-learning strategy parameters are read, then make selecting a label tag load that tag without unnecessarily reloading the current image. Done means the selected tag is loaded when advancing images and the existing image-loading behavior still works.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- desktop, machine-learning
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100