What is the use of applying img_to_array() after cv2.imread() In a book, I saw the following code to load images from a directory:
1.image = cv2.imread(imagePath)
2.image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
3.image = cv2.resize(image, (28,28))            
4.image = img_to_array(image)
5.data.append(image)

cv2.imread()

It converts image to a numpys array in BGR format

img_to_array()

It converts PIL instance to numpy array, but in this case image will stay in BGR format as the image is loaded by cv2.

What is the use of img_to_array() (from keras.preprocessing.image module) after cv2.imread(), as it is already in numpy array.
Also:
To double check, I displayed images before and after applying img_to_array() using cv2.imshow().
BEFORE applying img_to_array()

AFTER applying img_to_array()###

Also Also:
But, if I try to save the images using cv2.imwrite into a file, they both are saved as normal (ie. like the first image). Why is this happening?
This is because of the data type you provide to the imshow() function.
Check the documentation:

The function may scale the image, depending on its depth:
If the image is 8-bit unsigned, it is displayed as is. If the image is
16-bit unsigned or 32-bit integer, the pixels are divided by 256. That
is, the value range [0,255*256] is mapped to [0,255]. If the image is
32-bit or 64-bit floating-point, the pixel values are multiplied by
255. That is, the value range [0,1] is mapped to [0,255].

So when you use cv2.imread() it reads data uint8, that is 8-bit unsigned format thus imshow() displays the original data.
But when you use img_to_array() it converts data to the float. Thus imshow() multiplies it with 256. It expects the float values in normalized form, that is all the pixels are divided by 256. That is the reason for such a display.
This is how cv2.imread() data looks like...

and its data type...

This is how img_to_array() data looks like...

and its data type...

If you divide your image by 1.0 to convert it to the float...
import cv2
# from keras.preprocessing.image import img_to_array
image = cv2.imread(&quot;car.jpg&quot;)
image = image/1.0
cv2.imshow(&quot;Divided by 1.0&quot;, image)
cv2.waitKey(0)

...this is what you will get:

Same as img_to_array.
But it you divide image with 256.0 as follows:
import cv2
# from keras.preprocessing.image import img_to_array
image = cv2.imread(&quot;car.jpg&quot;)
image = image/256.0
cv2.imshow(&quot;Divided by 256.0&quot;, image)
cv2.waitKey(0)

You get the original image since imshow() multiplies the float with 256.

So what you need is to divide your img_to_array() output by 256 or convert it to the uint8.