首先,本人不是专业写代码的,因此说的不对的地方,请各位大神指教!一定要说啊。
对于非标自动化设备行业,利用工业相机做视觉识别,然后抓取工件的应用可谓非常成熟广泛,然后想着我要是也能略知一二那就好了,于是在工作之余研究了一下,自己画了一张图,就是下面这张:
模板取自图中的某个小号的“2”:
目标是找出目标图中所有的“2”,并确定旋转角度,精度只能到1°了!!!再高的精度还没研究,希望各位指教!!
好了下面开始说下我的思路:
Step1:以灰度图模式加载图片,就是imread(“...”,0);
Step2:对模板图和目标图分别进行边沿检测:先blur(...),再canny(....);大家也可以尝试其他的边沿检测方法!
Step3:由于目标图中存在有不同角度的旋转目标,所以最直接的做法是对模板图旋转1°,利用wrapAffine(...)得到新的模板图片后再与目标图的边沿图进行匹配,找出最佳匹配信息;
Step3.1:create一个原模板图旋转任何角度都能不丢失内容的图片,该图片cols和rows都为模板图片对角线长
Step3.2:定义一个仿射变换矩:确定旋转中心点,Point(对角线/2,对角线/2);缩放比例为1;
Step3.3:getRotationMatrix2D(......)得到仿射变换矩;
Step3.4:warpAffine(...)得到新的模板图;
Step4:将目标图的边沿图与上面得到新的模板图进行matchTemplate(...);
Step5:由于是多目标查找,封装了一个函数GetNextMaxLoc(...); /*没错,是NextMax,这里参考 点击打开链接 中的 getNextMinLoc(...)*/; 进行for循环;
Step5.1:定义一个数据结构,包含信息有:新模板图的旋转角度,GetNextMaxLoc(...)获取的最佳匹配点maxLoc, 和最大匹配值maxVal;
Step5.2:定义一个元素为上述数据结构的vector;
Step5.3:定义一个模板类,比较数据结构中的maxLoc元素是否为同一个点,参考: 在元素为结构体变量的vector中查找元素:http://blog.chinaunix.net/uid-22431962-id-125367.html
Step5.4:利用迭代器iterator进行过滤:如果容器中存在相同的maxLoc,比较相同maxLoc时两者的maxVal,如果新的 maxVal比原maxVal大,则替换掉maxVal和此时的模板旋转角度;否则不做处理;
如果不存在相同的maxLoc,则将此时的数据结构元素push_back(....)到5.2定义的容器中;
Step6:对step3-5进行while循环,匹配过滤得到最终的最佳的目标匹配信息容器;
Step7:对上述得到的匹配信息容器进行解析,在目标灰度图中用rotateRect类形的矩形标记,输出角度,匹配值,坐标信息
下面贴出两张结果图:
这是我作为opencv初学者多目标匹配的方法,是最笨的,所以大家看到了,0-180°的查找时间用了5秒多!希望各位过客有更高效的方法能够传授一二!!
感谢!!!