Valueerror for reshaping array for image entropy - python

I have a code for finding entropy info of an image by resizing the image and dividing it into its RGB channels.
import os
from PIL import Image
import numpy as np
from scipy.misc import imread
import cv2
import imageio
#读取RGB图像
def openRGB(image_path):
f = open(image_path,"rb")
data = f.read()
f.close()
data = [int(x) for x in data]
data = np.array(data).reshape((256*256, 3)).astype(np.uint8)
return data
def entropy(X):
n = len(X)
counts = np.bincount(X)
probs = counts[np.nonzero(counts)] / n
en = 0
for i in range(len(probs)):
en = en - probs[i] * np.log(probs[i])/np.log(2)
return en
def getEntropy(image_path):
data =openRGB(image_path)
data_B = data[:, 0]
data_G = data[:, 1]
data_R = data[:, 2]
B = entropy(data_B)
G = entropy(data_G)
R = entropy(data_R)
return (R+B+G)/2;
However, whenever I run the getentropy() function on a given image it keeps giving back this error
ValueError: cannot reshape array of size 37048 into shape (65536,3)
Any idea how I can reformat the image to fit that array shape?

There is a simple explanation: image_path length in bytes is only 37048.
When using np.array(data).reshape((256*256, 3)), the length of data must be 256*256*3 = 196608 bytes.
You are getting an exception because the lengths do not match.
It's simple to reproduce the problem.
Create an input sample file in size 196608 bytes, and there is no exception.
Create an input sample file in size 37048 bytes, get an exception.
Here is a code sample that reproduces the problem:
import os
#from PIL import Image
import numpy as np
#from scipy.misc import imread
#import cv2
#import imageio
def openRGB(image_path):
f = open(image_path, "rb")
data = f.read()
f.close()
data = [int(x) for x in data]
data = np.array(data).reshape((256*256, 3)).astype(np.uint8)
return data
def entropy(X):
n = len(X)
counts = np.bincount(X)
probs = counts[np.nonzero(counts)] / n
en = 0
for i in range(len(probs)):
en = en - probs[i] * np.log(probs[i])/np.log(2)
return en
def getEntropy(image_path):
data = openRGB(image_path)
data_B = data[:, 0]
data_G = data[:, 1]
data_R = data[:, 2]
B = entropy(data_B)
G = entropy(data_G)
R = entropy(data_R)
return (R+B+G)/2
# Create a binary file with random bytes
image_path = 'tmp.bin'
# When n_bytes=196608, there is no exception.
################################################################################
n_bytes = 256*256*3
tmp = np.random.randint(0, 255, n_bytes, np.uint8) # Build random array of n_bytes bytes
with open(image_path, 'wb') as f:
f.write(tmp) # Write tmp to a binary file
file_size_in_bytes = os.path.getsize(image_path)
print('file_size_in_bytes = ' + str(file_size_in_bytes))
res = getEntropy(image_path)
print(res)
################################################################################
# When n_bytes=37048, an exception is raised: ValueError: cannot reshape array of size 37048 into shape (65536,3)
################################################################################
n_bytes = 37048
tmp = np.random.randint(0, 255, n_bytes, np.uint8) # Build random array of n_bytes bytes
with open(image_path, 'wb') as f:
f.write(tmp) # Write tmp to a binary file
file_size_in_bytes = os.path.getsize(image_path)
print('file_size_in_bytes = ' + str(file_size_in_bytes))
res = getEntropy(image_path)
print(res)
################################################################################
Why are you reading 37048 bytes instead of 196608 bytes?
image_path is a JPEG image file, and you are reading the image using f = open(image_path, "rb") and data = f.read().
You may read and reshape the image as follows:
import cv2
def openRGB(image_path):
# For example: image_path = 'img.jpg'
img = cv2.imread(image_path) # Read image in BGR color format.
data = np.array(img).reshape(img.shape[0]*img.shape[1], 3) # Reshape to rows x cols x 3 (Blue in data[:, 0], green in data[:, 1], red in data[:, 2]).
return data
In the above example I used img.shape[0]*img.shape[1], the image resolution is:
height = img.shape[0]
width = img.shape[1]

Related

Debayering 16 bit bayer encoded Raw Images

I have images that are bayer encoded (RGGB) and each pixel is 16 bit. When I unpack the byte file and read the image, it appears greenish. I wonder what next image processing steps I should apply. 1200 X 1648, 16 bits per pixel.
I have tried using simple-image-debayer and colour-demosaicing libraries but I get a white image as a result.
The main area of the code (my point of doubt) is inside the if(bands == 1). I am unable to produce the right coloured image. I see a greenish image which i believe is because of the RGGB CFA.
LINK TO IMAGE IS :
https://pds-imaging.jpl.nasa.gov/data/mars2020/mars2020_mastcamz_sci_calibrated/data/0206/rad/ZL0_0206_0685235537_613RAD_N0071836ZCAM08234_1100LMA02.IMG
image_path = "ZL0_0206_0685235537_613RAD_N0071836ZCAM08234_1100LMA02.IMG"
import os
import requests
from bs4 import BeautifulSoup
import struct
import numpy as np
import cv2
import matplotlib.pyplot as plt
import re
import os
import shutil
import time
import colour
from colour_demosaicing import demosaicing_CFA_Bayer_Malvar2004,demosaicing_CFA_Bayer_Menon2007
############# convert image to png #############
def readHeader(file):
# print("Calling readHeader")
f = open(file,'rb')
continuing = 1
count = 0
h_bytes = -1
h_lines = -1
h_line_samples = -1
h_sample_type = 'UNSET' #MSB_INTEGER, IEEE_REAL
h_sample_bits = -1
h_bands = -1
while continuing == 1:
line = f.readline()
count = count + 1
arr = str(line, 'utf8').split("=")
arr[0] = str(arr[0]).strip()
if 'BYTES' == arr[0] and len(arr[0])>1:
h_bytes=int(str(arr[1]).strip())
elif 'LINES' == arr[0] and len(arr[0])>1:
h_lines=int(str(arr[1]).strip())
elif 'LINE_SAMPLES' == arr[0] and len(arr[0])>1:
h_line_samples=int(str(arr[1]).strip())
elif 'SAMPLE_TYPE' == arr[0] and len(arr[0])>1:
h_sample_type=str(arr[1]).strip()
elif 'SAMPLE_BITS' == arr[0] and len(arr[0])>1:
h_sample_bits = int(str(arr[1]).strip())
elif 'BANDS' == arr[0] and len(arr[0])>1:
h_bands=int(str(arr[1]).strip())
if (line.endswith(b'END\r\n') or count>600):
continuing = 0
f.close()
return h_bytes, h_lines,h_line_samples,h_sample_type,h_sample_bits,h_bands
def readImage(file, pixelbytes, sample_type,sample_bits, lines, line_samples, bands):
# print("Calling Read image")
f = open(file,'rb')
filesize = os.fstat(f.fileno()).st_size
h_bytes = filesize - pixelbytes
f.seek(h_bytes) # skip past the header bytes
fmt = '{endian}{pixels}{fmt}'.format(endian='>', pixels=lines*line_samples*bands, fmt=getFmt(sample_type,sample_bits))
if (bands==3):
print(pixelbytes,lines,line_samples,fmt)
img = np.array(struct.unpack(fmt,f.read(pixelbytes))).reshape(bands,lines,line_samples)
print(img)
m = np.max(np.max(img, axis=1))
img = np.clip(img/m,0,1) #normalize and clip so values are between 0 and 1
img = np.stack([img[0,:,:],img[1,:,:],img[2,:,:]],axis=2)
# print(img.shape)
elif (bands==1):
print(pixelbytes,lines,line_samples,fmt)
img = np.array(struct.unpack(fmt,f.read(pixelbytes))).reshape(lines,line_samples)
# data = np.fromfile(f, np.uint8, line_samples * lines * 3//2)
# data = data.astype(np.uint16) # Cast the data to uint16 type.
# result = np.zeros(data.size*2//3, np.uint16)
# img = np.array(struct.unpack(fmt,f.read(pixelbytes))).reshape(lines,line_samples)
# result[0::2] = ((data[1::3] & 15) << 8) | data[0::3]
# result[1::2] = (data[1::3] >> 4) | (data[2::3] << 4)
# bayer_im = np.reshape(result, (lines, line_samples))
img = cv2.cvtColor(np.uint16(img), cv2.COLOR_BAYER_BG2BGR)
return img
# return img
# fmtMap - converts sample_type from header to python format fmt.
def getFmt(sample_type, samplebits):
# print("Calling getFM funtion")
if (sample_type=='IEEE_REAL'):
return 'f'
elif (sample_type=='MSB_INTEGER'):
return 'H'
elif (sample_type=='UNSIGNED_INTEGER'):
return 'B'
else:
return 'X'
def convert_to_png(sol_folder_path):
hbytes,hlines,hline_samples,hsample_type,hsample_bits,hbands = readHeader(full_path)
numpixels = hlines * hline_samples * hbands
pixelbytes = numpixels*hsample_bits//8 # // is for integer division
img = readImage(full_path, pixelbytes, hsample_type,hsample_bits, hlines, hline_samples, hbands)
plt.imsave('debayer_test.png',np.uint8(img))
A raw image in Bayer mosaic format is a "single band" image.
After applying Demosaicing algorithm, the output is 3 color channels image (RGB).
After skipping the header, we may read the raw data, and apply Demosaicing in few steps:
Read raw data bytes (1200 * 1648 * 2 bytes):
data = f.read(pixelbytes)
Convert data bytes to uint16 NumPy array and reshape to image dimensions:
img = np.frombuffer(data, np.uint16).reshape(lines, line_samples)
Convert from big endian to little endian format by swapping high and low bytes of each uint16 element (required because the input format is big endian):
img = (img >> 8) + (img << 8)
Apply Demosaicing using OpenCV cvtColor method (convert from Bayer to BGR):
img = cv2.cvtColor(img, cv2.COLOR_BAYER_BG2BGR)
As a "bonus" I added Gamma correction (using standard sRGB gamma transfer function).
After applying gamma correction (or without gamma correction), we may convert the result to type uint8 and save as PNG.
For converting uint16 to uint8 we may scale by 255/(2**16-1).
Code sample:
import os
import numpy as np
import cv2
def readHeader(file):
# print("Calling readHeader")
f = open(file,'rb')
continuing = 1
count = 0
h_bytes = -1
h_lines = -1
h_line_samples = -1
h_sample_type = 'UNSET' #MSB_INTEGER, IEEE_REAL
h_sample_bits = -1
h_bands = -1
while continuing == 1:
line = f.readline()
count = count + 1
arr = str(line, 'utf8').split("=")
arr[0] = str(arr[0]).strip()
if 'BYTES' == arr[0] and len(arr[0])>1:
h_bytes=int(str(arr[1]).strip())
elif 'LINES' == arr[0] and len(arr[0])>1:
h_lines=int(str(arr[1]).strip())
elif 'LINE_SAMPLES' == arr[0] and len(arr[0])>1:
h_line_samples=int(str(arr[1]).strip())
elif 'SAMPLE_TYPE' == arr[0] and len(arr[0])>1:
h_sample_type=str(arr[1]).strip()
elif 'SAMPLE_BITS' == arr[0] and len(arr[0])>1:
h_sample_bits = int(str(arr[1]).strip())
elif 'BANDS' == arr[0] and len(arr[0])>1:
h_bands=int(str(arr[1]).strip())
if (line.endswith(b'END\r\n') or count>600):
continuing = 0
f.close()
return h_bytes, h_lines,h_line_samples,h_sample_type,h_sample_bits,h_bands
def readImage(file, pixelbytes, sample_type,sample_bits, lines, line_samples, bands):
f = open(file,'rb')
filesize = os.fstat(f.fileno()).st_size
h_bytes = filesize - pixelbytes
f.seek(h_bytes) # skip past the header bytes
# Assume bands = 1
print(pixelbytes, lines, line_samples)
data = f.read(pixelbytes) # Read raw data bytes
img = np.frombuffer(data, np.uint16).reshape(lines, line_samples) # Convert to uint16 NumPy array and reshape to image dimensions.
img = (img >> 8) + (img << 8) # Convert from big endian to little endian
img = cv2.cvtColor(img, cv2.COLOR_BAYER_BG2BGR) # Apply demosaicing (convert from Bayer to BGR).
return img
def lin2rgb(im):
""" Convert im from "Linear sRGB" to sRGB - apply Gamma. """
# sRGB standard applies gamma = 2.4, Break Point = 0.00304 (and computed Slope = 12.92)
# lin2rgb MATLAB functions uses the exact formula [we may approximate it to power of (1/gamma)].
g = 2.4
bp = 0.00304
inv_g = 1/g
sls = 1 / (g/(bp**(inv_g - 1)) - g*bp + bp)
fs = g*sls / (bp**(inv_g - 1))
co = fs*bp**(inv_g) - sls*bp
srgb = im.copy()
srgb[im <= bp] = sls * im[im <= bp]
srgb[im > bp] = np.power(fs*im[im > bp], inv_g) - co
return srgb
def convert_to_png(full_path):
hbytes, hlines, hline_samples, hsample_type, hsample_bits, hbands = readHeader(full_path)
numpixels = hlines * hline_samples * hbands
pixelbytes = numpixels*hsample_bits//8 # // is for integer division
img = readImage(full_path, pixelbytes, hsample_type,hsample_bits, hlines, hline_samples, hbands)
# Apply gamma correction, and convert to uint8
img_in_range_0to1 = img.astype(np.float32) / (2**16-1) # Convert to type float32 in range [0, 1] (before applying gamma correction).
gamma_img = lin2rgb(img_in_range_0to1)
gamma_img = np.round(gamma_img * 255).astype(np.uint8) # Convert from range [0, 1] to uint8 in range [0, 255].
cv2.imwrite('gamma_img.png', gamma_img) # Save image after demosaicing and gamma correction.
# Show the uint16 image and gamma_img for testing
cv2.imshow('img', img)
cv2.imshow('gamma_img', gamma_img)
cv2.waitKey()
cv2.destroyAllWindows()
image_path = "ZL0_0206_0685235537_613RAD_N0071836ZCAM08234_1100LMA02.IMG"
convert_to_png(image_path)
Output (downscaled):
The colors are probably not perfect...
When applying raw image processing, there is a lot of "color science" (for getting the right colors), but the subject exceeds the scope of the question.

dumping a numpy array into a CSV file: table elements look like printed arrays

I'm trying to use the OpenCV Python wrapper to calculate the Discrete wavelet Haar transform for an image. Supposedly, images == numpy arrays == CV matrices, so I thought this should work:
import cv2
import numpy as np
import pywt
from pywt import wavedec
import csv
imgcv1 = cv2.split(resize)[0]
cv2.boxFilter(imgcv1, 0, (7,7), imgcv1, (-1,-1), False, cv2.BORDER_DEFAULT)
cv2.resize( imgcv1, (32, 32 ) ,imgcv1)
imf = np.float32(imgcv1)/255.0 # float conversion/scale
coeffs = pywt.dwt(imf, "haar") # the dwt
cA = coeffs
#imgout = pywt.dwt(coeffs, "haar")
print(cA)
def zigzag(matrix):
rows=len(matrix)
columns=len(matrix[0])
solution=[[] for i in range(rows+columns-1)]
for i in range(rows):
for j in range(columns):
sum=i+j
if(sum%2 ==0):
solution[sum].insert(0,matrix[i][j])
else:
solution[sum].append(matrix[i][j])
data = (rows*columns)/3
data = round(data)
mtx_zigzag = []
for i in solution:
for j in i:
mtx_zigzag.append(j)
mtxawal = mtx_zigzag[2:26]
# mtxtengah = mtx_zigzag[83:107]
# mtxakhir = mtx_zigzag[191:215]
mtx = mtxawal
# +mtxtengah+mtxakhir
return mtx
hasil_zigzag= zigzag(cA)
print(hasil_zigzag)
zg=[]
zg.append(hasil_zigzag)
citra="tangan {}".format(counter)
file=open('database.csv','a+',newline='')
with file:
write=csv.writer(file)
write.writerows(zg)
the excel /csv data output is like this:
I want the matrix or csv/excel output to be like this:
can you guys help me

convert numpy array to uint8 using python

My code below is intended to get a batch of images and convert them to RGB. But I keep getting an error which says to convert to type uint8. I have seen other questions regarding the conversion to uint8, but none directly from an array to uint8. Any advice on how to make that happen is welcome, thank you!
from skimage import io
import numpy as np
import glob, os
from tkinter import Tk
from tkinter.filedialog import askdirectory
import cv2
# wavelength in microns
MWIR = 4.5
R = .692
G = .582
B = .140
rgb_sum = R + G + B;
NRed = R/rgb_sum;
NGreen = G/rgb_sum;
NBlue = B/rgb_sum;
path = askdirectory(title='Select PNG Folder') # shows dialog box and return the path
outpath = askdirectory(title='Select SAVE Folder')
for file in os.listdir(path):
if file.endswith(".png"):
imIn = io.imread(os.path.join(path, file))
imOut = np.zeros(imIn.shape)
for i in range(imIn.shape[0]): # Assuming Rayleigh-Jeans law
for j in range(imIn.shape[1]):
imOut[i,j,0] = imIn[i,j,0]/((NRed/MWIR)**4)
imOut[i,j,1] = imIn[i,j,0]/((NGreen/MWIR)**4)
imOut[i,j,2] = imIn[i,j,0]/((NBlue/MWIR)**4)
io.imsave(os.path.join(outpath, file) + '_RGB.png', imOut)
the code I am trying to integrate into my own (found in another thread, used to convert type to uint8) is:
info = np.iinfo(data.dtype) # Get the information of the incoming image type
data = data.astype(np.float64) / info.max # normalize the data to 0 - 1
data = 255 * data # Now scale by 255
img = data.astype(np.uint8)
cv2.imshow("Window", img)
thank you!
Normally imInt is of type uint8, after your normalisation it is of type float32 because of the casting cause by the division. you must convert back to uint8 before saving to PNG file:
io.imsave(os.path.join(outpath, file) + '_RGB.png', imOut.astype(np.uint8))
Note that the two loops are not necessary, you can use numpy vector operations instead:
MWIR = 4.5
R = .692
G = .582
B = .140
vector = [R, G, B]
vector = vector / vector.sum()
vector = vector / MWIR
vector = np.pow(vector, 4)
for file in os.listdir(path):
if file.endswith((".png"):
imgIn = ...
imgOut = imgIn * vector
io.imsave(
os.path.join(outpath, file) + '_RGB.png',
imgOut.astype(np.uint8))

Why CIFAR-10 images are not displayed properly using matplotlib?

From the training set I took a image('img') of size (3,32,32).
I have used plt.imshow(img.T). The image is not clear. Now changes I have to make to image('img') to make it more clearly visible.
Thanks.
Following prints 5X5 grid of random Cifar10 images. It isn't blurry, though not perfect either. Any suggestions welcome.
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from six.moves import cPickle
f = open('data/cifar10/cifar-10-batches-py/data_batch_1', 'rb')
datadict = cPickle.load(f,encoding='latin1')
f.close()
X = datadict["data"]
Y = datadict['labels']
X = X.reshape(10000, 3, 32, 32).transpose(0,2,3,1).astype("uint8")
Y = np.array(Y)
#Visualizing CIFAR 10
fig, axes1 = plt.subplots(5,5,figsize=(3,3))
for j in range(5):
for k in range(5):
i = np.random.choice(range(len(X)))
axes1[j][k].set_axis_off()
axes1[j][k].imshow(X[i:i+1][0])
Make sure you don't normalize your dataset when you want to display the image.
Example :
The loader...
import torch
from torchvision import datasets, transforms
import matplotlib.pyplot as plt
train_loader = torch.utils.data.DataLoader(
datasets.CIFAR10('../data', train=True, download=True,
transform=transforms.Compose([
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
# transforms.Normalize(
# (0.4914, 0.4822, 0.4465), (0.247, 0.243, 0.261))
])),
batch_size=64, shuffle=True)
The code that shows the image...
img = next(iter(train_loader))[0][0]
plt.imshow(transforms.ToPILImage()(img))
Normalized
Wihtout normalization
This file reads the cifar10 dataset and plots individual images using matplotlib.
import _pickle as pickle
import argparse
import numpy as np
import os
import matplotlib.pyplot as plt
cifar10 = "./cifar-10-batches-py/"
parser = argparse.ArgumentParser("Plot training images in cifar10 dataset")
parser.add_argument("-i", "--image", type=int, default=0,
help="Index of the image in cifar10. In range [0, 49999]")
args = parser.parse_args()
def unpickle(file):
with open(file, 'rb') as fo:
data = pickle.load(fo, encoding='bytes')
return data
def cifar10_plot(data, meta, im_idx=0):
im = data[b'data'][im_idx, :]
im_r = im[0:1024].reshape(32, 32)
im_g = im[1024:2048].reshape(32, 32)
im_b = im[2048:].reshape(32, 32)
img = np.dstack((im_r, im_g, im_b))
print("shape: ", img.shape)
print("label: ", data[b'labels'][im_idx])
print("category:", meta[b'label_names'][data[b'labels'][im_idx]])
plt.imshow(img)
plt.show()
def main():
batch = (args.image // 10000) + 1
idx = args.image - (batch-1)*10000
data = unpickle(os.path.join(cifar10, "data_batch_" + str(batch)))
meta = unpickle(os.path.join(cifar10, "batches.meta"))
cifar10_plot(data, meta, im_idx=idx)
if __name__ == "__main__":
main()
The image is blurry due to interpolation. To prevent blurring in matplotlib, call imshow with keyword interpolation='nearest':
plt.imshow(img.T, interpolation='nearest')
Also, it appears that your x and y axes are being swapped when you use the transpose so you may want to display like this instead:
plt.imshow(np.transpose(img, (1, 2, 0)), interpolation='nearest')
I have used the following code to show all CIFAR data as one big image. The code show the image, but if you want to save it and not be blurtry i sugest using plt.savefig(fname, format='png', dpi=1000)
import numpy as np
import matplotlib.pyplot as plt
def reshape_and_print(self, cifar_data):
# number of images in rows and columns
rows = cols = np.sqrt(cifar_data.shape[0]).astype(np.int32)
# Image hight and width. Divide by 3 because of 3 color channels
imh = imw = np.sqrt(cifar_data.shape[1] // 3).astype(np.int32)
# reshape to number of images X color channels X image size
# transpose to color channels X number of images X image size
timg = cifar_data.reshape(rows * cols, 3, imh * imh).transpose(1, 0, 2)
# reshape to color channels X rows X cols X image hight X image with
# swap axis to color channels X rows X image hight X cols X image with
timg = timg.reshape(3, rows, cols, imh, imw).swapaxes(2, 3)
# reshape to color channels X combined image hight X combined image with
# transpose to combined image hight X combined image with X color channels
timg = timg.reshape(3, rows * imh, cols * imw).transpose(1, 2, 0)
plt.imshow(timg)
plt.show()
I made a quick data helper class that i used for a small test project, I hope is can be useful:
import gzip
import pickle
import numpy as np
import matplotlib.pyplot as plt
class DataSet(object):
def __init__(self, seed=42, setsize=10000):
self.seed = seed
# set the seed for reproducability
np.random.seed(seed)
# load the data
train_set, test_set = self.load_data()
# self.split_data(train_set, valid_set, test_set)
self.split_data(train_set, test_set, setsize)
def split_data(self, data_set, test_set, split_size):
permutation = np.random.permutation(data_set.shape[0])
self.train = data_set[permutation[:split_size]]
self.valid = data_set[permutation[split_size:split_size * 2]]
self.test = test_set[:split_size]
def reshape_for_print(self, data):
raise NotImplemented
def load_data(self):
raise NotImplemented
def show_all_imgs(self, data):
raise NotImplemented
class CIFAR(DataSet):
def load_data(self):
# try to load data
with open('./data/cifar-100-python/train', 'rb') as f:
data = pickle.load(f, encoding='latin1')
train_set = data['data'].astype(np.float32) / 255.0
with open('./data/cifar-100-python/test', 'rb') as f:
data = pickle.load(f, encoding='latin1')
test_set = data['data'].astype(np.float32) / 255.0
return train_set, test_set
def reshape_for_print(self, data):
gh = gw = np.sqrt(data.shape[0]).astype(np.int32)
imh = imw = np.sqrt(data.shape[1] // 3).astype(np.int32)
timg = data.reshape(gh * gw, 3, imh * imh).transpose(1, 0, 2)
timg = timg.reshape(3, gh, gw, imh, imw).swapaxes(2, 3)
timg = timg.reshape(3, gh * imh, gw * imw).transpose(1, 2, 0)
return timg
def show_all_imgs(self, data):
timg = self.reshape_for_print(data)
plt.imshow(timg)
plt.show()
class MNIST(DataSet):
def load_data(self):
# try to load data
with gzip.open('./data/mnist.pkl.gz', 'rb') as f:
train_set, valid_set, test_set = pickle.load(f, encoding='latin1')
return train_set[0], test_set[0]
def reshape_for_print(self, data):
gh = gw = np.sqrt(data.shape[0]).astype(np.int32)
imh = imw = np.sqrt(data.shape[1]).astype(np.int32)
timg = data.reshape(gh, gw, imh, imw).swapaxes(1, 2)
timg = timg.reshape(gh * imh, gw * imw)
return timg
def show_all_imgs(self, data):
timg = self.reshape_for_print(data)
plt.imshow(timg, cmap=plt.cm.gray)
plt.show()
I made a function to plot the RGB image from a row in the CIFAR10 dataset.The image will be blurry at best since the original size of the image is very small (32px X 32px).
def unpickle(file):
with open(file, 'rb') as fo:
dict1 = pickle.load(fo, encoding='bytes')
return dict1
pd_tr = pd.DataFrame()
tr_y = pd.DataFrame()
for i in range(1,6):
data = unpickle('data/data_batch_' + str(i))
pd_tr = pd_tr.append(pd.DataFrame(data[b'data']))
tr_y = tr_y.append(pd.DataFrame(data[b'labels']))
pd_tr['labels'] = tr_y
tr_x = np.asarray(pd_tr.iloc[:, :3072])
tr_y = np.asarray(pd_tr['labels'])
ts_x = np.asarray(unpickle('data/test_batch')[b'data'])
ts_y = np.asarray(unpickle('data/test_batch')[b'labels'])
labels = unpickle('data/batches.meta')[b'label_names']
def plot_CIFAR(ind):
arr = tr_x[ind]
sc_dpi = 157.35
R = arr[0:1024].reshape(32,32)/255.0
G = arr[1024:2048].reshape(32,32)/255.0
B = arr[2048:].reshape(32,32)/255.0
img = np.dstack((R,G,B))
title = re.sub('[!##$b]', '', str(labels[tr_y[ind]]))
fig = plt.figure(figsize=(3,3))
ax = fig.add_subplot(111)
ax.imshow(img,interpolation='bicubic')
ax.set_title('Category = '+ title,fontsize =15)
plot_CIFAR(4)
try using
import matplotlib.pyplot as plt
from scipy.misc import toimage
plt.imshow(toimage(img))
I am not 100% sure of how the code works, but I think that because the images are stored in floating point numpy arrays, the imshow() function has a difficult time mapping them to the right colors. By typecasting them to image using toimage() you convert them into proper image format that imshow() expects, i.e not an array but an image encoded as .png or .jpg.
This code works for me every time I want to display images in python.
code result is: Try below code.
I found a very useful link about visualization of mnist and cifar images. You can find codes for various images :
https://machinelearningmastery.com/how-to-load-and-visualize-standard-computer-vision-datasets-with-keras/
cifar10 image code is below:
It works well. Image is above.
# example of loading the cifar10 dataset
from matplotlib import pyplot
from keras.datasets import cifar10
# load dataset
(trainX, trainy), (testX, testy) = cifar10.load_data()
# summarize loaded dataset
print('Train: X=%s, y=%s' % (trainX.shape, trainy.shape))
print('Test: X=%s, y=%s' % (testX.shape, testy.shape))
# plot first few images
for i in range(9):
# define subplot
pyplot.subplot(330 + 1 + i)
# plot raw pixel data
pyplot.imshow(trainX[i])
# show the figure
pyplot.show()
Add 0.5:
plt.imshow(np.transpose(img, (1, 2, 0)) + 0.5)

Python numpy ValueError when I load image data and transfer it to an array

I couldn't find the solution.My image shape is 128*128*3,it has three channel,but it also cause the error
File "E:/ML/keras_test/vgg.py", line 30, in load_data data[i,:,:,:] = arr
ValueError: could not broadcast input array from shape (128,128) into
shape (128,128,3)
My code as below:
def load_data(path):
data = np.empty((12755,128,128,3),dtype="uint8")
label = np.empty((12755,),dtype="uint8")
imgs = []
imgs_name = []
for each_person in os.listdir(path):
temp = os.path.join(path,each_person)
for each_image in os.listdir(temp):
imgs.append(temp + "\\" + each_image)
imgs_name.append(each_image)
num = len(imgs)
for i in range(num):
img = Image.open(imgs[i])
arr = np.asarray(img,dtype="uint8")
print arr.shape
data[i,:,:,:] = arr
label[i] = int(imgs_name[i].split('.')[0])
print 'load_data is ok!' + str(data.shape[0])
return data,label
You are trying to put the original data into a small package, which is impossible. I think you are trying to transfer a image which has RGB channel into a gray scale image which has one channel. Try
datum = (imgs.sum(axis=2) / 3).reshape((12755, -1))
The resulting datum is a 12755 x 16384 array.

Categories