Skip to content

Commit

Permalink
Merge branch 'JoinFilter' into master+gdWS
Browse files Browse the repository at this point in the history
  • Loading branch information
romangrothausmann committed Sep 10, 2018
2 parents 14fb16b + a714e11 commit 3ef7511
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 67 deletions.
68 changes: 1 addition & 67 deletions GUI/Model/JoinModel.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -94,75 +94,9 @@ bool
JoinModel::processCnJ(bool reverse_mode){
// Get the global objects
IRISApplication *driver = m_Parent->GetDriver();
GlobalState *gs = driver->GetGlobalState();

// Get Join source image
JsrcImageWrapper *jsrc = driver->GetJOINImageData()->GetJsrc();

// Get Join destination image
JdstImageWrapper *jdst = driver->GetJOINImageData()->GetJdst();

// Get the segmentation image
//LabelImageWrapper *imgLabel = driver->GetCurrentImageData()->GetSegmentation();

// Get the paint properties
LabelType drawing_color = gs->GetDrawingColorLabel();
DrawOverFilter drawover = gs->GetDrawOverFilter();

// Define a region of interest
//LabelImageWrapper::ImageType::RegionType xTestRegion= jsrc->GetImage()->GetBufferedRegion();
JsrcImageWrapper::ImageType::RegionType xTestRegion= jsrc->GetImage()->GetLargestPossibleRegion();

// Flag to see if anything was changed
bool flagUpdate = false;

JsrcImageWrapper::ImageType::ValueType JsrcClickPV= jsrc->GetImage()->GetPixel(to_itkIndex(m_MousePosition));
// JdstImageWrapper::ImageType::ValueType JdstClickPV= jdst->GetImage()->GetPixel(to_itkIndex(m_MousePosition));


// Iterate over the region
JsrcImageWrapper::Iterator sit(jsrc->GetImage(), xTestRegion);
LabelImageWrapper::Iterator dit(jdst->GetImage(), xTestRegion);
for(; !sit.IsAtEnd(); ++sit, ++dit){

if(sit.Get() != JsrcClickPV)
continue;

LabelType pxLabel = dit.Get();

// Standard paint mode
if(!reverse_mode)
{
if(drawover.CoverageMode == PAINT_OVER_ALL ||
(drawover.CoverageMode == PAINT_OVER_ONE && pxLabel == drawover.DrawOverLabel) ||
(drawover.CoverageMode == PAINT_OVER_VISIBLE && pxLabel != 0))
{
dit.Set(drawing_color);
if(pxLabel != drawing_color) flagUpdate = true;
}
}
// Background paint mode (clear label over current label)
else
{
if(drawing_color != 0 && pxLabel == drawing_color)
{
dit.Set(0);
if(pxLabel != 0) flagUpdate = true;
}
else if(drawing_color == 0 && drawover.CoverageMode == PAINT_OVER_ONE)
{
dit.Set(drawover.DrawOverLabel);
if(pxLabel != drawover.DrawOverLabel) flagUpdate = true;
}
}
}

// Image has been updated
if(flagUpdate)
{
jdst->GetImage()->Modified();
//imgLabel->GetImage()->Modified();
}
bool flagUpdate= driver->ExecuteCnJCopy(to_itkIndex(m_MousePosition));

return flagUpdate;
}
Expand Down
76 changes: 76 additions & 0 deletions Logic/Common/itkJoinCopyFilter.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
////image filter to set DrawingColor in output image if input pixel equals SeedValue

#ifndef __itkJoinCopyFilter_cxx
#define __itkJoinCopyFilter_cxx

#include "itkJoinCopyFilter.h"
#include <itkImageRegionIterator.h>
#include <itkImageRegionConstIterator.h>
#include <itkProgressReporter.h>

namespace itk{

template<typename TInputImage1, typename TInputImage2>
JoinCopyFilter<TInputImage1, TInputImage2>
::JoinCopyFilter(){
m_SeedActive= false;
m_SeedIndex.Fill(0);
m_SeedValue= NumericTraits<typename TInputImage2::PixelType>::Zero;
}

template<typename TInputImage1, typename TInputImage2>
void JoinCopyFilter<TInputImage1, TInputImage2>
::SetJsrc(const TInputImage1 *image1){
this->SetNthInput( 0, const_cast< TInputImage1 * >( image1 ) );
}

template<typename TInputImage1, typename TInputImage2>
void JoinCopyFilter<TInputImage1, TInputImage2>
::SetJdst(const TInputImage2 *image2){
this->SetNthInput( 1, const_cast< TInputImage2 * >( image2 ) );
}


template<typename TInputImage1, typename TInputImage2>
void JoinCopyFilter<TInputImage1, TInputImage2>
::BeforeThreadedGenerateData(){

if(m_SeedActive){
typename TInputImage1::ConstPointer input = dynamic_cast<const TInputImage1 *>( ProcessObject::GetInput(0) );
m_SeedValue= input->GetPixel(m_SeedIndex);
}
m_UpdateFlag= false;
}


template<typename TInputImage1, typename TInputImage2>
void JoinCopyFilter<TInputImage1, TInputImage2>
::ThreadedGenerateData(const typename Superclass::OutputImageRegionType& outputRegionForThread, ThreadIdType threadId){

if(m_SeedActive){
typename TInputImage1::ConstPointer input = dynamic_cast<const TInputImage1 *>( ProcessObject::GetInput(0) );
typename TInputImage2::Pointer output = this->GetOutput();

itk::ImageRegionConstIterator<TInputImage1> iti(input, outputRegionForThread);
itk::ImageRegionIterator<TInputImage2> ito(output, outputRegionForThread);

// support progress methods/callbacks with 1000 updates
ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels(), 1000);

while(!iti.IsAtEnd()){
if(iti.Get() == m_SeedValue){
ito.Set(m_DrawingColor);
}
++iti;
++ito;
progress.CompletedPixel();
}

m_UpdateFlag= true;
m_SeedActive= false;
//output->Modified();
}
}
}// end namespace

#endif //__itkJoinCopyFilter_cxx
73 changes: 73 additions & 0 deletions Logic/Common/itkJoinCopyFilter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#ifndef __itkJoinCopyFilter_h
#define __itkJoinCopyFilter_h

#include <itkInPlaceImageFilter.h>

namespace itk{
/** \class JoinCopyFilter
* \brief: sets DrawingColor in output image if input pixel equals SeedValue
*
* \ingroup ImageFilters
*/
template<typename TInputImage1, typename TInputImage2>
class JoinCopyFilter:
public InPlaceImageFilter<TInputImage2>{
public:
/** Standard class typedefs. */
typedef JoinCopyFilter Self;
typedef InPlaceImageFilter<TInputImage2> Superclass;
typedef SmartPointer<Self> Pointer;
typedef SmartPointer< const Self > ConstPointer;

/** Method for creation through the object factory. */
itkNewMacro(Self);

/** Run-time type information (and related methods). */
itkTypeMacro(JoinCopyFilter, InPlaceImageFilter);

void SetJsrc(const TInputImage1 *image1);
void SetJdst(const TInputImage2 *image2);

/** Set/Get SeedIndex value */
itkSetMacro(SeedIndex, typename TInputImage1::IndexType);
itkGetConstMacro(SeedIndex, typename TInputImage1::IndexType);

/** Set/Get DrawingColor value */
itkSetMacro(DrawingColor, typename TInputImage2::ValueType);
itkGetConstMacro(DrawingColor, typename TInputImage2::ValueType);

/** Get UpdateFlag value */
itkGetConstMacro(UpdateFlag, bool);

/** Get/Set SeedActive value */
itkSetMacro(SeedActive, bool);
itkGetConstMacro(SeedActive, bool);

protected:
JoinCopyFilter();
~JoinCopyFilter(){}

bool m_SeedActive;
typename TInputImage1::IndexType m_SeedIndex;
typename TInputImage1::ValueType m_SeedValue;
typename TInputImage2::ValueType m_DrawingColor;
bool m_UpdateFlag;


virtual void BeforeThreadedGenerateData();
virtual void ThreadedGenerateData(const typename Superclass::OutputImageRegionType& outputRegionForThread, ThreadIdType threadId);

private:
JoinCopyFilter(const Self &); //purposely not implemented
void operator=(const Self &); //purposely not implemented

};
} //namespace ITK


#ifndef ITK_MANUAL_INSTANTIATION
#include "itkJoinCopyFilter.cxx"
#endif

#endif // __itkJoinCopyFilter_h

25 changes: 25 additions & 0 deletions Logic/Framework/IRISApplication.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -289,10 +289,35 @@ ::InitializeJOINImageData(const SNAPSegmentationROISettings &roi, int CnJMode, c
// Remember the ROI object
m_GlobalState->SetSegmentationROISettings(roi);

// Initialize JoinCopyFilter
m_JOINImageData->InitializeJoinCF();

// The set of layers has changed
InvokeEvent(LayerChangeEvent());
}

bool
IRISApplication
::ExecuteCnJCopy(JsrcImageWrapper::ImageType::IndexType SeedIndex)
{
assert(m_JOINImageData->IsJsrcLoaded());

GlobalState *gs = GetGlobalState();

// Get the paint properties
LabelType drawing_color = gs->GetDrawingColorLabel();
DrawOverFilter drawover = gs->GetDrawOverFilter();

m_JOINImageData->GetJoinCF()->SetSeedIndex(SeedIndex);
m_JOINImageData->GetJoinCF()->SetDrawingColor(drawing_color);
m_JOINImageData->GetJoinCF()->SetSeedActive(true);
m_JOINImageData->GetJoinCF()->Update();
m_JOINImageData->GetJdst()->SetImage(m_JOINImageData->GetJoinCF()->GetOutput()); //needed because output has stolen the input's buffer and the input has no image buffer.

InvokeEvent(LayerChangeEvent());
return m_JOINImageData->GetJoinCF()->GetUpdateFlag();
}

void
IRISApplication
::CopySegementationToJsrc(const SNAPSegmentationROISettings &roi,
Expand Down
6 changes: 6 additions & 0 deletions Logic/Framework/IRISApplication.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "SystemInterface.h"
#include "UndoDataManager.h"
#include "SNAPEvents.h"
#include "JOINImageData.h" //for JsrcImageWrapper::ImageType::IndexType

// #include "itkImage.h"

Expand Down Expand Up @@ -320,6 +321,11 @@ class IRISApplication : public itk::Object
void InitializeJOINImageData(const SNAPSegmentationROISettings &roi, int CnJMode, const char* FileName,
CommandType *progressCommand = NULL);

/**
* Execute CnJ CopyFilter
*/
bool ExecuteCnJCopy(JsrcImageWrapper::ImageType::IndexType SeedIndex);

/**
* Copy Segmentation to Jsrc for JOIN-mode 0
*/
Expand Down
44 changes: 44 additions & 0 deletions Logic/Framework/JOINImageData.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@

#include "IRISApplication.h"
#include "JOINImageData.h"
//#include "itkJCFilterWatcher.h"
#include <itkCommand.h>


void FilterEventHandlerITK2(itk::Object *caller, const itk::EventObject &event, void*){

const itk::ProcessObject* filter = static_cast<const itk::ProcessObject*>(caller);

if(itk::ProgressEvent().CheckEvent(&event))
fprintf(stderr, "\r%s progress: %5.1f%%", filter->GetNameOfClass(), 100.0 * filter->GetProgress());//stderr is flushed directly
else if(itk::EndEvent().CheckEvent(&event))
std::cerr << std::endl << std::flush;
}


JOINImageData
::JOINImageData(){
Expand Down Expand Up @@ -301,4 +315,34 @@ void JOINImageData::UnloadAll(){

InvokeEvent(LayerChangeEvent());
}

void
JOINImageData
::InitializeJoinCF(){
////make sure Jsrc and Jdst exist
assert(IsJsrcLoaded());
assert(IsJdstLoaded());

////Initialize JoinCopyFilter
m_JoinCF= JoinCopyFilterType::New();

m_JoinCF->SetJsrc(m_JsrcWrapper->GetImage());
m_JoinCF->SetJdst(m_JdstWrapper->GetImage());
//m_JdstWrapper->SetImage(m_JoinCF->GetOutput()); //causes segfault due to missing transform of uninitialized output
m_JoinCF->InPlaceOn(); //makes 2nd input (SetJdst) be the output

itk::CStyleCommand::Pointer eventCallbackITK;
eventCallbackITK = itk::CStyleCommand::New();
eventCallbackITK->SetCallback(FilterEventHandlerITK2);

m_JoinCF->AddObserver(itk::ProgressEvent(), eventCallbackITK);
m_JoinCF->AddObserver(itk::EndEvent(), eventCallbackITK);

}

JOINImageData::JoinCopyFilterPointer
JOINImageData::GetJoinCF(){
////todo: introduce check if m_JoinCF was initialized
return m_JoinCF;
}

9 changes: 9 additions & 0 deletions Logic/Framework/JOINImageData.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

#include "GenericImageData.h"
#include "itkImageAdaptor.h"
#include "itkJoinCopyFilter.h"

/**
* \class JOINImageData
Expand All @@ -57,6 +58,9 @@ class JOINImageData : public GenericImageData
typedef JdstImageWrapper::ImageType JdstImageType;
typedef WsrcImageWrapper::ImageType WsrcImageType;

typedef itk::JoinCopyFilter<JsrcImageType, JdstImageType> JoinCopyFilterType;
typedef JoinCopyFilterType::Pointer JoinCopyFilterPointer;

/** Initialize to a ROI from another image data object */
void InitializeToROI(GenericImageData *source,
const SNAPSegmentationROISettings &roi,
Expand Down Expand Up @@ -88,6 +92,8 @@ class JOINImageData : public GenericImageData
bool IsWsrcLoaded();
void SetWsrcSticky(bool sticky);

void InitializeJoinCF();
JoinCopyFilterType::Pointer GetJoinCF();

protected:

Expand All @@ -102,6 +108,9 @@ class JOINImageData : public GenericImageData

// GWS source image
SmartPtr<WsrcImageWrapper> m_WsrcWrapper;

JoinCopyFilterPointer m_JoinCF;

};


Expand Down
7 changes: 7 additions & 0 deletions todo
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
TODOs for GWS:

- implement JoinCopyFilter (templated over dimension)
-- multi-threaded ImageRegionIterator
-- multi-threaded ImageScanlineIterator
-- FloodFilledImageFunctionConditionalIterator (Modules/Segmentation/RegionGrowing/include/itkConnectedThresholdImageFilter.hxx)
--- add 2D/3D option to GUI + implementation
- optimize CopySegementationToJdst and CopySegementationToJsrc

- combine mode 2 with mode 0 and add extra button for "LoadImageToJsrc"
-- restructure JoinDataPanel to have two main buttons: CnJ from Seg. or File OR CnJ from gWS
- add 'n' for next smallest unused label see eg m_Wrapper->GetHistogram(nBins) in ./Logic/ImageWrapper/DisplayMappingPolicy.cxx
Expand Down

0 comments on commit 3ef7511

Please sign in to comment.