All formats

OpenCV (Python)

LanguagePython 3 (binding of the C++ library)
LicenseApache 2.0
Repositorygithub.com/opencv/opencv-python (wheels), github.com/opencv/opencv
Documentationimgcodecs module
Depends onNumPy; libjpeg-turbo is bundled in the wheels
Read / writeyes / 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#