Visualize MNIST dataset using OpenCV or Matplotlib/Pyplot - python

i have MNIST dataset and i am trying to visualise it using pyplot. The dataset is in cvs format where each row is one image of 784 pixels. i want to visualise it in pyplot or opencv in the 28*28 image format. I am trying directly using :
plt.imshow(X[2:],cmap =plt.cm.gray_r, interpolation = "nearest")
but i its not working? any ideas on how should i approach this.

Assuming you have a CSV file with this format, which is a format the MNIST dataset is available in
label, pixel_1_1, pixel_1_2, ...
Here's how you can visulize it in Python with Matplotlib and then OpenCV
Matplotlib / Pyplot
import numpy as np
import csv
import matplotlib.pyplot as plt
with open('mnist_test_10.csv', 'r') as csv_file:
for data in csv.reader(csv_file):
# The first column is the label
label = data[0]
# The rest of columns are pixels
pixels = data[1:]
# Make those columns into a array of 8-bits pixels
# This array will be of 1D with length 784
# The pixel intensity values are integers from 0 to 255
pixels = np.array(pixels, dtype='uint8')
# Reshape the array into 28 x 28 array (2-dimensional array)
pixels = pixels.reshape((28, 28))
# Plot
plt.title('Label is {label}'.format(label=label))
plt.imshow(pixels, cmap='gray')
plt.show()
break # This stops the loop, I just want to see one
OpenCV
You can take the pixels numpy array from above which is of dtype='uint8' (unsigned 8-bits integer) and shape 28 x 28 , and plot with cv2.imshow()
title = 'Label is {label}'.format(label=label)
cv2.imshow(title, pixels)
cv2.waitKey(0)
cv2.destroyAllWindows()

Importing necessary packages
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
Reading mnist train dataset ( which is csv formatted ) as a pandas dataframe
s = pd.read_csv("mnist_train.csv")
Converting the pandas dataframe to a numpy matrix
data = np.matrix(s)
The first column contains the label, so store it in a separate array
output = data[:, 0]
And delete the first column from the data matrix
data = np.delete(data, 0, 1)
The first row represents the first image, it is 28X28 image (stored as 784 pixels)
img = data[0].reshape(28,28)
# And displaying the image
plt.imshow(img, cmap="gray")

For all like me who want a quick and dirty solution, simply to get a rough idea what a given input is about, in-console and without fancy libraries:
def print_greyscale(pixels, width=28, height=28):
def get_single_greyscale(pixel):
val = 232 + round(pixel * 23)
return '\x1b[48;5;{}m \x1b[0m'.format(int(val))
for l in range(height):
line_pixels = pixels[l * width:(l+1) * width]
print(''.join(get_single_greyscale(p) for p in line_pixels))
(expects the input to be shaped like [784] and with float values from 0 to 1. If either is not the case, you can easily convert (e.g. pixels = pixels.reshape((784,)) or pixels \= 255)
The output is a bit distorted but you get the idea.

Related

How to convert a csv dataset to a numpy array readable by opencv?

I have a csv dataset namely sign language mnist dataset. It contains information of 28x28 images with its pixel information. I would like to convert this dataset into a numpy array that can be read by opencv3. A numpy array where i can manipulate through opencv. I would like to apply histogram of oriented gradients into this dataset through opencv.
I have already successfully converted it into a numpy array and was able to isolate a row and reshape it into a 28x28 array. The row has a label at the beginning and i have also split it with only the 28x28 pixel data. I have used matplotlib to successfully plot it however I can't seem to use cv2.imshow() on the numpy array. I also know that opencv can only read certain datatypes and i have tried converting my data numpy array into both int32 and float but it still didnt work.
Here is how the CSV file looks like:
The CSV file showing the first 4 rows
Here is the file:
Sign Language CSV dataset
Site Where I got the Dataset[Kaggle.com - Sign Language Mnist]
The 1st column is the label for the image and the rest are the pixels. It goes up to the pixel 784 column.
Here is my code:
import cv2
data = np.genfromtxt('sign_mnist_test.csv', delimiter=',', skip_header=1)
labels = data[1:, 0].astype(np.float)
value1 = data[0, 1:].astype(np.float) #the 1st row of the dataset
reshaped = np.reshape(value1, (28, 28))
cv2.imshow('image', reshaped)
cv2.waitKey(0)
cv2.destroyAllWindows()
Here is how my numpy array for the 1st row looks like:
Numpy array of the 1st row
Here is the output:
Output Image
I expect it to show a 28x28 training image(a hand image) however it only shows a plain white 28x28 image with no features.
plt.imshow(reshaped, cmap="Greys")
plt.show()
Output using matplotlib
I am using PyCharm as IDE.
I am also looking for alternative options so that i can use my dataset for openCV if there is any solution that is better.
The problem is that you have made it a float on this line:
value1 = data[0, 1:].astype(np.float)
You need to preferably pass an np.uint8 to cv2.imshow().
I used resize instead of reshape
data = pd.read_csv("sign_mnist_train/sign_mnist_train.csv") # images of 28x28
labels = data.label
data = data.drop(columns=["label"])
value1 = data.iloc[0].astype(np.uint8)
reshaped = np.resize(value1, (28, 28))
cv2.imshow('image', reshaped)
cv2.waitKey(0)
cv2.destroyAllWindows()

How to randomize image pixels in python

I am new to computational vision and python and I could not really figure out what went wrong. I have tried to randomize all the image pixels in a RGB image, but my image turned out to be completely wrong as seen below. Can someone please shed some light?
from scipy import misc
import numpy as np
import matplotlib.pyplot as plt
#Loads an arbitrary RGB image from the misc library
rgbImg = misc.face()
%matplotlib inline
#Display out the original RGB image
plt.figure(1,figsize = (6, 4))
plt.imshow(rgbImg)
plt.show()
#Initialise a new array of zeros with the same shape as the selected RGB image
rdmImg = np.zeros((rgbImg.shape[0], rgbImg.shape[1], rgbImg.shape[2]))
#Convert 2D matrix of RGB image to 1D matrix
oneDImg = np.ravel(rgbImg)
#Randomly shuffle all image pixels
np.random.shuffle(oneDImg)
#Place shuffled pixel values into the new array
i = 0
for r in range (len(rgbImg)):
for c in range(len(rgbImg[0])):
for z in range (0,3):
rdmImg[r][c][z] = oneDImg[i]
i = i + 1
print rdmImg
plt.imshow(rdmImg)
plt.show()
original image
image of my attempt in randomizing image pixel
You are not shuffling the pixels, you are shuffling everything when you use np.ravel() and np.shuffle() afterwards.
When you shuffle the pixels, you have to make sure that the color, the RGB tuples, stay the same.
from scipy import misc
import numpy as np
import matplotlib.pyplot as plt
#Loads an arbitrary RGB image from the misc library
rgbImg = misc.face()
#Display out the original RGB image
plt.figure(1,figsize = (6, 4))
plt.imshow(rgbImg)
plt.show()
# doc on shuffle: multi-dimensional arrays are only shuffled along the first axis
# so let's make the image an array of (N,3) instead of (m,n,3)
rndImg2 = np.reshape(rgbImg, (rgbImg.shape[0] * rgbImg.shape[1], rgbImg.shape[2]))
# this like could also be written using -1 in the shape tuple
# this will calculate one dimension automatically
# rndImg2 = np.reshape(rgbImg, (-1, rgbImg.shape[2]))
#now shuffle
np.random.shuffle(rndImg2)
#and reshape to original shape
rdmImg = np.reshape(rndImg2, rgbImg.shape)
plt.imshow(rdmImg)
plt.show()
This is the random racoon, notice the colors. There is not red or blue there. Just the original ones, white, grey, green, black.
There are some other issues with your code I removed:
Do not use the nested for loops, slow.
The preallocation with np.zeros is not needed (if you ever need it, just pass rgbImg.shape as argument, no need to unpack the separate values)
Change plt.imshow(rdmImg) into plt.imshow(rdmImg.astype(np.uint8))
This may related to this issue https://github.com/matplotlib/matplotlib/issues/9391/

How to convert 1D array of pixels to image in python?

This is with respect to the FER2013 dataset. The data consists of 48x48 pixel grayscale images of faces. The CSV file contains three columns as (emotion, pixels, Usage), where Usage has any of three value - training, PrivateTest and PublicTest. I want to read the array of pixels, convert them into an image and save them in the respective folder named as per their Usage type.
I need python code that can do the above.
Following is my code
import pandas as pd
import numpy as np
from PIL import Image
df=pd.read_csv("fer2013.csv")
for rows in df:
arr=np.array(df['pixels'])
print(arr)
print(arr.shape)
img = Image.fromarray(arr.reshape(48,48), 'L')
img.save("dataset/df['Usage']/img.jpg", "JPEG")
The above code shows error:
cannot reshape array of size 35887 into shape (48,48).
In case there are any doubts (because I have been working with the FER dataset):
import pandas as pd
import numpy as np
from PIL import Image
df = pd.read_csv('fer2013.csv')
for image_pixels in df.iloc[1:,1]: #column 2 has the pixels. Row 1 is column name.
image_string = image_pixels.split(' ') #pixels are separated by spaces.
image_data = np.asarray(image_string, dtype=np.uint8).reshape(48,48)
img = Image.fromarray(image_data) #final image

Build the feature matrix and label vector:

I have a dataset “Digit” . The dataset includes 1797 small images (8x8 pixels), each one includes a hand-written digit (0-9). Each image is considered as a data sample with pixels as features. Thus, to build the feature table you have to convert each 8x8 image into a row of the feature matrix with 64 feature columns for 64 pixels. How to build a feature matrix and label vector for it ???
You can follow the scikit-learn tutorial on supervised learning, where they are using the Digit dataset
http://scikit-learn.org/stable/tutorial/basic/tutorial.html#loading-an-example-dataset
with more detail here. If you load the dataset as in the example, you can simple reshape the images:
from sklearn import datasets
digits = datasets.load_digits()
# To apply a classifier on this data, we need to flatten the image, to
# turn the data in a (samples, feature) matrix:
n_samples = len(digits.images)
data = digits.images.reshape((n_samples, -1))
This makes data a 2D matrix, with n_samples rows and as many columns as needed to fit the flattened image.
If you're using numpy and cv2 you can do the following:
import numpy as np
import cv2
fname = "image1.jpg"
image = cv2.imread(fname) # (8, 8, 1)
feature = image.reshape(64) # (64,)
to read a bunch of images and load into a 'feature matrix' (a numpy array) you can do the following:
N = 10 # number of images
data = np.zeros((N, 64))
for index in range(N):
# get the current image and convert to feature, as above
data[index] = np.copy(feature)
Each row of your data matrix is now one example (a 64 dim list of features).
Does this help?
The label vector can just be a 1D numpy array, i.e. labels = np.zeros(N)
EDIT:
There are a number of ways to read images:
(1) img = cv2.imread(filename)
(2) using matplotlib:
import matplotlib.image as mpimg
img = mpimg.imread(filename)
(3) using PIL (or PILLOW):
from PIL import Image
img = Image.open(filename)
It pays to check the shape of the image after it has been read, so that you know it is in the correct channel, width, height order that is appropriate for your application.

loading an image from cifar-10 dataset

I am using cifar-10 dataset for my training my classifier. I have downloaded the dataset and tried to display am image from the dataset. I have used the following code:
from six.moves import cPickle as pickle
from PIL import Image
import numpy as np
f = open('/home/jayanth/udacity/cifar-10-batches-py/data_batch_1', 'rb')
tupled_data= pickle.load(f, encoding='bytes')
f.close()
img = tupled_data[b'data']
single_img = np.array(img[5])
single_img_reshaped = single_img.reshape(32,32,3)
plt.imshow(single_img_reshaped)
the description of data is as follows:
Each array stores a 32x32 colour image. The first 1024 entries contain the red channel values, the next 1024 the green, and the final 1024 the blue. The image is stored in row-major order, so that the first 32 entries of the array are the red channel values of the first row of the image.
Is my implementation correct?
the above code gave me the following image:
I used
single_img_reshaped = np.transpose(np.reshape(single_img,(3, 32,32)), (1,2,0))
to get the correct format in my program.
Since Python uses the default C-like indexing order (row-major order), it can be forced to work in column-major order:
import numpy as np
import matplotlib.pyplot as plt
# I assume you have loaded your data into x_train (see some tutorial)
data = x_train[0, :] # get a row data
data = np.reshape(data, (32,32,3), order='F' ) # Fortran-like indexing order
plt.imshow(data)
single_img_reshaped = single_img.reshape(3,32,32).transpose([1, 2, 0])

Categories

Resources