OpenCV
| Language | Python 3 (bindings of the C++ library) |
|---|---|
| License | Apache 2.0 |
| Repository | github.com/opencv/opencv, Python packages: opencv-python |
| Documentation | docs.opencv.org, imread |
| Depends on | NumPy (libpng is bundled in the wheels) |
| Read / write | yes / yes, 8 and 16 bits, gray, BGR and BGRA; no text chunks |
OpenCV is a computer vision library. In Python, cv2.imread returns an image as a NumPy array, so you can process it with NumPy, scikit-image or machine learning frameworks directly. It reads and writes PNG with libpng, including 16-bit images and the alpha channel.
Two things trip people up: color channels are in BGR order, not RGB, and imread drops the alpha channel unless you pass cv2.IMREAD_UNCHANGED. OpenCV doesn’t read or write PNG metadata (text chunks, DPI).
Installation#
Shell
pip install opencv-python
# on servers without a GUI:
pip install opencv-python-headless
Basic usage: read and write a PNG#
Python
import cv2
img = cv2.imread("in.png", cv2.IMREAD_UNCHANGED) # keep alpha and 16-bit depth
if img is None:
raise SystemExit("cannot read in.png")
print(img.shape, img.dtype) # e.g. (480, 640, 4) uint8 -> height, width, BGRA
small = cv2.resize(img, (320, 240), interpolation=cv2.INTER_AREA)
if not cv2.imwrite("out.png", small):
raise SystemExit("cannot write out.png")
imread returns None instead of raising when the file is missing or isn’t an image.
How to set PNG compression level#
Python
import cv2
cv2.imwrite("out.png", img, [cv2.IMWRITE_PNG_COMPRESSION, 9]) # 0 (none) .. 9 (smallest), default 1
How to save a 16-bit PNG#
A uint16 array is written as a 16-bit PNG:
Python
import cv2
import numpy as np
depth = np.linspace(0, 65535, 640 * 480, dtype=np.uint16).reshape(480, 640)
cv2.imwrite("depth16.png", depth)
back = cv2.imread("depth16.png", cv2.IMREAD_UNCHANGED)
print(back.dtype) # uint16
How to encode and decode PNG in memory#
Python
import cv2
import numpy as np
ok, buf = cv2.imencode(".png", img) # buf is a 1-D uint8 array
png_bytes = buf.tobytes()
decoded = cv2.imdecode(np.frombuffer(png_bytes, np.uint8), cv2.IMREAD_UNCHANGED)
How to convert between BGR and RGB#
Convert before passing the array to Pillow, Matplotlib or a model that expects RGB:
Python
import cv2
bgra = cv2.imread("in.png", cv2.IMREAD_UNCHANGED)
rgba = cv2.cvtColor(bgra, cv2.COLOR_BGRA2RGBA)
How to convert PNG to JPEG#
Python
import cv2
import numpy as np
img = cv2.imread("in.png", cv2.IMREAD_UNCHANGED)
if img.ndim == 3 and img.shape[2] == 4:
# blend onto white using the alpha channel
alpha = img[:, :, 3:4].astype(np.float32) / 255.0
img = (img[:, :, :3] * alpha + 255 * (1 - alpha)).astype(np.uint8)
cv2.imwrite("out.jpg", img, [cv2.IMWRITE_JPEG_QUALITY, 85])
Tips#
cv2.imreadcan fail on non-ASCII paths on Windows. Usecv2.imdecode(np.fromfile(path, np.uint8), cv2.IMREAD_UNCHANGED)instead.cv2.IMREAD_GRAYSCALEconverts to one channel on load.cv2.IMWRITE_PNG_BILEVELwrites 1-bit black and white PNG files.