-
-
Notifications
You must be signed in to change notification settings - Fork 686
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ENH: Integrate FastBilateralImageFilter from remote module #5134
base: master
Are you sure you want to change the base?
Conversation
"New" files are taken directly from https://github.com/InsightSoftwareConsortium/ITKFastBilateral at commit e37be230b50c6934b0c260c2ffec8092bf54f498. Modified files are merger of corresponding content from the remote module.
Unless all style and compiler changes that have been contributed in the past 2 to 3 months by Hans and Niels are applied to this code, we will be introducing code having a discouraged style. |
There are multiple remote modules in the same boat. Should we integrate them, and then make code style changes pass on the entire source, including the newly added code? Or require those style changes be made before integrating? The second option will probably require more effort. @N-Dekker and @hjmjohnson might want to pitch in. |
Is the FastBilateralImageFilter still relevant nowadays? I see, there was a publication of the filter by Jordan Woehr on 2009-08-28, A Fast Approximation to the Bilateral Filter for ITK. The remote module was originally by Pablo (@phcerdan) InsightSoftwareConsortium/ITKFastBilateral@451baba In general I would suggest people to double-check if a remote module is still relevant, before integrating them into the core ITK Modules. Otherwise ITK will just grow and grow, increasing the maintenance burden and increasing build times. |
Just in October I wrote this code: if (smoothingSigma > 0.5)
{
// use FastBilateralImageFilter
...
}
else
{
// use BilateralImageFilter
...
} So yes, it is totally relevant. |
|
||
template <class TInputImage, class TOutputImage> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ITK started using typename
for template parameters back in 2013, especially commit 86bbb9d by Hans (@hjmjohnson)
double m_RangeSigma; | ||
DomainSigmaArrayType m_DomainSigma; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nowadays we would use data member initializers:
double m_RangeSigma{ 50.0 };
DomainSigmaArrayType m_DomainSigma{ DomainSigmaArrayType::Filled(40.0) };
FastBilateralImageFilter() | ||
{ | ||
m_DomainSigma.Fill(4.0); | ||
m_RangeSigma = 50.0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nowadays we would do = default
, and use default member initializers.
m_RangeSigma = 50.0; | ||
} | ||
|
||
virtual ~FastBilateralImageFilter() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nowadays:
~FastBilateralImageFilter() override = default;
itkFastBilateralImageFilterTest.cxx | ||
itkFastBilateralImageFilterTest2.cxx | ||
itkFastBilateralImageFilterTest3.cxx |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a fan of test names like "Test2", "Test3", etc. Hope we can eventually move towards more GTest style test, and use more meaningful names for tests.
// Generate test image | ||
itk::ImageFileWriter<ImageType>::Pointer writer; | ||
writer = itk::ImageFileWriter<ImageType>::New(); | ||
writer->SetInput(filter3->GetOutput()); | ||
writer->SetFileName(av[2]); | ||
writer->Update(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nowadays just one line of code:
itk::WriteImage(filter3->GetOutput(), av[2]);
// Generate test image | ||
itk::ImageFileWriter<ImageType>::Pointer writer; | ||
writer = itk::ImageFileWriter<ImageType>::New(); | ||
writer->SetInput(filter->GetOutput()); | ||
writer->SetFileName(av[2]); | ||
writer->Update(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nowadays just one line of code:
itk::WriteImage(filter3->GetOutput(), av[2]);
using WriterType = itk::ImageFileWriter<ImageType>; | ||
WriterType::Pointer writer = WriterType::New(); | ||
writer->SetFileName(outputImageFileName); | ||
writer->SetInput(filter->GetOutput()); | ||
writer->SetUseCompression(true); | ||
|
||
ITK_TRY_EXPECT_NO_EXCEPTION(writer->Update()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nowadays just one line of code:
itk::WriteImage(filter->GetOutput(), outputImageFileName, true);
Is `ITK_TRY_EXPECT_NO_EXCEPTION still necessary? With GTest, a unit test that throw an exception (uncaught) is automatically reported as test failure.
Niels, it would be good if you tackled these (and possibly other changes) yourself. Push changes either to my branch from which this PR is open, or in the current remote module (I would pick up the changes from there later and integrate them in this PR). |
gridImage->Allocate(); | ||
// Init values of image to 0 | ||
gridImage->FillBuffer(0.0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nowadays, no need to call Allocate(); FillBuffer(0.0)
, just call:
gridImage->AllocateInitialized();
for (size_t i = 0; i < ImageDimension + 1; ++i) | ||
{ | ||
gridStartPos[i] = 0; | ||
} | ||
|
||
GridRegionType region; | ||
region.SetSize(gridSize); | ||
region.SetIndex(gridStartPos); | ||
gridImage->SetRegions(region); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would remove both local variables gridStartPos
and region
. gridStartPos
just contains zero's. The region size of the gridImage can be specified directly, without local region
variable, by:
gridImage->SetRegions(gridSize);
@dzenanz Sorry, I'm just doing a little bit of reviewing of this PR now. By the way, none of the comments I made so far look like showstoppers to me. They could also be addressed after merging. Or you could directly address them yourself. |
Could we consider an alternative name to "FastBilateralImageFilter". Anything more descriptive of the name? If another version is created that is even faster, how would it be distinguished? |
I would prefer not to rename it during transition. Having the same class name will make it easier for people to find it. We could rename it in the future, either with next major version of ITK (e.g. v7), or when another implementation appears. |
IMO, all such changes should be applied to the remotes prior to integrating them, even when integrating them is not yet on the roadmap. We tend to forget about examples, modules not turned on by default and remotes. The later may be more difficult, but there have been multiple efforts over time to try to apply sweeping changes trying to avoid the burden it implies doing it one by one/separately/manually on each local clone, e.g. From issue #4748: Ongoing work: |
"New" files are taken directly from
https://github.com/InsightSoftwareConsortium/ITKFastBilateral at commit e37be230b50c6934b0c260c2ffec8092bf54f498.
Modified files are merger of corresponding content from the remote module.
This is the first remote module to be integrated as part of #3371.
PR Checklist