jeinsle / Grain_segmentation

5 stars 1 forks source link

Not able to calculate np.max(grain_nrm.data) #1

Open GanDuan opened 2 years ago

GanDuan commented 2 years ago

An TypeError appears in Input 6:

TypeError Traceback (most recent call last)

in ----> 1 grain_nrm.data = grain_nrm.data /np.max(grain_nrm.data) <__array_function__ internals> in amax(*args, **kwargs) /opt/anaconda3/lib/python3.8/site-packages/numpy/core/fromnumeric.py in amax(a, axis, out, keepdims, initial, where) 2731 5 2732 """ -> 2733 return _wrapreduction(a, np.maximum, 'max', axis, None, out, 2734 keepdims=keepdims, initial=initial, where=where) 2735 /opt/anaconda3/lib/python3.8/site-packages/numpy/core/fromnumeric.py in _wrapreduction(obj, ufunc, method, axis, dtype, out, **kwargs) 83 return reduction(axis=axis, dtype=dtype, out=out, **passkwargs) 84 else: ---> 85 return reduction(axis=axis, out=out, **passkwargs) 86 87 return ufunc.reduce(obj, axis, dtype, out, **passkwargs) /opt/anaconda3/lib/python3.8/site-packages/numpy/core/_methods.py in _amax(a, axis, out, keepdims, initial, where) 37 def _amax(a, axis=None, out=None, keepdims=False, 38 initial=_NoValue, where=True): ---> 39 return umr_maximum(a, axis, None, out, keepdims, initial, where) 40 41 def _amin(a, axis=None, out=None, keepdims=False, TypeError: cannot perform reduce with flexible type
jeinsle commented 2 years ago

Hi - I am not clear what the problem is here, could you please provide more information about the image you are trying to pass?

right now it looks like you are not passing a float/ interger array into the np.max - which is the numpy max function, which means you need to meet all the requirements of that function. So if your image is not in the correct type I would expect this error. But really can not adress with out more detail.

GanDuan commented 2 years ago

Hi Jeinsle, thanks very much for you quick response. I used hs.load to load an png file. And can see that the loaded data is a single2D file (hyperspy._signals.signal2d.Signal2D), and the grain.data is an array as below: Array([[(254, 254, 254), (255, 255, 255), (255, 255, 255), ..., (255, 255, 255), (255, 255, 255), (255, 255, 255)], [( 27, 30, 42), ( 27, 31, 41), ( 27, 31, 42), ..., ( 6, 8, 8), ( 6, 8, 8), ( 36, 40, 41)], [( 27, 31, 41), ( 27, 30, 39), ( 27, 31, 40), ..., ( 6, 8, 8), ( 6, 8, 8), ( 36, 40, 41)], ..., [( 33, 36, 44), ( 32, 35, 46), ( 33, 36, 44), ..., ( 32, 38, 49), ( 33, 40, 49), ( 70, 75, 86)], [( 33, 35, 44), ( 32, 35, 45), ( 33, 35, 44), ..., ( 33, 39, 50), ( 34, 39, 50), ( 71, 77, 86)], [( 68, 71, 80), ( 68, 71, 82), ( 68, 71, 80), ..., ( 71, 76, 86), ( 70, 75, 85), (107, 111, 118)]], dtype=[('R', 'u1'), ('G', 'u1'), ('B', 'u1')])

But the grain.data.shape is (12185, 7474), I suspect the right shape should be (12184, 7474, 4) as each pixel has four channels. Am I right? Or it doesn't matter?

GanDuan commented 2 years ago

Hi Jeinsle, I tired to convert the file from JPG to PNG, when loading JPG, it has three channels and when loading PNG, it has four channels. But I assume it shouldn't be a problem. The original JPG file is very big. Below is the PNG file used: T163_R_L

jeinsle commented 2 years ago

Ok this makes sense. I suspect that it has something to do with how the PNG file is being imported, espeically as they are not really a supported file format for hyperspy.

as you can see here the dtype is given as:

dtype=[('R', 'u1'), ('G', 'u1'), ('B', 'u1')])

where as usually with a tiff or similar image it would just say the data type that it is like this tiff from one of my projects (bold for emphasis)

[36880, 35536, 32368, ..., 43360, 43248, 44784]], dtype=uint16)

Also if you look at the shape below you can see there is some kind of flattening happening.

But the grain.data.shape is (12185, 7474), I suspect the right shape should be (12184, 7474, 4) as each pixel has four channels. Am I right? Or it doesn't matter?

Your image should have 3 or 4 channels depending on how the red-green-blue color mixing is stored origninally (either RGB or RGB plus alpha). I am not a full expert on PNG, but I think a few times that I have wanted to play with a PNG, I ended up converting to tiff first. here is a snipet of code to directly import using matplotlib's pyplot libary, and then convert that numpy into a signal 2D with 4 layers (one for each channel)

test=plt.imread('test.png')

test.shape

test_hs= hs.signals.Signal2D(test).transpose(signal_axes=(0,2))
print(test_hs.data.shape)

test_hs

at this point you need to make a decision about how to deal with the fact that you are now working with multichannel data. The workflow presented here is optimised around single channel electron microscopy images (we only have an intensity channel for back scattered electron data).

1) you could take the RGB data and either flattened / converted to a greyscale first or each channel handled seperately. The tools of SK-Image which we leverage for most of the workflow only work on a single channel at a time (or most do/ did at time of writing). There are several well known/ documented RGB- grayscale algorithms out there

2) alternativly, this becomes a low level data science problem to start pulling the phases apart that way... along the lines of color quantisation.

really your pick and depends on what you are trying to do with the image

GanDuan commented 2 years ago

Thanks for the detailed explanation! It totally makes sense to me know. You are right, I will try to convert it to greyscale first which should make things easier.

Cheers Gan

On Thu, 18 Aug 2022 at 20:48, Joshua F Einsle @.***> wrote:

Ok this makes sense. I suspect that it has something to do with how the PNG file is being imported, espeically as they are not really a supported file format for hyperspy.

as you can see here the dtype is given as:

dtype=[('R', 'u1'), ('G', 'u1'), ('B', 'u1')])

where as usually with a tiff or similar image it would just say the data type that it is like this tiff from one of my projects (bold for emphasis)

[36880, 35536, 32368, ..., 43360, 43248, 44784]], dtype=uint16)

Also if you look at the shape below you can see there is some kind of flattening happening.

But the grain.data.shape is (12185, 7474), I suspect the right shape should be (12184, 7474, 4) as each pixel has four channels. Am I right? Or it doesn't matter?

Your image should have 3 or 4 channels depending on how the red-green-blue color mixing is stored origninally (either RGB or RGB plus alpha). I am not a full expert on PNG, but I think a few times that I have wanted to play with a PNG, I ended up converting to tiff first. here is a snipet of code to directly import using matplotlib's pyplot libary, and then convert that numpy into a signal 2D with 4 layers (one for each channel)

test=plt.imread('test.png')

test.shape

test_hs= hs.signals.Signal2D(test).transpose(signal_axes=(0,2)) print(test_hs.data.shape)

test_hs

at this point you need to make a decision about how to deal with the fact that you are now working with multichannel data. The workflow presented here is optimised around single channel electron microscopy images (we only have an intensity channel for back scattered electron data).

1.

you could take the RGB data and either flattened / converted to a greyscale first or each channel handled seperately. The tools of SK-Image which we leverage for most of the workflow only work on a single channel at a time (or most do/ did at time of writing). There are several well known/ documented RGB- grayscale algorithms out there 2.

alternativly, this becomes a low level data science problem to start pulling the phases apart that way... along the lines of color quantisation.

really your pick and depends on what you are trying to do with the image

— Reply to this email directly, view it on GitHub https://github.com/jeinsle/Grain_segmentation/issues/1#issuecomment-1219451583, or unsubscribe https://github.com/notifications/unsubscribe-auth/AW3UHXJSO7CLVNS5WIR57QTVZYWJLANCNFSM564L3BBQ . You are receiving this because you authored the thread.Message ID: @.***>

jeinsle commented 2 years ago

not a problem. glad it helps. Again, I would emphasie that depending on what you are trying to get out of that image you need to be really careful how you do the conversion from RGBA to grayscale. especially as this will have the effect of flattening some mineral/ material information at best and combining two differnt catagories to the same feature at worst.