SJTU-RM-CV-2019
全图搜索模式:
在原图中寻找目标,并返回是否找到:
一.寻找所有可能的灯条
1.单通道,只用一个红或蓝通道
2.两种不同的二值化阈值,应对不同亮度
3.开闭运算:腐蚀一次,膨胀两次,再腐蚀一次,大小均为(3,5)
4.轮廓提取
5.只对没有子轮廓的轮廓进行判断:是否为有效灯条
1)最小外接矩形的长宽比范围:(1.2,10)
2)最小外界矩形的面积<50 且凸度(轮廓面积和其最小外接矩形面积之比)>0.4
3)最小外界矩形的面积>=50 且凸度(轮廓面积和其最小外接矩形面积之比)>0.6
条件的关系:1&&(2||3)
Note: 面积小的凸度可能容易不稳定
6.判断灯条颜色:
1)拿最小外界矩形的boundingRect(不倾斜的),再适当调大大小
2)与src取交集:region &= cv::Rect(0, 0, src.cols, src.rows);
3)遍历该roi:
red_cnt += roi.at<cv::Vec3b>(row, col)[2];
blue_cnt += roi.at<cv::Vec3b>(row, col)[0];
4)red_cnt > blue_cnt 则为红,反之,则为蓝
7. 遍历之前的两种阈值出来的二值图出来的灯条,判断是否为相同灯条:
1)两灯条中心距离的平方<9
8.若为相同灯条,则哪个凸度低,把哪个给remove
(先遍历,把要erase的序号记下来,从大到小erase!)
9.合并两种阈值出来的二值图出来的灯条
10.若light_blobs.size() >= 2,才return true
二.匹配灯条,得到装甲板
1.判断两个灯条是否可以匹配
1)颜色均为enemy_color
2)两个灯条的长度比lengthRatioJudge < 2.5 > 0.4
3)判断两个灯条的间距
side_length = sqrt(centers.ddot(centers));
(side_length / light_blob_i.length < 10
&& side_length / light_blob_i.length > 0.5);
4)判断两个灯条的错位度 中心差.x和角度cos乘积+中心差.y和角度sin乘积
5)判断装甲板方向 (angle_i + angle_j) / 2.0
(-120.0 < angle && angle < -60.0) || (60.0 < angle && angle < 120.0);
6)判断两个灯条的角度差 abs(angle_i - angle_j) < 20;
7)判断两个灯条的高度差 <30
2.判断是否是有效装甲板
1)装甲板区域超过src,则continue
2)装甲板中心位置的y不可能太低 (max_y + min_y) / 2 < 120
3)if ((max_x - min_x) / (max_y - min_y) < 0.8) continue;
Note:它们获得的装甲板是一个正矩形
3.用卷积神经网络对装甲板进行分类
Leran:
cv::countNonZero
rect可以&
point可加减
使用了opencv的Tracker
待完善-----------------