Commit e2666d23 SK

模板匹配

1 个父辈 7317aaf8
......@@ -61,6 +61,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="AoiProject.cs" />
<Compile Include="match\AoiTemplateMethod.cs" />
<Compile Include="util\Base64Util.cs" />
<Compile Include="util\ImageUtil.cs" />
<Compile Include="AoiMethod.cs" />
......
......@@ -18,9 +18,13 @@ namespace AOI
/// AOI检测结果,true表示OK, false表示NG
/// </summary>
public bool result = false;
/// <summary>
/// 标准区域图片
/// </summary>
public Image standardRoiImage;
/// <summary>
/// 当前区域图片
/// </summary>
public Image currentRoiImage;
public GraphicsPath roiPath;
......
......@@ -87,8 +87,12 @@ namespace AOI
Mat searchMat = ImageUtil.ToMat(new Bitmap(searchImage));
Mat markMat = ImageUtil.ToMat(new Bitmap(markImage));
//Cv2.CvtColor(searchMat, searchMat, ColorConversionCodes.RGB2GRAY);
//Cv2.CvtColor(markMat, markMat, ColorConversionCodes.RGB2GRAY);
//Mat graySearchMat = new Mat();
//Mat grayMarkMat = new Mat();
//Cv2.CvtColor(searchMat, graySearchMat, ColorConversionCodes.RGB2GRAY);
//Cv2.CvtColor(markMat, grayMarkMat, ColorConversionCodes.RGB2GRAY);
//double same = Cv2.MatchShapes(grayMarkMat, graySearchMat, ShapeMatchModes.I1);
//Console.WriteLine("===============" + same);
Mat result = new Mat(searchMat.Cols - markMat.Cols + 1, searchMat.Rows - markMat.Cols + 1, MatType.CV_32FC1);
......@@ -104,15 +108,10 @@ namespace AOI
//画出匹配的矩,
// Cv2.Rectangle(mat1, maxLocation, new Point (maxLocation.X+mat2.Cols, maxLocation.Y+mat2.Rows), Scalar.Red, 2);
Cv2.Rectangle(searchMat, maxLocation, new OpenCvSharp.Point(maxLocation.X + markMat.Cols, maxLocation.Y + markMat.Rows), Scalar.Red, 2);
Cv2.ImShow("mat1", searchMat);
//Console.WriteLine(minValue);
//Console.WriteLine(maxValue);
Console.WriteLine(minLocation + "=" + minVal);
Console.WriteLine(maxLocation + "=" + maxVal);
if (maxVal * 100 > 20)
if (maxVal * 100 > SamePercent)
{
//大于相似度,开始平移图像
var searchBounds = SearchPath.GetBounds();
......@@ -144,6 +143,7 @@ namespace AOI
public Image FixImage(Image standardImage, Image imageToCheck)
{
//Fix(standardImage, imageToCheck);
var affine = Fix(standardImage, imageToCheck);
if (affine != null)
......
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenCvSharp;
using OpenCvSharp.Blob;
using OpenCvSharp.XFeatures2D;
namespace AOI
{
/// <summary>
/// 模板匹配
/// </summary>
public class AoiTemplateMethod : AoiMethod
{
/// <summary>
/// 相似度百分比
/// </summary>
public double SamePercent = 50;
public override ResultBean Check(Image standardImage, Image imageToCheck)
{
ResultBean resultBean = new ResultBean();
bool needCut = true;
Image standardRoiImg = GetRoiImage(standardImage, needCut);
resultBean.standardRoiImage = standardRoiImg;
double percent = GetTemplateMatchPercent(standardImage, imageToCheck, out Image cutImg);
bool result = false;
if(SamePercent > 100)
{
SamePercent = 100;
}
if(percent >= SamePercent)
{
result = true;
}
resultBean.currentRoiImage = cutImg;
resultBean.result = result;
return resultBean;
}
/// <summary>
/// 获取模板相似度
/// </summary>
/// <param name="standardImage"></param>
/// <param name="imageToCheck"></param>
/// <param name="cutImg"></param>
/// <returns></returns>
public double GetTemplateMatchPercent(Image standardImage, Image imageToCheck, out Image cutImg)
{
bool needCut = true;
//标准图中的Mart区域
Image templateImage = GetRoiImage(standardImage, RoiPath, needCut);
//搜索区域
Image searchImage = GetRoiImage(imageToCheck, RoiPath, needCut);
cutImg = searchImage;
//searchImage = imageToCheck;
if (templateImage != null && searchImage != null)
{
Mat searchMat = ImageUtil.ToMat(new Bitmap(searchImage));
Mat templateMat = ImageUtil.ToMat(new Bitmap(templateImage));
Mat result = new Mat(searchMat.Cols - templateMat.Cols + 1, searchMat.Rows - templateMat.Cols + 1, MatType.CV_32FC1);
//进行匹配(1母图,2模版子图,3返回的result,4匹配模式_这里的算法比opencv少,具体可以看opencv的相关资料说明)
Cv2.MatchTemplate(searchMat, templateMat, result, TemplateMatchModes.CCoeffNormed);
//对结果进行归一化(这里我测试的时候没有发现有什么用,但在opencv的书里有这个操作,应该有什么神秘加成,这里也加上)
//Cv2.Normalize(result, result, 1, 0, NormTypes.MinMax, -1);
/// 通过函数 minMaxLoc 定位最匹配的位置
/// (这个方法在opencv里有5个参数,这里我写的时候发现在有3个重载,看了下可以直接写成拿到起始坐标就不取最大值和最小值了)
/// minLocation和maxLocation根据匹配调用的模式取不同的点
Cv2.MinMaxLoc(result, out double minVal, out double maxVal, out OpenCvSharp.Point minLocation, out OpenCvSharp.Point maxLocation);
return maxVal * 100;
}
return 0;
}
}
}
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!