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