changeset 488:aede9b042cb7 am-touch-events

now using ImageProcessing::FillPolygon
author am@osimis.io
date Tue, 19 Feb 2019 11:40:14 +0100
parents e4febcef669e
children 64d90190a08c
files Applications/Samples/SingleFrameEditorApplication.h Framework/Radiography/RadiographyLayerMaskTracker.cpp Framework/Radiography/RadiographyMaskLayer.cpp Framework/Radiography/RadiographyMaskLayer.h Framework/Radiography/RadiographyScene.cpp Framework/Radiography/RadiographyScene.h Framework/Radiography/RadiographySceneReader.cpp Framework/Radiography/RadiographySceneWriter.cpp
diffstat 8 files changed, 29 insertions(+), 135 deletions(-) [+]
line wrap: on
line diff
--- a/Applications/Samples/SingleFrameEditorApplication.h	Fri Feb 15 18:43:41 2019 +0100
+++ b/Applications/Samples/SingleFrameEditorApplication.h	Tue Feb 19 11:40:14 2019 +0100
@@ -499,12 +499,12 @@
         
         //scene_->LoadDicomWebFrame(context->GetWebService());
         
-        std::vector<MaskPoint> mask;
-        mask.push_back(MaskPoint(1100, 100));
-        mask.push_back(MaskPoint(1100, 1000));
-        mask.push_back(MaskPoint(2000, 1000));
-        mask.push_back(MaskPoint(2200, 150));
-        mask.push_back(MaskPoint(1500, 550));
+        std::vector<Orthanc::ImageProcessing::ImagePoint> mask;
+        mask.push_back(Orthanc::ImageProcessing::ImagePoint(1100, 100));
+        mask.push_back(Orthanc::ImageProcessing::ImagePoint(1100, 1000));
+        mask.push_back(Orthanc::ImageProcessing::ImagePoint(2000, 1000));
+        mask.push_back(Orthanc::ImageProcessing::ImagePoint(2200, 150));
+        mask.push_back(Orthanc::ImageProcessing::ImagePoint(1500, 550));
         maskLayer_ = dynamic_cast<RadiographyMaskLayer*>(&(scene_->LoadMask(mask, dynamic_cast<RadiographyDicomLayer&>(dicomLayer), 128.0f, NULL)));
         interactor_.SetMaskLayer(maskLayer_);
 
--- a/Framework/Radiography/RadiographyLayerMaskTracker.cpp	Fri Feb 15 18:43:41 2019 +0100
+++ b/Framework/Radiography/RadiographyLayerMaskTracker.cpp	Tue Feb 19 11:40:14 2019 +0100
@@ -45,7 +45,7 @@
       unsigned int ix, iy; // image coordinates
       if (maskLayer->GetPixel(ix, iy, sourceSceneCp_.x, sourceSceneCp_.y))
       {
-        maskLayer->SetCorner(MaskPoint(ix, iy), sourceSceneCp_.index);
+        maskLayer->SetCorner(Orthanc::ImageProcessing::ImagePoint((int32_t)ix, (int32_t)iy), sourceSceneCp_.index);
       }
     }
 
@@ -59,7 +59,7 @@
       unsigned int ix, iy; // image coordinates
       if (maskLayer->GetPixel(ix, iy, targetSceneCp_.x, targetSceneCp_.y))
       {
-        maskLayer->SetCorner(MaskPoint(ix, iy), targetSceneCp_.index);
+        maskLayer->SetCorner(Orthanc::ImageProcessing::ImagePoint((int32_t)ix, (int32_t)iy), targetSceneCp_.index);
       }
     }
 
@@ -77,7 +77,7 @@
       unsigned int ix, iy; // image coordinates
       if (maskLayer->GetPixel(ix, iy, targetSceneCp_.x, targetSceneCp_.y))
       {
-        maskLayer->SetCorner(MaskPoint(ix, iy), targetSceneCp_.index);
+        maskLayer->SetCorner(Orthanc::ImageProcessing::ImagePoint((int32_t)ix, (int32_t)iy), targetSceneCp_.index);
       }
     }
   };
@@ -133,7 +133,7 @@
         {
           throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
         }
-        maskLayer->SetCorner(MaskPoint(ix, iy), startSceneCp_.index);
+        maskLayer->SetCorner(Orthanc::ImageProcessing::ImagePoint((int32_t)ix, (int32_t)iy), startSceneCp_.index);
       }
     }
   }
--- a/Framework/Radiography/RadiographyMaskLayer.cpp	Fri Feb 15 18:43:41 2019 +0100
+++ b/Framework/Radiography/RadiographyMaskLayer.cpp	Tue Feb 19 11:40:14 2019 +0100
@@ -50,30 +50,12 @@
     return dicomLayer_.GetPixel(imageX, imageY, sceneX, sceneY);
   }
 
-
-  void ComputeMaskExtent(unsigned int& left, unsigned int& right, unsigned int& top, unsigned int& bottom, const std::vector<MaskPoint>& corners)
-  {
-    left = std::numeric_limits<unsigned int>::max();
-    right = std::numeric_limits<unsigned int>::min();
-    top = std::numeric_limits<unsigned int>::max();
-    bottom = std::numeric_limits<unsigned int>::min();
-
-    for (size_t i = 0; i < corners.size(); i++)
-    {
-      const MaskPoint& p = corners[i];
-      left = std::min(p.x, left);
-      right = std::max(p.x, right);
-      bottom = std::max(p.y, bottom);
-      top = std::min(p.y, top);
-    }
-  }
-
   std::string RadiographyMaskLayer::GetInstanceId() const
   {
     return dicomLayer_.GetInstanceId();
   }
 
-  void RadiographyMaskLayer::SetCorner(const MaskPoint& corner, size_t index)
+  void RadiographyMaskLayer::SetCorner(const Orthanc::ImageProcessing::ImagePoint& corner, size_t index)
   {
     if (index < corners_.size())
       corners_[index] = corner;
@@ -82,7 +64,7 @@
     invalidated_ = true;
   }
 
-  void RadiographyMaskLayer::SetCorners(const std::vector<MaskPoint>& corners)
+  void RadiographyMaskLayer::SetCorners(const std::vector<Orthanc::ImageProcessing::ImagePoint>& corners)
   {
     corners_ = corners;
     invalidated_ = true;
@@ -146,90 +128,12 @@
 
   void RadiographyMaskLayer::DrawMask() const
   {
-    unsigned int left;
-    unsigned int right;
-    unsigned int top;
-    unsigned int bottom;
-
-    ComputeMaskExtent(left, right, top, bottom, corners_);
-
     // first fill the complete image
     Orthanc::ImageProcessing::Set(*mask_, OUT_MASK_VALUE);
 
-    {
-      // from http://alienryderflex.com/polygon_fill/
-      std::auto_ptr<int> raiiNodeX(new int(corners_.size()));
-
-      // convert all control points to double only once
-      std::vector<double> cpx;
-      std::vector<double> cpy;
-      int cpSize = corners_.size();
-      for (size_t i = 0; i < corners_.size(); i++)
-      {
-        cpx.push_back((double)corners_[i].x);
-        cpy.push_back((double)corners_[i].y);
-      }
-
-      std::vector<int> nodeX;
-      nodeX.resize(cpSize);
-      int  nodes, pixelX, pixelY, i, j, swap ;
-
-      //  Loop through the rows of the image.
-      for (pixelY = (int)top; pixelY < (int)bottom; pixelY++)
-      {
-        double y = (double)pixelY;
-        //  Build a list of nodes.
-        nodes = 0;
-        j = cpSize - 1;
-
-        for (i = 0; i < cpSize; i++)
-        {
-          if ((cpy[i] < y && cpy[j] >=  y)
-              ||  (cpy[j] < y && cpy[i] >= y))
-          {
-            nodeX[nodes++]= (int)(cpx[i] + (y - cpy[i])/(cpy[j] - cpy[i]) *(cpx[j] - cpx[i]));
-          }
-          j=i;
-        }
+    // fill mask
+    Orthanc::ImageProcessing::FillPolygon(*mask_, corners_, IN_MASK_VALUE);
 
-        //  Sort the nodes, via a simple “Bubble” sort.
-        i=0;
-        while (i < nodes-1)
-        {
-          if (nodeX[i] > nodeX[i+1])
-          {
-            swap = nodeX[i];
-            nodeX[i] = nodeX[i+1];
-            nodeX[i+1] = swap;
-            if (i)
-              i--;
-          }
-          else
-          {
-            i++;
-          }
-        }
-
-        unsigned char* row = reinterpret_cast<unsigned char*>(mask_->GetRow(pixelY));
-        //  Fill the pixels between node pairs.
-        for (i=0; i<nodes; i+=2)
-        {
-          if   (nodeX[i  ]>=(int)right)
-            break;
-          if   (nodeX[i+1]>= (int)left)
-          {
-            if (nodeX[i  ]< (int)left )
-              nodeX[i  ]=(int)left ;
-            if (nodeX[i+1]> (int)right)
-              nodeX[i+1]=(int)right;
-            for (pixelX = nodeX[i]; pixelX <= nodeX[i+1]; pixelX++)
-            {
-              *(row + pixelX) = IN_MASK_VALUE;
-            }
-          }
-        }
-      }
-    }
   }
 
 }
--- a/Framework/Radiography/RadiographyMaskLayer.h	Fri Feb 15 18:43:41 2019 +0100
+++ b/Framework/Radiography/RadiographyMaskLayer.h	Tue Feb 19 11:40:14 2019 +0100
@@ -23,27 +23,17 @@
 
 #include "RadiographyLayer.h"
 #include "Core/Images/Image.h"
+#include "Core/Images/ImageProcessing.h"
 
 namespace OrthancStone
 {
   class RadiographyScene;
   class RadiographyDicomLayer;
 
-  struct MaskPoint
-  {
-    unsigned int x;
-    unsigned int y;
-
-    MaskPoint(unsigned int x, unsigned int y)
-      : x(x),
-        y(y)
-    {}
-  };
-
   class RadiographyMaskLayer : public RadiographyLayer
   {
   private:
-    std::vector<MaskPoint>            corners_;
+    std::vector<Orthanc::ImageProcessing::ImagePoint>            corners_;
     const RadiographyDicomLayer&      dicomLayer_;
     mutable bool                      invalidated_;
     float                             foreground_;
@@ -59,10 +49,10 @@
     {
     }
 
-    void SetCorners(const std::vector<MaskPoint>& corners);
-    void SetCorner(const MaskPoint& corner, size_t index);
+    void SetCorners(const std::vector<Orthanc::ImageProcessing::ImagePoint>& corners);
+    void SetCorner(const Orthanc::ImageProcessing::ImagePoint& corner, size_t index);
 
-    const std::vector<MaskPoint>& GetCorners() const
+    const std::vector<Orthanc::ImageProcessing::ImagePoint>& GetCorners() const
     {
       return corners_;
     }
@@ -86,7 +76,7 @@
     virtual void GetControlPoint(ControlPoint& cpScene,
                                          size_t index) const
     {
-      ControlPoint cp(corners_[index].x, corners_[index].y, index);
+      ControlPoint cp(corners_[index].GetX(), corners_[index].GetY(), index);
 
       // transforms image coordinates into scene coordinates
       GetTransform().Apply(cp.x, cp.y);
--- a/Framework/Radiography/RadiographyScene.cpp	Fri Feb 15 18:43:41 2019 +0100
+++ b/Framework/Radiography/RadiographyScene.cpp	Tue Feb 19 11:40:14 2019 +0100
@@ -293,7 +293,7 @@
     return LoadAlphaBitmap(block.release(), geometry);
   }
 
-  RadiographyLayer& RadiographyScene::LoadMask(const std::vector<MaskPoint>& corners,
+  RadiographyLayer& RadiographyScene::LoadMask(const std::vector<Orthanc::ImageProcessing::ImagePoint>& corners,
                                                const RadiographyDicomLayer& dicomLayer,
                                                float foreground,
                                                RadiographyLayer::Geometry* geometry)
--- a/Framework/Radiography/RadiographyScene.h	Fri Feb 15 18:43:41 2019 +0100
+++ b/Framework/Radiography/RadiographyScene.h	Tue Feb 19 11:40:14 2019 +0100
@@ -25,10 +25,10 @@
 #include "../Toolbox/OrthancApiClient.h"
 #include "Framework/StoneEnumerations.h"
 #include "Core/Images/Image.h"
+#include "Core/Images/ImageProcessing.h"
 
 namespace OrthancStone
 {
-  struct MaskPoint;
   class RadiographyDicomLayer;
 
   class RadiographyScene :
@@ -154,7 +154,7 @@
                                     unsigned int height,
                                     RadiographyLayer::Geometry* geometry);
 
-    RadiographyLayer& LoadMask(const std::vector<MaskPoint>& corners,
+    RadiographyLayer& LoadMask(const std::vector<Orthanc::ImageProcessing::ImagePoint>& corners,
                                const RadiographyDicomLayer& dicomLayer,
                                float foreground,
                                RadiographyLayer::Geometry* geometry);
--- a/Framework/Radiography/RadiographySceneReader.cpp	Fri Feb 15 18:43:41 2019 +0100
+++ b/Framework/Radiography/RadiographySceneReader.cpp	Tue Feb 19 11:40:14 2019 +0100
@@ -55,11 +55,11 @@
         ReadLayerGeometry(geometry, jsonLayer);
 
         float foreground = jsonLayer["foreground"].asFloat();
-        std::vector<MaskPoint> corners;
+        std::vector<Orthanc::ImageProcessing::ImagePoint> corners;
         for (size_t i = 0; i < jsonLayer["corners"].size(); i++)
         {
-          MaskPoint corner(jsonLayer["corners"][(int)i]["x"].asUInt(),
-              jsonLayer["corners"][(int)i]["y"].asUInt());
+          Orthanc::ImageProcessing::ImagePoint corner(jsonLayer["corners"][(int)i]["x"].asInt(),
+              jsonLayer["corners"][(int)i]["y"].asInt());
           corners.push_back(corner);
         }
 
--- a/Framework/Radiography/RadiographySceneWriter.cpp	Fri Feb 15 18:43:41 2019 +0100
+++ b/Framework/Radiography/RadiographySceneWriter.cpp	Tue Feb 19 11:40:14 2019 +0100
@@ -63,12 +63,12 @@
     output["instanceId"] = layer.GetInstanceId(); // the dicom layer it's being linked to
     output["foreground"] = layer.GetForeground();
     output["corners"] = Json::arrayValue;
-    const std::vector<MaskPoint>& corners = layer.GetCorners();
+    const std::vector<Orthanc::ImageProcessing::ImagePoint>& corners = layer.GetCorners();
     for (size_t i = 0; i < corners.size(); i++)
     {
       Json::Value corner;
-      corner["x"] = corners[i].x;
-      corner["y"] = corners[i].y;
+      corner["x"] = corners[i].GetX();
+      corner["y"] = corners[i].GetY();
       output["corners"].append(corner);
     }
   }