OpenCV 实战指南

FreeGuideOnline 最新 2026-07-14

bash pip install opencv-python

如果需要完整的 OpenCV 以及扩展模块(如 SIFT 特征检测),可安装:
```bash
pip install opencv-contrib-python

2.3 验证安装

在 Python 环境中输入以下代码,若打印出版本号则安装成功。

import cv2
print(cv2.__version__)

3. 图像基础操作

3.1 读取、显示与保存图片

import cv2

# 读取图片
img = cv2.imread('photo.jpg')
# 显示图片
cv2.imshow('Window Name', img)
cv2.waitKey(0)  # 按任意键关闭
cv2.destroyAllWindows()
# 保存图片
cv2.imwrite('output.jpg', img)

OpenCV 默认读入的图片格式为 BGR,与常见的 RGB 顺序不同,需要留意。

3.2 图像属性与色彩空间转换

height, width, channels = img.shape
print(f"尺寸:{width}x{height},通道数:{channels}")

# BGR 转 灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# BGR 转 HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

3.3 图像缩放与裁剪

# 等比缩放
resized = cv2.resize(img, (300, 200))
# 裁剪 [y_start:y_end, x_start:x_end]
cropped = img[50:200, 100:300]

4. 图像处理核心技术

4.1 图像平滑与滤波

图像平滑用于去除噪声,常见方法:

  • 均值滤波cv2.blur(img, (5,5))
  • 高斯滤波cv2.GaussianBlur(img, (5,5), 0)
  • 中值滤波 (去除椒盐噪声效果佳):cv2.medianBlur(img, 5)

4.2 边缘检测

Canny 边缘检测是最常用的方法:

edges = cv2.Canny(img, threshold1=100, threshold2=200)

threshold1threshold2 控制边缘强度筛选。

4.3 形态学操作

用于二值图像的去噪、填补孔洞、分离物体等。

  • 腐蚀:缩小白色区域
  • 膨胀:扩大白色区域
  • 开运算:先腐蚀后膨胀,消除小物体
  • 闭运算:先膨胀后腐蚀,填充孔洞
kernel = np.ones((5,5), np.uint8)
eroded = cv2.erode(binary_img, kernel, iterations=1)
dilated = cv2.dilate(binary_img, kernel, iterations=1)
opening = cv2.morphologyEx(binary_img, cv2.MORPH_OPEN, kernel)
closing = cv2.morphologyEx(binary_img, cv2.MORPH_CLOSE, kernel)

5. 视频处理入门

5.1 读取摄像头视频流

cap = cv2.VideoCapture(0)  # 0表示默认摄像头
while True:
    ret, frame = cap.read()
    if not ret:
        break
    cv2.imshow('Live Video', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()

5.2 处理本地视频文件

只需将 VideoCapture(0) 改为视频文件路径即可:

cap = cv2.VideoCapture('video.mp4')

5.3 保存视频

使用 VideoWriter 指定编码器、帧率和尺寸:

fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))
while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
    out.write(frame)
out.release()

6. 特征检测与描述

6.1 ORB 特征提取

ORB(Oriented FAST and Rotated BRIEF)是一种快速且免费的特征检测算法,适合实时应用。

orb = cv2.ORB_create()
keypoints, descriptors = orb.detectAndCompute(img, None)
# 绘制关键点
img_kp = cv2.drawKeypoints(img, keypoints, None, color=(0,255,0))

6.2 模板匹配

在一幅图像中寻找模板图像的位置:

result = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
top_left = max_loc
h, w = template.shape[:2]
bottom_right = (top_left[0]+w, top_left[1]+h)
cv2.rectangle(img, top_left, bottom_right, 255, 2)

7. 实战项目:人脸检测

7.1 使用 Haar 级联分类器

OpenCV 提供预训练的 Haar 特征模型,可快速检测人脸。

face_cascade = cv2.CascadeClassifier(
    cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)
for (x,y,w,h) in faces:
    cv2.rectangle(frame, (x,y), (x+w,y+h), (0,255,0), 2)

7.2 完整摄像头实时检测代码

import cv2

face_cascade = cv2.CascadeClassifier(
    cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, 1.1, 5)
    for (x,y,w,h) in faces:
        cv2.rectangle(frame, (x,y), (x+w,y+h), (255,0,0), 2)
    cv2.imshow('Face Detection', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

8. 进阶实战:虚拟画笔

8.1 原理概述

通过颜色阈值提取特定颜色的物体(如蓝色笔盖),跟踪其重心位置,在画布上绘制轨迹。

8.2 关键步骤

  1. 将图像从 BGR 转为 HSV,设定蓝色的 HSV 阈值范围。
  2. 生成颜色掩膜,并进行形态学开运算去除噪点。
  3. 寻找轮廓,获取最大轮廓的中心点。
  4. 将连续的中心点连接成线条。
import cv2
import numpy as np

drawing_canvas = np.zeros((480,640,3), np.uint8)
cap = cv2.VideoCapture(0)

# 蓝色的 HSV 大致范围
lower_blue = np.array([110,50,50])
upper_blue = np.array([130,255,255])
pts = []

while True:
    ret, frame = cap.read()
    frame = cv2.flip(frame, 1)  # 水平翻转,便于操作
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv, lower_blue, upper_blue)
    # 开运算去噪
    kernel = np.ones((5,5), np.uint8)
    mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
    # 寻找轮廓
    contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    center = None
    if contours:
        cnt = max(contours, key=cv2.contourArea)
        ((x,y), radius) = cv2.minEnclosingCircle(cnt)
        moment = cv2.moments(cnt)
        center = (int(moment['m10']/moment['m00']), int(moment['m01']/moment['m00']))
        pts.append(center)
        # 绘制连续线条
        for i in range(1, len(pts)):
            cv2.line(drawing_canvas, pts[i-1], pts[i], (255,255,255), 2)
    # 合并显示
    frame = cv2.addWeighted(frame, 0.5, drawing_canvas, 0.5, 0)
    cv2.imshow('Virtual Painter', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()