5

I'm trying a simple disk filter applied to a fits file:

from skimage.morphology import disk
from skimage.filters.rank import median
import numpy as np
import matplotlib.pyplot as plt
from astropy.io import fits

#    Open data files for image and mask
hdulist = fits.open('xbulge-w1.fits')
w1data = hdulist[0].data

hdulistmask = fits.open('xbulge-mask.fits')
maskdata = hdulistmask[0].data
mask = 1 - maskdata

w1_masked = np.ma.array(w1data, mask = mask)
selem = disk(5)
filt = median(w1_masked,
                            selem=disk(5),
                            out=None,
                            mask=mask)

plt.imshow(filt)
plt.show()

but this gives me a "ValueError: Images of type float must be between -1 and 1." What's going on?

Jim421616
  • 1,434
  • 3
  • 22
  • 47
  • Possible duplicate of [Why skimage mean filter does not work on float array?](https://stackoverflow.com/questions/45669794/why-skimage-mean-filter-does-not-work-on-float-array) – iled Apr 18 '18 at 01:22

1 Answers1

5

This should help you solve your problem. I initially wrote this answer for this question that was about the same message error, also for a filtering operation.

In general, (and this is valid for other programming languages), an image can be typically represented in 2 ways:

  • with intensity values in the range [0, 255]. In this case the values are of type uint8 - unsigned integer 8-bytes.
  • with intensity values in the range [0, 1]. In this case the values are of type float.

Depending on the language and library, the types and range of values allowed for the pixels' intensity can be more or less permissive.

The error here tells you that the pixels' values of your image are of type float but that they are not in the range [-1, 1]. If the values are in between [0, 255] (or [-255, 255]), you just need to divide them all by 255. Converting the values to integers may also work.

This holds for images represented as regular arrays (or matrices, depending on the language). In your case the use of masked arrays involves masked values that are neither floats nor integers. Hence, I doubt you can use regular filtering functions if you keep on using masked arrays.

Eskapp
  • 3,419
  • 2
  • 22
  • 39
  • I've added the lines w1_masked_rescaled = w1_masked/255 print(np.any(w1_masked_rescaled > 1)) below the declaration of w1_masked but I still get the same error. Where should I be dividing by 255? – Jim421616 Aug 15 '17 at 21:02
  • I don't think you can use masked arrays... If you want to use a regular filtering function, you will need to replace the masked values by a valid value, keep track of the position of the masked values and add them back... The documentation of `numpy.ma` does not mention any filtering operation... – Eskapp Aug 15 '17 at 21:10
  • What about this? https://docs.scipy.org/doc/numpy/reference/generated/numpy.ma.median.html – Jim421616 Aug 15 '17 at 21:32
  • 1
    This computes the median of an array, it does not do the filtering operation as you present it in your question (with the structuring element that is a disk). If you are willing to code yourself the filtering operation (the sliding disk over the masked array) you can use it. – Eskapp Aug 16 '17 at 16:25