Commit 1b6a604c authored by Emmanuel Promayon's avatar Emmanuel Promayon

Merge branch 'bug/#62' into 'develop'

Bug/#62

Closes #62

See merge request !110
parents f01a7319 76e614d4
......@@ -170,8 +170,8 @@
<camitk:action>
<camitk:name>Manual Threshold Filter</camitk:name>
<camitk:parameters>
<camitk:parameter name="Low threshold" value="1" type="int"/>
<camitk:parameter name="High threshold" value="1" type="int"/>
<camitk:parameter name="Low Threshold" value="1" type="int"/>
<camitk:parameter name="High Threshold" value="1" type="int"/>
</camitk:parameters>
<camitk:inputs>
<camitk:component name="output-3.mha" type="ImageComponent"/>
......
......@@ -24,6 +24,7 @@
****************************************************************************/
// CamiTK incldues
#include "ManualThreshold.h"
#include "ActionWidget.h"
#include <Application.h>
#include <ItkProgressObserver.h>
#include <Property.h>
......@@ -48,19 +49,19 @@ ManualThreshold::ManualThreshold(ActionExtension* extension) : Action(extension)
setComponent("ImageComponent");
// Setting classification family and tags
this->setFamily("ITK Segmentation");
this->addTag("Threshold");
this->addTag("Manal");
this->addTag("Classification");
setFamily("ITK Segmentation");
addTag("Threshold");
addTag("Manual");
addTag("Classification");
// Setting parameters default values
Property* lowThresholdProperty = new Property(tr("Low threshold"), 128, tr("Voxels which have a scalar value below this threshold will considered as black (0). Above it AND below high threshold, they will be considered as white (255)."), "");
Property* lowThresholdProperty = new Property(tr("Low Threshold"), 128, tr("Voxels which have a scalar value below this low threshold value will be set to black (min possible value). Above it AND below the high threshold value, they will be set to white (max possible value)."), "");
lowThresholdProperty->setAttribute("minimum", 0);
lowThresholdProperty->setAttribute("maximum", 255);
lowThresholdProperty->setAttribute("singleStep", 1);
addParameter(lowThresholdProperty);
Property* highThresholdProperty = new Property(tr("High threshold"), 255, tr("Voxels which have a scalar value above this threshold will considered as black (0). Below it AND above low threshold, they will be considered as white (255)."), "");
Property* highThresholdProperty = new Property(tr("High Threshold"), 255, tr("Voxels which have a scalar value above this high threshold will be set to black (min possible value). Below it AND above the low threshold value, they will be set to white (max possible value)."), "");
highThresholdProperty->setAttribute("minimum", 0);
highThresholdProperty->setAttribute("maximum", 255);
highThresholdProperty->setAttribute("singleStep", 1);
......@@ -72,6 +73,35 @@ ManualThreshold::~ManualThreshold() {
// do not delete the widget has it might have been used in the ActionViewer (i.e. the ownership might have been taken by the stacked widget)
}
// --------------- getWidget -------------------
QWidget* ManualThreshold::getWidget() {
// Computing the maximum and the minimum possible value for the selected images
double min = 0;
double max = 0;
for(Component *comp : getTargets()) {
vtkSmartPointer<vtkImageData> inputImage = dynamic_cast<ImageComponent*>(comp)->getImageData();
if (min > inputImage->GetScalarTypeMin())
min = inputImage->GetScalarTypeMin();
if (max < inputImage->GetScalarTypeMax())
max = inputImage->GetScalarTypeMax();
}
// Applying those min/max value to the threshold properties
camitk::Property *lowThresholdProperty = getProperty("Low Threshold");
lowThresholdProperty->setAttribute("minimum", min);
lowThresholdProperty->setAttribute("maximum", max);
lowThresholdProperty->setAttribute("singleStep", (max - min) / 255);
camitk::Property *highThresholdProperty = getProperty("High Threshold");
highThresholdProperty->setAttribute("minimum", min);
highThresholdProperty->setAttribute("maximum", max);
highThresholdProperty->setAttribute("singleStep", (max - min) / 255);
// return the default widget
return Action::getWidget();
}
// --------------- apply -------------------
Action::ApplyStatus ManualThreshold::apply() {
foreach (Component* comp, getTargets()) {
......@@ -84,8 +114,8 @@ Action::ApplyStatus ManualThreshold::apply() {
// --------------- process -------------------
void ManualThreshold::process(ImageComponent* comp) {
// Get the parameters
this->lowThreshold = property("Low threshold").toInt();
this->highThreshold = property("High threshold").toInt();
lowThreshold = property("Low Threshold").toInt();
highThreshold = property("High Threshold").toInt();
// ITK filter implementation using templates
vtkSmartPointer<vtkImageData> inputImage = comp->getImageData();
......
......@@ -46,6 +46,10 @@ public:
/// Default Destructor
virtual ~ManualThreshold();
/// Required to update the min/max constraints on the threshold value
/// from the currently selected images (which depends on the pixel type)
virtual QWidget* getWidget();
public slots:
/** this method is automatically called when the action is triggered.
* Use getTargets() QList to get the list of component to use.
......
......@@ -284,7 +284,7 @@ void ActionState::onEntry(QEvent* event) {
actionWidget->setButtonVisibility(false);
}
// set the widget
this->myStateWidget->setActionWidget(this->myAction->getWidget());
this->myStateWidget->setActionWidget(actionWidget);
}
}
......
<?xml version="1.0" encoding="UTF-8"?>
<!--
Document : log2html.xsl
Created on : 11 février 2013, 15:00
Author : cfouard
Description:
Show an ActionStateMachine application log in a readable way
/*****************************************************************************
* $CAMITK_LICENCE_BEGIN$
*
* CamiTK - Computer Assisted Medical Intervention ToolKit
* (c) 2001-2018 Univ. Grenoble Alpes, CNRS, TIMC-IMAG UMR 5525 (GMCAO)
* (c) 2001-2019 Univ. Grenoble Alpes, CNRS, TIMC-IMAG UMR 5525 (GMCAO)
*
* Visit http://camitk.imag.fr for more information
*
......@@ -30,6 +25,10 @@
*
* $CAMITK_LICENCE_END$
****************************************************************************/
XSL document to display an ActionStateMachine application log in HTML.
Can be used as a client-side XSLT
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
......@@ -222,8 +221,14 @@ td.simple {
<td><span class="actionColor">Inputs</span></td>
<td><span class="actionColor">Outputs</span></td></tr>
<tr>
<td><xsl:apply-templates select="log:parameters"/></td>
<td><xsl:apply-templates select="log:inputs"/></td>
<!-- for some action, the parameters and inputs are logged inside the <applyAction> element
but for most of the action they are logged inside the <state> element.
The two XPath expression below are selecting the <parameters> and <inputs> elements
- inside the current <applyAction> element
- as well as inside the preceding <state> element (which corresponds to the current state)
-->
<td><xsl:apply-templates select="log:parameters|../preceding-sibling::*[1]/log:parameters"/></td>
<td><xsl:apply-templates select="log:inputs|../preceding-sibling::*[1]/log:inputs"/></td>
<td><xsl:apply-templates select="log:outputs"/></td>
</tr>
</table>
......
......@@ -108,7 +108,7 @@ void Property::setEnumTypeName(QString nameOfTheEnum, QObject* objectDeclaringTh
setAttribute("enumNames", enumAutoGuiLiterals);
}
// -------------------- setAttribute --------------------
// -------------------- getEnumValueAsString --------------------
QString Property::getEnumValueAsString(const QObject* objectDeclaringTheEnum) const {
if (!enumTypeName.isNull()) {
int indexOfEnum = objectDeclaringTheEnum->metaObject()->indexOfEnumerator(enumTypeName.toStdString().c_str());
......@@ -159,7 +159,8 @@ QStringList Property::getAttributeList() {
// -------------------- setAttribute --------------------
void Property::setAttribute(const QString& attribute, const QVariant& value) {
attributeValues[attribute] = value;
// If there is already an item with the key attribute, that item's value is replaced with the given value
attributeValues.insert(attribute,value);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment