Search code examples
pythonimagenumpycsvgenfromtxt

Converting height data from CSV file to IMG


I have some height data from a microscope. My question is: How can I convert CSV files to an IMG output and scale the color correctly? The data I have are CSV files like:

90,40,50,30,20
11, 2, 7,30,20
90,40,50,30,50
16,40,50, 4, 6
90, 4,50,30,20
...

Where the columns are the x coordinates, the rows are y coordinates, and the entries are the z coordinates.

Also it should be over a fixed scale. That means that the generated image should not be generated over the highest and lowest value, so that multiple files are comparable.

What I did so far is:

IMG = genfromtxt('RohCSV/{}.csv'.format(filename), delimiter=',')

That kind of works, but I have the scale problem. The results are not comparable.

I hope it is kind of understandable.


Solution

  • It depends on how you compare outputs. When using Matplotlib for example, you should get a min/max normalized output per default. Let's see the following example:

    from matplotlib import pyplot as plt
    import numpy as np
    
    plt.figure(1, figsize=(12, 5))
    
    # Original data/image
    IMG = np.genfromtxt('test.csv', delimiter=',')
    plt.subplot(1, 2, 1), plt.imshow(IMG), plt.colorbar()
    
    # Min/max normalized data/image
    IMG = IMG - np.min(IMG)
    IMG = IMG / np.max(IMG)
    plt.subplot(1, 2, 2), plt.imshow(IMG), plt.colorbar()
    
    plt.tight_layout()
    plt.show()
    

    That'd be the output:

    Output

    As you can see, the default output of Matplotlib (left) as well as the output of the explicitly min/max normalized data/image (right) are equal.

    Apart from that, the presented min/max normalization should be, what you're looking for.

    Hope that helps!

    -----------------------
    System information
    -----------------------
    Python:      3.8.1
    Matplotlib:  3.2.0rc1
    NumPy:       1.18.1
    -----------------------
    

    EDIT: After clarification in the comment, I guess using the vmin and vmax parameters in Matplotlib's imshow might be the simplest way to go:

    from matplotlib import pyplot as plt
    import numpy as np
    
    
    def plot_scaled(data, min_scale, max_scale):
        plt.imshow(data, vmin=min_scale, vmax=max_scale), plt.colorbar()
    
    
    # Original data/image
    IMG = np.genfromtxt('test.csv', delimiter=',')
    
    # Artificial data
    IMG_large = IMG + 10
    IMG_even_larger = IMG + 100
    
    plt.figure(1, figsize=(15, 4))
    for i, img in enumerate([IMG, IMG_large, IMG_even_larger]):
        plt.subplot(1, 3, i+1), plot_scaled(img, 0, 200)
    plt.tight_layout()
    plt.show()
    

    New output

    Value 100 has the same color in all three plots.