一、核心知识点详解

1. 图像的XY坐标体系

OpenCV中图像的坐标原点在左上角,这是和数学坐标系(原点在左下角)最核心的区别:

  • 图像的尺寸表示为 (H, W)(高度Height,宽度Width),其中:
    • W 对应X轴(水平方向),取值范围 0 ~ W-1
    • H 对应Y轴(垂直方向),取值范围 0 ~ H-1
    • 例如坐标点 (10, 20) 表示:X=10(横向第11个像素)、Y=20(纵向第21个像素),对应图像的高为20、宽为10的位置(注意:图像shape返回的是 (H, W, C),C为通道数)。

代码示例

import cv2
import numpy as np

# 创建一个高20、宽10的黑色灰度图(单通道)
img = np.zeros((20, 10), dtype=np.uint8)
print("图像shape (H, W):", img.shape)  # 输出 (20, 10)

# 修改坐标(10, 20)?注意:X最大为9,Y最大为19,这里纠正为合法坐标(9, 19)
img[19, 9] = 255  # Y=19, X=9 处设为白色
print("坐标(9,19)的像素值:", img[19, 9])  # 输出 255

2. 像素值与灰度图

每个坐标点的像素值是图像的核心数据,核心规则:

  • 单通道(灰度图):像素值范围 0 ~ 255,0=纯黑(光强最弱),255=纯白(光强最强);
  • 像素平均值的意义:若整幅图像的像素平均值 < 100,说明图像整体过暗;若 > 230,说明整体过亮,均需调整相机参数或拍摄环境。

代码示例

import cv2

# 读取灰度图
img_gray = cv2.imread("test.jpg", cv2.IMREAD_GRAYSCALE)
# 计算平均值
mean_val = cv2.mean(img_gray)[0]  # mean返回 (均值, 0, 0, 0),取第一个值
print(f"图像平均值: {mean_val:.2f}")

# 判断是否过暗/过亮
if mean_val < 100:
    print("图像过暗,建议调整拍摄参数")
elif mean_val > 230:
    print("图像过亮,建议调整拍摄参数")
else:
    print("图像亮度正常")

3. 色彩空间

图像的色彩空间是像素值的“组织方式”,不同空间适用于不同场景:

色彩空间 通道组成 关键说明
BGR 蓝、绿、红 OpenCV默认读图格式(和常规RGB相反,需注意)
RGB 红、绿、蓝 PIL/Python Imaging Library的默认格式
Gray 灰度值 单通道,由BGR转换而来(公式:Gray = 0.299R + 0.587G + 0.114B)
HSV 色相(H)、饱和度(S)、明度(V) 分离色彩与亮度,适合颜色分割(如抠图)

HSV空间补充:

  • H(色相):范围 [0, 180),对应实际0~360°(OpenCV压缩了一倍),例如:红色H≈0~10⁄170~180,绿色H≈40~70,蓝色H≈100~130;
  • S(饱和度):范围 [0, 255),0=无色彩(灰度),255=纯色彩(无白色混入);
  • V(明度):范围 [0, 255),0=纯黑(无亮度),255=最亮(不影响色相/饱和度)。

代码示例(色彩空间转换)

import cv2

# 读取图像(默认BGR)
img_bgr = cv2.imread("test.jpg")

# BGR转RGB(适配PIL)
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)

# BGR转灰度图
img_gray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY)

# BGR转HSV
img_hsv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV)

# 查看HSV某点的像素值
h, s, v = img_hsv[100, 100]  # Y=100, X=100处的HSV值
print(f"H: {h}, S: {s}, V: {v}")

4. 图像梯度

图像的梯度是两个相邻坐标点的像素值变化量

(1)核心定义

图像梯度本质是像素值在空间维度上的变化率(导数),反映像素值的“变化快慢”:

  • 基础梯度:相邻像素的差值(如横向梯度=右侧像素-左侧像素,纵向梯度=下侧像素-上侧像素);
  • 梯度幅值:梯度的“大小”,代表像素值的变化程度(幅值越大,变化越剧烈);
  • 梯度方向:像素值变化最大的方向(而非简单的横向/纵向)。

(2)梯度与图像视觉效果的关联

  • 梯度小:像素值变化微弱(如纯色区域、模糊背景),图像视觉上“平滑/模糊”,此时图像的标准差小(像素值集中在均值附近,离散程度低);
  • 梯度大:像素值突变(如物体边缘、文字边界、纹理细节),图像视觉上“清晰/有棱角”,此时标准差大(像素值离散)。

(3)OpenCV中常用的梯度计算方法

基础差值仅适用于理解,实际工程中用梯度算子(增强边缘检测效果):

  • Sobel算子:计算X(横向)/Y(纵向)方向的梯度,可过滤噪声;
  • Scharr算子:比Sobel更精准(适合小尺寸图像);
  • Laplacian算子:计算二阶梯度,对边缘更敏感(易受噪声影响)。

代码示例(Sobel梯度检测)

import cv2
import numpy as np
import matplotlib.pyplot as plt

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

# 计算X方向梯度(横向边缘)
sobel_x = cv2.Sobel(img_gray, cv2.CV_64F, dx=1, dy=0, ksize=3)
sobel_x = cv2.convertScaleAbs(sobel_x)  # 转换为绝对值(避免负数丢失)

# 计算Y方向梯度(纵向边缘)
sobel_y = cv2.Sobel(img_gray, cv2.CV_64F, dx=0, dy=1, ksize=3)
sobel_y = cv2.convertScaleAbs(sobel_y)

# 合并梯度
sobel_xy = cv2.addWeighted(sobel_x, 0.5, sobel_y, 0.5, 0)

# 显示结果
plt.subplot(221), plt.imshow(img_gray, cmap='gray'), plt.title('原图')
plt.subplot(222), plt.imshow(sobel_x, cmap='gray'), plt.title('X方向梯度')
plt.subplot(223), plt.imshow(sobel_y, cmap='gray'), plt.title('Y方向梯度')
plt.subplot(224), plt.imshow(sobel_xy, cmap='gray'), plt.title('合并梯度')
plt.show()

(4)梯度的应用场景

  • 边缘检测:利用梯度大的区域定位物体边缘(如轮廓提取);
  • 图像锐化:增强梯度值,提升图像细节(让模糊图像变清晰);
  • 模糊检测:计算整幅图像的梯度均值,若均值过小则判定为模糊;
  • 运动检测:对比前后帧图像的梯度变化,识别运动区域。

总结

  1. OpenCV图像坐标原点在左上角,尺寸表示为 (H, W),像素值范围0~255(单通道),平均值可判断亮度是否正常;
  2. OpenCV默认读取BGR格式,HSV空间因分离色彩与亮度,是颜色分割的首选;
  3. 图像梯度是像素值的空间变化率,梯度小对应图像平滑/模糊(标准差小),梯度大对应边缘/细节(标准差大),常用Sobel算子计算。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐