概述
这个项目是本周数字图像处理课程的一个project。因为杨老师主要做的是无人机及遥感方向的研究,所以这是一个与无人机控制相关的识别标记任务,原项目是识别无人机摄像头采集到视频数据中出现的黄色标记,并利用黄色标记的位置实现精准降落以及飞行高度的控制;本次作业是其中的一小部分,即识别视频文件中的黄色标记牌,并标记其边缘。我主要是利用的HSV颜色空间以及标记牌的边缘嵌套关系进行的识别与定位。
相关知识
HSV颜色空间
我们通常使用的RGB颜色空间是利用的三原色进行颜色的标识,但是HSV颜色空间与之不同,这个模型中颜色的参数分别是:色调(H),饱和度(S),明度(V)。
更详细的介绍可以参考:wiki:HSL and HSV。
关于HSV中详细的色彩划分区间,可以参考:OpenCV中HSV颜色模型及颜色分量范围。
思路整理
此项目的处理对象是视频,我们可以先从视频中有特点的几帧开始测试处理。因此我先观察了一遍视频,然后截取视频中的几张比较有代表性的情况,用来进行初始的测试。其中包含一般情况下标记牌,在旋转过程中边境较为模糊的标记牌,以及由于相机角度偏转标志牌变为非规则矩形的情况。其中一张如下:。
我的思路整体是将RGB图像转变为HSV图像,然后利用色相进行限制,提取出黄色部分;然后利用标记牌即中间数字的嵌套关系,进行除标记牌以外黄色部分的剔除;最后标记除黄色标记牌边缘即可。
首先利用HSV的黄色色相限制筛选的范围:1
2lower = np.array([26, 43, 20])
upper = np.array([34, 255, 255])
然后进行RGB到HSV空间的转换,并进行筛选:1
2
3
4# change the photo to hsv model
img_HSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# use upper and lower to locate the yellow in the photo
img_mask = cv2.inRange(img_HSV, lower, upper)
但是这样操作之后发现,由于桌子即地板均为黄色,所以这样筛选出出来的区域较大,难以进行标志牌的分割。此时观察到标记牌和桌子虽然都是黄色,但是标记牌的饱和度明显高于其他位置黄色,所以逐步调制范围上界的饱和度数值,只到将饱和度上界上升到160的时候,经过筛选的部分仅仅包括标记牌和少部分杂物。之后进行后续操作。即利用标记牌的轮廓嵌套关系进行其余杂物的剔除:1
2
3
4
5
6
7
8
9
10
11
12
13# get the contours and the hierarchy of contours
img_fc, contours, hierarchy = cv2.findContours(edge_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# use the nested models to locate the yellow mark
hierarchy = hierarchy[0]
found = []
for i in range(len(contours)):
k = i
c = 0
while hierarchy[k][2] != -1:
k = hierarchy[k][2]
c = c + 1
if c >= 2:
found.append(i)
此时将标记牌完全筛选出,然后提取边缘即可,结果如下:
这样就完成了一帧的操作,之后在完成视频的读取和写入操作即可。
代码实现
代码完整实现参考我的github:SuperYanyann/locatingYellowMark。包括了单张图片的和视频的标记牌的提取。
小结
将测试视频输入,输出处理后视频后观察发现,绝大部分帧的操作效果较好,但是有少部分帧由于视频旋转较快,标记牌边界的嵌套关系发生细微的变化,所以有些偏差,整体效果尚可。总的来说,本次的任务主要是根据标记牌色相和饱和度的特征进行筛选操作,难度不大。