Mercurial > hg > orthanc-stone
annotate OrthancStone/Sources/Toolbox/SubpixelReader.h @ 2105:ca376147db15 dicom-sr
integration mainline->dicom-sr
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 22 Nov 2023 07:43:50 +0100 |
parents | 07964689cb0b |
children | c23eef785569 |
rev | line source |
---|---|
182 | 1 /** |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
2077
07964689cb0b
upgrade to year 2023
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1871
diff
changeset
|
5 * Copyright (C) 2017-2023 Osimis S.A., Belgium |
07964689cb0b
upgrade to year 2023
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1871
diff
changeset
|
6 * Copyright (C) 2021-2023 Sebastien Jodogne, ICTEAM UCLouvain, Belgium |
182 | 7 * |
8 * This program is free software: you can redistribute it and/or | |
1598
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
9 * modify it under the terms of the GNU Lesser General Public License |
182 | 10 * as published by the Free Software Foundation, either version 3 of |
11 * the License, or (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, but | |
14 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
1598
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
16 * Lesser General Public License for more details. |
1596
4fb8fdf03314
removed annoying whitespace
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1571
diff
changeset
|
17 * |
1598
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
18 * You should have received a copy of the GNU Lesser General Public |
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
19 * License along with this program. If not, see |
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
20 * <http://www.gnu.org/licenses/>. |
182 | 21 **/ |
22 | |
23 | |
24 #pragma once | |
25 | |
194
7a031ac16b2d
rename Enumerations.h to StoneEnumerations.h to avoid clashes with Orthanc
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
183
diff
changeset
|
26 #include "../StoneEnumerations.h" |
182 | 27 #include "GeometryToolbox.h" |
28 | |
1455
30deba7bc8e2
simplifying include_directories
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1270
diff
changeset
|
29 #include <Images/ImageTraits.h> |
182 | 30 |
31 #include <boost/noncopyable.hpp> | |
32 #include <cmath> | |
33 | |
34 namespace OrthancStone | |
35 { | |
36 namespace Internals | |
37 { | |
38 class SubpixelReaderBase : public boost::noncopyable | |
39 { | |
40 private: | |
41 const Orthanc::ImageAccessor& source_; | |
42 unsigned int width_; | |
43 unsigned int height_; | |
44 | |
45 public: | |
1571 | 46 explicit SubpixelReaderBase(const Orthanc::ImageAccessor& source) : |
182 | 47 source_(source), |
48 width_(source.GetWidth()), | |
49 height_(source.GetHeight()) | |
50 { | |
51 } | |
52 | |
53 ORTHANC_FORCE_INLINE | |
54 const Orthanc::ImageAccessor& GetSource() const | |
55 { | |
56 return source_; | |
57 } | |
58 | |
59 ORTHANC_FORCE_INLINE | |
60 unsigned int GetWidth() const | |
61 { | |
62 return width_; | |
63 } | |
64 | |
65 ORTHANC_FORCE_INLINE | |
66 unsigned int GetHeight() const | |
67 { | |
68 return height_; | |
69 } | |
70 }; | |
71 } | |
72 | |
73 | |
74 template <Orthanc::PixelFormat Format, | |
75 ImageInterpolation Interpolation> | |
76 class SubpixelReader; | |
77 | |
78 | |
79 template <Orthanc::PixelFormat Format> | |
80 class SubpixelReader<Format, ImageInterpolation_Nearest> : | |
81 public Internals::SubpixelReaderBase | |
82 { | |
83 public: | |
84 typedef Orthanc::PixelTraits<Format> Traits; | |
85 typedef typename Traits::PixelType PixelType; | |
86 | |
1571 | 87 explicit SubpixelReader(const Orthanc::ImageAccessor& source) : |
182 | 88 SubpixelReaderBase(source) |
89 { | |
90 } | |
91 | |
92 inline bool GetValue(PixelType& target, | |
93 float x, | |
94 float y) const; | |
183 | 95 |
96 inline bool GetFloatValue(float& target, | |
97 float x, | |
98 float y) const; | |
182 | 99 }; |
183 | 100 |
182 | 101 |
102 | |
103 template <Orthanc::PixelFormat Format> | |
104 class SubpixelReader<Format, ImageInterpolation_Bilinear> : | |
105 public Internals::SubpixelReaderBase | |
106 { | |
107 public: | |
108 typedef Orthanc::PixelTraits<Format> Traits; | |
109 typedef typename Traits::PixelType PixelType; | |
110 | |
1571 | 111 explicit SubpixelReader(const Orthanc::ImageAccessor& source) : |
182 | 112 SubpixelReaderBase(source) |
113 { | |
114 } | |
115 | |
183 | 116 inline bool GetFloatValue(float& target, |
117 float x, | |
118 float y) const; | |
119 | |
182 | 120 inline bool GetValue(PixelType& target, |
121 float x, | |
183 | 122 float y) const; |
182 | 123 }; |
124 | |
125 | |
126 | |
127 template <Orthanc::PixelFormat Format> | |
128 bool SubpixelReader<Format, ImageInterpolation_Nearest>::GetValue(PixelType& target, | |
129 float x, | |
130 float y) const | |
131 { | |
132 if (x < 0 || | |
133 y < 0) | |
134 { | |
135 return false; | |
136 } | |
137 else | |
138 { | |
139 unsigned int ux = static_cast<unsigned int>(std::floor(x)); | |
140 unsigned int uy = static_cast<unsigned int>(std::floor(y)); | |
141 | |
142 if (ux < GetWidth() && | |
143 uy < GetHeight()) | |
144 { | |
145 Orthanc::ImageTraits<Format>::GetPixel(target, GetSource(), ux, uy); | |
146 return true; | |
147 } | |
148 else | |
149 { | |
150 return false; | |
151 } | |
152 } | |
153 } | |
154 | |
155 | |
156 | |
157 template <Orthanc::PixelFormat Format> | |
183 | 158 bool SubpixelReader<Format, ImageInterpolation_Nearest>::GetFloatValue(float& target, |
159 float x, | |
160 float y) const | |
161 { | |
162 PixelType value; | |
163 | |
164 if (GetValue(value, x, y)) | |
165 { | |
166 target = Traits::PixelToFloat(value); | |
167 return true; | |
168 } | |
169 else | |
170 { | |
171 return false; | |
172 } | |
173 } | |
174 | |
175 | |
176 | |
177 template <Orthanc::PixelFormat Format> | |
182 | 178 bool SubpixelReader<Format, ImageInterpolation_Bilinear>::GetValue(PixelType& target, |
179 float x, | |
183 | 180 float y) const |
181 { | |
182 float value; | |
183 | |
184 if (GetFloatValue(value, x, y)) | |
185 { | |
186 Traits::FloatToPixel(target, value); | |
187 return true; | |
188 } | |
189 else | |
190 { | |
191 return false; | |
192 } | |
193 } | |
194 | |
195 | |
196 | |
197 template <Orthanc::PixelFormat Format> | |
198 bool SubpixelReader<Format, ImageInterpolation_Bilinear>::GetFloatValue(float& target, | |
199 float x, | |
200 float y) const | |
182 | 201 { |
202 x -= 0.5f; | |
203 y -= 0.5f; | |
204 | |
205 if (x < 0 || | |
206 y < 0) | |
207 { | |
208 return false; | |
209 } | |
210 else | |
211 { | |
212 unsigned int ux = static_cast<unsigned int>(std::floor(x)); | |
213 unsigned int uy = static_cast<unsigned int>(std::floor(y)); | |
214 | |
215 float f00, f01, f10, f11; | |
216 | |
217 if (ux < GetWidth() && | |
218 uy < GetHeight()) | |
219 { | |
220 f00 = Orthanc::ImageTraits<Format>::GetFloatPixel(GetSource(), ux, uy); | |
221 } | |
222 else | |
223 { | |
224 return false; | |
225 } | |
226 | |
227 if (ux + 1 < GetWidth()) | |
228 { | |
229 f01 = Orthanc::ImageTraits<Format>::GetFloatPixel(GetSource(), ux + 1, uy); | |
230 } | |
231 else | |
232 { | |
233 f01 = f00; | |
234 } | |
235 | |
236 if (uy + 1 < GetHeight()) | |
237 { | |
238 f10 = Orthanc::ImageTraits<Format>::GetFloatPixel(GetSource(), ux, uy + 1); | |
239 } | |
240 else | |
241 { | |
242 f10 = f00; | |
243 } | |
244 | |
245 if (ux + 1 < GetWidth() && | |
246 uy + 1 < GetHeight()) | |
247 { | |
248 f11 = Orthanc::ImageTraits<Format>::GetFloatPixel(GetSource(), ux + 1, uy + 1); | |
249 } | |
250 else | |
251 { | |
252 f11 = f00; | |
253 } | |
254 | |
255 float ax = x - static_cast<float>(ux); | |
256 float ay = y - static_cast<float>(uy); | |
183 | 257 target = GeometryToolbox::ComputeBilinearInterpolationUnitSquare(ax, ay, f00, f01, f10, f11); |
182 | 258 |
259 return true; | |
260 } | |
261 } | |
262 } |