上学期《计算机视觉》课的project题目,我们组使用OpenCV配合实验室的Delta并联机器人实现了一个简单的打地鼠游戏的物理外挂。
说是外挂,其实效果和人工操作起来还是有差距的。
废话不多说,先上效果展示:
https://www.bilibili.com/video/av44728617
项目代码链接:https://github.com/chenyr0021/WhacAMole
OpenCV版本:3.2.0
运行平台:win10,Visual Studio 2015
游戏来源:iPad AppStore
标定程序是从网上找到的,参见
https://blog.csdn.net/hust_bochu_xuchao/article/details/51838732
在这里我把代码稍作改动,封装成一个标定函数,方便在我的主程序调用。
将标定好的数据包括内外参数和畸变参数保存到xml文件里,以后再使用同一个摄像头就不用再次标定了。
预处理部分主要是裁剪,二值化,寻找iPad轮廓及投影变换。
frame = src_frame(Rect(Point(150,150),Point(550,380)));
inRange()
函数。其他方法例如灰度图直接二值化、使用HSV的V通道二值化都对环境光照鲁棒性不强,使用Canny算子提取边缘的效果也不太好。findContours()
函数,按面积筛选出iPad的内边框,拟合成四边形,提取角点,这个区域设为ROI。//寻找、筛选轮廓
vector< vector<cv::Point> > contours_list;
vector< vector<cv::Point> > contours_sublist;
findContours(binary_frame, contours_list, RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
vector<Point> corner;
for (int i = 0; i < contours_list.size(); i++)
{
if (contourArea(contours_list[i]) > 20000)
contours_sublist.push_back(contours_list[i]);
}
//筛选面积大于20000中最小的
int min_area = 640*480;
for (int i = 0; i < contours_sublist.size(); i++)
{
if (contourArea(contours_sublist[i]) < min_area)
{
min_area = contourArea(contours_sublist[i]);
//cout <<"min_area: "<< min_area << endl;
corner = contours_sublist[i];
}
//drawContours(frame_to_show, contours_sublist, i, Scalar(255), 8);
}
Point2f corner_dst[4] = {Point2f(0, 0),
Point2f(400, 0),
Point2f(400, 300),
Point2f(0, 300)};
//计算投影变换矩阵
Mat transfer_mat = getPerspectiveTransform(corner_dst, corner_src);
PS:这里应当注意两组角点的顺序应当一致
最后一道工序就是直方图均衡化了,变换后的效果图差不多就是这个样子:
到这一步,基本就可以进行模板匹配了。从上图里面选个幸运儿,截个图下来就是一个模板了。
但是只用一个模板的话可能效果不太好,毕竟图像本身比较糊,而且这些位置的地鼠亮度什么的不太一致。
我们采用的方法就是把所有的地鼠都做个模板,一一匹配,哪个值最高就选哪个。这样虽然牺牲了一些时间,但是效果会提升很多。
当然如果有其他的方法把图像处理的更清楚就更好了,不过本菜鸡没想到哈哈。
识别的代码就比较简单了,注意阈值的设置需要调试。
到这里,视觉的部分就全部结束了。
地鼠已经识别出来了,具体的打击操作还需要专业人士——Delta机器人来完成。
Delta机器人是隔壁实验室的三轴并联机器人,本身比较大,视频演示中并没有拍到它的全貌。用到这个项目上的确有点小题大作了,嗯。
这里使用串口通讯的方式向机器人的上位机发送地鼠的位置,9个地鼠分别编号1~9。根据地鼠的像素坐标确定其编号。
windows的串口操作本菜鸡也不是很懂,因此参照了
https://blog.csdn.net/zmdsjtu/article/details/78539681
这里不再赘述。
全部代码已上传至GitHub,链接在开头。
整个课程设计做了大概两周,感谢 琪宝宝 和 A+少女真真姐 的辛苦付出~