In Python and OpenCV, you can read (load) and write (save) image files with cv2.imread()
and cv2.imwrite()
. Images are read as NumPy array ndarray
.
This article describes the following contents.
- Read and write images in color (BGR)
- Read an image file with
cv2.imread()
- Write
ndarray
as an image file withcv2.imwrite()
- Read an image file with
- Read and write images in grayscale
- Read an image file with
cv2.imread()
- Write
ndarray
as an image file withcv2.imwrite()
- Read an image file with
- Notes on
cv2.imread()
cv2.imread()
does not raise an exception- JPEG library
- If images cannot be read with
cv2.imread()
- Check the current directory
- Supported formats for
cv2.imread()
It is also possible to read image files as ndarray
using Pillow instead of OpenCV.
The following image is used as an example.
Read and write images in color (BGR)
Read an image file with cv2.imread()
Color image files are read as a 3D ndarray of row (height) x column (width) x color (3)
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import cv2 im = cv2.imread('data/src/lena.jpg') print(type(im)) # <class 'numpy.ndarray'> print(im.shape) # (225, 400, 3) print(im.dtype) # uint8 |
Note that the color order is BGR instead of RGB. As an example, set 0th (B: blue) and 1st (G: green) to 0 (black).
1 2 3 |
im[:, :, (0, 1)] = 0 |
Write ndarray as an image file with cv2.imwrite()
To save ndarray
as an image file, set the file path and ndarray
object to cv2.imwrite()
.
The format of the image file is automatically determined from the file path extension. If it is .jpg
, it is saved as JPEG, and if it is .png
, it is saved as PNG.
1 2 3 |
cv2.imwrite('data/dst/lena_opencv_red.jpg', im) |
Format-specific parameters can be specified for the third parameter. Specify with a list like [paramId_1, paramValue_1, paramId_2, paramValue_2, ...]
.
For example, the quality of JPEG is specified by cv2.IMWRITE_JPEG_QUALITY
. 0
is the lowest and 100
is the highest, the default is 95
.
If saved as 50
:
1 2 3 |
cv2.imwrite('data/dst/lena_opencv_red_low.jpg', im, [cv2.IMWRITE_JPEG_QUALITY, 50]) |
If saved as 100
:
1 2 3 |
cv2.imwrite('data/dst/lena_opencv_red_high.jpg', im, [cv2.IMWRITE_JPEG_QUALITY, 100]) |
Note that JPEG is lossy compression, so even if it is the highest quality 100
, when the saved image is reloaded, a difference occurs with the original pixel value. If you want to save the original image as it is, save it as PNG or BMP.
Read and write images in grayscale
Read an image file with cv2.imread()
By passing cv2.IMREAD_GRAYSCALE
as the second argument of cv2.imread()
, a color image file can be read in grayscale (black and white). Since cv2.IMREAD_GRAYSCALE
is equivalent to 0
, even passing 0
is OK.
It is useful for detecting edges and other situations where color information is not required.
In this case, the image is read as 2D ndarray
of row (height) x column (width)
.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
im_gray = cv2.imread('data/src/lena.jpg', cv2.IMREAD_GRAYSCALE) # im_gray = cv2.imread('data/src/lena.jpg', 0) print(type(im_gray)) # <class 'numpy.ndarray'> print(im_gray.shape) # (225, 400) print(im_gray.dtype) # uint8 |
You can read the image file as color and convert it to grayscale with cv2.cvtColor()
and cv2.COLOR_BGR2GRAY
.
Because cv2.IMREAD_GRAYSCALE
with cv2.imread()
perform codec-dependent conversions instead of OpenCV-implemented conversions, you may get different results on different platforms. cv2.cvtColor()
with cv2.COLOR_BGR2GRAY
is safer to use if you want to handle pixel values strictly.
Write ndarray as an image file with cv2.imwrite()
If 2D ndarray
of row(height) x column(width)
is specified as the argument of cv2.imwrite()
, it is saved as a grayscale image file.
1 2 3 |
cv2.imwrite('data/dst/lena_opencv_gray.jpg', im_gray) |
If you want to save a color image (3D ndarray
) as a grayscale image file, convert it to grayscale with cv2.cvtColor()
and cv2.COLOR_BGR2GRAY
.
If you save 2D ndarray
to a file and read it again with cv2.imread()
, it will be read as 3D ndarray
in which each color is the same value.
It does not automatically read in as a two-dimensional array.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
im_gray_read = cv2.imread('data/dst/lena_opencv_gray.jpg') print(im_gray_read.shape) # (225, 400, 3) import numpy as np print(np.array_equal(im_gray_read[:, :, 0], im_gray_read[:, :, 1])) # True print(np.array_equal(im_gray_read[:, :, 1], im_gray_read[:, :, 2])) # True |
Notes on cv2.imread()
cv2.imread() does not raise an exception
Even if a nonexistent path is specified, cv2.imread()
does not raise an exception and return None
. An error will occur when a user performs some operation assuming it is read as ndarray
.
1 2 3 4 5 6 7 8 9 |
im = cv2.imread('xxxxxxx') print(im) # None # print(im.shape) # AttributeError: 'NoneType' object has no attribute 'shape' |
Even if the file exists, None
is returned if OpenCV does not support it.
1 2 3 4 5 6 |
im = cv2.imread('data/src/sample.csv') print(im) # None |
Because None
is regarded as False
, you can check whether the image was loaded correctly
1 2 3 4 5 6 7 8 9 |
im = cv2.imread('xxxxxxx') if im: print('Image is read.') else: print('Image is not read.') # Image is not read. |
1 2 3 4 5 6 7 8 9 |
im = cv2.imread('xxxxxxx') if not im: print('Image is not read.') else: print('Image is read.') # Image is not read. |
JPEG library
As you can see in the GitHub issue below, the library used to process JPEGs depends on the OpenCV version, platform, etc. Therefore, even if the same file is read, there may be differences in the values if the environment is different.
If images cannot be read with cv2.imread()
Check the current directory
Like the built-in function open()
, with cv2.imread()
and cv2.imwrite()
, you can specify the path of a file with one of the following methods:
- Relative path from the current directory
- Absolute path
If the file should be there but cannot be read, it is often because of a simple mistake that the current directory is different from what is expected.
Supported formats for cv2.imread()
Of course, image files in formats not supported by OpenCV cannot be read.
The following formats are supported by cv2.imread()
of OpenCV 4.2.0
.