Coverage for python/lsst/afw/image/utils.py: 9%

61 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-04-15 02:24 -0700

1# This file is part of afw. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (https://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# This program is free software: you can redistribute it and/or modify 

10# it under the terms of the GNU General Public License as published by 

11# the Free Software Foundation, either version 3 of the License, or 

12# (at your option) any later version. 

13# 

14# This program is distributed in the hope that it will be useful, 

15# but WITHOUT ANY WARRANTY; without even the implied warranty of 

16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

17# GNU General Public License for more details. 

18# 

19# You should have received a copy of the GNU General Public License 

20# along with this program. If not, see <https://www.gnu.org/licenses/>. 

21 

22__all__ = ["clipImage", "projectImage", "getProjectionIndices"] 

23 

24import lsst.afw.detection as afwDetect 

25from ._maskedImage import MaskedImage, makeMaskedImage 

26from ._image import Mask 

27 

28 

29def clipImage(im, minClip, maxClip): 

30 """Clip an image to lie between minClip and maxclip (None to ignore)""" 

31 if isinstance(im, MaskedImage): 

32 mi = im 

33 else: 

34 mi = makeMaskedImage(im, Mask(im.getDimensions())) 

35 

36 if minClip is not None: 

37 ds = afwDetect.FootprintSet( 

38 mi, afwDetect.Threshold(-minClip, afwDetect.Threshold.VALUE, False)) 

39 afwDetect.setImageFromFootprintList( 

40 mi.getImage(), ds.getFootprints(), minClip) 

41 

42 if maxClip is not None: 

43 ds = afwDetect.FootprintSet(mi, afwDetect.Threshold(maxClip)) 

44 afwDetect.setImageFromFootprintList( 

45 mi.getImage(), ds.getFootprints(), maxClip) 

46 

47 

48def getProjectionIndices(imageBBox, targetBBox): 

49 """Get the indices to project an image 

50 

51 Given an image and target bounding box, 

52 calculate the indices needed to appropriately 

53 slice the input image and target image to 

54 project the image to the target. 

55 

56 Parameters 

57 ---------- 

58 imageBBox: Box2I 

59 Bounding box of the input image 

60 targetBBox: Box2I 

61 Bounding box of the target image 

62 

63 Returns 

64 ------- 

65 targetSlices: tuple 

66 Slices of the target image in the form (by, bx), (iy, ix). 

67 imageIndices: tuple 

68 Slices of the input image in the form (by, bx), (iy, ix). 

69 """ 

70 def getMin(dXmin): 

71 """Get minimum indices""" 

72 if dXmin < 0: 

73 bxStart = -dXmin 

74 ixStart = 0 

75 else: 

76 bxStart = 0 

77 ixStart = dXmin 

78 return bxStart, ixStart 

79 

80 def getMax(dXmax): 

81 """Get maximum indices""" 

82 if dXmax < 0: 

83 bxEnd = None 

84 ixEnd = dXmax 

85 elif dXmax != 0: 

86 bxEnd = -dXmax 

87 ixEnd = None 

88 else: 

89 bxEnd = ixEnd = None 

90 return bxEnd, ixEnd 

91 

92 dXmin = targetBBox.getMinX() - imageBBox.getMinX() 

93 dXmax = targetBBox.getMaxX() - imageBBox.getMaxX() 

94 dYmin = targetBBox.getMinY() - imageBBox.getMinY() 

95 dYmax = targetBBox.getMaxY() - imageBBox.getMaxY() 

96 

97 bxStart, ixStart = getMin(dXmin) 

98 byStart, iyStart = getMin(dYmin) 

99 bxEnd, ixEnd = getMax(dXmax) 

100 byEnd, iyEnd = getMax(dYmax) 

101 

102 bx = slice(bxStart, bxEnd) 

103 by = slice(byStart, byEnd) 

104 ix = slice(ixStart, ixEnd) 

105 iy = slice(iyStart, iyEnd) 

106 return (by, bx), (iy, ix) 

107 

108 

109def projectImage(image, bbox, fill=0): 

110 """Project an image into a bounding box 

111 

112 Return a new image whose pixels are equal to those of 

113 `image` within `bbox`, and equal to `fill` outside. 

114 

115 Parameters 

116 ---------- 

117 image: `afw.Image` or `afw.MaskedImage` 

118 The image to project 

119 bbox: `Box2I` 

120 The bounding box to project onto. 

121 fill: number 

122 The value to fill the region of the new 

123 image outside the bounding box of the original. 

124 

125 Returns 

126 ------- 

127 newImage: `afw.Image` or `afw.MaskedImage` 

128 The new image with the input image projected 

129 into its bounding box. 

130 """ 

131 if image.getBBox() == bbox: 

132 return image 

133 (by, bx), (iy, ix) = getProjectionIndices(image.getBBox(), bbox) 

134 

135 if isinstance(image, MaskedImage): 

136 newImage = type(image.image)(bbox) 

137 newImage.array[by, bx] = image.image.array[iy, ix] 

138 newMask = type(image.mask)(bbox) 

139 newMask.array[by, bx] = image.mask.array[iy, ix] 

140 newVariance = type(image.image)(bbox) 

141 newVariance.array[by, bx] = image.variance.array[iy, ix] 

142 newImage = MaskedImage(image=newImage, mask=newMask, variance=newVariance, dtype=newImage.array.dtype) 

143 else: 

144 newImage = type(image)(bbox) 

145 if fill != 0: 

146 newImage.set(fill) 

147 newImage.array[by, bx] = image.array[iy, ix] 

148 return newImage