Added removal of symmetric areas from the ADC thresholded mask up to slice 10 to...
authormccreedy@NIH.GOV <mccreedy@NIH.GOV@ba61647d-9d00-f842-95cd-605cb4296b96>
Thu, 1 Mar 2018 18:35:02 +0000 (18:35 +0000)
committermccreedy@NIH.GOV <mccreedy@NIH.GOV@ba61647d-9d00-f842-95cd-605cb4296b96>
Thu, 1 Mar 2018 18:35:02 +0000 (18:35 +0000)
git-svn-id: https://citdcbmipav.cit.nih.gov/repos-pub/mipav/trunk@15394 ba61647d-9d00-f842-95cd-605cb4296b96

mipav/src/plugins/PlugInAlgorithmStrokeSegmentation.java
mipav/src/plugins/PlugInDialogStrokeSegmentation.java

index dabf9c1..1df6161 100644 (file)
@@ -23,6 +23,10 @@ public class PlugInAlgorithmStrokeSegmentation extends AlgorithmBase {
     \r
     private int adcThreshold;\r
     \r
+    private boolean doSymmetryRemoval;\r
+    \r
+    private int maxSymmetryRemovalSlice = 10;\r
+    \r
     private VOI coreVOI;\r
     \r
     private MaskObject largestObject;\r
@@ -32,7 +36,7 @@ public class PlugInAlgorithmStrokeSegmentation extends AlgorithmBase {
     private int minAdcObjectSize = 10;\r
     private int maxAdcObjectSize = 100000;\r
     \r
-    private static final String outputBasename = "CoreSeg";\r
+    private String outputBasename = "CoreSeg";\r
     \r
     private static final String voiExtension = ".xml";\r
     \r
@@ -44,13 +48,16 @@ public class PlugInAlgorithmStrokeSegmentation extends AlgorithmBase {
      * @param  dwi  DWI image\r
      * @param  adc  ADC image\r
      */\r
-    public PlugInAlgorithmStrokeSegmentation(ModelImage dwi, ModelImage adc, int threshold, String outputDir) {\r
+    public PlugInAlgorithmStrokeSegmentation(ModelImage dwi, ModelImage adc, int threshold, boolean symmetryRemoval, String outputDir) {\r
         super();\r
         \r
         dwiImage = dwi;\r
         adcImage = adc;\r
         adcThreshold = threshold;\r
+        doSymmetryRemoval = symmetryRemoval;\r
         coreOutputDir = outputDir;\r
+        \r
+        outputBasename = new File(coreOutputDir).getName() + "_" + outputBasename;\r
     }\r
     \r
     /**\r
@@ -109,7 +116,9 @@ public class PlugInAlgorithmStrokeSegmentation extends AlgorithmBase {
         fireProgressStateChanged("Extracting DWI mask ...");\r
         fireProgressStateChanged(45);\r
         \r
-        final int volLength = dwiImage.getExtents()[0] * dwiImage.getExtents()[1] * dwiImage.getExtents()[2];\r
+        final int[] extents = dwiImage.getExtents();\r
+        final int sliceLength = extents[0] * extents[1];\r
+        final int volLength = sliceLength * extents[2];\r
         short[] dwiSegBuffer = new short[volLength];\r
         try {\r
             dwiSeg.exportData(0, volLength, dwiSegBuffer);\r
@@ -168,10 +177,42 @@ public class PlugInAlgorithmStrokeSegmentation extends AlgorithmBase {
         saveImageFile(dwiSeg, coreOutputDir, outputBasename + "_ADC_thresh");\r
         \r
         // select largest object\r
-        // TODO: non-symmetric across midline?\r
         fireProgressStateChanged("Finding core lesion ...");\r
         fireProgressStateChanged(70);\r
         \r
+        if (doSymmetryRemoval) {\r
+            short[] removedBuffer = new short[volLength];\r
+            \r
+            // if values are mirrored across the the l->r of the image, cancel them out.  core values should only be on one side, while the cerebelum will have values on both sides\r
+            for (int iZ = 0; iZ < maxSymmetryRemovalSlice && iZ < extents[2]; iZ++) {\r
+                for (int iY = 0; iY < extents[1]; iY++) {\r
+                    for (int iX = 0; iX < extents[0] / 2; iX++) {\r
+                        int index = (iZ * sliceLength) + (iY * extents[0]) + iX;\r
+                        int mirroredIndex = (iZ * sliceLength) + (iY * extents[0]) + (extents[0] - iX - 1);\r
+                        \r
+                        if (dwiSegBuffer[index] > 0 && dwiSegBuffer[mirroredIndex] > 0) {\r
+                            dwiSegBuffer[index] = 0;\r
+                            dwiSegBuffer[mirroredIndex] = 0;\r
+                            \r
+                            removedBuffer[index] = 1;\r
+                            removedBuffer[mirroredIndex] = 1;\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            \r
+            try {\r
+                dwiSeg.importData(0, removedBuffer, true);\r
+            } catch (IOException error) {\r
+                dwiSegBuffer = null;\r
+                displayError("Error on mirrored removed data importData: " + dwiImage.getImageName());\r
+                setCompleted(false);\r
+                return;\r
+            }\r
+            \r
+            saveImageFile(dwiSeg, coreOutputDir, outputBasename + "_ADC_thresh_removed");\r
+        }\r
+        \r
         short[] objectBuffer = keepOnlyLargestObject(dwiSeg, dwiSegBuffer);\r
         \r
         try {\r
index e0db82b..8a019c3 100644 (file)
@@ -33,6 +33,8 @@ public class PlugInDialogStrokeSegmentation extends JDialogStandaloneScriptableP
     private JTextField dwiImageFileField;\r
     \r
     private JTextField adcThresholdField;\r
+    \r
+    private JCheckBox symmetryCheckbox;\r
 \r
     private boolean adcImageMultifile = false;\r
     private ModelImage adcImage;\r
@@ -42,6 +44,8 @@ public class PlugInDialogStrokeSegmentation extends JDialogStandaloneScriptableP
     \r
     private int adcThreshold = 620;\r
     \r
+    private boolean doSymmetryRemoval = true;\r
+    \r
     private PlugInAlgorithmStrokeSegmentation segAlgo = null;\r
     \r
     private static final String svnVersion = "$Rev$";\r
@@ -253,6 +257,8 @@ public class PlugInDialogStrokeSegmentation extends JDialogStandaloneScriptableP
             }\r
         }\r
         \r
+        doSymmetryRemoval = symmetryCheckbox.isSelected();\r
+        \r
         return true;\r
     }\r
 \r
@@ -263,7 +269,7 @@ public class PlugInDialogStrokeSegmentation extends JDialogStandaloneScriptableP
     protected void callAlgorithm() {\r
 \r
         try {\r
-            segAlgo = new PlugInAlgorithmStrokeSegmentation(dwiImage, adcImage, adcThreshold, outputDir);\r
+            segAlgo = new PlugInAlgorithmStrokeSegmentation(dwiImage, adcImage, adcThreshold, doSymmetryRemoval, outputDir);\r
 \r
             // This is very important. Adding this object as a listener allows the algorithm to\r
             // notify this object when it has completed or failed. See algorithm performed event.\r
@@ -307,6 +313,8 @@ public class PlugInDialogStrokeSegmentation extends JDialogStandaloneScriptableP
         \r
         adcThreshold = scriptParameters.getParams().getInt("adc_threshold");\r
         \r
+        doSymmetryRemoval = scriptParameters.getParams().getBoolean("do_symmetry_removal");\r
+        \r
         outputDir = adcImage.getImageDirectory() + File.separator;\r
     }\r
 \r
@@ -314,6 +322,7 @@ public class PlugInDialogStrokeSegmentation extends JDialogStandaloneScriptableP
         scriptParameters.storeImage(adcImage, "adc_image");\r
         scriptParameters.storeImage(dwiImage, "dwi_image");\r
         scriptParameters.getParams().put(ParameterFactory.newParameter("adc_threshold", adcThreshold));\r
+        scriptParameters.getParams().put(ParameterFactory.newParameter("do_symmetry_removal", doSymmetryRemoval));\r
     }\r
     \r
     /**\r
@@ -359,6 +368,14 @@ public class PlugInDialogStrokeSegmentation extends JDialogStandaloneScriptableP
         \r
         gbc.gridwidth = 3;\r
         \r
+        symmetryCheckbox = new JCheckBox("Perform symmetry removal on ADC mask", doSymmetryRemoval);\r
+        symmetryCheckbox.setForeground(Color.black);\r
+        symmetryCheckbox.setFont(serif12);\r
+        mainPanel.add(symmetryCheckbox, gbc);\r
+        \r
+        gbc.gridy++;\r
+        gbc.gridx = 0;\r
+        \r
         dirMethodRadio = new JRadioButton("Select directory with Baseline_ADC and Baseline_DWI files/subdirectories");\r
         dirMethodRadio.setForeground(Color.black);\r
         dirMethodRadio.setFont(serif12);\r