snelzb
snelzb

Reputation: 157

Convert csv file having pixel values into images

I have a csv file, in which each row contains the pixel values for an image. Therefore, each column of a row contains pixel values, except for the last column, which contains the 'labels' for the image, which are words such as "coat", "dress", "sandal" etc. (Note: First row contains the column names and is not an image).

I wish to read these rows as images and save all of them (preferably sorted by label, such as 'dress1', 'dress2',....,'sandal1', 'sandal2',.., etc. for each of the four labels).

I tried the following approach for saving without label classification, but I am getting an error:

import numpy as np
import csv
import matplotlib.pyplot as plt
i=0
with open('myfile.csv', 'r') as csv_file:
      for data in csv.reader(csv_file):
      pixels = data[:]
      pixels = np.array(pixels, dtype='uint8')
      #Reshape the array into 28 x 28 array (As images are 28x28)
      pixels = pixels.reshape((28, 28)) 
      i +=1
      plt.savefig(str(i))

Looking for the most efficient way to go about this. Any inputs will be appreciated. Thanks!

Upvotes: 1

Views: 5636

Answers (1)

furas
furas

Reputation: 142744

If you have name in last column then you have to convert without last element data[:-1]. And use last column in filenamename savefig( data[-1] + str(i) + '.jpg' ). Without extension it may not know what type of image to write.

You have to count i for every label separatelly - ie. using dict

i = dict() 
i[label] = 0 

# later 

i[label] += 1 
savefig( label + str(i[label]) + '.jpg' 

You can also use PIL/'pillowinstead ofmatplotlib` to write it.

from PIL import Image    

image = Image.fromarray(pixels)
image.save(filename)

import numpy as np
import csv
from PIL import Image    

counter = dict()

with open('myfile.csv') as csv_file:
    csv_reader = csv.reader(csv_file)

    # skip headers
    next(csv_reader)

    for row in csv.reader(csv_reader):

        pixels = row[:-1] # without label
        pixels = np.array(pixels, dtype='uint8')
        pixels = pixels.reshape((28, 28))
        image = Image.fromarray(pixels)

        label = row[-1]

        if label not in counter:
            counter[label] = 0
        counter[label] += 1

        filename = '{}{}.jpg'.format(label, counter[label])
        image.save(filename)

        print('saved:', filename)

EDIT: Example which show it with one row of data for those which whan to test it without downloading csv file.

import numpy as np
import csv
from PIL import Image

counter = dict()

row = [
        255,   0,   0,   0,   0,   0,  255,
          0, 255, 255, 255, 255, 255,    0,
          0, 255,   0, 255,   0, 255,    0,
          0, 255, 255, 255, 255, 255,    0,
          0, 255,   0,   0,   0, 255,    0,
          0, 255, 255, 255, 255, 255,    0,
        255,   0,   0,   0,   0,   0,  255,
        'face'
      ]

pixels = row[:-1]

pixels = np.array(pixels, dtype='uint8')
pixels = pixels.reshape((7, 7))
image = Image.fromarray(pixels)

label = row[-1]

if label not in counter:
    counter[label] = 0
counter[label] += 1

filename = '{}{}.png'.format(label, counter[label])

image.save(filename)

print('saved:', filename)

Result: face1.png:

enter image description here


EDIT: I checked your csv file and pixels are not integer values but float (positive, negative) values so you can't use uint8. It has to be float.

pixels = np.array(pixels, dtype='float')

You could convert image to RGB or grayscale L to save it

image = image.convert('RGB')
image = image.convert('L')

but it seems it has problem to convert negative values.

Using

plt.imsave(filename, pixels)

I get expected result


import numpy as np
import csv
from PIL import Image    
import matplotlib.pyplot as plt

counter = dict()

with open('gen_image_wgan.csv') as csv_file:
    csv_reader = csv.reader(csv_file)

    # skip headers
    next(csv_reader)

    for row in csv_reader:

        pixels = row[:-1] # without label
        pixels = np.array(pixels, dtype='float')
        pixels = pixels.reshape((28, 28))

        label = row[-1]

        if label not in counter:
            counter[label] = 0
        counter[label] += 1

        filename = '{}{}.png'.format(label, counter[label])
        plt.imsave(filename, pixels)

        print('saved:', filename)

Upvotes: 2

Related Questions