Skip to content

Commit 7eb6a74

Browse files
authored
Merge pull request #1251 from mathildemerle/registrationMedInria
[Registration] cast data in LCC and Diffeo, enhance txt in Manual
2 parents 14e61b1 + e011fa5 commit 7eb6a74

File tree

9 files changed

+59
-126
lines changed

9 files changed

+59
-126
lines changed

RELEASE_NOTES.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ medInria 4.0:
2222
- Switch to Ubuntu 22.
2323
- PolygonROI: update icons, fix a glitch when users change ROI label, hide label panel in pipelines.
2424
- Fix some plugins wrongly loaded on Windows.
25-
- BUGFIX 4.0.1: fix the path to the online documentation.
25+
- BUGFIX 4.0.1:
26+
* Fix the path to the online documentation.
27+
* Allow to use data with different size or spacing in LCCLogDemons and DiffeomorphicDemons.
28+
* Manual Registration: enhance landmark numbers for better user understanding.
29+
* Fix Histogram Analysis width problem displaying multi-results.
2630

2731
medInria 3.3:
2832
- Fix mirrored DICOM images problem

src/plugins/legacy/LCCLogDemons/LCCLogDemons.cpp

Lines changed: 21 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
// /////////////////////////////////////////////////////////////////
2020

2121
#include <itkImageRegistrationMethod.h>
22-
2322
#include <itkImage.h>
2423
#include <itkResampleImageFilter.h>
2524
#include <itkCastImageFilter.h>
@@ -167,17 +166,24 @@ QString LCCLogDemons::description() const
167166
template <typename PixelType>
168167
int LCCLogDemonsPrivate::update()
169168
{
170-
int testResult = proc->testInputs();
171-
if (testResult != medAbstractProcessLegacy::SUCCESS)
172-
{
173-
return testResult;
174-
}
175-
169+
RegImageType *inputFixed = static_cast<RegImageType*>(proc->fixedImage().GetPointer());
170+
RegImageType *inputMoving = static_cast<RegImageType*>(proc->movingImages()[0].GetPointer());
171+
172+
// Cast spacing, origin, direction and size from the moving data to the fixed one
173+
typedef itk::ResampleImageFilter<RegImageType, RegImageType> ResampleFilterType;
174+
typename ResampleFilterType::Pointer resampleFilter = ResampleFilterType::New();
175+
resampleFilter->SetOutputSpacing(inputFixed->GetSpacing());
176+
resampleFilter->SetOutputOrigin(inputFixed->GetOrigin());
177+
resampleFilter->SetOutputDirection(inputFixed->GetDirection());
178+
resampleFilter->SetSize(inputFixed->GetLargestPossibleRegion().GetSize());
179+
resampleFilter->SetInput(inputMoving);
180+
resampleFilter->Update();
181+
inputMoving = resampleFilter->GetOutput();
182+
183+
// Register the fixed and moving data
176184
registrationMethod = new rpi::LCClogDemons<RegImageType,RegImageType,double> ();
177-
178-
registrationMethod->SetFixedImage((const RegImageType*) proc->fixedImage().GetPointer());
179-
registrationMethod->SetMovingImage((const RegImageType*) proc->movingImages()[0].GetPointer());
180-
185+
registrationMethod->SetFixedImage(inputFixed);
186+
registrationMethod->SetMovingImage(inputMoving);
181187
registrationMethod->SetUpdateRule(updateRule);
182188
registrationMethod->SetVerbosity(verbose);
183189

@@ -219,12 +225,8 @@ int LCCLogDemonsPrivate::update()
219225
typedef itk::ResampleImageFilter< RegImageType,RegImageType, double> ResampleFilterType;
220226
typename ResampleFilterType::Pointer resampler = ResampleFilterType::New();
221227
resampler->SetTransform(registrationMethod->GetDisplacementFieldTransformation());
222-
resampler->SetInput((const RegImageType*)proc->movingImages()[0].GetPointer());
223-
resampler->SetSize( proc->fixedImage()->GetLargestPossibleRegion().GetSize() );
224-
resampler->SetOutputOrigin( proc->fixedImage()->GetOrigin() );
225-
resampler->SetOutputSpacing( proc->fixedImage()->GetSpacing() );
226-
resampler->SetOutputDirection( proc->fixedImage()->GetDirection() );
227-
resampler->SetDefaultPixelValue( 0 );
228+
resampler->SetInput(inputMoving);
229+
resampler->SetDefaultPixelValue(0);
228230

229231
// Set the image interpolator
230232
switch(interpolatorType)
@@ -266,31 +268,11 @@ int LCCLogDemonsPrivate::update()
266268
qDebug() << "ExceptionObject caught (resampler): " << err.GetDescription();
267269
return medAbstractProcessLegacy::FAILURE;
268270
}
269-
270-
itk::ImageBase<3>::Pointer result = resampler->GetOutput();
271-
result->DisconnectPipeline();
272-
273-
if (proc->output())
274-
{
275-
proc->output()->setData (result);
276-
}
277-
return medAbstractProcessLegacy::SUCCESS;
278-
}
279271

280-
medAbstractProcessLegacy::DataError LCCLogDemons::testInputs()
281-
{
282-
if (d->proc->fixedImage()->GetLargestPossibleRegion().GetSize()
283-
!= d->proc->movingImages()[0]->GetLargestPossibleRegion().GetSize())
284-
{
285-
return medAbstractProcessLegacy::MISMATCHED_DATA_SIZE;
286-
}
287-
288-
if (d->proc->fixedImage()->GetSpacing()
289-
!= d->proc->movingImages()[0]->GetSpacing())
272+
if (proc->output())
290273
{
291-
return medAbstractProcessLegacy::MISMATCHED_DATA_SPACING;
274+
proc->output()->setData(resampler->GetOutput());
292275
}
293-
294276
return medAbstractProcessLegacy::SUCCESS;
295277
}
296278

src/plugins/legacy/LCCLogDemons/LCCLogDemons.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,6 @@ class LCCLogDemonsPLUGIN_EXPORT LCCLogDemons : public itkProcessRegistration
6969
*/
7070
virtual QString getTitleAndParameters();
7171

72-
/**
73-
* @brief testInputs() tests origin, dimension and spacing of the input
74-
* @return medAbstractProcess::DataError according to the test result
75-
*/
76-
medAbstractProcessLegacy::DataError testInputs();
7772
protected :
7873
/**
7974
* @brief

src/plugins/legacy/LCCLogDemons/LCCLogDemonsToolBox.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,8 @@ class LCCLogDemonsToolBoxPrivate
5353
LCCLogDemonsToolBox::LCCLogDemonsToolBox(QWidget *parent) : medAbstractSelectableToolBox(parent), d(new LCCLogDemonsToolBoxPrivate)
5454
{
5555
QWidget *widget = new QWidget(this);
56-
5756
QVBoxLayout * layout = new QVBoxLayout();
5857

59-
QLabel *explanation = new QLabel("Drop 2 datasets with same size and spacing.\n");
60-
explanation->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
61-
explanation->setWordWrap(true);
62-
explanation->setStyleSheet("font: italic");
63-
layout->addWidget(explanation);
64-
6558
// Standard parameters
6659
d->iterationsLine = new QLineEdit();
6760
d->iterationsLine->setText("15x10x5");

src/plugins/legacy/diffeomorphicDemons/diffeomorphicDemons.cpp

Lines changed: 25 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
#include <dtkCoreSupport/dtkAbstractProcessFactory.h>
1717
#include <DiffeomorphicDemons/rpiDiffeomorphicDemons.hxx>
18-
#include <itkChangeInformationImageFilter.h>
18+
#include <itkResampleImageFilter.h>
1919
#include <rpiCommonTools.hxx>
2020

2121
// /////////////////////////////////////////////////////////////////
@@ -93,33 +93,29 @@ int diffeomorphicDemonsPrivate::update()
9393
{
9494
typedef itk::Image< PixelType, 3 > FixedImageType;
9595
typedef itk::Image< PixelType, 3 > MovingImageType;
96-
9796
typedef itk::Image< float, 3 > RegImageType;
9897
typedef double TransformScalarType;
9998

100-
int testResult = proc->testInputs();
101-
if (testResult != medAbstractProcessLegacy::SUCCESS)
102-
{
103-
return testResult;
104-
}
105-
106-
FixedImageType *inputFixed = (FixedImageType*) proc->fixedImage().GetPointer();
107-
MovingImageType *inputMoving = (MovingImageType*) proc->movingImages()[0].GetPointer();
108-
109-
// The output volume is going to located at the origin/direction of the fixed input. Needed for rpi::DiffeomorphicDemons
110-
typedef itk::ChangeInformationImageFilter< FixedImageType > FilterType;
111-
typename FilterType::Pointer filter = FilterType::New();
112-
filter->SetOutputOrigin(inputFixed->GetOrigin());
113-
filter->ChangeOriginOn();
114-
filter->SetOutputDirection(inputFixed->GetDirection());
115-
filter->ChangeDirectionOn();
116-
filter->SetInput(inputMoving);
117-
99+
FixedImageType *inputFixed = static_cast<FixedImageType*>(proc->fixedImage().GetPointer());
100+
MovingImageType *inputMoving = static_cast<MovingImageType*>(proc->movingImages()[0].GetPointer());
101+
102+
// Cast spacing, origin, direction and size from the moving data to the fixed one
103+
typedef itk::ResampleImageFilter<MovingImageType, MovingImageType> ResampleFilterType;
104+
typename ResampleFilterType::Pointer resampleFilter = ResampleFilterType::New();
105+
resampleFilter->SetOutputSpacing(inputFixed->GetSpacing());
106+
resampleFilter->SetOutputOrigin(inputFixed->GetOrigin());
107+
resampleFilter->SetOutputDirection(inputFixed->GetDirection());
108+
resampleFilter->SetSize(inputFixed->GetLargestPossibleRegion().GetSize());
109+
resampleFilter->SetInput(inputMoving);
110+
resampleFilter->Update();
111+
inputMoving = resampleFilter->GetOutput();
112+
113+
// Register the fixed and moving data
118114
typedef rpi::DiffeomorphicDemons< RegImageType, RegImageType, TransformScalarType > RegistrationType;
119115
RegistrationType *registration = new RegistrationType;
120116
registrationMethod = registration;
121117
registration->SetFixedImage(inputFixed);
122-
registration->SetMovingImage(filter->GetOutput());
118+
registration->SetMovingImage(inputMoving);
123119
registration->SetNumberOfIterations(iterations);
124120
registration->SetMaximumUpdateStepLength(maximumUpdateStepLength);
125121
registration->SetUpdateFieldStandardDeviation(updateFieldStandardDeviation);
@@ -160,7 +156,6 @@ int diffeomorphicDemonsPrivate::update()
160156

161157
// Print method parameters
162158
QString methodParameters = proc->getTitleAndParameters();
163-
164159
qDebug() << "METHOD PARAMETERS";
165160
qDebug() << methodParameters;
166161

@@ -181,53 +176,29 @@ int diffeomorphicDemonsPrivate::update()
181176

182177
emit proc->progressed(80);
183178

184-
typedef itk::ResampleImageFilter< MovingImageType,MovingImageType,TransformScalarType > ResampleFilterType;
185-
typename ResampleFilterType::Pointer resampler = ResampleFilterType::New();
186-
resampler->SetTransform(registration->GetTransformation());
187-
resampler->SetInput((const MovingImageType*) inputMoving);
188-
resampler->SetSize( proc->fixedImage()->GetLargestPossibleRegion().GetSize() );
189-
resampler->SetOutputOrigin( proc->fixedImage()->GetOrigin() );
190-
resampler->SetOutputSpacing( proc->fixedImage()->GetSpacing() );
191-
resampler->SetOutputDirection( proc->fixedImage()->GetDirection() );
192-
resampler->SetDefaultPixelValue( 0 );
193-
179+
// Cast new transformation
180+
typedef itk::ResampleImageFilter< MovingImageType,MovingImageType,TransformScalarType > ResampleTransformation;
181+
typename ResampleTransformation::Pointer resampleTransformation = ResampleTransformation::New();
182+
resampleTransformation->SetTransform(registration->GetTransformation());
183+
resampleTransformation->SetInput(inputMoving);
184+
resampleTransformation->SetDefaultPixelValue(0);
194185
try
195186
{
196-
resampler->Update();
187+
resampleTransformation->Update();
197188
}
198189
catch (itk::ExceptionObject & err)
199190
{
200191
qDebug() << "ExceptionObject caught (resampler): " << err.GetDescription();
201192
return medAbstractProcessLegacy::FAILURE;
202193
}
203194

204-
itk::ImageBase<3>::Pointer result = resampler->GetOutput();
205-
result->DisconnectPipeline();
206-
207195
if (proc->output())
208196
{
209-
proc->output()->setData (result);
197+
proc->output()->setData(resampleTransformation->GetOutput());
210198
}
211199
return medAbstractProcessLegacy::SUCCESS;
212200
}
213201

214-
medAbstractProcessLegacy::DataError diffeomorphicDemons::testInputs()
215-
{
216-
if (d->proc->fixedImage()->GetLargestPossibleRegion().GetSize()
217-
!= d->proc->movingImages()[0]->GetLargestPossibleRegion().GetSize())
218-
{
219-
return medAbstractProcessLegacy::MISMATCHED_DATA_SIZE;
220-
}
221-
222-
if (d->proc->fixedImage()->GetSpacing()
223-
!= d->proc->movingImages()[0]->GetSpacing())
224-
{
225-
return medAbstractProcessLegacy::MISMATCHED_DATA_SPACING;
226-
}
227-
228-
return medAbstractProcessLegacy::SUCCESS;
229-
}
230-
231202
int diffeomorphicDemons::update(itkProcessRegistration::ImageType imgType)
232203
{
233204
// Cast has been done in itkProcessRegistration

src/plugins/legacy/diffeomorphicDemons/diffeomorphicDemons.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,6 @@ class DIFFEOMORPHICDEMONSPLUGIN_EXPORT diffeomorphicDemons : public itkProcessRe
138138
*/
139139
virtual QString getTitleAndParameters();
140140

141-
/**
142-
* @brief testInputs() tests origin, dimension and spacing of the input
143-
* @return medAbstractProcess::DataError according to the test result
144-
*/
145-
medAbstractProcessLegacy::DataError testInputs();
146-
147141
protected :
148142
/**
149143
* @brief Writes the transformation, in this case the displacement field,

src/plugins/legacy/diffeomorphicDemons/diffeomorphicDemonsToolBox.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,8 @@ diffeomorphicDemonsToolBox::diffeomorphicDemonsToolBox(QWidget *parent)
4242
: medAbstractSelectableToolBox(parent), d(new diffeomorphicDemonsToolBoxPrivate)
4343
{
4444
QWidget *widget = new QWidget(this);
45-
4645
QVBoxLayout *layout = new QVBoxLayout();
4746

48-
QLabel *explanation = new QLabel("Drop 2 datasets with same size and spacing.\n");
49-
explanation->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
50-
explanation->setWordWrap(true);
51-
explanation->setStyleSheet("font: italic");
52-
layout->addWidget(explanation);
53-
5447
d->iterationsBox = new QLineEdit();
5548
d->iterationsBox->setText("15x10x5");
5649
d->iterationsBox->setToolTip(tr("Each number of iteration per level must be separated by \"x\". From coarser to finest levels"));

src/plugins/legacy/manualRegistration/manualRegistration.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,12 @@ template <typename PixelType, typename TransformType> int manualRegistrationPriv
160160
typedef itk::ResampleImageFilter< MovingImageType,MovingImageType,TransformScalarType > ResampleFilterType;
161161
typename ResampleFilterType::Pointer resampler = ResampleFilterType::New();
162162
resampler->SetTransform(transform);
163-
resampler->SetInput((const MovingImageType*)proc->movingImages()[0].GetPointer());
164-
resampler->SetSize( proc->fixedImage()->GetLargestPossibleRegion().GetSize() );
163+
resampler->SetInput(static_cast<const MovingImageType*>(proc->movingImages()[0].GetPointer()));
164+
resampler->SetSize(proc->fixedImage()->GetLargestPossibleRegion().GetSize());
165165
resampler->SetOutputOrigin( proc->fixedImage()->GetOrigin() );
166166
resampler->SetOutputSpacing( proc->fixedImage()->GetSpacing() );
167167
resampler->SetOutputDirection( proc->fixedImage()->GetDirection() );
168-
resampler->SetDefaultPixelValue( 0 );
168+
resampler->SetDefaultPixelValue(0);
169169

170170
try
171171
{

src/plugins/legacy/manualRegistration/manualRegistrationToolBox.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,10 @@ manualRegistrationToolBox::manualRegistrationToolBox(QWidget *parent)
7070
d->b_startManualRegistration->setObjectName("startManualRegistrationButton");
7171

7272
d->explanation = new QLabel("To add a landmark: \n\tShift + left mouse button\nTo remove a pair of landmarks: \n\tBackspace + left mouse button", widget);
73+
d->explanation->setStyleSheet("font: italic");
7374

74-
d->numberOfLdInLeftContainer = new QLabel("Number of landmarks in left container: 0", widget);
75-
d->numberOfLdInRightContainer = new QLabel("Number of landmarks in right container: 0", widget);
75+
d->numberOfLdInLeftContainer = new QLabel("Number of landmarks in left container: <b>0</b>", widget);
76+
d->numberOfLdInRightContainer = new QLabel("Number of landmarks in right container: <b>0</b>", widget);
7677

7778
// Choice between transformations
7879
QHBoxLayout* transformationLayout = new QHBoxLayout;
@@ -564,8 +565,8 @@ void manualRegistrationToolBox::displayButtons(bool show)
564565

565566
void manualRegistrationToolBox::updateGUI(int left, int right)
566567
{
567-
d->numberOfLdInLeftContainer->setText( "Number of landmarks in left container: " + QString::number(left));
568-
d->numberOfLdInRightContainer->setText("Number of landmarks in right container: " + QString::number(right));
568+
d->numberOfLdInLeftContainer->setText(QString("Number of landmarks in left container: <b>%1</b>").arg(left));
569+
d->numberOfLdInRightContainer->setText(QString("Number of landmarks in right container: <b>%1</b>").arg(right));
569570

570571
if (left == right)
571572
{

0 commit comments

Comments
 (0)