LSST Applications 27.0.0,g0265f82a02+469cd937ee,g02d81e74bb+21ad69e7e1,g1470d8bcf6+cbe83ee85a,g2079a07aa2+e67c6346a6,g212a7c68fe+04a9158687,g2305ad1205+94392ce272,g295015adf3+81dd352a9d,g2bbee38e9b+469cd937ee,g337abbeb29+469cd937ee,g3939d97d7f+72a9f7b576,g487adcacf7+71499e7cba,g50ff169b8f+5929b3527e,g52b1c1532d+a6fc98d2e7,g591dd9f2cf+df404f777f,g5a732f18d5+be83d3ecdb,g64a986408d+21ad69e7e1,g858d7b2824+21ad69e7e1,g8a8a8dda67+a6fc98d2e7,g99cad8db69+f62e5b0af5,g9ddcbc5298+d4bad12328,ga1e77700b3+9c366c4306,ga8c6da7877+71e4819109,gb0e22166c9+25ba2f69a1,gb6a65358fc+469cd937ee,gbb8dafda3b+69d3c0e320,gc07e1c2157+a98bf949bb,gc120e1dc64+615ec43309,gc28159a63d+469cd937ee,gcf0d15dbbd+72a9f7b576,gdaeeff99f8+a38ce5ea23,ge6526c86ff+3a7c1ac5f1,ge79ae78c31+469cd937ee,gee10cc3b42+a6fc98d2e7,gf1cff7945b+21ad69e7e1,gfbcc870c63+9a11dc8c8f
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