OpenCV 入门实例

以下是 OpenCV 入门实例教程(中文),通过几个基础示例帮助你快速掌握 OpenCV 的核心功能,包括图像读取、显示、基本处理和简单应用。每个示例都包含完整代码、解释和输出结果,适合初学者快速上手。


一、基础图像操作

1.1 读取、显示和保存图像

目标:学习 OpenCV 的基本 I/O 操作。

import cv2
import numpy as np

# 读取图像
img = cv2.imread('lena.jpg')  # 替换为你的图像路径

# 检查是否成功加载
if img is None:
    print("错误:无法加载图像,请检查文件路径")
else:
    print(f"图像尺寸: {img.shape}")  # 输出 (height, width, channels)

    # 显示图像
    cv2.imshow('原始图像', img)
    key = cv2.waitKey(0)  # 等待按键
    if key == ord('s'):  # 按 's' 保存
        cv2.imwrite('output.jpg', img)
        print("图像已保存为 output.jpg")

    cv2.destroyAllWindows()  # 关闭所有窗口

输出示例

图像尺寸: (512, 512, 3)

说明

  • imread:读取图像为 BGR 格式的 NumPy 数组。
  • imshow:显示图像窗口。
  • waitKey(0):等待用户按键(0 表示无限等待)。
  • destroyAllWindows():关闭所有 OpenCV 窗口。

1.2 图像基本属性和操作

import cv2

img = cv2.imread('lena.jpg')

# 基本属性
print("图像形状:", img.shape)  # (高度, 宽度, 通道数)
print("数据类型:", img.dtype)  # uint8
print("像素总数:", img.size)   # 总像素数
print("图像类型:", img.ndim)   # 维度数

# 访问单个像素
px = img[100, 100]  # BGR 值
print("像素(100,100):", px)

# 修改像素
img[100, 100] = [0, 255, 0]  # 改为绿色

# ROI(感兴趣区域)
roi = img[100:200, 100:200]  # 裁剪 100x100 区域
cv2.imshow('ROI', roi)
cv2.waitKey(0)
cv2.destroyAllWindows()

二、颜色空间转换

2.1 BGR、RGB 和灰度转换

import cv2
import matplotlib.pyplot as plt

img_bgr = cv2.imread('lena.jpg')

# BGR -> 灰度
img_gray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY)

# BGR -> RGB (用于 matplotlib 显示)
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)

# 显示对比
cv2.imshow('BGR', img_bgr)
cv2.imshow('Gray', img_gray)
cv2.waitKey(0)

# 使用 matplotlib 显示 RGB
plt.figure(figsize=(15, 5))
plt.subplot(131), plt.imshow(img_bgr), plt.title('BGR'), plt.axis('off')
plt.subplot(132), plt.imshow(img_gray, cmap='gray'), plt.title('Gray'), plt.axis('off')
plt.subplot(133), plt.imshow(img_rgb), plt.title('RGB'), plt.axis('off')
plt.tight_layout()
plt.show()

cv2.destroyAllWindows()

说明

  • OpenCV 默认使用 BGR 格式,与 Matplotlib 的 RGB 相反。
  • cvtColor:颜色空间转换函数,支持多种格式。

三、图像几何变换

3.1 缩放、平移和旋转

import cv2
import numpy as np

img = cv2.imread('lena.jpg')

# 1. 缩放
height, width = img.shape[:2]
resized = cv2.resize(img, (int(width/2), int(height/2)), interpolation=cv2.INTER_CUBIC)

# 2. 平移
rows, cols = img.shape[:2]
M = np.float32([[1, 0, 50], [0, 1, 50]])  # x+50, y+50
translated = cv2.warpAffine(img, M, (cols, rows))

# 3. 旋转
center = (cols//2, rows//2)
angle = 45
scale = 1.0
rot_matrix = cv2.getRotationMatrix2D(center, angle, scale)
rotated = cv2.warpAffine(img, rot_matrix, (cols, rows))

# 显示结果
cv2.imshow('Original', img)
cv2.imshow('Resized', resized)
cv2.imshow('Translated', translated)
cv2.imshow('Rotated', rotated)
cv2.waitKey(0)
cv2.destroyAllWindows()

四、图像滤波和边缘检测

4.1 模糊滤波

import cv2

img = cv2.imread('lena.jpg')

# 1. 均值模糊
blur_avg = cv2.blur(img, (15, 15))

# 2. 高斯模糊
blur_gaussian = cv2.GaussianBlur(img, (15, 15), 0)

# 3. 中值模糊(对椒盐噪声有效)
blur_median = cv2.medianBlur(img, 15)

# 显示对比
cv2.imshow('Original', img)
cv2.imshow('Average Blur', blur_avg)
cv2.imshow('Gaussian Blur', blur_gaussian)
cv2.imshow('Median Blur', blur_median)
cv2.waitKey(0)
cv2.destroyAllWindows()

4.2 边缘检测

import cv2

img = cv2.imread('lena.jpg', cv2.IMREAD_GRAYSCALE)  # 直接读取灰度图

# 1. Canny 边缘检测
edges = cv2.Canny(img, 100, 200)

# 2. Sobel 边缘检测
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
sobel = np.sqrt(sobelx**2 + sobely**2).astype(np.uint8)

# 显示结果
cv2.imshow('Original', img)
cv2.imshow('Canny Edges', edges)
cv2.imshow('Sobel Edges', sobel)
cv2.waitKey(0)
cv2.destroyAllWindows()

五、阈值处理和轮廓检测

5.1 二值化阈值

import cv2
import numpy as np

# 读取灰度图像
img = cv2.imread('lena.jpg', cv2.IMREAD_GRAYSCALE)

# 1. 简单阈值
_, thresh_simple = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)

# 2. 自适应阈值
thresh_adaptive = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, 
                                       cv2.THRESH_BINARY, 11, 2)

# 显示结果
cv2.imshow('Original', img)
cv2.imshow('Simple Threshold', thresh_simple)
cv2.imshow('Adaptive Threshold', thresh_adaptive)
cv2.waitKey(0)
cv2.destroyAllWindows()

5.2 轮廓检测

import cv2

# 创建测试图像(包含简单形状)
img = np.zeros((512, 512, 3), dtype=np.uint8)
cv2.rectangle(img, (100, 100), (200, 200), (0, 255, 0), -1)
cv2.circle(img, (300, 300), 50, (255, 0, 0), -1)
cv2.ellipse(img, (400, 400), (30, 50), 30, 0, 360, (0, 0, 255), -1)

# 转换为灰度并二值化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

# 寻找轮廓
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 绘制轮廓
img_contours = img.copy()
cv2.drawContours(img_contours, contours, -1, (0, 255, 255), 2)

cv2.imshow('Contours', img_contours)
cv2.waitKey(0)
cv2.destroyAllWindows()

六、视频处理入门

6.1 视频文件处理

import cv2

# 打开视频文件
cap = cv2.VideoCapture('video.mp4')  # 替换为你的视频路径

# 检查是否成功打开
if not cap.isOpened():
    print("错误:无法打开视频文件")
    exit()

# 获取视频属性
fps = int(cap.get(cv2.CAP_PROP_FPS))
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
print(f"FPS: {fps}, 总帧数: {frame_count}")

frame_num = 0
while True:
    ret, frame = cap.read()
    if not ret:
        break

    frame_num += 1

    # 每隔 30 帧处理一次(降采样)
    if frame_num % 30 == 0:
        # 转换为灰度
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # 显示
        cv2.imshow('Video', gray)

        if cv2.waitKey(1) & 0xFF == ord('q'):  # 按 'q' 退出
            break

cap.release()
cv2.destroyAllWindows()

6.2 摄像头实时处理

import cv2

# 打开摄像头
cap = cv2.VideoCapture(0)  # 0 为默认摄像头

if not cap.isOpened():
    print("错误:无法打开摄像头")
    exit()

print("按 'q' 退出,按 's' 保存截图")

while True:
    ret, frame = cap.read()
    if not ret:
        break

    # 镜像翻转(模拟自拍效果)
    frame = cv2.flip(frame, 1)

    # 显示
    cv2.imshow('Camera', frame)

    key = cv2.waitKey(1) & 0xFF
    if key == ord('q'):
        break
    elif key == ord('s'):
        cv2.imwrite('screenshot.jpg', frame)
        print("截图已保存为 screenshot.jpg")

cap.release()
cv2.destroyAllWindows()

七、综合示例:简单图像处理流水线

import cv2
import numpy as np

def process_image(image_path):
    """图像处理流水线"""
    # 1. 读取图像
    img = cv2.imread(image_path)
    if img is None:
        print("错误:无法加载图像")
        return

    # 2. 转换为灰度
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 3. 高斯模糊
    blurred = cv2.GaussianBlur(gray, (5, 5), 0)

    # 4. Canny 边缘检测
    edges = cv2.Canny(blurred, 50, 150)

    # 5. 形态学操作(膨胀)
    kernel = np.ones((3, 3), np.uint8)
    dilated = cv2.dilate(edges, kernel, iterations=1)

    # 6. 轮廓检测
    contours, _ = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # 7. 在原图上绘制轮廓
    img_with_contours = img.copy()
    cv2.drawContours(img_with_contours, contours, -1, (0, 255, 0), 2)

    # 8. 显示结果
    cv2.imshow('Original', img)
    cv2.imshow('Gray', gray)
    cv2.imshow('Edges', edges)
    cv2.imshow('Contours', img_with_contours)

    # 保存结果
    cv2.imwrite('processed_edges.jpg', edges)
    cv2.imwrite('processed_contours.jpg', img_with_contours)

    cv2.waitKey(0)
    cv2.destroyAllWindows()

# 使用示例
process_image('lena.jpg')  # 替换为你的图像路径

八、注意事项

  1. 图像路径:确保文件路径正确,支持 JPG、PNG、BMP 等格式。
  2. 内存管理:及时释放视频捕获对象(cap.release())和关闭窗口。
  3. 性能优化:处理大图像时考虑降采样或使用 ROI。
  4. 颜色格式:OpenCV 使用 BGR,与 Matplotlib 的 RGB 不同。
  5. 错误处理:检查 imreadVideoCapture 的返回值。

九、资源

  • 官方文档:https://docs.opencv.org/master/
  • Python 教程:https://opencv-python-tutroals.readthedocs.io/
  • 示例代码:https://github.com/opencv/opencv/tree/master/samples/python

这些入门实例涵盖了 OpenCV 的核心功能。如果你需要更深入的示例(如人脸检测、特征匹配、实时视频处理)或针对特定任务的代码,请告诉我,我可以提供详细的解决方案!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注