I want to create an image out of an csv data.
I am reading the csv with:
f = open('file.csv', 'rb')
reader = csv.reader(f)
From here, I want to make a grayscale image that is translating each row of numbers in the list into a line of intensities in an image file.
Not sure what would be useful but here are some details about my csv file:
using floats, columns:315, rows: 144
Thanks
Two steps:
convert the csv file to a numpy array using genfromtxt
From #Andrew on How to read csv into record array in numpy?
from numpy import genfromtxt
my_data = genfromtxt('my_file.csv', delimiter=',')
then save the numpy array as an image
from numpy import genfromtxt
from matplotlib import pyplot
from matplotlib.image import imread
my_data = genfromtxt('path to csv', delimiter=',')
matplotlib.image.imsave('path to save image as Ex: output.png', my_data, cmap='gray')
image_1 = imread('path to read image as Ex: output.png')
# plot raw pixel data
pyplot.imshow(image_1)
# show the figure
pyplot.show()
For a very simple solution if you just want to get an impression of what the image would look like you can use the pgm format.
You can create it by writing out the pixels as ascii. The link goes into more detail but the gist is that you have a file of the format:
P2 //which format it is
width height //dimensions
maxValue //the highest value a pixel can have (represents white)
a b c ... //the pixel values (new line needed at the end of each row)
How you get the values out of the CSV should be straightforward, then you could use a function like (untested):
def toFile(array, filename):
f = file(filename, 'w')
f.write("P2\n%d %d\n255\n" %(len(array[1]), len(array))
for i in array:
for j in i:
f.write("%d " %(j))
f.write("\n")
f.close()
I think you could try with glob.glob, what should help
import numpy as np
import glob
import cv2
import csv
Libraries ⬆️; You know what⬇️
image_list = []
for filename in glob.glob(r'C:\your path to\file*.png'): # '*' will count files each by one
#Read
img = cv2.imread(filename)
flattened = img.flatten()
print(flattened) # recommend to avoid duplicates, see files and so on.
#Save
with open('output2.csv', 'ab') as f: #ab is set
np.savetxt(f, flattened, delimiter=",")
Cheers
Also, find an easier method that is making fast and not weight image/csv
image_list = []
with open('train_train_.csv', 'w') as csv_file:
csv_writer = csv.writer(csv_file, delimiter ='-')
for filename in glob.glob(r'C:\your path to\file*.png'):
img = cv2.imread(filename)
image_list.append(img)
csv_writer.writerow(img)
print(img)
Related
I created an model in blender. From here I took 2d slices through the y-plane of that model leading to the following.
600 png files each corresponding to a ylocation i.e y=0, y=0.1 etc
Each png file has a resolution of 500 x 600.
I am now trying to merge the 600 pngs into a h5 file using python before loading the .h5 into some software. I find that each individual png file is read fine and looks great. However when I look at the final 3d image there is some stretching of the image, and im not sure how this is being created.
The images are resized (from 600x600 to 500x600, but I have checked and this is not the cause of the stretching). I would like to know why I am introducing such stretching in other planes (not y-plane).
Here is my code, please note that there is some work in progress here, hence why I append the dataset to a list (this is to be used for later code)
from PIL import Image
import sys
import os
import h5py
import numpy as np
import cv2
from datetime import datetime
dir_path = os.path.dirname(os.path.realpath(__file__))
sys.path.append(dir_path + '//..//..')
Xlen=500
Ylen=600
Zlen=600
directory=dir_path+"/LowPolyA21/"
for filename in os.listdir(directory):
if fnmatch.fnmatch(filename, '*.png'):
image = Image.open(directory+filename)
new_image = image.resize((Zlen, Xlen))
new_image.save(directory+filename)
dataset = np.zeros((Xlen, Zlen, Ylen), np.float)
# traverse all the pictures under the specified address
cnt_num = 0
img_list = sorted(os.listdir(directory))
os.chdir(directory)
for img in (img_list):
if img.endswith(".png"):
gray_img = cv2.imread(img, 0)
dataset[:, :, cnt_num] = gray_img
cnt_num += 1
dataset[dataset == 0] = -1
dataset=dataset.swapaxes(1,2)
datasetlist=[]
datasetlist.append(dataset)
dz_dy_dz = (float(0.001),float(0.001),float(0.001))
for j in range(Xlen):
for k in range(Ylen):
for l in range(Zlen):
if datasetlist[i][j,k,l]>1:
datasetlist[i][j,k,l]=1
now = datetime.now()
timestamp = now.strftime("%d%m%Y_%H%M%S%f")
out_h5_path='voxelA_'+timestamp+'_flipped'
out_h5_path2='voxelA_'+timestamp+'_flipped.h5'
with h5py.File(out_h5_path2, 'w') as f:
f.attrs['dx_dy_dz'] = dz_dy_dz
f['data'] = datasetlist[i] # Write data to the file's primary key data below
Example of image without stretching (in y-plane)
Example of image with stretching (in x-plane)
*library
there is a mostly known library imported from NumPy and imageio
import NumPy as np
import os
import nibabel as nib
import imageio
// method where I have I write code to convert a nift to png
Method
convert a nift(.nii) image to png image
def nii_to_image(niifile):
filenames = os.listdir(filepath) #read nii folder
slice_trans = []
#filename is the path of nii image
for f in filenames:
#Start reading nii files
img_path = os.path.join(filepath, f)
img = nib.load(img_path) #read nii
img_fdata = img.get_fdata()
fname = f.replace('.nii','')
# Remove the nickname of nii
img_f_path = os.path.join(imgfile, fname)
#Create a folder corresponding to the image of nii
if not os.path.exists(img_f_path):
os.mkdir(img_f_path) #New folder
# to image
(x,y,z) = img.shape
for i in range(z): #x is the sequence of images
silce = img_fdata[i, :, :] #Select which direction the slice can be
imageio.imwrite(os.path.join(img_f_path,'{}.png'.format(i)), silce) #Save image
#main function where fill path was gived
main
if __name__ == '__main__':
filepath = '/content/drive/MyDrive/sem 8/dataset/pr'
imgfile = '/content/drive/MyDrive/sem 8/dataset/propi'
nii_to_image(filepath)
After you load the nifti file as NumPy array as you did, run on every slice (z from img.shape) and then save the array to png.
Make sure that when you run on each slice you save only the existing one (the z_slice_number):
slice = img_fdata[:, :, z_slice_numer]
And to save this slice you can do as follow (or another way from here):
matplotlib.image.imsave('name.png', slice)
I have a script here that takes the pixel coordinate data to draw rectangles around features within an image, often drawing multiple features within each image.
My entire script is:
import os
import numpy as np
import pandas as pd
import csv
%matplotlib inline
import PIL
from PIL import Image
from PIL import ImageDraw
import glob
import re
Creating a dataframe with the relevant values (filename and x/y/r pixel coords of the feature):
FandC = []
for index, row in data.iterrows():
filename = row['filename']
xyrcoords = row['points']
x, y, r = re.findall(r'[0-9.]+',xyrcoords)
print(f'DEBUG: filename={filename}, x={x}, y={y}, r={r}')
FandC.append({'filename': filename, 'x':x, 'y':y, 'r':r})
master_df = pd.DataFrame(FandC)
#creates a dataframe for "filename", "x", "y", and "r".
master_df.sort_values('filename', inplace = True, axis = 0)
master_df['filename'] [master_df['filename']=='M116_13331848_13109013315679.jpg']
# shows "master_df['filename']" where the "filename" is equal to (==) the string "M116_13331848_13109013315679.jpg"
Creating a function that draws rectangles around the features:
def draw_rectangle(filename, master_df):
img_path = 'G:\\Documents\\Thesis\\AutoSub_Images\\Compiled_transects\\{}'.format(filename)
im= Image.open(img_path)
img1_df = master_df[master_df['filename'].str.match(filename)]
im = im.convert('RGBA')
overlay = Image.new('RGBA', im.size)
draw = ImageDraw.Draw(overlay)
for index, row in img1_df.iterrows():
for i in range(len(img1_df)):
draw.rectangle(((float(row['x'])-float(row['r']), float(row['y'])-float(row['r'])), (float(row['x'])+float(row['r']), float(row['y'])+float(row['r']))), fill=(255,0,0,55))
#return coords
img = Image.alpha_composite(im, overlay)
img = img.convert("RGB")
img.save('G:\\Documents\\Thesis\\Outputs\\Outputs_JPGs\\annotated_{}'.format(filename))
Creating a function that saves the new data to .csv file:
def write_csv(filename, master_df):
csv_file = 'G:\\Documents\\Thesis\\Outputs\\Outputs_CSVs\\{}.csv'.format(filename[0:-4])
img1_df = master_df[master_df['filename'].str.match(filename)]
with open(csv_file, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['Filename', 'Centerpoint x', 'Centerpoint y', 'Height', 'Width'])
for index, row in img1_df.iterrows():
writer.writerow([row['filename'], float(row['x']), float(row['y']), float(row['r'])+float(row['r']), float(row['r'])+float(row['r'])])
Executing both functions above:
for i, row in master_df.iterrows():
if i == 0:
filename_tmp = row['filename']
draw_rectangle(filename_tmp, master_df)
write_csv(filename_tmp, master_df)
#print(row['filename'] == filename_tmp)
if row['filename'] == filename_tmp:
pass
#elif row['filename'] != filename_tmp:
else:
#load this img, and plot xenos on top.
filename_tmp = row['filename']
draw_rectangle(filename_tmp, master_df)
write_csv(filename_tmp, master_df)
if i == 50000:
break
The 'draw_rectangle' function above works well, and produces an image with all the features specified in the coordinate data highlighted by a red box, as seen here:
How can I modify this code (or specifically the draw rectangle function), so that instead of exporting the image above with 12 features highlighted on it, I actually export the 12 individual features as seperate image files?
If any clarification is needed, please feel free to ask :)
cheers,
R
After the line draw.rectangle() add some new code that does:
ROI = im.crop(YOUR BOUNDING BOX)
ROI.save(f'Crop-{i}.png', ROI)
I have two folders full of images (around 2000 files each) of different sizes. I need all of them in 28x28 format. After that I need to convert all of those images of each folder into one csv-file. Any ideas how I could do that? I'm an absolute beginner in python so please be a little bit patient, if i need more time to understand the basics.
I tried a solution I found here : Converting images to csv file in python
Specifically :
import numpy as np
import cv2
import os
IMG_DIR = 'C:/Users/Anwender/Documents/Uni/KI/Trainingsdaten/Train'
for img in os.listdir(IMG_DIR):
img_array = cv2.imread(os.path.join(IMG_DIR,img), cv2.IMREAD_GRAYSCALE)
img_array = (img_array.flatten())
img_array = img_array.reshape(-1,1).T
print(img_array)
with open('train.csv', 'ab') as f:
np.savetxt(f, img_array, delimiter=",")`
I hoped that changing img_array = img_array.reshape(-1,1).T into img_array = img_array.reshape(-1,28*28).T would give me the described result but instead delivers : "ValueError: cannot reshape array of size 2500 into shape (784)". I understand that there is no common denominator of both numbers so the dividing process without a remainder is not possible.
Use PIL to resize the image before converting into CSV.
import numpy as np
from PIL import Image
import cv2
import os
IMG_DIR = 'C:/Users/Anwender/Documents/Uni/KI/Trainingsdaten/Train'
for img in os.listdir(IMG_DIR):
img_array = cv2.imread(os.path.join(IMG_DIR,img), cv2.IMREAD_GRAYSCALE)
img_pil = Image.fromarray(img_array)
img_28x28 = np.array(img_pil.resize((28, 28), Image.ANTIALIAS))
img_array = (img_28x28.flatten())
img_array = img_array.reshape(-1,1).T
print(img_array)
with open('train.csv', 'ab') as f:
np.savetxt(f, img_array, delimiter=",")
You can use cv2.resize() to resize each image to 28X28.
Try below code:
for img in os.listdir(IMG_DIR):
img_array = cv2.imread(os.path.join(IMG_DIR,img), cv2.IMREAD_GRAYSCALE)
resized_image = cv2.resize(img_array, (28, 28))
img_flatten = resized_image.reshape(-1)
#print(img_flatten)
with open('train1.csv', 'ab') as f:
np.savetxt(f, img_flatten, delimiter=",")
In data.reshape function , -1 is used as a placeholder for figure out what the given dimension should be. You can also use resized_image.flatten() in place of img_flatten = resized_image.reshape(-1) to flatten the numpy array to one dimension.
In this case, each image will be saved into the csv file as a numpy array of shape (784,). On adding img_flatten.reshape(-1, 1).T to the above code will convert its shape to (1, 784). It's solely up to you how you want to save.
I'm working on a The Japanese Female Facial Expression (JAFFE) Database. You can find the database on this link http://www.kasrl.org/jaffe.html.
When I download the database I got a list of pictures. I would like to convert these image files into a CSV file but I'm still new in deep learning and I don't know how. Someone proposed that I work with OpenCV. what should I do?
i have simple example
i hope this help you.
from PIL import Image
import numpy as np
import sys
import os
import csv
def createFileList(myDir, format='.jpg'):
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
# load the original image
myFileList = createFileList('path/to/directory/')
for file in fileList:
print(file)
img_file = Image.open(file)
# 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')
value = np.asarray(img_grey.getdata(), dtype=np.int).reshape((img_grey.size[1], img_grey.size[0]))
value = value.flatten()
print(value)
with open("img_pixels.csv", 'a') as f:
writer = csv.writer(f)
writer.writerow(value)
Install pillow, numpy, pandas
Convert the image to RGB
plot RGB along with x,y co-ordinates in a pandas Dataframe
Save the dataframe as csv
Sample working code as below
from PIL import Image
from numpy import array, moveaxis, indices, dstack
from pandas import DataFrame
image = Image.open("data.tiff")
pixels = image.convert("RGB")
rgbArray = array(pixels.getdata()).reshape(image.size + (3,))
indicesArray = moveaxis(indices(image.size), 0, 2)
allArray = dstack((indicesArray, rgbArray)).reshape((-1, 5))
df = DataFrame(allArray, columns=["y", "x", "red","green","blue"])
print(df.head())
df.to_csv("data.csv",index=False)
You don't need to write any code, you can just use vips on the command-line on macOS, Linux or Windows.
So, in Terminal (or Command Prompt, if on Windows):
vips im_vips2csv TM.AN1.190.tiff result.csv
will convert the 256x256 greyscale image TM.AN1.190.tiff into a 256 line CSV with 256 entries per line. Simples!
If you want to replace the tab separators by commas, you can do:
tr '\t' , < result.csv > NewFile.csv