Reputation: 157
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
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 of
matplotlib` 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
:
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