文章目录
- 一、函数介绍
- 二、演示
- 1.原始素材
- 2.代码
- 3.运行结果
一、函数介绍
MatchShapes()函数,可以比较两个轮廓的相似度,而且对于旋转、放大、缩小的轮廓都能适用,利用这个函数就能实现最简单的物体检测。函数官方定义如下
public static double MatchShapes(
IInputArray contour1, // 待比较的轮廓1
IInputArray contour2, // 待比较的轮廓2
ContoursMatchType method, // 比较方式
double parameter = 0.0 // 对比精度0.0 - 1.0 ,越小匹配程度越高
)
ContoursMatchType 有I1、I2、I3共三种,我也不知道有什么区别。
二、演示
1.原始素材
模板图像templateMat如下图:
目标图像targetMat如下图:
我们的目标是在targetMat中,找到与templateMat相似的字母“A”。
2.代码
轮廓检索模式要选择RetrType.External,代码如下:
Mat tempTemplateMat = templateMat.Clone();
Mat tempTargetMat = targetMat.Clone();
Mat dstMat = tempTargetMat.Clone();
Mat templateGray = new Mat();
Mat targetGray = new Mat();
int threshold = 40;
double comparison = Convert.ToDouble("0.02");
// 1.查找模版图像的轮廓
CvInvoke.CvtColor(tempTemplateMat, templateGray, ColorConversion.Bgr2Gray);
CvInvoke.Threshold(templateGray, templateGray, threshold, 255, ThresholdType.Binary); // 二值化,确保黑里面找白
CvInvoke.Imshow("1.Threshold template Mat", templateGray);
VectorOfVectorOfPoint contoursTemplate = new VectorOfVectorOfPoint(); // 模版图像的轮廓
VectorOfRect hierarchyTemplate = new VectorOfRect();
CvInvoke.FindContours(templateGray, contoursTemplate, hierarchyTemplate, RetrType.External, ChainApproxMethod.ChainApproxNone);
CvInvoke.DrawContours(tempTemplateMat, contoursTemplate, -1, new MCvScalar(255, 0, 255), 1);
// 2.查找模板图像的轮廓
CvInvoke.CvtColor(tempTargetMat, templateGray, ColorConversion.Bgr2Gray);
CvInvoke.Threshold(templateGray, templateGray, threshold, 255, ThresholdType.Binary);
CvInvoke.Imshow("2.Threshold target Mat", templateGray);
VectorOfVectorOfPoint contoursTarget = new VectorOfVectorOfPoint(); // 模版图像的轮廓
VectorOfRect hierarchyTarget = new VectorOfRect();
CvInvoke.FindContours(templateGray, contoursTarget, hierarchyTarget, RetrType.External, ChainApproxMethod.ChainApproxNone);
// 3.形状匹配---比较两个形状或轮廓间的相似度
double a0 = 0;
for (int i = 0; i < contoursTarget.Size; i++)
{
a0 = CvInvoke.MatchShapes(contoursTemplate[0], contoursTarget[i], ContoursMatchType.I1, 0);
Console.WriteLine("模版图像轮廓与目标图像轮廓" + i + "的相似度: " + a0);
if (a0 < comparison) // 轮廓与模版轮廓的相似度小于设定值,证明找到了
{
CvInvoke.DrawContours(dstMat, contoursTarget, i, new MCvScalar(0, 255, 0), 5);
}
}
CvInvoke.Imshow("Final result image, " + dstMat.Size.ToString(), dstMat); // 显示最终结果
3.运行结果
刚才对比精度是0.02,结果只找到了两个字母“A”,如果换成0.2呢,全部的“A”都会找到,包括颜色不一样的、大小不一样的、旋转的等等,如下所示:
原创不易,请勿抄袭。共同进步,相互学习。