changeset 6480:e26d2e84d9f5 pixel-anon

added DicomModification::SetDicomModifier()
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 25 Nov 2025 13:53:19 +0100
parents eac46cac2ed5
children a9abcdac2eee
files OrthancFramework/Sources/DicomParsing/DicomModification.cpp OrthancFramework/Sources/DicomParsing/DicomModification.h OrthancServer/Sources/ServerContext.cpp TODO
diffstat 4 files changed, 17 insertions(+), 218 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancFramework/Sources/DicomParsing/DicomModification.cpp	Tue Nov 25 08:23:24 2025 +0100
+++ b/OrthancFramework/Sources/DicomParsing/DicomModification.cpp	Tue Nov 25 13:53:19 2025 +0100
@@ -1939,8 +1939,15 @@
     }
   }
 
-  bool DicomModification::RequiresUncompressedTransferSyntax() const
+  void DicomModification::SetDicomModifier(IDicomModifier* modifier)
   {
-    return dicomModifier_ != NULL;
+    if (modifier == NULL)
+    {
+      throw OrthancException(ErrorCode_NullPointer);
+    }
+    else
+    {
+      dicomModifier_.reset(modifier);
+    }
   }
 }
--- a/OrthancFramework/Sources/DicomParsing/DicomModification.h	Tue Nov 25 08:23:24 2025 +0100
+++ b/OrthancFramework/Sources/DicomParsing/DicomModification.h	Tue Nov 25 13:53:19 2025 +0100
@@ -168,7 +168,7 @@
     SequenceReplacements sequenceReplacements_;  // Must *never* be a path whose prefix is empty
 
     // New in Orthanc 1.12.10
-    std::unique_ptr<IDicomModifier>     dicomModifier_;    // TODO-PIXEL-ANON: check ownership & serialization
+    std::unique_ptr<IDicomModifier>   dicomModifier_;
 
     std::string MapDicomIdentifier(const std::string& original,
                                    ResourceType level);
@@ -286,6 +286,11 @@
 
     bool IsAlteredTag(const DicomTag& tag) const;
 
-    bool RequiresUncompressedTransferSyntax() const;
+    bool IsAnonymization() const
+    {
+      return isAnonymization_;
+    }
+
+    void SetDicomModifier(IDicomModifier* modifier);
   };
 }
--- a/OrthancServer/Sources/ServerContext.cpp	Tue Nov 25 08:23:24 2025 +0100
+++ b/OrthancServer/Sources/ServerContext.cpp	Tue Nov 25 13:53:19 2025 +0100
@@ -2098,7 +2098,7 @@
 
     // do we need to transcode before applying e.g custom pixels modifications ?
     DicomTransferSyntax currentTransferSyntax;
-    if (modification.RequiresUncompressedTransferSyntax() && 
+    if (// modification.RequiresUncompressedTransferSyntax() &&   // TODO-PIXEL-ANON
         dicomFile->LookupTransferSyntax(currentTransferSyntax) &&
         !IsRawTransferSyntax(currentTransferSyntax))
     {
--- a/TODO	Tue Nov 25 08:23:24 2025 +0100
+++ b/TODO	Tue Nov 25 13:53:19 2025 +0100
@@ -436,216 +436,3 @@
 
 * Create REST bindings with Slicer
 * Create REST bindings with Horos/OsiriX
-
-
-
-
-
-
-
-WORK IN PROGRESS: pixel-anon API
-================================
-
-Rest API proposal:
-
-{
-	"MaskPixelData" : {
-		"Regions": [
-			{
-				"MaskType": "MeanFilter",
-				"FilterWidth": 20,
-				"RegionType" : "2D",             // area is defined by an area in pixel coordinates
-				"Origin": [150, 100],            // X, Y in pixel coordinates
-				"End": [400, 200],               // X, Y in pixel coordinates
-				"TargetSeries" : [               // the series the pixel mask applies to.  If empty -> applies to all series
-					"cd589a09-6e705e06-57997219-7812eb49-709873a9"
-				],
-        "TargetInstances" : [            // the instances the pixel mask applies to.  If empty -> applies to all instances
-        ]
-			},
-			{                                    
-				"MaskType": "Fill",
-				"FillValue": 0,
-				"RegionType" : "3D",                // area is defined by a volume in world coordinates
-				"Origin": [-150.5, -250.4, -811],   // X, Y, Z in World coordinates
-				"End": [148.4, 220.7, -955],        // X, Y, Z in World coordinates
-				"TargetSeries" : [                  // in this mode, no need to list the instances since the Z coordinate shall handle that !
-					"94df9100-3b476f5b-f4e8c381-d78c327f-a387bc7e"
-				]
-			}
-		]
-	}
-}
-
-# anonymize a single instance
-curl http://localhost:8043/instances/19565ed8-6bd8f20e-efbd6c34-36688133-bc91329e/anonymize --data-binary '{"MaskPixelData" : {"Regions": [{"MaskType": "MeanFilter", "FilterWidth": 20, "RegionType" : "Pixels", "Origin": [150, 100], "End": [400, 200]} ]} }' --output out.dcm
-curl http://localhost:8043/instances/19565ed8-6bd8f20e-efbd6c34-36688133-bc91329e/anonymize --data-binary '{"MaskPixelData" : {"Regions": [{"MaskType": "Fill", "FillValue": 0, "RegionType" : "Pixels", "Origin": [150, 100], "End": [400, 200]} ]} }' --output out.dcm
-
-# modify all slices of one series of a study
-curl -X POST http://localhost:8043/studies/321d3848-40c81c82-49f6f235-df6b1ec7-ed52f2fa/modify \
---data-binary @- << EOF
-{
-    "Replace" : {"StudyInstanceUID": "1.2.2", "StudyDescription": "modified-all-slices"},
-    "Force": true,
-    "MaskPixelData": {
-        "Regions": [{
-            "MaskType": "Fill",
-            "FillValue": 4000,
-            "RegionType" : "2D",
-            "Origin": [150, 100],
-            "End": [400, 200],
-            "TargetSeries" : ["d5f6c1a2-d6f2f01a-a3cc4e8b-424476dc-f34b0cd1"]
-      }]
-    }
-}
-EOF
-
-
-# modify a few slices of one series of a study
-curl -X POST http://localhost:8043/studies/321d3848-40c81c82-49f6f235-df6b1ec7-ed52f2fa/modify \
---data-binary @- << EOF
-{
-    "Replace" : {"StudyInstanceUID": "1.2.3", "StudyDescription": "modified-few-slices"},
-    "Force": true,
-    "MaskPixelData": {
-        "Regions": [{
-            "MaskType": "Fill",
-            "FillValue": 4000,
-            "RegionType" : "2D",
-            "Origin": [150, 100],
-            "End": [400, 200],
-            "TargetInstances" : ["11e0b13a-fb44c3d5-819193d8-314b3bb5-4da13bc4", "372d70bb-886e6cc5-a89eefcc-405b2346-f4676bb2"]
-      }]
-    }
-}
-EOF
-
-# modify a few slices of one series of a study with a 3D Region
-curl -X POST http://localhost:8043/studies/321d3848-40c81c82-49f6f235-df6b1ec7-ed52f2fa/modify \
---data-binary @- << EOF
-{
-    "Replace" : {"StudyInstanceUID": "1.2.3", "StudyDescription": "modified-few-slices"},
-    "Force": true,
-    "MaskPixelData": {
-        "Regions": [{
-            "MaskType": "Fill",
-            "FillValue": 4000,
-            "RegionType" : "3D",
-            "Origin": [-150.0, -300, -750],
-            "End": [150.0, -250, -1000]
-      }]
-    }
-}
-EOF
-
-curl -X POST http://localhost:8043/studies/321d3848-40c81c82-49f6f235-df6b1ec7-ed52f2fa/modify \
---data-binary @- << EOF
-{
-    "Replace" : {"StudyInstanceUID": "1.2.3", "StudyDescription": "modified-few-slices"},
-    "Force": true,
-    "MaskPixelData": {
-        "Regions": [{
-            "MaskType": "MeanFilter",
-            "FilterWidth": 30,
-            "RegionType" : "3D",
-            "Origin": [-150.0, -300, -750],
-            "End": [150.0, -250, -1000]
-      }]
-    }
-}
-EOF
-
-
-# modify all frames of a multiframe study (CARDIO)
-curl -X POST http://localhost:8043/studies/595df1a1-74fe920a-4b9e3509-826f17a3-762a2dc3/modify \
---data-binary @- << EOF
-{
-    "Replace" : {"StudyInstanceUID": "1.2.4", "StudyDescription": "modified-multi-frame"},
-    "Force": true,
-    "MaskPixelData": {
-        "Regions": [{
-            "MaskType": "MeanFilter",
-            "FilterWidth": 30,
-            "RegionType" : "2D",
-            "Origin": [150, 100],
-            "End": [400, 200]
-      }]
-    }
-}
-EOF
-
-# modify all frames of a multiframe US study (Cine US, TS = .50)
-curl -X POST http://localhost:8043/studies/50f2961c-c35755eb-8762b05b-0e01cd97-dd8a294c/modify \
---data-binary @- << EOF
-{
-    "Replace" : {"StudyInstanceUID": "1.2.5", "StudyDescription": "modified-multi-frame-us"},
-    "Force": true,
-    "MaskPixelData": {
-        "Regions": [{
-            "MaskType": "MeanFilter",
-            "FilterWidth": 30,
-            "RegionType" : "2D",
-            "Origin": [0, 0],
-            "End": [768, 45]
-      }]
-    }
-}
-EOF
-
-
-# modify some frames of a multiframe scintigraphy study
-curl -X POST http://localhost:8043/studies/ab67d5f8-95865506-8fb83c8b-93610651-ddce6e77/modify \
---data-binary @- << EOF
-{
-    "Replace" : {"StudyInstanceUID": "1.2.6", "StudyDescription": "modified-scinti"},
-    "Force": true,
-    "MaskPixelData": {
-        "Regions": [{
-            "MaskType": "Fill",
-            "FillValue": 3000,
-            "RegionType" : "3D",
-            "Origin": [-150.0, -200, 200],
-            "End": [150.0, -150, 100]
-      }]
-    }
-}
-EOF
-
-# modify some frames of a multiframe scintigraphy series
-curl -X POST http://localhost:8043/series/08a23232-a61c3cb9-5cdb4518-b725cd5d-820ee1f6/modify \
---data-binary @- << EOF
-{
-    "Replace" : {"StudyInstanceUID": "1.2.6", "StudyDescription": "modified-scinti"},
-    "Force": true,
-    "MaskPixelData": {
-        "Regions": [{
-            "MaskType": "Fill",
-            "FillValue": 3000,
-            "RegionType" : "3D",
-            "Origin": [-150.0, -200, 200],
-            "End": [150.0, -150, 100]
-      }]
-    }
-}
-EOF
-
-
-
-# modify some frames of a multiframe PET-CT study
-curl -X POST http://localhost:8043/studies/890e1167-55ad171a-7721ffec-db91e2c1-700778c0/modify \
---data-binary @- << EOF
-{
-    "Replace" : {"StudyInstanceUID": "1.2.7", "StudyDescription": "modified-pet-ct"},
-    "Force": true,
-    "MaskPixelData": {
-        "Regions": [{
-            "MaskType": "Fill",
-            "FillValue": 3000,
-            "RegionType" : "3D",
-            "Origin": [-150.0, -100, -85],
-            "End": [150.0, 100, -250]
-      }]
-    }
-}
-EOF
-