I am working on a program to take an image and flatten it so it can be written into a CSV file. That part works. I am having an issue when I try to read back the line from the CSV file. I try to reconstruct the image and I get an error of "ValueError: cannot reshape array of size 0 into shape (476,640,3)". I added sample output from the CSV file.
sample output
import csv
import cv2
import numpy as np
from skimage import io
from matplotlib import pyplot as plt
image = cv2.imread('Li.jpg')
def process_images (img):
img = np.array(img)
img = img.flatten()
return img
def save_data(img):
dataset = open('dataset.csv', 'w+')
with dataset:
writer = csv.writer(dataset)
writer.writerow(img)
def load_data():
with open('dataset.csv', 'r') as processed_data:
reader = csv.reader(processed_data)
for row in reader:
img = np.array(row , dtype='uint8')
img = img.reshape(476,6, 3)
return img
def print_image_stats (img):
print (img)
print (img.shape)
print (img.dtype)
def rebuilt_image(img):
img = img.reshape(476,640,3)
plt.imshow(img)
plt.show()
return img
p_images = process_images(image)
print_image_stats(p_images)
r_image = rebuilt_image(p_images)
print_image_stats(r_image)
save_data(p_images)
loaded_data = load_data()
#r_image = rebuilt_image(load_data)
#print_image_stats(r_image)
The empty lines at the end of the file you posted are significant. They are considered rows by the CSV reader object, and will be iterated over in your for loop. Thus there are passes through the loop in which an empty row is converted to an array of size zero, as the row has no elements. Resizing that obviously fails.
Either remove the rows from the CSV file, or directly use the np.loadtxt function, specifying the delimiter=',' option.
Related
I would like to perform a threshold analysis for several images, each with different values for the lower threshold limit. I would like to save the results in a csv file. Unfortunately, my code does not work the way I want it to. I am a python beginner.
Thanks for your help!
import cv2 as cv
import numpy as np
import os
import csv
x = []
y = []
Source_Path = 'Images/Image'
with open('Thresh.csv', 'w', newline='') as f:
writer = csv.writer(f)
for i, filename in enumerate(os.listdir(Source_Path)):
for j in range(100,255):
ret,thresh = cv.threshold(i,j,255,cv.THRESH_BINARY)
count = np.sum(thresh == 255)
x.append(count)
y.append(x)
writer.writerow(y)
You'll need to read the image first before you can threshold it. Start with
img = cv.imread("file.jpg")
img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(img, 120, 255, cv.THRESH_BINARY)
Don't worry about writing the results to a csv file until you have gathered all the statistics that you want in a numpy array. Then write that array to disk using
np.savetext("foo.csv", np_array, delimiter=",")
I have around 300 Images which I am fetching from Image URL. Each Image (RGB) is 256x256x3. I want a numpy array that I can feed into CNN model of shape = (300,256,256,3). How to do this in Python?
This code below is giving me error
X_data = np.array([])
print('Iterating across ',len(df_train),' rows')
for index,row in tqdm_notebook(df_train.iterrows()):
img = {}
try:
img = img_to_array(load_img(BytesIO(requests.get(row['IMAGE_URL_1']).content), target_size=(256, 256)))
X_data.append(img)
except Exception:
print('Error in Fetching Image_URL_1 = ',row['IMAGE_URL_1'],' lot = ',row['LOT_NUMBER'])
pass
You can the Pillow library for reading the image data from URL content. Here's is a simple example.
from io import BytesIO
from PIL import Image
import numpy as np
import requests
X_data = []
print('Iterating across ',len(df_train),' rows')
for index,row in tqdm_notebook(df_train.iterrows()):
try:
# https://pillow.readthedocs.io/en/3.1.x/reference/Image.html#PIL.Image.Image.resize
img = Image.open(BytesIO(requests.get(row['IMAGE_URL_1']).content)).resize((256, 256), PIL.Image.LANCZOS)
X_data.append(np.array(img))
except Exception:
print('Error in Fetching Image_URL_1 = ',row['IMAGE_URL_1'],' lot = ',row['LOT_NUMBER'])
pass
You are right: After the Code of Sanjay you need to convert the list to an array.
You do this by simply writing X_data_4D=np.stack(X_data, axis=0) after the for-loop.
Like that, you will convert a list of (256,256,3) images to one (300,256,256,3) array.
I'm a newbie in Python.
I want to extract RGB values from multiple images. I want to use RGB values of every images as an input of K-Fold Cross Validation.
I can only get the RGB values of one image only. So I tried to get from multiple images with the following code:
from __future__ import with_statement
from PIL import Image
import glob
#Path to file
for img in glob.glob({Path}+"*.jpg"):
im = Image.open(img)
#Load the pixel info
pix = im.load()
#Get a tuple of the x and y dimensions of the image
width, height = im.size
#Open a file to write the pixel data
with open('output_file.csv', 'w+') as f:
f.write('R,G,B\n')
#Read the details of each pixel and write them to the file
for x in range(width):
for y in range(height):
r = pix[x,y][0]
g = pix[x,x][1]
b = pix[x,x][2]
f.write('{0},{1},{2}\n'.format(r,g,b))
I expect to get input like this in CSV file:
img_name,R,G,B
1.jpg,50,50,50
2.jpg,60,60,70
But the actual output is the CSV file contain 40000+ rows.
Is it possible to automate RGB value from multiple images?
Your code is currently writing the value of each pixel as a separate row in your CSV file, so you are likely to have a huge number of rows.
To work on multiple files, you need to rearrange your code a bit and indent the file writing inside your loop. It might also be a good idea to make use of Python's CSV library to write the CSV file just in case any of your filenames contain commas. If this happened, it would correctly wrap the field in quotes.
from PIL import Image
import glob
import os
import csv
#Open a file to write the pixel data
with open('output_file.csv', 'w', newline='') as f_output:
csv_output = csv.writer(f_output)
csv_output.writerow(["img_name", "R", "G", "B"])
#Path to file
for filename in glob.glob("*.jpg"):
im = Image.open(filename)
img_name = os.path.basename(filename)
#Load the pixel info
pix = im.load()
#Get a tuple of the x and y dimensions of the image
width, height = im.size
print(f'{filename}, Width {width}, Height {height}') # show progress
#Read the details of each pixel and write them to the file
for x in range(width):
for y in range(height):
r = pix[x,y][0]
g = pix[x,y][1]
b = pix[x,y][2]
csv_output.writerow([img_name, r, g, b])
Note: There was also a problem with getting your r g b values, you had [x,x] in two cases.
As noted by #GiacomoCatenazzi, your loops could also be removed:
from itertools import product
from PIL import Image
import glob
import os
import csv
#Open a file to write the pixel data
with open('output_file.csv', 'w', newline='') as f_output:
csv_output = csv.writer(f_output)
csv_output.writerow(["img_name", "R", "G", "B"])
#Path to file
for filename in glob.glob("*.jpg"):
im = Image.open(filename)
img_name = os.path.basename(filename)
#Load the pixel info
pix = im.load()
#Get a tuple of the x and y dimensions of the image
width, height = im.size
print(f'{filename}, Width {width}, Height {height}') # show
#Read the details of each pixel and write them to the file
csv_output.writerows([img_name, *pix[x,y]] for x, y in product(range(width), range(height)))
I have a set of 1000 gray scale images (28x28), I want to read them into 4D numpy array (number of images, 1, img_dim1,img_dim2). Following is my code but it doesn't work properly. Any idea how I can fix the issue in the code?
from PIL import Image
import numpy as np
import os
mypath=os.path.dirname('path/to/directory/')
def load_dataset( ) :
data =np.zeros((1000,1,28,28), dtype=np.float64)
for fname in os.listdir(mypath):
pathname = os.path.join(mypath, fname)
img = Image.open(pathname)
data = np.dstack((data, img))
return data
data=load_dataset()
print(data.shape)
The problem has been solved by using append and adding a new axis np.newaxis
from PIL import Image
import numpy as np
import os
mypath=os.path.dirname('path/to/directory/')
def load_dataset( ) :
data =[]
for fname in os.listdir(mypath):
pathname = os.path.join(mypath, fname)
img = Image.open(pathname)
img1 = img[np.newaxis,:,:]
data.append(img1)
return data
data= load_dataset()
data_x=np.array(data)
print data_x.shape
So I have some problems with a simple image processing task. The code looks like this:
from scipy.misc.pilutil import imread, imsave
import numpy as np
infile = imread('in.png')
outfile = np.multiply(infile, 1.0).astype(int) # Just an example of array manipulation
print type(infile) == type(outfile) # True
# Exactly the same
print infile
print outfile
imsave('out.png', outfile)
This produces an array with different grayscale colors than the input image. It magically works if I change the manipulation to be outfile = np.multiply(infile, 1) (with an int instead of a float).
Can someone explain to me what I don't understand? The input image is a greyscale image.