1
1
#include < catch2/catch.hpp>
2
2
3
+ #include " ITKImageProcessing/Filters/ITKImageReader.hpp"
3
4
#include " ITKImageProcessing/Filters/ITKImportImageStack.hpp"
4
5
#include " ITKImageProcessing/ITKImageProcessing_test_dirs.hpp"
5
6
#include " ITKTestBase.hpp"
6
7
7
8
#include " simplnx/DataStructure/DataArray.hpp"
8
9
#include " simplnx/DataStructure/Geometry/ImageGeom.hpp"
10
+ #include " simplnx/Parameters/ChoicesParameter.hpp"
9
11
#include " simplnx/Parameters/GeneratedFileListParameter.hpp"
10
12
#include " simplnx/UnitTest/UnitTestCommon.hpp"
11
13
@@ -20,6 +22,144 @@ namespace
20
22
const std::string k_ImageStackDir = unit_test::k_DataDir.str() + " /ImageStack" ;
21
23
const DataPath k_ImageGeomPath = {{" ImageGeometry" }};
22
24
const DataPath k_ImageDataPath = k_ImageGeomPath.createChildPath(ImageGeom::k_CellDataName).createChildPath(" ImageData" );
25
+ const std::string k_FlippedImageStackDirName = " image_flip_test_images" ;
26
+ const DataPath k_XGeneratedImageGeomPath = DataPath({" xGeneratedImageGeom" });
27
+ const DataPath k_YGeneratedImageGeomPath = DataPath({" yGeneratedImageGeom" });
28
+ const DataPath k_XFlipImageGeomPath = DataPath({" xFlipImageGeom" });
29
+ const DataPath k_YFlipImageGeomPath = DataPath({" yFlipImageGeom" });
30
+ const std::string k_ImageDataName = " ImageData" ;
31
+ const ChoicesParameter::ValueType k_NoImageTransform = 0 ;
32
+ const ChoicesParameter::ValueType k_FlipAboutXAxis = 1 ;
33
+ const ChoicesParameter::ValueType k_FlipAboutYAxis = 2 ;
34
+ const fs::path k_ImageFlipStackDir = fs::path(fmt::format(" {}/{}" , unit_test::k_TestFilesDir, k_FlippedImageStackDirName));
35
+
36
+ // Exemplar Array Paths
37
+ const DataPath k_XFlippedImageDataPath = k_XFlipImageGeomPath.createChildPath(Constants::k_Cell_Data).createChildPath(::k_ImageDataName);
38
+ const DataPath k_YFlippedImageDataPath = k_YFlipImageGeomPath.createChildPath(Constants::k_Cell_Data).createChildPath(::k_ImageDataName);
39
+
40
+ // Make sure we can instantiate the ITK Import Image Stack Filter
41
+ // ITK Image Processing Plugin Uuid
42
+ constexpr AbstractPlugin::IdType k_ITKImageProcessingID = *Uuid::FromString (" 115b0d10-ab97-5a18-88e8-80d35056a28e" );
43
+ const FilterHandle k_ImportImageStackFilterHandle (nx::core::FilterTraits<ITKImportImageStack>::uuid, k_ITKImageProcessingID);
44
+
45
+ void ExecuteImportImageStackXY (DataStructure& dataStructure, const std::string& filePrefix)
46
+ {
47
+ // Filter needs RotateSampleRefFrameFilter to run
48
+ Application::GetOrCreateInstance ()->loadPlugins (unit_test::k_BuildDir.view (), true );
49
+ auto * filterList = nx::core::Application::Instance ()->getFilterList ();
50
+ REQUIRE (filterList != nullptr );
51
+
52
+ // Define Shared parameters
53
+ std::vector<float32> k_Origin = {0 .0f , 0 .0f , 0 .0f };
54
+ std::vector<float32> k_Spacing = {1 .0f , 1 .0f , 1 .0f };
55
+ GeneratedFileListParameter::ValueType k_FileListInfo;
56
+
57
+ // Set File list for reads
58
+ {
59
+ k_FileListInfo.inputPath = k_ImageFlipStackDir.string ();
60
+ k_FileListInfo.startIndex = 1 ;
61
+ k_FileListInfo.endIndex = 1 ;
62
+ k_FileListInfo.incrementIndex = 1 ;
63
+ k_FileListInfo.fileExtension = " .tiff" ;
64
+ k_FileListInfo.filePrefix = filePrefix;
65
+ k_FileListInfo.fileSuffix = " " ;
66
+ k_FileListInfo.paddingDigits = 1 ;
67
+ k_FileListInfo.ordering = GeneratedFileListParameter::Ordering::LowToHigh;
68
+ }
69
+
70
+ // Run generated X flip
71
+ {
72
+ auto importImageStackFilter = filterList->createFilter (::k_ImportImageStackFilterHandle);
73
+ REQUIRE (nullptr != importImageStackFilter);
74
+
75
+ Arguments args;
76
+
77
+ args.insertOrAssign (ITKImportImageStack::k_Origin_Key, std::make_any<std::vector<float32>>(k_Origin));
78
+ args.insertOrAssign (ITKImportImageStack::k_Spacing_Key, std::make_any<std::vector<float32>>(k_Spacing));
79
+ args.insertOrAssign (ITKImportImageStack::k_InputFileListInfo_Key, std::make_any<GeneratedFileListParameter::ValueType>(k_FileListInfo));
80
+ args.insertOrAssign (ITKImportImageStack::k_ImageGeometryPath_Key, std::make_any<DataPath>(::k_XGeneratedImageGeomPath));
81
+ args.insertOrAssign (ITKImportImageStack::k_ImageTransformChoice_Key, std::make_any<ChoicesParameter::ValueType>(::k_FlipAboutXAxis));
82
+
83
+ auto preflightResult = importImageStackFilter->preflight (dataStructure, args);
84
+ SIMPLNX_RESULT_REQUIRE_VALID (preflightResult.outputActions )
85
+
86
+ auto executeResult = importImageStackFilter->execute (dataStructure, args);
87
+ SIMPLNX_RESULT_REQUIRE_VALID (executeResult.result )
88
+ }
89
+
90
+ // Run generated Y flip
91
+ {
92
+ auto importImageStackFilter = filterList->createFilter (::k_ImportImageStackFilterHandle);
93
+ REQUIRE (nullptr != importImageStackFilter);
94
+
95
+ Arguments args;
96
+
97
+ args.insertOrAssign (ITKImportImageStack::k_Origin_Key, std::make_any<std::vector<float32>>(k_Origin));
98
+ args.insertOrAssign (ITKImportImageStack::k_Spacing_Key, std::make_any<std::vector<float32>>(k_Spacing));
99
+ args.insertOrAssign (ITKImportImageStack::k_InputFileListInfo_Key, std::make_any<GeneratedFileListParameter::ValueType>(k_FileListInfo));
100
+ args.insertOrAssign (ITKImportImageStack::k_ImageGeometryPath_Key, std::make_any<DataPath>(::k_YGeneratedImageGeomPath));
101
+ args.insertOrAssign (ITKImportImageStack::k_ImageTransformChoice_Key, std::make_any<ChoicesParameter::ValueType>(::k_FlipAboutYAxis));
102
+
103
+ auto preflightResult = importImageStackFilter->preflight (dataStructure, args);
104
+ SIMPLNX_RESULT_REQUIRE_VALID (preflightResult.outputActions )
105
+
106
+ auto executeResult = importImageStackFilter->execute (dataStructure, args);
107
+ SIMPLNX_RESULT_REQUIRE_VALID (executeResult.result )
108
+ }
109
+ }
110
+
111
+ void ReadInFlippedXYExemplars (DataStructure& dataStructure, const std::string& filePrefix)
112
+ {
113
+ {
114
+ ITKImageReader filter;
115
+ Arguments args;
116
+
117
+ fs::path filePath = k_ImageFlipStackDir / (filePrefix + " flip_x.tiff" );
118
+ args.insertOrAssign (ITKImageReader::k_FileName_Key, filePath);
119
+ args.insertOrAssign (ITKImageReader::k_ImageGeometryPath_Key, ::k_XFlipImageGeomPath);
120
+ args.insertOrAssign (ITKImageReader::k_ImageDataArrayPath_Key, ::k_XFlippedImageDataPath);
121
+
122
+ auto preflightResult = filter.preflight (dataStructure, args);
123
+ SIMPLNX_RESULT_REQUIRE_VALID (preflightResult.outputActions )
124
+
125
+ auto executeResult = filter.execute (dataStructure, args);
126
+ SIMPLNX_RESULT_REQUIRE_VALID (executeResult.result )
127
+ }
128
+ {
129
+ ITKImageReader filter;
130
+ Arguments args;
131
+
132
+ fs::path filePath = k_ImageFlipStackDir / (filePrefix + " flip_y.tiff" );
133
+ args.insertOrAssign (ITKImageReader::k_FileName_Key, filePath);
134
+ args.insertOrAssign (ITKImageReader::k_ImageGeometryPath_Key, ::k_YFlipImageGeomPath);
135
+ args.insertOrAssign (ITKImageReader::k_ImageDataArrayPath_Key, ::k_YFlippedImageDataPath);
136
+
137
+ auto preflightResult = filter.preflight (dataStructure, args);
138
+ SIMPLNX_RESULT_REQUIRE_VALID (preflightResult.outputActions )
139
+
140
+ auto executeResult = filter.execute (dataStructure, args);
141
+ SIMPLNX_RESULT_REQUIRE_VALID (executeResult.result )
142
+ }
143
+ }
144
+
145
+ void CompareXYFlippedGeometries (DataStructure& dataStructure)
146
+ {
147
+ UnitTest::CompareImageGeometry (dataStructure, ::k_XFlipImageGeomPath, k_XGeneratedImageGeomPath);
148
+ UnitTest::CompareImageGeometry (dataStructure, ::k_YFlipImageGeomPath, k_YGeneratedImageGeomPath);
149
+
150
+ // Processed
151
+ DataPath k_XGeneratedImageDataPath = k_XGeneratedImageGeomPath.createChildPath (Constants::k_Cell_Data).createChildPath (::k_ImageDataName);
152
+ DataPath k_YGeneratedImageDataPath = k_YGeneratedImageGeomPath.createChildPath (Constants::k_Cell_Data).createChildPath (::k_ImageDataName);
153
+ const auto & xGeneratedImageData = dataStructure.getDataRefAs <UInt8Array>(k_XGeneratedImageDataPath);
154
+ const auto & yGeneratedImageData = dataStructure.getDataRefAs <UInt8Array>(k_YGeneratedImageDataPath);
155
+
156
+ // Exemplar
157
+ const auto & xFlippedImageData = dataStructure.getDataRefAs <UInt8Array>(k_XFlippedImageDataPath);
158
+ const auto & yFlippedImageData = dataStructure.getDataRefAs <UInt8Array>(k_YFlippedImageDataPath);
159
+
160
+ UnitTest::CompareDataArrays<uint8>(xGeneratedImageData, xFlippedImageData);
161
+ UnitTest::CompareDataArrays<uint8>(yGeneratedImageData, yFlippedImageData);
162
+ }
23
163
} // namespace
24
164
25
165
TEST_CASE (" ITKImageProcessing::ITKImportImageStack: NoInput" , " [ITKImageProcessing][ITKImportImageStack]" )
@@ -154,3 +294,91 @@ TEST_CASE("ITKImageProcessing::ITKImportImageStack: CompareImage", "[ITKImagePro
154
294
const std::string md5Hash = ITKTestBase::ComputeMd5Hash (dataStructure, k_ImageDataPath);
155
295
REQUIRE (md5Hash == " 2620b39f0dcaa866602c2591353116a4" );
156
296
}
297
+
298
+ TEST_CASE (" ITKImageProcessing::ITKImportImageStack: Flipped Image Even-Even X/Y" , " [ITKImageProcessing][ITKImportImageStack]" )
299
+ {
300
+ const nx::core::UnitTest::TestFileSentinel testDataSentinel (nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, " image_flip_test_images.tar.gz" , k_FlippedImageStackDirName);
301
+
302
+ const std::string k_FilePrefix = " image_flip_even_even_" ;
303
+
304
+ DataStructure dataStructure;
305
+
306
+ // Generate XY Image Geometries with ITKImportImageStack
307
+ ::ExecuteImportImageStackXY (dataStructure, k_FilePrefix);
308
+
309
+ // Read in exemplars
310
+ ::ReadInFlippedXYExemplars (dataStructure, k_FilePrefix);
311
+
312
+ #ifdef SIMPLNX_WRITE_TEST_OUTPUT
313
+ UnitTest::WriteTestDataStructure (dataStructure, fmt::format (" {}/even_even_import_image_stack_test.dream3d" , unit_test::k_BinaryTestOutputDir));
314
+ #endif
315
+
316
+ // Compare against exemplars
317
+ ::CompareXYFlippedGeometries (dataStructure);
318
+ }
319
+
320
+ TEST_CASE (" ITKImageProcessing::ITKImportImageStack: Flipped Image Even-Odd X/Y" , " [ITKImageProcessing][ITKImportImageStack]" )
321
+ {
322
+ const nx::core::UnitTest::TestFileSentinel testDataSentinel (nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, " image_flip_test_images.tar.gz" , k_FlippedImageStackDirName);
323
+
324
+ const std::string k_FilePrefix = " image_flip_even_odd_" ;
325
+
326
+ DataStructure dataStructure;
327
+
328
+ // Generate XY Image Geometries with ITKImportImageStack
329
+ ::ExecuteImportImageStackXY (dataStructure, k_FilePrefix);
330
+
331
+ // Read in exemplars
332
+ ::ReadInFlippedXYExemplars (dataStructure, k_FilePrefix);
333
+
334
+ #ifdef SIMPLNX_WRITE_TEST_OUTPUT
335
+ UnitTest::WriteTestDataStructure (dataStructure, fmt::format (" {}/even_odd_import_image_stack_test.dream3d" , unit_test::k_BinaryTestOutputDir));
336
+ #endif
337
+
338
+ // Compare against exemplars
339
+ ::CompareXYFlippedGeometries (dataStructure);
340
+ }
341
+
342
+ TEST_CASE (" ITKImageProcessing::ITKImportImageStack: Flipped Image Odd-Even X/Y" , " [ITKImageProcessing][ITKImportImageStack]" )
343
+ {
344
+ const nx::core::UnitTest::TestFileSentinel testDataSentinel (nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, " image_flip_test_images.tar.gz" , k_FlippedImageStackDirName);
345
+
346
+ const std::string k_FilePrefix = " image_flip_odd_even_" ;
347
+
348
+ DataStructure dataStructure;
349
+
350
+ // Generate XY Image Geometries with ITKImportImageStack
351
+ ::ExecuteImportImageStackXY (dataStructure, k_FilePrefix);
352
+
353
+ // Read in exemplars
354
+ ::ReadInFlippedXYExemplars (dataStructure, k_FilePrefix);
355
+
356
+ #ifdef SIMPLNX_WRITE_TEST_OUTPUT
357
+ UnitTest::WriteTestDataStructure (dataStructure, fmt::format (" {}/odd_even_import_image_stack_test.dream3d" , unit_test::k_BinaryTestOutputDir));
358
+ #endif
359
+
360
+ // Compare against exemplars
361
+ ::CompareXYFlippedGeometries (dataStructure);
362
+ }
363
+
364
+ TEST_CASE (" ITKImageProcessing::ITKImportImageStack: Flipped Image Odd-Odd X/Y" , " [ITKImageProcessing][ITKImportImageStack]" )
365
+ {
366
+ const nx::core::UnitTest::TestFileSentinel testDataSentinel (nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, " image_flip_test_images.tar.gz" , k_FlippedImageStackDirName);
367
+
368
+ const std::string k_FilePrefix = " image_flip_odd_odd_" ;
369
+
370
+ DataStructure dataStructure;
371
+
372
+ // Generate XY Image Geometries with ITKImportImageStack
373
+ ::ExecuteImportImageStackXY (dataStructure, k_FilePrefix);
374
+
375
+ // Read in exemplars
376
+ ::ReadInFlippedXYExemplars (dataStructure, k_FilePrefix);
377
+
378
+ #ifdef SIMPLNX_WRITE_TEST_OUTPUT
379
+ UnitTest::WriteTestDataStructure (dataStructure, fmt::format (" {}/odd_odd_import_image_stack_test.dream3d" , unit_test::k_BinaryTestOutputDir));
380
+ #endif
381
+
382
+ // Compare against exemplars
383
+ ::CompareXYFlippedGeometries (dataStructure);
384
+ }
0 commit comments