MorphologicalAttributeFilters
Public API documentation
Loading...
Searching...
No Matches
Image.hpp
Go to the documentation of this file.
1#pragma once
2
8#include <memory>
9#include <cstdint>
10#include <cstddef>
11#include <algorithm>
12#include <utility>
13#include <cstdlib>
14#include <limits>
15#include <stdexcept>
16
17namespace mmcfilters {
18
36template <typename PixelType>
37class Image {
38 private:
39 int numRows;
40 int numCols;
41 std::shared_ptr<PixelType[]> data;
42 using Ptr = std::shared_ptr<Image<PixelType>>;
43
44 static std::size_t checkedSize(int rows, int cols) {
45 if (rows <= 0 || cols <= 0) {
46 throw std::invalid_argument("Image dimensions must be positive.");
47 }
48 const auto rowCount = static_cast<std::size_t>(rows);
49 const auto colCount = static_cast<std::size_t>(cols);
50 if (rowCount > static_cast<std::size_t>(std::numeric_limits<int>::max()) / colCount) {
51 throw std::overflow_error("Image dimensions exceed the supported int-indexed size.");
52 }
53 return rowCount * colCount;
54 }
55
56 public:
58 using Type = PixelType;
59
68 Image(int rows, int cols): numRows(rows), numCols(cols), data(new PixelType[checkedSize(rows, cols)], std::default_delete<PixelType[]>()) {}
69
79 [[nodiscard]] static Ptr create(int rows, int cols) {
80 return std::make_shared<Image>(rows, cols);
81 }
82
93 [[nodiscard]] static Ptr create(int rows, int cols, PixelType initValue) {
94 auto img = create(rows, cols);
95 img->fill(initValue);
96 return img;
97 }
98
112 [[nodiscard]] static Ptr fromExternal(PixelType* rawPtr, int rows, int cols) {
113 if (rawPtr == nullptr) {
114 throw std::invalid_argument("Image::fromExternal requires a non-null raw pointer.");
115 }
116 auto img = create(rows, cols);
117 img->data = std::shared_ptr<PixelType[]>(rawPtr, [](PixelType*) {
118 // Empty deleter: the wrapper does not release external memory.
119 });
120 return img;
121 }
122
133 [[nodiscard]] static Ptr fromRaw(PixelType* rawPtr, int rows, int cols) {
134 if (rawPtr == nullptr) {
135 throw std::invalid_argument("Image::fromRaw requires a non-null raw pointer.");
136 }
137 auto img = create(rows, cols);
138 img->data = std::shared_ptr<PixelType[]>(rawPtr, std::default_delete<PixelType[]>());
139 return img;
140 }
141
142
149 std::fill_n(data.get(), numRows * numCols, value);
150 }
151
160 bool isEqual(const Ptr& other) const {
161 if (numRows != other->numRows || numCols != other->numCols)
162 return false;
163 int n = numRows * numCols;
164 for (int i = 0; i < n; ++i) {
165 if (data[i] != (*other)[i])
166 return false;
167 }
168 return true;
169 }
170
178 [[nodiscard]] Ptr clone() const {
179 auto newImg = create(numRows, numCols);
180 std::copy(data.get(), data.get() + (numRows * numCols), newImg->data.get());
181 return newImg;
182 }
183
191 std::shared_ptr<PixelType[]> rawDataPtr(){ return data; }
192
199 PixelType* rawData() { return data.get(); }
200
204 int getNumRows() const { return numRows; }
205
209 int getNumCols() const { return numCols; }
210
214 int getSize() const { return numRows * numCols; }
215
222 PixelType& operator[](int index) { return data[index]; }
223
230 const PixelType& operator[](int index) const { return data[index]; }
231
232
233};
234
241
243using ImageUInt8Ptr = std::shared_ptr<ImageUInt8>;
245using ImageInt32Ptr = std::shared_ptr<ImageInt32>;
247using ImageFloatPtr = std::shared_ptr<ImageFloat>;
248
252template <typename PixelType>
253using ImagePtr = std::shared_ptr<Image<PixelType>>;
254
255
263public:
272 inline static int to1D(int row, int col, int numCols) noexcept{
273 return row * numCols + col;
274 }
275
283 inline static std::pair<int, int> to2D(int index, int numCols) noexcept {
284 int row = index / numCols;
285 int col = index - row * numCols;
286 return {row, col};
287 }
288
303 int max = 0;
305 for (int i = 0; i < sizeImage; i++){
306 if (img[i] > max)
307 max = img[i];
308 }
309
310 std::unique_ptr<int[]> r(new int[max + 1]);
311 std::unique_ptr<int[]> g(new int[max + 1]);
312 std::unique_ptr<int[]> b(new int[max + 1]);
313 r[0] = 0;
314 g[0] = 0;
315 r[0] = 0;
316 for (int i = 1; i <= max; i++){
317 r[i] = rand() % 256;
318 g[i] = rand() % 256;
319 b[i] = rand() % 256;
320 }
321
322 int sizeOutput = sizeImage * 3; // [(R,G,B), (R,G,B), ...]
323 ImageUInt8Ptr outImage = ImageUInt8::create(numRowsOfImage, numColsOfImage * 3);
324
325 auto output = outImage->rawData();
326 // Initialise with zero.
327 std::fill_n(output, sizeOutput, 0);
328
329 for (int pidx = 0; pidx < sizeImage; pidx++){
330 int cpidx = pidx * 3; // (coloured) for 3 channels
331 output[cpidx] = r[img[pidx]];
332 output[cpidx + 1] = g[img[pidx]];
333 output[cpidx + 2] = b[img[pidx]];
334 }
335 return outImage;
336 }
337
338
339};
340
341}
std::shared_ptr< ImageFloat > ImageFloatPtr
Shared pointer to a single-precision floating-point image.
Definition Image.hpp:247
std::shared_ptr< ImageInt32 > ImageInt32Ptr
Shared pointer to a 32-bit signed integer image.
Definition Image.hpp:245
std::shared_ptr< Image< PixelType > > ImagePtr
Shared pointer alias for an image with arbitrary pixel type.
Definition Image.hpp:253
std::shared_ptr< ImageUInt8 > ImageUInt8Ptr
Shared pointer to an 8-bit unsigned image.
Definition Image.hpp:243
Utility functions for basic image conversion and manipulation.
Definition Image.hpp:262
static std::pair< int, int > to2D(int index, int numCols) noexcept
Converts a row-major linear index to (row, col).
Definition Image.hpp:283
static int to1D(int row, int col, int numCols) noexcept
Converts (row, col) to a row-major linear index.
Definition Image.hpp:272
static ImageUInt8Ptr createRandomColor(int *img, int numRowsOfImage, int numColsOfImage)
Creates a random-colour visualisation from an integer-labelled image.
Definition Image.hpp:302
Generic row-major 2D image with contiguous storage and shared ownership.
Definition Image.hpp:37
const PixelType & operator[](int index) const
Returns immutable linear access to pixel index.
Definition Image.hpp:230
int getSize() const
Returns the total number of pixels.
Definition Image.hpp:214
Image(int rows, int cols)
Allocates an owned row-major image buffer.
Definition Image.hpp:68
int getNumCols() const
Returns the number of image columns.
Definition Image.hpp:209
void fill(PixelType value)
Fills every pixel with value.
Definition Image.hpp:148
bool isEqual(const Ptr &other) const
Returns true when shape and pixel values match other.
Definition Image.hpp:160
static Ptr create(int rows, int cols, PixelType initValue)
Creates an owned image and fills every pixel with initValue.
Definition Image.hpp:93
PixelType & operator[](int index)
Returns mutable linear access to pixel index.
Definition Image.hpp:222
static Ptr fromRaw(PixelType *rawPtr, int rows, int cols)
Wraps row-major memory and takes ownership through delete[].
Definition Image.hpp:133
Ptr clone() const
Returns a deep copy with its own owned buffer.
Definition Image.hpp:178
PixelType * rawData()
Returns a mutable pointer to the contiguous row-major buffer.
Definition Image.hpp:199
static Ptr create(int rows, int cols)
Creates an owned image with uninitialised pixel values.
Definition Image.hpp:79
std::shared_ptr< PixelType[]> rawDataPtr()
Returns the shared pointer that owns or wraps the raw buffer.
Definition Image.hpp:191
int getNumRows() const
Returns the number of image rows.
Definition Image.hpp:204
static Ptr fromExternal(PixelType *rawPtr, int rows, int cols)
Wraps external row-major memory without taking ownership.
Definition Image.hpp:112
Owning result for one computed scalar attribute layout and buffer.