lsst.afw g28e9080985+60ce4897b0
Image.cc
Go to the documentation of this file.
1// -*- lsst-c++ -*-
2
3/*
4 * LSST Data Management System
5 * Copyright 2008-2016 AURA/LSST.
6 *
7 * This product includes software developed by the
8 * LSST Project (http://www.lsst.org/).
9 *
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the LSST License Statement and
21 * the GNU General Public License along with this program. If not,
22 * see <http://www.lsstcorp.org/LegalNotices/>.
23 */
24
25/*
26 * Implementation for ImageBase and Image
27 */
28#include <cstdint>
29#include <iostream>
30#include <functional>
31#include "boost/format.hpp"
32#include "boost/gil.hpp"
33
34#include "lsst/pex/exceptions.h"
38#include "lsst/afw/fits.h"
40
41namespace lsst {
42namespace afw {
43namespace image {
44
45template <typename PixelT>
46typename ImageBase<PixelT>::_view_t ImageBase<PixelT>::_allocateView(lsst::geom::Extent2I const& dimensions,
47 Manager::Ptr& manager) {
48 if (dimensions.getX() < 0 || dimensions.getY() < 0) {
50 str(boost::format("Both width and height must be non-negative: %d, %d") %
51 dimensions.getX() % dimensions.getY()));
52 }
53 if (dimensions.getX() != 0 && dimensions.getY() > std::numeric_limits<int>::max() / dimensions.getX()) {
55 str(boost::format("Image dimensions (%d x %d) too large; int overflow detected.") %
56 dimensions.getX() % dimensions.getY()));
57 }
59 ndarray::SimpleManager<PixelT>::allocate(dimensions.getX() * dimensions.getY());
60 manager = r.first;
61 return boost::gil::interleaved_view(dimensions.getX(), dimensions.getY(),
62 (typename _view_t::value_type*)r.second,
63 dimensions.getX() * sizeof(PixelT));
64}
65template <typename PixelT>
66typename ImageBase<PixelT>::_view_t ImageBase<PixelT>::_makeSubView(lsst::geom::Extent2I const& dimensions,
67 lsst::geom::Extent2I const& offset,
68 const _view_t& view) {
69 if (offset.getX() < 0 || offset.getY() < 0 || offset.getX() + dimensions.getX() > view.width() ||
70 offset.getY() + dimensions.getY() > view.height()) {
71 throw LSST_EXCEPT(
73 (boost::format(
74 "Box2I(Point2I(%d,%d),lsst::geom::Extent2I(%d,%d)) doesn't fit in image %dx%d") %
75 offset.getX() % offset.getY() % dimensions.getX() % dimensions.getY() % view.width() %
76 view.height())
77 .str());
78 }
79 if (dimensions.getX() == 0 && dimensions.getY() == 0
80 && view.width() == 0 && view.height() == 0) {
81 // Getting a zero-extent subview of a zero-extent view returns itself
82 return view;
83 } else {
84 return boost::gil::subimage_view(view, offset.getX(), offset.getY(), dimensions.getX(),
85 dimensions.getY());
86 }
88
89template <typename PixelT>
91 : _origin(0, 0), _manager(), _gilView(_allocateView(dimensions, _manager)) {}
92
93template <typename PixelT>
95 : _origin(bbox.getMin()), _manager(), _gilView(_allocateView(bbox.getDimensions(), _manager)) {}
96
97template <typename PixelT>
98ImageBase<PixelT>::ImageBase(ImageBase const& rhs, bool const deep
99
100 )
101 : _origin(rhs._origin), _manager(rhs._manager), _gilView(rhs._gilView) {
102 if (deep) {
103 ImageBase tmp(getBBox());
104 tmp.assign(*this); // now copy the pixels
105 swap(tmp);
106 }
107}
108// Delegate to copy-constructor for backwards compatibility
109template <typename PixelT>
111
112template <typename PixelT>
114 bool const deep
115
116 )
117 : _origin((origin == PARENT) ? bbox.getMin() : rhs._origin + lsst::geom::Extent2I(bbox.getMin())),
118 _manager(rhs._manager), // reference counted pointer, don't copy pixels
119 _gilView(_makeSubView(bbox.getDimensions(), _origin - rhs._origin, rhs._gilView)) {
120 if (deep) {
122 tmp.assign(*this); // now copy the pixels
123 swap(tmp);
124 }
125}
126
127template <typename PixelT>
128ImageBase<PixelT>::ImageBase(Array const& array, bool deep, lsst::geom::Point2I const& xy0)
129 : _origin(xy0),
130 _manager(array.getManager()),
131 _gilView(boost::gil::interleaved_view(array.template getSize<1>(), array.template getSize<0>(),
132 (typename _view_t::value_type*)array.getData(),
133 array.template getStride<0>() * sizeof(PixelT))) {
134 if (deep) {
135 ImageBase tmp(*this, true);
136 swap(tmp);
137 }
138}
139
140template <typename PixelT>
142 ImageBase tmp(rhs);
143 swap(tmp); // See Meyers, Effective C++, Item 11
144
145 return *this;
146}
147// Delegate to copy-assignment for backwards compatibility
148template <typename PixelT>
150 return *this = rhs;
151}
152
153template <typename PixelT>
155 auto lhsDim = bbox.isEmpty() ? getDimensions() : bbox.getDimensions();
156 if (lhsDim != rhs.getDimensions()) {
158 (boost::format("Dimension mismatch: %dx%d v. %dx%d") % lhsDim.getX() %
159 lhsDim.getY() % rhs.getWidth() % rhs.getHeight())
160 .str());
161 }
162 if (bbox.isEmpty()) {
163 copy_pixels(rhs._gilView, _gilView);
164 } else {
165 auto lhsOff = (origin == PARENT) ? bbox.getMin() - _origin : lsst::geom::Extent2I(bbox.getMin());
166 auto lhsGilView = _makeSubView(lhsDim, lhsOff, _gilView);
167 copy_pixels(rhs._gilView, lhsGilView);
168 }
169}
170
171template <typename PixelT>
173 return const_cast<typename ImageBase<PixelT>::PixelReference>(
174 static_cast<typename ImageBase<PixelT>::PixelConstReference>(_gilView(x, y)[0]));
176
177template <typename PixelT>
179 CheckIndices const& check) {
180 if (check && (x < 0 || x >= getWidth() || y < 0 || y >= getHeight())) {
182 (boost::format("Index (%d, %d) is out of range [0--%d], [0--%d]") % x % y %
183 (getWidth() - 1) % (getHeight() - 1))
184 .str());
185 }
186
187 return const_cast<typename ImageBase<PixelT>::PixelReference>(
188 static_cast<typename ImageBase<PixelT>::PixelConstReference>(_gilView(x, y)[0]));
189}
190
191template <typename PixelT>
193 return _gilView(x, y)[0];
194}
195
196template <typename PixelT>
198 int x, int y, CheckIndices const& check) const {
199 if (check && (x < 0 || x >= getWidth() || y < 0 || y >= getHeight())) {
201 (boost::format("Index (%d, %d) is out of range [0--%d], [0--%d]") % x % y %
202 (this->getWidth() - 1) % (this->getHeight() - 1))
203 .str());
205
206 return _gilView(x, y)[0];
207}
209template <typename PixelT>
211 ImageOrigin origin) {
212 int x = index.getX();
213 int y = index.getY();
214 if (origin == PARENT) {
215 x -= getX0();
216 y -= getY0();
217 }
218 return _gilView(x, y)[0];
219}
220
221template <typename PixelT>
223 ImageOrigin origin) const {
224 int x = index.getX();
225 int y = index.getY();
226 if (origin == PARENT) {
227 x -= getX0();
228 y -= getY0();
229 }
230 return _gilView(x, y)[0];
231}
232
233template <typename PixelT>
235 using std::swap; // See Meyers, Effective C++, Item 25
236
237 swap(_manager, rhs._manager); // just swapping the pointers
238 swap(_gilView, rhs._gilView);
239 swap(_origin, rhs._origin);
240}
241
242template <typename PixelT>
244 a.swap(b);
245}
246
247//
248// Iterators
249//
250template <typename PixelT>
252 return _gilView.begin();
253}
255template <typename PixelT>
257 return _gilView.end();
258}
259
260template <typename PixelT>
262 return _gilView.rbegin();
263}
264
265template <typename PixelT>
267 return _gilView.rend();
268}
269
270template <typename PixelT>
272 return _gilView.at(x, y);
274
275template <typename PixelT>
277 if (!contiguous) {
278 throw LSST_EXCEPT(pex::exceptions::RuntimeError, "Only contiguous == true makes sense");
280 if (!this->isContiguous()) {
281 throw LSST_EXCEPT(pex::exceptions::RuntimeError, "Image's pixels are not contiguous");
283
284 return row_begin(0);
286
287template <typename PixelT>
289 if (!contiguous) {
290 throw LSST_EXCEPT(pex::exceptions::RuntimeError, "Only contiguous == true makes sense");
291 }
292 if (!this->isContiguous()) {
293 throw LSST_EXCEPT(pex::exceptions::RuntimeError, "Image's pixels are not contiguous");
294 }
295
296 return row_end(getHeight() - 1);
297}
298
299template <typename PixelT>
301 fill_pixels(_gilView, rhs);
302
303 return *this;
304}
305
306//
307// On to Image itself. ctors, cctors, and operator=
308//
309template <typename PixelT>
310Image<PixelT>::Image(unsigned int width, unsigned int height, PixelT initialValue)
311 : ImageBase<PixelT>(lsst::geom::ExtentI(width, height)) {
312 *this = initialValue;
313}
314
315template <typename PixelT>
317 : ImageBase<PixelT>(dimensions) {
318 *this = initialValue;
319}
320
321template <typename PixelT>
322Image<PixelT>::Image(lsst::geom::Box2I const& bbox, PixelT initialValue) : ImageBase<PixelT>(bbox) {
323 *this = initialValue;
324}
326template <typename PixelT>
327Image<PixelT>::Image(Image const& rhs, bool const deep) : ImageBase<PixelT>(rhs, deep) {}
328// Delegate to copy-constructor for backwards compatibility
329template <typename PixelT>
330Image<PixelT>::Image(Image&& rhs) : Image(rhs, false) {}
331
332template <typename PixelT>
334 bool const deep)
335 : ImageBase<PixelT>(rhs, bbox, origin, deep) {}
336
337template <typename PixelT>
341 return *this;
343
344template <typename PixelT>
347
348 return *this;
349}
350// Delegate to copy-assignment for backwards compatibility
351template <typename PixelT>
353 return *this = rhs;
355
356#ifndef DOXYGEN // doc for this section has been moved to header
357
358template <typename PixelT>
360 lsst::geom::Box2I const& bbox, ImageOrigin origin, bool allowUnsafe) {
361 ImageFitsReader reader(fileName, hdu);
362 *this = reader.read<PixelT>(bbox, origin, allowUnsafe);
363 if (metadata) {
364 metadata->combine(reader.readMetadata());
365 }
367
368template <typename PixelT>
369Image<PixelT>::Image(fits::MemFileManager& manager, int const hdu,
371 ImageOrigin const origin, bool allowUnsafe) {
372 ImageFitsReader reader(manager, hdu);
373 *this = reader.read<PixelT>(bbox, origin, allowUnsafe);
374 if (metadata) {
375 metadata->combine(reader.readMetadata());
377}
379template <typename PixelT>
381 lsst::geom::Box2I const& bbox, ImageOrigin const origin, bool allowUnsafe) {
382 ImageFitsReader reader(&fitsFile);
383 *this = reader.read<PixelT>(bbox, origin, allowUnsafe);
384 if (metadata) {
385 metadata->combine(reader.readMetadata());
386 }
388
389template <typename PixelT>
390void Image<PixelT>::writeFits(std::string const& fileName,
392 std::string const& mode) const {
393 fits::Fits fitsfile(fileName, mode, fits::Fits::AUTO_CLOSE | fits::Fits::AUTO_CHECK);
394 writeFits(fitsfile, metadata_i);
396
397template <typename PixelT>
400 std::string const& mode) const {
402 writeFits(fitsfile, metadata_i);
403}
404
405template <typename PixelT>
408 fitsfile.writeImage(*this, fits::ImageWriteOptions(*this), metadata);
409}
410
411template <typename PixelT>
412void Image<PixelT>::writeFits(std::string const& filename, fits::ImageWriteOptions const& options,
414 std::shared_ptr<Mask<MaskPixel> const> mask) const {
415 fits::Fits fitsfile(filename, mode, fits::Fits::AUTO_CLOSE | fits::Fits::AUTO_CHECK);
416 writeFits(fitsfile, options, header, mask);
417}
418
419template <typename PixelT>
420void Image<PixelT>::writeFits(fits::MemFileManager& manager, fits::ImageWriteOptions const& options,
422 std::shared_ptr<Mask<MaskPixel> const> mask) const {
423 fits::Fits fitsfile(manager, mode, fits::Fits::AUTO_CLOSE | fits::Fits::AUTO_CHECK);
424 writeFits(fitsfile, options, header, mask);
425}
426
427template <typename PixelT>
428void Image<PixelT>::writeFits(fits::Fits& fitsfile, fits::ImageWriteOptions const& options,
430 std::shared_ptr<Mask<MaskPixel> const> mask) const {
431 fitsfile.writeImage(*this, options, header, mask);
432}
433
434#endif // !DOXYGEN
435
436template <typename PixelT>
438 using std::swap; // See Meyers, Effective C++, Item 25
440 ; // no private variables to swap
441}
442
443template <typename PixelT>
445 a.swap(b);
446}
447
448// In-place, per-pixel, sqrt().
449template <typename PixelT>
451 transform_pixels(_getRawView(), _getRawView(),
452 [](PixelT const& l) -> PixelT { return static_cast<PixelT>(std::sqrt(l)); });
453}
454
455template <typename PixelT>
457 transform_pixels(_getRawView(), _getRawView(), [&rhs](PixelT const& l) -> PixelT { return l + rhs; });
458 return *this;
459}
460
461template <typename PixelT>
463 if (this->getDimensions() != rhs.getDimensions()) {
465 (boost::format("Images are of different size, %dx%d v %dx%d") % this->getWidth() %
466 this->getHeight() % rhs.getWidth() % rhs.getHeight())
467 .str());
468 }
469 transform_pixels(_getRawView(), rhs._getRawView(), _getRawView(),
470 [](PixelT const& l, PixelT const& r) -> PixelT { return l + r; });
471 return *this;
472}
473
474template <typename PixelT>
476 for (int y = 0; y != this->getHeight(); ++y) {
477 double const yPos = this->indexToPosition(y, Y);
478 double xPos = this->indexToPosition(0, X);
479 for (typename Image<PixelT>::x_iterator ptr = this->row_begin(y), end = this->row_end(y); ptr != end;
480 ++ptr, ++xPos) {
481 *ptr += function(xPos, yPos);
482 }
483 }
484 return *this;
485}
486
487template <typename PixelT>
488void Image<PixelT>::scaledPlus(double const c, Image<PixelT> const& rhs) {
489 if (this->getDimensions() != rhs.getDimensions()) {
491 (boost::format("Images are of different size, %dx%d v %dx%d") % this->getWidth() %
492 this->getHeight() % rhs.getWidth() % rhs.getHeight())
493 .str());
494 }
495 transform_pixels(
496 _getRawView(), rhs._getRawView(), _getRawView(),
497 [&c](PixelT const& l, PixelT const& r) -> PixelT { return l + static_cast<PixelT>(c * r); });
498}
499
500template <typename PixelT>
502 transform_pixels(_getRawView(), _getRawView(), [&rhs](PixelT const& l) -> PixelT { return l - rhs; });
503 return *this;
504}
505
506template <typename PixelT>
508 if (this->getDimensions() != rhs.getDimensions()) {
510 (boost::format("Images are of different size, %dx%d v %dx%d") % this->getWidth() %
511 this->getHeight() % rhs.getWidth() % rhs.getHeight())
512 .str());
513 }
514 transform_pixels(_getRawView(), rhs._getRawView(), _getRawView(),
515 [](PixelT const& l, PixelT const& r) -> PixelT { return l - r; });
516 return *this;
517}
518
519template <typename PixelT>
520void Image<PixelT>::scaledMinus(double const c, Image<PixelT> const& rhs) {
521 if (this->getDimensions() != rhs.getDimensions()) {
523 (boost::format("Images are of different size, %dx%d v %dx%d") % this->getWidth() %
524 this->getHeight() % rhs.getWidth() % rhs.getHeight())
525 .str());
526 }
527 transform_pixels(
528 _getRawView(), rhs._getRawView(), _getRawView(),
529 [&c](PixelT const& l, PixelT const& r) -> PixelT { return l - static_cast<PixelT>(c * r); });
530}
531
532template <typename PixelT>
534 for (int y = 0; y != this->getHeight(); ++y) {
535 double const yPos = this->indexToPosition(y, Y);
536 double xPos = this->indexToPosition(0, X);
537 for (typename Image<PixelT>::x_iterator ptr = this->row_begin(y), end = this->row_end(y); ptr != end;
538 ++ptr, ++xPos) {
539 *ptr -= function(xPos, yPos);
540 }
541 }
542 return *this;
543}
544
545template <typename PixelT>
547 transform_pixels(_getRawView(), _getRawView(), [&rhs](PixelT const& l) -> PixelT { return l * rhs; });
548 return *this;
549}
550
551template <typename PixelT>
553 if (this->getDimensions() != rhs.getDimensions()) {
555 (boost::format("Images are of different size, %dx%d v %dx%d") % this->getWidth() %
556 this->getHeight() % rhs.getWidth() % rhs.getHeight())
557 .str());
558 }
559 transform_pixels(_getRawView(), rhs._getRawView(), _getRawView(),
560 [](PixelT const& l, PixelT const& r) -> PixelT { return l * r; });
561 return *this;
562}
563
564template <typename PixelT>
565void Image<PixelT>::scaledMultiplies(double const c, Image<PixelT> const& rhs) {
566 if (this->getDimensions() != rhs.getDimensions()) {
568 (boost::format("Images are of different size, %dx%d v %dx%d") % this->getWidth() %
569 this->getHeight() % rhs.getWidth() % rhs.getHeight())
570 .str());
571 }
572 transform_pixels(
573 _getRawView(), rhs._getRawView(), _getRawView(),
574 [&c](PixelT const& l, PixelT const& r) -> PixelT { return l * static_cast<PixelT>(c * r); });
575}
576
577template <typename PixelT>
579 transform_pixels(_getRawView(), _getRawView(), [&rhs](PixelT const& l) -> PixelT { return l / rhs; });
580 return *this;
581}
582//
583// Specialize float and double for efficiency
584//
585template <>
587 double const irhs = 1 / rhs;
588 *this *= irhs;
589 return *this;
590}
591
592template <>
594 float const irhs = 1 / rhs;
595 *this *= irhs;
596 return *this;
597}
598
599template <typename PixelT>
601 if (this->getDimensions() != rhs.getDimensions()) {
603 (boost::format("Images are of different size, %dx%d v %dx%d") % this->getWidth() %
604 this->getHeight() % rhs.getWidth() % rhs.getHeight())
605 .str());
606 }
607 transform_pixels(_getRawView(), rhs._getRawView(), _getRawView(),
608 [](PixelT const& l, PixelT const& r) -> PixelT { return l / r; });
609 return *this;
610}
611
612template <typename PixelT>
613void Image<PixelT>::scaledDivides(double const c, Image<PixelT> const& rhs) {
614 if (this->getDimensions() != rhs.getDimensions()) {
616 (boost::format("Images are of different size, %dx%d v %dx%d") % this->getWidth() %
617 this->getHeight() % rhs.getWidth() % rhs.getHeight())
618 .str());
619 }
620 transform_pixels(
621 _getRawView(), rhs._getRawView(), _getRawView(),
622 [&c](PixelT const& l, PixelT const& r) -> PixelT { return l / static_cast<PixelT>(c * r); });
623}
624
625namespace {
626/*
627 * Worker routine for manipulating images;
628 */
629template <typename LhsPixelT, typename RhsPixelT>
630struct plusEq : public pixelOp2<LhsPixelT, RhsPixelT> {
631 LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs) const override {
632 return static_cast<LhsPixelT>(lhs + rhs);
633 }
634};
635
636template <typename LhsPixelT, typename RhsPixelT>
637struct minusEq : public pixelOp2<LhsPixelT, RhsPixelT> {
638 LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs) const override {
639 return static_cast<LhsPixelT>(lhs - rhs);
640 }
641};
642
643template <typename LhsPixelT, typename RhsPixelT>
644struct timesEq : public pixelOp2<LhsPixelT, RhsPixelT> {
645 LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs) const override {
646 return static_cast<LhsPixelT>(lhs * rhs);
647 }
648};
649
650template <typename LhsPixelT, typename RhsPixelT>
651struct divideEq : public pixelOp2<LhsPixelT, RhsPixelT> {
652 LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs) const override {
653 return static_cast<LhsPixelT>(lhs / rhs);
654 }
655};
656} // namespace
657
658template <typename LhsPixelT, typename RhsPixelT>
660 for_each_pixel(lhs, rhs, plusEq<LhsPixelT, RhsPixelT>());
661 return lhs;
662}
663
664template <typename LhsPixelT, typename RhsPixelT>
666 for_each_pixel(lhs, rhs, minusEq<LhsPixelT, RhsPixelT>());
667 return lhs;
668}
669
670template <typename LhsPixelT, typename RhsPixelT>
672 for_each_pixel(lhs, rhs, timesEq<LhsPixelT, RhsPixelT>());
673 return lhs;
674}
675
676template <typename LhsPixelT, typename RhsPixelT>
678 for_each_pixel(lhs, rhs, divideEq<LhsPixelT, RhsPixelT>());
679 return lhs;
680}
681
684 if (metadata.exists("ZNAXIS1") && metadata.exists("ZNAXIS2")) {
685 dims = lsst::geom::Extent2I(metadata.getAsInt("ZNAXIS1"), metadata.getAsInt("ZNAXIS2"));
686 } else {
687 dims = lsst::geom::Extent2I(metadata.getAsInt("NAXIS1"), metadata.getAsInt("NAXIS2"));
688 }
690 return lsst::geom::Box2I(xy0, dims);
691}
692
693template <typename T1, typename T2>
694bool imagesOverlap(ImageBase<T1> const& image1, ImageBase<T2> const& image2) {
695
696 if (image1.getArea() == 0 || image2.getArea() == 0) {
697 // zero-area images cannot overlap.
698 return false;
699 }
700
701 auto arr1 = image1.getArray();
702 // get the address of the first and one-past-the-last element of arr1 using ndarray iterators;
703 // this works because the iterators for contiguous 1-d ndarray Arrays are just pointers
704 auto beg1Addr = arr1.front().begin();
705 auto end1Addr = arr1.back().end();
706
707 auto arr2 = image2.getArray();
708 auto beg2Addr = arr2.front().begin();
709 auto end2Addr = arr2.back().end();
710
711 auto ptrLess = std::less<void const* const>();
712 return ptrLess(beg1Addr, end2Addr) && ptrLess(beg2Addr, end1Addr);
713}
714
715//
716// Explicit instantiations
717//
719#define INSTANTIATE_OPERATOR(OP_EQ, T) \
720 template Image<T>& operator OP_EQ(Image<T>& lhs, Image<std::uint16_t> const& rhs); \
721 template Image<T>& operator OP_EQ(Image<T>& lhs, Image<int> const& rhs); \
722 template Image<T>& operator OP_EQ(Image<T>& lhs, Image<float> const& rhs); \
723 template Image<T>& operator OP_EQ(Image<T>& lhs, Image<double> const& rhs); \
724 template Image<T>& operator OP_EQ(Image<T>& lhs, Image<std::uint64_t> const& rhs);
725
726#define INSTANTIATE(T) \
727 template class ImageBase<T>; \
728 template class Image<T>; \
729 INSTANTIATE_OPERATOR(+=, T); \
730 INSTANTIATE_OPERATOR(-=, T); \
731 INSTANTIATE_OPERATOR(*=, T); \
732 INSTANTIATE_OPERATOR(/=, T)
733
734#define INSTANTIATE2(T1, T2) template bool imagesOverlap<T1, T2>(ImageBase<T1> const&, ImageBase<T2> const&);
735
737INSTANTIATE(int);
738INSTANTIATE(float);
739INSTANTIATE(double);
741
747
749INSTANTIATE2(int, int);
750INSTANTIATE2(int, float);
751INSTANTIATE2(int, double);
753
755INSTANTIATE2(float, int);
756INSTANTIATE2(float, float);
757INSTANTIATE2(float, double);
759
761INSTANTIATE2(double, int);
762INSTANTIATE2(double, float);
763INSTANTIATE2(double, double);
765
771
773} // namespace image
774} // namespace afw
775} // namespace lsst
AmpInfoBoxKey bbox
Definition: Amplifier.cc:117
int end
double x
#define INSTANTIATE(FROMSYS, TOSYS)
Definition: Detector.cc:484
#define LSST_EXCEPT(type,...)
afw::table::PointKey< int > dimensions
Definition: GaussianPsf.cc:48
afw::table::Key< afw::table::Array< MaskPixelT > > mask
#define INSTANTIATE2(ImagePixelT1, ImagePixelT2)
Definition: MaskedImage.cc:690
int y
Definition: SpanSet.cc:48
table::Key< int > b
table::Key< int > a
A simple struct that combines the two arguments that must be passed to most cfitsio routines and cont...
Definition: fits.h:297
void writeImage(ndarray::Array< T const, N, C > const &array)
Write an ndarray::Array to a FITS image HDU.
Definition: fits.h:477
Lifetime-management for memory that goes into FITS memory files.
Definition: fits.h:121
A class used to request that array accesses be checked.
Definition: ImageBase.h:74
std::shared_ptr< daf::base::PropertyList > readMetadata()
Read the image's FITS header.
The base class for all image classed (Image, Mask, MaskedImage, ...)
Definition: ImageBase.h:102
iterator end() const
Return an STL compliant iterator to the end of the image.
Definition: Image.cc:256
iterator begin() const
Return an STL compliant iterator to the start of the image.
Definition: Image.cc:251
static _view_t _allocateView(lsst::geom::Extent2I const &dimensions, Manager::Ptr &manager)
Definition: Image.cc:46
typename Reference< PixelT >::type PixelReference
A Reference to a PixelT.
Definition: ImageBase.h:117
typename _view_t::iterator iterator
An STL compliant iterator.
Definition: ImageBase.h:125
PixelReference operator()(int x, int y)
Return a reference to the pixel (x, y) in LOCAL coordinates.
Definition: Image.cc:172
static _view_t _makeSubView(lsst::geom::Extent2I const &dimensions, lsst::geom::Extent2I const &offset, const _view_t &view)
Definition: Image.cc:66
int getWidth() const
Return the number of columns in the image.
Definition: ImageBase.h:294
lsst::geom::Box2I getBBox(ImageOrigin origin=PARENT) const
Definition: ImageBase.h:445
int getArea() const
Return the area of the image.
Definition: ImageBase.h:298
lsst::geom::Extent2I getDimensions() const
Return the image's size; useful for passing to constructors.
Definition: ImageBase.h:356
typename ndarray::Array< PixelT, 2, 1 > Array
A mutable ndarray representation of the image.
Definition: ImageBase.h:149
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.
Definition: Image.cc:154
x_iterator fast_iterator
A fast STL compliant iterator for contiguous images N.b.
Definition: ImageBase.h:137
typename _view_t::reverse_iterator reverse_iterator
An STL compliant reverse iterator.
Definition: ImageBase.h:129
int getHeight() const
Return the number of rows in the image.
Definition: ImageBase.h:296
ImageBase & operator=(const ImageBase &rhs)
Shallow assignment operator.
Definition: Image.cc:141
iterator at(int x, int y) const
Return an STL compliant iterator at the point (x, y)
Definition: Image.cc:271
typename _view_t::x_iterator x_iterator
An iterator for traversing the pixels in a row.
Definition: ImageBase.h:133
reverse_iterator rbegin() const
Return an STL compliant reverse iterator to the start of the image.
Definition: Image.cc:261
_view_t _getRawView() const
Definition: ImageBase.h:465
PixelReference get(lsst::geom::Point2I const &index, ImageOrigin origin)
Return a reference to a single pixel (with no bounds check).
Definition: Image.cc:210
void swap(ImageBase &rhs)
Definition: Image.cc:234
typename ConstReference< PixelT >::type PixelConstReference
A ConstReference to a PixelT.
Definition: ImageBase.h:119
reverse_iterator rend() const
Return an STL compliant reverse iterator to the end of the image.
Definition: Image.cc:266
A FITS reader class for regular Images.
Image< PixelT > read(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT, bool allowUnsafe=false)
Read the Image.
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:51
void scaledPlus(double const c, Image< PixelT > const &rhs)
Add Image c*rhs to lhs.
Definition: Image.cc:488
Image & operator*=(PixelT const rhs)
Multiply lhs by scalar rhs.
Definition: Image.cc:546
void scaledMinus(double const c, Image< PixelT > const &rhs)
Subtract Image c*rhs from lhs.
Definition: Image.cc:520
Image & operator-=(PixelT const rhs)
Subtract scalar rhs from lhs.
Definition: Image.cc:501
Image & operator=(const PixelT rhs)
Set the image's pixels to rhs.
Definition: Image.cc:338
void scaledMultiplies(double const c, Image< PixelT > const &rhs)
Multiply lhs by Image c*rhs (i.e. pixel-by-pixel multiplication)
Definition: Image.cc:565
Image & operator+=(PixelT const rhs)
Add scalar rhs to lhs.
Definition: Image.cc:456
void swap(Image &rhs)
Definition: Image.cc:437
Image & operator/=(PixelT const rhs)
Divide lhs by scalar rhs.
Definition: Image.cc:578
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.
void scaledDivides(double const c, Image< PixelT > const &rhs)
Divide lhs by Image c*rhs (i.e. pixel-by-pixel division)
Definition: Image.cc:613
friend class Image
Definition: Image.h:65
A Function taking two arguments.
Definition: Function.h:259
int getAsInt(std::string const &name) const
bool exists(std::string const &name) const
lsst::geom::Point2I getImageXY0FromMetadata(daf::base::PropertySet &metadata, std::string const &wcsName, bool strip=false)
Definition: wcsUtils.cc:95
std::string const wcsNameForXY0
Definition: ImageBase.h:70
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
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.
Definition: Image.cc:659
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.
Definition: Image.cc:665
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)
Definition: Image.cc:682
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.
Definition: Image.cc:677
double indexToPosition(double ind)
Convert image index to image position.
Definition: ImageUtils.h:55
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.
Definition: Image.cc:671
bool imagesOverlap(ImageBase< T1 > const &image1, ImageBase< T2 > const &image2)
Return true if the pixels for two images or masks overlap in memory.
Definition: Image.cc:694
void swap(Image< PixelT > &a, Image< PixelT > &b)
Definition: Image.cc:444
Extent< int, 2 > ExtentI
Extent< int, 2 > Extent2I
A base class for image defects.
T sqrt(T... args)
Options for writing an image to FITS.
Definition: fits.h:219
A functor class equivalent to std::function<LhsT (LhsT, RhsT)>, but with a virtual operator()
T swap(T... args)