A bit map picture is exactly what the name makes one suspect: a sequence of bits (0 or 1) that together represent a digital photo. The picture consists of a matrix (rectangle grid) of individual picture elements (or pixels) that each have their own colour. Lets us look at a typical bit map picture to explain this principle:
On the left you can see a photo and on the right you can see a 250% enlargement of one of the mountains. As you can see in the enlargement, a bit map picture consists of hundreds of rows and columns of small elements that each have their own colour. One of those elements is called a pixel (which is the short form of picture element). The human eye is not capable of seeing an individual pixel, which is the reason why we cannot see a picture with flowing gradations. The number of pixels that is necessary to get a realistic looking picture, depends largely on the way the picture is going to be used.
The colour of a pixel in a bit map picture can be presented in different ways. For this assignment, we distinguish two categories:
black-and-white pictures: the colour of a pixel is a greyscale that is represented as an integer between 0 (black) and 255 (white) or as a floating point number between 0.0 (black) and 1.0 (white).
colour picture: the colour of a pixel is represented by a list of three numbers that represent a red, a green and a blue component. This is called the RGB-representation of the colour. By mixing different amounts of these components, a colour is obtained (think about mixing coloured paint). Every component is represented either by an integer between 0 and 255, or by a floating point number between 0.0 and 1.0. The extra values respectively represent 0% and 100% colour for this component.
We represent a bit map as a list of lists, where the inner lists always represent the colours of a sequence of pixels from a row of the picture. Every colour is represented by an integer or a floating point (black-and-whit pictures) or a list of three integers or floats (colour pictures). In this assignment, we ask you to do image manipulations, by converting every colour of the bit map to another colour. You work as follows:
Write a function color2gray that converts the RGB representation ($$r$$, $$g$$, $$b$$) of a colour (with $$r$$, $$g$$ and $$b$$ integers or floats) to a number $$x \in [0, 1]$$ that represents a greyscale, base on the following formula \[ x = 0.299r + 0.587g + 0.114b \] If the colour components are represented by integers, these first have to be divided by 255 before applying the formula. A list of three integers should be given to the function. The function should print the value of $$x$$ as a result. With this function, a colour image can be converted to a black-and-white picture.
Write a function invert, that converts a colour to its invert colour as follows:
$$x \rightarrow 255 - x$$ if the colour is represented by $$x \in \mathbb{N}$$
$$x \rightarrow 1 - x$$ if the colour is represented by $$x \in \mathbb{R}$$
$$[r, g, b] \rightarrow [255 -r, 255 - g, 255 -b]$$ if $$r, g, b \in \mathbb{N}$$
$$[r, g, b] \rightarrow [1 -r, 1 - g, 1 -b]$$ if $$r, g, b \in \mathbb{R}$$
Write a function convertBitmap in which all colours of a bit map can be converted in another colour. To the compulsory parameter bitmap a list of lists should be given that represents a bit map as described above. The function should print a new list of lists that represents the bit map that is obtained by converting the values of the bit map given. The standard conversion is done by squaring all colours of the given bit map:
$$x \rightarrow (x / 255)^2$$ if the colour is represented by $$x \in \mathbb{N}$$
$$x \rightarrow x^2$$ if the colour is represented by $$x \in \mathbb{R}$$
$$[r, g, b] \rightarrow [(r / 255)^2, g / 255)^2, b / 255)^2]$$ if $$r, g, b \in \mathbb{N}$$
$$[r, g, b] \rightarrow [r^2, g^2, b^2]$$ if $$r, g, b \in \mathbb{R}$$
To determine whether a given object has a certain type of specifications, you can of course use the built-in function type(o), that prints the type of specification of the object o. However, it is better to use the built-in function isinstance(o, t). This function prints a Boolean value that indicates whether the object o belongs to type t, or not.
>>> type(3) == int
True
>>> isinstance(3.14, int)
False
>>> isinstance(3.14, float)
True
>>> isinstance([1, 2, 3], list)
True
>>> color2gray([238, 172, 98])
0.7188156862745098
>>> color2gray([0.7, 0.2, 0.6])
0.3951
>>> invert(168)
87
>>> invert(0.4)
0.6
>>> invert([238, 172, 98])
[17, 83, 157]
>>> invert([0.7, 0.2, 0.6])
[0.3, 0.8, 0.4]
>>> matrix = [[234, 124, 28], [36, 45, 179]]
>>> convertBitmap(bitmap=matrix, converter=invert)
[[21, 131, 227], [219, 210, 76]]
>>> matrix = [[[0.2, 0.4, 0.6], [0.5, 0.9, 0.0]], [[0.5, 0.7, 0.1], [0.4, 0.3, 1.0]]]
>>> convertBitmap(matrix)
[[[0.04, 0.16, 0.36], [0.25, 0.81, 0.0]], [[0.25, 0.49, 0.01], [0.16, 0.09, 1.0]]]
>>> convertBitmap(bitmap=matrix, converter=color2gray)
[[0.363, 0.6778], [0.5718, 0.4097]]
>>> convertBitmap(bitmap=matrix, converter=invert)
[[[0.8, 0.6, 0.4], [0.5, 0.1, 1.0]], [[0.5, 0.3, 0.9], [0.6, 0.7, 0.0]]]