4. 图像基本操作与颜色空间
在农业机器视觉任务中,拿到一张田间图像后,我们很少直接把它送进模型。更常见的流程是:先对图像做几何变换,把感兴趣的区域摆正、放大或对齐;再把颜色从RGB转换到HSV,利用色调(Hue)把绿色作物从土壤、地膜、阴影中分离出来。本节围绕这两类操作展开,最终完成一个可运行的“绿色植被分割”小任务。
一、几何操作:裁剪、缩放、旋转、翻转
OpenCV 把图像读成 NumPy 数组,形状为 (高, 宽, 通道),通道顺序是 BGR 而不是 RGB,这一点在后续颜色处理时必须牢记。几何操作本质上是对像素坐标做映射,理解坐标约定是避免出错的前提:图像左上角为原点 (0,0),x 轴向右,y 轴向下,本节所有图示与代码均遵循这一约定。
裁剪是最简单的操作,用数组切片即可,语法为 img[y1:y2, x1:x2],先写行(y)再写列(x)。例如从一张 1280×720 的田间图中取出中央 400×400 的区域:
import cv2
img = cv2.imread("field.jpg") # 形状 (720, 1280, 3),BGR
crop = img[160:560, 440:840] # 高400、宽400
print(crop.shape) # (400, 400, 3)
缩放用 cv2.resize,关键是选对插值方式:缩小图像用 INTER_AREA,能避免摩尔纹;放大图像用 INTER_LINEAR 或 INTER_CUBIC。缩放会改变像素与实际尺寸的对应关系,若后续要测量叶面积或株距,必须同步记录缩放比例。
旋转用 cv2.getRotationMatrix2D(中心点, 角度, 缩放因子) 生成 2×3 变换矩阵,再用 cv2.warpAffine 应用。注意 OpenCV 中正角度表示逆时针旋转。旋转后图像四角可能被裁掉,需要重新计算输出尺寸或设置边界填充值。
翻转用 cv2.flip(src, flipCode):flipCode=1 水平翻转(左右镜像),0 垂直翻转(上下镜像),-1 同时水平和垂直翻转。翻转常用于数据增强,但要注意它可能改变具有方向含义的目标,例如倾斜的植株倒伏方向。
二、从 RGB 到 HSV:为什么换颜色空间
RGB 三个通道都同时混合了亮度与色彩信息。同一片绿叶,在正午强光下 R、G、B 数值都高,在阴影里都低,用固定的 RGB 阈值几乎不可能同时覆盖。HSV 把颜色拆成三个更符合直觉的分量:H 色调表示颜色种类(0~179,对应 0°~360°),S 饱和度表示颜色纯度(0~255),V 明度表示亮度(0~255)。绿色在 H 通道上集中在一个较窄的区间,因此用 H 做阈值对光照变化更稳健。
转换只需一行:hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)。需要特别注意 OpenCV 的 H 范围是 0~179 而非 0~360,这是 8 位存储导致的折半,写阈值时不要照搬网上 0~360 的数值。
三、用 HSV 提取绿色作物区域
绿色在 OpenCV 的 H 通道中大致落在 35~85 之间。一个常用的起点是:H 取 35~85,S 取 43~255,V 取 46~255。S 下限用于排除灰白色的地膜和水泥路面,V 下限用于排除深阴影。这三个区间不是万能值,需要根据实际图像微调。
hsv = cv2.cvtColor(crop, cv2.COLOR_BGR2HSV)
lower = np.array([35, 43, 46])
upper = np.array([85, 255, 255])
mask = cv2.inRange(hsv, lower, upper) # 绿色区域为255,其余为0
# 形态学去噪:先开后闭
k = np.ones((5, 5), np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, k) # 去掉零散噪点
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, k) # 填补叶片内部小孔
result = cv2.bitwise_and(crop, crop, mask=mask)
ratio = cv2.countNonZero(mask) / (mask.shape[0] * mask.shape[1])
print(f"绿色像素占比: {ratio:.2%}")
这段代码的输出有两个用途:一是 result 可视化,直观检查分割是否把叶片完整保留、是否把土壤误判为绿色;二是 ratio 这个数值指标,可用于判断出苗覆盖度是否达到某个阈值,例如示例中若得到 0.32,说明约三成画面被绿色覆盖。
四、参数调优与常见问题
实际调试时,建议先用 cv2.createTrackbar 做一个滑动条窗口,实时拖动 H、S、V 的上下限观察掩膜变化,比反复改代码高效得多。常见问题有三类:
- 叶片被漏掉:多为强反光导致 V 过高或 S 过低,可适当放宽 S 下限,或对高光区域单独处理。
- 土壤被误判为绿色:潮湿土壤或苔藓在 H 上接近绿色,可收紧 H 区间并提高 S 下限。
- 掩膜边缘毛糙:形态学核过大导致,改用 3×3 核,或先做一次中值滤波
cv2.medianBlur。
几何操作与颜色分割通常组合使用:先裁剪出垄间区域减少计算量,再缩放统一尺寸,最后在 HSV 空间做阈值分割。这样一条流水线在普通笔记本上处理 720p 图像通常只需几十毫秒,足以支撑田间实时预筛。掌握本节内容后,你就具备了从原始图像到“作物/背景”二值结果的基本能力,为后续的轮廓提取、连通域分析和目标检测打下基础。