Loading [MathJax]/extensions/tex2jax.js
LSST Applications g0fba68d861+849f694866,g1fd858c14a+7a7b9dd5ed,g2c84ff76c0+5cb23283cf,g30358e5240+f0e04ebe90,g35bb328faa+fcb1d3bbc8,g436fd98eb5+bdc6fcdd04,g4af146b050+742274f7cd,g4d2262a081+9d5bd0394b,g4e0f332c67+cb09b8a5b6,g53246c7159+fcb1d3bbc8,g5a012ec0e7+477f9c599b,g60b5630c4e+bdc6fcdd04,g67b6fd64d1+2218407a0c,g78460c75b0+2f9a1b4bcd,g786e29fd12+cf7ec2a62a,g7b71ed6315+fcb1d3bbc8,g87b7deb4dc+777438113c,g8852436030+ebf28f0d95,g89139ef638+2218407a0c,g9125e01d80+fcb1d3bbc8,g989de1cb63+2218407a0c,g9f33ca652e+42fb53f4c8,g9f7030ddb1+11b9b6f027,ga2b97cdc51+bdc6fcdd04,gab72ac2889+bdc6fcdd04,gabe3b4be73+1e0a283bba,gabf8522325+3210f02652,gb1101e3267+9c79701da9,gb58c049af0+f03b321e39,gb89ab40317+2218407a0c,gcf25f946ba+ebf28f0d95,gd6cbbdb0b4+e8f9c9c900,gd9a9a58781+fcb1d3bbc8,gde0f65d7ad+47bbabaf80,gded526ad44+8c3210761e,ge278dab8ac+3ef3db156b,ge410e46f29+2218407a0c,gf67bdafdda+2218407a0c,v29.0.0.rc3
LSST Data Management Base Package
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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
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.
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
std::int32_t MaskPixel
default type for Masks and MaskedImage Masks
OutImageT::SinglePixel convolveAtAPoint(typename InImageT::const_xy_locator inImageLocator, typename lsst::afw::image::Image< lsst::afw::math::Kernel::Pixel >::const_xy_locator kernelLocator, int kWidth, int kHeight)
Apply convolution kernel to an image at one point.
Point< double, 2 > Point2D
Definition Point.h:324
Point< int, 2 > Point2I
Definition Point.h:321
A traits class for MaskedImage.
Definition MaskedImage.h:51