mrkeyoor.com_
Wed 05 Aug 05:00 UTC
PyPIAI / MLupdated 05 Aug 2026

opencv-python

opencv-python packages the OpenCV C++ computer vision library as pre-built, CPU-only Python wheels, so pip install works without compiling anything. You import it as cv2, images are plain numpy arrays, and it covers image and video I/O, camera capture, resizing and color conversion, filtering, thresholding, contours, feature detection, Haar cascades, and the DNN module for running trained models. The current wheels track OpenCV 5.0 and support Python 3.7 through 3.14.

Verdict

The standard way to get OpenCV into Python, and the pre-built wheels save you a genuine CMake ordeal. Install the headless variant on servers, and reach for Pillow when you are only resizing thumbnails.

API stability4/5The cv2 API tracks upstream OpenCV, which moves slowly and deprecates carefully; findContours-era breaks are rare. The 5.0 major landed recently, so expect some churn at the edges while 4.x code migrates.
Docs3/5The README documents packaging, variants, and build options thoroughly, but the actual API docs at docs.opencv.org are C++-first with auto-generated Python signatures, and third-party tutorials span a decade of versions.
Maintenance4/5Wheels are rebuilt for each upstream OpenCV release and new Python versions, with pushes through July 2026. The repo is build scripts; library bugs must be fixed upstream in opencv/opencv.
Ecosystem5/5About 13.5 million weekly downloads and the assumed baseline of most Python computer vision tutorials, courses, and downstream packages.

Use it if

  • You do classic computer vision work: contours, homography, template matching, filtering, or camera and video frame processing
  • You preprocess images or video frames for ML models and need fast CPU operations backed by optimized C++
  • You want face or object detection with bundled Haar cascade files (cv2.data.haarcascades) or DNN-module inference without installing a deep learning framework
Skip it if

Setup reality

pip install opencv-python just works on mainstream platforms because wheels exist for everything current. The traps: there are four package variants (main, contrib, headless, contrib-headless) that all install the same cv2 namespace, and installing more than one silently corrupts your environment, so pick exactly one. pip older than 19.3 cannot use the manylinux2014 wheels and falls back to a source build that fails or takes hours. On Windows you may need the Visual C++ redistributable, and N editions need the Media Feature Pack. cv2.imshow does nothing in headless installs, and everyone gets bitten once by BGR channel order.

Patterns

Read and write an imageread-write-image

import cv2

img = cv2.imread('photo.jpg')  # BGR numpy array
if img is None:
    raise FileNotFoundError('photo.jpg missing or unreadable')

cv2.imwrite('out.png', img)

imread returns None instead of raising on a bad path or unsupported format; always check before using the array.

Convert BGR to RGB for other librariesbgr-to-rgb

import cv2

img = cv2.imread('photo.jpg')
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# now safe for matplotlib, PIL, or ML frameworks
import matplotlib.pyplot as plt
plt.imshow(rgb)

OpenCV loads images as BGR; feeding them to RGB-expecting code produces blue-tinted output, the most common cv2 bug.

Resize an imageresize-image

import cv2

img = cv2.imread('photo.jpg')
small = cv2.resize(img, (640, 360), interpolation=cv2.INTER_AREA)
double = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)

The size tuple is (width, height) while numpy shape is (height, width); INTER_AREA shrinks best, INTER_CUBIC enlarges best.

Read frames from a camera or video filevideo-capture

import cv2

cap = cv2.VideoCapture(0)  # or 'clip.mp4'
while True:
    ret, frame = cap.read()
    if not ret:
        break
    cv2.imshow('frame', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()

imshow needs the GUI build; on headless installs it raises an error, so process frames without display there.

Write frames to a video filewrite-video

import cv2

fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('out.mp4', fourcc, 30.0, (1280, 720))

for frame in frames:
    out.write(frame)  # frames must match (1280, 720), BGR
out.release()

If the frame size does not match the size passed to VideoWriter, frames are dropped silently and the file plays empty.

Draw boxes and labels on an imagedraw-annotations

import cv2

cv2.rectangle(img, (50, 50), (220, 180), (0, 255, 0), 2)
cv2.putText(img, 'cat 0.97', (50, 40),
            cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)

Drawing functions modify the array in place; call img.copy() first if you need the original.

Threshold a grayscale imagethreshold-image

import cv2

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

adaptive = cv2.adaptiveThreshold(
    gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
    cv2.THRESH_BINARY, 11, 2)

Otsu picks the global threshold for you; use adaptive thresholding when lighting varies across the image.

Find and draw contoursfind-contours

import cv2

contours, hierarchy = cv2.findContours(
    binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

big = [c for c in contours if cv2.contourArea(c) > 500]
cv2.drawContours(img, big, -1, (0, 0, 255), 2)

findContours expects a binary image (threshold or Canny output first) and finds white objects on a black background.

Detect faces with a bundled Haar cascadeface-detect-haar

import cv2

cascade = cv2.CascadeClassifier(
    cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)
for (x, y, w, h) in faces:
    cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

All package variants ship the cascade XML files; cv2.data.haarcascades is the path shortcut. Expect false positives versus DNN detectors.

Blur an image and detect edgesblur-and-edges

import cv2

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edges = cv2.Canny(blurred, 50, 150)

Blur before Canny or sensor noise becomes edges; kernel sizes must be odd numbers.

Alternatives

PackageRegistryPick it when
pillowPyPIYou just need to open, resize, convert, and save images without CV machinery
scikit-imagePyPIYou prefer algorithm-focused image processing with an idiomatic numpy/scipy API
opencv-python-headlessPyPISame library for servers and Docker, minus the GUI dependency chain