OpenCV 图像处理基础

OpenCV 图像处理基础 教程(中文)重点讲解 OpenCV 中用于图像处理的核心功能,主要基于 imgproc 模块,涵盖颜色空间转换、滤波、阈值处理、边缘检测、几何变换等基础操作。教程包括详细解释、Python 代码示例和注意事项,适合初学者快速上手。本教程假设你已安装 OpenCV(opencv-python),并以简洁清晰的方式呈现。


一、图像处理基础概念

  • 图像表示:在 OpenCV 中,图像是 NumPy 数组,形状为 (height, width, channels),默认使用 BGR 颜色格式(与 RGB 相反)。
  • imgproc 模块:提供图像处理的核心函数,包括滤波、变换、边缘检测等。
  • 关键操作
  • 颜色空间转换:BGR ↔ 灰度、RGB、HSV。
  • 图像平滑:去除噪声(如高斯模糊)。
  • 阈值处理:图像分割(如二值化)。
  • 边缘检测:提取图像边缘(如 Canny)。
  • 几何变换:缩放、平移、旋转、透视变换。
  • 轮廓处理:查找和绘制轮廓。

二、核心图像处理功能与代码示例

以下按功能分类,逐一讲解并提供 Python 示例。

2.1 颜色空间转换

颜色空间转换用于改变图像的表示方式,例如从 BGR 转换为灰度或 HSV。

示例:BGR、灰度和 HSV 转换

import cv2
import numpy as np

# 读取图像
img = cv2.imread('lena.jpg')  # 替换为你的图像路径
if img is None:
    print("错误:无法加载图像")
    exit()

# BGR -> 灰度
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# BGR -> HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# BGR -> RGB(用于 Matplotlib)
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 显示结果
cv2.imshow('原始图像 (BGR)', img)
cv2.imshow('灰度', gray)
cv2.imshow('HSV', hsv)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 保存结果
cv2.imwrite('gray.jpg', gray)
cv2.imwrite('hsv.jpg', hsv)

说明

  • cv2.cvtColor:转换颜色空间,常用标志包括 COLOR_BGR2GRAYCOLOR_BGR2HSVCOLOR_BGR2RGB
  • 灰度图像是单通道,HSV 适合颜色分析。

2.2 图像平滑(滤波)

图像平滑用于去除噪声,常见方法包括均值模糊、高斯模糊和中值模糊。

示例:比较不同模糊方法

import cv2

img = cv2.imread('lena.jpg')
if img is None:
    print("错误:无法加载图像")
    exit()

# 均值模糊
blur_avg = cv2.blur(img, (5, 5))  # 核大小 5x5

# 高斯模糊
blur_gaussian = cv2.GaussianBlur(img, (5, 5), sigmaX=0)

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

# 显示结果
cv2.imshow('原始图像', img)
cv2.imshow('均值模糊', blur_avg)
cv2.imshow('高斯模糊', blur_gaussian)
cv2.imshow('中值模糊', blur_median)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 保存结果
cv2.imwrite('blur_avg.jpg', blur_avg)
cv2.imwrite('blur_gaussian.jpg', blur_gaussian)
cv2.imwrite('blur_median.jpg', blur_median)

说明

  • blur:简单均值滤波,适合轻微噪声。
  • GaussianBlur:基于高斯分布,保留边缘信息。
  • medianBlur:对椒盐噪声效果更好。

2.3 阈值处理

阈值处理用于图像分割,将像素值转换为二值或其他形式。

示例:简单阈值与自适应阈值

import cv2

# 读取灰度图像
img = cv2.imread('lena.jpg', cv2.IMREAD_GRAYSCALE)
if img is None:
    print("错误:无法加载图像")
    exit()

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

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

# 显示结果
cv2.imshow('原始灰度图像', img)
cv2.imshow('简单阈值', thresh_simple)
cv2.imshow('自适应阈值', thresh_adaptive)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 保存结果
cv2.imwrite('thresh_simple.jpg', thresh_simple)
cv2.imwrite('thresh_adaptive.jpg', thresh_adaptive)

说明

  • threshold:全局阈值,适合对比度高的图像。
  • adaptiveThreshold:基于局部像素值,适合光照不均的图像。

2.4 边缘检测

边缘检测用于提取图像中的边缘信息,常用算法包括 Canny 和 Sobel。

示例:Canny 边缘检测

import cv2
import numpy as np

img = cv2.imread('lena.jpg', cv2.IMREAD_GRAYSCALE)
if img is None:
    print("错误:无法加载图像")
    exit()

# 高斯模糊(减少噪声)
blurred = cv2.GaussianBlur(img, (5, 5), 0)

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

# 显示结果
cv2.imshow('原始灰度图像', img)
cv2.imshow('Canny 边缘', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()

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

说明

  • Canny:高效的边缘检测算法,需调整低阈值和高阈值(50 和 150)。
  • 高斯模糊预处理可减少噪声干扰。

2.5 几何变换

几何变换包括缩放、平移、旋转等,用于调整图像大小或位置。

示例:缩放、平移和旋转

import cv2
import numpy as np

img = cv2.imread('lena.jpg')
if img is None:
    print("错误:无法加载图像")
    exit()

# 缩放
height, width = img.shape[:2]
resized = cv2.resize(img, (int(width*0.5), int(height*0.5)), interpolation=cv2.INTER_LINEAR)

# 平移
M = np.float32([[1, 0, 50], [0, 1, 50]])  # x+50, y+50
translated = cv2.warpAffine(img, M, (width, height))

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

# 显示结果
cv2.imshow('原始图像', img)
cv2.imshow('缩放', resized)
cv2.imshow('平移', translated)
cv2.imshow('旋转', rotated)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 保存结果
cv2.imwrite('resized.jpg', resized)
cv2.imwrite('translated.jpg', translated)
cv2.imwrite('rotated.jpg', rotated)

说明

  • resize:调整图像大小,INTER_LINEAR 是常用插值方法。
  • warpAffine:通过变换矩阵实现平移和旋转。

2.6 轮廓检测

轮廓检测用于提取图像中的对象边界,常用于分割和形状分析。

示例:查找和绘制轮廓

import cv2
import numpy as np

# 读取图像并转换为灰度
img = cv2.imread('lena.jpg', cv2.IMREAD_GRAYSCALE)
if img is None:
    print("错误:无法加载图像")
    exit()

# 二值化
_, thresh = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)

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

# 在原图上绘制轮廓
img_color = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)  # 转换为彩色以绘制
cv2.drawContours(img_color, contours, -1, (0, 255, 0), 2)

# 显示结果
cv2.imshow('原始灰度图像', img)
cv2.imshow('轮廓', img_color)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 保存结果
cv2.imwrite('contours.jpg', img_color)

说明

  • findContours:返回轮廓列表,需二值图像作为输入。
  • drawContours:绘制轮廓,-1 表示绘制所有轮廓。

三、综合示例:图像处理流水线

以下是一个综合示例,结合多种图像处理技术:

import cv2
import numpy as np

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

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

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

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

    # 二值化
    _, thresh = cv2.threshold(blurred, 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, 0), 2)

    # 显示结果
    cv2.imshow('原始图像', img)
    cv2.imshow('灰度', gray)
    cv2.imshow('边缘', edges)
    cv2.imshow('轮廓', img_contours)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

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

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

四、注意事项

  1. 颜色格式
  • OpenCV 使用 BGR 格式,需转换为 RGB(用于 Matplotlib)或灰度。
  1. 参数调整
  • 模糊核大小(如 (5, 5))和边缘检测阈值需根据图像调整。
  1. 内存管理
  • 及时关闭窗口(cv2.destroyAllWindows())。
  • 处理大图像时考虑降采样以节省内存。
  1. 错误处理
  • 检查 imread 返回值,防止图像加载失败。
  • 确保输入图像格式正确(如 JPG、PNG)。
  1. 性能优化
  • 使用 NumPy 操作加速处理。
  • 对于复杂处理,考虑 ROI(感兴趣区域)减少计算量。

五、资源

  • 官方文档:https://docs.opencv.org/master/d7/dff/tutorial_how_to_use_OpenCV.html
  • imgproc 模块:https://docs.opencv.org/master/d7/d1d/tutorial_how_to_use_IPP.html
  • 社区:在 X 平台搜索 #opencv 获取最新讨论。

如果你需要更深入的图像处理示例(如形态学操作、图像分割)或 C++ 代码实现,请告诉我,我可以提供详细的代码或针对特定任务的优化方案!

类似文章

发表回复

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