Commit 1dc5b13a authored by Edward Andò's avatar Edward Andò
Browse files

generalisation of getImagettes for labels to avoid redundant code, some...

generalisation of getImagettes for labels to avoid redundant code, some changes to input of spam-pixelSearchPropagate
parent 6ac0abe4
Pipeline #61447 passed with stages
in 13 minutes and 28 seconds
......@@ -184,88 +184,53 @@ def correlateOneLabel(label):
# WARNING HACK BAD FIXME
labelDilateCurrent = args.LABEL_DILATE
initialDisplacement = numpy.round(PhiField[label][0:3, 3]).astype(int)
if args.DEBUG: print("\n\n\nWorking on label:", label, "\n")
if args.DEBUG: print("Position (ZYX):", centresOfMass[label])
imagetteReturns = spam.label.getImagettesLabelled(lab1, label,
PhiField[label],
im1, im2,
[0, 0, 0, 0, 0, 0], # Search range, don't worry about it
boundingBoxes, centresOfMass,
margin=args.LABEL_CORRELATE_MARGIN,
labelDilate=labelDilateCurrent,
maskOtherLabels=args.LABEL_CORRELATE_MASK_OTHERS,
applyF='no',
volumeThreshold=args.VOLUME_THRESHOLD)
badPhi = numpy.eye(4)
badPhi[0:3, 3] = numpy.nan
getLabel = spam.label.getLabel(lab1, label,
extractCube=False,
boundingBoxes=boundingBoxes,
centresOfMass=centresOfMass,
margin=labelDilateCurrent + args.LABEL_CORRELATE_MARGIN,
maskOtherLabels=args.MASK,
labelDilate=labelDilateCurrent,
labelDilateMaskOtherLabels=args.LABEL_CORRELATE_MASK_OTHERS)
# In case the label is missing or the Phi is duff
if getLabel is None or not numpy.all(numpy.isfinite(PhiField[label])):
if imagetteReturns['returnStatus'] != 1 or not numpy.all(numpy.isfinite(PhiField[label])):
return label, badPhi, -7, numpy.inf, 0, numpy.inf, labelDilateCurrent
else:
# Maskette 1 is either a boolean array if args.MASK
# otherwise it contains ints i.e., labels
if args.MASK:
maskette1 = getLabel['subvol']
maskette1vol = numpy.sum(maskette1)
else:
maskette1 = None
maskette1vol = numpy.inf # must pass "if" below
# Use new padded slicer, to remain aligned with getLabel['subvol']
# + add 1 on the "max" side for bounding box -> slice
imagette1 = spam.helpers.slicePadded(im1, getLabel['boundingBox'] + numpy.array([0,1,0,1,0,1]))
#imagette1 = im1[getLabel['slice']].copy()
if maskette1vol > args.VOLUME_THRESHOLD:
labelDisplacementInt = numpy.round(PhiField[label][0:3, -1]).astype(int)
# 2020-09-25 OS and EA: Prepare startStop array for imagette 2 to be extracted with new
# slicePadded, this should solved "Boss: failed imDiff" and RS=-5 forever
startStopIm2 = [int(int(boundingBoxes[label][0]) - args.LABEL_CORRELATE_MARGIN - max(labelDilateCurrent, 0) + labelDisplacementInt[0] ),
int(int(boundingBoxes[label][1]) + args.LABEL_CORRELATE_MARGIN + max(labelDilateCurrent, 0) + labelDisplacementInt[0] + 1),
int(int(boundingBoxes[label][2]) - args.LABEL_CORRELATE_MARGIN - max(labelDilateCurrent, 0) + labelDisplacementInt[1] ),
int(int(boundingBoxes[label][3]) + args.LABEL_CORRELATE_MARGIN + max(labelDilateCurrent, 0) + labelDisplacementInt[1] + 1),
int(int(boundingBoxes[label][4]) - args.LABEL_CORRELATE_MARGIN - max(labelDilateCurrent, 0) + labelDisplacementInt[2] ),
int(int(boundingBoxes[label][5]) + args.LABEL_CORRELATE_MARGIN + max(labelDilateCurrent, 0) + labelDisplacementInt[2] + 1)]
imagette2 = spam.helpers.slicePadded(im2, startStopIm2)
#imagette2imagette1sizeDiff = numpy.array(imagette2.shape) - numpy.array(imagette1.shape)
# If all of imagette2 is nans it fell outside im2 (or in any case it's going to be difficult to correlate)
if not numpy.all(numpy.isnan(imagette2)):
# Remove int() part of displacement since it's already used to extract imagette2
PhiTemp = PhiField[label].copy()
PhiTemp[0:3, -1] -= labelDisplacementInt
if args.DEBUG: print("Starting lk iterations with Phi - int(disp):\n", PhiTemp)
if args.DEBUG: print("\nStarting lk iterations with int(disp):\n", labelDisplacementInt)
registerReturns = spam.DIC.correlate.registerMultiscale(imagette1,
imagette2,
args.LABEL_CORRELATE_MULTISCALE_BINNING,
im1mask=maskette1,
margin=1,
PhiInit=PhiTemp,
PhiRigid=args.LABEL_CORRELATE_RIGID,
updateGradient=args.LABEL_CORRELATE_UPDATE_GRADIENT,
maxIterations=args.LABEL_CORRELATE_MAX_ITERATIONS,
deltaPhiMin=args.LABEL_CORRELATE_MIN_PHI_CHANGE,
interpolationOrder=args.LABEL_CORRELATE_INTERPOLATION_ORDER,
verbose=args.DEBUG,
imShowProgress=args.DEBUG)
goodPhi = registerReturns['Phi']
goodPhi[0:3, -1] += labelDisplacementInt
return label, goodPhi, registerReturns['returnStatus'], registerReturns['error'], registerReturns['iterations'], registerReturns['deltaPhiNorm'], labelDilateCurrent
else: # failed imDiff condition, should now be impossible thanks to slicePadded() --> now it means if imagette2 is completely outside im2
print("\t\tBoss: Empty imagette 2 with initial displacement", labelDisplacementInt)
return label, badPhi, -4, numpy.inf, 0, numpy.inf, labelDilateCurrent
else: # failed the volume condition
return label, badPhi, -5, numpy.inf, 0, numpy.inf, labelDilateCurrent
# Remove int() part of displacement since it's already used to extract imagette2
PhiTemp = PhiField[label].copy()
PhiTemp[0:3, -1] -= initialDisplacement
if args.DEBUG: print("Starting lk iterations with Phi - int(disp):\n", PhiTemp)
if args.DEBUG: print("\nStarting lk iterations with int(disp):\n", initialDisplacement)
registerReturns = spam.DIC.correlate.registerMultiscale(imagetteReturns['imagette1'],
imagetteReturns['imagette2'],
args.LABEL_CORRELATE_MULTISCALE_BINNING,
im1mask=imagetteReturns['imagette1mask'],
margin=1,
PhiInit=PhiTemp,
PhiRigid=args.LABEL_CORRELATE_RIGID,
updateGradient=args.LABEL_CORRELATE_UPDATE_GRADIENT,
maxIterations=args.LABEL_CORRELATE_MAX_ITERATIONS,
deltaPhiMin=args.LABEL_CORRELATE_MIN_PHI_CHANGE,
interpolationOrder=args.LABEL_CORRELATE_INTERPOLATION_ORDER,
verbose=args.DEBUG,
imShowProgress=args.DEBUG)
goodPhi = registerReturns['Phi']
goodPhi[0:3, -1] += initialDisplacement
return label, goodPhi, registerReturns['returnStatus'], registerReturns['error'], registerReturns['iterations'], registerReturns['deltaPhiNorm'], labelDilateCurrent
# Add labels to a queue -- mostly useful for MPI
......
......@@ -215,41 +215,26 @@ def pixelSearchOneNode(nodeNumber):
# All global variables, we will return a list with:
# nodeNumber,
if args.LAB1 is not None:
imagetteReturns = {}
gottenLabel = spam.label.getLabel(lab1, nodeNumber, boundingBoxes=boundingBoxes, centresOfMass=nodePositions, maskOtherLabels=True, labelDilate=args.LABEL_DILATE, margin=1+args.LABEL_DILATE)
if gottenLabel is not None:
# 2020-07-05 try applying F to im1 this is expected to help with pixel searching
PhiNoDisp = PhiField[nodeNumber].copy()
PhiNoDisp[0:3,-1] = 0.0
initialDisplacement = numpy.round(PhiField[nodeNumber, 0:3, 3]).astype(int)
imagette1 = spam.helpers.slicePadded(im1, gottenLabel['boundingBox'] + numpy.array([0,1,0,1,0,1]))
imagette1def = spam.DIC.applyPhi(imagette1, PhiNoDisp, PhiPoint=gottenLabel['centreOfMassREL'])
maskette1def = spam.DIC.applyPhi(gottenLabel['subvol'], PhiNoDisp, PhiPoint=gottenLabel['centreOfMassREL'], interpolationOrder=0)
imagette1def[maskette1def == 0] = numpy.nan
imagetteReturns['imagette1'] = imagette1def
imagetteReturns['imagette1mask'] = gottenLabel['subvol']
imagetteReturns['imagette2mask'] = None
# 2020-09-25 OS and EA: Prepare startStop array for imagette 2 to be extracted with new slicePadded
startStopIm2 = [int(gottenLabel['boundingBox'][0] - max(args.LABEL_DILATE, 0) + initialDisplacement[0] + searchRange[0] ),
int(gottenLabel['boundingBox'][1] + max(args.LABEL_DILATE, 0) + initialDisplacement[0] + searchRange[1] + 1),
int(gottenLabel['boundingBox'][2] - max(args.LABEL_DILATE, 0) + initialDisplacement[1] + searchRange[2] ),
int(gottenLabel['boundingBox'][3] + max(args.LABEL_DILATE, 0) + initialDisplacement[1] + searchRange[3] + 1),
int(gottenLabel['boundingBox'][4] - max(args.LABEL_DILATE, 0) + initialDisplacement[2] + searchRange[4] ),
int(gottenLabel['boundingBox'][5] + max(args.LABEL_DILATE, 0) + initialDisplacement[2] + searchRange[5] + 1)]
imagetteReturns['imagette2'] = spam.helpers.slicePadded(im2, startStopIm2)
imagetteReturns['pixelSearchOffset'] = searchRange[0::2] - numpy.array([max(args.LABEL_DILATE, 0)]*3)
imagetteReturns['returnStatus'] = 1
else:
imagetteReturns['returnStatus'] = 0
imagetteReturns = spam.label.getImagettesLabelled(lab1, nodeNumber,
PhiField[nodeNumber].copy(),
im1, im2,
searchRange.copy(),
boundingBoxes, nodePositions,
margin=args.LABEL_DILATE,
labelDilate=args.LABEL_DILATE,
applyF=args.APPLY_F,
volumeThreshold=3**3)
imagetteReturns['imagette2mask'] = None
else:
imagetteReturns = spam.DIC.getImagettes(im1, nodePositions[nodeNumber], args.HWS, PhiField[nodeNumber].copy(), im2, searchRange.copy(), im1mask=im1mask, im2mask=im2mask, minMaskCoverage=args.MASK_COVERAGE, greyThreshold=[args.GREY_LOW_THRESH, args.GREY_HIGH_THRESH], applyF=args.APPLY_F, twoD=twoD)
imagetteReturns = spam.DIC.getImagettes(im1,
nodePositions[nodeNumber],
args.HWS,
PhiField[nodeNumber].copy(),
im2, searchRange.copy(),
im1mask=im1mask, im2mask=im2mask, minMaskCoverage=args.MASK_COVERAGE,
greyThreshold=[args.GREY_LOW_THRESH, args.GREY_HIGH_THRESH],
applyF=args.APPLY_F,
twoD=twoD)
# If getImagettes was successful (size check and mask coverage check)
if imagetteReturns['returnStatus'] == 1:
......
......@@ -49,10 +49,18 @@ for key in sorted(argsDict):
print("\t{}: {}".format(key, argsDict[key]))
# Fill in search range
searchRange = numpy.array([args.SEARCH_RANGE[0], args.SEARCH_RANGE[1], args.SEARCH_RANGE[2], args.SEARCH_RANGE[3], args.SEARCH_RANGE[4], args.SEARCH_RANGE[5]])
searchRange = numpy.array([args.SEARCH_RANGE[0],
args.SEARCH_RANGE[1],
args.SEARCH_RANGE[2],
args.SEARCH_RANGE[3],
args.SEARCH_RANGE[4],
args.SEARCH_RANGE[5]])
pixelSearchCCmin = args.CC_MIN
weightingDistance = args.DIST
startPoint = numpy.array(args.START_POINT_DISP[0:3])
startPointDisplacement = numpy.array(args.START_POINT_DISP[3:6])
# Load reference image
im1 = tifffile.imread(args.im1.name)
# Detect unpadded 2D image first:
......@@ -78,18 +86,35 @@ if args.MASK2:
else:
im2mask = None
### There are 3 modes:
# - points-to-correlate defined by input "guiding points", which should be points with good texture
# - points-to-correlate defined by labelled image
# - points-to-correlate defined by regular grid
# Detect guiding points mode
if args.GUIDING_POINTS_FILE is not None:
gp = numpy.genfromtxt(args.gp.name)
# ...or label mode
elif args.LAB1 is not None:
lab1 = tifffile.imread(args.LAB1.name).astype(spam.label.labelType)
boundingBoxes = spam.label.boundingBoxes(lab1)
centresOfMass = spam.label.centresOfMass(lab1, boundingBoxes=boundingBoxes)
im1mask = None
im2mask = None
gp = numpy.vstack([startPoint, centresOfMass])
else:
gp, nodesDim = spam.DIC.makeGrid(im1.shape, args.NS)
gp = numpy.vstack([startPoint, gp])
print("\n\tRanking points")
gp = numpy.genfromtxt(args.gp.name)
#gp = numpy.abs(gp[:, -1:1:-1]) #swap x-z axes and give abs coordinates
guidingPoints = spam.mesh.rankPoints(gp, neighbourRadius=args.RADIUS)
numberOfPoints = guidingPoints.shape[0]
# Possible to do it on a structured grid, too!
# (provided that the fist point is well chosen...)
#gp, nodesDim = spam.DIC.makeGrid(im1.shape, args.NS)
#gp[0] = [26, 25, 245] #overwrite the first point (this can easily be an input actually)
#guidingPoints = spam.mesh.rankPoints(gp, neighbourRadius=args.RADIUS)
#numberOfPoints = guidingPoints.shape[0]
print(guidingPoints[0:10])
# Initialise arrays
PhiField = numpy.zeros((numberOfPoints, 4, 4))
......@@ -100,7 +125,7 @@ pixelSearchCC = numpy.zeros((numberOfPoints), dtype=float)
# Returns compatible with register()
error = numpy.zeros((numberOfPoints), dtype=float)
returnStatus = numpy.zeros((numberOfPoints), dtype=int)
deltaPhiNorm = numpy.ones((numberOfPoints), dtype=int)
deltaPhiNorm = numpy.ones((numberOfPoints), dtype=int)
iterations = numpy.zeros((numberOfPoints), dtype=int)
print("\n\tStarting sequential Pixel Search")
......@@ -109,7 +134,20 @@ pbar = progressbar.ProgressBar(widgets=widgets, maxval=numberOfPoints)
pbar.start()
# Step 1: simple PS for first point
imagetteReturnsTop = spam.DIC.getImagettes(im1, guidingPoints[0], args.HWS, PhiField[0].copy(), im2, searchRange.copy(), applyF='no')
if args.LAB1 is not None:
imagetteReturnsTop = spam.label.getImagettesLabelled(lab1, nodeNumber,
PhiField[0].copy(),
im1, im2,
searchRange.copy(),
boundingBoxes, nodePositions,
margin=args.LABEL_DILATE,
labelDilate=args.LABEL_DILATE,
applyF=args.APPLY_F,
volumeThreshold=3**3)
imagetteReturnsTop['imagette2mask'] = None
else:
imagetteReturnsTop = spam.DIC.getImagettes(im1, guidingPoints[0], args.HWS, PhiField[0].copy(), im2, searchRange.copy(), applyF='no')
# If getImagettes was successful (size check and mask coverage check)
if imagetteReturnsTop['returnStatus'] == 1:
......@@ -123,7 +161,11 @@ if imagetteReturnsTop['returnStatus'] == 1:
error[0] = PSreturnsTop[2]
# Failed to extract imagettes or something
else:
print("That's a bit of a problem I'm afraid!")
print("Failed to extact correlation window for starting point, exiting")
exit()
if pixelSearchCC[0] < args.CC_MIN:
print("CC obtained for starting point is less than threshold, not continuing")
exit()
# Step 2: Loop sequentially over the guiding points list
# 2.1: create the tree of the coordinates to find easily neighbours
......
......@@ -420,12 +420,6 @@ def ddicParser(parser):
dest='NEIGHBOURS',
help="Number of neighbours for field interpolation. Default = 12")
parser.add_argument('-nomask',
'--no-mask',
action="store_false",
dest='MASK',
help='Don\'t mask each label\'s image')
parser.add_argument('-lcm',
'--label-correlate-margin',
type=numpy.uint,
......@@ -2206,11 +2200,35 @@ def pixelSearchPropagate(parser):
type=argparse.FileType('r'),
help="Greyscale image of deformed state for correlation")
parser.add_argument('gp',
metavar='gp',
parser.add_argument('-sp',
'--starting-point-and-displacement',
nargs=6,
type=int,
default=[-1, -1, -1, 0, 0, 0],
dest='START_POINT_DISP',
help='Z Y X of first point for the propagation, Z Y X displacement of that point, required')
parser.add_argument('-gp',
'--guiding-points-file',
dest='GUIDING_POINTS_FILE',
default=None,
type=argparse.FileType('r'),
help='Path to file containing the guiding points')
parser.add_argument('-lab1',
'--labelledFile1',
dest='LAB1',
default=None,
type=argparse.FileType('r'),
help="Path to tiff file containing a labelled image 1 that defines zones to correlate. Disactivates -hws and -ns options")
#parser.add_argument('-ld',
#'--label-dilate',
#type=int,
#default=1,
#dest='LABEL_DILATE',
#help="Only if -lab1 is defined: Number of times to dilate labels. Default = 1")
parser.add_argument('-mf1',
'--maskFile1',
dest='MASK1',
......@@ -2245,26 +2263,35 @@ def pixelSearchPropagate(parser):
'--half-window-size',
nargs=1,
type=int,
default=10,
default=[5],
dest='HWS',
help="Half correlation window size (in pixels), measured each side of the node pixel (assumed equal in all 3 directions -- see -hws3 for different setting). Default = 10 px")
help="Half correlation window size (in pixels), measured each side of the node pixel (assumed equal in all 3 directions -- see -hws3 for different setting). Default = 5 px")
# Possible: window size different in all three directions
parser.add_argument('-hws3',
'--half-window-size-3',
nargs=3,
type=int,
default=[10, 10, 10],
default=None,
dest='HWS',
help="Half correlation window size (in pixels), measured each side of the node pixel (different in 3 directions). Default = 10, 10, 10px")
#parser.add_argument('-ns3',
#'--node-spacing-3',
#nargs=3,
#type=int,
#default=None,
#dest='NS',
#help="Node spacing in pixels (different in 3 directions). Default = 10, 10, 10px")
# Default: node spacing equal in all three directions
parser.add_argument('-ns',
'--node-spacing',
nargs=1,
type=int,
default=None,
dest='NS',
help="Node spacing in pixels (assumed equal in all 3 directions -- see -ns3 for different setting). Default = 10px")
parser.add_argument('-ns3',
'--node-spacing-3',
nargs=3,
type=int,
default=None,
dest='NS',
help="Node spacing in pixels (different in 3 directions). Default = 10, 10, 10px")
parser.add_argument('-nr',
'--neighbourhood-radius',
......@@ -2337,6 +2364,11 @@ def pixelSearchPropagate(parser):
# twoD = False
#tiff.close()
# You really need a start point...
if args.START_POINT_DISP[0:3] == [-1, -1, -1]:
print("You need to input a starting point from which to propagate!\n(even if displacement is zero)")
exit()
# If we have no out dir specified, deliver on our default promise -- this can't be done inline before since parser.parse_args() has not been run at that stage.
if args.OUT_DIR is None:
args.OUT_DIR = os.path.dirname(args.im1.name)
......@@ -2360,9 +2392,6 @@ def pixelSearchPropagate(parser):
else:
args.PREFIX += "-pixelSearchPropagate"
# Catch 3D options
if len(args.HWS) == 1:
args.HWS = [args.HWS[0]]*3
# Fill radius and dist if not given
if args.RADIUS is None:
......@@ -2371,11 +2400,57 @@ def pixelSearchPropagate(parser):
if args.DIST is None:
args.DIST = numpy.sum(args.HWS) + numpy.sum(args.SEARCH_RANGE[1]+args.SEARCH_RANGE[3]+args.SEARCH_RANGE[5])
## Catch and overwrite 2D options
#if twoD:
#args.HWS[0] = 0
#args.SEARCH_RANGE[0] = 0
#args.SEARCH_RANGE[1] = 0
### There are 3 modes:
# - points-to-correlate defined by input "guiding points", which should be points with good texture
# - points-to-correlate defined by labelled image
# - points-to-correlate defined by regular grid
if args.GUIDING_POINTS_FILE is not None:
print("I have been passed a guiding points file, so I am disactivating:")
print("\t- node spacing")
print("\t- label file")
args.NS = None
args.LAB1 = None
# Catch 3D options
if len(args.HWS) == 1:
args.HWS = [args.HWS[0]]*3
elif args.LAB1 is not None:
# We have a labelled image and so no nodeSpacing or halfWindowSize
print("I have been passed a labelled image and so I am disactivating:")
print("\t- node spacing")
print("\t- half-window size")
args.HWS = None
args.NS = None
args.MASK1 = None
args.MASK_COVERAGE = 0
else:
print("Regular grid mode")
# We are in grid, with a nodeSpacing and halfWindowSize
# Catch interdependent node spacing and correlation window sizes
if args.NS is None:
print("\nUsing default node spacing: "),
if args.HWS is None:
print("2x default half window size"),
args.HWS = [10]
print("({}) which is".format(args.HWS[0])),
args.NS = [args.HWS[0] * 2]
else:
print("2x user-set half window size"),
if len(args.HWS) == 1:
print("({}) which is".format(args.HWS[0])),
args.NS = [int(args.HWS[0] * 2)]
elif len(args.HWS) == 3:
print("({} -- selecting smallest) which is".format(args.HWS)),
args.NS = [int(min(args.HWS) * 2)]
print(args.NS)
# Catch 3D options
if len(args.NS) == 1:
args.NS = [args.NS[0], args.NS[0], args.NS[0]]
if len(args.HWS) == 1:
args.HWS = [args.HWS[0], args.HWS[0], args.HWS[0]]
return args
......@@ -602,6 +602,149 @@ def getLabel(labelledVolume, label, boundingBoxes=None, centresOfMass=None, marg
return output
def getImagettesLabelled(lab1, label, Phi, im1, im2, searchRange, boundingBoxes, centresOfMass, margin=0, labelDilate=0, maskOtherLabels=True, applyF='all', volumeThreshold=100):
"""
This function is responsible for extracting correlation windows ("imagettes") from two larger images (im1 and im2) with the help of a labelled im1.
This is generally to do image correlation, this function will be used for spam-ddic and pixelSearch modes.
Parameters
----------
lab1 : 3D numpy array of ints
Labelled image containing nLabels
label : int
Label of interest
Phi : 4x4 numpy array of floats
Phi matrix representing the movement of imagette1,
if not equal to `I`, imagette1 is deformed by the non-translation parts of Phi (F)
and the displacement is added to the search range (see below)
im1 : 3D numpy array
This is the large input reference image of greyvalues
im2 : 3D numpy array
This is the large input deformed image of greyvalues
searchRange : 6-component numpy array of ints
This defines where imagette2 should be extracted with respect to imagette1's position in im1.
The 6 components correspond to [ Zbot Ztop Ybot Ytop Xbot Xtop ].
If Z, Y and X values are the same, then imagette2 will be displaced and the same size as imagette1.
If 'bot' is lower than 'top', imagette2 will be larger in that dimension
boundingBoxes : nLabels*2 array of ints
Bounding boxes as returned by ``boundingBoxes``
centresOfMass : nLabels*3 array of floats
Centres of mass as returned by ``centresOfMass``
margin : int, optional
Margin around the grain to extract in pixels
Default = 0
labelDilate : int, optional
How much to dilate the label before computing the mask?
Default = 0
maskOtherLabels : bool, optional
In the returned subvolume, should other labels be masked?
If true, the mask is directly returned.
Default = True
applyF : string, optional
If a non-identity Phi is passed, should the F be applied to the returned imagette1?
Options are: 'all', 'rigid', 'no'
Default = 'all'
Note: as of January 2021, it seems to make more sense to have this as 'all' for pixelSearch, and 'no' for local DIC
volumeThreshold : int, optional
Pixel volume of labels that are discarded
Default = 100
Returns
-------
Dictionary :
'imagette1' : 3D numpy array,
'imagette1mask': 3D numpy array of same size as imagette1 or None,
'imagette2': 3D numpy array, bigger or equal size to imagette1
'returnStatus': int,
Describes success in extracting imagette1 and imagette2.
If == 1 success, otherwise negative means failure.
'pixelSearchOffset': 3-component list of ints
Coordinates of the top of the pixelSearch range in im1, i.e., the displacement that needs to be
added to the raw pixelSearch output to make it a im1 -> im2 displacement
"""
returnStatus = 1
imagette1mask = None
imagette2mask = None
initialDisplacement = numpy.round(Phi[0:3, 3]).astype(int)
PhiNoDisp = Phi.copy()
PhiNoDisp[0:3,-1] -= initialDisplacement
if applyF == 'rigid':
PhiNoDisp = spam.deformation.computeRigidPhi(PhiNoDisp)
gottenLabel = getLabel(lab1, label,
extractCube=False,
boundingBoxes=boundingBoxes,
centresOfMass=centresOfMass,
margin=labelDilate + margin,
maskOtherLabels=True,
labelDilate=labelDilate,
labelDilateMaskOtherLabels=maskOtherLabels)
# In case the label is missing or the Phi is duff
if gottenLabel is None or not numpy.all(numpy.isfinite(Phi)):
returnStatus = -7
else:
# Maskette 1 is either a boolean array if args.MASK
# otherwise it contains ints i.e., labels
# Use new padded slicer, to remain aligned with getLabel['subvol']
# + add 1 on the "max" side for bounding box -> slice
imagette1 = spam.helpers.slicePadded(im1, gottenLabel['boundingBox'] + numpy.array([0,1,0,1,0,1]))
if applyF == "all" or applyF == "rigid":
imagette1 = spam.DIC.applyPhi(imagette1, PhiNoDisp, PhiPoint=gottenLabel['centreOfMassREL'])
maskette1 = spam.DIC.applyPhi(gottenLabel['subvol'], PhiNoDisp, PhiPoint=gottenLabel['centreOfMassREL'], interpolationOrder=0)
elif applyF == "no":
maskette1 = gottenLabel['subvol']
else: