Loading [MathJax]/extensions/tex2jax.js
LSST Applications g0fba68d861+05816baf74,g1ec0fe41b4+f536777771,g1fd858c14a+a9301854fb,g35bb328faa+fcb1d3bbc8,g4af146b050+a5c07d5b1d,g4d2262a081+6e5fcc2a4e,g53246c7159+fcb1d3bbc8,g56a49b3a55+9c12191793,g5a012ec0e7+3632fc3ff3,g60b5630c4e+ded28b650d,g67b6fd64d1+ed4b5058f4,g78460c75b0+2f9a1b4bcd,g786e29fd12+cf7ec2a62a,g8352419a5c+fcb1d3bbc8,g87b7deb4dc+7b42cf88bf,g8852436030+e5453db6e6,g89139ef638+ed4b5058f4,g8e3bb8577d+d38d73bdbd,g9125e01d80+fcb1d3bbc8,g94187f82dc+ded28b650d,g989de1cb63+ed4b5058f4,g9d31334357+ded28b650d,g9f33ca652e+50a8019d8c,gabe3b4be73+1e0a283bba,gabf8522325+fa80ff7197,gb1101e3267+d9fb1f8026,gb58c049af0+f03b321e39,gb665e3612d+2a0c9e9e84,gb89ab40317+ed4b5058f4,gcf25f946ba+e5453db6e6,gd6cbbdb0b4+bb83cc51f8,gdd1046aedd+ded28b650d,gde0f65d7ad+941d412827,ge278dab8ac+d65b3c2b70,ge410e46f29+ed4b5058f4,gf23fb2af72+b7cae620c0,gf5e32f922b+fcb1d3bbc8,gf67bdafdda+ed4b5058f4,w.2025.16
LSST Data Management Base Package
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
ConvolveImage.cc
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
25/*
26 * Definition of functions declared in ConvolveImage.h
27 */
28#include <cstdint>
29#include <iostream>
30#include <vector>
31#include <string>
32
33#include "lsst/pex/exceptions.h"
37
38namespace pexExcept = lsst::pex::exceptions;
39
40namespace lsst {
41namespace afw {
42namespace math {
43
44namespace {
45
58template <typename OutImageT, typename InImageT>
59inline void setEdgePixels(OutImageT& outImage, Kernel const& kernel, InImageT const& inImage, bool doCopyEdge,
61 const unsigned int imWidth = outImage.getWidth();
62 const unsigned int imHeight = outImage.getHeight();
63 const unsigned int kWidth = kernel.getWidth();
64 const unsigned int kHeight = kernel.getHeight();
65 const unsigned int kCtrX = kernel.getCtr().getX();
66 const unsigned int kCtrY = kernel.getCtr().getY();
67
68 const typename OutImageT::SinglePixel edgePixel =
70 std::vector<lsst::geom::Box2I> bboxList;
71
72 // create a list of bounding boxes describing edge regions, in this order:
73 // bottom edge, top edge (both edge to edge),
74 // left edge, right edge (both omitting pixels already in the bottom and top edge regions)
75 int const numHeight = kHeight - (1 + kCtrY);
76 int const numWidth = kWidth - (1 + kCtrX);
77 bboxList.emplace_back(lsst::geom::Point2I(0, 0), lsst::geom::Extent2I(imWidth, kCtrY));
78 bboxList.emplace_back(lsst::geom::Point2I(0, imHeight - numHeight),
79 lsst::geom::Extent2I(imWidth, numHeight));
80 bboxList.emplace_back(lsst::geom::Point2I(0, kCtrY),
81 lsst::geom::Extent2I(kCtrX, imHeight + 1 - kHeight));
82 bboxList.emplace_back(lsst::geom::Point2I(imWidth - numWidth, kCtrY),
83 lsst::geom::Extent2I(numWidth, imHeight + 1 - kHeight));
84
85 for (auto const &bboxIter : bboxList) {
86 OutImageT outView(outImage, bboxIter, image::LOCAL);
87 if (doCopyEdge) {
88 // note: set only works with data of the same type
89 // so convert the input image to output format
90 outView.assign(OutImageT(InImageT(inImage, bboxIter, image::LOCAL), true));
91 } else {
92 outView = edgePixel;
93 }
94 }
95}
96
109template <typename OutImageT, typename InImageT>
110inline void setEdgePixels(OutImageT& outImage, Kernel const& kernel, InImageT const& inImage, bool doCopyEdge,
112 const unsigned int imWidth = outImage.getWidth();
113 const unsigned int imHeight = outImage.getHeight();
114 const unsigned int kWidth = kernel.getWidth();
115 const unsigned int kHeight = kernel.getHeight();
116 const unsigned int kCtrX = kernel.getCtr().getX();
117 const unsigned int kCtrY = kernel.getCtr().getY();
118
119 const typename OutImageT::SinglePixel edgePixel =
121 std::vector<lsst::geom::Box2I> bboxList;
122
123 // create a list of bounding boxes describing edge regions, in this order:
124 // bottom edge, top edge (both edge to edge),
125 // left edge, right edge (both omitting pixels already in the bottom and top edge regions)
126 int const numHeight = kHeight - (1 + kCtrY);
127 int const numWidth = kWidth - (1 + kCtrX);
128 bboxList.emplace_back(lsst::geom::Point2I(0, 0), lsst::geom::Extent2I(imWidth, kCtrY));
129 bboxList.emplace_back(lsst::geom::Point2I(0, imHeight - numHeight),
130 lsst::geom::Extent2I(imWidth, numHeight));
131 bboxList.emplace_back(lsst::geom::Point2I(0, kCtrY),
132 lsst::geom::Extent2I(kCtrX, imHeight + 1 - kHeight));
133 bboxList.emplace_back(lsst::geom::Point2I(imWidth - numWidth, kCtrY),
134 lsst::geom::Extent2I(numWidth, imHeight + 1 - kHeight));
135
137 for (auto const &bboxIter : bboxList) {
138 OutImageT outView(outImage, bboxIter, image::LOCAL);
139 if (doCopyEdge) {
140 // note: set only works with data of the same type
141 // so convert the input image to output format
142 outView.assign(OutImageT(InImageT(inImage, bboxIter, image::LOCAL), true));
143 *(outView.getMask()) |= edgeMask;
144 } else {
145 outView = edgePixel;
146 }
147 }
148}
149
150} // anonymous namespace
151
152template <typename OutImageT, typename InImageT>
153void scaledPlus(OutImageT& outImage, double c1, InImageT const& inImage1, double c2,
154 InImageT const& inImage2) {
155 if (outImage.getDimensions() != inImage1.getDimensions()) {
157 os << "outImage dimensions = ( " << outImage.getWidth() << ", " << outImage.getHeight() << ") != ("
158 << inImage1.getWidth() << ", " << inImage1.getHeight() << ") = inImage1 dimensions";
159 throw LSST_EXCEPT(pexExcept::InvalidParameterError, os.str());
160 } else if (inImage1.getDimensions() != inImage2.getDimensions()) {
162 os << "inImage1 dimensions = ( " << inImage1.getWidth() << ", " << inImage1.getHeight() << ") != ("
163 << inImage2.getWidth() << ", " << inImage2.getHeight() << ") = inImage2 dimensions";
164 throw LSST_EXCEPT(pexExcept::InvalidParameterError, os.str());
165 }
166
167 using InConstXIter = typename InImageT::const_x_iterator;
168 using OutXIter = typename OutImageT::x_iterator;
169 for (int y = 0; y != inImage1.getHeight(); ++y) {
170 InConstXIter const end1 = inImage1.row_end(y);
171 InConstXIter inIter1 = inImage1.row_begin(y);
172 InConstXIter inIter2 = inImage2.row_begin(y);
173 OutXIter outIter = outImage.row_begin(y);
174 for (; inIter1 != end1; ++inIter1, ++inIter2, ++outIter) {
175 *outIter = (*inIter1 * c1) + (*inIter2 * c2);
176 }
177 }
178}
179
180template <typename OutImageT, typename InImageT, typename KernelT>
181void convolve(OutImageT& convolvedImage, InImageT const& inImage, KernelT const& kernel,
182 ConvolutionControl const& convolutionControl) {
183 detail::basicConvolve(convolvedImage, inImage, kernel, convolutionControl);
184 setEdgePixels(convolvedImage, kernel, inImage, convolutionControl.getDoCopyEdge(),
186 convolvedImage.setXY0(inImage.getXY0());
187}
188
189template <typename OutImageT, typename InImageT, typename KernelT>
190void convolve(OutImageT& convolvedImage, InImageT const& inImage, KernelT const& kernel, bool doNormalize,
191 bool doCopyEdge) {
192 ConvolutionControl convolutionControl;
193 convolutionControl.setDoNormalize(doNormalize);
194 convolutionControl.setDoCopyEdge(doCopyEdge);
195 convolve(convolvedImage, inImage, kernel, convolutionControl);
196}
197
199/*
200 * Explicit instantiation of all convolve functions.
201 *
202 * This code needs to be compiled with full optimization, and there's no reason why
203 * it should be instantiated in the swig wrappers.
204 */
205#define IMAGE(PIXTYPE) image::Image<PIXTYPE>
206#define MASKEDIMAGE(PIXTYPE) image::MaskedImage<PIXTYPE, image::MaskPixel, image::VariancePixel>
207//
208// Next a macro to generate needed instantiations for IMGMACRO (either IMAGE or MASKEDIMAGE)
209// and the specified pixel types
210//
211/* NL's a newline for debugging -- don't define it and say
212 g++ -C -E -I$(eups list -s -d boost)/include Convolve.cc | perl -pe 's| *NL *|\n|g'
213*/
214#define NL /* */
215//
216// Instantiate one kernel-specific specializations of convolution functions for Image or MaskedImage
217// IMGMACRO = IMAGE or MASKEDIMAGE
218// KERNELTYPE = a kernel class
219//
220#define INSTANTIATE_IM_OR_MI_KERNEL(IMGMACRO, OUTPIXTYPE, INPIXTYPE, KERNELTYPE) \
221 template void convolve(IMGMACRO(OUTPIXTYPE)&, IMGMACRO(INPIXTYPE) const &, KERNELTYPE const&, bool, \
222 bool); \
223 NL template void convolve(IMGMACRO(OUTPIXTYPE)&, IMGMACRO(INPIXTYPE) const &, KERNELTYPE const&, \
224 ConvolutionControl const&); \
225 NL
226//
227// Instantiate Image or MaskedImage versions of all functions defined in this file.
228// Call INSTANTIATE_IM_OR_MI_KERNEL once for each kernel class.
229// IMGMACRO = IMAGE or MASKEDIMAGE
230//
231#define INSTANTIATE_IM_OR_MI(IMGMACRO, OUTPIXTYPE, INPIXTYPE) \
232 template void scaledPlus(IMGMACRO(OUTPIXTYPE)&, double, IMGMACRO(INPIXTYPE) const &, double, \
233 IMGMACRO(INPIXTYPE) const &); \
234 NL INSTANTIATE_IM_OR_MI_KERNEL(IMGMACRO, OUTPIXTYPE, INPIXTYPE, \
235 AnalyticKernel) INSTANTIATE_IM_OR_MI_KERNEL(IMGMACRO, OUTPIXTYPE, \
236 INPIXTYPE, \
237 DeltaFunctionKernel) \
238 INSTANTIATE_IM_OR_MI_KERNEL(IMGMACRO, OUTPIXTYPE, INPIXTYPE, FixedKernel) \
239 INSTANTIATE_IM_OR_MI_KERNEL(IMGMACRO, OUTPIXTYPE, INPIXTYPE, LinearCombinationKernel) \
240 INSTANTIATE_IM_OR_MI_KERNEL(IMGMACRO, OUTPIXTYPE, INPIXTYPE, SeparableKernel) \
241 INSTANTIATE_IM_OR_MI_KERNEL(IMGMACRO, OUTPIXTYPE, INPIXTYPE, Kernel) //
242// Instantiate all functions defined in this file for one specific output and input pixel type
243//
244#define INSTANTIATE(OUTPIXTYPE, INPIXTYPE) \
245 INSTANTIATE_IM_OR_MI(IMAGE, OUTPIXTYPE, INPIXTYPE) \
246 INSTANTIATE_IM_OR_MI(MASKEDIMAGE, OUTPIXTYPE, INPIXTYPE)
247//
248// Instantiate all functions defined in this file
249//
250INSTANTIATE(double, double)
251INSTANTIATE(double, float)
252INSTANTIATE(double, int)
254INSTANTIATE(float, float)
255INSTANTIATE(float, int)
257INSTANTIATE(int, int)
260} // namespace math
261} // namespace afw
262} // namespace lsst
#define INSTANTIATE(FROMSYS, TOSYS)
Definition Detector.cc:509
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition Exception.h:48
Represent a 2-dimensional array of bitmask pixels.
Definition Mask.h:82
Parameters to control convolution.
void setDoCopyEdge(bool doCopyEdge)
void setDoNormalize(bool doNormalize)
Kernels are used for convolution with MaskedImages and (eventually) Images.
Definition Kernel.h:110
T emplace_back(T... args)
std::int32_t MaskPixel
default type for Masks and MaskedImage Masks
void basicConvolve(OutImageT &convolvedImage, InImageT const &inImage, lsst::afw::math::Kernel const &kernel, lsst::afw::math::ConvolutionControl const &convolutionControl)
Low-level convolution function that does not set edge pixels.
void scaledPlus(OutImageT &outImage, double c1, InImageT const &inImage1, double c2, InImageT const &inImage2)
Compute the scaled sum of two images.
void convolve(OutImageT &convolvedImage, InImageT const &inImage, KernelT const &kernel, ConvolutionControl const &convolutionControl=ConvolutionControl())
Convolve an Image or MaskedImage with a Kernel, setting pixels of an existing output image.
ImageT::SinglePixel edgePixel(lsst::afw::image::detail::Image_tag)
Return an off-the-edge pixel appropriate for a given Image type.
Extent< int, 2 > Extent2I
Definition Extent.h:397
Point< int, 2 > Point2I
Definition Point.h:321
T str(T... args)
A traits class for MaskedImage.
Definition MaskedImage.h:51
typename ImageT::image_category image_category
Definition ImageBase.h:67