1
Automation / Re: Grayvalues for Material ID's using Python
« on: June 24, 2025, 02:42:11 PM »
Hi,
your code worked more or less for me. In your plot it seems, as if no solid material ID was found. Did you load the segmented structure file with material ID 1 and 2?
By the way, it would be great if you would copy paste your code here instead of using screenshots. Then, it would be easier for me to reproduce the problem ;) Use the "#" symbol above the editor to enter the code beginning and ending markers
However I did not understand, why you want to divide the X-values by 2? Then the histogram gets moved to the left. I assume, that you wanted to account for the problem of the different lengths of the arrays count and bin_edges. For that I think it would be better to just remove the last entry of bin_edges. Even better would be to use matplotlib instead to plot the histogram. You can find an example for a very basic plot below. Matplotlib offers many options to change the plotting style as desired.
Another improvement you find in my code example below is to get the gray values with numpy.where instead of a for loop. This is much faster for large gray value images.
your code worked more or less for me. In your plot it seems, as if no solid material ID was found. Did you load the segmented structure file with material ID 1 and 2?
By the way, it would be great if you would copy paste your code here instead of using screenshots. Then, it would be easier for me to reproduce the problem ;) Use the "#" symbol above the editor to enter the code beginning and ending markers
However I did not understand, why you want to divide the X-values by 2? Then the histogram gets moved to the left. I assume, that you wanted to account for the problem of the different lengths of the arrays count and bin_edges. For that I think it would be better to just remove the last entry of bin_edges. Even better would be to use matplotlib instead to plot the histogram. You can find an example for a very basic plot below. Matplotlib offers many options to change the plotting style as desired.
Another improvement you find in my code example below is to get the gray values with numpy.where instead of a for loop. This is much faster for large gray value images.
Code: [Select]
import numpy as np
import matplotlib.pyplot as plt
VolumeInfo = gd.getVolumeFieldsInfo() # get list of dictionaries of loaded Volume Fields and assign it to variable VolumeInfo
nx, ny, nz = gd.getVolDimensions() # get the number of voxels in X-, Y- and Z-direction and assign the numbers to variables
Structure = gd.getStructure() # assign 3D numpy array describing the loaded structure to the variable Structure
Name = VolumeInfo[0]['name'] # assign the name of the volume field to the variable Name.
VolumeField = gd.getVolumeField(Name) # assign the numpy array describing the volume field to the variable VolumeField
Statistic = [] # Create empty list to store the statistical values
grayvalues = np.empty((nx,ny,nz),dtype=np.float32) # create 3D numpy array with the same shape as the gray value image
material_ID = np.where(Structure[:,:,:]==1) # find out where the structure has ID 1
grayvalues[material_ID]=VolumeField[material_ID] # take the gray values where the structure has ID 1 and save them in the new field
flat = grayvalues.flatten()
# ---------- plot with graph dialog GeoPy API ------------------
gDlg = gd.makeGraphDialog()
graph = gDlg.addGraph('Histogram', Name, "Voxel Count")
bin_count = 256
counts, bin_edges = np.histogram(flat,bins = bin_count, range=(0,255))
x_values = bin_edges[1:-1] # crop the first value, because the number of zeros is not interesting, crop the last value to match the number of entries in counts
y_values = counts[1:] # crop the first entry, because the number of zeros is not interesting
x_list = x_values.tolist()
y_list = y_values.tolist()
graph.addData(x_list,y_list, Name)
gDlg.run()
# ---------- plot with matplotlib ------------------
plt.hist(flat, bins=bin_edges)
plt.title('Histogram')
plt.xlabel('Gray Values')
plt.ylabel('Voxel Count')
plt.savefig('HistogramPlot.png')