OpenCV 图像操作入门:从零开始玩转计算机视觉

OpenCV 图像操作入门:从零开始玩转计算机视觉

用 Python + OpenCV,10 个核心操作带你打开计算机视觉的大门 🎨


前言

OpenCV(Open Source Computer Vision Library)是计算机视觉领域最流行的开源库,支持 Python、C++、Java 等多种语言。无论是图像处理、人脸识别、目标检测,还是视频分析,OpenCV 都是绕不开的利器。

本文以 Python + OpenCV 为例,通过 10 个常用操作示例,带你快速上手图像处理的核心技能。


环境准备

安装依赖

bash 复制代码
pip install opencv-python numpy matplotlib

说明

  • opencv-python:OpenCV 核心库
  • numpy:图像本质上是数组,numpy 是基础
  • matplotlib:用于在 Jupyter/脚本中可视化展示图像

验证安装

python 复制代码
import cv2
import numpy as np
print(f"OpenCV 版本:{cv2.__version__}")

输出类似 OpenCV 版本:4.9.0 即表示安装成功。


基础概念

在正式操作之前,有两个概念必须先搞清楚:

图像在 OpenCV 中的本质

在 OpenCV 里,一张图像就是一个 NumPy 多维数组

  • 灰度图 :形状为 (height, width),每个像素值范围 0~255
  • 彩色图 :形状为 (height, width, 3),三个通道分别是 B(蓝)、G(绿)、R(红)

⚠️ 注意:OpenCV 的通道顺序是 BGR,而不是我们常见的 RGB,这是一个高频踩坑点!

坐标系

OpenCV 的坐标原点在左上角,x 轴向右,y 轴向下。


操作一:读取、显示与保存图像

这是最基础的三板斧。

python 复制代码
import cv2

# 读取图像(默认彩色模式)
img = cv2.imread("example.jpg")

# 读取为灰度图
img_gray = cv2.imread("example.jpg", cv2.IMREAD_GRAYSCALE)

# 显示图像(弹出窗口)
cv2.imshow("原图", img)
cv2.imshow("灰度图", img_gray)

# 等待按键后关闭窗口
cv2.waitKey(0)
cv2.destroyAllWindows()

# 保存图像
cv2.imwrite("output.jpg", img_gray)
print("保存成功!")

常用读取模式:

参数 说明
cv2.IMREAD_COLOR 彩色模式(默认)
cv2.IMREAD_GRAYSCALE 灰度模式
cv2.IMREAD_UNCHANGED 原始模式(含 Alpha 通道)

操作二:图像基本属性

python 复制代码
import cv2

img = cv2.imread("example.jpg")

# 图像形状:(高度, 宽度, 通道数)
print(f"形状:{img.shape}")        # 例:(480, 640, 3)

# 像素总数
print(f"像素总数:{img.size}")     # 例:921600

# 数据类型
print(f"数据类型:{img.dtype}")    # uint8

# 获取单个像素的 BGR 值
pixel = img[100, 200]
print(f"坐标(100,200)的像素:B={pixel[0]}, G={pixel[1]}, R={pixel[2]}")

# 修改单个像素
img[100, 200] = [255, 0, 0]  # 改为纯蓝色

操作三:颜色空间转换

python 复制代码
import cv2

img = cv2.imread("example.jpg")

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

# BGR → RGB(用于 matplotlib 显示)
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# BGR → HSV(色相-饱和度-亮度,常用于颜色检测)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# 用 matplotlib 正确显示彩色图
import matplotlib.pyplot as plt

plt.figure(figsize=(12, 4))
plt.subplot(1, 3, 1); plt.imshow(rgb);  plt.title("RGB 原图");   plt.axis("off")
plt.subplot(1, 3, 2); plt.imshow(gray, cmap="gray"); plt.title("灰度图"); plt.axis("off")
plt.subplot(1, 3, 3); plt.imshow(hsv);  plt.title("HSV 图");     plt.axis("off")
plt.tight_layout()
plt.show()

💡 小技巧:用 matplotlib 显示 OpenCV 图像时,记得先把 BGR 转成 RGB,否则颜色会"蓝红反转"。


操作四:图像缩放与裁剪

python 复制代码
import cv2

img = cv2.imread("example.jpg")
h, w = img.shape[:2]
print(f"原始尺寸:{w} x {h}")

# --- 缩放 ---
# 指定目标尺寸
resized = cv2.resize(img, (320, 240))

# 按比例缩放(缩小到 50%)
half = cv2.resize(img, (0, 0), fx=0.5, fy=0.5)

# 放大 1.5 倍,使用双三次插值(质量更好)
enlarged = cv2.resize(img, (0, 0), fx=1.5, fy=1.5, interpolation=cv2.INTER_CUBIC)

# --- 裁剪(ROI:感兴趣区域)---
# 语法:img[y_start:y_end, x_start:x_end]
roi = img[50:200, 100:300]   # 裁剪 y:50~200, x:100~300 的区域

cv2.imshow("缩放后", resized)
cv2.imshow("裁剪区域", roi)
cv2.waitKey(0)
cv2.destroyAllWindows()

插值方法对比:

插值方法 适用场景
cv2.INTER_NEAREST 速度最快,质量最差
cv2.INTER_LINEAR 默认,双线性,速度与质量均衡
cv2.INTER_CUBIC 双三次,放大时质量好
cv2.INTER_AREA 缩小时效果最佳

操作五:图像翻转与旋转

python 复制代码
import cv2

img = cv2.imread("example.jpg")

# 翻转
flip_h = cv2.flip(img, 1)   # 水平翻转(左右镜像)
flip_v = cv2.flip(img, 0)   # 垂直翻转(上下翻转)
flip_b = cv2.flip(img, -1)  # 同时水平 + 垂直翻转

# 旋转(以图像中心为轴,旋转 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("水平翻转", flip_h)
cv2.imshow("旋转45度", rotated)
cv2.waitKey(0)
cv2.destroyAllWindows()

操作六:绘制图形与文字

OpenCV 提供了丰富的绘图函数,常用于标注检测结果。

python 复制代码
import cv2
import numpy as np

# 创建一块黑色画布(500x500,3通道)
canvas = np.zeros((500, 500, 3), dtype=np.uint8)

# 画直线:起点、终点、颜色(BGR)、线宽
cv2.line(canvas, (50, 50), (450, 50), (0, 255, 0), 2)

# 画矩形:左上角、右下角、颜色、线宽(-1 表示填充)
cv2.rectangle(canvas, (100, 100), (300, 250), (0, 0, 255), 3)

# 画圆:圆心、半径、颜色、线宽
cv2.circle(canvas, (400, 350), 80, (255, 0, 0), -1)   # 填充蓝色圆

# 画多边形
pts = np.array([[250, 300], [350, 400], [150, 400]], dtype=np.int32)
cv2.polylines(canvas, [pts], isClosed=True, color=(0, 255, 255), thickness=2)

# 写文字:文本、位置、字体、字号、颜色、线宽
cv2.putText(
    canvas, "Hello OpenCV!",
    (80, 470),
    cv2.FONT_HERSHEY_SIMPLEX,
    1.2,
    (255, 255, 255),
    2
)

cv2.imshow("绘图示例", canvas)
cv2.waitKey(0)
cv2.destroyAllWindows()

操作七:图像滤波(模糊与锐化)

滤波是图像预处理的核心步骤,用于去噪或增强细节。

python 复制代码
import cv2

img = cv2.imread("example.jpg")

# 均值模糊:内核越大越模糊
blur_avg = cv2.blur(img, (5, 5))

# 高斯模糊:更自然的模糊效果(常用于降噪)
blur_gauss = cv2.GaussianBlur(img, (5, 5), 0)

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

# 双边滤波:保留边缘的同时去噪(效果好但速度慢)
blur_bilateral = cv2.bilateralFilter(img, 9, 75, 75)

# 锐化(使用自定义卷积核)
import numpy as np
kernel_sharpen = np.array([
    [ 0, -1,  0],
    [-1,  5, -1],
    [ 0, -1,  0]
])
sharpened = cv2.filter2D(img, -1, kernel_sharpen)

cv2.imshow("原图", img)
cv2.imshow("高斯模糊", blur_gauss)
cv2.imshow("锐化", sharpened)
cv2.waitKey(0)
cv2.destroyAllWindows()

操作八:边缘检测

边缘检测是目标识别的重要前处理步骤。

python 复制代码
import cv2

img = cv2.imread("example.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Canny 边缘检测(最常用)
# 参数:输入图、低阈值、高阈值
edges_canny = cv2.Canny(gray, 50, 150)

# Sobel 算子(分别检测 X、Y 方向边缘)
sobel_x = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)
sobel = cv2.magnitude(sobel_x, sobel_y)
sobel = cv2.convertScaleAbs(sobel)

# Laplacian 算子
laplacian = cv2.Laplacian(gray, cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)

cv2.imshow("原图(灰度)", gray)
cv2.imshow("Canny 边缘", edges_canny)
cv2.imshow("Sobel 边缘", sobel)
cv2.imshow("Laplacian 边缘", laplacian)
cv2.waitKey(0)
cv2.destroyAllWindows()

💡 Canny 参数调优建议:低阈值 = 高阈值 × 1/3,高阈值从 100~200 开始尝试。


操作九:阈值分割与轮廓检测

python 复制代码
import cv2
import numpy as np

img = cv2.imread("example.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 全局阈值(大于127的像素变白,其余变黑)
_, thresh_global = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

# 自适应阈值(对光照不均的图像效果更好)
thresh_adaptive = cv2.adaptiveThreshold(
    gray, 255,
    cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
    cv2.THRESH_BINARY, 11, 2
)

# Otsu 自动阈值(自动确定最佳阈值)
_, thresh_otsu = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

# --- 轮廓检测 ---
contours, hierarchy = cv2.findContours(
    thresh_otsu,
    cv2.RETR_EXTERNAL,     # 只检测外轮廓
    cv2.CHAIN_APPROX_SIMPLE
)

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

print(f"共检测到 {len(contours)} 个轮廓")

cv2.imshow("Otsu 阈值", thresh_otsu)
cv2.imshow("轮廓检测", img_contours)
cv2.waitKey(0)
cv2.destroyAllWindows()

操作十:综合实战------提取图像中的红色区域

将前面学到的知识组合起来,做一个实用的颜色检测小程序。

python 复制代码
import cv2
import numpy as np

def detect_red_region(image_path):
    """检测图像中的红色区域并标注"""

    # 1. 读取图像并转换到 HSV 空间
    img = cv2.imread(image_path)
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

    # 2. 定义红色的 HSV 范围(红色在 HSV 中分两段)
    lower_red1 = np.array([0,   120, 70])
    upper_red1 = np.array([10,  255, 255])
    lower_red2 = np.array([170, 120, 70])
    upper_red2 = np.array([180, 255, 255])

    # 3. 创建掩码
    mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
    mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
    mask = cv2.bitwise_or(mask1, mask2)

    # 4. 形态学处理(去除噪点)
    kernel = np.ones((5, 5), np.uint8)
    mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN,  kernel)  # 开运算去小噪点
    mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)  # 闭运算填补空洞

    # 5. 找轮廓并绘制边界框
    contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    result = img.copy()

    for cnt in contours:
        area = cv2.contourArea(cnt)
        if area > 500:  # 过滤掉太小的区域
            x, y, w, h = cv2.boundingRect(cnt)
            cv2.rectangle(result, (x, y), (x + w, y + h), (0, 255, 0), 2)
            cv2.putText(result, f"Red Area: {area:.0f}px",
                        (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)

    # 6. 显示结果
    cv2.imshow("原图", img)
    cv2.imshow("红色掩码", mask)
    cv2.imshow("检测结果", result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    return len([c for c in contours if cv2.contourArea(c) > 500])


# 调用
count = detect_red_region("example.jpg")
print(f"共检测到 {count} 个红色区域")

常用速查表

颜色转换

python 复制代码
cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)   # 彩色 → 灰度
cv2.cvtColor(img, cv2.COLOR_BGR2RGB)    # BGR → RGB
cv2.cvtColor(img, cv2.COLOR_BGR2HSV)    # BGR → HSV
cv2.cvtColor(img, cv2.COLOR_BGR2LAB)    # BGR → LAB

几何变换

python 复制代码
cv2.resize(img, (w, h))                          # 缩放
cv2.flip(img, 1)                                 # 翻转
cv2.warpAffine(img, M, (w, h))                   # 仿射变换
cv2.warpPerspective(img, M, (w, h))              # 透视变换

滤波

python 复制代码
cv2.GaussianBlur(img, (5, 5), 0)                 # 高斯模糊
cv2.medianBlur(img, 5)                           # 中值模糊
cv2.Canny(gray, 50, 150)                         # 边缘检测
cv2.filter2D(img, -1, kernel)                    # 自定义卷积

形态学操作

python 复制代码
cv2.erode(img, kernel)                           # 腐蚀
cv2.dilate(img, kernel)                          # 膨胀
cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)    # 开运算
cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)   # 闭运算

常见踩坑汇总

问题 原因 解决方法
图像颜色异常(蓝红互换) OpenCV 使用 BGR,matplotlib 使用 RGB 显示前转换:cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
imread 返回 None 文件路径错误或文件不存在 检查路径,避免中文路径,用 os.path.exists() 验证
旋转后图像被裁剪 warpAffine 输出尺寸不够 计算旋转后的新尺寸并传入
轮廓检测结果异常 输入图像不是二值图 先进行阈值处理再检测轮廓
imshow 窗口一闪而过 没有 waitKey 加上 cv2.waitKey(0)

小结

本文覆盖了 OpenCV 图像操作的 10 个核心知识点:

  1. 📂 读取、显示、保存------三板斧
  2. 📐 基本属性------shape、dtype、像素访问
  3. 🎨 颜色空间转换------BGR/RGB/HSV/灰度
  4. ✂️ 缩放与裁剪------resize、ROI
  5. 🔄 翻转与旋转------flip、warpAffine
  6. ✏️ 绘图与标注------line、rectangle、putText
  7. 🌫️ 滤波------模糊与锐化
  8. 🔍 边缘检测------Canny、Sobel
  9. 🎯 阈值与轮廓------threshold、findContours
  10. 🛠️ 综合实战------颜色区域检测

掌握这些基础操作后,你就可以进一步探索人脸检测、目标识别、OCR 文字识别等更高级的计算机视觉应用了。


延伸阅读


本文示例基于 OpenCV 4.x + Python 3.8+,最后更新:2026 年 3 月

相关推荐
前进的李工1 小时前
LangChain使用之Model IO(提示词模版之PromptTemplate)
开发语言·人工智能·python·langchain
Techblog of HaoWANG1 小时前
目标检测与跟踪(9)-- Jetson Xavier NX GPIO控制3D结构光C与Python双版本实现(中)
c语言·人工智能·目标检测
掘金一周1 小时前
吃龙虾🦞咯!万字拆解OpenClaw的架构与设计 | 掘金一周 3.19
前端·人工智能·后端
段小二2 小时前
Chat Memory 实战:让 LLM 记住多轮对话(Java 架构师的 AI 工程笔记 05)
人工智能
东离与糖宝2 小时前
Java 21 虚拟线程与 AI 推理结合的最新实践
java·人工智能
火山引擎开发者社区2 小时前
火山养“龙虾”日志 | 14 大神仙玩法,原来 AI Agent 还能这么用
人工智能
新缸中之脑2 小时前
Hermes-Agent 简明指南
人工智能
鲸鱼在dn2 小时前
【CS336】Lecture1课程讲义-语言模型发展历程&Tokenization概念
人工智能·语言模型·自然语言处理
WiSirius2 小时前
LLM:基于 AgentScope + Streamlit 的 AI Agent脑暴室
人工智能·深度学习·自然语言处理·大模型·llama