1

I have a simple task to accomplish, but the current save functions I am finding are not helping me at all. What I have to do is simply convert a gray-scale image to another one which has intensities belonging to a smaller interval (specifically between 120 and 180).

I implemented the conversion (like a changing different temperature scales), but when I save the image, scipy.misc.imsave normalizes it. The conversion is correct because I created histograms to display the intensities before the saving, and they are all lying between the specified range.

I've tried other tools like:

imageio.imwrite(path, img)
numpy.save(path, img)
scipy.misc.toimage(img, cmin=120, cmax=180, mode='L').save(path)

I confess this last one I don't understand the parameters quite well (I have a guess), and the documentation didn't help. Could anybody help me with this issue?

EDIT: I am posting the code

def ex3():
    I = misc.imread(imgname)
    N =  numpy.multiply(I , float(12.0/51.0))
    N = numpy.add(N, 120)
    NEG = I
    NEG = numpy.add(NEG, -255)
    NEG = numpy.absolute(NEG)
    misc.imsave(path, N)
    misc.imsave(os.getcwd()+"/a0/results/"+file.replace(path, NEG)

The image was perfectly rendered when I switched to OpenCV. But I would like to stick with Scipy if possible.

Warren Weckesser
  • 110,654
  • 19
  • 194
  • 214
  • 1
    `np.save` shouldn't add any normalization or changes to `img` (provided it is a `ndarray`). – hpaulj Mar 09 '18 at 17:00
  • It would help if you post the part of your code that is failing. Use something like `img = np.random.randn(...)` to replace your data with something equivalent for this example. – user2699 Mar 09 '18 at 18:41
  • Thanks for your answer. @user2699 I updated the post. If there is anything you would like to request, let me know. hpaulj, unfortunately I've already tried to use np.save, but I got the normalized image as well. But I agree with you: it should not do that. – Alan Ricardo Mar 09 '18 at 20:22
  • See [this question](https://stackoverflow.com/questions/33529401/scipy-imsave-saves-wrong-values) and my answer there. – Warren Weckesser Mar 10 '18 at 02:01
  • 1
    `numpy.save` does not normalize the data, but it also does not save the data in an image format. – Warren Weckesser Mar 10 '18 at 02:05
  • Thank you, @WarrenWeckesser. It worked fine now that I set the datatype. I answered the question giving you the credits for it. – Alan Ricardo Mar 11 '18 at 15:23

2 Answers2

1

As answered by Warren Weckesser on this question, there is no normalization of the values, but the functions re scale the values according to the data type. The solution for this issue is to set datatype of the array image to uint8 as it can be seen bellow:

misc.imsave(path, img.astype(numpy.uint8))  
0

I had a similar problem with matplotlib imsave and was looking at converting to scipy imsave based on Alan's solution when I managed to get it working.

Using matplotlib:

palette_cm = ['#000000', '#ff0000', '#00ff00', '#0000ff', 
                '#ffff00', '#ff00ff', '#00ffff', '#ffffff']
def myColorMap():
    return ListedColormap(palette_cm)
plt.imsave('test.png', im.astype(np.uint8), cmap=myColorMap(), vmin=0, vmax=7)

The uint8 should have caused imsave to have the same behavior as in scipy, fixing as specific values, and in one method it did. In another method it was scaling the range even with explicit casts, so I had to add the vmin and vmax options. This may have been caused by my 8 value colormap, but the autoscaling of uint8 is specifically mentioned as a defect in github issues posts for matplotlib.

user15741
  • 1,392
  • 16
  • 27