diff --git a/MRIcroGL.lps b/MRIcroGL.lps
index 8184dd9..455e468 100755
--- a/MRIcroGL.lps
+++ b/MRIcroGL.lps
@@ -19,8 +19,8 @@
-
-
+
+
@@ -151,7 +151,7 @@
-
+
@@ -159,23 +159,23 @@
-
+
-
-
-
-
+
+
+
+
-
-
+
+
@@ -204,9 +204,8 @@
-
-
-
+
+
@@ -214,7 +213,7 @@
-
+
@@ -418,7 +417,7 @@
-
+
@@ -428,123 +427,123 @@
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
diff --git a/MRIcroGL_llvm.lpi b/MRIcroGL_llvm.lpi
index 927c95b..d112630 100755
--- a/MRIcroGL_llvm.lpi
+++ b/MRIcroGL_llvm.lpi
@@ -139,7 +139,7 @@
diff --git a/mainunit.pas b/mainunit.pas
index 5dc7677..f63e161 100755
--- a/mainunit.pas
+++ b/mainunit.pas
@@ -5602,7 +5602,8 @@ procedure TGLForm1.SaveNIfTIMenuClick(Sender: TObject);
niftiVol: TNIfTI;
fnm : string;
begin
- if not vols.Layer(0,niftiVol) then exit;
+ //if not vols.Layer(0,niftiVol) then exit; //save background layer
+ if not vols.Layer(LayerList.ItemIndex,niftiVol) then exit; //save selected layer
fnm := NiftiSaveDialogFilename(false, niftiVol.Filename);
if fnm = '' then exit;
niftiVol.SaveFormatBasedOnExt(fnm);
@@ -8754,6 +8755,8 @@ function versionStr: string;
{$ENDIF}
{$IFDEF CPULLVM}
w := w + ' LLVM';
+ {$ELSE}
+ w := w + ' FPC';
{$ENDIF}
w := w + chr(13)+chr(10);
w := w + 'Author: Chris Rorden' +kEOLN;
diff --git a/nifti.pas b/nifti.pas
index be64c42..5feeecd 100755
--- a/nifti.pas
+++ b/nifti.pas
@@ -803,13 +803,18 @@ function correlR(var x, y: TFloat32s): single;
{$ENDIF} //FASTCORREL2
function TNIfTI.EdgeMap(isSmooth: boolean): TUInt8s;
//https://afni.nimh.nih.gov/pub/dist/doc/htmldoc/programs/3dedge3_sphx.html
+// 2dedge3 uses R. Deriche formula https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.476.5736&rep=rep1&type=pdf
//https://en.wikipedia.org/wiki/Sobel_operator#Extension_to_other_dimensions
+//optional compile:
+// Asjad and M. Deriche: https://www.researchgate.net/publication/283280465_A_new_approach_for_salt_dome_detection_using_a_3D_multidirectional_edge_detector
+//{$DEFINE ASJAD}
var
x, y, z, vx, nXYZ, nXY, nX, nY, nZ: int64;
llh, mlh, hlh, lmh, mmh, hmh, lhh, mhh, hhh, //voxel neighbors: slice above (high)
llm, mlm, hlm, lmm, hmm, lhm, mhm, hhm, //voxel neighbors: same slice (middle)
lll, mll, hll, lml, mml, hml, lhl, mhl, hhl, //voxel neighbors: slice below (low)
gx, gy, gz, mn, mx, scale255: single;
+ {$IFDEF ASJAD}g45, g135: single; {$ENDIF}
vol8: TUInt8s;
vol32: TFloat32s;
begin
@@ -866,7 +871,47 @@ function TNIfTI.EdgeMap(isSmooth: boolean): TUInt8s;
gx := (hlh + hmh + hhh + hlm + hmm + hhm + hll + hml + hhl) - (llh + lmh + lhh + llm + lmm + lhm + lll + lml + lhl);
gy := (lhh + mhh + hhh + lhm + mhm + hhm + lhl + mhl + hhl) - (llh + mlh + hlh + llm + mlm + hlm + lll + mll + hll);
gz := (llh + mlh + hlh + lmh + mmh + hmh + lhh + mhh + hhh) - (lll + mll + hll + lml + mml + hml + lhl + mhl + hhl);
+ {$IFDEF ASJAD}
+ //slice above (high)
+ llh := vol8[vx - 1 - nX + nXY] * 2;
+ mlh := vol8[vx - 0 - nX + nXY];
+ hlh := vol8[vx + 1 - nX + nXY] * 2;
+ lmh := vol8[vx - 1 - 0 + nXY];
+ //mmh := vol8[vx - 0 - 0 + nXY] * 0;
+ hmh := vol8[vx + 1 - 0 + nXY];
+ lhh := vol8[vx - 1 + nX + nXY] * 2;
+ mhh := vol8[vx - 0 + nX + nXY];
+ hhh := vol8[vx + 1 + nX + nXY] * 2;
+ //same slice (middle)
+ llm := vol8[vx - 1 - nX + 0] * 4;
+ mlm := vol8[vx - 0 - nX + 0] * 2;
+ hlm := vol8[vx + 1 - nX + 0] * 4;
+ lmm := vol8[vx - 1 - 0 + 0] * 2;
+ //mmm := vol8[vx - 0 - 0 + 0];
+ hmm := vol8[vx + 1 - 0 + 0] * 2;
+ lhm := vol8[vx - 1 + nX + 0] * 4;
+ mhm := vol8[vx - 0 + nX + 0] * 2;
+ hhm := vol8[vx + 1 + nX + 0] * 4;
+ //slice below (low)
+ lll := vol8[vx - 1 - nX - nXY] * 2;
+ mll := vol8[vx - 0 - nX - nXY];
+ hll := vol8[vx + 1 - nX - nXY] * 2;
+ lml := vol8[vx - 1 - 0 - nXY];
+ //mml := vol8[vx - 0 - 0 - nXY] * 0;
+ hml := vol8[vx + 1 - 0 - nXY];
+ lhl := vol8[vx - 1 + nX - nXY] * 2;
+ mhl := vol8[vx - 0 + nX - nXY];
+ hhl := vol8[vx + 1 + nX - nXY] * 2;
+
+ g45 := (hmh + mlh + hlh + hmm + mlm + hlm + hml + mll + hll) - (lhh + mhh + lmh + lhm + mhm + lmm + lhl + mhl + lml);
+ g135 := (lmh + llh + mlh + lmm + llm + mlm + lml + lll +mll) - (mhh + hhh + hmh + mhm + hhm + hmm + mhl + hhl + hml);
+
+
+ vol32[vx] += sqrt( sqr(gx) + sqr(gy) + sqr(gz) + sqr(g45) + sqr(g135));
+ {$ELSE}
vol32[vx] += sqrt( sqr(gx) + sqr(gy) + sqr(gz));
+ {$ENDIF}
+
end;
//scale 0..1
mn := infinity;
diff --git a/niftis.pas b/niftis.pas
index 4001e95..141129b 100644
--- a/niftis.pas
+++ b/niftis.pas
@@ -393,6 +393,7 @@ function TNIfTIs.AddEdgeLayer(Idx: integer; backColor: TRGBA): boolean;
if length(img8) < 1 then exit;
hdr := niis[Idx].Header;
hdr.intent_code := kNIFTI_INTENT_NONE;
+ hdr.descrip := 'Sobel MRIcroGL'+kVers;
prefix := 'edge_';
niis[fNumLayers] := TNIfTI.Create(prefix+niis[Idx].shortname, backColor, niis[Idx].Mat, niis[Idx].Dim, fInterpolateOverlays, hdr, TFloat32s(img8), true);
fNumLayers := fNumLayers + 1;