comparison UnitTestsSources/VolumeRenderingTests.cpp @ 1779:9ab251c03eda

unit test VolumeRendering.TextureCorners
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 14 May 2021 10:01:20 +0200
parents de5c965f0697
children b7c9fd1e9fb0
comparison
equal deleted inserted replaced
1778:de5c965f0697 1779:9ab251c03eda
23 #include "../OrthancStone/Sources/Scene2D/CopyStyleConfigurator.h" 23 #include "../OrthancStone/Sources/Scene2D/CopyStyleConfigurator.h"
24 #include "../OrthancStone/Sources/Scene2D/ColorTextureSceneLayer.h" 24 #include "../OrthancStone/Sources/Scene2D/ColorTextureSceneLayer.h"
25 #include "../OrthancStone/Sources/Volumes/DicomVolumeImageMPRSlicer.h" 25 #include "../OrthancStone/Sources/Volumes/DicomVolumeImageMPRSlicer.h"
26 #include "../OrthancStone/Sources/Volumes/DicomVolumeImageReslicer.h" 26 #include "../OrthancStone/Sources/Volumes/DicomVolumeImageReslicer.h"
27 27
28 #include <Images/ImageProcessing.h>
28 #include <Images/ImageTraits.h> 29 #include <Images/ImageTraits.h>
29 #include <OrthancException.h> 30 #include <OrthancException.h>
30 31
31 #include <gtest/gtest.h> 32 #include <gtest/gtest.h>
32 33
90 { 91 {
91 Orthanc::ImageAccessor region; 92 Orthanc::ImageAccessor region;
92 image.GetRegion(region, x, y, width, height); 93 image.GetRegion(region, x, y, width, height);
93 return IsConstImage(value, region); 94 return IsConstImage(value, region);
94 } 95 }
96
97
98 static void Assign3x3Pattern(Orthanc::ImageAccessor& image)
99 {
100 if (image.GetFormat() == Orthanc::PixelFormat_Grayscale8 &&
101 image.GetWidth() == 3 &&
102 image.GetHeight() == 3)
103 {
104 unsigned int v = 0;
105 for (unsigned int y = 0; y < image.GetHeight(); y++)
106 {
107 uint8_t *p = reinterpret_cast<uint8_t*>(image.GetRow(y));
108 for (unsigned int x = 0; x < image.GetWidth(); x++, p++)
109 {
110 *p = v;
111 v += 25;
112 }
113 }
114 }
115 else
116 {
117 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
118 }
119 }
95 120
96 121
97 TEST(VolumeRendering, Axial) 122 TEST(VolumeRendering, Axial)
98 { 123 {
99 Orthanc::DicomMap dicom; 124 Orthanc::DicomMap dicom;
113 volume->Initialize(geometry, Orthanc::PixelFormat_Grayscale8, false); 138 volume->Initialize(geometry, Orthanc::PixelFormat_Grayscale8, false);
114 volume->SetDicomParameters(OrthancStone::DicomInstanceParameters(dicom)); 139 volume->SetDicomParameters(OrthancStone::DicomInstanceParameters(dicom));
115 140
116 { 141 {
117 OrthancStone::ImageBuffer3D::SliceWriter writer(volume->GetPixelData(), OrthancStone::VolumeProjection_Axial, 0); 142 OrthancStone::ImageBuffer3D::SliceWriter writer(volume->GetPixelData(), OrthancStone::VolumeProjection_Axial, 0);
118 unsigned int v = 0; 143 Assign3x3Pattern(writer.GetAccessor());
119 for (unsigned int y = 0; y < writer.GetAccessor().GetHeight(); y++)
120 {
121 uint8_t *p = reinterpret_cast<uint8_t*>(writer.GetAccessor().GetRow(y));
122 for (unsigned int x = 0; x < writer.GetAccessor().GetWidth(); x++, p++)
123 {
124 *p = v;
125 v += 25;
126 }
127 }
128 } 144 }
129 145
130 OrthancStone::Vector v = volume->GetGeometry().GetVoxelDimensions(OrthancStone::VolumeProjection_Axial); 146 OrthancStone::Vector v = volume->GetGeometry().GetVoxelDimensions(OrthancStone::VolumeProjection_Axial);
131 ASSERT_FLOAT_EQ(1, v[0]); 147 ASSERT_FLOAT_EQ(1, v[0]);
132 ASSERT_FLOAT_EQ(1, v[1]); 148 ASSERT_FLOAT_EQ(1, v[1]);
186 Orthanc::ImageAccessor rendered; 202 Orthanc::ImageAccessor rendered;
187 compositor.GetCanvas().GetReadOnlyAccessor(rendered); 203 compositor.GetCanvas().GetReadOnlyAccessor(rendered);
188 204
189 ASSERT_EQ(5u, rendered.GetWidth()); 205 ASSERT_EQ(5u, rendered.GetWidth());
190 ASSERT_EQ(5u, rendered.GetHeight()); 206 ASSERT_EQ(5u, rendered.GetHeight());
191 ASSERT_EQ(0, GetPixelValue(rendered, 0, 0)); 207 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 0, 0));
192 ASSERT_EQ(0, GetPixelValue(rendered, 1, 0)); 208 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 1, 0));
193 ASSERT_EQ(0, GetPixelValue(rendered, 2, 0)); 209 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 2, 0));
194 ASSERT_EQ(0, GetPixelValue(rendered, 3, 0)); 210 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 3, 0));
195 ASSERT_EQ(0, GetPixelValue(rendered, 4, 0)); 211 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 4, 0));
196 ASSERT_EQ(0, GetPixelValue(rendered, 0, 1)); 212 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 0, 1));
197 ASSERT_EQ(0, GetPixelValue(rendered, 1, 1)); 213 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 1, 1));
198 ASSERT_EQ(0, GetPixelValue(rendered, 2, 1)); 214 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 2, 1));
199 ASSERT_EQ(0, GetPixelValue(rendered, 3, 1)); 215 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 3, 1));
200 ASSERT_EQ(0, GetPixelValue(rendered, 4, 1)); 216 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 4, 1));
201 ASSERT_EQ(0, GetPixelValue(rendered, 0, 2)); 217 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 0, 2));
202 ASSERT_EQ(0, GetPixelValue(rendered, 1, 2)); 218 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 1, 2));
203 ASSERT_EQ(0, GetPixelValue(rendered, 2, 2)); 219 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 2, 2));
204 ASSERT_EQ(25, GetPixelValue(rendered, 3, 2)); 220 ASSERT_FLOAT_EQ(25, GetPixelValue(rendered, 3, 2));
205 ASSERT_EQ(50, GetPixelValue(rendered, 4, 2)); 221 ASSERT_FLOAT_EQ(50, GetPixelValue(rendered, 4, 2));
206 ASSERT_EQ(0, GetPixelValue(rendered, 0, 3)); 222 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 0, 3));
207 ASSERT_EQ(0, GetPixelValue(rendered, 1, 3)); 223 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 1, 3));
208 ASSERT_EQ(75, GetPixelValue(rendered, 2, 3)); 224 ASSERT_FLOAT_EQ(75, GetPixelValue(rendered, 2, 3));
209 ASSERT_EQ(100, GetPixelValue(rendered, 3, 3)); 225 ASSERT_FLOAT_EQ(100, GetPixelValue(rendered, 3, 3));
210 ASSERT_EQ(125, GetPixelValue(rendered, 4, 3)); 226 ASSERT_FLOAT_EQ(125, GetPixelValue(rendered, 4, 3));
211 ASSERT_EQ(0, GetPixelValue(rendered, 0, 4)); 227 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 0, 4));
212 ASSERT_EQ(0, GetPixelValue(rendered, 1, 4)); 228 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 1, 4));
213 ASSERT_EQ(150, GetPixelValue(rendered, 2, 4)); 229 ASSERT_FLOAT_EQ(150, GetPixelValue(rendered, 2, 4));
214 ASSERT_EQ(175, GetPixelValue(rendered, 3, 4)); 230 ASSERT_FLOAT_EQ(175, GetPixelValue(rendered, 3, 4));
215 ASSERT_EQ(200, GetPixelValue(rendered, 4, 4)); 231 ASSERT_FLOAT_EQ(200, GetPixelValue(rendered, 4, 4));
216 } 232 }
217 } 233 }
234
235
236
237 TEST(VolumeRendering, TextureCorners)
238 {
239 // The origin of a 2D texture is the coordinate of the BORDER of the
240 // top-left pixel, *not* the center of the top-left pixel (as in
241 // DICOM 3D convention)
242
243 Orthanc::Image pixel(Orthanc::PixelFormat_RGB24, 1, 1, false);
244 Orthanc::ImageProcessing::Set(pixel, 255, 0, 0, 255);
245
246 {
247 std::unique_ptr<OrthancStone::ColorTextureSceneLayer> layer(new OrthancStone::ColorTextureSceneLayer(pixel));
248 layer->SetOrigin(0, 0);
249
250 OrthancStone::Scene2D scene;
251 scene.SetLayer(0, layer.release());
252
253 OrthancStone::CairoCompositor compositor(2, 2);
254 compositor.Refresh(scene);
255
256 Orthanc::ImageAccessor rendered;
257 compositor.GetCanvas().GetReadOnlyAccessor(rendered);
258
259 ASSERT_EQ(2u, rendered.GetWidth());
260 ASSERT_EQ(2u, rendered.GetHeight());
261
262 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 0, 0));
263 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 1, 0));
264 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 0, 1));
265 ASSERT_FLOAT_EQ(255, GetPixelValue(rendered, 1, 1));
266 }
267
268 {
269 std::unique_ptr<OrthancStone::ColorTextureSceneLayer> layer(new OrthancStone::ColorTextureSceneLayer(pixel));
270 layer->SetOrigin(-0.01, 0);
271
272 OrthancStone::Scene2D scene;
273 scene.SetLayer(0, layer.release());
274
275 OrthancStone::CairoCompositor compositor(2, 2);
276 compositor.Refresh(scene);
277
278 Orthanc::ImageAccessor rendered;
279 compositor.GetCanvas().GetReadOnlyAccessor(rendered);
280 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 0, 0));
281 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 1, 0));
282 ASSERT_FLOAT_EQ(255, GetPixelValue(rendered, 0, 1));
283 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 1, 1));
284 }
285
286 {
287 std::unique_ptr<OrthancStone::ColorTextureSceneLayer> layer(new OrthancStone::ColorTextureSceneLayer(pixel));
288 layer->SetOrigin(-0.01, -0.01);
289
290 OrthancStone::Scene2D scene;
291 scene.SetLayer(0, layer.release());
292
293 OrthancStone::CairoCompositor compositor(2, 2);
294 compositor.Refresh(scene);
295
296 Orthanc::ImageAccessor rendered;
297 compositor.GetCanvas().GetReadOnlyAccessor(rendered);
298 ASSERT_FLOAT_EQ(255, GetPixelValue(rendered, 0, 0));
299 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 1, 0));
300 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 0, 1));
301 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 1, 1));
302 }
303
304 {
305 std::unique_ptr<OrthancStone::ColorTextureSceneLayer> layer(new OrthancStone::ColorTextureSceneLayer(pixel));
306 layer->SetOrigin(0, -0.01);
307
308 OrthancStone::Scene2D scene;
309 scene.SetLayer(0, layer.release());
310
311 OrthancStone::CairoCompositor compositor(2, 2);
312 compositor.Refresh(scene);
313
314 Orthanc::ImageAccessor rendered;
315 compositor.GetCanvas().GetReadOnlyAccessor(rendered);
316 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 0, 0));
317 ASSERT_FLOAT_EQ(255, GetPixelValue(rendered, 1, 0));
318 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 0, 1));
319 ASSERT_FLOAT_EQ(0, GetPixelValue(rendered, 1, 1));
320 }
321 }