lsst.afw  22.0.1-22-gf1d71818e+4206820b0d
WarpAtOnePoint.h
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 
3 /*
4  * LSST Data Management System
5  * Copyright 2008, 2009, 2010 LSST Corporation.
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 #include <vector>
25 
26 #include "lsst/afw/math/Kernel.h"
27 #include "lsst/afw/image/Image.h"
29 #include "lsst/geom/Point.h"
30 
31 namespace lsst {
32 namespace afw {
33 namespace math {
34 namespace detail {
35 
39 template <typename DestImageT, typename SrcImageT>
41 public:
42  WarpAtOnePoint(SrcImageT const &srcImage, WarpingControl const &control,
43  typename DestImageT::SinglePixel padValue)
44  : _srcImage(srcImage),
45  _kernelPtr(control.getWarpingKernel()),
46  _maskKernelPtr(control.getMaskWarpingKernel()),
47  _hasMaskKernel(control.getMaskWarpingKernel()),
48  _kernelCtr(_kernelPtr->getCtr()),
49  _maskKernelCtr(_maskKernelPtr ? _maskKernelPtr->getCtr() : lsst::geom::Point2I(0, 0)),
50  _growFullMask(control.getGrowFullMask()),
51  _xList(_kernelPtr->getWidth()),
52  _yList(_kernelPtr->getHeight()),
53  _maskXList(_maskKernelPtr ? _maskKernelPtr->getWidth() : 0),
54  _maskYList(_maskKernelPtr ? _maskKernelPtr->getHeight() : 0),
55  _padValue(padValue),
56  _srcGoodBBox(_kernelPtr->shrinkBBox(srcImage.getBBox(lsst::afw::image::LOCAL))){};
57 
63  bool operator()(typename DestImageT::x_iterator &destXIter, lsst::geom::Point2D const &srcPos,
64  double relativeArea, lsst::afw::image::detail::Image_tag) {
65  // Compute associated source pixel index as integer and nonnegative fractional parts;
66  // the latter is used to compute the remapping kernel.
67  std::pair<int, double> srcIndFracX = _srcImage.positionToIndex(srcPos[0], lsst::afw::image::X);
68  std::pair<int, double> srcIndFracY = _srcImage.positionToIndex(srcPos[1], lsst::afw::image::Y);
69  if (srcIndFracX.second < 0) {
70  ++srcIndFracX.second;
71  --srcIndFracX.first;
72  }
73  if (srcIndFracY.second < 0) {
74  ++srcIndFracY.second;
75  --srcIndFracY.first;
76  }
77 
78  if (_srcGoodBBox.contains(lsst::geom::Point2I(srcIndFracX.first, srcIndFracY.first))) {
79  // Offset source pixel index from kernel center to kernel corner (0, 0)
80  // so we can convolveAtAPoint the pixels that overlap between source and kernel
81  int srcStartX = srcIndFracX.first - _kernelCtr[0];
82  int srcStartY = srcIndFracY.first - _kernelCtr[1];
83 
84  // Compute warped pixel
85  double kSum = _setFracIndex(srcIndFracX.second, srcIndFracY.second);
86 
87  typename SrcImageT::const_xy_locator srcLoc = _srcImage.xy_at(srcStartX, srcStartY);
88 
89  *destXIter = lsst::afw::math::convolveAtAPoint<DestImageT, SrcImageT>(srcLoc, _xList, _yList);
90  *destXIter *= relativeArea / kSum;
91  return true;
92  } else {
93  // Edge pixel
94  *destXIter = _padValue;
95  return false;
96  }
97  }
98 
105  bool operator()(typename DestImageT::x_iterator &destXIter, lsst::geom::Point2D const &srcPos,
106  double relativeArea, lsst::afw::image::detail::MaskedImage_tag) {
107  // Compute associated source pixel index as integer and nonnegative fractional parts;
108  // the latter is used to compute the remapping kernel.
109  std::pair<int, double> srcIndFracX = _srcImage.positionToIndex(srcPos[0], lsst::afw::image::X);
110  std::pair<int, double> srcIndFracY = _srcImage.positionToIndex(srcPos[1], lsst::afw::image::Y);
111  if (srcIndFracX.second < 0) {
112  ++srcIndFracX.second;
113  --srcIndFracX.first;
114  }
115  if (srcIndFracY.second < 0) {
116  ++srcIndFracY.second;
117  --srcIndFracY.first;
118  }
119 
120  if (_srcGoodBBox.contains(lsst::geom::Point2I(srcIndFracX.first, srcIndFracY.first))) {
121  // Offset source pixel index from kernel center to kernel corner (0, 0)
122  // so we can convolveAtAPoint the pixels that overlap between source and kernel
123  int srcStartX = srcIndFracX.first - _kernelCtr[0];
124  int srcStartY = srcIndFracY.first - _kernelCtr[1];
125 
126  // Compute warped pixel
127  double kSum = _setFracIndex(srcIndFracX.second, srcIndFracY.second);
128 
129  typename SrcImageT::const_xy_locator srcLoc = _srcImage.xy_at(srcStartX, srcStartY);
130 
131  *destXIter = lsst::afw::math::convolveAtAPoint<DestImageT, SrcImageT>(srcLoc, _xList, _yList);
132  *destXIter *= relativeArea / kSum;
133 
134  if (_hasMaskKernel) {
135  // compute mask value based on the mask kernel (replacing the value computed above)
136  int maskStartX = srcIndFracX.first - _maskKernelCtr[0];
137  int maskStartY = srcIndFracY.first - _maskKernelCtr[1];
138 
139  typename SrcImageT::Mask::const_xy_locator srcMaskLoc =
140  _srcImage.getMask()->xy_at(maskStartX, maskStartY);
141 
143 
144  typename DestImageT::Mask::SinglePixel destMaskValue = 0;
145  for (k_iter kernelYIter = _maskYList.begin(), yEnd = _maskYList.end(); kernelYIter != yEnd;
146  ++kernelYIter) {
147  typename DestImageT::Mask::SinglePixel destMaskValueY = 0;
148  for (k_iter kernelXIter = _maskXList.begin(), xEnd = _maskXList.end();
149  kernelXIter != xEnd; ++kernelXIter, ++srcMaskLoc.x()) {
150  typename lsst::afw::math::Kernel::Pixel const kValX = *kernelXIter;
151  if (kValX != 0) {
152  destMaskValueY |= *srcMaskLoc;
153  }
154  }
155 
156  double const kValY = *kernelYIter;
157  if (kValY != 0) {
158  destMaskValue |= destMaskValueY;
159  }
160 
161  srcMaskLoc += lsst::afw::image::detail::difference_type(-_maskXList.size(), 1);
162  }
163 
164  destXIter.mask() = (destXIter.mask() & _growFullMask) | destMaskValue;
165  }
166  return true;
167  } else {
168  // Edge pixel
169  *destXIter = _padValue;
170  return false;
171  }
172  }
173 
174 private:
180  double _setFracIndex(double xFrac, double yFrac) {
181  std::pair<double, double> srcFracInd(xFrac, yFrac);
182  _kernelPtr->setKernelParameters(srcFracInd);
183  double kSum = _kernelPtr->computeVectors(_xList, _yList, false);
184  if (_maskKernelPtr) {
185  _maskKernelPtr->setKernelParameters(srcFracInd);
186  _maskKernelPtr->computeVectors(_maskXList, _maskYList, false);
187  }
188  return kSum;
189  }
190 
191  SrcImageT _srcImage;
194  bool _hasMaskKernel;
195  lsst::geom::Point2I _kernelCtr;
196  lsst::geom::Point2I _maskKernelCtr;
197  lsst::afw::image::MaskPixel _growFullMask;
198  std::vector<double> _xList;
199  std::vector<double> _yList;
200  std::vector<double> _maskXList;
201  std::vector<double> _maskYList;
202  typename DestImageT::SinglePixel _padValue;
203  lsst::geom::Box2I const _srcGoodBBox;
204 };
205 } // namespace detail
206 } // namespace math
207 } // namespace afw
208 } // namespace lsst
T begin(T... args)
void setKernelParameters(std::vector< double > const &params)
Set the kernel parameters of a spatially invariant kernel.
Definition: Kernel.h:342
double computeVectors(std::vector< Pixel > &colList, std::vector< Pixel > &rowList, bool doNormalize, double x=0.0, double y=0.0) const
Compute the column and row arrays in place, where kernel(col, row) = colList(col) * rowList(row)
Parameters to control convolution.
Definition: warpExposure.h:276
A functor that computes one warped pixel.
bool operator()(typename DestImageT::x_iterator &destXIter, lsst::geom::Point2D const &srcPos, double relativeArea, lsst::afw::image::detail::Image_tag)
Compute one warped pixel, Image specialization.
bool operator()(typename DestImageT::x_iterator &destXIter, lsst::geom::Point2D const &srcPos, double relativeArea, lsst::afw::image::detail::MaskedImage_tag)
Compute one warped pixel, MaskedImage specialization.
WarpAtOnePoint(SrcImageT const &srcImage, WarpingControl const &control, typename DestImageT::SinglePixel padValue)
bool contains(Point2I const &point) const noexcept
T end(T... args)
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
class[[deprecated("Removed with no replacement (but see lsst::afw::image::TransmissionCurve). Will be " "removed after v22.")]] FilterProperty final
Describe the properties of a Filter (e.g.
Definition: Filter.h:53
A base class for image defects.
T size(T... args)
A traits class for MaskedImage.
Definition: MaskedImage.h:50