arr = []
for i in range(len(x1)):
image = x1[i].reshape(150, 150, 3)
grayscale = image[0:150, 0:150, 1]
grayscale = grayscale.reshape(22500)
arr = np.append(arr, np.array(grayscale), axis=0)
print(arr.shape) # (742500,)
I am working on a school project, and I have created more data with augmentation in RGB format. I would like to convert this to grayscale after augmentation because it will require fewer computations. However, for some reason, I am having problems with appending the reshaped version into a new array. It is append everything into one row and not to a separate rows, I want to have (33,22500) not (742500), can anyone help plz
there are several ways;
way1:
arr = []
for i in range(len(x1)):
image = x1[i].reshape(150,150,3)
grayscale = image[:150,:150,1]
grayscale = grayscale.reshape(22500)
arr.append(grayscale)
arr = np.array(arr)
Related
I am trying to run a CNN where the input images have three channels (rgb) and the label (target) images are grayscale images (1 channel). The input and label images are in float32 and tif format.
I got the list of image and label tile pairs as below:
def get_train_test_lists(imdir, lbldir):
imgs = glob.glob(imdir+"/*.tif")
dset_list = []
for img in imgs:
filename_split = os.path.splitext(img)
filename_zero, fileext = filename_split
basename = os.path.basename(filename_zero)
dset_list.append(basename)
x_filenames = []
y_filenames = []
for img_id in dset_list:
x_filenames.append(os.path.join(imdir, "{}.tif".format(img_id)))
y_filenames.append(os.path.join(lbldir, "{}.tif".format(img_id)))
print("number of images: ", len(dset_list))
return dset_list, x_filenames, y_filenames
train_list, x_train_filenames, y_train_filenames = get_train_test_lists(img_dir, label_dir)
test_list, x_test_filenames, y_test_filenames = get_train_test_lists(test_img_dir, test_label_dir)
from sklearn.model_selection import train_test_split
x_train_filenames, x_val_filenames, y_train_filenames, y_val_filenames =
train_test_split(x_train_filenames, y_train_filenames, test_size=0.1, random_state=42)
num_train_examples = len(x_train_filenames)
num_val_examples = len(x_val_filenames)
num_test_examples = len(x_test_filenames)
In order to read the tiles into tensor, firstly I defined the image dimensions and batch size:
img_shape = (128, 128, 3)
batch_size = 2
I noticed that there is no decoder in tensorflow for tif image based on this link. tfio.experimental.image.decode_tiff can be used but it decodes to unit8 tensor.
here is a sample code for png images:
def _process_pathnames(fname, label_path):
# We map this function onto each pathname pair
img_str = tf.io.read_file(fname)
img = tf.image.decode_png(img_str, channels=3)
label_img_str = tf.io.read_file(label_path)
# These are png images so they return as (num_frames, h, w, c)
label_img = tf.image.decode_png(label_img_str, channels=1)
# The label image should have any values between 0 and 9, indicating pixel wise
# cropt type class or background (0). We take the first channel only.
label_img = label_img[:, :, 0]
label_img = tf.expand_dims(label_img, axis=-1)
return img, label_img
Is it possible to modify this code by tf.convert_to_tensor or any other option to get float32 tensor from tif images? (I asked this question before, but I don't know how to integrate tf.convert_to_tensor with the mentioned codes)
You can read almost any image format and convert it to a numpy array with the Pillow image package:
from PIL import Image
import numpy as np
img = Image.open("image.tiff")
img = np.array(img)
print(img.shape, img.dtype)
# (986, 1853, 4) uint8
You can integrate this function into your code and then convert the numpy array to a tensorflow tensor as well as doing the appropriated image conversions.
Side note: you can simplify a lot your get_train_test_lists function using the pathlib package (which is integrated to Python3 like os but much simpler to use).
def get_train_test_lists(imdir, lbldir):
x_filenames = list(Path(imdir).glob("*.tif"))
y_filenames = [Path(lbldir) / f.name for f in x_filenames]
dset_list = [f.stem for f in x_filenames]
return dset_list, x_filenames, y_filenames
Note that x_filenames and y_filenames are now absolute paths but this shouldn't be an issue in your code.
EDIT: I have found a workaround, which is assigning it to an array, then use that array to create a numpy array:
a = []
for i in range(0,width/image_size):
for j in range(0,height/image_size):
roi = img[image_size*j:image_size*(j+1),image_size*i:image_size*(i+1)]
a.append(roi)
arr = np.asarray(a) #HERE
ORIGINAL QUESTION:
I have created an empty numpy array of shape (180,28,28), which should hold 180 gray scale images size 28x28.
height, width = img.shape[:2]
arr = np.empty(((height/image_size)*(width/image_size), 28, 28 )) #arr.shape = (180,28,28)
I have multiple image regions size 28x28 that I want to populate into arr
for i in range(0,width/image_size):
for j in range(0,height/image_size):
roi = img[image_size*j:image_size*(j+1),image_size*i:image_size*(i+1)]
#HERE - how can I set the value in arr to be an (28x28) roi
Thank you.
I have found a workaround, which is assigning it to an array, then use that array to create a numpy array:
a = []
for i in range(0,width/image_size):
for j in range(0,height/image_size):
roi = img[image_size*j:image_size*(j+1),image_size*i:image_size*(i+1)]
a.append(roi)
arr = np.asarray(a) #assign it to numpy array here
However, I'm not sure if there is a better, or more elegant way to do it.
I have an image that I have encoded and sent out using protobuf like so:
message.image = numpy.ndarray.tobytes(image)
when I receive and parse that message I use this:
image_array = numpy.frombuffer(request.image, numpy.uint8)
This gives me a one-dimensional array. I cannot get this back into an image format. I have tried using numpy's reshape command like so but with no luck:
image = image_array.reshape( 400, 600, 3 )
The image being sent is 400x600 pixels and it is a 3 channel color image. Any suggestions on what I am missing?
You would also need to store the img.shape data of the original image you wanted to encode and whole decoding you need that img.shape value to reshape the matrix to it's original form as:
import numpy as np
# Create a dummy matrix
img = np.ones((50, 50, 3), dtype=np.uint8) * 255
# Save the shape of original matrix.
img_shape = img.shape
message_image = np.ndarray.tobytes(img)
re_img = np.frombuffer(message_image, dtype=np.uint8)
# Convert back the data to original image shape.
re_img = np.reshape(re_img, img_shape)
I am trying to customize an existing code to suit my own need. Originally, the code use imgs = np.ndarray((total, 1, image_rows, image_cols), dtype=np.uint8) to store a list of image files in an numpy array format. Iterating the folder, each image file is read as follows img = skimage.io.imread(os.path.join(train_data_path, image_name)) It works just fine.
The code is as follows:
image_rows = 420
image_cols = 580
imgs = np.ndarray((total, 1, image_rows, image_cols), dtype=np.uint8)
i=0
for image_name in images:
img = skimage.io.imread(os.path.join(train_data_path, image_name))
img = np.array([img])
imgs[i]=img
i+=1
In order to suit my own need, I tend to have image file array with the shape [total, image_rows,image_cols,1]. In other words, I modified it as imgs = np.ndarray((total,image_rows, image_cols,1), dtype=np.uint8) However, running the code causes the following error
imgs[i] = img
ValueError: could not broadcast input array from shape (1,420,580) into shape
(420,580,1)
Are there any way to change the shape of img, which originally has shape of [1,420,580] after reading from file. How can I change it to [420,580,1] without affecting the corresponding pixel values in the image.
You want to transpose the dimensions. It can be done using the transpose method:
img = img.transpose(1,2,0)
(for your case)
I want implement VGG Face Descriptor in python. But I keep getting an error:
TypeError: can only concatenate list (not "numpy.ndarray") to list
My code:
import numpy as np
import cv2
import caffe
img = cv2.imread("ak.png")
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
net = caffe.Net("VGG_FACE_deploy.prototxt","VGG_FACE.caffemodel", caffe.TEST)
print net.forward(img)
Can you help me ?
UPDATE 1
This working code is example in matlab
% Copyright (c) 2015, Omkar M. Parkhi
% All rights reserved.
img = imread('ak.png');
img = single(img);
Img = [129.1863,104.7624,93.5940] ;
img = cat(3,img(:,:,1)-averageImage(1),...
img(:,:,2)-averageImage(2),...
img(:,:,3)-averageImage(3));
img = img(:, :, [3, 2, 1]); % convert from RGB to BGR
img = permute(img, [2, 1, 3]); % permute width and height
model = 'VGG_FACE_16_deploy.prototxt';
weights = 'VGG_FACE.caffemodel';
caffe.set_mode_cpu();
net = caffe.Net(model, weights, 'test'); % create net and load weights
res = net.forward({img});
prob = res{1};
caffe_ft = net.blobs('fc7').get_data();
To use python interface you need to transform the input image before feeding it to the net
img = caffe.io.load_image( "ak.png" )
img = img[:,:,::-1]*255.0 # convert RGB->BGR
avg = np.array([93.5940, 104.7624, 129.1863]) # BGR mean values
img = img - avg # subtract mean (numpy takes care of dimensions :)
Now img is H-by-W-by-3 numpy array.
Caffe expects its inputs as 4D: batch_index x channel x width x height.
Therefore you need to transpose the input and add a singleton dimension to represent the "batch_index" leading dimension
img = img.transpose((2,0,1))
img = img[None,:] # add singleton dimension
Now you can run the forward pass
out = net.forward_all( data = img )
OpenCV reads in BGR and scaled to 255 format by default, so:
img = cv2.imread('ak.png')
avg = np.array([93.5940,104.7624,129.1863]) # BGR mean from VGG
img -= avg # subtract mean
img = img.transpose((2,0,1)) # to match image input dimension: 3x224x224
img = img[None,:] # add singleton dimension to match batch dimension
out = net.forward_all(data = img)
Try passing a single element list to the method.
net.forward ([img])