OpenCV (Python)
| Language | Python 3 (binding of the C++ library) |
|---|---|
| License | Apache 2.0 |
| Repository | github.com/opencv/opencv-python (wheels), github.com/opencv/opencv |
| Documentation | imgcodecs module |
| Depends on | NumPy; libjpeg-turbo is bundled in the wheels |
| Read / write | yes / yes; baseline and progressive, quality, subsampling, Huffman optimization; no metadata on write |
OpenCV’s cv2.imread and cv2.imwrite decode and encode JPEG with libjpeg-turbo and return NumPy arrays of shape (height, width, 3) in BGR order. It’s the usual way to load images for computer vision and ML pipelines. imread applies the Exif orientation by default.
OpenCV ignores metadata when writing: Exif, XMP and ICC profiles are lost. Use Pillow when metadata matters.
Installation#
Shell
pip install opencv-python
# on servers without a display
pip install opencv-python-headless
Basic usage: read, process and write a JPEG#
Python
import cv2
img = cv2.imread("photo.jpg") # BGR, uint8; None if the file can't be read
if img is None:
raise SystemExit("cannot read photo.jpg")
h, w = img.shape[:2]
print(w, "x", h)
small = cv2.resize(img, (w // 2, h // 2), interpolation=cv2.INTER_AREA)
gray = cv2.cvtColor(small, cv2.COLOR_BGR2GRAY)
cv2.imwrite("out.jpg", gray, [cv2.IMWRITE_JPEG_QUALITY, 85])
How to save a progressive JPEG with 4:4:4 subsampling#
Python
params = [
cv2.IMWRITE_JPEG_QUALITY, 92,
cv2.IMWRITE_JPEG_PROGRESSIVE, 1,
cv2.IMWRITE_JPEG_OPTIMIZE, 1,
cv2.IMWRITE_JPEG_SAMPLING_FACTOR, cv2.IMWRITE_JPEG_SAMPLING_FACTOR_444,
]
ok = cv2.imwrite("out.jpg", img, params)
The default quality is 95 and the default subsampling 4:2:0.
How to decode a JPEG at half, quarter or eighth size#
The IMREAD_REDUCED_* flags use libjpeg’s scaled decoding, much faster than full decode plus resize:
Python
quarter = cv2.imread("big.jpg", cv2.IMREAD_REDUCED_COLOR_4)
gray_eighth = cv2.imread("big.jpg", cv2.IMREAD_REDUCED_GRAYSCALE_8)
How to encode and decode JPEG in memory#
Python
import cv2
import numpy as np
ok, buf = cv2.imencode(".jpg", img, [cv2.IMWRITE_JPEG_QUALITY, 80])
jpeg_bytes = buf.tobytes() # send over the network, store in a DB...
decoded = cv2.imdecode(np.frombuffer(jpeg_bytes, np.uint8), cv2.IMREAD_COLOR)
How to convert between OpenCV and Pillow#
Python
from PIL import Image
pil_img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
back = cv2.cvtColor(np.asarray(pil_img), cv2.COLOR_RGB2BGR)
Tips#
cv2.imreadreturnsNoneinstead of raising an error. Always check it.- On Windows
imreadfails on paths with non-ASCII characters. Usecv2.imdecode(np.fromfile(path, np.uint8), cv2.IMREAD_COLOR). - Pass
cv2.IMREAD_COLOR | cv2.IMREAD_IGNORE_ORIENTATIONto get the pixels as stored, without Exif rotation.