Broadcast one channel in Numpy array into three channels
If you absolutely want to have the mask being (2560, 1920, 3)
, you can simply expand it along an axis (there are several ways to do that, but this one is quite straightforward):
>>> mask = np.random.random_integers(0, 255, (15, 12))
>>> mask_3d = mask[:, :, None] * np.ones(3, dtype=int)[None, None, :]
>>> mask.shape
(15L, 12L)
>>> mask_3d.shape
(15L, 12L, 3L)
However, in general, you can use these broadcasts directly. For instance, if you want to multiply your image by your mask:
>>> img = np.random.random_integers(0, 255, (15, 12, 3))
>>> img.shape
(15L, 12L, 3L)
>>> converted = img * mask[:, :, None]
>>> converted.shape
(15L, 12L, 3L)
So you never have to create the (n, m, 3)
mask: broadcasting is done on the fly by manipulating the strides of the mask array, rather than creating a bigger, redundant one. Most of the numpy operations support this kind of broadcasting: binary operations (as above), but also indexing:
>>> # Take the lower part of the image
>>> mask = np.tri(15, 12, dtype=bool)
>>> # Apply mask to first channel
>>> one_channel = img[:, :, 0][mask]
>>> one_channel.shape
(114L,)
>>> # Apply mask to all channels
>>> pixels = img[mask]
>>> pixels.shape
(114L, 3L)
>>> np.all(pixels[:, 0] == one_channel)
True
How to convert a 1 channel image into a 3 channel with opencv2?
Here's a way of doing that in Python:
img = cv2.imread("D:\\img.jpg")
gray = cv2.cvtColor(img, cv.CV_BGR2GRAY)
img2 = np.zeros_like(img)
img2[:,:,0] = gray
img2[:,:,1] = gray
img2[:,:,2] = gray
cv2.circle(img2, (10,10), 5, (255,255,0))
cv2.imshow("colour again", img2)
cv2.waitKey()
Here's the complete code for OpenCV3:
import cv2
import numpy as np
img = cv2.imread('10524.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img2 = np.zeros_like(img)
img2[:,:,0] = gray
img2[:,:,1] = gray
img2[:,:,2] = gray
cv2.imwrite('10524.jpg', img2)
Get the second channel from a three channels image as a Numpy array
If you are asking about a usage convention, in image processing for machine learning, I usually see each image flattened so that each image is one long row, in row-major order followed by channel order. Numpy has obj.flatten() command to make this easy. Then to retrieve the middle channel, Numpy slicing or indexing can be used. Each processed batch has many images (rows), and each image is one very long flattened row.
Example:
b = a.flatten()
print(b)
# output array([1, 2, 3, 4, 5, 6, 7, 8, 9])
channel2 = b[3:6]
print(channel2)
# output array([4, 5, 6])
For other use cases, there may be a different convention.
Longer example using a 3x3 image array with 3 channels.
Note numerical values are in row-major order followed by channel order.
img_a = np.arange(0, 27).reshape(3, 3, 3)
''' output
array([[[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8]],
[[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17]],
[[18, 19, 20],
[21, 22, 23],
[24, 25, 26]]])
'''
# Flatten into one long row
row_a = img_a.flatten()
# output array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
# 17, 18, 19, 20, 21, 22, 23, 24, 25, 26])
# Select middle channel using Numpy slicing
channel_mid = row_a[9:18]
# output array([ 9, 10, 11, 12, 13, 14, 15, 16, 17])
# Convert middle channel back into a matrix shape (if needed).
matrix_mid = channel_mid.reshape(3, 3)
''' output
array([[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17]])
'''
How to convert a 1 channel image into a 3 channel with PIL?
Here's one way without looking too hard at the docs..
fake image:
im = Image.new('P', (16,4), 127)
Get the (pixel) size of the single band image; create a new 3-band image of the same size; use zip
to create pixel tuples from the original; put that into the new image..
w, h = im.size
ima = Image.new('RGB', (w,h))
data = zip(im.getdata(), im.getdata(), im.getdata())
ima.putdata(list(data))
Or even possibly
new = im.convert(mode='RGB')
convert a grayscale image to a 3-channel image
You can use np.stack
to accomplish this much more concisely:
img = np.array([[1, 2], [3, 4]])
stacked_img = np.stack((img,)*3, axis=-1)
print(stacked_img)
# array([[[1, 1, 1],
# [2, 2, 2]],
# [[3, 3, 3],
# [4, 4, 4]]])
ValueError: could not broadcast input array from shape (300,300,3) into shape (300,300)
Since I was able to identify the problem after some discussion in the comments, I will post it as an answer.
At the line
training_images = np.array([i[0] for i in training_data]).reshape(-1, IMAGE_SIZE, IMAGE_SIZE, 1)
you are attempting to reshape 3-channel RGB images into single channel (greyscale) images, which is not possible (and also not something you want to do, since you want to keep the colours), hence the ValueError
. This part was only necessary before you removed img = img.convert('L')
, in order to give the training data the proper shape for the model, which had an input shape of (IMAGE_SIZE, IMAGE_SIZE, 1)
.
Now that you are working with RGB images, the reshape
can be removed, since the images will already have the correct shape (IMAGE_SIZE, IMAGE_SIZE, 3)
as returned by load_data()
. However, as explained in nneonneo's answer, your model will need to be modified to be able to handle the new input shape.
Convert multi-channel PyAudio into NumPy array
It appears to be interleaved sample-by-sample, with left channel first. With signal on left channel input and silence on right channel, I get:
result = [0.2776, -0.0002, 0.2732, -0.0002, 0.2688, -0.0001, 0.2643, -0.0003, 0.2599, ...
So to separate it out into a stereo stream, reshape into a 2D array:
result = np.fromstring(in_data, dtype=np.float32)
result = np.reshape(result, (frames_per_buffer, 2))
Now to access the left channel, use result[:, 0]
, and for right channel, use result[:, 1]
.
def decode(in_data, channels):
"""
Convert a byte stream into a 2D numpy array with
shape (chunk_size, channels)
Samples are interleaved, so for a stereo stream with left channel
of [L0, L1, L2, ...] and right channel of [R0, R1, R2, ...], the output
is ordered as [L0, R0, L1, R1, ...]
"""
# TODO: handle data type as parameter, convert between pyaudio/numpy types
result = np.fromstring(in_data, dtype=np.float32)
chunk_length = len(result) / channels
assert chunk_length == int(chunk_length)
result = np.reshape(result, (chunk_length, channels))
return result
def encode(signal):
"""
Convert a 2D numpy array into a byte stream for PyAudio
Signal should be a numpy array with shape (chunk_size, channels)
"""
interleaved = signal.flatten()
# TODO: handle data type as parameter, convert between pyaudio/numpy types
out_data = interleaved.astype(np.float32).tostring()
return out_data
numpy filter across dimensions for specific values
I'm sure you can use select
for masking, and ravel
to get 1-D
array:
array = np.array([[[0,0,0],[128,128,128]],
[[128,128,128],[255,255,0]]
])
label = np.select([(array==(0,0,0)).all(-1), # all make sure all channels are identical
(array==(255,255,0)).all(-1)],
[1,2], 0)
print(label.ravel())
Output:
array([1, 0, 0, 2])
Related Topics
How to Divide Each Column of Pandas Dataframe by a Series
Python Format Size Application (Converting B to Kb, Mb, Gb, Tb)
How to Verify If a Button Is Enabled and Disabled in Webdriver Python
Replacing Blank Values (White Space) With Nan in Pandas
How to Remove Parentheses from a String
How to Remove Square Brackets from List in Python
How to Remove Strings Present in a List from a Column in Pandas
How to Clear Only Last One Line in Python Output Console
Removing Backslashes from a String in Python
How to Limit the User Input to Only Integers in Python
How to Kill a While Loop With a Keystroke
How to Determine If My Python Shell Is Executing in 32Bit or 64Bit
How to Constantly Run Python Script in the Background on Windows
How to Check If a String Column in Pyspark Dataframe Is All Numeric
How to Convert Strings With Billion or Million Abbreviation into Integers in a List
Calculating the Area Under a Curve Given a Set of Coordinates, Without Knowing the Function
Python: Pandas Pd.Read_Excel Giving Importerror: Install Xlrd >= 0.9.0 for Excel Support