基于openCV的形状模版匹配
展开全文
2018年10月17日 20:42:47 sillykog 阅读数:1038
版权声明:本文为陈默含原创文章。 blog.csdn/sillykog/article/details/83116793
初衷
果然halcon用顺手了,人就变懒了,正好有项目需要自己写个形状匹配的程序,就拿来练练手,程序不是很复杂,速度上感觉和halcon里面find_scaled_shape_model还是有差距,目前也不知道如何进一步改进,暂时就先这样了。大佬们如果有什么改进的想法可以评论一下,这样才能不断进步。
思路
主要的想法还是基于散点的重合度,虽然openCV自带matchTemplate和matchShape函数,但其内部是进行遍历像素矩计算,由于检测图中会有干扰边缘的存在,所以这些函数对于形
状匹配(局部像素点集匹配)来说是不适合的。当然这些函数运行速度还是非常快的,目前我也不知道用什么办法可以达到同数量级的运算速度。
算法实现过程中主要遇到了几个问题:
1.生成旋转模版的问题
openCV没有自带的旋转函数,需要通过getRotationMatrix2D生成旋转矩阵,再用warpAffine进行仿射变换。但是warpAffine生成的图形会自动进行裁剪,会带来一些问题,因此需要稍微修改(详情见imrotate函数)。
2.遍历边缘点还是进行卷积的问题
由于openCV和halcon对于取像素点的操作都特别慢,所以对比之下只能采取用filter2D进行遍历,不得不说openCV自带的硬件加速库还是高效。
3.遍历运算速度过慢
openCV一些函数的源代码在内部还是进行了hal库的调用,用户没有办法修改,因此没有
办法在函数内部进行算法修改。尝试用ppl库进行并行加速,效果还可以。
程序使用说明
(1)优先修改金字塔层数PyrLevel,层数越大,搜索速度越快,主函数中有缩放后的边缘图片,根据边缘是否清晰来修改PyrLevel和Canny函数的阈值,保证待检测图和模版图片的边缘足够清晰完整。
(2)如果不到,适当减小minScore,越接近0,搜索相似容忍度越大,但运行速度同时也越慢。
函数片段
具体代码工程见
download.csdn/download/sillykog/10727775
/*************************************************
Function: // CreateScaledShapeModel
Description: // 创建模版集
Input: // Template:模版图片的边缘图
PyrLevel:金字塔缩小层数
AngleStart,AngleExtent,AngleStep:旋转角度候选参数
ScaleMin,ScaleMax,ScaleStep:缩放比例候选参数
Output: // pModelImageSet,pModelPointSet,pScaleSet,pAngleSet:模版集指针
Return: // 无
Others: //
*************************************************/
void CreateScaledShapeModel(Mat Template, int PyrLevel, int AngleStart, int AngleExtent, int AngleStep, float ScaleMin, float ScaleMax, float ScaleStep, vector<Mat
>* pModelImageSet, vector<int>* pModelPointSet, vector<float>* pScaleSet, vector<float>* pAngleSet)
{
vector<Mat> ModelImageSet;
vector<int> ModelPointSet;
vector<float> AngleSet;
vector<float> ScaleSet;
while (ScaleMin <= ScaleMax)
{
cout << ScaleMax << endl;
ScaleSet.push_back(ScaleMax);
ScaleMax -= ScaleStep;
}
while (AngleStart <= AngleExtent)
{
cout << AngleExtent << endl;
AngleSet.push_back(AngleExtent);
AngleExtent -= AngleStep;
}
//模版生成
for (int level = 0; level <= PyrLevel; level++)
{
Mat pyrmodelImage = Template;
for (int i = 0; i < level; i++)
{
pyrDown(pyrmodelImage, pyrmodelImage);
}
//缩放
for (int i = 0; i < ScaleSet.size(); i++)
{
Mat scaleImage;
resize(pyrmodelImage, scaleImage, Size(ls*ScaleSet[i]), ls*ScaleSet[i])), 0, 0, INTER_LINEAR);
//旋转
for (int j = 0; j < AngleSet.size(); j++)
{
Mat rotateImage;
imrotate(scaleImage, rotateImage, AngleSet[j]);
//threshold(rotateImage, rotateImage, 1, 255, 0);
Canny(rotateImage, rotateImage, 50, 100, 3, false);
rotateImage /= 255;
//imshow("旋转", rotateImage);
//imwrite("旋转.jpg", rotateImage);
//waitKey(0);
ModelImageSet.push_back(rotateImage);
int pointNum = 0;
for (int i = 0; i < ls; i++)
{
for (int j = 0; j < ws; j++)
{
if (rotateImage.at<uchar>(Point(i, j)) != 0)
pointNum++;
}
}
ModelPointSet.push_back(pointNum);
lease();
}
lease();
}
}
*pModelImageSet = ModelImageSet;
*pModelPointSet = ModelPointSet;
*pAngleSet = AngleSet;rectangle函数opencv
*pScaleSet = ScaleSet;
}
/*************************************************
Function: // FindScaledShapeModel
Description: // 在一张图片中搜索与模版相似的图形
Input: // Image:待检测图片
ModelImageSet,ModelPointSet,ScaleSet,AngleSet:模版集
PyrLevel:金字塔缩小层数
MinScore:筛选相似度阈值
Output: // pRow,pCol,pScale,pAngle,pScore:输出匹配到的元素参数集合的指针
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论