   Table of content

## Numpy Arrays for OpenCV

Images are treated as Array of colors in OpenCV

Arrays are nothing but data store in continuous memory; this data could be in any data type in python. We can create arrays in multiple ways. I have listed a few below.

##### From List to Arrays:

We can create the arrays from the list data types.

``````import numpy as np
my_first_list = [1, 8, 2]
type(my_first_list)

#output
list``````

Convert the list into an array using the array() function present in the numpy module.

``````first_array = np.array(my_first_list)
print(first_array)
print(type(first_array))

# output
[1 8 2]
<class 'numpy.ndarray'>``````
##### Arrays using arange():

We can create the arrays using `arange()` function in the numpy(can be called 'a range'). `arange()` function accepts three parameters.

• Start : the starting value for the array, first element value.
• Stop : up to this, the array will be created and excluding the stop value.
• Step : the interval between the elements in the array.
The last value in the array may or may not reach the stop value when the user provides an interval.

Without step, by default, the step will be considered as 1 if no step value is provided.

``````np.arange(1, 9)
#output
array([1, 2, 3, 4, 5, 6, 7, 8])``````

The step value is 5, and the array will have an interval of 5 between the values in the array.

``````np.arange(1, 9, 5)
#output
array([1, 6])``````

The step value could be negative. When negative step value is provided, then the interval will be in negative

``````np.arange(90, 1, -10)
#output
array([90, 80, 70, 60, 50, 40, 30, 20, 10])``````

Start value and step values are optional, but the stop value is mandatory. When the start value is not given, then the array will be started with 0 as the start value.

``````np.arange(9)
#output
array([0, 1, 2, 3, 4, 5, 6, 7, 8])``````

We can generate the floating values also using the `arange()` function.

``````print(np.arange(1.0, 9))
print(np.arange(1.0, 9.0))
print(np.arange(1.0, 9.0, 3.0))

#output
[1. 2. 3. 4. 5. 6. 7. 8.]
[1. 2. 3. 4. 5. 6. 7. 8.]
[1. 4. 7.]``````

You can not use the char along with `arange()` function.

``````np.arange('a', 'z')
#output
-------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-28-747b6224a3cd> in <module>
----> 1 np.arange('a', 'z')
TypeError: unsupported operand type(s) for -: 'str' and 'str'``````

## Operations over Arrays in numpy

In multi-dimensional arrays, the array will be present in the form of a table like rows and columns. To access any element, we got to provide row and column index values. We can create multi-dimensional arrays in a few ways; let's see them.

##### zeros() function in numpy:
zeros() funtion creates arrays with float values

`zeros()` function will create an array with the given shape, here the shape is nothing but the number of rows and columns.

`zeros()` function can create 1d arrays as well when only one value is given in the shape tuple, then 1D will be created with given number values.

``````np.zeros()
#output
array([0., 0.])``````

`zeros()` creates a 2D array when we provide two values in the shape tuple/list, 2D arrays are nothing but a table/matrix.

``````np.zeros([2, 3])
#output
array([[0., 0., 0.],
[0., 0., 0.]])``````

Numpy creates 3D array when we provide 3 values to the shape.

``````np.zeros(shape = (2,4,6))
#output
array([[[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.]],

[[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.]]])``````
##### ones():

Similar to zeros(), we have another method called ones(), which will create the arrays with a value of 1.

``````np.ones([rows, columns])
np.ones([2, 10])
#output
array([[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]])``````
##### random numbers generation:

In some cases, we might need to generate the random number into an array, random.randint() will create an array with a given number of values, and these values will be very random.

First and seconds values are low and high value, so a random number will be generated from 0 till 100 (100 is exclusive). The third parameter is a number of random numbers to be generated.

Generate only one random number as an int

``````np.random.randint(start, end) #exclusive of end
np.random.randint(0, 100)``````

Generate random numbers as an array.

``````np.random.randint(start, end,  number_items)
np.random.randint(0, 100, 5)
#output
array([53, 56, 36, 55, 33]) # output may change because it is random``````
##### the max value of an array :

max() function provides the max value of the array.

``````sample_array = np.random.randint(0,100, 5)
print(sample_array)
print(sample_array.max())
#output
[51 91 16 37 44]
91``````
While writing this, I made my program like below, and I was wondering why the correct value is not picked as a max number.
``````print(np.random.randint(0,100, 5))
print(np.random.randint(0,100, 5).max())
#output
[71 65 56 46  3]
72``````
Do note that "np.random.randint(0,100, 5)" will generate new array whenever it is called, so store the result and process on it.

min() function provides min value of an array

``````sample_array = np.random.randint(0,100, 5)
print(sample_array)
print(sample_array.min())
#output
[22 46 20 48 23]
20``````

Mean value of the array

``````sample_array = np.random.randint(0,100, 5)
print(sample_array)
print(sample_array.mean())
#output
[11 90 96 60 11]
53.6``````
##### Position of value in the array.

You can find the position of the max and min values in the array with numpy, by using the argmax() and argmin() functions.

``````sample_array = np.random.randint(0, 100, 5)
print(sample_array)
print("position of min value " , sample_array.argmin())
print("position of max value ", sample_array.argmax())
#output
[13 75 52 56 51]
position of min value  0
position of max value  1``````
##### the shape of an array.

The shape of an array is nothing but the number of rows and columns present in the array.

``````print(np.random.randint(0,100, 5).shape)
#output
(5,)``````

The result is having the number of values because it is a 1D array.

##### change the shape:

Sometimes it becomes very important to change the number of rows and columns of an array, which is known as changing the shape. reshape() in numpy helps the user to change the shape.

The number of elements should match for shape. *(12 elements can be created as * 6 rows and 2 columns and 6 rows 3 rows and 4 columns 4 rows and 3 columns, many more but the total number of elements should be same.

``````shape_array = np.random.randint(0,100, 12)
print(shape_array)
print("---4rows*3columns---")
print(shape_array.reshape(4,3))
print("---2rows*6columns---")
print(shape_array.reshape(2,6))`````` wrong details for shape

When you provide wrong rows and column for shape, then the number of elements in the array may not be sufficient, so numpy gives an error

``````shape_array = np.random.randint(0,100, 12)
print(shape_array)
print("---trying for 5rows*5columns---")
print(shape_array.reshape(5,5))``````

The above program requires 15 elements, but the array has only 12 elements. So error occurs

ValueError: cannot reshape array of size 12 into shape (5,5)
##### retrieve the value at a position

The index of the arrays starts from 0, and the index is nothing but the position where a specific value id present in the array.

So based on this position, we can find the value present at that location. We need to specify the position inside brackets along with the name of the array.

``````my_first_list = [1, 8, 2]
first_array = np.array(my_first_list)
print(first_array)
#output
8``````

Get position value from a table/ matrix

``````my_first_matrix = [[1, 8, 2],
[3, 4, 7]]
first_array_matrix = np.array(my_first_matrix)
row = 0 # starts from 0
col = 2 # starts from 0
print(first_array_matrix[row, col])
#output
2
``````
##### slicing:

Slicing is operation to get values from a list; slicing is usually used to fetch more the one values. In slicing, we mention the start and end of the required elements.

Start and end values are inclusive, start and end values are separated by a :(colon) inside brackets.

``````my_first_list = [1, 8, 2, 4, 5, 9]
first_array = np.array(my_first_list)
print(first_array[1:4])
#output
array([8, 2, 4])``````

If we do not mention the start value, then by default 0 will be considered as start value.

``````my_first_list = [1, 8, 2, 4, 5, 9]
first_array = np.array(my_first_list)
print(first_array[:4])
#output
array([2, 4, 5, 9])``````

When we do not mention the start and end value, then we get the complete list because when there is not start value, the default start value is 0, and default end value id length of the list

So we get the full list.

``````my_first_list = [1, 8, 2, 4, 5, 9]
first_array = np.array(my_first_list)
first_array[:]
#output
array([1, 8, 2, 4, 5, 9])``````

# We can get the values using -ve values when you -ve then -1 points to the last element. In the below list, 9 is the last value.

``````my_first_list = [1, 8, 2, 4, 5, 9]
first_array = np.array(my_first_list)
print(first_array[-1])
print(first_array[:-3])
#output
9
[1 8 2]``````

An interesting thing, when you mention end as -1, then we get the list in reverse, but we need to use the double colon.

``````my_first_list = [1, 8, 2, 4, 5, 9]
first_array = np.array(my_first_list)
print(first_array[::-1])
print(first_array[3::-1])
#output
[9 5 4 2 8 1]
[4 2 8 1]``````

Now we know how slicing works with the 1D array; slicing operation works in the same way for Multi-dimension arrays/matrix as well.

``````my_first_matrix = [[1, 8, 2],
[3, 4, 7]]
first_array_matrix = np.array(my_first_matrix)``````

When we do not provide the start and end, then we get complete values.

``````print(first_array_matrix[:, :])
#output
array([[1, 8, 2],
[3, 4, 7]])``````

We can get a specific row from the matrix; we need to provide only : for column value so that all values in the column are included and pass the row value as the first param.

#Fecteches the first row

``````print(first_array_matrix[0,:])
#output
array([1, 8, 2])``````

Similarly, we can get the column values as well.

``````print(first_array_matrix[:,1])
#output
array([8, 4])``````

We can get a partial matrix if we provide the row and column values.

``````print(first_array_matrix[0:2,0:2])
#output
array([[1, 8],
[3, 4]])``````

We can assign values to the list/matrix while slicing.

``````first_array_matrix[0:2,0:2] = 8
print(first_array_matrix)
#output
[[8 8 2]
[8 8 7]]``````