Convert an image array to a binarized image - python

I have an Image array Indice which is like this:
array([[158, 0, 252, ..., 185, 186, 187],
[254, 253, 252, ..., 188, 188, 189],
[247, 249, 252, ..., 188, 187, 186],
...,
[176, 172, 168, ..., 204, 205, 205],
[178, 175, 172, ..., 206, 205, 206],
[180, 177, 174, ..., 206, 207, 207]], dtype=uint8)
I want to convert Indice to a binarized image (values between 0 and 1) with a threshehold near 0 (0.1 or 0.2). how can I do it in Python ?

You can use np.where to binarize the data after converting it to the range from 0 to 1 by dividing by 255
threshold = 0.2
new_indice = np.where(Indice/255>=threshold, 1, 0)

If a boolean binary array is fine for you, you can simply use numpy's element-wise comparison:
new_indice = (Indice/255 > threshold)
In fact, for random test arrays this seemed to be slightly faster than the np.where solution. In case you need an integer binary array you can simply add a 1* in front of the parentheses, but then the speed advantage seems to be gone.

An easy way to do this kind of task is by using list comprehensions.
In your case:
array([[1 if x>threshold else 0 for x in line] for line in Indice])
Where threshold would be set to the value you want.

Related

How to create a 2D array where all elements have the same number?

I would like to create an array size 576x720 where each element has the same number.
I tried it like this but did not succeed:
#Define row and column
int row = 576, col = 720;
#Initialize 2D character array
char array2D[row][col] = {[0 ... (row-1)][0 ... (col-1)] = '137'};
How can I create such an array?
Personally speaking, the easiest way would be using numpy module and full function:
row = 576
col = 720
valueToFill = 137
numpy.full((row, col), valueToFill)
Output
array([[137, 137, 137, ..., 137, 137, 137],
[137, 137, 137, ..., 137, 137, 137],
[137, 137, 137, ..., 137, 137, 137],
...,
[137, 137, 137, ..., 137, 137, 137],
[137, 137, 137, ..., 137, 137, 137],
[137, 137, 137, ..., 137, 137, 137]])
If you wanna make sure the shape of the matrix is as same as what you asked for, you can try calling shape attribute on the array:
row = 576
col = 720
valueToFill = 1
array = numpy.full((row, col), valueToFill)
array.shape
which results in:
(576, 720)
Here it is:
row,col = 576, 720
array2D = [[137]*row for i in range(col)]

How to get a list of doc name from numpy array

I have a 2d numpy array:
dataset_tr = 'data/20news_clean/train.txt.npy'
data_tr = np.load(dataset_tr)
thedata_tr looks like this: It is a 3*10 numpy array:
[array([ 700, 152, 572, 572, 619, 724, 326, 1571, 572, 99])
array([ 331, 152, 397, 1273, 89, 228, 0, 0, 0, 0])
array([ 6, 1, 26, 174, 216, 135, 1060, 259, 75, 7])]
Each row here is a representation for a document in the 20newsgroup dataset.
All I want to do is to create a key out of this 2d array. The result will be 1 * 3 because I had 3 row in my 2d aaray.
Actually what I am doing here is that I am trying to assign a name to each row of that array. So the result will look like this:
['doc1', 'doc2', 'doc3']
I am able to get this but by looping through the 2d array.
Is there any better numpy way of doing this?
You can get the desired result with a list comprehension:
result = ['doc%i' % i for i in range(len(data_tr))]
docs = ['doc'+str(i+1) for i in range(len(data_tr)]

Make an array like numpy.array() without numpy

I've an image processing task and we're prohibited to use NumPy so we need to code from scratch. I've done the logic image transformation but now I'm stuck on creating an array without numpy.
So here's my last output code :
Output :
new_log =
[[236,
232,
226,
.
.
.
198,
204]]
I need to convert this to an array so I can write the image like this (with Numpy)
new_log =
array([[236, 232, 226, ..., 208, 209, 212],
[202, 197, 187, ..., 198, 200, 203],
[192, 188, 180, ..., 205, 206, 207],
...,
[233, 226, 227, ..., 172, 189, 199],
[235, 233, 228, ..., 175, 182, 192],
[235, 232, 228, ..., 195, 198, 204]], dtype=uint8)
cv.imwrite('log_transformed.jpg', new_log)
# new_log must be shaped like the second output
You can make a straightforward function to take your list and reshape it in a similar way to NumPy's np.reshape(). But it's not going to be fast, and it doesn't know anything about data types (NumPy's dtype) so... my advice is to challenge whoever it is that doesn't like NumPy. Especially if you're using OpenCV — it depends on NumPy!
Here's an example of what you could do in pure Python:
def reshape(l, shape):
"""Reshape a list.
Example
-------
>>> l = [1,2,3,4,5,6,7,8,9]
>>> reshape(l, shape=(3, -1))
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
"""
nrows, ncols = shape
if ncols == -1:
ncols = len(l) // nrows
if nrows == -1:
nrows = len(l) // ncols
array = []
for r in range(nrows):
row = []
for c in range(ncols):
row.append(l[ncols*r + c])
array.append(row)
return array

python add multiple arrays together

I have multiple 5x5 arrays which are contained within one large array - the overarching shape is: 5 x 5 x 29. I want to sum every 5 x 5 array to produce one single array, instead of 29 single arrays.
I know that you can do something along the lines of:
new_data = data1[:,:,0] + data1[:,:,1] + ... + data1[:,:,29]
However, this gets very cumbersome for large arrays. Is there an easier way to do this?
Assuming you are using NumPy, you should be able to do this with:
In [13]: data1 = np.arange(100).reshape(5, 5, 4) # For example
In [14]: data1[:,:,0] + data1[:,:,1] + data1[:,:,2] + data1[:,:,3] # Bad way
Out[14]:
array([[ 6, 22, 38, 54, 70],
[ 86, 102, 118, 134, 150],
[166, 182, 198, 214, 230],
[246, 262, 278, 294, 310],
[326, 342, 358, 374, 390]])
In [15]: data1.sum(axis=2) # Good way
Out[15]:
array([[ 6, 22, 38, 54, 70],
[ 86, 102, 118, 134, 150],
[166, 182, 198, 214, 230],
[246, 262, 278, 294, 310],
[326, 342, 358, 374, 390]])
If you are saying you have a list of arrays, then use a for loop.
for i in range(29):
new_data+= data1[:,:,i]
If you are saying you have a tensor or some ND array you should review and research numpy's ND array docs.
You can use a for loop. Like this:
import numpy as np
new_data = np.zeros((5, 5))
for i in range(29):
new_data += data1[:,:,i]

How can I change the dimension of an array?

How to change this array into a 5*2 matrix?
This is my array:
[[ ([[315, 327, 333, 334, 339]], [[146, 143, 145, 145, 146]])]]
how to change the array into a 5*2 matrix
I'm really not sure what you meant by that, but if you want to rotate it (2*5 --> 5*2) you can try this
arrays = [[315, 327, 333, 334, 339], [146, 143, 145, 145, 146]]
newArrays = [[] for _ in range(len(arrays[0]))] # initialise this list first
for arr in arrays:
for i,item in enumerate(arr):
newArrays[i].append(item)
print(newArrays)
# [[315, 146], [327, 143], [333, 145], [334, 145], [339, 146]]
Numpy provides reshape method to reshape an array into array of any dimension with the same number of elements. You can use the method to reshape array of any shape into another shape as long as the product of the original array dimension(s) is/are equal to the product of new array dimension(s).
import numpy as np
a=[[ ([[315, 327, 333, 334, 339]], [[146, 143, 145, 145, 146]])]]
b=np.array(a).reshape((5,2))
list_b=b.tolist();
print list_b
# [[315, 327], [333, 334], [339, 146], [143, 145], [145, 146]]

Categories

Resources