Files
pyTrainSeg/test.ipynb
T

361 KiB

Test with real image data and multiple filters

In [3]:
from skimage import io
import numpy as np
import matplotlib.pyplot as plt
from skimage import filters
from skimage import feature
from skimage.morphology import disk
from sklearn.ensemble import RandomForestClassifier
import os
import imageio
import sys
In [2]:
im = io.imread(r"U:\01_Python\00_playground\test_pytorch\Dataset\test_tomcat\test_im.tif")
plt.imshow(im)
# "U:\01_Python\00_playground\test_pytorch\Dataset\test_tomcat\water_truth.tif"
Out[2]:
<matplotlib.image.AxesImage at 0x21a7fc3b1f0>
No description has been provided for this image

load label images iteratively optimized in trainable weka segmentation

In [3]:
air = io.imread(r"U:\01_Python\00_playground\test_pytorch\Dataset\test_tomcat\air_truth.tif")>0
water = io.imread(r"U:\01_Python\00_playground\test_pytorch\Dataset\test_tomcat\water_truth.tif")>0
fiber = io.imread(r"U:\01_Python\00_playground\test_pytorch\Dataset\test_tomcat\fiber_truth.tif")>0
truth = io.imread(r"U:\01_Python\00_playground\test_pytorch\Dataset\test_tomcat\test_truth.tif")

develop feature Stack creation as in trainable weka segmentaion (TWS)

TWS creates Gaussian Blurs for sigma=0,1,2,4,8,16,... (whatever the limit is)

on each sigma, a sobel and hessian filter is applied

for hessian one image each for hessian, hessian trace, hessian determinant, hessian eigenvalue 1 & 2, hessian orientation, hessian square eigenvalue difference, normalized eigenvalue difference

difference of gaussians for all: larger sigma - smaller

Filters in TWS

In [92]:
def TWS_gaussian(im, sig=0):
    G = filters.gaussian(im, sigma=sig, mode='reflect', preserve_range=True)
    fullname = ''.join(['gaussian_',f'{sig:.1f}'])
    return G, fullname

def TWS_gaussian_stack(im, sigmas):
    fullnames = []
    gstack = np.zeros((im.shape[0],im.shape[1], len(sigmas)))
    for sig,i in zip(sigmas, range(len(sigmas))):
        if np.abs(sig-0)<0.1:
            gstack[:,:,i] = im
            name = ''.join(['gaussian_',f'{0:.1f}'])
        else:
            gstack[:,:,i], name = TWS_gaussian(im, sig)
        fullnames.append(name)
    return gstack, fullnames

def TWS_sobel(im, sig):
    #sigma is only passed to the name! make sure it's correct
    S = filters.sobel(im, mode='reflect')
    name = ''.join(['sobel_',f'{sig:.1f}'])
    return S, name

def TWS_sobel_stack(gstack, sigmas):
    Sstack = np.zeros(gstack.shape)
    fullnames = []
    for i in range(len(sigmas)):
        Sstack[:,:,i], name = TWS_sobel(gstack[:,:,i], sigmas[i])
        fullnames.append(name)
    return Sstack, fullnames

def TWS_hessian(im, sig):
    #creates 8 images per sigma
    #sigma is only passed to the name! make sure it's correct
    Hxx, Hxy, Hyy =  feature.hessian_matrix(im)
    a, b, d =  feature.hessian_matrix(im, mode='reflect')
    c = b
    
    mod = np.sqrt(a**2+b*c+d**2)
    trace = a+d
    det = a*d-c*b
    eig1 = (a+d)/2 + np.sqrt((4*b**2+(a-d)**2)/2)
    eig2 = (a+d)/2 - np.sqrt((4*b**2+(a-d)**2)/2)
    
    gamma_norm_eig_diff = (a-d)**2*((a-d)**2+4*b**2)
    square_norm_eig_diff = ((a-d)**2+4*b**2) 
    
    orient = 0.5*np.arccos(4*b**2+(a-d)**2)
    hessian_stack = np.dstack([mod,trace,det,eig1,eig2,orient,gamma_norm_eig_diff,square_norm_eig_diff])
    names = ['module', 'trace', 'determinant', 'eigenvalue1', 'eigenvalue2', 'orientation', 'gamma_norm_eig_diff', 'square_norm_eig_diff']

    fullnames = []
    for name in names:
        fullname = ''.join(['hessian_',name,'_',f'{sig:.1f}'])
        fullnames.append(fullname)
    return hessian_stack, fullnames

def TWS_hessian_stack(gstack, sigmas):
    size = len(sigmas)*8
    Hstack = np.zeros((gstack.shape[0],gstack.shape[1], size))
    fullnames = []
    for i in range(len(sigmas)):
        Hstack[:,:,i*8:i*8+8], names = TWS_hessian(gstack[:,:,i],sigmas[i])
        fullnames = fullnames + names
    return Hstack, fullnames
        

def TWS_diff_of_gaussians(gstack, sigmas):
    #creates a stack of {size} (see below)
    n = len(sigmas)
    size = int(n*(n-1)/2)
    
    diff_stack = np.zeros((im.shape[0], im.shape[1], size))
    fullnames = []
    cc = 0
    for i in range(1,n):
        for j in range(i):
            DG = gstack[:,:,i]-gstack[:,:,j]
            diff_stack[:,:,cc] = DG
            name = ''.join(['diff_of_gauss_',f'{sigmas[i]:.1f}','_',f'{sigmas[j]:.1f}'])
            fullnames.append(name)
            cc = cc + 1
    return diff_stack, fullnames
            
            
def TWS_minimum(im, sigma):
    M = filters.rank.minimum(im, disk(sigma))
    fullname = ''.join(['minimum_',f'{sigma:.1f}'])
    return M, fullname

def TWS_minimum_stack(im, sigmas):
    size = len(sigmas)-1
    min_stack = np.zeros((im.shape[0], im.shape[1], size))
    fullnames = []
    i = 0
    for i in range(size):
        sig = sigmas[i+1]
        min_stack[:,:,i], fullname = TWS_minimum(im, sig)
        fullnames.append(fullname)
    return min_stack, fullnames

def TWS_maximum(im, sigma):
    M = filters.rank.maximum(im, disk(sigma))
    fullname = ''.join(['maximum_',f'{sigma:.1f}'])
    return M, fullname

def TWS_maximum_stack(im, sigmas):
    size = len(sigmas)-1
    max_stack = np.zeros((im.shape[0], im.shape[1], size))
    fullnames = []
    i = 0
    for i in range(size):
        sig = sigmas[i+1]
        max_stack[:,:,i], fullname = TWS_maximum(im, sig)
        fullnames.append(fullname)
    return max_stack, fullnames
    

reverse engineered feature stack

In [76]:
def TWS_feature_stack(im, sigmas, feat_select):
        feat_names = []
        stack_list = []
    #TODO: allow ticking off features
    
        #gaussian filters
        if feat_select['Gaussian']:
            g_stack, gfeat = TWS_gaussian_stack(im, sigmas)
            stack_list.append(g_stack)
            feat_names = feat_names + gfeat
            
        #sobel filter on every gaussian sigma
        if feat_select['Sobel']:
            s_stack, sfeat = TWS_sobel_stack(g_stack, sigmas)
            stack_list.append(s_stack)
            feat_names = feat_names + sfeat
            
        #stack of hessian stacks for every sigma
        if feat_select['Hessian']:
            h_stack, hfeat = TWS_hessian_stack(g_stack, sigmas)
            stack_list.append(h_stack)
            feat_names = feat_names + hfeat
            
        #diff of gaussians
        if feat_select['Diff of Gaussians']:
            d_stack, dfeat = TWS_diff_of_gaussians(g_stack, sigmas)
            stack_list.append(d_stack)
            feat_names = feat_names + dfeat
        
        #minimum filters
        if feat_select['minimum']:
            min_stack, minfeat = TWS_minimum_stack(im, sigmas)
            stack_list.append(min_stack)
            feat_names = feat_names + minfeat

            
        #maximum filters
        if feat_select['maximum']:
            max_stack, maxfeat = TWS_maximum_stack(im, sigmas)
            stack_list.append(max_stack)
            feat_names = feat_names + maxfeat
            
        feat_stack = np.dstack(stack_list)
                        
        return feat_stack, feat_names
        
        
        
    

Function to classify one slice automatically detecting phases in truth image

In [8]:
def label_data_slice(im, truth, sigmas, feat_select, feat_stack=None):
    #TODO: automatically detect phases in truth image and aovid overlap
    #TODO: define format of truth image
    phase1 = truth==1
    phase2 = truth==2
    phase3 = truth==4
    
    if feat_stack is None:
        feat_stack, _ = TWS_feature_stack(im, sigmas, feat_select)
    
    X1 = feat_stack[phase1]
    y1 = np.zeros(X1.shape[0])
    X2 = feat_stack[phase2]
    y2 = np.ones(X2.shape[0])
    X3 = feat_stack[phase3]
    y3 = 2*np.ones(X3.shape[0])

    y = np.concatenate([y1,y2,y3])
    X = np.concatenate([X1,X2,X3])
    
    return X,y, feat_stack
In [63]:
 def classify_and_plot(X,y,im, feat_stack, plot=True):
    # TODO: allow choice and manipulation of ML method
    clf =  RandomForestClassifier(n_estimators = 200, n_jobs=-1, random_state = 42, max_features=None) 
    clf.fit(X, y)
    num_feat = feat_stack.shape[2]
    ypred = clf.predict(feat_stack.reshape(-1,num_feat))
    result = ypred.reshape(im.shape).astype(np.uint8)
    if plot:
        fig, (ax1, ax2)= plt.subplots(1,2,figsize=(12,7))
        ax1.imshow(im, cmap='Greys_r')
        ax2.imshow(result)
    return result, clf
In [126]:
def slicewise_classify_for_training(im, slice_name,sigmas, training_path, XTM_data_path, feat_select, plot=True,  feat_stack=None, truth=None, training_dict=None):
    #consider training data from other slices but do not simpliy append to avoid duplicates
    flag = False #TODO: get rid of flag
    if training_dict is not None:
        slices = list(training_dict.keys())
        if slice_name in slices: 
            slices.remove(slice_name)
        if len(slices)>0:
            flag = True
            Xall = training_dict[slices[0]][0]
            yall = training_dict[slices[0]][1]
            for i in range(1,len(slices)):
                Xall = np.concatenate([Xall, training_dict[slices[i]][0]])
                yall = np.concatenate([yall, training_dict[slices[i]][1]])
    
    
    if feat_stack is None:
        print('creating feature stack')
        X,y, feat_stack =  label_data_slice(im, truth, sigmas, feat_select)
    else:
        X,y, feat_stack =  label_data_slice(im, truth, sigmas, feat_select, feat_stack=feat_stack) 
    
    print('training and classifying')
    
    if training_dict is not None and flag:
        Xt = np.concatenate([Xall,X])
        yt = np.concatenate([yall,y])
        Xall = None
        yall = None
    else:
        Xt = X
        yt = y
    
    result, clf = classify_and_plot(Xt,yt,im, feat_stack, plot)
    
    print('save slice result, retrain if needed')
    imageio.imsave(os.path.join(training_path,''.join([slice_name,'_classified.tif'])), result)
    return X, y, feat_stack, clf        

end of definitions

train classifier and plot result on "test" slice

In [9]:
sigmas = [0, 2,4,6,8]  #hard-coded for now, sobel and hessian require that first sigma is 0, diff, gaussian(sig=0) = 0

# default feature choice
feat_select = {'Gaussian': True,
               'Sobel': True,
               'Hessian': True,
               'Diff of Gaussians': True
              }
    
In [10]:
slice_name = 'test'
training_path = r"U:\01_Python\00_playground\test_pytorch\Dataset\test_tomcat"
In [10]:
im = io.imread(r"U:\01_Python\00_playground\test_pytorch\Dataset\test_tomcat\test_im.tif")
air = io.imread(r"U:\01_Python\00_playground\test_pytorch\Dataset\test_tomcat\air_truth.tif")>0
water = io.imread(r"U:\01_Python\00_playground\test_pytorch\Dataset\test_tomcat\water_truth.tif")>0
fiber = io.imread(r"U:\01_Python\00_playground\test_pytorch\Dataset\test_tomcat\fiber_truth.tif")>0
truth = air+water*2+fiber*4
In [12]:
X,y, feat_stack, clf = slicewise_classify_for_training(im, slice_name, truth=truth,training_path = r"U:\01_Python\00_playground\test_pytorch\Dataset\test_tomcat", XTM_data_path = r"U:\01_Python\00_playground\test_pytorch\Dataset\test_tomcat")
creating feature stack
training and classifying
save slice result
No description has been provided for this image
In [13]:
training_dict = {}
training_dict[slice_name] = (X,y, feat_stack)

proper training workflow for 3 phases air, water, fiber TODO: make general

In [14]:
XTM_data_path = r"D:\TOMCAT_2\01_intcorrect_med_leg_0"
training_path = r"U:\01_Python\00_playground\test_pytorch\Dataset\test_tomcat\training"


time_folder = os.listdir(XTM_data_path)
timestep_folder = time_folder[0]
images_first = os.listdir(os.path.join(XTM_data_path, timestep_folder))
In [37]:
# randomly suggest slice for training
num_ts = len(time_folder)
num_slices = len(images_first)

ts = np.random.choice(range(num_ts))+1
print('try time step ',ts )
sn = np.random.choice(range(num_slices))+1
print('try slice number ', sn)

slice_name= ''.join(['ts_',str(ts),'_slice_',str(sn)])
watername = ''.join([slice_name, '_water.tif'])
waterpath = os.path.join(training_path, watername)
if not os.path.exists(waterpath):
    print('create missing training set with ImageJ-script!')
try time step  9
try slice number  326
create missing training set with ImageJ-script!
In [27]:
time_step = 15
slice_number = 519

time_folder = os.listdir(XTM_data_path)
timestep_folder = time_folder[time_step]
images = os.listdir(os.path.join(XTM_data_path, timestep_folder))
image_name = images[slice_number]
im = io.imread(os.path.join(XTM_data_path, timestep_folder, image_name))

slice_name= ''.join(['ts_',str(time_step),'_slice_',str(slice_number)])
watername = ''.join([slice_name, '_water.tif'])
waterpath = os.path.join(training_path, watername)
airname = ''.join([slice_name, '_air.tif'])
airpath = os.path.join(training_path, airname)
fibername = ''.join([slice_name, '_fiber.tif'])
fiberpath = os.path.join(training_path, fibername)

air = io.imread(airpath)>0
water = io.imread(waterpath)>0
fiber = io.imread(fiberpath)>0
truth = air+water*2+fiber*4

if slice_name in training_dict.keys():
    X,y, feat_stack, clf = slicewise_classify_for_training(im, slice_name, XTM_data_path=XTM_data_path, training_path=training_path, feat_stack=training_dict[slice_name][2], truth=truth, training_dict=training_dict)
else:
    X,y, feat_stack, clf = slicewise_classify_for_training(im, slice_name, XTM_data_path=XTM_data_path, training_path=training_path, truth=truth, training_dict=training_dict)

training_dict[slice_name] = (X,y, feat_stack)
print('training dict contains ',len(training_dict.keys()),'entries, keep track of memory')
training and classifying
save slice result
No description has been provided for this image
In [31]:
### make test feature_stack and names
_, feat_names = TWS_feature_stack(im, sigmas)
In [32]:
plt.figure( figsize=(16,9))
plt.plot(feat_names,clf.feature_importances_,'x')
plt.xticks(rotation=90)
Out[32]:
([0,
  1,
  2,
  3,
  4,
  5,
  6,
  7,
  8,
  9,
  10,
  11,
  12,
  13,
  14,
  15,
  16,
  17,
  18,
  19,
  20,
  21,
  22,
  23,
  24,
  25,
  26,
  27,
  28,
  29,
  30,
  31,
  32,
  33,
  34,
  35,
  36,
  37,
  38,
  39,
  40,
  41,
  42,
  43,
  44,
  45,
  46,
  47,
  48,
  49,
  50,
  51,
  52,
  53,
  54,
  55,
  56,
  57,
  58,
  59],
 [Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, '')])
No description has been provided for this image

segment wood time series

In [15]:
XTM_data_path = r"C:\Zwischenlager\wood_time_slices\00_raw"
training_path = r"C:\Zwischenlager\wood_time_slices\training_data"


time_folder = os.listdir(XTM_data_path)
timestep_folder = time_folder[0]
images_first = os.listdir(os.path.join(XTM_data_path, timestep_folder))
In [128]:
sigmas = [0, 2,4,8]  #hard-coded for now, sobel and hessian require that first sigma is 0, diff, gaussian(sig=0) = 0

# default feature choice
feat_select = {'Gaussian': True,
               'Sobel': True,
               'Hessian': True,
               'Diff of Gaussians': True,
               'maximum': True,
               'minimum': True
              }
    
In [129]:
feat_select
Out[129]:
{'Gaussian': True,
 'Sobel': True,
 'Hessian': True,
 'Diff of Gaussians': True,
 'maximum': True,
 'minimum': True}
In [121]:
training_dict = {}

iteratative loop

In [18]:
# randomly suggest slice for training
num_ts = len(time_folder)
num_slices = len(images_first)

ts = np.random.choice(range(num_ts))+1
print('try time step ',ts )
sn = np.random.choice(range(num_slices))+1
print('try slice number ', sn)

slice_name= ''.join(['ts_',str(ts),'_slice_',str(sn)])
watername = ''.join([slice_name, '_water.tif'])
waterpath = os.path.join(training_path, watername)
if not os.path.exists(waterpath):
    print('create missing training set with ImageJ-script!')
try time step  1
try slice number  67
create missing training set with ImageJ-script!
In [127]:
time_step = 5
slice_number = 54

time_folder = os.listdir(XTM_data_path)
timestep_folder = time_folder[time_step]
images = os.listdir(os.path.join(XTM_data_path, timestep_folder))
image_name = images[slice_number]
im = io.imread(os.path.join(XTM_data_path, timestep_folder, image_name))

slice_name= ''.join(['ts_',str(time_step),'_slice_',str(slice_number)])
watername = ''.join([slice_name, '_water.tif'])
waterpath = os.path.join(training_path, watername)
airname = ''.join([slice_name, '_air.tif'])
airpath = os.path.join(training_path, airname)
fibername = ''.join([slice_name, '_fiber.tif'])
fiberpath = os.path.join(training_path, fibername)

air = io.imread(airpath)>0
water = io.imread(waterpath)>0
fiber = io.imread(fiberpath)>0
truth = air+water*2+fiber*4

if slice_name in training_dict.keys():
    X,y, feat_stack, clf = slicewise_classify_for_training(im, slice_name,sigmas,XTM_data_path, training_path, feat_select,  feat_stack=training_dict[slice_name][2], truth=truth, training_dict=training_dict)
else:
    X,y, feat_stack, clf = slicewise_classify_for_training(im, slice_name,sigmas, XTM_data_path, training_path, feat_select, truth=truth, training_dict=training_dict)

training_dict[slice_name] = (X,y, feat_stack)
print('training dict contains ',len(training_dict.keys()),'entries, keep track of memory')
creating feature stack
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Input In [133], in <cell line: 23>()
     24     X,y, feat_stack, clf = slicewise_classify_for_training(im, slice_name,sigmas,XTM_data_path, training_path, feat_select,  feat_stack=training_dict[slice_name][2], truth=truth, training_dict=training_dict)
     25 else:
---> 26     X,y, feat_stack, clf = slicewise_classify_for_training(im, slice_name,sigmas, XTM_data_path, training_path, feat_select, truth=truth, training_dict=training_dict)
     28 training_dict[slice_name] = (X,y, feat_stack)
     29 print('training dict contains ',len(training_dict.keys()),'entries, keep track of memory')

Input In [126], in slicewise_classify_for_training(im, slice_name, sigmas, training_path, XTM_data_path, feat_select, plot, feat_stack, truth, training_dict)
     17 if feat_stack is None:
     18     print('creating feature stack')
---> 19     X,y, feat_stack =  label_data_slice(im, truth, sigmas, feat_select)
     20 else:
     21     X,y, feat_stack =  label_data_slice(im, truth, sigmas, feat_select, feat_stack=feat_stack) 

Input In [8], in label_data_slice(im, truth, sigmas, feat_select, feat_stack)
      6 phase3 = truth==4
      8 if feat_stack is None:
----> 9     feat_stack, _ = TWS_feature_stack(im, sigmas, feat_select)
     11 X1 = feat_stack[phase1]
     12 y1 = np.zeros(X1.shape[0])

Input In [76], in TWS_feature_stack(im, sigmas, feat_select)
     18 #stack of hessian stacks for every sigma
     19 if feat_select['Hessian']:
---> 20     h_stack, hfeat = TWS_hessian_stack(g_stack, sigmas)
     21     stack_list.append(h_stack)
     22     feat_names = feat_names + hfeat

Input In [130], in TWS_hessian_stack(gstack, sigmas)
     62 fullnames = []
     63 for i in range(len(sigmas)):
---> 64     Hstack[:,:,i*8:i*8+8], names = TWS_hessian(gstack[:,:,i],sigmas[i])
     65     fullnames = fullnames + names
     66 return Hstack, fullnames

ValueError: could not broadcast input array from shape (690,744,7) into shape (690,744,8)
In [38]:
feat_stack = training_dict['ts_5_slice_54'][2]
In [116]:
### make test feature_stack and names
_, feat_names = TWS_feature_stack(im, sigmas, feat_select)
C:\Users\fische_r\Miniconda3\envs\pyweka\lib\site-packages\skimage\filters\rank\generic.py:262: UserWarning: Bad rank filter performance is expected due to a large number of bins (38360), equivalent to an approximate bitdepth of 15.2.
  image, footprint, out, mask, n_bins = _preprocess_input(image, footprint,
In [123]:
plt.figure( figsize=(16,9))
plt.stem(feat_names,clf.feature_importances_,'x')
plt.xticks(rotation=90)
C:\Users\fische_r\AppData\Local\Temp\ipykernel_10900\968998534.py:2: MatplotlibDeprecationWarning: Passing the linefmt parameter positionally is deprecated since Matplotlib 3.5; the parameter will become keyword-only two minor releases later.
  plt.stem(feat_names,clf.feature_importances_,'x')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Input In [123], in <cell line: 2>()
      1 plt.figure( figsize=(16,9))
----> 2 plt.stem(feat_names,clf.feature_importances_,'x')
      3 plt.xticks(rotation=90)

File ~\Miniconda3\envs\pyweka\lib\site-packages\matplotlib\pyplot.py:2885, in stem(linefmt, markerfmt, basefmt, bottom, label, use_line_collection, orientation, data, *args)
   2880 @_copy_docstring_and_deprecators(Axes.stem)
   2881 def stem(
   2882         *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0,
   2883         label=None, use_line_collection=True, orientation='vertical',
   2884         data=None):
-> 2885     return gca().stem(
   2886         *args, linefmt=linefmt, markerfmt=markerfmt, basefmt=basefmt,
   2887         bottom=bottom, label=label,
   2888         use_line_collection=use_line_collection,
   2889         orientation=orientation,
   2890         **({"data": data} if data is not None else {}))

File ~\Miniconda3\envs\pyweka\lib\site-packages\matplotlib\__init__.py:1412, in _preprocess_data.<locals>.inner(ax, data, *args, **kwargs)
   1409 @functools.wraps(func)
   1410 def inner(ax, *args, data=None, **kwargs):
   1411     if data is None:
-> 1412         return func(ax, *map(sanitize_sequence, args), **kwargs)
   1414     bound = new_sig.bind(ax, *args, **kwargs)
   1415     auto_label = (bound.arguments.get(label_namer)
   1416                   or bound.kwargs.get(label_namer))

File ~\Miniconda3\envs\pyweka\lib\site-packages\matplotlib\axes\_axes.py:2890, in Axes.stem(self, linefmt, markerfmt, basefmt, bottom, label, use_line_collection, orientation, *args)
   2888         linestyle = rcParams['lines.linestyle']
   2889     xlines = self.vlines if orientation == "vertical" else self.hlines
-> 2890     stemlines = xlines(
   2891         locs, bottom, heads,
   2892         colors=linecolor, linestyles=linestyle, label="_nolegend_")
   2893 # Old behaviour is to plot each of the lines individually
   2894 else:
   2895     stemlines = []

File ~\Miniconda3\envs\pyweka\lib\site-packages\matplotlib\__init__.py:1412, in _preprocess_data.<locals>.inner(ax, data, *args, **kwargs)
   1409 @functools.wraps(func)
   1410 def inner(ax, *args, data=None, **kwargs):
   1411     if data is None:
-> 1412         return func(ax, *map(sanitize_sequence, args), **kwargs)
   1414     bound = new_sig.bind(ax, *args, **kwargs)
   1415     auto_label = (bound.arguments.get(label_namer)
   1416                   or bound.kwargs.get(label_namer))

File ~\Miniconda3\envs\pyweka\lib\site-packages\matplotlib\axes\_axes.py:1134, in Axes.vlines(self, x, ymin, ymax, colors, linestyles, label, **kwargs)
   1132 masked_verts[:, 0, 1] = ymin
   1133 masked_verts[:, 1, 0] = x
-> 1134 masked_verts[:, 1, 1] = ymax
   1136 lines = mcoll.LineCollection(masked_verts, colors=colors,
   1137                              linestyles=linestyles, label=label)
   1138 self.add_collection(lines, autolim=False)

File ~\Miniconda3\envs\pyweka\lib\site-packages\numpy\ma\core.py:3377, in MaskedArray.__setitem__(self, indx, value)
   3374     mval = tuple([False] * len(_dtype.names))
   3375 if _mask is nomask:
   3376     # Set the data, then the mask
-> 3377     _data[indx] = dval
   3378     if mval is not nomask:
   3379         _mask = self._mask = make_mask_none(self.shape, _dtype)

ValueError: could not broadcast input array from shape (2,) into shape (20,)
No description has been provided for this image
In [40]:
import robpylib
In [68]:
feat_files = []
for feat in feat_names:
    feat_files.append(feat+'.tif')
In [69]:
robpylib.CommonFunctions.ImportExport.WriteStackNew(r"C:\Zwischenlager\wood_time_slices\pywekastack", feat_files, feat_stack)
In [44]:
feat_names[0]
Out[44]:
'gaussian_0.0'
In [ ]: