I am trying to get the image data (i.e. the grayscale values per pixel) for multiple images, and output them in a CSV file that contains one row for each image, and one column for each pixel. Eventually I want to run a convolutional neural network on them so that I can classify the shapes even if they are in different locations on the image.
Here is how I generated the shapes, if you want to do that yourself:
import numpy as np
import os
import tensorflow as tf
import tensorflow_datasets as tfds
from keras.models import Sequential
from keras.layers import Dense
from tensorflow.keras.layers import Dense, Conv2D, Dropout, Flatten, MaxPooling2D
from PIL import ImageDraw
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
from scipy import ndimage
from sklearn.preprocessing import LabelEncoder
import random
import imageio
import csv
import glob
print(tf.__version__)
# https://stackoverflow.com/questions/20747345/python-pil-draw-circle
# https://diycomputerscienceandelectronics.wordpress.com/2017/04/28/pygame-and-python-continued-draw-shapes-randomly-at-random-positions-on-the-screen20170428orderasc/
training = np.array([])
n=1
for i in range(1000):
img_size = 28
rand_num1 = random.uniform(0,img_size-0.25*img_size)
rand_num2 = random.uniform(0,img_size-0.3*img_size)
rand_num3 = random.uniform(0,img_size-0.3*img_size)
rand_num4 = random.uniform(0,img_size-0.3*img_size)
rand_num5 = random.uniform(0,img_size-0.15*img_size)
rand_num6 = random.uniform(0,img_size-0.15*img_size)
image = Image.new('RGBA', (img_size,img_size))
draw = ImageDraw.Draw(image)
if n % 3 == 1:
draw.ellipse((rand_num5, rand_num6, rand_num5+0.15*img_size, rand_num6+0.15*img_size), fill = 'black')
training = np.append(training, [['circle']])
image.save('circle%d.png' % i)
if n % 3 == 2:
draw.polygon([(rand_num3,rand_num2), (rand_num3+0.08*img_size, rand_num2+0.2*img_size), (rand_num3+0.25*img_size,rand_num2+0.05*img_size)], fill = "black")
training = np.append(training, [['triangle']])
image.save('triangle%d.png' % i)
if n % 3 == 0:
draw.rectangle(((rand_num1, rand_num4), (rand_num1+0.15*img_size, rand_num4+0.25*img_size)), fill="black")
training = np.append(training, [['rectangle']])
image.save('rectangle%d.png' % i)
n = n + 1
testing = np.array([])
for i in range(1000):
img_size = 28
rand_num1 = random.uniform(0,img_size-0.25*img_size)
rand_num2 = random.uniform(0,img_size-0.3*img_size)
rand_num3 = random.uniform(0,img_size-0.3*img_size)
rand_num4 = random.uniform(0,img_size-0.3*img_size)
rand_num5 = random.uniform(0,img_size-0.15*img_size)
rand_num6 = random.uniform(0,img_size-0.15*img_size)
image = Image.new('RGBA', (img_size,img_size))
draw = ImageDraw.Draw(image)
if n % 3 == 1:
draw.ellipse((rand_num5, rand_num6, rand_num5+0.15*img_size, rand_num6+0.15*img_size), fill = 'blue', outline ='blue')
testing = np.append(testing, [['circle']])
if n % 3 == 2:
draw.polygon([(rand_num3,rand_num2), (rand_num3+0.08*img_size, rand_num2+0.2*img_size), (rand_num3+0.25*img_size,rand_num2+0.05*img_size)], fill = (255,0,0))
testing = np.append(testing, [['triangle']])
if n % 3 == 0:
draw.rectangle(((rand_num1, rand_num4), (rand_num1+0.15*img_size, rand_num4+0.25*img_size)), fill="black")
testing = np.append(testing, [['rectangle']])
n = n + 1
I am aware of these links which get close to what I want, but don't quite: How can I convert a png to a dataframe for python? Converting images to csv file in python
When I attempt to use these solutions, I don't get any pixel data - just zeros - and I am only able to make the program work for only one image, not the 1000 that I have in my database.
Here is what I have tried:
import numpy as np
import cv2
import csv
for filen in glob.glob('*.png'):
#img_file = Image.open(filen)
img = cv2.imread(filen, 0) # load grayscale image. Shape (28,28)
flattened = img.flatten() # flatten the image, new shape (784,)
flattened = np.insert(flattened, 0, 0) # insert the label at the beginning of the array, in this case we add a 0 at the index 0. Shape (785,0)
#create column names
column_names = []
column_names.append("label")
[column_names.append("pixel"+str(x)) for x in range(0, 784)] # shape (785,0)
# write to csv
with open('custom_test.csv', 'w') as file:
writer = csv.writer(file, delimiter=';')
writer.writerows([column_names]) # dump names into csv
writer.writerows([flattened]) # add image row
# optional: add addtional image rows
and
def createFileList(myDir, format='.pgn'):
fileList = []
print(myDir)
for root, dirs, files in os.walk(myDir, topdown=False):
for name in files:
if name.endswith(format):
fullName = os.path.join(root, name)
fileList.append(fullName)
return fileList
for filen in glob.glob('*.png'):
print(filen)
img_file = Image.open(filen)
# img_file.show()
# get original image parameters...
width, height = img_file.size
format = img_file.format
mode = img_file.mode
# Make image Greyscale
#img_grey = img_file.convert('L')
#img_grey.save('result.png')
#img_grey.show()
# Save Greyscale values
value = np.asarray(img_file.getdata(), dtype=np.int).reshape((28, 28))
value = value.flatten()
train_example.append(value)
print(value)
with open("training_data.csv", 'w') as f:
writer = csv.writer(f)
writer.writerow(value)
print(train_example)