diff --git a/Modules/AlgorithmsExt/include/mitkSimpleHistogram.h b/Modules/AlgorithmsExt/include/mitkSimpleHistogram.h index cdccbae459..117fb10ff7 100644 --- a/Modules/AlgorithmsExt/include/mitkSimpleHistogram.h +++ b/Modules/AlgorithmsExt/include/mitkSimpleHistogram.h @@ -1,151 +1,130 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkSimpleHistogram_h #define mitkSimpleHistogram_h #ifndef __itkHistogram_h #include #endif #include "MitkAlgorithmsExtExports.h" #include #include #include #include namespace mitk { //##Documentation //## @brief Abstract superclass for histograms with double values. //## Classes which are deriving from this class can be cached //## in the same way. class MITKALGORITHMSEXT_EXPORT SimpleHistogram { public: /** @brief Returns the minimal value of the histogram. */ virtual double GetMin() const = 0; /** @brief Returns the maximum value of the histogram. */ virtual double GetMax() const = 0; /** @brief Creates a new histogram out the source. */ virtual void ComputeFromBaseData(BaseData *source) = 0; /** @brief TODO: (What should this method do?)*/ virtual float GetRelativeBin(double start, double end) const = 0; }; class MITKALGORITHMSEXT_EXPORT SimpleImageHistogram : public SimpleHistogram { public: typedef itk::Statistics::Histogram HistogramType; SimpleImageHistogram() { valid = false; - histogram = nullptr; } ~SimpleImageHistogram() { - if (histogram) - delete histogram; } /** @return Returns if the current histogram is valid, false if not. */ bool GetValid(); typedef itk::Image CTImage; typedef itk::ImageRegionIterator CTIteratorType; typedef itk::ImageRegionIteratorWithIndex CTIteratorIndexType; typedef itk::Image BinImage; typedef itk::ImageRegionIterator BinIteratorType; typedef itk::ImageRegionIteratorWithIndex BinIteratorIndexType; typedef unsigned long CountType; protected: - CountType *histogram; + HistogramType::ConstPointer histogram; bool valid; - - int first; - int last; - int min; - int max; - CountType highest; + int nBins = 256; double invLogHighest; public: - double GetMin() const override - { - if (!valid) - return 0; - - return min; - } - - double GetMax() const override - { - if (!valid) - return 1; - - return max; - } + double GetMin() const override; + double GetMax() const override; /** @brief Creates a new histogram out the source which must be an image. Method does nothing if the image is * invalid, nullptr, etc.. */ void ComputeFromBaseData(BaseData *source) override; float GetRelativeBin(double start, double end) const override; }; class MITKALGORITHMSEXT_EXPORT SimpleHistogramCache { public: static const unsigned int maxCacheSize = 64; class MITKALGORITHMSEXT_EXPORT Element { public: mitk::WeakPointer baseData; itk::TimeStamp m_LastUpdateTime; virtual ~Element(); virtual void ComputeFromBaseData(BaseData *baseData) = 0; virtual SimpleHistogram *GetHistogram() = 0; }; typedef std::list CacheContainer; CacheContainer cache; SimpleHistogramCache() {} ~SimpleHistogramCache() { TrimCache(true); } SimpleHistogram *operator[](BaseData::Pointer sp_BaseData); protected: void TrimCache(bool full = false) { unsigned int targetSize = full ? 0 : maxCacheSize; while (cache.size() > targetSize) { delete cache.back(); cache.pop_back(); } } }; } #endif diff --git a/Modules/AlgorithmsExt/src/mitkSimpleHistogram.cpp b/Modules/AlgorithmsExt/src/mitkSimpleHistogram.cpp index 1174ac545d..3435545e63 100644 --- a/Modules/AlgorithmsExt/src/mitkSimpleHistogram.cpp +++ b/Modules/AlgorithmsExt/src/mitkSimpleHistogram.cpp @@ -1,311 +1,171 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkSimpleHistogram.h" #include "mitkImageReadAccessor.h" #include "mitkSimpleUnstructuredGridHistogram.h" #include "mitkUnstructuredGrid.h" +#include namespace mitk { void SimpleImageHistogram::ComputeFromBaseData(BaseData *src) { valid = false; // check if input is valid if (src == nullptr) return; auto *source = dynamic_cast(src); if (source == nullptr) return; else if (source->IsEmpty()) return; - // dummy histogram - { - min = 0; - max = 1; - first = 0; - last = 1; - } + auto generator = mitk::HistogramGenerator::New(); + generator->SetImage(source); + generator->SetSize(nBins); + generator->ComputeHistogram(); + histogram = static_cast (generator->GetHistogram()); + CountType highest = 0; + for (unsigned int i = 0; i < histogram->GetSize()[0]; ++i) { - int typInt = 0; - { - auto typ = source->GetPixelType().GetComponentType(); - if (typ == itk::IOComponentEnum::UCHAR) - typInt = 0; - else if (typ == itk::IOComponentEnum::CHAR) - typInt = 1; - else if (typ == itk::IOComponentEnum::USHORT) - typInt = 2; - else if (typ == itk::IOComponentEnum::SHORT) - typInt = 3; - else if (typ == itk::IOComponentEnum::INT) - typInt = 4; - else if (typ == itk::IOComponentEnum::UINT) - typInt = 5; - else if (typ == itk::IOComponentEnum::LONG) - typInt = 6; - else if (typ == itk::IOComponentEnum::ULONG) - typInt = 7; - else if (typ == itk::IOComponentEnum::FLOAT) - typInt = 8; - else if (typ == itk::IOComponentEnum::DOUBLE) - typInt = 9; - else - { - MITK_WARN << "Pixel type not supported by SimpleImageHistogram"; - return; - } - } - - first = -32768; - last = 65535; // support at least full signed and unsigned short range - - if (histogram) - delete histogram; - - histogram = new CountType[last - first + 1]; - memset(histogram, 0, sizeof(CountType) * (last - first + 1)); - highest = 0; - max = first - 1; - min = last + 1; - - unsigned int num = 1; - for (unsigned int r = 0; r < source->GetDimension(); r++) - num *= source->GetDimension(r); - - // MITK_INFO << "building histogramm of integer image: 0=" << source->GetDimension(0) << " 1=" << - // source->GetDimension(1) << " 2=" << source->GetDimension(2) << " 3=" << source->GetDimension(3); - - ImageReadAccessor sourceAcc(source); - const void *src = sourceAcc.GetData(); - - do - { - int value = 0; - - switch (typInt) - { - case 0: - { - auto *t = (unsigned char *)src; - value = *t++; - src = (void *)t; - } - break; - case 1: - { - auto *t = (signed char *)src; - value = *t++; - src = (void *)t; - } - break; - case 2: - { - auto *t = (unsigned short *)src; - value = *t++; - src = (void *)t; - } - break; - case 3: - { - auto *t = (signed short *)src; - value = *t++; - src = (void *)t; - } - break; - case 4: - { - auto *t = (signed int *)src; - value = *t++; - src = (void *)t; - } - break; - case 5: - { - auto *t = (unsigned int *)src; - value = *t++; - src = (void *)t; - } - break; - case 6: - { - auto *t = (signed long *)src; - value = *t++; - src = (void *)t; - } - break; - case 7: - { - auto *t = (unsigned long *)src; - value = *t++; - src = (void *)t; - } - break; - case 8: - { - auto *t = (float *)src; - value = *t++; - src = (void *)t; - } - break; - case 9: - { - auto *t = (double *)src; - value = *t++; - src = (void *)t; - } - break; - } - - if (value >= first && value <= last) - { - if (value < min) - min = value; - if (value > max) - max = value; - CountType tmp = ++histogram[value - first]; - if (tmp > highest) - highest = tmp; - } - } while (--num); - - MITK_INFO << "histogramm computed: min=" << min << " max=" << max << " highestBin=" << highest - << " samples=" << num; + CountType count = histogram->GetFrequency(i); + if (count > highest) + highest = count; } - invLogHighest = 1.0 / log(double(highest)); valid = true; } bool SimpleImageHistogram::GetValid() { return valid; } float SimpleImageHistogram::GetRelativeBin(double left, double right) const { if (!valid) return 0.0f; - int iLeft = floorf(left); - int iRight = ceilf(right); - - /* - double sum = 0; - - for( int r = 0 ; r < 256 ; r++) - { - int pos = left + (right-left) * r/255.0; - int posInArray = floorf(pos+0.5f) - first; - sum += float(log(double(histogram[posInArray]))); - } - - sum /= 256.0; - return float(sum*invLogHighest); - */ - CountType maximum = 0; - for (int i = iLeft; i <= iRight; i++) + for (unsigned int i = 0; i < nBins; i++) { - int posInArray = i - first; - if (histogram[posInArray] > maximum) - maximum = histogram[posInArray]; + auto binMin = histogram->GetBinMin(0, i); + auto binMax = histogram->GetBinMax(0, i); + if (left < binMax && right > binMin) + { + maximum = histogram->GetFrequency(i); + } } - return float(log(double(maximum)) * invLogHighest); } + double SimpleImageHistogram::GetMin() const + { + if (!valid) + return 0; + + return histogram->GetBinMin(0, 0); + } + + double SimpleImageHistogram::GetMax() const + { + if (!valid) + return 1; + + return histogram->GetBinMax(0, nBins - 1); + } + class ImageHistogramCacheElement : public SimpleHistogramCache::Element { public: void ComputeFromBaseData(BaseData *baseData) override { histogram.ComputeFromBaseData(baseData); } SimpleHistogram *GetHistogram() override { return &histogram; } SimpleImageHistogram histogram; }; class UnstructuredGridHistogramCacheElement : public SimpleHistogramCache::Element { public: void ComputeFromBaseData(BaseData *baseData) override { histogram.ComputeFromBaseData(baseData); } SimpleHistogram *GetHistogram() override { return &histogram; } SimpleUnstructuredGridHistogram histogram; }; SimpleHistogram *SimpleHistogramCache::operator[](BaseData::Pointer sp_BaseData) { BaseData *p_BaseData = sp_BaseData.GetPointer(); if (!p_BaseData) { MITK_WARN << "SimpleHistogramCache::operator[] with null base data called"; return nullptr; } Element *elementToUpdate = nullptr; bool first = true; for (auto iter = cache.begin(); iter != cache.end(); iter++) { Element *e = *iter; BaseData *p_tmp = e->baseData.Lock(); if (p_tmp == p_BaseData) { if (!first) { cache.erase(iter); cache.push_front(e); } if (p_BaseData->GetMTime() > e->m_LastUpdateTime.GetMTime()) { elementToUpdate = e; goto recomputeElement; } // MITK_INFO << "using a cached histogram"; return e->GetHistogram(); } first = false; } if (dynamic_cast(p_BaseData)) { elementToUpdate = new ImageHistogramCacheElement(); } else if (dynamic_cast(p_BaseData)) { elementToUpdate = new UnstructuredGridHistogramCacheElement(); } else { MITK_WARN << "not supported: " << p_BaseData->GetNameOfClass(); } elementToUpdate->baseData = p_BaseData; cache.push_front(elementToUpdate); TrimCache(); recomputeElement: // MITK_INFO << "computing a new histogram"; elementToUpdate->ComputeFromBaseData(p_BaseData); elementToUpdate->m_LastUpdateTime.Modified(); return elementToUpdate->GetHistogram(); } SimpleHistogramCache::Element::~Element() {} } diff --git a/Modules/QtWidgetsExt/include/QmitkTransferFunctionWidget.h b/Modules/QtWidgetsExt/include/QmitkTransferFunctionWidget.h index a24e0a331b..0634b6750f 100755 --- a/Modules/QtWidgetsExt/include/QmitkTransferFunctionWidget.h +++ b/Modules/QtWidgetsExt/include/QmitkTransferFunctionWidget.h @@ -1,79 +1,80 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QmitkTransferFunctionWidget_h #define QmitkTransferFunctionWidget_h #include "MitkQtWidgetsExtExports.h" #include "ui_QmitkTransferFunctionWidget.h" #include #include #include #include #include #include #include namespace mitk { class BaseRenderer; } class MITKQTWIDGETSEXT_EXPORT QmitkTransferFunctionWidget : public QWidget, public Ui::QmitkTransferFunctionWidget { Q_OBJECT public: QmitkTransferFunctionWidget(QWidget *parent = nullptr, Qt::WindowFlags f = {}); ~QmitkTransferFunctionWidget() override; void SetDataNode(mitk::DataNode *node, mitk::TimeStepType timestep = 0, const mitk::BaseRenderer *renderer = nullptr); void SetScalarLabel(const QString &scalarLabel); void ShowScalarOpacityFunction(bool show); void ShowColorFunction(bool show); void ShowGradientOpacityFunction(bool show); void SetScalarOpacityFunctionEnabled(bool enable); void SetColorFunctionEnabled(bool enable); void SetGradientOpacityFunctionEnabled(bool enable); public slots: void SetXValueScalar(const QString text); void SetYValueScalar(const QString text); void SetXValueGradient(const QString text); void SetYValueGradient(const QString text); void SetXValueColor(const QString text); void OnUpdateCanvas(); void UpdateRanges(); + void UpdateStepSize(); void OnResetSlider(); - void OnSpanChanged(int lower, int upper); + void OnSpanChanged(double lower, double upper); protected: mitk::TransferFunctionProperty::Pointer tfpToChange; - int m_RangeSliderMin; - int m_RangeSliderMax; + double m_RangeSliderMin; + double m_RangeSliderMax; mitk::SimpleHistogramCache histogramCache; }; #endif diff --git a/Modules/QtWidgetsExt/src/QmitkTransferFunctionWidget.cpp b/Modules/QtWidgetsExt/src/QmitkTransferFunctionWidget.cpp index 2f5e727ba6..773cea31c9 100755 --- a/Modules/QtWidgetsExt/src/QmitkTransferFunctionWidget.cpp +++ b/Modules/QtWidgetsExt/src/QmitkTransferFunctionWidget.cpp @@ -1,263 +1,271 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkTransferFunctionWidget.h" #include "mitkImageTimeSelector.h" #include QmitkTransferFunctionWidget::QmitkTransferFunctionWidget(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f) { this->setupUi(this); // signals and slots connections connect(m_XEditScalarOpacity, SIGNAL(textEdited(const QString &)), this, SLOT(SetXValueScalar(const QString &))); connect(m_YEditScalarOpacity, SIGNAL(textEdited(const QString &)), this, SLOT(SetYValueScalar(const QString &))); connect(m_XEditGradientOpacity, SIGNAL(textEdited(const QString &)), this, SLOT(SetXValueGradient(const QString &))); connect(m_YEditGradientOpacity, SIGNAL(textEdited(const QString &)), this, SLOT(SetYValueGradient(const QString &))); connect(m_XEditColor, SIGNAL(textEdited(const QString &)), this, SLOT(SetXValueColor(const QString &))); m_RangeSlider->setMinimum(-2048); m_RangeSlider->setMaximum(2048); - connect(m_RangeSlider, SIGNAL(valuesChanged(int, int)), this, SLOT(OnSpanChanged(int, int))); + UpdateStepSize(); + connect(m_RangeSlider, SIGNAL(valuesChanged(double, double)), this, SLOT(OnSpanChanged(double, double))); // reset button connect(m_RangeSliderReset, SIGNAL(pressed()), this, SLOT(OnResetSlider())); m_ScalarOpacityFunctionCanvas->SetQLineEdits(m_XEditScalarOpacity, m_YEditScalarOpacity); m_GradientOpacityCanvas->SetQLineEdits(m_XEditGradientOpacity, m_YEditGradientOpacity); m_ColorTransferFunctionCanvas->SetQLineEdits(m_XEditColor, nullptr); m_ScalarOpacityFunctionCanvas->SetTitle("Grayvalue -> Opacity"); m_GradientOpacityCanvas->SetTitle("Grayvalue/Gradient -> Opacity"); m_ColorTransferFunctionCanvas->SetTitle("Grayvalue -> Color"); } QmitkTransferFunctionWidget::~QmitkTransferFunctionWidget() { } void QmitkTransferFunctionWidget::SetScalarLabel(const QString &scalarLabel) { m_textLabelX->setText(scalarLabel); m_textLabelX_2->setText(scalarLabel); m_textLabelX_3->setText(scalarLabel); m_ScalarOpacityFunctionCanvas->SetTitle(scalarLabel + " -> Opacity"); m_GradientOpacityCanvas->SetTitle(scalarLabel + "/Gradient -> Opacity"); m_ColorTransferFunctionCanvas->SetTitle(scalarLabel + " -> Color"); } void QmitkTransferFunctionWidget::ShowScalarOpacityFunction(bool show) { m_ScalarOpacityWidget->setVisible(show); } void QmitkTransferFunctionWidget::ShowColorFunction(bool show) { m_ColorWidget->setVisible(show); } void QmitkTransferFunctionWidget::ShowGradientOpacityFunction(bool show) { m_GradientOpacityWidget->setVisible(show); } void QmitkTransferFunctionWidget::SetScalarOpacityFunctionEnabled(bool enable) { m_ScalarOpacityWidget->setEnabled(enable); } void QmitkTransferFunctionWidget::SetColorFunctionEnabled(bool enable) { m_ColorWidget->setEnabled(enable); } void QmitkTransferFunctionWidget::SetGradientOpacityFunctionEnabled(bool enable) { m_GradientOpacityWidget->setEnabled(enable); } void QmitkTransferFunctionWidget::SetDataNode(mitk::DataNode *node, mitk::TimeStepType timestep, const mitk::BaseRenderer *renderer) { if (node) { tfpToChange = dynamic_cast(node->GetProperty("TransferFunction", renderer)); if (!tfpToChange) { if (!dynamic_cast(node->GetData())) { MITK_WARN << "QmitkTransferFunctionWidget::SetDataNode called with non-image node"; goto turnOff; } node->SetProperty("TransferFunction", tfpToChange = mitk::TransferFunctionProperty::New()); } mitk::TransferFunction::Pointer tf = tfpToChange->GetValue(); if (mitk::Image *data = dynamic_cast(node->GetData())) { mitk::SimpleHistogram *h = nullptr; if (data->GetTimeSteps() > 1) { if (!data->GetTimeGeometry()->IsValidTimeStep(timestep)) { return; } mitk::ImageTimeSelector::Pointer timeselector = mitk::ImageTimeSelector::New(); timeselector->SetInput(data); timeselector->SetTimeNr(timestep); timeselector->UpdateLargestPossibleRegion(); auto inputImage = timeselector->GetOutput(); h = histogramCache[inputImage]; } else { h = histogramCache[data]; } m_RangeSliderMin = h->GetMin(); m_RangeSliderMax = h->GetMax(); + UpdateStepSize(); m_RangeSlider->blockSignals(true); m_RangeSlider->setMinimum(m_RangeSliderMin); m_RangeSlider->setMaximum(m_RangeSliderMax); m_RangeSlider->setMinimumValue(m_RangeSliderMin); m_RangeSlider->setMaximumValue(m_RangeSliderMax); m_RangeSlider->blockSignals(false); m_ScalarOpacityFunctionCanvas->SetHistogram(h); m_GradientOpacityCanvas->SetHistogram(h); m_ColorTransferFunctionCanvas->SetHistogram(h); } OnUpdateCanvas(); return; } turnOff: m_ScalarOpacityFunctionCanvas->setEnabled(false); m_ScalarOpacityFunctionCanvas->SetHistogram(nullptr); m_GradientOpacityCanvas->setEnabled(false); m_GradientOpacityCanvas->SetHistogram(nullptr); m_ColorTransferFunctionCanvas->setEnabled(false); m_ColorTransferFunctionCanvas->SetHistogram(nullptr); tfpToChange = nullptr; } void QmitkTransferFunctionWidget::OnUpdateCanvas() { if (tfpToChange.IsNull()) return; mitk::TransferFunction::Pointer tf = tfpToChange->GetValue(); if (tf.IsNull()) return; m_ScalarOpacityFunctionCanvas->SetPiecewiseFunction(tf->GetScalarOpacityFunction()); m_GradientOpacityCanvas->SetPiecewiseFunction(tf->GetGradientOpacityFunction()); m_ColorTransferFunctionCanvas->SetColorTransferFunction(tf->GetColorTransferFunction()); UpdateRanges(); m_ScalarOpacityFunctionCanvas->update(); m_GradientOpacityCanvas->update(); m_ColorTransferFunctionCanvas->update(); } void QmitkTransferFunctionWidget::SetXValueScalar(const QString text) { if (!text.endsWith(".")) { m_ScalarOpacityFunctionCanvas->SetX(text.toFloat()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkTransferFunctionWidget::SetYValueScalar(const QString text) { if (!text.endsWith(".")) { m_ScalarOpacityFunctionCanvas->SetY(text.toFloat()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkTransferFunctionWidget::SetXValueGradient(const QString text) { if (!text.endsWith(".")) { m_GradientOpacityCanvas->SetX(text.toFloat()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkTransferFunctionWidget::SetYValueGradient(const QString text) { if (!text.endsWith(".")) { m_GradientOpacityCanvas->SetY(text.toFloat()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkTransferFunctionWidget::SetXValueColor(const QString text) { if (!text.endsWith(".")) { m_ColorTransferFunctionCanvas->SetX(text.toFloat()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkTransferFunctionWidget::UpdateRanges() { - int lower = m_RangeSlider->minimumValue(); - int upper = m_RangeSlider->maximumValue(); + double lower = m_RangeSlider->minimumValue(); + double upper = m_RangeSlider->maximumValue(); m_ScalarOpacityFunctionCanvas->SetMin(lower); m_ScalarOpacityFunctionCanvas->SetMax(upper); m_GradientOpacityCanvas->SetMin(lower); m_GradientOpacityCanvas->SetMax(upper); m_ColorTransferFunctionCanvas->SetMin(lower); m_ColorTransferFunctionCanvas->SetMax(upper); } -void QmitkTransferFunctionWidget::OnSpanChanged(int, int) +void QmitkTransferFunctionWidget::UpdateStepSize() +{ + double step = (m_RangeSliderMax - m_RangeSliderMin) / 1000.; + m_RangeSlider->setSingleStep(step); +} + +void QmitkTransferFunctionWidget::OnSpanChanged(double, double) { UpdateRanges(); m_GradientOpacityCanvas->update(); m_ColorTransferFunctionCanvas->update(); m_ScalarOpacityFunctionCanvas->update(); } void QmitkTransferFunctionWidget::OnResetSlider() { m_RangeSlider->blockSignals(true); m_RangeSlider->setMaximumValue(m_RangeSliderMax); m_RangeSlider->setMinimumValue(m_RangeSliderMin); m_RangeSlider->blockSignals(false); UpdateRanges(); m_GradientOpacityCanvas->update(); m_ColorTransferFunctionCanvas->update(); m_ScalarOpacityFunctionCanvas->update(); } diff --git a/Modules/QtWidgetsExt/src/QmitkTransferFunctionWidget.ui b/Modules/QtWidgetsExt/src/QmitkTransferFunctionWidget.ui index 7332ab3bae..ddfc7db000 100755 --- a/Modules/QtWidgetsExt/src/QmitkTransferFunctionWidget.ui +++ b/Modules/QtWidgetsExt/src/QmitkTransferFunctionWidget.ui @@ -1,557 +1,557 @@ QmitkTransferFunctionWidget 0 0 300 542 1 1 Form 0 0 0 0 - + Change transfer function window range. Qt::Horizontal 0 0 48 16777215 Resets range to histogram minimum and maximum. Reset 0 3 0 0 0 0 0 1 0 64 Left-click to select a point or add a new point. Hold left mouse button to move selected point. Click right mouse button to delete a point. true 0 0 64 0 64 16777215 Edit x-coordinate (grayvalue) of currently selected point. Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Edit x-coordinate (grayvalue) of currently selected point. Grayvalue false Qt::Horizontal 40 20 0 0 Edit y-coordinate (opacity) of currently selected point. Opacity Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 64 0 64 16777215 Edit y-coordinate (opacity) of currently selected point. Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 0 0 0 0 0 1 0 48 Left-click to select a point or add a new point. Hold left mouse button to move selected point. Click right mouse button to delete a point. Double-click left mouse button to change color of a point. 0 0 64 0 64 16777215 Edit x-coordinate (grayvalue) of currently selected point. Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Edit x-coordinate (grayvalue) of currently selected point. Grayvalue false Qt::Horizontal 40 20 0 2 0 0 0 0 0 1 0 64 Left-click to select a point or add a new point. Hold left mouse button to move selected point. Click right mouse button to delete a point. 0 0 64 0 64 16777215 Edit x-coordinate (grayvalue) of currently selected point. Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Edit x-coordinate (grayvalue) of currently selected point. Grayvalue false Qt::Horizontal 40 20 Edit y-coordinate (opacity) of currently selected point. Opacity Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 64 0 64 16777215 Edit y-coordinate (opacity) of currently selected point. Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::Vertical 20 0 QmitkPiecewiseFunctionCanvas QWidget
QmitkPiecewiseFunctionCanvas.h
QmitkColorTransferFunctionCanvas QWidget
QmitkColorTransferFunctionCanvas.h
ctkRangeSlider QWidget
ctkRangeSlider.h