计算机视觉实验一:图像通道提取与处理
📋 实验目标
学习 OpenCV 中图像通道的提取、处理和显示方法,理解 BGR 颜色空间和图像数组操作。
🛠️ 实验环境
- Python 版本: 3.x
- 主要库: OpenCV, NumPy, Matplotlib
- 图像文件: leaf.jpg
📚 核心知识点
1. OpenCV 颜色通道顺序
OpenCV 使用 BGR(蓝-绿-红)格式存储彩色图像:
- 通道 0: 蓝色通道 (Blue)
- 通道 1: 绿色通道 (Green)
- 通道 2: 红色通道 (Red)
2. NumPy 数组切片语法
img[:,:,0] # 选择所有行、所有列、第0个通道
- 第一个
:
: 选择所有行(高度) - 第二个
:
: 选择所有列(宽度) - 第三个
0
: 选择第0个通道(蓝色)
3. 图像数组维度
- 3维数组:
(height, width, channels)
- 彩色图像 - 2维数组:
(height, width)
- 灰度图像
💻 实验代码详解
步骤1: 导入库和加载图像
import cv2
import numpy as np
import matplotlib.pyplot as pltimg = cv2.imread('leaf.jpg')
步骤2: 提取蓝色通道
# 提取蓝色通道(单通道)
img_blue = img[:,:,0]
cv2.imshow('img_blue', img_blue)
⚠️ 重要发现: 提取蓝色通道后显示的是灰度图像,而不是蓝色图像!
原因分析:
img_blue
是单通道的2维数组- OpenCV 显示单通道图像时自动转换为灰度显示
- 要显示蓝色,需要保持3通道结构
步骤3: 创建只显示蓝色的彩色图像
# 创建与原始图像相同形状的零数组
img_blue_true = np.zeros_like(img)# 只保留蓝色通道,其他通道设为0
img_blue_true[:,:,0] = img_blue
关键函数: np.zeros_like(img)
- 创建与
img
形状和数据类型完全相同的数组 - 所有元素填充为 0
- 保持3通道结构
步骤4: 图像拼接显示
# 水平拼接两个图像进行对比
combined_img = np.hstack((img, img_blue_true))
cv2.imshow('combined_img', combined_img)
步骤5: 图像缩放处理
# 获取原始图像尺寸
height, width = img.shape[:2] # 注意:返回的是(height, width)# 设置缩放比例
scale_factor = 0.5 # 缩小到50%
new_width = int(width * scale_factor)
new_height = int(height * scale_factor)# 缩放图像
img_blue = cv2.resize(img_blue, (new_width, new_height))
img_blue_true = cv2.resize(img_blue_true, (new_width, new_height))
步骤6: 通道转换和最终拼接
# 将单通道灰度图像转换为3通道BGR图像
img_blue = cv2.cvtColor(img_blue, cv2.COLOR_GRAY2BGR)# 拼接缩放后的图像
combined_img_new = np.hstack((img_blue, img_blue_true))
cv2.imshow('combined_new', combined_img_new)
🚨 常见错误与解决方案
错误1: 数组维度不匹配
# ❌ 错误写法
img_blue_true[:,:,0] = img_blue[:,:,0] # img_blue是2维数组,不能用3维索引# ✅ 正确写法
img_blue_true[:,:,0] = img_blue
错误2: 宽高顺序错误
# ❌ 错误写法
width, height = img.shape[:2] # 顺序错误# ✅ 正确写法
height, width = img.shape[:2] # img.shape返回(height, width, channels)
错误3: 通道数不匹配拼接
# ❌ 错误写法
combined = np.hstack((img_blue, img_blue_true)) # 2维和3维数组无法拼接# ✅ 正确写法
img_blue_3channel = cv2.cvtColor(img_blue, cv2.COLOR_GRAY2BGR)
combined = np.hstack((img_blue_3channel, img_blue_true))
📊 实验结果
显示效果对比
- 原始图像: 完整的彩色图像
- 蓝色通道(灰度): 单通道提取,显示为灰度图像
- 蓝色通道(彩色): 只显示蓝色分量,其他通道为0
- 拼接对比: 并排显示,便于观察差异
关键观察
- 蓝色通道提取后,图像中蓝色分量强的区域在灰度图中显示较亮
- 通过设置其他通道为0,可以创建只显示特定颜色分量的图像
- 图像缩放和拼接是图像处理中的常用技术
🔧 实用技巧
1. 图像尺寸获取
height, width, channels = img.shape # 获取完整形状信息
height, width = img.shape[:2] # 只获取高度和宽度
2. 图像缩放
# 等比例缩放
scale_factor = 0.5
new_width = int(width * scale_factor)
new_height = int(height * scale_factor)
resized_img = cv2.resize(img, (new_width, new_height))
3. 通道转换
# 灰度转BGR
gray_3channel = cv2.cvtColor(gray_img, cv2.COLOR_GRAY2BGR)# BGR转灰度
gray_img = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2GRAY)
4. 图像拼接
# 水平拼接
combined_h = np.hstack((img1, img2))# 垂直拼接
combined_v = np.vstack((img1, img2))
📝 总结
本次实验学习了:
- OpenCV 图像读取和显示
- BGR 颜色空间和通道提取
- NumPy 数组操作和切片语法
- 图像缩放和拼接技术
- 通道转换和图像处理技巧
通过对比不同处理方法的显示效果,深入理解了图像在计算机中的存储和表示方式。
实验日期: 2025年9月20日
实验者: Atta