OpenCV 是计算机视觉领域的标准工具和事实上的行业标杆,掌握它对你进入 CV 领域非常重要。
下面我将用一个思维导图为你概括 OpenCV 的主要学习路径,然后我们再深入各个部分的细节。
下面是各个部分你需要掌握的具体内容和代码示例。
🛠️ 1. 安装与环境配置
首先,你需要安装 OpenCV。对于 Python 用户,最便捷的方式是使用 pip
。推荐安装 opencv-contrib-python
,它包含了主模块和额外的贡献模块。
pip install opencv-contrib-python
安装完成后,可以通过以下代码验证是否成功:
import cv2
print("OpenCV 版本:", cv2.__version__) # 预期输出:4.x.x
📷 2. 图像读写与显示
图像处理的第一步是读取、显示和保存图像。OpenCV 使用 cv2.imread()
读取图像,返回一个 NumPy 数组。
import cv2
# 读取图像 (默认以 BGR 格式读取彩色图像)
img = cv2.imread('path/to/your/image.jpg') # 替换为你的图像路径
if img is None:
print("图像读取失败,请检查路径")
else:
# 显示图像
cv2.imshow('Demo Image', img)
cv2.waitKey(0) # 等待按键(0表示无限等待)
cv2.destroyAllWindows() # 关闭所有窗口
# 保存图像
cv2.imwrite('output.jpg', img)
注意:
cv2.imread()
读取失败会返回None
,务必检查。- OpenCV 默认读取彩色图像的通道顺序是 BGR(Blue, Green, Red),而不是常见的 RGB。
cv2.waitKey(0)
会等待直到有键按下,cv2.destroyAllWindows()
会关闭所有 OpenCV 创建的窗口。
🎨 3. 图像基本操作
3.1 获取图像信息
图像在 OpenCV 中以 NumPy 数组形式存储,你可以获取其形状、大小和数据类型。
if img is not None:
print("形状(高, 宽, 通道数):", img.shape) # 例如 (500, 800, 3)
print("像素总数:", img.size) # 高 * 宽 * 通道数
print("数据类型:", img.dtype) # 通常是 uint8 (0-255)
3.2 像素操作与 ROI (Region of Interest)
你可以直接访问和修改像素值,或操作图像的某个区域(ROI)。
# 访问 (100, 200) 处的像素值 (B, G, R)
px_value = img[100, 200]
print("像素值(B, G, R):", px_value)
# 修改该像素点为绿色 (B=0, G=255, R=0)
img[100, 200] = [0, 255, 0]
# 获取 ROI (例如从 (50,100) 开始,高100像素,宽200像素的区域)
roi = img[100:200, 50:250] # 高度范围在前,宽度范围在后
# 可以对 ROI 进行操作,例如将其变为红色
roi[:, :] = [0, 0, 255] # 注意是 BGR
3.3 绘图功能
OpenCV 提供了在图像上绘制几何图形和文字的函数,常用于标记检测结果。
# 绘制一个蓝色矩形框 (从点(50,50)到点(200,200)),线宽为2
cv2.rectangle(img, (50, 50), (200, 200), (255, 0, 0), 2)
# 绘制一个实心红色圆 (圆心(300,300),半径40)
cv2.circle(img, (300, 300), 40, (0, 0, 255), -1) # 线宽-1表示填充
# 添加文字 "Hello OpenCV"
cv2.putText(img, 'Hello OpenCV', (50, 300), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
cv2.imshow('Drawing', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
🔄 4. 图像处理基础
4.1 色彩空间转换
除了 BGR 和灰度图,OpenCV 还支持 HSV、Lab 等色彩空间,用于不同任务。
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转为灰度图
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 转为HSV空间,常用于颜色分割
lab_img = cv2.cvtColor(img, cv2.COLOR_BGR2LAB) # 转为Lab空间,对光照变化更鲁棒
cv2.imshow('Gray', gray_img)
cv2.imshow('HSV', hsv_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
4.2 图像几何变换
常见的几何变换包括缩放、旋转、平移等。
# 缩放至指定尺寸
resized = cv2.resize(img, (400, 300))
# 按比例缩放 (例如缩小一半)
scaled = cv2.resize(img, None, fx=0.5, fy=0.5)
# 旋转 (围绕图像中心旋转45度,缩放因子1.0)
(h, w) = img.shape[:2]
center = (w // 2, h // 2)
M = cv2.getRotationMatrix2D(center, 45, 1.0) # 获取旋转矩阵
rotated = cv2.warpAffine(img, M, (w, h)) # 执行仿射变换
cv2.imshow('Resized', resized)
cv2.imshow('Rotated', rotated)
cv2.waitKey(0)
cv2.destroyAllWindows()
4.3 图像滤波
滤波常用于去噪或模糊图像。
# 高斯模糊 (内核大小需为正奇数,sigmaX为X方向高斯核标准差)
gaussian_blur = cv2.GaussianBlur(img, (5, 5), 0)
# 中值滤波 (对椒盐噪声效果好,内核大小也为奇数)
median_blur = cv2.medianBlur(img, 5)
cv2.imshow('Original', img)
cv2.imshow('Gaussian Blur', gaussian_blur)
cv2.imshow('Median Blur', median_blur)
cv2.waitKey(0)
cv2.destroyAllWindows()
4.4 形态学操作
形态学操作主要针对二值图像,用于消除噪声、分割、提取边缘等。
# 通常先得到二值图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 定义结构元素(内核)
kernel = np.ones((5, 5), np.uint8)
# 腐蚀(消除细小边界)
erosion = cv2.erode(thresh, kernel, iterations=1)
# 膨胀(扩大边界)
dilation = cv2.dilate(thresh, kernel, iterations=1)
# 开运算(先腐蚀后膨胀,去除小物体)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
# 闭运算(先膨胀后腐蚀,填充小孔洞)
closing = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
cv2.imshow('Original Binary', thresh)
cv2.imshow('Opening', opening)
cv2.imshow('Closing', closing)
cv2.waitKey(0)
cv2.destroyAllWindows()
4.5 阈值分割
阈值处理将图像转换为二值图像,用于分割。
# 简单阈值
ret, thresh_binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 自适应阈值 (适用于光照不均的图像)
thresh_adaptive = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 11, 2)
cv2.imshow('Binary Threshold', thresh_binary)
cv2.imshow('Adaptive Threshold', thresh_adaptive)
cv2.waitKey(0)
cv2.destroyAllWindows()
🔍 5. 图像分析
5.1 边缘检测
Canny 边缘检测是常用算法。
# 通常先模糊降噪
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# Canny 边缘检测 (阈值1, 阈值2)
edges = cv2.Canny(blurred, 50, 150) # 低于阈值1为非边缘,高于阈值2为强边缘,中间为待定
cv2.imshow('Original', img)
cv2.imshow('Edges', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
5.2 特征检测
OpenCV 提供了多种特征检测方法,如 SIFT (尺度不变特征变换)。
# 创建 SIFT 检测器
sift = cv2.SIFT_create()
# 检测关键点并计算描述符
keypoints, descriptors = sift.detectAndCompute(gray, None)
# 在图像上绘制关键点
img_with_keypoints = cv2.drawKeypoints(img, keypoints, None, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imshow('SIFT Keypoints', img_with_keypoints)
cv2.waitKey(0)
cv2.destroyAllWindows()
📹 6. 视频处理
OpenCV 可以处理视频文件或摄像头实时流。
# 打开摄像头 (0 通常是默认摄像头)
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("无法打开摄像头")
exit()
while True:
# 逐帧捕获
ret, frame = cap.read()
if not ret:
print("无法获取帧")
break
# 在此处对帧进行处理 (例如转换为灰度图)
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 显示结果
cv2.imshow('Camera', gray_frame)
# 按 'q' 键退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放资源
cap.release()
cv2.destroyAllWindows()
👤 7. 实战:人脸检测
OpenCV 提供了预训练的 Haar 级联分类器,可用于人脸检测等任务。
# 加载预训练的人脸检测器
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
# 转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 检测人脸
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
# 在检测到的人脸周围绘制矩形
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
# 显示结果
cv2.imshow('Face Detection', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
detectMultiScale
参数含义:
scaleFactor
:图像缩放比例(>1),用于构建图像金字塔。minNeighbors
:候选矩形框附近需要有多少个邻居框才被保留,值越大检测越严格。minSize
:目标的最小尺寸。
🚀 下一步学习建议
- 扎实基础:熟练掌握上述基本操作是核心。
- 探索进阶功能:
- 轮廓检测:
cv2.findContours()
- 直方图处理
- 特征匹配
- OpenCV 的 DNN 模块:加载和运行深度学习模型(如来自 TensorFlow、PyTorch 的模型)。
- 轮廓检测:
- 做项目:选择感兴趣的小项目,如文档扫描仪、运动检测、简单的人脸识别系统、AR 标记检测等。
- 利用资源:
- 官方文档:https://docs.opencv.org/
- 教程和社区:CSDN、Stack Overflow、GitHub 上有大量代码和项目。
- 书籍:《Learning OpenCV》。
学习 OpenCV 最好的方式就是多动手实践。从简单的代码开始,不断尝试和修改,逐步构建更复杂的项目。祝你学习愉快!