Getting pixels in and out reliably is the first step of every vision script, and imread fails silently.
cv2.imread(path, flags) loads an image file into a NumPy array. The flag picks what you get:
cv2.IMREAD_COLOR(default): 3-channel BGR, any alpha droppedcv2.IMREAD_GRAYSCALE: single channelcv2.IMREAD_UNCHANGED: keep alpha and bit depth, e.g. 16-bit PNGs
The big gotcha: imread does not raise on a missing or unreadable file. It returns None, and the error only surfaces later as a confusing 'NoneType' object has no attribute 'shape'. Always check the result.
cv2.imwrite(path, img, params) picks the format from the file extension and returns True on success. Optional params control encoding, for example [cv2.IMWRITE_JPEG_QUALITY, 90] or [cv2.IMWRITE_PNG_COMPRESSION, 9].
To work in memory (web uploads, databases), use cv2.imencode('.png', img), which returns (ok, buffer), and cv2.imdecode(np_bytes, flags). This is also the workaround for file paths with non-ASCII characters on Windows.
For a quick look, cv2.imshow(window_name, img) opens a window, but nothing is drawn until you call cv2.waitKey(ms), which also pumps the GUI events; waitKey(0) waits for a key. Finish with cv2.destroyAllWindows(). In Jupyter or on headless servers (opencv-python-headless), there is no GUI: convert to RGB and show with matplotlib instead.
Example
import cv2
import numpy as np
img = np.full((60, 80, 3), (0, 128, 255), np.uint8) # orange in BGR
ok = cv2.imwrite("orange.png", img)
print(ok) # True
back = cv2.imread("orange.png") # BGR uint8
print(back.shape, back[0, 0]) # (60, 80, 3) [ 0 128 255]
gray = cv2.imread("orange.png", cv2.IMREAD_GRAYSCALE)
print(gray.shape) # (60, 80)
missing = cv2.imread("no_such_file.jpg")
print(missing is None) # True -- no exception!
ok, buf = cv2.imencode(".jpg", img, [cv2.IMWRITE_JPEG_QUALITY, 90])
print(ok, buf.dtype) # True uint8 (encoded bytes)
decoded = cv2.imdecode(buf, cv2.IMREAD_COLOR)
print(decoded.shape) # (60, 80, 3)Remember
imreadreturns None instead of raising: always check it- The flag chooses colour, grayscale or unchanged (alpha, 16-bit)
imwritepicks the format from the extension;imencode/imdecodework in memoryimshowneedswaitKeyto actually draw
Watch out for
- Calling
cv2.imshowwithoutcv2.waitKey, so the window never paints, or using it on a headless install.