C++ Images
Image Classes
-
template<typename T>
class AssignableToImage AssignableToImage is a base class for anything that can be assigned to an Image.
It is the base class for both BaseImage, which has all the real image types and various composite types that are used to make im3 = im1 + im2 efficient.
Subclassed by galsim::BaseImage< T >
-
template<typename T>
class BaseImage : public galsim::AssignableToImage<T> BaseImage class defines the interface of what you can do with Images without modifying pixels.
BaseImage is the base class for the other Image types:
You should never need to declare an object of this class directly, using instead the various derived classes. However, if you are using an image as a parameter to a function in a non-modifying context, then it is convenient to declare the parameter “const BaseImage<T>&” so that any of the various image types can be used without requiring any casts.
Subclassed by galsim::ConstImageView< T >, galsim::ImageAlloc< T >, galsim::ImageView< T >
Public Functions
-
inline virtual ~BaseImage()
Destructor is virtual and public.
Note: There are no public constructors, since this is an abstract base class. But the destructor should be public (and virtual).
Nothing special needs to be done here, since shared_ptr takes care of deleting the data if this is the last thing to own the data.
-
inline shared_ptr<T> getOwner() const
Return a shared pointer that manages the lifetime of the image’s pixels.
The actual pointer will point to a parent image rather than the image itself if this is a subimage.
-
inline bool ok_ptr(const T *p) const
Check that the ptr is valid, properly accounting for step, stride.
-
inline ptrdiff_t getNElements() const
Return how many data elements are currently allocated in memory.
This is usually the same as getBounds().area(), but it may not be if the image has been resized.
-
inline int getStride() const
Return the number of elements between rows in memory.
-
inline int getStep() const
Return the number of elements between cols in memory.
-
inline int getNCol() const
Return the number of columns in the image.
-
inline int getNRow() const
Return the number of rows in the image.
-
inline int getNSkip() const
Return the number of columns to skip at the end of each row when iterating.
-
inline bool isContiguous() const
Return whether the data is contiguous in memory.
Shorthand for: (getStride() == getNCol()) or equivalently (getNSkip() == 0)
-
inline ImageAlloc<T> copy() const
Deep copy the image.
The returned image will have the same bounding box and pixel values as this, but will they will not share data.
-
inline ConstImageView<T> view() const
Create a new view of the image.
The returned image will share data with this image
-
ConstImageView<T> subImage(const Bounds<int> &bounds) const
New image that is a subimage of this (shares pixels)
-
inline ConstImageView<T> operator[](const Bounds<int> &bounds) const
im[bounds] is another syntax for making a sub-image
-
Bounds<int> nonZeroBounds() const
Return the smallest bounds that includes all non-zero elements of the image.
-
inline void shift(const Position<int> &delta)
Shift the bounding box of the image, changing the logical location of the pixels.
xmin_new = xmin + dx xmax_new = xmax + dx ymin_new = ymin + dy ymax_new = ymax + dy
-
inline int getXMin() const
Convenience accessors for the bounding box corners.
-
inline int getXMax() const
-
inline int getYMin() const
-
inline int getYMax() const
-
inline virtual ~BaseImage()
-
template<typename T>
class ImageAlloc : public galsim::BaseImage<T> ImageAlloc class.
The ImageAlloc class is a 2-d array with pixel values stored contiguously in memory along rows (but not necessarily between rows). An image’s pixel values may be shared between multiple image objects (with reference counting), and a subimage may share data with its parent and multiple siblings. ImageAllocs may also share pixel values with NumPy arrays when the allocation happens in the C++ layer.
An ImageAlloc also contains a bounding box; its origin need not be (0,0) or (1,1).
The const semantics for this are pretty normal. You cannot change either the pixel values or the ancillary information (like bounds) for a const ImageAlloc, while you can change things about a non-const ImageAlloc.
ImageAlloc templates for uint16_t, uint32_t, int16_t, int32_t, float, and double are explicitly instantiated in Image.cpp.
Public Functions
-
inline ImageAlloc()
Default constructor leaves the image’s data pointer as null.
-
ImageAlloc(int ncol, int nrow)
Create a new image with origin at (1,1).
An exception is thrown if ncol or nrow <= 0
-
ImageAlloc(int ncol, int nrow, T init_value)
Create a new image with origin at (1,1), intialized with some init_value.
An exception is thrown if ncol or nrow <= 0
-
ImageAlloc(const Bounds<int> &bounds, T init_value)
Create a new image with the given bounding box and initial value.
-
inline ImageAlloc(const ImageAlloc<T> &rhs)
Deep copy constructor.
-
inline ImageAlloc(const AssignableToImage<T> &rhs)
Can construct from any AssignableToImage.
-
template<typename U>
inline ImageAlloc(const BaseImage<U> &rhs) If rhs is a BaseImage, then type doesn’t have to match.
-
inline ImageAlloc<T> &operator=(const AssignableToImage<T> &rhs)
Deep assignment operator.
The bounds must be commensurate (i.e. the same shape). If not, an exception will be thrown.
-
inline ImageAlloc<T> &operator=(const ImageAlloc<T> &rhs)
Repeat for ImageAlloc to prevent compiler from making the default op=.
-
template<typename U>
inline ImageAlloc<T> &operator=(const BaseImage<U> &rhs) Copy from BaseImage allowed for different types.
-
inline ImageAlloc<T> &operator=(T x)
-
inline void setZero()
-
inline void invertSelf()
Set each element to its inverse: im(i,j) = 1/im(i,j)
Note that if an element is zero, then this function quietly returns its inverse as zero.
-
void resize(const Bounds<int> &new_bounds, bool release = true)
Resize the image to a new bounds. The values are left uninitialized.
Any views that share data with this ImageAlloc are still valid and still share data with each other, but the tie to this ImageAlloc is severed.
This typically allocates new memory for the array. The only exception is if the new size is the same as the current size and are there are no other views of the data. Then it just updates the bounds to the new bounds and keeps the current array.
You can also optionally keep the current array if you are shrinking the bounds to a smaller size, with the same limit of there not being other views. To get this behavior, set release=false, and it will not release the allocated memory when shrinking the size of the image.
-
inline ConstImageView<T> view() const
-
inline ImageView<T> subImage(const Bounds<int> &bounds)
New image that is a subimage of this (shares pixels)
-
inline ConstImageView<T> subImage(const Bounds<int> &bounds) const
-
inline ImageView<T> operator[](const Bounds<int> &bounds)
im[bounds] is another syntax for making a sub-image
-
inline ConstImageView<T> operator[](const Bounds<int> &bounds) const
-
inline void setValue(int x, int y, T value)
Another way to set a value. Equivalent to im(x,y) = value.
The python layer can’t implement the im(x,y) = value syntax, so we need something else to set a single pixel. This function is unnecessary at the C++ level, but in the interest of trying to keep the two layers as close as possible, we might as well include it.
Note: This uses the checked element access.
-
inline ImageAlloc()
-
template<typename T>
class ImageView : public galsim::BaseImage<T> ImageView class is a mutable view of an Image.
The copy constructor is shallow, so ImageView’s can be cheaply returned by value. The data values persist until the last view of some data goes out of scope.
The op= is deep, though. This is the intuitive behavior, so you can write something like
im1[bounds] = im2
and the data in im2 will be copied to the sub-image of im1.
Also note that through the python interface, we can make an ImageView that views a numpy array rather than anything that was created as an ImageAlloc. We have some tricky stuff in pysrc/Image.cpp to get the C++ shared_ptr to interact correctly with numpy’s reference counting so the data are deleted when the last numpy array or ImageView finally goes out of scope.
You could do the same thing within the C++ layer too. You would just have to provide a shared_ptr explicitly to set up the ownership.
Public Functions
Direct constructor given all the necessary information.
-
inline ImageView(const ImageView<T> &rhs)
Shallow copy constructor.
The original image and its copy will share pixel values, but their bounding boxes will not be shared (even though they will be set to the same values initially).
-
inline ImageView(ImageAlloc<T> &rhs)
Shallow copy constructor from ImageAlloc.
The original image and its copy will share pixel values, but their bounding boxes will not be shared (even though they will be set to the same values initially).
-
inline ImageView<T> &operator=(const AssignableToImage<T> &rhs)
Deep assignment operator.
The bounds must be commensurate (i.e. the same shape). If not, an exception will be thrown.
-
inline ImageView<T> &operator=(const ImageView<T> &rhs)
Repeat for ImageView to prevent compiler from making the default op=.
-
template<typename U>
inline ImageView<T> &operator=(const BaseImage<U> &rhs) Allow copy from a different type.
-
inline void setZero()
-
void invertSelf()
Set each element to its inverse: im(i,j) = 1/im(i,j)
Note that if an element is zero, then this function quietly returns its inverse as zero.
-
void depixelizeSelf(const double *unit_integrals, const int n)
Make a depixelized version of the image.
-
inline T *getData()
Return a pointer to the first pixel in the image.
This overrides the version in BaseImage, since this one returns a non-const pointer. (T*, not const T*)
-
ImageView<T> subImage(const Bounds<int> &bounds)
New image that is a subimage of this (shares pixels)
-
inline ImageView<T> operator[](const Bounds<int> &bounds)
im[bounds] is another syntax for making a sub-image
-
inline void setValue(int x, int y, T value)
Another way to set a value. Equivalent to im(x,y) = value.
The python layer can’t implement the im(x,y) = value syntax, so we need something else to set a single pixel. This function is unnecessary at the C++ level, but in the interest of trying to keep the two layers as close as possible, we might as well include it.
Note: This uses the checked element access.
-
template<typename T>
class ConstImageView : public galsim::BaseImage<T> ConstImageView class views an Image in a read-only context.
Read-only only refers to the data values. The bounds may be changed.
Public Functions
Direct constructor given all the necessary information.
-
inline ConstImageView(const BaseImage<T> &rhs)
Copy Constructor from a BaseImage makes a new view of the same data.
-
inline ConstImageView(const ConstImageView<T> &rhs)
Repeat the same copy constructor functionality for ConstImageView to make sure the compiler doesn’t make the default one.
-
inline ConstImageView<T> view() const
View just returns itself.