OpenCV-Python 中图像的表示本质上是NumPy 多维数组,不同类型的图像(灰度、彩色、带透明通道)对应不同维度的数组结构。理解图像的表示方法是后续处理的基础,以下详细介绍各类图像的表示形式、数据类型及关键属性。
一、图像的基本表示:NumPy 数组
OpenCV 读取的图像以NumPy.ndarray存储,数组的维度、形状和数据类型直接反映图像特征:
- 维度:对应图像的高度(行)、宽度(列)、通道数;
- 数据类型 :默认
uint8(0-255),表示像素的亮度 / 颜色值; - 索引方式 :
img[row, col, channel](行优先,与常规坐标(x,y)相反)。
二、不同类型图像的表示
1. 灰度图像(单通道)
灰度图像仅包含亮度信息,用二维数组 表示:shape = (height, width),每个元素对应像素的灰度值(0 = 黑,255 = 白)。
python
import cv2
import numpy as np
# 读取灰度图像
gray_img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
print(f"灰度图像形状: {gray_img.shape}") # 输出 (高度, 宽度),例如(480, 640)
print(f"数据类型: {gray_img.dtype}") # uint8
print(f"像素值范围: {gray_img.min()} ~ {gray_img.max()}") # 0 ~ 255
# 访问像素值(第100行,第200列)
pixel = gray_img[100, 200]
print(f"灰度像素值: {pixel}")
2. 彩色图像(三通道)
OpenCV 默认以BGR 格式 存储彩色图像(与 PIL 的 RGB 相反),用三维数组 表示:shape = (height, width, 3),第三维对应 B、G、R 三个通道。
python
# 读取彩色图像(BGR格式)
color_img = cv2.imread('image.jpg')
print(f"彩色图像形状: {color_img.shape}") # (高度, 宽度, 3),例如(480, 640, 3)
# 访问BGR通道像素值(第100行,第200列)
b = color_img[100, 200, 0] # 蓝色通道
g = color_img[100, 200, 1] # 绿色通道
r = color_img[100, 200, 2] # 红色通道
print(f"BGR像素值: ({b}, {g}, {r})")
# 分离/合并通道
b_channel, g_channel, r_channel = cv2.split(color_img) # 分离通道
merged_img = cv2.merge([b_channel, g_channel, r_channel]) # 合并通道
注:需特别注意OpenCV的图像默认是BGR格式存储(与其他的RGB是不同的)。
3. 带透明通道的图像(四通道)
PNG、TIFF 等格式支持Alpha 通道 (透明度),用四维数组 表示:shape = (height, width, 4),第四维对应 Alpha 通道(0 = 完全透明,255 = 完全不透明)。
python
# 读取带Alpha通道的图像
rgba_img = cv2.imread('transparent.png', cv2.IMREAD_UNCHANGED)
print(f"RGBA图像形状: {rgba_img.shape}") # (高度, 宽度, 4)
# 访问Alpha通道
alpha = rgba_img[100, 200, 3]
print(f"Alpha值: {alpha}")
三、图像的数据类型转换
OpenCV 默认使用uint8存储图像,但处理时可能需要转换为其他类型(如浮点型):
1. 常见数据类型
| 类型 | 取值范围 | 用途 |
|---|---|---|
uint8 |
0 ~ 255 | 常规图像存储 |
uint16 |
0 ~ 65535 | 高动态范围图像(HDR) |
float32 |
0.0 ~ 1.0 | 归一化处理、浮点运算 |
int32 |
-2¹⁵ ~ 2¹⁵-1 | 差值计算(如边缘检测) |
2. 转换示例
python
# uint8转float32(归一化到[0,1])
float_img = color_img.astype(np.float32) / 255.0
# float32转回uint8(用于保存)
uint8_img = (float_img * 255).astype(np.uint8)
# 灰度图转彩色图(单通道→三通道)
gray_to_color = cv2.cvtColor(gray_img, cv2.COLOR_GRAY2BGR)
四、图像的坐标系统
OpenCV 采用笛卡尔坐标系,但原点在图像左上角:
(0, 0):左上角像素;(width-1, height-1):右下角像素;- 索引顺序:
img[row, col](行对应 y 轴,列对应 x 轴)。
python
# 访问坐标(x=200, y=100)的像素(注意顺序:行=100,列=200)
pixel = color_img[100, 200]
五、图像的创建与初始化
可通过 NumPy 直接创建自定义图像:
python
# 创建黑色灰度图像(480x640)
black_gray = np.zeros((480, 640), dtype=np.uint8)
# 创建白色彩色图像(480x640)
white_color = np.ones((480, 640, 3), dtype=np.uint8) * 255
# 创建红色图像(BGR格式,红色对应(0,0,255))
red_img = np.zeros((480, 640, 3), dtype=np.uint8)
red_img[:, :, 2] = 255 # 红色通道设为255
六、图像的内存布局
OpenCV 图像数组采用行优先存储 ,连续的行内存可通过img.is_contiguous()判断,非连续数组可通过img = img.copy()转为连续存储,提升处理效率。
七、完整示例:图像表示与操作
python
import cv2
import numpy as np
# 1. 读取图像
img = cv2.imread('image.jpg')
if img is None:
raise ValueError("图像读取失败!")
# 2. 打印基本信息
print(f"图像形状: {img.shape}")
print(f"数据类型: {img.dtype}")
print(f"像素总数: {img.size}")
# 3. 访问并修改像素
img[100:200, 200:300] = [0, 255, 0] # 将区域设为绿色(BGR)
# 4. 转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 5. 显示图像
cv2.imshow('Original', img)
cv2.imshow('Gray', gray)
cv2.waitKey(0)
cv2.destroyAllWindows()
总结
OpenCV 中图像的核心表示是NumPy 多维数组,不同维度对应不同类型的图像:
- 二维数组:灰度图像;
- 三维数组:彩色图像(BGR);
- 四维数组:带透明通道图像**(BGRA)**。
掌握数组的维度、数据类型和索引方式,是实现像素操作、通道处理、格式转换的基础。结合 NumPy 的数组运算,可高效完成各类图像处理任务。