Reputation: 5450
I have an image represented as numpy array which has values of 0 and 255 (no other value within the range). What is the best way to convert it to 0 and 1 array.
Upvotes: 7
Views: 14662
Reputation: 11922
my_array = np.array([255,255,0,0])
my_array = my_array / 255
Will output
array([ 1., 1., 0., 0.])
In other words, it will work to normalize all values in the range of 0-255 (even though you said it's the only 2 values, it will work for everything in between as well, while keeping the ratios)
Upvotes: 8
Reputation: 3392
Because there are so many answers that give the right answer, I just wanted to test the different approaches and decide which is the best in terms of computational cost. I wrote the following code that creates a given data set, which is an image of 0 and 255 values, placed at random, and then I study the mean elapsed time for each proposed algorithm, varying the number of pixels of the image (note that I use the mean to reduce the noise in the measurement):
import numpy as np
import time
times1_all = []
times2_all = []
times3_all = []
for i in xrange(20):
times1 = []
times2 = []
times3 = []
xsizes = np.arange(100,10000,500)
print len(xsizes)
for xsize in xsizes:
#Create the dataset
ysize = xsize
xrand = np.random.randint(0,xsize, xsize)
yrand = np.random.randint(0,ysize, xsize)
a = np.zeros([xsize,ysize])
a[xrand, yrand] = 255
start = time.time()
b = (a == 255).astype('int')
stop = time.time()
time1 = stop-start
start = time.time()
b = a/255
stop = time.time()
time2 = stop-start
start = time.time()
b = a.clip(max=1)
stop = time.time()
time3 = stop-start
print time3
times1.append(time1)
times2.append(time2)
times3.append(time3)
print 'Elapsed times --> (1)/(1)=%.2f, (2)/(1)=%.2f, (3)/(1)=%.2f' %(time1/time1,time2/time1,time3/time1)
times1_all.append(times1)
times2_all.append(times2)
times3_all.append(times3)
times1_mean = np.mean(times1_all, axis=0)
times2_mean = np.mean(times2_all, axis=0)
times3_mean = np.mean(times3_all, axis=0)
The results of this test are shown in the image below, which shows the elapsed time of different algorithms as a function of the image pixel number (I only quote the side number of pixels in the x-axis). As expected, the bigger the image, the longer it takes to do the job. However, it is clear that there are systematic differences amongst the algorithms. For any number of pixels, the algorithms proposed by @randomir and @Ofer perform better than that proposed by @user1717828. So, According to this metric, @Ofer and $randomir are equivalent.
Upvotes: 2
Reputation: 18687
Sounds like a job for numpy.clip
:
>>> a = np.array([0, 255, 0, 255, 255, 0])
>>> a.clip(max=1)
array([0, 1, 0, 1, 1, 0])
From the docs:
Given an interval, values outside the interval are clipped to the interval edges. For example, if an interval of [0, 1] is specified, values smaller than 0 become 0, and values larger than 1 become 1.
Upvotes: 5
Reputation: 7225
You can mask (either with >0
or ==255
or really anything else) then convert to type int
:
npa = np.array([0,255,0,255,255,255,0])
npa
array([ 0, 255, 0, 255, 255, 255, 0])
(npa>0).astype('int')
array([0, 1, 0, 1, 1, 1, 0])
Upvotes: 1