comparison UnitTestsSources/VolumeRenderingTests.cpp @ 1783:75d3e2ab1fe1

BREAKING: SubvoxelReader using the same Z-axis ordering as ImageBuffer3D
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 14 May 2021 18:30:24 +0200
parents f053c80ea411
children 42a2880d690f
comparison
equal deleted inserted replaced
1782:f053c80ea411 1783:75d3e2ab1fe1
20 20
21 21
22 #include "../OrthancStone/Sources/Scene2D/CairoCompositor.h" 22 #include "../OrthancStone/Sources/Scene2D/CairoCompositor.h"
23 #include "../OrthancStone/Sources/Scene2D/ColorTextureSceneLayer.h" 23 #include "../OrthancStone/Sources/Scene2D/ColorTextureSceneLayer.h"
24 #include "../OrthancStone/Sources/Scene2D/CopyStyleConfigurator.h" 24 #include "../OrthancStone/Sources/Scene2D/CopyStyleConfigurator.h"
25 #include "../OrthancStone/Sources/Toolbox/SubvoxelReader.h"
25 #include "../OrthancStone/Sources/Volumes/DicomVolumeImageMPRSlicer.h" 26 #include "../OrthancStone/Sources/Volumes/DicomVolumeImageMPRSlicer.h"
26 #include "../OrthancStone/Sources/Volumes/DicomVolumeImageReslicer.h" 27 #include "../OrthancStone/Sources/Volumes/DicomVolumeImageReslicer.h"
27 28
28 #include <Images/ImageProcessing.h> 29 #include <Images/ImageProcessing.h>
29 #include <Images/ImageTraits.h> 30 #include <Images/ImageTraits.h>
30 #include <OrthancException.h> 31 #include <OrthancException.h>
31 32
32 #include <gtest/gtest.h> 33 #include <gtest/gtest.h>
34
33 35
34 36
35 static float GetPixelValue(const Orthanc::ImageAccessor& image, 37 static float GetPixelValue(const Orthanc::ImageAccessor& image,
36 unsigned int x, 38 unsigned int x,
37 unsigned int y) 39 unsigned int y)
293 { 295 {
294 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); 296 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
295 } 297 }
296 298
297 return SliceVolume(volume, volumeCoordinates, cuttingPlane, type); 299 return SliceVolume(volume, volumeCoordinates, cuttingPlane, type);
300 }
301
302
303 TEST(VolumeRendering, Pattern)
304 {
305 {
306 // Axial
307 OrthancStone::ImageBuffer3D image(Orthanc::PixelFormat_Grayscale8, 3, 3, 1, true);
308
309 {
310 OrthancStone::ImageBuffer3D::SliceWriter writer(image, OrthancStone::VolumeProjection_Axial, 0);
311 Assign3x3Pattern(writer.GetAccessor());
312 }
313
314 float a, b;
315 ASSERT_TRUE(image.GetRange(a, b));
316 ASSERT_FLOAT_EQ(0, a);
317 ASSERT_FLOAT_EQ(200, b);
318
319 ASSERT_EQ(0, image.GetVoxelGrayscale8(0, 0, 0));
320 ASSERT_EQ(25, image.GetVoxelGrayscale8(1, 0, 0));
321 ASSERT_EQ(50, image.GetVoxelGrayscale8(2, 0, 0));
322 ASSERT_EQ(75, image.GetVoxelGrayscale8(0, 1, 0));
323 ASSERT_EQ(100, image.GetVoxelGrayscale8(1, 1, 0));
324 ASSERT_EQ(125, image.GetVoxelGrayscale8(2, 1, 0));
325 ASSERT_EQ(150, image.GetVoxelGrayscale8(0, 2, 0));
326 ASSERT_EQ(175, image.GetVoxelGrayscale8(1, 2, 0));
327 ASSERT_EQ(200, image.GetVoxelGrayscale8(2, 2, 0));
328
329 float v;
330 OrthancStone::SubvoxelReader<Orthanc::PixelFormat_Grayscale8,
331 OrthancStone::ImageInterpolation_Nearest> reader(image);
332
333 ASSERT_TRUE(reader.GetFloatValue(v, 0.01, 0.01, 0.01)); ASSERT_FLOAT_EQ(0, v);
334 ASSERT_TRUE(reader.GetFloatValue(v, 1.01, 0.01, 0.01)); ASSERT_FLOAT_EQ(25, v);
335 ASSERT_TRUE(reader.GetFloatValue(v, 2.01, 0.01, 0.01)); ASSERT_FLOAT_EQ(50, v);
336 ASSERT_TRUE(reader.GetFloatValue(v, 0.01, 1.01, 0.01)); ASSERT_FLOAT_EQ(75, v);
337 ASSERT_TRUE(reader.GetFloatValue(v, 1.01, 1.01, 0.01)); ASSERT_FLOAT_EQ(100, v);
338 ASSERT_TRUE(reader.GetFloatValue(v, 2.01, 1.01, 0.01)); ASSERT_FLOAT_EQ(125, v);
339 ASSERT_TRUE(reader.GetFloatValue(v, 0.01, 2.01, 0.01)); ASSERT_FLOAT_EQ(150, v);
340 ASSERT_TRUE(reader.GetFloatValue(v, 1.01, 2.01, 0.01)); ASSERT_FLOAT_EQ(175, v);
341 ASSERT_TRUE(reader.GetFloatValue(v, 2.01, 2.01, 0.01)); ASSERT_FLOAT_EQ(200, v);
342
343 ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 0.99, 0.99)); ASSERT_FLOAT_EQ(0, v);
344 ASSERT_TRUE(reader.GetFloatValue(v, 1.99, 0.99, 0.99)); ASSERT_FLOAT_EQ(25, v);
345 ASSERT_TRUE(reader.GetFloatValue(v, 2.99, 0.99, 0.99)); ASSERT_FLOAT_EQ(50, v);
346 ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 1.99, 0.99)); ASSERT_FLOAT_EQ(75, v);
347 ASSERT_TRUE(reader.GetFloatValue(v, 1.99, 1.99, 0.99)); ASSERT_FLOAT_EQ(100, v);
348 ASSERT_TRUE(reader.GetFloatValue(v, 2.99, 1.99, 0.99)); ASSERT_FLOAT_EQ(125, v);
349 ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 2.99, 0.99)); ASSERT_FLOAT_EQ(150, v);
350 ASSERT_TRUE(reader.GetFloatValue(v, 1.99, 2.99, 0.99)); ASSERT_FLOAT_EQ(175, v);
351 ASSERT_TRUE(reader.GetFloatValue(v, 2.99, 2.99, 0.99)); ASSERT_FLOAT_EQ(200, v);
352 }
353
354 {
355 // Coronal
356 OrthancStone::ImageBuffer3D image(Orthanc::PixelFormat_Grayscale8, 3, 1, 3, true);
357
358 {
359 OrthancStone::ImageBuffer3D::SliceWriter writer(image, OrthancStone::VolumeProjection_Coronal, 0);
360 Assign3x3Pattern(writer.GetAccessor());
361 }
362
363 float a, b;
364 ASSERT_TRUE(image.GetRange(a, b));
365 ASSERT_FLOAT_EQ(0, a);
366 ASSERT_FLOAT_EQ(200, b);
367
368 // "Z" is in reverse order in "Assign3x3Pattern()", because important note in "ImageBuffer3D"
369 ASSERT_EQ(0, image.GetVoxelGrayscale8(0, 0, 2));
370 ASSERT_EQ(25, image.GetVoxelGrayscale8(1, 0, 2));
371 ASSERT_EQ(50, image.GetVoxelGrayscale8(2, 0, 2));
372 ASSERT_EQ(75, image.GetVoxelGrayscale8(0, 0, 1));
373 ASSERT_EQ(100, image.GetVoxelGrayscale8(1, 0, 1));
374 ASSERT_EQ(125, image.GetVoxelGrayscale8(2, 0, 1));
375 ASSERT_EQ(150, image.GetVoxelGrayscale8(0, 0, 0));
376 ASSERT_EQ(175, image.GetVoxelGrayscale8(1, 0, 0));
377 ASSERT_EQ(200, image.GetVoxelGrayscale8(2, 0, 0));
378
379 // Ensure that "SubvoxelReader" is consistent with "image.GetVoxelGrayscale8()"
380 float v;
381 OrthancStone::SubvoxelReader<Orthanc::PixelFormat_Grayscale8,
382 OrthancStone::ImageInterpolation_Nearest> reader(image);
383
384 ASSERT_TRUE(reader.GetFloatValue(v, 0.01, 0.01, 2.01)); ASSERT_FLOAT_EQ(0, v);
385 ASSERT_TRUE(reader.GetFloatValue(v, 1.01, 0.01, 2.01)); ASSERT_FLOAT_EQ(25, v);
386 ASSERT_TRUE(reader.GetFloatValue(v, 2.01, 0.01, 2.01)); ASSERT_FLOAT_EQ(50, v);
387 ASSERT_TRUE(reader.GetFloatValue(v, 0.01, 0.01, 1.01)); ASSERT_FLOAT_EQ(75, v);
388 ASSERT_TRUE(reader.GetFloatValue(v, 1.01, 0.01, 1.01)); ASSERT_FLOAT_EQ(100, v);
389 ASSERT_TRUE(reader.GetFloatValue(v, 2.01, 0.01, 1.01)); ASSERT_FLOAT_EQ(125, v);
390 ASSERT_TRUE(reader.GetFloatValue(v, 0.01, 0.01, 0.01)); ASSERT_FLOAT_EQ(150, v);
391 ASSERT_TRUE(reader.GetFloatValue(v, 1.01, 0.01, 0.01)); ASSERT_FLOAT_EQ(175, v);
392 ASSERT_TRUE(reader.GetFloatValue(v, 2.01, 0.01, 0.01)); ASSERT_FLOAT_EQ(200, v);
393
394 ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 0.99, 2.99)); ASSERT_FLOAT_EQ(0, v);
395 ASSERT_TRUE(reader.GetFloatValue(v, 1.99, 0.99, 2.99)); ASSERT_FLOAT_EQ(25, v);
396 ASSERT_TRUE(reader.GetFloatValue(v, 2.99, 0.99, 2.99)); ASSERT_FLOAT_EQ(50, v);
397 ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 0.99, 1.99)); ASSERT_FLOAT_EQ(75, v);
398 ASSERT_TRUE(reader.GetFloatValue(v, 1.99, 0.99, 1.99)); ASSERT_FLOAT_EQ(100, v);
399 ASSERT_TRUE(reader.GetFloatValue(v, 2.99, 0.99, 1.99)); ASSERT_FLOAT_EQ(125, v);
400 ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 0.99, 0.99)); ASSERT_FLOAT_EQ(150, v);
401 ASSERT_TRUE(reader.GetFloatValue(v, 1.99, 0.99, 0.99)); ASSERT_FLOAT_EQ(175, v);
402 ASSERT_TRUE(reader.GetFloatValue(v, 2.99, 0.99, 0.99)); ASSERT_FLOAT_EQ(200, v);
403 }
404
405 {
406 // Sagittal
407 OrthancStone::ImageBuffer3D image(Orthanc::PixelFormat_Grayscale8, 1, 3, 3, true);
408
409 {
410 OrthancStone::ImageBuffer3D::SliceWriter writer(image, OrthancStone::VolumeProjection_Sagittal, 0);
411 Assign3x3Pattern(writer.GetAccessor());
412 }
413
414 float a, b;
415 ASSERT_TRUE(image.GetRange(a, b));
416 ASSERT_FLOAT_EQ(0, a);
417 ASSERT_FLOAT_EQ(200, b);
418
419 // "Z" is in reverse order in "Assign3x3Pattern()", because important note in "ImageBuffer3D"
420 ASSERT_EQ(0, image.GetVoxelGrayscale8(0, 0, 2));
421 ASSERT_EQ(25, image.GetVoxelGrayscale8(0, 1, 2));
422 ASSERT_EQ(50, image.GetVoxelGrayscale8(0, 2, 2));
423 ASSERT_EQ(75, image.GetVoxelGrayscale8(0, 0, 1));
424 ASSERT_EQ(100, image.GetVoxelGrayscale8(0, 1, 1));
425 ASSERT_EQ(125, image.GetVoxelGrayscale8(0, 2, 1));
426 ASSERT_EQ(150, image.GetVoxelGrayscale8(0, 0, 0));
427 ASSERT_EQ(175, image.GetVoxelGrayscale8(0, 1, 0));
428 ASSERT_EQ(200, image.GetVoxelGrayscale8(0, 2, 0));
429
430 // Ensure that "SubvoxelReader" is consistent with "image.GetVoxelGrayscale8()"
431 float v;
432 OrthancStone::SubvoxelReader<Orthanc::PixelFormat_Grayscale8,
433 OrthancStone::ImageInterpolation_Nearest> reader(image);
434
435 ASSERT_TRUE(reader.GetFloatValue(v, 0.1, 0.01, 2.01)); ASSERT_FLOAT_EQ(0, v);
436 ASSERT_TRUE(reader.GetFloatValue(v, 0.1, 1.01, 2.01)); ASSERT_FLOAT_EQ(25, v);
437 ASSERT_TRUE(reader.GetFloatValue(v, 0.1, 2.01, 2.01)); ASSERT_FLOAT_EQ(50, v);
438 ASSERT_TRUE(reader.GetFloatValue(v, 0.1, 0.01, 1.01)); ASSERT_FLOAT_EQ(75, v);
439 ASSERT_TRUE(reader.GetFloatValue(v, 0.1, 1.01, 1.01)); ASSERT_FLOAT_EQ(100, v);
440 ASSERT_TRUE(reader.GetFloatValue(v, 0.1, 2.01, 1.01)); ASSERT_FLOAT_EQ(125, v);
441 ASSERT_TRUE(reader.GetFloatValue(v, 0.1, 0.01, 0.01)); ASSERT_FLOAT_EQ(150, v);
442 ASSERT_TRUE(reader.GetFloatValue(v, 0.1, 1.01, 0.01)); ASSERT_FLOAT_EQ(175, v);
443 ASSERT_TRUE(reader.GetFloatValue(v, 0.1, 2.01, 0.01)); ASSERT_FLOAT_EQ(200, v);
444
445 ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 0.99, 2.99)); ASSERT_FLOAT_EQ(0, v);
446 ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 1.99, 2.99)); ASSERT_FLOAT_EQ(25, v);
447 ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 2.99, 2.99)); ASSERT_FLOAT_EQ(50, v);
448 ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 0.99, 1.99)); ASSERT_FLOAT_EQ(75, v);
449 ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 1.99, 1.99)); ASSERT_FLOAT_EQ(100, v);
450 ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 2.99, 1.99)); ASSERT_FLOAT_EQ(125, v);
451 ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 0.99, 0.99)); ASSERT_FLOAT_EQ(150, v);
452 ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 1.99, 0.99)); ASSERT_FLOAT_EQ(175, v);
453 ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 2.99, 0.99)); ASSERT_FLOAT_EQ(200, v);
454 }
298 } 455 }
299 456
300 457
301 TEST(VolumeRendering, Axial) 458 TEST(VolumeRendering, Axial)
302 { 459 {