LSST Applications g06d8191974+de063e15a7,g180d380827+d0b6459378,g2079a07aa2+86d27d4dc4,g2305ad1205+f1ae3263cc,g29320951ab+5752d78b6e,g2bbee38e9b+85cf0a37e7,g337abbeb29+85cf0a37e7,g33d1c0ed96+85cf0a37e7,g3a166c0a6a+85cf0a37e7,g3ddfee87b4+b5254b9343,g48712c4677+9ea88d309d,g487adcacf7+05f7dba17f,g50ff169b8f+96c6868917,g52b1c1532d+585e252eca,g591dd9f2cf+48904e3942,g64a986408d+de063e15a7,g858d7b2824+de063e15a7,g864b0138d7+33ab2bc355,g8a8a8dda67+585e252eca,g99cad8db69+4508353287,g9c22b2923f+53520f316c,g9ddcbc5298+9a081db1e4,ga1e77700b3+15fc3df1f7,gb0e22166c9+60f28cb32d,gba4ed39666+c2a2e4ac27,gbb8dafda3b+ccb7f83a87,gc120e1dc64+6caf640b9b,gc28159a63d+85cf0a37e7,gc3e9b769f7+548c5e05a3,gcf0d15dbbd+b5254b9343,gdaeeff99f8+f9a426f77a,ge6526c86ff+515b6c9330,ge79ae78c31+85cf0a37e7,gee10cc3b42+585e252eca,gff1a9f87cc+de063e15a7,w.2024.17
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