changeset 1287:8e82fdc6200e bugs/2020-02-invisible-slice

Heavy (temporary) logging in the path that leads from multiframe volume to slice (rendered texture)
author Benjamin Golinvaux <bgo@osimis.io>
date Fri, 14 Feb 2020 15:00:54 +0100
parents ddb6676bbcbf
children d8c42e5e5843
files Framework/Scene2D/FloatTextureSceneLayer.cpp Framework/Scene2D/Internals/OpenGLLookupTableTextureRenderer.cpp Framework/Toolbox/DicomInstanceParameters.cpp Framework/Volumes/DicomVolumeImageMPRSlicer.cpp
diffstat 4 files changed, 169 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Scene2D/FloatTextureSceneLayer.cpp	Fri Feb 14 14:59:32 2020 +0100
+++ b/Framework/Scene2D/FloatTextureSceneLayer.cpp	Fri Feb 14 15:00:54 2020 +0100
@@ -21,6 +21,8 @@
 
 #include "FloatTextureSceneLayer.h"
 
+#include "../Toolbox/ImageToolbox.h"
+
 #include <Core/Images/Image.h>
 #include <Core/Images/ImageProcessing.h>
 #include <Core/OrthancException.h>
@@ -38,6 +40,30 @@
                            false));
 
       Orthanc::ImageProcessing::Convert(*t, texture);
+
+      if (OrthancStone_Internals_dump_LoadTexture_histogram == 1)
+      {
+        LOG(ERROR) << "+----------------------------------------+";
+        LOG(ERROR) << "|        This is not an error!           |";
+        LOG(ERROR) << "+----------------------------------------+";
+        LOG(ERROR) << "Work on the \"invisible slice\" bug";
+        LOG(ERROR) << "in FloatTextureSceneLayer::FloatTextureSceneLayer";
+        LOG(ERROR) << "will dump \"t\" after \"Orthanc::ImageProcessing::Convert(*t, texture);\"";
+
+        HistogramData hd;
+        double minValue = 0;
+        double maxValue = 0;
+        ComputeMinMax(*t, minValue, maxValue);
+        double binSize = (maxValue - minValue) * 0.01;
+        ComputeHistogram(*t, hd, binSize);
+        std::string s;
+        DumpHistogramResult(s, hd);
+        LOG(ERROR) << s;
+        LOG(ERROR) << "+----------------------------------------+";
+        LOG(ERROR) << "|        end of debug dump               |";
+        LOG(ERROR) << "+----------------------------------------+";
+      }
+
       SetTexture(t.release());
     }
 
--- a/Framework/Scene2D/Internals/OpenGLLookupTableTextureRenderer.cpp	Fri Feb 14 14:59:32 2020 +0100
+++ b/Framework/Scene2D/Internals/OpenGLLookupTableTextureRenderer.cpp	Fri Feb 14 15:00:54 2020 +0100
@@ -21,6 +21,9 @@
 
 #include "OpenGLLookupTableTextureRenderer.h"
 
+#include "../../Toolbox/ImageToolbox.h"
+
+
 #include <Core/OrthancException.h>
 
 
@@ -89,7 +92,6 @@
             }
           }
 
-
           for (unsigned int y = 0; y < height; y++)
           {
             const float* p = reinterpret_cast<const float*>(source.GetConstRow(y));
@@ -109,9 +111,10 @@
 
               uint8_t vv = static_cast<uint8_t>(v);
 
-              if(OrthancStone_Internals_dump_LoadTexture_histogram == 1)
+              if (OrthancStone_Internals_dump_LoadTexture_histogram == 1)
                 debugHistogram[vv] += 1;
 
+
               q[0] = lut[4 * vv + 0];  // R
               q[1] = lut[4 * vv + 1];  // G
               q[2] = lut[4 * vv + 2];  // B
@@ -124,21 +127,60 @@
 
           if (OrthancStone_Internals_dump_LoadTexture_histogram == 1)
           {
-            uint8_t vv;
-            LOG(INFO) << "Dumping texture loaded with OpenGLLookupTableTextureRenderer::LoadTexture";
-            for (int i = 0; i <= 255; ++i)
+            LOG(ERROR) << "+----------------------------------------+";
+            LOG(ERROR) << "|        This is not an error!           |";
+            LOG(ERROR) << "+----------------------------------------+";
+            LOG(ERROR) << "Work on the \"invisible slice\" bug";
+            LOG(ERROR) << "--> in OpenGLLookupTableTextureRenderer::LoadTexture():";
+            LOG(ERROR) << "layer.GetMinValue() = " << layer.GetMinValue() << " | layer.GetMaxValue() = " << layer.GetMaxValue();
+            LOG(ERROR) << "a = " << a << " | slope = " << slope;
+
+            LOG(ERROR) << "SOURCE gets scaled and offset, this yields --> TEMP that gets through the lut to yield RESULT";
+            LOG(ERROR) << "The SOURCE (layer.GetTexture()) will be dumped below (format is Float32)";
+            LOG(ERROR) << "";
+            HistogramData hd;
+            double minValue = 0;
+            double maxValue = 0;
+            ComputeMinMax(source, minValue, maxValue);
+            double binSize = (maxValue - minValue) * 0.01; // split in 100 bins
+            ComputeHistogram(source, hd, binSize);
+            std::string s;
+            DumpHistogramResult(s, hd);
+            LOG(ERROR) << s;
+            LOG(ERROR) << "";
+
+
+            LOG(ERROR) << "TEMP will be dumped below (format is uint8_t)";
+            LOG(ERROR) << "";
+
             {
-              vv = static_cast<uint8_t>(i);
-              int ivv = vv;
-              int count = debugHistogram[vv];
-              int lutr = lut[4 * vv + 0];
-              int lutg = lut[4 * vv + 1]; 
-              int lutb = lut[4 * vv + 2];
-              int luta = lut[4 * vv + 3];
+              uint8_t vv = 0;
+              do
+              {
+                LOG(ERROR) << "    TEMP. Pixel " << (int)vv << " is present "
+                  << debugHistogram[vv] << " times";
+              } while (vv++ != 255);
+            }
+
+            LOG(ERROR) << "\nThe LUT will be dumped below";
+            LOG(ERROR) << "----------------------------";
+            LOG(ERROR) << "";
 
-              LOG(ERROR) << "This is no error! Y= " << ivv << " count= " << count
-                << " lut R= " << lutr << " lut G= " << lutg << " lut B= " << lutb << " lut A= " << luta;
+            {
+              uint8_t vv = 0;
+              // proper way to loop on all unsigned values is a do while loop
+              do
+              {
+                LOG(ERROR) << "    LUT[" << (int)vv << "] ="
+                  << " R:" << (int)lut[4 * vv + 0]
+                  << " G:" << (int)lut[4 * vv + 1]
+                  << " B:" << (int)lut[4 * vv + 2]
+                  << " A:" << (int)lut[4 * vv + 3];
+              } while (vv++ != 255);
             }
+            LOG(ERROR) << "+----------------------------------------+";
+            LOG(ERROR) << "|        end of debug dump               |";
+            LOG(ERROR) << "+----------------------------------------+";
           }
         }
 
--- a/Framework/Toolbox/DicomInstanceParameters.cpp	Fri Feb 14 14:59:32 2020 +0100
+++ b/Framework/Toolbox/DicomInstanceParameters.cpp	Fri Feb 14 15:00:54 2020 +0100
@@ -24,6 +24,7 @@
 #include "../Scene2D/ColorTextureSceneLayer.h"
 #include "../Scene2D/FloatTextureSceneLayer.h"
 #include "../Toolbox/GeometryToolbox.h"
+#include "../Toolbox/ImageToolbox.h"
 
 #include <Core/Images/Image.h>
 #include <Core/Images/ImageProcessing.h>
@@ -281,6 +282,16 @@
       offset = rescaleIntercept_;
     }
 
+    if (OrthancStone_Internals_dump_LoadTexture_histogram == 1)
+    {
+      LOG(ERROR) << "in DicomInstanceParameters::Data::ApplyRescaleAndDoseScaling:";
+      LOG(ERROR) << "    doseGridScaling_ = " << doseGridScaling_ 
+        << " hasRescale_ = " << hasRescale_ 
+        << " rescaleSlope_ = " << rescaleSlope_ 
+        << " rescaleIntercept_ = " << rescaleIntercept_;
+      LOG(ERROR) << "    --> factor = " << factor << " offset = " << offset;
+    }
+
     if ( (factor != 1.0) || (offset != 0.0) )
     {
       const unsigned int width = image.GetWidth();
@@ -375,10 +386,57 @@
                                                                false));
     Orthanc::ImageProcessing::Convert(*converted, pixelData);
 
+    if (OrthancStone_Internals_dump_LoadTexture_histogram == 1)
+    {
+      LOG(ERROR) << "+----------------------------------------+";
+      LOG(ERROR) << "|        This is not an error!           |";
+      LOG(ERROR) << "+----------------------------------------+";
+      LOG(ERROR) << "Work on the \"invisible slice\" bug";
+      LOG(ERROR) << "in: DicomInstanceParameters::ConvertToFloat()";
+      LOG(ERROR) << "dumping texture hist after conversion from native sliceReader to Float32";
+      LOG(ERROR) << "(source buffer address before conversion is: " << pixelData.GetConstBuffer() << ")";
+      LOG(ERROR) << " target buffer address after conversion is: " << converted->GetConstBuffer();
+
+      LOG(ERROR) << "Target histo:";
+      LOG(ERROR) << "-------------";
+      {
+        HistogramData hd;
+        double minValue = 0;
+        double maxValue = 0;
+        ComputeMinMax(*converted, minValue, maxValue);
+        double binSize = (maxValue - minValue) * 0.01;
+        ComputeHistogram(*converted, hd, binSize);
+        std::string s;
+        DumpHistogramResult(s, hd);
+        LOG(ERROR) << s;
+      }
+    }
+                                                   
     // Correct rescale slope/intercept if need be
     //data_.ApplyRescaleAndDoseScaling(*converted, (pixelData.GetFormat() == Orthanc::PixelFormat_Grayscale32));
     data_.ApplyRescaleAndDoseScaling(*converted, false);
 
+    if (OrthancStone_Internals_dump_LoadTexture_histogram == 1)
+    {
+
+      LOG(ERROR) << "Target histo after data_.ApplyRescaleAndDoseScaling";
+      LOG(ERROR) << "---------------------------------------------------";
+      {
+        HistogramData hd;
+        double minValue = 0;
+        double maxValue = 0;
+        ComputeMinMax(*converted, minValue, maxValue);
+        double binSize = (maxValue - minValue) * 0.01;
+        ComputeHistogram(*converted, hd, binSize);
+        std::string s;
+        DumpHistogramResult(s, hd);
+        LOG(ERROR) << s;
+      }
+      LOG(ERROR) << "+----------------------------------------+";
+      LOG(ERROR) << "|        end of debug dump               |";
+      LOG(ERROR) << "+----------------------------------------+";
+    }
+
     return converted.release();
   }
 
--- a/Framework/Volumes/DicomVolumeImageMPRSlicer.cpp	Fri Feb 14 14:59:32 2020 +0100
+++ b/Framework/Volumes/DicomVolumeImageMPRSlicer.cpp	Fri Feb 14 15:00:54 2020 +0100
@@ -23,6 +23,8 @@
 
 #include "../StoneException.h"
 
+#include "../Toolbox/ImageToolbox.h"
+
 #include <Core/OrthancException.h>
 //#include <Core/Images/PngWriter.h>
 #include <Core/Images/JpegWriter.h>
@@ -80,6 +82,33 @@
     {
       const DicomInstanceParameters& parameters = volume_.GetDicomParameters();
       ImageBuffer3D::SliceReader reader(volume_.GetPixelData(), projection_, sliceIndex_);
+
+      if (OrthancStone_Internals_dump_LoadTexture_histogram == 1)
+      {
+        LOG(ERROR) << "+----------------------------------------+";
+        LOG(ERROR) << "|        This is not an error!           |";
+        LOG(ERROR) << "+----------------------------------------+";
+        LOG(ERROR) << "Work on the \"invisible slice\" bug";
+        LOG(ERROR) << "InvisibleSlice -- about to dump histogram (100 buckets) for volume_ "
+          << "with OrthancId: " << parameters.GetOrthancInstanceIdentifier()
+          << " and SopInstanceUid: " << parameters.GetSopInstanceUid()
+          << " for projection_ (AxiCorSag): projection_ "
+          << " and slice: " << sliceIndex_;
+
+        HistogramData hd;
+        double minValue = 0;
+        double maxValue = 0;
+        ComputeMinMax(reader.GetAccessor(), minValue, maxValue);
+        double binSize = (maxValue - minValue) * 0.01;
+        ComputeHistogram(reader.GetAccessor(), hd, binSize);
+        std::string s;
+        DumpHistogramResult(s, hd);
+        LOG(ERROR) << s;
+        LOG(ERROR) << "+----------------------------------------+";
+        LOG(ERROR) << "|        end of debug dump               |";
+        LOG(ERROR) << "+----------------------------------------+";
+      }
+
       texture.reset(dynamic_cast<TextureBaseSceneLayer*>
                     (configurator->CreateTextureFromDicom(reader.GetAccessor(), parameters)));