How to resolve IndexError: index 440 is out of bounds for axis 0 with size 440 in Python? - conv-neural-network

The following method does exactly that, taking multiple horizontal slices and putting them in a 2D matrix
def slices_matrix_2D(img):
''' Transform a 3D MRI image into a 2D image, by obtaining 9 slices
and placing them in a 4x4 two-dimensional grid.
All 16 cuts are from a horizontal/axial view. They are selected
from the 30th to the 60th level of the original 3D image.
Parameters:
img -- np.ndarray with the 3D image
Returns:
np.ndarray -- The resulting 2D image
'''
# create the final 2D image
image_2D = np.empty(IMG_2D_SHAPE)
# set the limits and the step
TOP = 60
BOTTOM = 30
STEP = 2
N_CUTS = 16
# iterator for the cuts
cut_it = TOP
# iterator for the rows of the 2D final image
row_it = 0
# iterator for the columns of the 2D final image
col_it = 0
for cutting_time in range(N_CUTS):
# cut
cut = img[cut_it, :, :]
cut_it -= STEP
# reset the row iterator and move the
# col iterator when needed
if cutting_time in [4, 8, 12]:
row_it = 0
col_it += cut.shape[1]
# copy the cut to the 2D image
for i in range(cut.shape[0]):
for j in range(cut.shape[1]):
image_2D[i + row_it, j + col_it] = cut[i, j]
row_it += cut.shape[0]
# return the final 2D image, with 3 channels
# this is necessary for working with most pre-trained nets
return np.repeat(image_2D[None, ...], 3, axis=0).T
#return image_2D
**The following method uses the previous 2D transformation to load the 3D images from disk and transforms them. Also returns the image label.
**
def load_image_2D(abs_path, labels):
''' Load an image (.nii) and its label, from its absolute path.
Transform it into a 2D image, by obtaining 16 slices and placing them
in a 4x4 two-dimensional grid.
Parameters:
abs_path -- Absolute path, filename included
labels -- Label mapper
Returns:
img -- The .nii image, converted into a numpy array
label -- The label of the image (from argument 'labels')
'''
# obtain the label from the path (it is the last directory name)
label = labels[abs_path.split('/')[-2]]
# load the image with SimpleITK
sitk_image = sitk.ReadImage(abs_path)
# transform into a numpy array
img = sitk.GetArrayFromImage(sitk_image)
# apply whitening
img = preprocessing.whitening(img)
# make the 2D image
img = slices_matrix_2D(img)
return img, label
Define the complete filename for each one of the .tfrecords.
train_tfrec2D = os.path.join(DB_TF_2D_PATH, TFREC_2D_SS_TRAIN)
test_tfrec2D = os.path.join(DB_TF_2D_PATH, TFREC_2D_SS_TEST)
val_tfrec2D = os.path.join(DB_TF_2D_PATH, TFREC_2D_SS_VAL)
Design the method for creating a .tfrecords, given the all the images filenames, the name of the file and the label mapper (always the LABELS constant). It uses the previous two methods for loading the images
def create_tf_record_2D(img_filenames, tf_rec_filename, labels):
''' Create a TFRecord file, including the information
of the specified images, after converting them into
a 2D grid.
Parameters:
img_filenames -- Array with the path to every
image that is going to be included
in the TFRecords file.
tf_rec_filename -- Name of the TFRecords file.
labels -- Label mapper
'''
# open the file
writer = tf.python_io.TFRecordWriter(tf_rec_filename)
# iterate through all .nii files
for meta_data in img_filenames:
# load the image and label
img, label = load_image_2D(meta_data, labels)
# create a feature
feature = {'label': _int64_feature(label),
'image': _float_feature(img.ravel())}
# create an example protocol buffer
example = tf.train.Example(features=tf.train.Features(feature=feature))
# serialize to string and write on the file
writer.write(example.SerializeToString())
writer.close()
Finally, create the .tfrecords.
create_tf_record_2D(training_set, train_tfrec2D, LABELS)
create_tf_record_2D(test_set, test_tfrec2D, LABELS)
create_tf_record_2D(validation_set, val_tfrec2D, LABELS)

---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-119-7ac7d2b5c98e> in <module>
----> 1 create_tf_record_2D(training_set, train_tfrec2D, LABELS)
2 create_tf_record_2D(test_set, test_tfrec2D, LABELS)
3 create_tf_record_2D(validation_set, val_tfrec2D, LABELS)
<ipython-input-118-a58a668df074> in create_tf_record_2D(img_filenames, tf_rec_filename, labels)
19
20 # load the image and label
---> 21 img, label = load_image_2D(meta_data, labels)
22
23 # create a feature
<ipython-input-114-8a6e1c4008a3> in load_image_2D(abs_path, labels)
27
28 # make the 2D image
---> 29 img = slices_matrix_2D(img)
30
31 return img, label
<ipython-input-113-9f2419afd597> in slices_matrix_2D(img)
44 for i in range(cut.shape[0]):
45 for j in range(cut.shape[1]):
---> 46 image_2D[i + row_it, j + col_it] = cut[i, j]
47 row_it += cut.shape[0]
48
IndexError: index 440 is out of bounds for axis 0 with size 440

Related

create an empty array with 0 row and 4096 columns this number from feature

I'm still a beginner with ML, here im reading the images from local folder that contains breast cancer images then compute features for each image with converting the image pixels to a numpy array and prepare the image for the VGG model.
here im creating an empty array with 0 row and 4096 columns this number from fature.
i just need it to be 2048 instead of 4096
list_features1 = np.empty((0,4096), float)
when i change the number to 2048 it returns :
ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 2048 and the array at index 1 has size 4096
code :
def read_images(folder_path, classlbl):
# load all images into a list
images = []
# dimensions of images
img_width, img_height = 224, 224
class1=[]
for img in os.listdir(folder_path):
img = os.path.join(folder_path, img)
img = load_img(img, target_size=(img_width, img_height))
class1.append(classlbl)# class one.
# img = image.img_to_array(img)
# img = np.expand_dims(img, axis=0)
images.append(img)
return images, class1
#compute features for each image.
def computefeatures(model,image):
# convert the image pixels to a numpy array
image = img_to_array(image)
# reshape data for the model
image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))
# prepare the image for the VGG model
image = preprocess_input(image)
# get extracted features
features = model.predict(image)
return features
# load model
model = VGG16()
# remove the output layer
model.layers.pop()
model = Model(inputs=model.inputs, outputs=model.layers[-1].output)
# call the image read and
folder_path = 'C:path'
classlbl=5
images, class1 =read_images(folder_path, classlbl)
# call the fucntion to compute the features for each image.
list_features1=[]
list_features1 = np.empty((0,4096), float)# create an empty array with 0 row and 4096 columns this number from fature
# extraction from vg16
for img in range(len(images)):
f2=computefeatures(model,images[img])
#list_features1=np.append(list_features1, f2, axis=1)
list_features1 = np.append(list_features1, f2, axis=0)
classes1 = []
count = 0
for i in range(156):
if count >= 0 and count <= 156:
classes1.append(5)
count = count + 1
print(len(classes1))
df1= pd.DataFrame(list_features1,columns=list(range(1,4097)))
df1['class'] = classes1
dfs = {'40X':df1,}
# list_features1 :row ,
writer = pd.ExcelWriter('multi-classLCResNet.xlsx')
for sheet_name in dfs.keys():
dfs[sheet_name].to_excel(writer,sheet_name=sheet_name,index=False)
writer.save()
current output :
1 2 3 4 4096
0.12 0.23 0.345 0.5372 0.21111
0.2313 0.321 0.214 0.3542 0.46756
.
.
desired output :
1 2 3 4 2048
0.12 0.23 0.345 0.5372 0.21111
0.2313 0.321 0.214 0.3542 0.46756
.
.
You must somehow change the size of f2 form 4096 to 2048.
Depending on you application, you can skip every 2nd element:
Change:
list_features1 = np.empty((0,4096), float)
for img in range(len(images)):
f2=computefeatures(model,images[img])
list_features1 = np.append(list_features1, f2, axis=0)
to
list_features1 = np.empty((0,2048), float)
for img in range(len(images)):
f2=computefeatures(model,images[img])
f2 = f2[...,::2] # skip every 2-nd element along the last dimension
list_features1 = np.append(list_features1, f2, axis=0)
Using np.append is a very non-optimal solution but it is a separate problem.

Overlapped predictions on segmented image

Context and examples of symptoms
I am using a neural network to do super-resolution (increase the resolution of images). However, since an image can be big, I need to segment it in multiple smaller images and make predictions on each one of those separately before merging the result back together.
Here are examples of what this gives me:
Example 1: you can see a subtle vertical line passing through the shoulder of the skier in the output picture.
Example 2: once you start seeing them, you'll notice that the subtle lines are forming squares throughout the whole image (remnants of the way I segmented the image for individual predictions).
Example 3: you can clearly see the vertical line crossing the lake.
Source of the problem
Basically, my network makes poor predictions along the edges, which I believe is normal since there is less "surrounding" information.
Source code
import numpy as np
import matplotlib.pyplot as plt
import skimage.io
from keras.models import load_model
from constants import verbosity, save_dir, overlap, \
model_name, tests_path, input_width, input_height
from utils import float_im
def predict(args):
model = load_model(save_dir + '/' + args.model)
image = skimage.io.imread(tests_path + args.image)[:, :, :3] # removing possible extra channels (Alpha)
print("Image shape:", image.shape)
predictions = []
images = []
crops = seq_crop(image) # crops into multiple sub-parts the image based on 'input_' constants
for i in range(len(crops)): # amount of vertical crops
for j in range(len(crops[0])): # amount of horizontal crops
current_image = crops[i][j]
images.append(current_image)
print("Moving on to predictions. Amount:", len(images))
for p in range(len(images)):
if p%3 == 0 and verbosity == 2:
print("--prediction #", p)
# Hack because GPU can only handle one image at a time
input_img = (np.expand_dims(images[p], 0)) # Add the image to a batch where it's the only member
predictions.append(model.predict(input_img)[0]) # returns a list of lists, one for each image in the batch
return predictions, image, crops
def show_pred_output(input, pred):
plt.figure(figsize=(20, 20))
plt.suptitle("Results")
plt.subplot(1, 2, 1)
plt.title("Input : " + str(input.shape[1]) + "x" + str(input.shape[0]))
plt.imshow(input, cmap=plt.cm.binary).axes.get_xaxis().set_visible(False)
plt.subplot(1, 2, 2)
plt.title("Output : " + str(pred.shape[1]) + "x" + str(pred.shape[0]))
plt.imshow(pred, cmap=plt.cm.binary).axes.get_xaxis().set_visible(False)
plt.show()
# adapted from https://stackoverflow.com/a/52463034/9768291
def seq_crop(img):
"""
To crop the whole image in a list of sub-images of the same size.
Size comes from "input_" variables in the 'constants' (Evaluation).
Padding with 0 the Bottom and Right image.
:param img: input image
:return: list of sub-images with defined size
"""
width_shape = ceildiv(img.shape[1], input_width)
height_shape = ceildiv(img.shape[0], input_height)
sub_images = [] # will contain all the cropped sub-parts of the image
for j in range(height_shape):
horizontal = []
for i in range(width_shape):
horizontal.append(crop_precise(img, i*input_width, j*input_height, input_width, input_height))
sub_images.append(horizontal)
return sub_images
def crop_precise(img, coord_x, coord_y, width_length, height_length):
"""
To crop a precise portion of an image.
When trying to crop outside of the boundaries, the input to padded with zeros.
:param img: image to crop
:param coord_x: width coordinate (top left point)
:param coord_y: height coordinate (top left point)
:param width_length: width of the cropped portion starting from coord_x
:param height_length: height of the cropped portion starting from coord_y
:return: the cropped part of the image
"""
tmp_img = img[coord_y:coord_y + height_length, coord_x:coord_x + width_length]
return float_im(tmp_img) # From [0,255] to [0.,1.]
# from https://stackoverflow.com/a/17511341/9768291
def ceildiv(a, b):
return -(-a // b)
# adapted from https://stackoverflow.com/a/52733370/9768291
def reconstruct(predictions, crops):
# unflatten predictions
def nest(data, template):
data = iter(data)
return [[next(data) for _ in row] for row in template]
if len(crops) != 0:
predictions = nest(predictions, crops)
H = np.cumsum([x[0].shape[0] for x in predictions])
W = np.cumsum([x.shape[1] for x in predictions[0]])
D = predictions[0][0]
recon = np.empty((H[-1], W[-1], D.shape[2]), D.dtype)
for rd, rs in zip(np.split(recon, H[:-1], 0), predictions):
for d, s in zip(np.split(rd, W[:-1], 1), rs):
d[...] = s
return recon
if __name__ == '__main__':
print(" - ", args)
preds, original, crops = predict(args) # returns the predictions along with the original
enhanced = reconstruct(preds, crops) # reconstructs the enhanced image from predictions
plt.imsave('output/' + args.save, enhanced, cmap=plt.cm.gray)
show_pred_output(original, enhanced)
The question (what I want)
There are many obvious naive approaches to solving this problem, but I'm convinced there must be a very concise way of doing it: how do I add an overlap_amount variable which would allow me to make overlapped predictions, thus discarding the "edge parts" of each sub-image ("segments") and replacing it with the result of the predictions on the segments surrounding it (since they would not contain "edge-predictions")?
I, of course, want to minimize the amount of "useless" predictions (pixels to be discarded). It might also be worth noting that the input segments produce an output segment which is 4 times bigger (i.e. if it was a 20x20 pixels image, you now get a 80x80 pixels image as output).
I solved a similiar problem by moving inference into the CPU. It was much, much slower but at least in my case solved the patch border problems better than overlapping ROI voting- or discarding based approaches I also tested.
Assuming you are using the Tensorflow backend:
from tensorflow.python import device
with device('cpu:0')
prediction = model.predict(...)
Of course assuming that you have enough RAM to fit your model. Comment below if that is not the case and I'll check out if there's something in my code that could be used here.
Solved it through a naive approach. It could be much better, but at least this works.
The process
Basically, it takes the initial image, then adds a padding around it, then crops it in multiple sub-images which are all lined up into an array. The crops are done so that all images overlap their surrounding neighbours as well.
Then, each image is fed into the network and the predictions are collected (4x on the resolution of the image, basically, in this case). When reconstructing the image, each prediction is taken individually and it's edge is cropped out (since it contains errors). The cropping is done so that the gluing of all the predictions ends up with no overlap, and only the middle parts of the predictions coming from the neural network are stuck together.
Finally, the surrounding padding is removed.
Result
No more line! :D
Code
import numpy as np
import matplotlib.pyplot as plt
import skimage.io
from keras.models import load_model
from constants import verbosity, save_dir, overlap, \
model_name, tests_path, input_width, input_height, scale_fact
from utils import float_im
def predict(args):
"""
Super-resolution on the input image using the model.
:param args:
:return:
'predictions' contains an array of every single cropped sub-image once enhanced (the outputs of the model).
'image' is the original image, untouched.
'crops' is the array of every single cropped sub-image that will be used as input to the model.
"""
model = load_model(save_dir + '/' + args.model)
image = skimage.io.imread(tests_path + args.image)[:, :, :3] # removing possible extra channels (Alpha)
print("Image shape:", image.shape)
predictions = []
images = []
# Padding and cropping the image
overlap_pad = (overlap, overlap) # padding tuple
pad_width = (overlap_pad, overlap_pad, (0, 0)) # assumes color channel as last
padded_image = np.pad(image, pad_width, 'constant') # padding the border
crops = seq_crop(padded_image) # crops into multiple sub-parts the image based on 'input_' constants
# Arranging the divided image into a single-dimension array of sub-images
for i in range(len(crops)): # amount of vertical crops
for j in range(len(crops[0])): # amount of horizontal crops
current_image = crops[i][j]
images.append(current_image)
print("Moving on to predictions. Amount:", len(images))
upscaled_overlap = overlap * 2
for p in range(len(images)):
if p % 3 == 0 and verbosity == 2:
print("--prediction #", p)
# Hack due to some GPUs that can only handle one image at a time
input_img = (np.expand_dims(images[p], 0)) # Add the image to a batch where it's the only member
pred = model.predict(input_img)[0] # returns a list of lists, one for each image in the batch
# Cropping the useless parts of the overlapped predictions (to prevent the repeated erroneous edge-prediction)
pred = pred[upscaled_overlap:pred.shape[0]-upscaled_overlap, upscaled_overlap:pred.shape[1]-upscaled_overlap]
predictions.append(pred)
return predictions, image, crops
def show_pred_output(input, pred):
plt.figure(figsize=(20, 20))
plt.suptitle("Results")
plt.subplot(1, 2, 1)
plt.title("Input : " + str(input.shape[1]) + "x" + str(input.shape[0]))
plt.imshow(input, cmap=plt.cm.binary).axes.get_xaxis().set_visible(False)
plt.subplot(1, 2, 2)
plt.title("Output : " + str(pred.shape[1]) + "x" + str(pred.shape[0]))
plt.imshow(pred, cmap=plt.cm.binary).axes.get_xaxis().set_visible(False)
plt.show()
# adapted from https://stackoverflow.com/a/52463034/9768291
def seq_crop(img):
"""
To crop the whole image in a list of sub-images of the same size.
Size comes from "input_" variables in the 'constants' (Evaluation).
Padding with 0 the Bottom and Right image.
:param img: input image
:return: list of sub-images with defined size (as per 'constants')
"""
sub_images = [] # will contain all the cropped sub-parts of the image
j, shifted_height = 0, 0
while shifted_height < (img.shape[0] - input_height):
horizontal = []
shifted_height = j * (input_height - overlap)
i, shifted_width = 0, 0
while shifted_width < (img.shape[1] - input_width):
shifted_width = i * (input_width - overlap)
horizontal.append(crop_precise(img,
shifted_width,
shifted_height,
input_width,
input_height))
i += 1
sub_images.append(horizontal)
j += 1
return sub_images
def crop_precise(img, coord_x, coord_y, width_length, height_length):
"""
To crop a precise portion of an image.
When trying to crop outside of the boundaries, the input to padded with zeros.
:param img: image to crop
:param coord_x: width coordinate (top left point)
:param coord_y: height coordinate (top left point)
:param width_length: width of the cropped portion starting from coord_x (toward right)
:param height_length: height of the cropped portion starting from coord_y (toward bottom)
:return: the cropped part of the image
"""
tmp_img = img[coord_y:coord_y + height_length, coord_x:coord_x + width_length]
return float_im(tmp_img) # From [0,255] to [0.,1.]
# adapted from https://stackoverflow.com/a/52733370/9768291
def reconstruct(predictions, crops):
"""
Used to reconstruct a whole image from an array of mini-predictions.
The image had to be split in sub-images because the GPU's memory
couldn't handle the prediction on a whole image.
:param predictions: an array of upsampled images, from left to right, top to bottom.
:param crops: 2D array of the cropped images
:return: the reconstructed image as a whole
"""
# unflatten predictions
def nest(data, template):
data = iter(data)
return [[next(data) for _ in row] for row in template]
if len(crops) != 0:
predictions = nest(predictions, crops)
# At this point "predictions" is a 3D image of the individual outputs
H = np.cumsum([x[0].shape[0] for x in predictions])
W = np.cumsum([x.shape[1] for x in predictions[0]])
D = predictions[0][0]
recon = np.empty((H[-1], W[-1], D.shape[2]), D.dtype)
for rd, rs in zip(np.split(recon, H[:-1], 0), predictions):
for d, s in zip(np.split(rd, W[:-1], 1), rs):
d[...] = s
# Removing the pad from the reconstruction
tmp_overlap = overlap * (scale_fact - 1) # using "-2" leaves the outer edge-prediction error
return recon[tmp_overlap:recon.shape[0]-tmp_overlap, tmp_overlap:recon.shape[1]-tmp_overlap]
if __name__ == '__main__':
print(" - ", args)
preds, original, crops = predict(args) # returns the predictions along with the original
enhanced = reconstruct(preds, crops) # reconstructs the enhanced image from predictions
# Save and display the result
plt.imsave('output/' + args.save, enhanced, cmap=plt.cm.gray)
show_pred_output(original, enhanced)
Constants and extra bits
verbosity = 2
input_width = 64
input_height = 64
overlap = 16
scale_fact = 4
def float_im(img):
return np.divide(img, 255.)
Alternative
A possibly better alternative which you might want to consider if you run into the same kind of problem as me; it's the same basic idea, but more polished and perfected.

Index 150 out of bounds in axis0 with size 1

I was making histogram using numpy array in Python with open cv. The code is as follows:
#finding histogram of an image
import numpy as np
import cv2
img = cv2.imread("cr7.jpg")
gry_img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
a=np.zeros((1,256),dtype=np.uint8)
#finding how many times a particular pixel intensity repeats
for x in range (0,183): #size of gray_img is (184,275)
for y in range (0,274):
g=gry_ img[x,y]
a[g]=a[g]+1
print(a)
Error is as follows:
IndexError: index 150 is out of bounds for axis 0 with size 1
Since you haven't supplied the image, it is only from guessing that it seems you've made a mistake with the dimensions of the image. Alternatively the issue is entirely with the shape of your results array a.
The code you have is rather fragile, and here is a cleaner way to interact with images. I use an image from opencv's data directory: aero1.jpg.
The code here resolves both potential issues identified above, whichever one it was:
fname = 'aero1.jpg'
im = cv2.imread(fname)
gry_img = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
gry_img.shape
>>> (480, 640)
# note that the image is 640pix wide by 480 tall;
# the numpy array shows the number of rows first.
# rows are in y / columns are in x
# NOTE the results array `a` need only be 1-dimensional, not 2d (1x256)
a=np.zeros((256, ), dtype=np.uint8)
# iterating over all pixels, whatever the shape of the image.
height, width = gry_img.shape
for x in xrange(width):
for y in xrange(height):
g = gry_img[y, x] # NOTE y, x not x, y
a[g] += 1
But note that you could also achieve this easily with a numpy function np.histogram (docs), with slightly careful handling of the bin edges.
histb, bin_edges = np.histogram(gry_img.reshape(-1), bins=xrange(0, 257))
# check that we arrived at the same result as iterating manually:
(a == histb).all()
>>> True

Tensorflow Endless eval [duplicate]

i am loading the cifar-10 data set , the methods adds the data to tensor array , so to access the data i used .eval() with session , on a normal tf constant it return the value , but on the labels and the train set which are tf array it wont
1- i am using docker tensorflow-jupyter
2- it uses python 3
3- the batch file must be added to data folder
i am using the first batch [data_batch_1.bin]from this file
http://www.cs.toronto.edu/~kriz/cifar-10-binary.tar.gz
As notebook:
https://drive.google.com/open?id=0B_AFMME1kY1obkk1YmJHcjV0ODA
The code[As in tensorflow site but modified to read 1 patch] [check the last 7 lines for the data loading] :
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import urllib
import tensorflow as tf
from six.moves import xrange # pylint: disable=redefined-builtin
# Global constants describing the CIFAR-10 data set.
NUM_CLASSES = 10
NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN = 5000
NUM_EXAMPLES_PER_EPOCH_FOR_EVAL = 1000
IMAGE_SIZE = 32
def _generate_image_and_label_batch(image, label, min_queue_examples,
batch_size, shuffle):
"""Construct a queued batch of images and labels.
Args:
image: 3-D Tensor of [height, width, 3] of type.float32.
label: 1-D Tensor of type.int32
min_queue_examples: int32, minimum number of samples to retain
in the queue that provides of batches of examples.
batch_size: Number of images per batch.
shuffle: boolean indicating whether to use a shuffling queue.
Returns:
images: Images. 4D tensor of [batch_size, height, width, 3] size.
labels: Labels. 1D tensor of [batch_size] size.
"""
# Create a queue that shuffles the examples, and then
# read 'batch_size' images + labels from the example queue.
num_preprocess_threads = 2
if shuffle:
images, label_batch = tf.train.shuffle_batch(
[image, label],
batch_size=batch_size,
num_threads=num_preprocess_threads,
capacity=min_queue_examples + 3 * batch_size,
min_after_dequeue=min_queue_examples)
else:
images, label_batch = tf.train.batch(
[image, label],
batch_size=batch_size,
num_threads=num_preprocess_threads,
capacity=min_queue_examples + 3 * batch_size)
# Display the training images in the visualizer.
tf.image_summary('images', images)
return images, tf.reshape(label_batch, [batch_size])
def read_cifar10(filename_queue):
"""Reads and parses examples from CIFAR10 data files.
Recommendation: if you want N-way read parallelism, call this function
N times. This will give you N independent Readers reading different
files & positions within those files, which will give better mixing of
examples.
Args:
filename_queue: A queue of strings with the filenames to read from.
Returns:
An object representing a single example, with the following fields:
height: number of rows in the result (32)
width: number of columns in the result (32)
depth: number of color channels in the result (3)
key: a scalar string Tensor describing the filename & record number
for this example.
label: an int32 Tensor with the label in the range 0..9.
uint8image: a [height, width, depth] uint8 Tensor with the image data
"""
class CIFAR10Record(object):
pass
result = CIFAR10Record()
# Dimensions of the images in the CIFAR-10 dataset.
# See http://www.cs.toronto.edu/~kriz/cifar.html for a description of the
# input format.
label_bytes = 1 # 2 for CIFAR-100
result.height = 32
result.width = 32
result.depth = 3
image_bytes = result.height * result.width * result.depth
# Every record consists of a label followed by the image, with a
# fixed number of bytes for each.
record_bytes = label_bytes + image_bytes
# Read a record, getting filenames from the filename_queue. No
# header or footer in the CIFAR-10 format, so we leave header_bytes
# and footer_bytes at their default of 0.
reader = tf.FixedLengthRecordReader(record_bytes=record_bytes)
result.key, value = reader.read(filename_queue)
# Convert from a string to a vector of uint8 that is record_bytes long.
record_bytes = tf.decode_raw(value, tf.uint8)
# The first bytes represent the label, which we convert from uint8->int32.
result.label = tf.cast(
tf.slice(record_bytes, [0], [label_bytes]), tf.int32)
# The remaining bytes after the label represent the image, which we reshape
# from [depth * height * width] to [depth, height, width].
depth_major = tf.reshape(tf.slice(record_bytes, [label_bytes], [image_bytes]),
[result.depth, result.height, result.width])
# Convert from [depth, height, width] to [height, width, depth].
result.uint8image = tf.transpose(depth_major, [1, 2, 0])
return result
def inputs(eval_data, data_dir, batch_size):
"""Construct input for CIFAR evaluation using the Reader ops.
Args:
eval_data: bool, indicating if one should use the train or eval data set.
data_dir: Path to the CIFAR-10 data directory.
batch_size: Number of images per batch.
Returns:
images: Images. 4D tensor of [batch_size, IMAGE_SIZE, IMAGE_SIZE, 3] size.
labels: Labels. 1D tensor of [batch_size] size.
"""
filenames=[];
filenames.append(os.path.join(data_dir, 'data_batch_1.bin') )
num_examples_per_epoch = NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN
print(filenames)
# Create a queue that produces the filenames to read.
filename_queue = tf.train.string_input_producer(filenames)
# Read examples from files in the filename queue.
read_input = read_cifar10(filename_queue)
reshaped_image = tf.cast(read_input.uint8image, tf.float32)
height = IMAGE_SIZE
width = IMAGE_SIZE
# Image processing for evaluation.
# Crop the central [height, width] of the image.
resized_image = tf.image.resize_image_with_crop_or_pad(reshaped_image,
width, height)
# Subtract off the mean and divide by the variance of the pixels.
float_image = tf.image.per_image_whitening(resized_image)
# Ensure that the random shuffling has good mixing properties.
min_fraction_of_examples_in_queue = 0.4
min_queue_examples = int(num_examples_per_epoch *
min_fraction_of_examples_in_queue)
# Generate a batch of images and labels by building up a queue of examples.
return _generate_image_and_label_batch(float_image, read_input.label,
min_queue_examples, batch_size,
shuffle=False)
sess = tf.InteractiveSession()
train_data,train_labels = inputs(False,"data",6000)
print (train_data,train_labels)
train_data=train_data.eval()
train_labels=train_labels.eval()
print(train_data)
print(train_labels)
sess.close()
You must call tf.train.start_queue_runners(sess) before you call train_data.eval() or train_labels.eval().
This is a(n unfortunate) consequence of how TensorFlow input pipelines are implemented: the tf.train.string_input_producer(), tf.train.shuffle_batch(), and tf.train.batch() functions internally create queues that buffer records between different stages in the input pipeline. The tf.train.start_queue_runners() call tells TensorFlow to start fetching records into these buffers; without calling it the buffers remain empty and eval() hangs indefinitely.

Error while trying to perform skimage.equalize_hist over a masked array

I have an image represented as a numpy masked array. The image consists of a foreground and a background, I'm not interested in the background so I masked it away. It's an image with poor contrast, and I'd like to increase the contrast in the foreground using skimage.exposure.equalize_hist
I noticed the equalize_hist function takes a named parameter mask, to ignore the unmasked data.
My code looks like this
import numpy as np
import skimage.exposure as ske
import matplotlib.pyplot as plt
# doesn't really exist
from proprietary import openImage, findForeground
imagePath = "...." # path to the image file
# image format is proprietary, so we have a custom function open it for us
# it returns a regular numpy uint16 2d array
# print(type(img), img.dtype, img.shape) shows
# `
# <class 'numpy.ndarray'> float64 (2688, 1151)
# `
img = openImage(imagePath)
foreground = findForeground(img) # this function sets all background pixels to white
# 65535 == white for a uint16 array
masked_img = np.ma.masked_where(foreground==65535, foreground)
# plotting this `masked_img` using plt.imshow works perfectly, the background is completely white
# and the foreground is shown as it is supposed to
# this goes wrong
mask = np.ma.getmask(masked_img)
equalized = ske.equalize_hist(masked_img, mask=mask)
The ske.equalize_hist call generates this error, and I'm unsure why.
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-4-e2b4f8e60ef9> in <module>()
37 print(type(mask))
38 print(mask)
---> 39 equalized = ske.equalize_hist(fg, mask=mask)
40 plt.imshow(equalized, cmap=cmap)
41 plt.set_title("Equalized histogram with colormap {cmap}".format(cmap=cmap))
C:\Users\myuser\AppData\Local\Continuum\Anaconda3\lib\site-packages\skimage\exposure\exposure.py in equalize_hist(image, nbins, mask)
165 cdf, bin_centers = cumulative_distribution(image[mask], nbins)
166 else:
--> 167 cdf, bin_centers = cumulative_distribution(image, nbins)
168 out = np.interp(image.flat, bin_centers, cdf)
169 return out.reshape(image.shape)
C:\Users\myuser\AppData\Local\Continuum\Anaconda3\lib\site-packages\skimage\exposure\exposure.py in cumulative_distribution(image, nbins)
125 True
126 """
--> 127 hist, bin_centers = histogram(image, nbins)
128 img_cdf = hist.cumsum()
129 img_cdf = img_cdf / float(img_cdf[-1])
C:\Users\myuser\AppData\Local\Continuum\Anaconda3\lib\site-packages\skimage\exposure\exposure.py in histogram(image, nbins)
86 return hist[idx:], bin_centers[idx:]
87 else:
---> 88 hist, bin_edges = np.histogram(image.flat, bins=nbins)
89 bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2.
90 return hist, bin_centers
C:\Users\myuser\AppData\Local\Continuum\Anaconda3\lib\site-packages\numpy\lib\function_base.py in histogram(a, bins, range, normed, weights, density)
495 mn, mx = 0.0, 1.0
496 else:
--> 497 mn, mx = a.min() + 0.0, a.max() + 0.0
498 else:
499 mn, mx = [mi + 0.0 for mi in range]
TypeError: unsupported operand type(s) for +: 'MaskedIterator' and 'float'
Anyone have any idea why this happens? I'm at a loss.
As #hpaulij suggests, stay away from masked arrays as much as you can when you are planning on passing the data around. Given the usage you show here, there is no particular reason not to just maintain a separate mask:
import numpy as np
import skimage.exposure as ske
import matplotlib.pyplot as plt
# doesn't really exist
from proprietary import openImage, findForeground
imagePath = "...." # path to the image file
# image format is proprietary, so we have a custom function open it for us
# it returns a regular numpy uint16 2d array
# print(type(img), img.dtype, img.shape) shows
# `
# <class 'numpy.ndarray'> float64 (2688, 1151)
# `
img = openImage(imagePath)
foreground = findForeground(img) # this function sets all background pixels to white
# 65535 == white for a uint16 array
mask = (foreground != 65536)
# plotting this `masked_img` using plt.imshow works perfectly, the background is completely white
# and the foreground is shown as it is supposed to
# foreground should work as well as the original img here
equalized = ske.equalize_hist(img, mask=mask)
Keep in mind also that the mask for masked arrays has the opposite sense of what equalize_hist is expecting. numpy.ma.MaskedArray sets invalid elements to True, while equalize_hist expects the valid elements to be True.
It may be beneficial to have proprietary.findForeground just return a mask for you, instead of messing with the original image. This would have the advantage of not tying the masked value to the dtype of the image, and not running into issues with saturated foreground pixels. If you have the ability to do this, your code would look something like:
mask = findForeground(img) # Now returns a boolean array of the correct size
...
equalized = ske.equalize_hist(img, mask=mask)
As you can see, this will eliminate step from your process.

Resources