diff toolbox/imtools.py @ 0:6bec4fef6b2e draft

"planemo upload for repository https://github.com/ohsu-comp-bio/unmicst commit 73e4cae15f2d7cdc86719e77470eb00af4b6ebb7-dirty"
author perssond
date Fri, 12 Mar 2021 00:17:29 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toolbox/imtools.py	Fri Mar 12 00:17:29 2021 +0000
@@ -0,0 +1,312 @@
+import matplotlib.pyplot as plt
+import tifffile
+import os
+import numpy as np
+from skimage import io as skio
+from scipy.ndimage import *
+from skimage.morphology import *
+from skimage.transform import resize
+
+def tifread(path):
+    return tifffile.imread(path)
+
+def tifwrite(I,path):
+    tifffile.imsave(path, I)
+
+def imshow(I,**kwargs):
+    if not kwargs:
+        plt.imshow(I,cmap='gray')
+    else:
+        plt.imshow(I,**kwargs)
+        
+    plt.axis('off')
+    plt.show()
+
+def imshowlist(L,**kwargs):
+    n = len(L)
+    for i in range(n):
+        plt.subplot(1, n, i+1)
+        if not kwargs:
+            plt.imshow(L[i],cmap='gray')
+        else:
+            plt.imshow(L[i],**kwargs)
+        plt.axis('off')
+    plt.show()
+
+def imread(path):
+    return skio.imread(path)
+
+def imwrite(I,path):
+    skio.imsave(path,I)
+
+def im2double(I):
+    if I.dtype == 'uint16':
+        return I.astype('float64')/65535
+    elif I.dtype == 'uint8':
+        return I.astype('float64')/255
+    elif I.dtype == 'float32':
+        return I.astype('float64')
+    elif I.dtype == 'float64':
+        return I
+    else:
+        print('returned original image type: ', I.dtype)
+        return I
+
+def size(I):
+    return list(I.shape)
+
+def imresizeDouble(I,sizeOut): # input and output are double
+    return resize(I,(sizeOut[0],sizeOut[1]),mode='reflect')
+
+def imresize3Double(I,sizeOut): # input and output are double
+    return resize(I,(sizeOut[0],sizeOut[1],sizeOut[2]),mode='reflect')
+
+def imresizeUInt8(I,sizeOut): # input and output are UInt8
+    return np.uint8(resize(I.astype(float),(sizeOut[0],sizeOut[1]),mode='reflect',order=0))
+
+def imresize3UInt8(I,sizeOut): # input and output are UInt8
+    return np.uint8(resize(I.astype(float),(sizeOut[0],sizeOut[1],sizeOut[2]),mode='reflect',order=0))
+
+def normalize(I):
+    m = np.min(I)
+    M = np.max(I)
+    if M > m:
+        return (I-m)/(M-m)
+    else:
+        return I
+
+def snormalize(I):
+    m = np.mean(I)
+    s = np.std(I)
+    if s > 0:
+        return (I-m)/s
+    else:
+        return I
+
+def cat(a,I,J):
+    return np.concatenate((I,J),axis=a)
+
+def imerode(I,r):
+    return binary_erosion(I, disk(r))
+
+def imdilate(I,r):
+    return binary_dilation(I, disk(r))
+
+def imerode3(I,r):
+    return morphology.binary_erosion(I, ball(r))
+
+def imdilate3(I,r):
+    return morphology.binary_dilation(I, ball(r))
+
+def sphericalStructuralElement(imShape,fRadius):
+    if len(imShape) == 2:
+        return disk(fRadius,dtype=float)
+    if len(imShape) == 3:
+        return ball(fRadius,dtype=float)
+
+def medfilt(I,filterRadius):
+    return median_filter(I,footprint=sphericalStructuralElement(I.shape,filterRadius))
+
+def maxfilt(I,filterRadius):
+    return maximum_filter(I,footprint=sphericalStructuralElement(I.shape,filterRadius))
+
+def minfilt(I,filterRadius):
+    return minimum_filter(I,footprint=sphericalStructuralElement(I.shape,filterRadius))
+
+def ptlfilt(I,percentile,filterRadius):
+    return percentile_filter(I,percentile,footprint=sphericalStructuralElement(I.shape,filterRadius))
+
+def imgaussfilt(I,sigma,**kwargs):
+    return gaussian_filter(I,sigma,**kwargs)
+
+def imlogfilt(I,sigma,**kwargs):
+    return -gaussian_laplace(I,sigma,**kwargs)
+
+def imgradmag(I,sigma):
+    if len(I.shape) == 2:
+        dx = imgaussfilt(I,sigma,order=[0,1])
+        dy = imgaussfilt(I,sigma,order=[1,0])
+        return np.sqrt(dx**2+dy**2)
+    if len(I.shape) == 3:
+        dx = imgaussfilt(I,sigma,order=[0,0,1])
+        dy = imgaussfilt(I,sigma,order=[0,1,0])
+        dz = imgaussfilt(I,sigma,order=[1,0,0])
+        return np.sqrt(dx**2+dy**2+dz**2)
+
+def localstats(I,radius,justfeatnames=False):
+    ptls = [10,30,50,70,90]
+    featNames = []
+    for i in range(len(ptls)):
+        featNames.append('locPtl%d' % ptls[i])
+    if justfeatnames == True:
+        return featNames
+    sI = size(I)
+    nFeats = len(ptls)
+    F = np.zeros((sI[0],sI[1],nFeats))
+    for i in range(nFeats):
+        F[:,:,i] = ptlfilt(I,ptls[i],radius)
+    return F
+
+def localstats3(I,radius,justfeatnames=False):
+    ptls = [10,30,50,70,90]
+    featNames = []
+    for i in range(len(ptls)):
+        featNames.append('locPtl%d' % ptls[i])
+    if justfeatnames == True:
+        return featNames
+    sI = size(I)
+    nFeats = len(ptls)
+    F = np.zeros((sI[0],sI[1],sI[2],nFeats))
+    for i in range(nFeats):
+        F[:,:,:,i] = ptlfilt(I,ptls[i],radius)
+    return F
+
+def imderivatives(I,sigmas,justfeatnames=False):
+    if type(sigmas) is not list:
+        sigmas = [sigmas]
+    derivPerSigmaFeatNames = ['d0','dx','dy','dxx','dxy','dyy','normGrad','normHessDiag']
+    if justfeatnames == True:
+        featNames = [];
+        for i in range(len(sigmas)):
+            for j in range(len(derivPerSigmaFeatNames)):
+                featNames.append('derivSigma%d%s' % (sigmas[i],derivPerSigmaFeatNames[j]))
+        return featNames
+    nDerivativesPerSigma = len(derivPerSigmaFeatNames)
+    nDerivatives = len(sigmas)*nDerivativesPerSigma
+    sI = size(I)
+    D = np.zeros((sI[0],sI[1],nDerivatives))
+    for i in range(len(sigmas)):
+        sigma = sigmas[i]
+        dx = imgaussfilt(I,sigma,order=[0,1])
+        dy = imgaussfilt(I,sigma,order=[1,0])
+        dxx = imgaussfilt(I,sigma,order=[0,2])
+        dyy = imgaussfilt(I,sigma,order=[2,0])
+        D[:,:,nDerivativesPerSigma*i  ] = imgaussfilt(I,sigma)
+        D[:,:,nDerivativesPerSigma*i+1] = dx
+        D[:,:,nDerivativesPerSigma*i+2] = dy
+        D[:,:,nDerivativesPerSigma*i+3] = dxx
+        D[:,:,nDerivativesPerSigma*i+4] = imgaussfilt(I,sigma,order=[1,1])
+        D[:,:,nDerivativesPerSigma*i+5] = dyy
+        D[:,:,nDerivativesPerSigma*i+6] = np.sqrt(dx**2+dy**2)
+        D[:,:,nDerivativesPerSigma*i+7] = np.sqrt(dxx**2+dyy**2)
+    return D
+    # derivatives are indexed by the last dimension, which is good for ML features but not for visualization,
+    # in which case the expected dimensions are [plane,channel,y(row),x(col)]; to obtain that ordering, do
+    # D = np.moveaxis(D,[0,3,1,2],[0,1,2,3])
+
+def imderivatives3(I,sigmas,justfeatnames=False):
+    if type(sigmas) is not list:
+        sigmas = [sigmas]
+
+    derivPerSigmaFeatNames = ['d0','dx','dy','dz','dxx','dxy','dxz','dyy','dyz','dzz','normGrad','normHessDiag']
+
+    # derivPerSigmaFeatNames = ['d0','normGrad','normHessDiag']
+
+    if justfeatnames == True:
+        featNames = [];
+        for i in range(len(sigmas)):
+            for j in range(len(derivPerSigmaFeatNames)):
+                featNames.append('derivSigma%d%s' % (sigmas[i],derivPerSigmaFeatNames[j]))
+        return featNames
+    nDerivativesPerSigma = len(derivPerSigmaFeatNames)
+    nDerivatives = len(sigmas)*nDerivativesPerSigma
+    sI = size(I)
+    D = np.zeros((sI[0],sI[1],sI[2],nDerivatives)) # plane, channel, y, x
+    for i in range(len(sigmas)):
+        sigma = sigmas[i]
+        dx  = imgaussfilt(I,sigma,order=[0,0,1]) # z, y, x
+        dy  = imgaussfilt(I,sigma,order=[0,1,0])
+        dz  = imgaussfilt(I,sigma,order=[1,0,0])
+        dxx = imgaussfilt(I,sigma,order=[0,0,2])
+        dyy = imgaussfilt(I,sigma,order=[0,2,0])
+        dzz = imgaussfilt(I,sigma,order=[2,0,0])
+
+        D[:,:,:,nDerivativesPerSigma*i   ] = imgaussfilt(I,sigma)
+        D[:,:,:,nDerivativesPerSigma*i+1 ] = dx
+        D[:,:,:,nDerivativesPerSigma*i+2 ] = dy
+        D[:,:,:,nDerivativesPerSigma*i+3 ] = dz
+        D[:,:,:,nDerivativesPerSigma*i+4 ] = dxx
+        D[:,:,:,nDerivativesPerSigma*i+5 ] = imgaussfilt(I,sigma,order=[0,1,1])
+        D[:,:,:,nDerivativesPerSigma*i+6 ] = imgaussfilt(I,sigma,order=[1,0,1])
+        D[:,:,:,nDerivativesPerSigma*i+7 ] = dyy
+        D[:,:,:,nDerivativesPerSigma*i+8 ] = imgaussfilt(I,sigma,order=[1,1,0])
+        D[:,:,:,nDerivativesPerSigma*i+9 ] = dzz
+        D[:,:,:,nDerivativesPerSigma*i+10] = np.sqrt(dx**2+dy**2+dz**2)
+        D[:,:,:,nDerivativesPerSigma*i+11] = np.sqrt(dxx**2+dyy**2+dzz**2)
+
+        # D[:,:,:,nDerivativesPerSigma*i   ] = imgaussfilt(I,sigma)
+        # D[:,:,:,nDerivativesPerSigma*i+1 ] = np.sqrt(dx**2+dy**2+dz**2)
+        # D[:,:,:,nDerivativesPerSigma*i+2 ] = np.sqrt(dxx**2+dyy**2+dzz**2)
+    return D
+    # derivatives are indexed by the last dimension, which is good for ML features but not for visualization,
+    # in which case the expected dimensions are [plane,y(row),x(col)]; to obtain that ordering, do
+    # D = np.moveaxis(D,[2,0,1],[0,1,2])
+
+def imfeatures(I=[],sigmaDeriv=1,sigmaLoG=1,locStatsRad=0,justfeatnames=False):
+    if type(sigmaDeriv) is not list:
+        sigmaDeriv = [sigmaDeriv]
+    if type(sigmaLoG) is not list:
+        sigmaLoG = [sigmaLoG]
+    derivFeatNames = imderivatives([],sigmaDeriv,justfeatnames=True)
+    nLoGFeats = len(sigmaLoG)
+    locStatsFeatNames = []
+    if locStatsRad > 1:
+        locStatsFeatNames = localstats([],locStatsRad,justfeatnames=True)
+    nLocStatsFeats = len(locStatsFeatNames)
+    if justfeatnames == True:
+        featNames = derivFeatNames
+        for i in range(nLoGFeats):
+            featNames.append('logSigma%d' % sigmaLoG[i])
+        for i in range(nLocStatsFeats):
+            featNames.append(locStatsFeatNames[i])
+        return featNames
+    nDerivFeats = len(derivFeatNames)
+    nFeatures = nDerivFeats+nLoGFeats+nLocStatsFeats
+    sI = size(I)
+    F = np.zeros((sI[0],sI[1],nFeatures))
+    F[:,:,:nDerivFeats] = imderivatives(I,sigmaDeriv)
+    for i in range(nLoGFeats):
+        F[:,:,nDerivFeats+i] = imlogfilt(I,sigmaLoG[i])
+    if locStatsRad > 1:
+        F[:,:,nDerivFeats+nLoGFeats:] = localstats(I,locStatsRad)
+    return F
+
+def imfeatures3(I=[],sigmaDeriv=2,sigmaLoG=2,locStatsRad=0,justfeatnames=False):
+    if type(sigmaDeriv) is not list:
+        sigmaDeriv = [sigmaDeriv]
+    if type(sigmaLoG) is not list:
+        sigmaLoG = [sigmaLoG]
+    derivFeatNames = imderivatives3([],sigmaDeriv,justfeatnames=True)
+    nLoGFeats = len(sigmaLoG)
+    locStatsFeatNames = []
+    if locStatsRad > 1:
+        locStatsFeatNames = localstats3([],locStatsRad,justfeatnames=True)
+    nLocStatsFeats = len(locStatsFeatNames)
+    if justfeatnames == True:
+        featNames = derivFeatNames
+        for i in range(nLoGFeats):
+            featNames.append('logSigma%d' % sigmaLoG[i])
+        for i in range(nLocStatsFeats):
+            featNames.append(locStatsFeatNames[i])
+        return featNames
+    nDerivFeats = len(derivFeatNames)
+    nFeatures = nDerivFeats+nLoGFeats+nLocStatsFeats
+    sI = size(I)
+    F = np.zeros((sI[0],sI[1],sI[2],nFeatures))
+    F[:,:,:,:nDerivFeats] = imderivatives3(I,sigmaDeriv)
+    for i in range(nLoGFeats):
+        F[:,:,:,nDerivFeats+i] = imlogfilt(I,sigmaLoG[i])
+    if locStatsRad > 1:
+        F[:,:,:,nDerivFeats+nLoGFeats:] = localstats3(I,locStatsRad)
+    return F
+
+def stack2list(S):
+    L = []
+    for i in range(size(S)[2]):
+        L.append(S[:,:,i])
+    return L
+
+def thrsegment(I,wsBlr,wsThr): # basic threshold segmentation
+    G = imgaussfilt(I,sigma=(1-wsBlr)+wsBlr*5) # min 1, max 5
+    M = G > wsThr
+    return M
\ No newline at end of file