Page MenuHomePhabricator

Bug4276.diff

Authored By
xplanes
Jun 11 2010, 5:47 PM
Size
17 KB
Referenced Files
None
Subscribers
None

Bug4276.diff

Index: Algorithms/mitkOverwriteSliceImageFilter.cpp
===================================================================
--- Algorithms/mitkOverwriteSliceImageFilter.cpp (revision 21081)
+++ Algorithms/mitkOverwriteSliceImageFilter.cpp (working copy)
@@ -25,8 +25,11 @@
#include "mitkDiffImageApplier.h"
#include "mitkImageTimeSelector.h"
+#include "mitkContourTool.h"
+
#include <itkImageSliceIteratorWithIndex.h>
#include <itkImageRegionIterator.h>
+#include <algorithm>
mitk::OverwriteSliceImageFilter::OverwriteSliceImageFilter()
:m_SliceIndex(0),
@@ -34,8 +37,11 @@
m_TimeStep(0),
m_Dimension0(0),
m_Dimension1(1),
+ m_pixelValue(1),
+ m_bEraseOnlySelectedColor(false),
m_CreateUndoInformation(false)
{
+ m_bSliceAndImageOriented = true;
}
mitk::OverwriteSliceImageFilter::~OverwriteSliceImageFilter()
@@ -80,15 +86,33 @@
break;
}
- if ( slice->GetDimension() < 2 || input->GetDimension() > 4 ||
- slice->GetDimension(0) != input->GetDimension(m_Dimension0) ||
- slice->GetDimension(1) != input->GetDimension(m_Dimension1) ||
- m_SliceIndex >= input->GetDimension(m_SliceDimension)
- )
+ if ( slice->GetDimension() != 2 ||
+ ( input->GetDimension() != 2 && input->GetDimension() != 3 && input->GetDimension() != 4 ) )
{
itkExceptionMacro("Slice and image dimensions differ or slice index is too large. Sorry, cannot work like this.");
return;
}
+
+ if ( slice->GetDimension(0) != input->GetDimension(m_Dimension0) ||
+ slice->GetDimension(1) != input->GetDimension(m_Dimension1) ||
+ m_SliceIndex >= input->GetDimension(m_SliceDimension)
+ )
+ {
+ m_bSliceAndImageOriented = false;
+ }
+ else
+ {
+ m_bSliceAndImageOriented = true;
+ }
+
+ if ( input->GetDimension() == 4 )
+ {
+ ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New();
+ timeSelector->SetInput( input );
+ timeSelector->SetTimeNr( m_TimeStep );
+ timeSelector->UpdateLargestPossibleRegion();
+ input3D = timeSelector->GetOutput();
+ }
if ( input->GetDimension() == 4 )
{
@@ -108,18 +132,28 @@
m_SliceDifferenceImage->Initialize( pixelType, 2, m_SliceImage->GetDimensions() );
}
- //MITK_INFO << "Overwriting slice " << m_SliceIndex << " in dimension " << m_SliceDimension << " at time step " << m_TimeStep << std::endl;
+ //LOG_INFO << "Overwriting slice " << m_SliceIndex << " in dimension " << m_SliceDimension << " at time step " << m_TimeStep << std::endl;
// this will do a long long if/else to find out both pixel types
- AccessFixedDimensionByItk( input3D, ItkImageSwitch, 3 );
+ if ( input->GetDimension() >= 3 )
+ {
+ AccessFixedDimensionByItk( input3D, ItkImageSwitch, 3 );
+ }
+ else
+ {
+ AccessFixedDimensionByItk( input3D, ItkImageSwitch, 2 );
+ }
SegmentationInterpolationController* interpolator = SegmentationInterpolationController::InterpolatorForImage( input );
if (interpolator)
{
interpolator->BlockModified(true);
- interpolator->SetChangedSlice( m_SliceDifferenceImage, m_SliceDimension, m_SliceIndex, m_TimeStep );
+ if ( m_bSliceAndImageOriented )
+ {
+ interpolator->SetChangedSlice( m_SliceDifferenceImage, m_SliceDimension, m_SliceIndex, m_TimeStep );
+ }
}
- if ( m_CreateUndoInformation )
+ if ( m_bSliceAndImageOriented && m_CreateUndoInformation )
{
// create do/undo operations (we don't execute the doOp here, because it has already been executed during calculation of the diff image
ApplyDiffImageOperation* doOp = new ApplyDiffImageOperation( OpTEST, const_cast<Image*>(input.GetPointer()), m_SliceDifferenceImage, m_TimeStep, m_SliceDimension, m_SliceIndex );
@@ -182,16 +216,6 @@
typedef itk::ImageRegionConstIterator< SliceImageType > InputSliceIteratorType;
typedef itk::ImageRegionIterator< DiffImageType > DiffSliceIteratorType;
- typename VolumeImageType::RegionType sliceInVolumeRegion;
-
- sliceInVolumeRegion = outputImage->GetLargestPossibleRegion();
- sliceInVolumeRegion.SetSize( m_SliceDimension, 1 ); // just one slice
- sliceInVolumeRegion.SetIndex( m_SliceDimension, m_SliceIndex ); // exactly this slice, please
-
- OutputSliceIteratorType outputIterator( outputImage, sliceInVolumeRegion );
- outputIterator.SetFirstDirection(m_Dimension0);
- outputIterator.SetSecondDirection(m_Dimension1);
-
InputSliceIteratorType inputIterator( inputImage, inputImage->GetLargestPossibleRegion() );
typename DiffImageType::Pointer diffImage;
@@ -199,25 +223,123 @@
DiffSliceIteratorType diffIterator( diffImage, diffImage->GetLargestPossibleRegion() );
// iterate over output slice (and over input slice simultaneously)
- outputIterator.GoToBegin();
inputIterator.GoToBegin();
diffIterator.GoToBegin();
- while ( !outputIterator.IsAtEnd() )
+ if ( m_bSliceAndImageOriented )
{
- while ( !outputIterator.IsAtEndOfSlice() )
- {
- while ( !outputIterator.IsAtEndOfLine() )
- {
- diffIterator.Set( static_cast<short signed int>(inputIterator.Get() - outputIterator.Get()) ); // oh oh, not good for bigger values
- outputIterator.Set( (TPixel2) inputIterator.Get() );
- ++outputIterator;
- ++inputIterator;
- ++diffIterator;
- }
- outputIterator.NextLine();
- }
- outputIterator.NextSlice();
+ typename VolumeImageType::RegionType sliceInVolumeRegion;
+
+ sliceInVolumeRegion = outputImage->GetLargestPossibleRegion();
+ if ( outputImage->GetImageDimension( ) == 3 )
+ {
+ sliceInVolumeRegion.SetSize( m_SliceDimension, 1 ); // just one slice
+ sliceInVolumeRegion.SetIndex( m_SliceDimension, m_SliceIndex ); // exactly this slice, please
+ }
+
+ // Get an iterator to the output image slice
+ OutputSliceIteratorType outputIterator( outputImage, sliceInVolumeRegion );
+ outputIterator.SetFirstDirection(m_Dimension0);
+ outputIterator.SetSecondDirection(m_Dimension1);
+
+ outputIterator.GoToBegin();
+ while ( !outputIterator.IsAtEnd() )
+ {
+ while ( !outputIterator.IsAtEndOfSlice() )
+ {
+ while ( !outputIterator.IsAtEndOfLine() )
+ {
+ diffIterator.Set( static_cast<short signed int>(inputIterator.Get() - outputIterator.Get()) ); // oh oh, not good for bigger values
+ if( inputIterator.Get() == mitk::paint::addPixelValue )
+ {
+ outputIterator.Set( (TPixel2)( m_pixelValue ) );
+ }
+ else if( inputIterator.Get() == mitk::paint::subPixelValue )
+ {
+ if (m_bEraseOnlySelectedColor)
+ {
+ if ( outputIterator.Get() == (TPixel2)( m_pixelValue ) )
+ {
+ outputIterator.Set( (TPixel2)( 0 ) );
+ }
+ }
+ else
+ {
+ outputIterator.Set( (TPixel2)( 0 ) );
+ }
+ }
+ ++outputIterator;
+ ++inputIterator;
+ ++diffIterator;
+ }
+ outputIterator.NextLine();
+ }
+ outputIterator.NextSlice();
+ }
}
+ else
+ {
+ while ( !inputIterator.IsAtEnd() )
+ {
+ // Input world point
+ Point3D currentPointIn2D;
+ currentPointIn2D.Fill(0);
+ for (int i = 0; i < 2; ++i) currentPointIn2D[i] = inputIterator.GetIndex()[i];
+ Point3D worldPointIn3D;
+ worldPointIn3D.Fill(0);
+ m_SliceGeometry3D->IndexToWorld( currentPointIn2D, worldPointIn3D );
+
+ // Offset the world coordinate by one pixel to compensate for
+ // index/world origin differences.
+ Point3D offsetIndex;
+ offsetIndex.Fill( 1 );
+ Point3D offsetWorld;
+ offsetWorld.Fill( 0 );
+ m_SliceGeometry3D->IndexToWorld( offsetIndex, offsetWorld );
+ // remove origin shift
+ const Point3D origin = m_SliceGeometry3D->GetOrigin();
+ offsetWorld[0] -= origin[0];
+ offsetWorld[1] -= origin[1];
+ offsetWorld[2] -= origin[2];
+ // offset world coordinate
+ worldPointIn3D[ 0 ] += offsetWorld[0];
+ worldPointIn3D[ 1 ] += offsetWorld[1];
+ worldPointIn3D[ 2 ] += offsetWorld[2];
+
+ // Output index
+ typename itk::Image<TPixel2,VImageDimension2>::IndexType outputIndex;
+ m_ImageGeometry3D->WorldToIndex( worldPointIn3D, outputIndex );
+
+ // Only access ITK image if it's inside
+ TPixel2 outputPixel = 0;
+ if ( m_ImageGeometry3D->IsIndexInside( outputIndex ) )
+ {
+ outputPixel = outputImage->GetPixel( outputIndex );
+ if( inputIterator.Get() == mitk::paint::addPixelValue )
+ {
+ outputImage->SetPixel( outputIndex, (TPixel2)( m_pixelValue ) );
+ }
+ else if( inputIterator.Get() == mitk::paint::subPixelValue )
+ {
+ if (m_bEraseOnlySelectedColor)
+ {
+ if ( outputImage->GetPixel( outputIndex ) == (TPixel2)( m_pixelValue ) )
+ {
+ outputImage->SetPixel( outputIndex, (TPixel2)( 0 ) );
+ }
+ }
+ else
+ {
+ outputImage->SetPixel( outputIndex, (TPixel2)( 0 ) );
+ }
+ }
+ }
+
+ // Set difference image
+ diffIterator.Set( static_cast<short signed int>(inputIterator.Get() - outputPixel ) ); // oh oh, not good for bigger values
+ ++inputIterator;
+ ++diffIterator;
+ }
+ }
}
std::string mitk::OverwriteSliceImageFilter::EventDescription( unsigned int sliceDimension, unsigned int sliceIndex, unsigned int timeStep )
@@ -244,3 +366,42 @@
return s.str();
}
+
+const mitk::Geometry3D* mitk::OverwriteSliceImageFilter::GetSliceGeometry3D() const
+{
+ return m_SliceGeometry3D;
+}
+
+void mitk::OverwriteSliceImageFilter::SetSliceGeometry3D( const mitk::Geometry3D* val )
+{
+ m_SliceGeometry3D = val;
+}
+
+const mitk::Geometry3D* mitk::OverwriteSliceImageFilter::GetImageGeometry3D() const
+{
+ return m_ImageGeometry3D;
+}
+
+void mitk::OverwriteSliceImageFilter::SetImageGeometry3D( const mitk::Geometry3D* val )
+{
+ m_ImageGeometry3D = val;
+}
+
+
+void mitk::OverwriteSliceImageFilter::SetPixelValue(int n) {
+ m_pixelValue = n;
+}
+
+int mitk::OverwriteSliceImageFilter::GetPixelValue() {
+ return m_pixelValue;
+}
+
+void mitk::OverwriteSliceImageFilter::SetEraseOnlySelectedColor(bool b)
+{
+ m_bEraseOnlySelectedColor = b;
+}
+
+bool mitk::OverwriteSliceImageFilter::GetEraseOnlySelectedColor()
+{
+ return m_bEraseOnlySelectedColor;
+}
\ No newline at end of file
Index: Algorithms/mitkOverwriteSliceImageFilter.h
===================================================================
--- Algorithms/mitkOverwriteSliceImageFilter.h (revision 21081)
+++ Algorithms/mitkOverwriteSliceImageFilter.h (working copy)
@@ -88,6 +88,19 @@
const Image* GetSliceImage() { return m_SliceImage.GetPointer(); }
const Image* GetLastDifferenceImage() { return m_SliceDifferenceImage.GetPointer(); }
+
+ const Geometry3D* GetSliceGeometry3D() const;
+ void SetSliceGeometry3D(const Geometry3D* val);
+
+ const Geometry3D* GetImageGeometry3D() const;
+ void SetImageGeometry3D(const Geometry3D* val);
+
+ void SetPixelValue(int n);
+ int GetPixelValue();
+
+ void SetEraseOnlySelectedColor(bool b);
+ bool GetEraseOnlySelectedColor();
+
protected:
@@ -114,6 +127,17 @@
unsigned int m_Dimension1;
bool m_CreateUndoInformation;
+
+ //! Slice and image are oriented on the same direction
+ bool m_bSliceAndImageOriented;
+
+ const Geometry3D* m_ImageGeometry3D;
+ const Geometry3D* m_SliceGeometry3D;
+
+ //! Pixel value used to paint the region
+ int m_pixelValue;
+ //! If true then is only possible to remove pixels with value m_pixelValue
+ bool m_bEraseOnlySelectedColor;
};
} // namespace
Index: Interactions/mitkContourTool.cpp
===================================================================
--- Interactions/mitkContourTool.cpp (revision 21081)
+++ Interactions/mitkContourTool.cpp (working copy)
@@ -23,10 +23,13 @@
#include "mitkBaseRenderer.h"
#include "mitkRenderingManager.h"
//#include "mitkProperties.h"
+#include "mitkImageWriter.h"
mitk::ContourTool::ContourTool(int paintingPixelValue)
:FeedbackContourTool("PressMoveReleaseWithCTRLInversion"),
- m_PaintingPixelValue(paintingPixelValue)
+ m_PaintingPixelValue(paintingPixelValue),
+ m_pixelValue( 1 ),
+ m_bEraseOnlySelectedColor( false )
{
}
@@ -102,7 +105,7 @@
DataTreeNode* workingNode( m_ToolManager->GetWorkingData(0) );
if (!workingNode) return false;
-
+
Image* image = dynamic_cast<Image*>(workingNode->GetData());
const PlaneGeometry* planeGeometry( dynamic_cast<const PlaneGeometry*> (positionEvent->GetSender()->GetCurrentWorldGeometry2D() ) );
if ( !image || !planeGeometry ) return false;
@@ -113,51 +116,43 @@
{
// 2. Slice is known, now we try to get it as a 2D image and project the contour into index coordinates of this slice
Image::Pointer slice = SegTool2D::GetAffectedImageSliceAs2DImage( positionEvent, image );
-
if ( slice.IsNull() )
{
MITK_ERROR << "Unable to extract slice." << std::endl;
return false;
}
+
+ // 3. Get the contour and project it on the 2D slice
+ Contour* feedbackContour( FeedbackContourTool::GetFeedbackContour() );
+ // arg3: true: actually no idea why this is neccessary, but it works :-(
+ // arg4: false: don't constrain the contour to the image's inside
+ Contour::Pointer projectedContour = FeedbackContourTool::ProjectContourTo2DSlice( slice, feedbackContour, true, false );
+
+ if (projectedContour.IsNull())
+ {
+ MITK_ERROR << "Unable to project contour." << std::endl;
+ return false;
+ }
- /*
- DataTreeNode::Pointer debugNode = DataTreeNode::New();
- debugNode->SetData( slice );
- debugNode->SetProperty( "name", StringProperty::New("extracted slice") );
- debugNode->SetProperty( "color", ColorProperty::New(1.0, 0.0, 0.0) );
- debugNode->SetProperty( "layer", FloatProperty::New(100) );
- m_ToolManager->GetDataStorage()->Add( debugNode );
- */
-
- Contour* feedbackContour( FeedbackContourTool::GetFeedbackContour() );
- Contour::Pointer projectedContour = FeedbackContourTool::ProjectContourTo2DSlice( slice, feedbackContour, true, false ); // true: actually no idea why this is neccessary, but it works :-(
- // false: don't constrain the contour to the image's inside
- /*
- Contour::Pointer back = FeedbackContourTool::BackProjectContourFrom2DSlice( slice, projectedContour, true ); // true: actually no idea why this is neccessary, but it works :-(
- for (unsigned int idx = 0; idx < back->GetNumberOfPoints(); ++idx)
- {
- Point3D before = feedbackContour->GetPoints()->ElementAt(idx);
- Point3D inbtw = projectedContour->GetPoints()->ElementAt(idx);
- Point3D after = back->GetPoints()->ElementAt(idx);
-
- MITK_DEBUG << "before " << before << " zwischen " << inbtw << " after " << after;
- }
- */
-
- if (projectedContour.IsNull()) return false;
-
- FeedbackContourTool::FillContourInSlice( projectedContour, slice, m_PaintingPixelValue );
-
+ // 4. Fill in the contour
+ FeedbackContourTool::FillContourInSlice( projectedContour, slice, m_PaintingPixelValue );
+
// 5. Write the modified 2D working data slice back into the image
+ const Geometry3D* geometry3D = positionEvent->GetSender()->GetCurrentWorldGeometry();
+ Geometry3D* imageGeometry = image->GetGeometry(0);
OverwriteSliceImageFilter::Pointer slicewriter = OverwriteSliceImageFilter::New();
slicewriter->SetInput( image );
slicewriter->SetCreateUndoInformation( true );
slicewriter->SetSliceImage( slice );
slicewriter->SetSliceDimension( affectedDimension );
slicewriter->SetSliceIndex( affectedSlice );
+ slicewriter->SetSliceGeometry3D( slice->GetGeometry() );
+ slicewriter->SetImageGeometry3D( imageGeometry );
slicewriter->SetTimeStep( positionEvent->GetSender()->GetTimeStep( image ) );
+ slicewriter->SetPixelValue(GetPixelValue());
+ slicewriter->SetEraseOnlySelectedColor(GetEraseOnlySelectedColor());
slicewriter->Update();
-
+
// 6. Make sure the result is drawn again --> is visible then.
assert( positionEvent->GetSender()->GetRenderWindow() );
@@ -179,17 +174,32 @@
if (!FeedbackContourTool::OnInvertLogic(action, stateEvent)) return false;
// Inversion only for 0 and 1 as painting values
- if (m_PaintingPixelValue == 1)
+ if (m_PaintingPixelValue == mitk::paint::addPixelValue)
{
- m_PaintingPixelValue = 0;
+ m_PaintingPixelValue = mitk::paint::subPixelValue;
FeedbackContourTool::SetFeedbackContourColor( 1.0, 0.0, 0.0 );
}
- else if (m_PaintingPixelValue == 0)
+ else if (m_PaintingPixelValue == mitk::paint::subPixelValue)
{
- m_PaintingPixelValue = 1;
+ m_PaintingPixelValue = mitk::paint::addPixelValue;
FeedbackContourTool::SetFeedbackContourColorDefault();
}
return true;
}
+void mitk::ContourTool::SetPixelValue(int n) {
+ m_pixelValue = n;
+}
+
+int mitk::ContourTool::GetPixelValue() {
+ return m_pixelValue;
+}
+
+void mitk::ContourTool::SetEraseOnlySelectedColor(bool b) {
+ m_bEraseOnlySelectedColor = b;
+}
+
+bool mitk::ContourTool::GetEraseOnlySelectedColor() {
+ return m_bEraseOnlySelectedColor;
+}
\ No newline at end of file
Index: Interactions/mitkContourTool.h
===================================================================
--- Interactions/mitkContourTool.h (revision 21081)
+++ Interactions/mitkContourTool.h (working copy)
@@ -26,6 +26,14 @@
class Image;
+// The intermediate data and the final one do not use the same pixel values
+// in order not to confuse and re-process them.
+namespace paint
+{
+ const int addPixelValue = 253; // unsigned
+ const int subPixelValue = 254; // unsigned
+}
+
/**
\brief Simple contour filling tool.
@@ -52,6 +60,10 @@
public:
mitkClassMacro(ContourTool, FeedbackContourTool);
+ void SetPixelValue(int n);
+ int GetPixelValue();
+ void SetEraseOnlySelectedColor(bool b);
+ bool GetEraseOnlySelectedColor();
protected:
@@ -68,6 +80,10 @@
int m_PaintingPixelValue;
+ //! Pixel value used to paint the region. Passed to OverwriteSliceImageFilter
+ int m_pixelValue;
+ //! If true then is only possible to remove pixels with value m_pixelValue
+ bool m_bEraseOnlySelectedColor;
};
} // namespace

File Metadata

Mime Type
text/plain
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
521
Default Alt Text
Bug4276.diff (17 KB)