Residual image cannot be generated due to shape differences

Issue #13 new
Former user created an issue

Hey there,

I tried to generate a residual image but received a value error stating that residual image cannot be reshaped into the shape of the actual image.

The issue seems to be in the _residual_image() function and image_as_line attribute:

In the former this line

residuals = self.image_as_line - np.sum(fractions[np.newaxis, :, 0:-1] * endmembers, axis=2)

gives a value error because the shapes within the np.sum() are different. If I am not mistaking, this first issue is that the class axis is subset instead of the first spatial axis and the second one is that summation is not done over the class axis. I think this solves the first two problems inside the np.sum():

residuals = self.image_as_line - np.sum(fractions[np.newaxis, 0:-1, :] * endmembers, axis=1)

Furthermore, the image_as_line attribute does not have the no_data_pixels, resulting in a different number of pixels compared to the result of np.sum(). Instead the image can be used like:

residuals = image - np.sum(fractions[np.newaxis, 0:-1, :] * endmembers, axis=1)

I hope this makes sense.

Best, Marcel

Comments (2)

  1. Marcel KOENIG

    Above statement can be ignored: I figured out that I did my testing on 3D arrays while fractions and models are 2D arrays inside the functions.

    Yet, the problem persists and is related to the no_data_pixels:

    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
    /tmp/ipykernel_1827220/2586602671.py in <module>
         32                                             use_band_weighing = False, # use the weighted linear spectral mixture analysis (Somers et al, 2009), default: False
         33                                             use_band_selection = False, # use the bands selection algorithm (Somers et al, 2010), default: False
    ---> 34                                             bands_selection_values = (0.99, 0.01) # correlation threshold and decrease for the band selection algorithm, default: (0.99, 0.01)
         35                                            )
         36 
    
    ~/.conda/envs/CarbonMapper_py3712/lib/python3.7/site-packages/mesma/core/mesma.py in execute(self, image, library, look_up_table, em_per_class, constraints, fusion_value, no_data_pixels, shade_spectrum, residual_image, use_band_weighing, use_band_selection, bands_selection_values, log)
        566                     np.reshape(fractions_expanded.T, (self.n_classes + 1,) + image_dimensions),
        567                     np.reshape(rmse_expanded, image_dimensions),
    --> 568                     np.reshape(residuals, image.shape))
        569 
        570         else:
    
    <__array_function__ internals> in reshape(*args, **kwargs)
    
    ~/.conda/envs/CarbonMapper_py3712/lib/python3.7/site-packages/numpy/core/fromnumeric.py in reshape(a, newshape, order)
        296            [5, 6]])
        297     """
    --> 298     return _wrapfunc(a, 'reshape', newshape, order=order)
        299 
        300 
    
    ~/.conda/envs/CarbonMapper_py3712/lib/python3.7/site-packages/numpy/core/fromnumeric.py in _wrapfunc(obj, method, *args, **kwds)
         55 
         56     try:
    ---> 57         return bound(*args, **kwds)
         58     except TypeError:
         59         # A TypeError occurs if the object does have such a method in its
    
    ValueError: cannot reshape array of size 24107036 into shape (314,100,768)
    

  2. Marcel KOENIG

    OK, the problem seems to be in line 568 in mesma.py where residuals should be changed to residuals_expanded.

    The original code is:

                return (np.reshape(models_expanded.T, (self.n_classes,) + image_dimensions),
                        np.reshape(fractions_expanded.T, (self.n_classes + 1,) + image_dimensions),
                        np.reshape(rmse_expanded, image_dimensions),
                        np.reshape(residuals, image.shape))
    

    and I think the problem is solved with this one:

    return (np.reshape(models_expanded.T, (self.n_classes,) + image_dimensions),
                        np.reshape(fractions_expanded.T, (self.n_classes + 1,) + image_dimensions),
                        np.reshape(rmse_expanded, image_dimensions),
                        np.reshape(residuals_expanded, image.shape))
    

  3. Log in to comment