LSSTApplications
20.0.0
LSSTDataManagementBasePackage
|
Go to the documentation of this file.
31 #include <type_traits>
32 #include "boost/mpl/vector.hpp"
33 #pragma clang diagnostic push
34 #pragma clang diagnostic ignored "-Wunused-variable"
35 #pragma clang diagnostic pop
36 #include "boost/format.hpp"
37 #include "boost/filesystem/path.hpp"
39 #include "boost/version.hpp"
40 #if BOOST_VERSION < 106900
41 #include "boost/gil/gil_all.hpp"
43 #include "boost/gil.hpp"
57 template <
typename PixelT>
59 Manager::Ptr& manager) {
62 str(
boost::format(
"Both width and height must be non-negative: %d, %d") %
67 str(
boost::format(
"Image dimensions (%d x %d) too large; int overflow detected.") %
74 (
typename _view_t::value_type*)r.second,
77 template <
typename PixelT>
80 const _view_t& view) {
81 if (offset.getX() < 0 || offset.getY() < 0 || offset.getX() +
dimensions.getX() > view.width() ||
82 offset.getY() +
dimensions.getY() > view.height()) {
86 "Box2I(Point2I(%d,%d),lsst::geom::Extent2I(%d,%d)) doesn't fit in image %dx%d") %
91 return boost::gil::subimage_view(view, offset.getX(), offset.getY(),
dimensions.getX(),
95 template <
typename PixelT>
97 : _origin(0, 0), _manager(), _gilView(_allocateView(
dimensions, _manager)) {}
99 template <
typename PixelT>
101 : _origin(
bbox.getMin()), _manager(), _gilView(_allocateView(
bbox.getDimensions(), _manager)) {}
103 template <
typename PixelT>
107 : _origin(rhs._origin), _manager(rhs._manager), _gilView(rhs._gilView) {
115 template <
typename PixelT>
118 template <
typename PixelT>
124 _manager(rhs._manager),
125 _gilView(_makeSubView(
bbox.getDimensions(), _origin - rhs._origin, rhs._gilView)) {
133 template <
typename PixelT>
136 _manager(array.getManager()),
137 _gilView(
boost::gil::interleaved_view(array.template
getSize<1>(), array.template
getSize<0>(),
138 (typename _view_t::value_type*)array.getData(),
139 array.template getStride<0>() * sizeof(
PixelT))) {
146 template <
typename PixelT>
154 template <
typename PixelT>
159 template <
typename PixelT>
165 template <
typename PixelT>
167 auto lhsDim =
bbox.isEmpty() ? getDimensions() :
bbox.getDimensions();
170 (
boost::format(
"Dimension mismatch: %dx%d v. %dx%d") % lhsDim.getX() %
174 if (
bbox.isEmpty()) {
175 copy_pixels(rhs._gilView, _gilView);
178 auto lhsGilView = _makeSubView(lhsDim, lhsOff, _gilView);
179 copy_pixels(rhs._gilView, lhsGilView);
183 template <
typename PixelT>
189 template <
typename PixelT>
192 if (check && (x < 0 || x >= getWidth() || y < 0 || y >= getHeight())) {
194 (
boost::format(
"Index (%d, %d) is out of range [0--%d], [0--%d]") %
x %
y %
195 (getWidth() - 1) % (getHeight() - 1))
203 template <
typename PixelT>
205 return _gilView(
x,
y)[0];
208 template <
typename PixelT>
211 if (check && (x < 0 || x >= getWidth() || y < 0 || y >= getHeight())) {
213 (
boost::format(
"Index (%d, %d) is out of range [0--%d], [0--%d]") %
x %
y %
214 (this->getWidth() - 1) % (this->getHeight() - 1))
218 return _gilView(
x,
y)[0];
221 template <
typename PixelT>
224 int x = index.getX();
225 int y = index.getY();
230 return _gilView(
x,
y)[0];
233 template <
typename PixelT>
236 int x = index.getX();
237 int y = index.getY();
242 return _gilView(
x,
y)[0];
245 template <
typename PixelT>
249 swap(_manager, rhs._manager);
250 swap(_gilView, rhs._gilView);
254 template <
typename PixelT>
262 template <
typename PixelT>
264 return _gilView.begin();
267 template <
typename PixelT>
269 return _gilView.end();
272 template <
typename PixelT>
274 return _gilView.rbegin();
277 template <
typename PixelT>
279 return _gilView.rend();
282 template <
typename PixelT>
284 return _gilView.at(
x,
y);
287 template <
typename PixelT>
292 if (!this->isContiguous()) {
299 template <
typename PixelT>
304 if (!this->isContiguous()) {
308 return row_end(getHeight() - 1);
311 template <
typename PixelT>
313 fill_pixels(_gilView, rhs);
321 template <
typename PixelT>
324 *
this = initialValue;
327 template <
typename PixelT>
330 *
this = initialValue;
333 template <
typename PixelT>
335 *
this = initialValue;
338 template <
typename PixelT>
341 template <
typename PixelT>
344 template <
typename PixelT>
349 template <
typename PixelT>
356 template <
typename PixelT>
363 template <
typename PixelT>
368 #ifndef DOXYGEN // doc for this section has been moved to header
370 template <
typename PixelT>
374 *
this = reader.read<
PixelT>(
bbox, origin, allowUnsafe);
376 metadata->combine(reader.readMetadata());
380 template <
typename PixelT>
391 template <
typename PixelT>
394 ImageFitsReader reader(&fitsFile);
397 metadata->combine(reader.readMetadata());
401 template <
typename PixelT>
406 writeFits(fitsfile, metadata_i);
409 template <
typename PixelT>
414 writeFits(fitsfile, metadata_i);
417 template <
typename PixelT>
423 template <
typename PixelT>
428 writeFits(fitsfile, options, header,
mask);
431 template <
typename PixelT>
436 writeFits(fitsfile, options, header,
mask);
439 template <
typename PixelT>
448 template <
typename PixelT>
455 template <
typename PixelT>
461 template <
typename PixelT>
463 transform_pixels(_getRawView(), _getRawView(),
467 template <
typename PixelT>
469 transform_pixels(_getRawView(), _getRawView(), [&rhs](
PixelT const& l) ->
PixelT {
return l + rhs; });
473 template <
typename PixelT>
477 (
boost::format(
"Images are of different size, %dx%d v %dx%d") % this->getWidth() %
481 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
486 template <
typename PixelT>
488 for (
int y = 0;
y != this->getHeight(); ++
y) {
493 *
ptr +=
function(xPos, yPos);
499 template <
typename PixelT>
503 (
boost::format(
"Images are of different size, %dx%d v %dx%d") % this->getWidth() %
512 template <
typename PixelT>
514 transform_pixels(_getRawView(), _getRawView(), [&rhs](
PixelT const& l) ->
PixelT {
return l - rhs; });
518 template <
typename PixelT>
522 (
boost::format(
"Images are of different size, %dx%d v %dx%d") % this->getWidth() %
526 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
531 template <
typename PixelT>
535 (
boost::format(
"Images are of different size, %dx%d v %dx%d") % this->getWidth() %
544 template <
typename PixelT>
546 for (
int y = 0;
y != this->getHeight(); ++
y) {
551 *
ptr -=
function(xPos, yPos);
557 template <
typename PixelT>
559 transform_pixels(_getRawView(), _getRawView(), [&rhs](
PixelT const& l) ->
PixelT {
return l * rhs; });
563 template <
typename PixelT>
567 (
boost::format(
"Images are of different size, %dx%d v %dx%d") % this->getWidth() %
571 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
576 template <
typename PixelT>
580 (
boost::format(
"Images are of different size, %dx%d v %dx%d") % this->getWidth() %
589 template <
typename PixelT>
591 transform_pixels(_getRawView(), _getRawView(), [&rhs](
PixelT const& l) ->
PixelT {
return l / rhs; });
599 double const irhs = 1 / rhs;
606 float const irhs = 1 / rhs;
611 template <
typename PixelT>
615 (
boost::format(
"Images are of different size, %dx%d v %dx%d") % this->getWidth() %
619 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
624 template <
typename PixelT>
628 (
boost::format(
"Images are of different size, %dx%d v %dx%d") % this->getWidth() %
641 template <
typename LhsPixelT,
typename RhsPixelT>
642 struct plusEq :
public pixelOp2<LhsPixelT, RhsPixelT> {
643 LhsPixelT
operator()(LhsPixelT lhs, RhsPixelT rhs)
const override {
644 return static_cast<LhsPixelT
>(lhs + rhs);
648 template <
typename LhsPixelT,
typename RhsPixelT>
649 struct minusEq :
public pixelOp2<LhsPixelT, RhsPixelT> {
650 LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs)
const override {
651 return static_cast<LhsPixelT
>(lhs - rhs);
655 template <
typename LhsPixelT,
typename RhsPixelT>
656 struct timesEq :
public pixelOp2<LhsPixelT, RhsPixelT> {
657 LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs)
const override {
658 return static_cast<LhsPixelT
>(lhs * rhs);
662 template <
typename LhsPixelT,
typename RhsPixelT>
663 struct divideEq :
public pixelOp2<LhsPixelT, RhsPixelT> {
664 LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs)
const override {
665 return static_cast<LhsPixelT
>(lhs / rhs);
670 template <
typename LhsPixelT,
typename RhsPixelT>
676 template <
typename LhsPixelT,
typename RhsPixelT>
682 template <
typename LhsPixelT,
typename RhsPixelT>
688 template <
typename LhsPixelT,
typename RhsPixelT>
696 if (metadata.
exists(
"ZNAXIS1") && metadata.
exists(
"ZNAXIS2")) {
705 template <
typename T1,
typename T2>
710 auto beg1Addr = arr1.front().begin();
711 auto end1Addr = arr1.back().end();
714 auto beg2Addr = arr2.front().begin();
715 auto end2Addr = arr2.back().end();
718 return ptrLess(beg1Addr, end2Addr) && ptrLess(beg2Addr, end1Addr);
725 #define INSTANTIATE_OPERATOR(OP_EQ, T) \
726 template Image<T>& operator OP_EQ(Image<T>& lhs, Image<std::uint16_t> const& rhs); \
727 template Image<T>& operator OP_EQ(Image<T>& lhs, Image<int> const& rhs); \
728 template Image<T>& operator OP_EQ(Image<T>& lhs, Image<float> const& rhs); \
729 template Image<T>& operator OP_EQ(Image<T>& lhs, Image<double> const& rhs); \
730 template Image<T>& operator OP_EQ(Image<T>& lhs, Image<std::uint64_t> const& rhs);
732 #define INSTANTIATE(T) \
733 template class ImageBase<T>; \
734 template class Image<T>; \
735 INSTANTIATE_OPERATOR(+=, T); \
736 INSTANTIATE_OPERATOR(-=, T); \
737 INSTANTIATE_OPERATOR(*=, T); \
738 INSTANTIATE_OPERATOR(/=, T)
740 #define INSTANTIATE2(T1, T2) template bool imagesOverlap<T1, T2>(ImageBase<T1> const&, ImageBase<T2> const&);
void writeFits(std::string const &fileName, std::shared_ptr< lsst::daf::base::PropertySet const > metadata=std::shared_ptr< lsst::daf::base::PropertySet const >(), std::string const &mode="w") const
Write an image to a regular FITS file.
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
static _view_t _allocateView(lsst::geom::Extent2I const &dimensions, Manager::Ptr &manager)
int getAsInt(std::string const &name) const
Get the last value for a bool/char/short/int property name (possibly hierarchical).
ndarray::Array< PixelT, 2, 1 > Array
A mutable ndarray representation of the image.
void assign(ImageBase const &rhs, lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT)
Copy pixels from another image to a specified subregion of this image.
Image< PixelT > read(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT, bool allowUnsafe=false)
Read the Image.
Image & operator*=(PixelT const rhs)
Multiply lhs by scalar rhs.
Represent a 2-dimensional array of bitmask pixels.
reverse_iterator rbegin() const
Return an STL compliant reverse iterator to the start of the image.
void scaledMultiplies(double const c, Image< PixelT > const &rhs)
Multiply lhs by Image c*rhs (i.e. pixel-by-pixel multiplication)
A simple struct that combines the two arguments that must be passed to most cfitsio routines and cont...
reverse_iterator rend() const
Return an STL compliant reverse iterator to the end of the image.
iterator at(int x, int y) const
Return an STL compliant iterator at the point (x, y)
iterator end() const
Return an STL compliant iterator to the end of the image.
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
_view_t::reverse_iterator reverse_iterator
An STL compliant reverse iterator.
_view_t _getRawView() const
bool exists(std::string const &name) const
Determine if a name (possibly hierarchical) exists.
Image & operator/=(PixelT const rhs)
Divide lhs by scalar rhs.
double indexToPosition(double ind)
Convert image index to image position.
ImageBase & operator=(const ImageBase &rhs)
Shallow assignment operator.
Image & operator+=(PixelT const rhs)
Add scalar rhs to lhs.
#define INSTANTIATE(FROMSYS, TOSYS)
Lifetime-management for memory that goes into FITS memory files.
int getHeight() const
Return the number of rows in the image.
A FITS reader class for regular Images.
Options for writing an image to FITS.
PixelReference operator()(int x, int y)
Return a reference to the pixel (x, y) in LOCAL coordinates.
void scaledPlus(double const c, Image< PixelT > const &rhs)
Add Image c*rhs to lhs.
Image< LhsPixelT > & operator*=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Multiply lhs by Image rhs (i.e. pixel-by-pixel multiplication) where types are different.
void scaledMinus(double const c, Image< PixelT > const &rhs)
Subtract Image c*rhs from lhs.
iterator begin() const
Return an STL compliant iterator to the start of the image.
Reference< PixelT >::type PixelReference
A Reference to a PixelT.
Reports attempts to exceed implementation-defined length limits for some classes.
static _view_t _makeSubView(lsst::geom::Extent2I const &dimensions, lsst::geom::Extent2I const &offset, const _view_t &view)
afw::table::PointKey< int > dimensions
ImageBase & operator<<=(const ImageBase &rhs)
Set the lhs's pixel values to equal the rhs's.
A class used to request that array accesses be checked.
Image & operator=(const PixelT rhs)
Set the image's pixels to rhs.
Image< LhsPixelT > & operator-=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Subtract lhs from Image rhs (i.e. pixel-by-pixel subtraction) where types are different.
_view_t::x_iterator x_iterator
An iterator for traversing the pixels in a row.
A base class for image defects.
std::string const wcsNameForXY0
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
void for_each_pixel(Image< LhsT > &lhs, pixelOp0< LhsT > const &func)
Set each pixel in an Image<LhsT> to func()
lsst::geom::Box2I bboxFromMetadata(daf::base::PropertySet &metadata)
Determine the image bounding box from its metadata (FITS header)
virtual LhsT operator()(LhsT lhs, RhsT rhs) const =0
lsst::geom::Extent2I getDimensions() const
Return the image's size; useful for passing to constructors.
x_iterator fast_iterator
A fast STL compliant iterator for contiguous images N.b.
std::shared_ptr< daf::base::PropertyList > readMetadata()
Read the image's FITS header.
Extent< int, 2 > Extent2I
Image< LhsPixelT > & operator/=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Divide lhs by Image rhs (i.e. pixel-by-pixel division) where types are different.
_view_t::iterator iterator
An STL compliant iterator.
A functor class equivalent to std::function<LhsT (LhsT, RhsT)>, but with a virtual operator()
Class for storing generic metadata.
An integer coordinate rectangle.
lsst::geom::Point2I getImageXY0FromMetadata(daf::base::PropertySet &metadata, std::string const &wcsName, bool strip=false)
void swap(Image< PixelT > &a, Image< PixelT > &b)
#define INSTANTIATE2(ImagePixelT1, ImagePixelT2)
Image< LhsPixelT > & operator+=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Add lhs to Image rhs (i.e. pixel-by-pixel addition) where types are different.
bool imagesOverlap(ImageBase< T1 > const &image1, ImageBase< T2 > const &image2)
Return true if the pixels for two images or masks overlap in memory.
lsst::geom::Box2I getBBox(ImageOrigin origin=PARENT) const
A class to represent a 2-dimensional array of pixels.
void swap(ImageBase &rhs)
Image & operator-=(PixelT const rhs)
Subtract scalar rhs from lhs.
ConstReference< PixelT >::type PixelConstReference
A ConstReference to a PixelT.
The base class for all image classed (Image, Mask, MaskedImage, ...)
PixelReference get(lsst::geom::Point2I const &index, ImageOrigin origin)
Return a reference to a single pixel (with no bounds check).
int getWidth() const
Return the number of columns in the image.
Reports errors that are due to events beyond the control of the program.
void writeImage(ndarray::Array< T const, N, C > const &array)
Write an ndarray::Array to a FITS image HDU.