LSST Applications g0f08755f38+82efc23009,g12f32b3c4e+e7bdf1200e,g1653933729+a8ce1bb630,g1a0ca8cf93+50eff2b06f,g28da252d5a+52db39f6a5,g2bbee38e9b+37c5a29d61,g2bc492864f+37c5a29d61,g2cdde0e794+c05ff076ad,g3156d2b45e+41e33cbcdc,g347aa1857d+37c5a29d61,g35bb328faa+a8ce1bb630,g3a166c0a6a+37c5a29d61,g3e281a1b8c+fb992f5633,g414038480c+7f03dfc1b0,g41af890bb2+11b950c980,g5fbc88fb19+17cd334064,g6b1c1869cb+12dd639c9a,g781aacb6e4+a8ce1bb630,g80478fca09+72e9651da0,g82479be7b0+04c31367b4,g858d7b2824+82efc23009,g9125e01d80+a8ce1bb630,g9726552aa6+8047e3811d,ga5288a1d22+e532dc0a0b,gae0086650b+a8ce1bb630,gb58c049af0+d64f4d3760,gc28159a63d+37c5a29d61,gcf0d15dbbd+2acd6d4d48,gd7358e8bfb+778a810b6e,gda3e153d99+82efc23009,gda6a2b7d83+2acd6d4d48,gdaeeff99f8+1711a396fd,ge2409df99d+6b12de1076,ge79ae78c31+37c5a29d61,gf0baf85859+d0a5978c5a,gf3967379c6+4954f8c433,gfb92a5be7c+82efc23009,gfec2e1e490+2aaed99252,w.2024.46
LSST Data Management Base Package
Loading...
Searching...
No Matches
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
29#include "lsst/geom/Point.h"
30
31namespace lsst {
32namespace afw {
33namespace math {
34namespace detail {
35
39template <typename DestImageT, typename SrcImageT>
40class WarpAtOnePoint final {
41public:
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
142 using k_iter = typename std::vector<lsst::afw::math::Kernel::Pixel>::const_iterator;
143
144 typename DestImageT::Mask::SinglePixel destMaskValue = 0;
145 for (double kValY : _maskYList) {
146 typename DestImageT::Mask::SinglePixel destMaskValueY = 0;
147 for (k_iter kernelXIter = _maskXList.begin(), xEnd = _maskXList.end();
148 kernelXIter != xEnd; ++kernelXIter, ++srcMaskLoc.x()) {
149 typename lsst::afw::math::Kernel::Pixel const kValX = *kernelXIter;
150 if (kValX != 0) {
151 destMaskValueY |= *srcMaskLoc;
152 }
153 }
154
155 if (kValY != 0) {
156 destMaskValue |= destMaskValueY;
157 }
158
159 srcMaskLoc += lsst::afw::image::detail::difference_type(-_maskXList.size(), 1);
160 }
161
162 destXIter.mask() = (destXIter.mask() & _growFullMask) | destMaskValue;
163 }
164 return true;
165 } else {
166 // Edge pixel
167 *destXIter = _padValue;
168 return false;
169 }
170 }
171
172private:
178 double _setFracIndex(double xFrac, double yFrac) {
179 std::pair<double, double> srcFracInd(xFrac, yFrac);
180 _kernelPtr->setKernelParameters(srcFracInd);
181 double kSum = _kernelPtr->computeVectors(_xList, _yList, false);
182 if (_maskKernelPtr) {
183 _maskKernelPtr->setKernelParameters(srcFracInd);
184 _maskKernelPtr->computeVectors(_maskXList, _maskYList, false);
185 }
186 return kSum;
187 }
188
189 SrcImageT _srcImage;
192 bool _hasMaskKernel;
193 lsst::geom::Point2I _kernelCtr;
194 lsst::geom::Point2I _maskKernelCtr;
195 lsst::afw::image::MaskPixel _growFullMask;
196 std::vector<double> _xList;
197 std::vector<double> _yList;
198 std::vector<double> _maskXList;
199 std::vector<double> _maskYList;
200 typename DestImageT::SinglePixel _padValue;
201 lsst::geom::Box2I const _srcGoodBBox;
202};
203} // namespace detail
204} // namespace math
205} // namespace afw
206} // 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:341
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.
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)
An integer coordinate rectangle.
Definition Box.h:55
bool contains(Point2I const &point) const noexcept
Return true if the box contains the point.
Definition Box.cc:114
T end(T... args)
T size(T... args)
A traits class for MaskedImage.
Definition MaskedImage.h:51