Skip to content

Commit b91c3fb

Browse files
author
Francois Budin
committed
Merge pull request #13 from jeanyves-yang/master
MedianFilter
2 parents e749061 + 10bb6be commit b91c3fb

File tree

9 files changed

+815
-0
lines changed

9 files changed

+815
-0
lines changed

Exercices/MedianFilter/CMakeLists.txt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
cmake_minimum_required(VERSION 2.8)
2+
3+
project(MedianFilter)
4+
5+
# Find SlicerExecutionModel
6+
find_package(SlicerExecutionModel REQUIRED)
7+
include(${SlicerExecutionModel_USE_FILE})
8+
include(${GenerateCLP_USE_FILE})
9+
10+
# Find ITK
11+
find_package(ITK REQUIRED)
12+
include(${ITK_USE_FILE})
13+
14+
set(MedianFilter_SOURCE MedianFilter.cxx)
15+
16+
SEMMacroBuildCLI(
17+
NAME MedianFilter
18+
EXECUTABLE_ONLY
19+
TARGET_LIBRARIES ${ITK_LIBRARIES}
20+
)
21+
22+
option(BUILD_TESTING "Build the testing tree" ON)
23+
24+
IF(BUILD_TESTING)
25+
include(CTest)
26+
ADD_SUBDIRECTORY(Testing)
27+
ENDIF(BUILD_TESTING)
28+
29+
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/*=============================================================================
2+
Licensed under the Apache License, Version 2.0 (the "License");
3+
you may not use this file except in compliance with the License.
4+
You may obtain a copy of the License at
5+
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
8+
Unless required by applicable law or agreed to in writing, software
9+
distributed under the License is distributed on an "AS IS" BASIS,
10+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
See the License for the specific language governing permissions and
12+
limitations under the License.
13+
=============================================================================*/
14+
#include "itkImage.h"
15+
#include "itkImageFileReader.h"
16+
#include "itkImageFileWriter.h"
17+
#include "itkMedianImageFilter.h"
18+
#include "MedianFilterCLP.h"
19+
#include "stdlib.h"
20+
#include "itkImageIOBase.h"
21+
22+
void GetImageType ( std::string fileName , itk::ImageIOBase::IOComponentType &componentType )
23+
{
24+
typedef itk::Image< unsigned char, 3 > ImageType ;
25+
itk::ImageFileReader<ImageType>::Pointer imageReader = itk::ImageFileReader< ImageType >::New() ;
26+
imageReader->SetFileName( fileName.c_str() ) ;
27+
imageReader->UpdateOutputInformation() ;
28+
componentType = imageReader->GetImageIO()->GetComponentType() ;
29+
}
30+
31+
template< class TImage >
32+
int ReadImage( const char* fileName , typename TImage::Pointer& image )
33+
{
34+
typedef TImage ImageType ;
35+
typedef itk::ImageFileReader< ImageType > ImageReaderType ;
36+
typename ImageReaderType::Pointer reader = ImageReaderType::New() ;
37+
reader->SetFileName( fileName ) ;
38+
try
39+
{
40+
reader->Update() ;
41+
}
42+
catch( itk::ExceptionObject& e )
43+
{
44+
std::cerr << e.what() << std::endl ;
45+
return 1 ;
46+
}
47+
image = reader->GetOutput() ;
48+
return 0 ;
49+
}
50+
/* Creates the Median Filter and the output image with the input type. */
51+
template< class ComponentType >
52+
int MedianFilter( std::string inputFileName , std::string outputFileName , int radius )
53+
{
54+
typedef itk::Image< ComponentType , 3 > ImageType ;
55+
typedef itk::MedianImageFilter < ImageType , ImageType > FilterType ;
56+
typename FilterType::Pointer medianFilter = FilterType::New() ;
57+
typename FilterType::InputSizeType filterRadius ;
58+
typename ImageType::Pointer image = ImageType::New() ;
59+
if( radius < 1 )
60+
{
61+
std::cout << "Radius value must be non-zero positive integer." << std::endl ;
62+
return EXIT_FAILURE ;
63+
}
64+
if( ReadImage< ImageType >( inputFileName.c_str() , image ) )
65+
{
66+
std::cout << "Image could not be read." << std::endl ;
67+
return EXIT_FAILURE ;
68+
}
69+
filterRadius.Fill( radius ) ;
70+
medianFilter->SetRadius( filterRadius ) ;
71+
medianFilter->SetInput( image ) ;
72+
typedef itk::ImageFileWriter< ImageType > WriterType ;
73+
typename WriterType::Pointer writer = WriterType::New() ;
74+
writer->SetInput( medianFilter->GetOutput() ) ;
75+
writer->SetFileName( outputFileName ) ;
76+
writer->Update() ;
77+
return EXIT_SUCCESS ;
78+
}
79+
80+
int main( int argc , char *argv[] )
81+
{
82+
PARSE_ARGS ;
83+
itk::ImageIOBase::IOPixelType pixelType ;
84+
itk::ImageIOBase::IOComponentType componentType ;
85+
try
86+
{
87+
GetImageType( input , componentType ) ;
88+
/* Apply the Median Filter according to the type of the input file */
89+
switch( componentType )
90+
{
91+
case itk::ImageIOBase::UCHAR:
92+
{
93+
return MedianFilter< unsigned char >( input , output , radius ) ;
94+
break ;
95+
}
96+
case itk::ImageIOBase::CHAR:
97+
{
98+
return MedianFilter< char >( input , output , radius ) ;
99+
break ;
100+
}
101+
case itk::ImageIOBase::USHORT:
102+
{
103+
return MedianFilter< unsigned short >( input , output , radius ) ;
104+
break ;
105+
}
106+
case itk::ImageIOBase::SHORT:
107+
{
108+
return MedianFilter< short >( input , output , radius ) ;
109+
break ;
110+
}
111+
case itk::ImageIOBase::UINT:
112+
{
113+
return MedianFilter< unsigned int >( input , output , radius ) ;
114+
break ;
115+
}
116+
case itk::ImageIOBase::INT:
117+
{
118+
return MedianFilter< int >( input , output , radius ) ;
119+
break ;
120+
}
121+
case itk::ImageIOBase::ULONG:
122+
{
123+
return MedianFilter< unsigned long >( input , output , radius ) ;
124+
break ;
125+
}
126+
case itk::ImageIOBase::LONG:
127+
{
128+
return MedianFilter< long >( input , output , radius ) ;
129+
break ;
130+
}
131+
case itk::ImageIOBase::FLOAT:
132+
{
133+
return MedianFilter< float >( input , output , radius ) ;
134+
break ;
135+
}
136+
case itk::ImageIOBase::DOUBLE:
137+
{
138+
return MedianFilter< double >( input , output , radius ) ;
139+
break ;
140+
}
141+
default:
142+
case itk::ImageIOBase::UNKNOWNCOMPONENTTYPE:
143+
{
144+
std::cerr << "Unknown and unsupported component type!" << std::endl ;
145+
return EXIT_FAILURE ;
146+
}
147+
}
148+
}
149+
catch( itk::ExceptionObject &excep )
150+
{
151+
std::cerr << argv[0] << ": exception caught !" << std::endl ;
152+
std::cerr << excep << std::endl ;
153+
return EXIT_FAILURE ;
154+
}
155+
return EXIT_SUCCESS ;
156+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<executable>
3+
<category>Filtering.Arithmetic</category>
4+
<title>Median Image Filtering</title>
5+
<description>Median filter of a image</description>
6+
7+
<parameters>
8+
<label>IO</label>
9+
<description>Input/Output parameters</description>
10+
11+
<image>
12+
<name>input</name>
13+
<label>image input</label>
14+
<channel>image</channel>
15+
<index>0</index>
16+
<description>image input</description>
17+
</image>
18+
19+
<image>
20+
<name>output</name>
21+
<label>image output</label>
22+
<channel>image</channel>
23+
<index>1</index>
24+
<description>image output</description>
25+
</image>
26+
27+
<integer>
28+
<name>radius</name>
29+
<longflag>radius</longflag>
30+
<flag>r</flag>
31+
<label>radius</label>
32+
<description>radius value</description>
33+
<constraints>
34+
<minimum>1</minimum>
35+
</constraints>
36+
</integer>
37+
38+
</parameters>
39+
40+
</executable>
41+
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
set(Data Data)
2+
3+
set(TEMP_DIR ${MedianFilter_BINARY_DIR}/Testing/Temporary )
4+
set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/${Data} )
5+
6+
set(BaselineRadius2 ${SOURCE_DIR}/baselineT2Radius2.nrrd )
7+
set(BaselineRadius4 ${SOURCE_DIR}/baselineT2Radius4.nrrd )
8+
set(DummyOutput ${SOURCE_DIR}/DummyOutput.nrrd )
9+
set(Input ${SOURCE_DIR}/inputT2.nrrd )
10+
include_directories( ${CMAKE_SOURCE_DIR} )
11+
add_executable(MedianFilterTest MedianFilterTest.cxx)
12+
target_link_libraries(MedianFilterTest MedianFilterLib)
13+
set( RadiusValue2 ${TEMP_DIR}/RadiusValue2.nrrd )
14+
set( RadiusValue4 ${TEMP_DIR}/RadiusValue4.nrrd )
15+
16+
# Test checking that the program cannot run without arguments
17+
add_test(NAME OpenFileTest COMMAND $<TARGET_FILE:MedianFilter>)
18+
set_tests_properties(OpenFileTest PROPERTIES WILL_FAIL true )
19+
20+
# Test checking that the radius value cannot go below 1
21+
add_test(NAME RadiusLimitMin COMMAND $<TARGET_FILE:MedianFilter>
22+
${Input}
23+
${DummyOutput}
24+
-r 0
25+
)
26+
set_tests_properties( RadiusLimitMin PROPERTIES WILL_FAIL true )
27+
28+
#Test checking that a wrong input will prevent the program from running
29+
add_test(NAME MedianFilterWrongInputFileName COMMAND $<TARGET_FILE:MedianFilter>
30+
WrongInput.nrrd
31+
${DummyOutput}
32+
-r 20
33+
)
34+
set_tests_properties( MedianFilterWrongInputFileName PROPERTIES WILL_FAIL true )
35+
36+
# Tests checking that that the output image is what is expected
37+
add_test(NAME MedianFilterRadiusValue2 COMMAND $<TARGET_FILE:MedianFilterTest>
38+
--compare
39+
${BaselineRadius2}
40+
${RadiusValue2}
41+
ModuleEntryPoint
42+
${Input}
43+
${RadiusValue2}
44+
-r 2
45+
)
46+
47+
add_test(NAME MedianFilterRadiusValue4 COMMAND $<TARGET_FILE:MedianFilterTest>
48+
--compare
49+
${BaselineRadius4}
50+
${RadiusValue4}
51+
ModuleEntryPoint
52+
${Input}
53+
${RadiusValue4}
54+
-r 4
55+
)
56+
57+
# Test for the command --help
58+
add_test(NAME PrintHelp COMMAND $<TARGET_FILE:MedianFilter> --help)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include "itkTestMain.h"
2+
3+
#ifdef WIN32
4+
#define MODULE_IMPORT __declspec(dllimport)
5+
#else
6+
#define MODULE_IMPORT
7+
#endif
8+
9+
extern "C" MODULE_IMPORT int ModuleEntryPoint(int, char * []);
10+
11+
void RegisterTests()
12+
{
13+
StringToTestFunctionMap["ModuleEntryPoint"] = ModuleEntryPoint;
14+
}

0 commit comments

Comments
 (0)