1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
/*=========================================================================
*
* Copyright UMC Utrecht and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
#ifndef itkImageFullSampler_h
#define itkImageFullSampler_h
#include "itkImageSamplerBase.h"
#include "elxMaskHasSameImageDomain.h"
namespace itk
{
/** \class ImageFullSampler
*
* \brief Samples all voxels in the InputImageRegion.
*
* This ImageSampler samples all voxels in the InputImageRegion.
* If a mask is given: only those voxels within the mask AND the
* InputImageRegion.
*
* \ingroup ImageSamplers
*/
template <class TInputImage>
class ITK_TEMPLATE_EXPORT ImageFullSampler : public ImageSamplerBase<TInputImage>
{
public:
ITK_DISALLOW_COPY_AND_MOVE(ImageFullSampler);
/** Standard ITK-stuff. */
using Self = ImageFullSampler;
using Superclass = ImageSamplerBase<TInputImage>;
using Pointer = SmartPointer<Self>;
using ConstPointer = SmartPointer<const Self>;
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Run-time type information (and related methods). */
itkTypeMacro(ImageFullSampler, ImageSamplerBase);
/** Typedefs inherited from the superclass. */
using typename Superclass::DataObjectPointer;
using typename Superclass::OutputVectorContainerType;
using typename Superclass::OutputVectorContainerPointer;
using typename Superclass::InputImageType;
using typename Superclass::InputImagePointer;
using typename Superclass::InputImageConstPointer;
using typename Superclass::InputImageRegionType;
using typename Superclass::InputImagePixelType;
using typename Superclass::ImageSampleType;
using typename Superclass::ImageSampleContainerType;
using typename Superclass::ImageSampleContainerPointer;
// Clang/macos-12/Xcode_14.2 does not like `using typename Superclass::MaskType`, saying "error: 'MaskType' is not a
// class, namespace, or enumeration"
using MaskType = typename Superclass::MaskType;
/** The input image dimension. */
itkStaticConstMacro(InputImageDimension, unsigned int, Superclass::InputImageDimension);
/** Other typdefs. */
using typename Superclass::InputImageIndexType;
// using typename Superclass::InputImageSpacingType;
using typename Superclass::InputImagePointType;
/** Typedefs for support of user defined grid spacing for the spatial samples. */
using InputImageSizeType = typename InputImageType::SizeType;
/** Selecting new samples makes no sense if nothing changed. The same samples would be selected anyway. */
bool
SelectNewSamplesOnUpdate() override
{
return false;
}
/** Returns whether the sampler supports SelectNewSamplesOnUpdate(). */
bool
SelectingNewSamplesOnUpdateSupported() const override
{
return false;
}
protected:
/** The constructor. */
ImageFullSampler() = default;
/** The destructor. */
~ImageFullSampler() override = default;
using Superclass::PrintSelf;
/** Function that does the work. */
void
GenerateData() override;
private:
struct WorkUnit
{
const InputImageRegionType imageRegion{};
// Should point to the first sample for this specific work unit.
ImageSampleType * const Samples{};
// The number of samples retrieved by this work unit. Only used when a mask is specified.
size_t NumberOfSamples{};
};
struct UserData
{
ITK_DISALLOW_COPY_AND_MOVE(UserData);
const InputImageType & InputImage;
const MaskType * const Mask{};
std::vector<WorkUnit> WorkUnits{};
};
template <elastix::MaskCondition VMaskCondition>
static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION
ThreaderCallback(void * arg);
/** Generates the work units, to be processed when doing multi-threading. */
static std::vector<WorkUnit>
GenerateWorkUnits(const ThreadIdType numberOfWorkUnits,
const InputImageRegionType & croppedInputImageRegion,
std::vector<ImageSampleType> & samples);
static void
SingleThreadedGenerateData(const TInputImage & inputImage,
const MaskType * const mask,
const InputImageRegionType & croppedInputImageRegion,
std::vector<ImageSampleType> & samples);
static void
MultiThreadedGenerateData(MultiThreaderBase & multiThreader,
const ThreadIdType numberOfWorkUnits,
const TInputImage & inputImage,
const MaskType * const mask,
const InputImageRegionType & croppedInputImageRegion,
std::vector<ImageSampleType> & samples);
/** Generates the data for one specific work unit. */
template <elastix::MaskCondition VMaskCondition>
static void
GenerateDataForWorkUnit(WorkUnit &, const InputImageType &, const MaskType *);
};
} // end namespace itk
#ifndef ITK_MANUAL_INSTANTIATION
# include "itkImageFullSampler.hxx"
#endif
#endif // end #ifndef itkImageFullSampler_h
|