Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chaining multiple skimage functions leads to conversion issues #1334

Open
opticverge opened this issue Jan 13, 2015 · 6 comments
Open

Chaining multiple skimage functions leads to conversion issues #1334

opticverge opened this issue Jan 13, 2015 · 6 comments
Labels

Comments

@opticverge
Copy link

I am using the skimage library to chain a list of randomly selected skimage functions. During the chaining process a function will need to convert the image to a format for processing and it is here I experience the "Images of type float must be between -1 and 1". This is because a previous function, such as "histogram of oriented gradients" outputs an ndarray of type float with values less than -1 and greater than 1 then another function "adaptive histogram" attempts to convert the result and throws the error.

Does anyone know the best way to handle the conversion in order to ensure that a chain of transformations will execute successfully regardless of the type? Thanks.

@jni
Copy link
Member

jni commented Jan 13, 2015

Hi @thirdoctet,

hog is not supposed to output an image (unless you are using visualise=True?). In general though, function chaining should work across all images and types, assuming the initial image is within the valid range for its dtype.

Whether your result is expected or a bug depends entirely on the function sequence and on your original image's validity. Could you provide a minimal example with data and code for your error?

Thanks for reporting!

@opticverge
Copy link
Author

Yes I am using visualise=True for hog. Here is an example of multiple transformations being applied. As you can see I can successfully chain multiple image transformations, if i want to continue to chain beyond hog then i get the value error.

import matplotlib.pyplot as plt
from skimage.data import lena
from skimage import color
from skimage import exposure
from skimage import filter
from skimage import feature
from skimage import transform
from skimage.morphology import disk

lena = transform.resize(color.rgb2gray(lena()), (256, 256))

lena_transformed = filter.gabor_filter(lena, 1.77)[1]

lena_transformed = filter.rank.gradient(lena_transformed, disk(5))

lena_transformed = exposure.equalize_adapthist(lena_transformed, 10, 5, 0.28)

lena_transformed = filter.sobel(lena_transformed)

lena_transformed = filter.canny(lena_transformed, 0.473)

lena_transformed = feature.hog(lena_transformed, pixels_per_cell=(3, 3), visualise=True)[1]

#This is an example where the chaining fails
#lena_transformed = filter.rank.equalize(lena_transformed, disk(5))

fig, (ax0, ax1) = plt.subplots(nrows=2, figsize=(12,12))

ax0.imshow(lena, cmap=plt.cm.gray)
ax0.set_title('lena')
ax0.axis('off')

ax1.imshow(lena_transformed, cmap=plt.cm.gray)
ax1.set_title('multi transform sample')
ax1.axis('off')

plt.show()

@jni
Copy link
Member

jni commented Jan 13, 2015

Hey @thirdoctet,

This is a conundrum. On the one hand, you would never (I think) want to do what you're doing, which is to take the gradient of an edge of a gradient of a gradient of a gradient. (!!!) So in that sense it's not surprising that you're getting nonsense at the end of this thing.

On the other hand, there's various parts of that pipeline that are letting you down and maybe shouldn't. In particular,

  1. due to lack of precision, the filters.rank.gradient call converts the float image into a uint8 image with just three levels, (0, 1, 2). I wouldn't expect anything useful to come after that!
  2. the HOG image is invalid even after receiving valid(ish) input.

@stefanv @blink1073 any thoughts on this? My instinct:

  1. This is at a minimum a bug in the img_as_ubyte documentation, imho: it states "positive values are scaled between 0 and 255". A more accurate description would be "the interval [0.0, 1.0] is mapped to [0, 255]". Other than that, I don't see a consistent way to deal with very low dynamic range images. Perhaps we should not allow such images into rank filters?
  2. This is a bug in how the HOG image is generated, and it should be rescaled to prevent this.

@blink1073
Copy link
Member

I think the description should be along the lines of "positive values in the valid dtype range" to account for integer types as well. I agree that a rescale should be used prior to ranking, so that we are basing the rank on the full dynamic range. Agreed, HOG should generate a valid output range.

@stefanv
Copy link
Member

stefanv commented Jan 13, 2015

Agreed with all the above.

@opticverge
Copy link
Author

@jni ideally I would like to be able to chain and use the full range of applicable image transformations. If for any reason other chained transformations fail is there a pre processing stage I can apply? I.e prepare the image to avoid failure or best attempt to enable continuation

Thanks for any assistance

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants