# HG changeset patch # User am@osimis.io # Date 1550572814 -3600 # Node ID aede9b042cb7c5bce0de1a4a534189f1baf4f3f2 # Parent e4febcef669e9ae0cd855dc854283cc05297f681 now using ImageProcessing::FillPolygon diff -r e4febcef669e -r aede9b042cb7 Applications/Samples/SingleFrameEditorApplication.h --- 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 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 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(&(scene_->LoadMask(mask, dynamic_cast(dicomLayer), 128.0f, NULL))); interactor_.SetMaskLayer(maskLayer_); diff -r e4febcef669e -r aede9b042cb7 Framework/Radiography/RadiographyLayerMaskTracker.cpp --- 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); } } } diff -r e4febcef669e -r aede9b042cb7 Framework/Radiography/RadiographyMaskLayer.cpp --- 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& corners) - { - left = std::numeric_limits::max(); - right = std::numeric_limits::min(); - top = std::numeric_limits::max(); - bottom = std::numeric_limits::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& corners) + void RadiographyMaskLayer::SetCorners(const std::vector& 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 raiiNodeX(new int(corners_.size())); - - // convert all control points to double only once - std::vector cpx; - std::vector 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 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(mask_->GetRow(pixelY)); - // Fill the pixels between node pairs. - for (i=0; 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; - } - } - } - } - } } } diff -r e4febcef669e -r aede9b042cb7 Framework/Radiography/RadiographyMaskLayer.h --- 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 corners_; + std::vector corners_; const RadiographyDicomLayer& dicomLayer_; mutable bool invalidated_; float foreground_; @@ -59,10 +49,10 @@ { } - void SetCorners(const std::vector& corners); - void SetCorner(const MaskPoint& corner, size_t index); + void SetCorners(const std::vector& corners); + void SetCorner(const Orthanc::ImageProcessing::ImagePoint& corner, size_t index); - const std::vector& GetCorners() const + const std::vector& 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); diff -r e4febcef669e -r aede9b042cb7 Framework/Radiography/RadiographyScene.cpp --- 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& corners, + RadiographyLayer& RadiographyScene::LoadMask(const std::vector& corners, const RadiographyDicomLayer& dicomLayer, float foreground, RadiographyLayer::Geometry* geometry) diff -r e4febcef669e -r aede9b042cb7 Framework/Radiography/RadiographyScene.h --- 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& corners, + RadiographyLayer& LoadMask(const std::vector& corners, const RadiographyDicomLayer& dicomLayer, float foreground, RadiographyLayer::Geometry* geometry); diff -r e4febcef669e -r aede9b042cb7 Framework/Radiography/RadiographySceneReader.cpp --- 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 corners; + std::vector 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); } diff -r e4febcef669e -r aede9b042cb7 Framework/Radiography/RadiographySceneWriter.cpp --- 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& corners = layer.GetCorners(); + const std::vector& 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); } }