OpenCvSharp通过特征点匹配

OpenCvSharp经过特征点匹配图片

现在的手游根本都是重复操作,一个动作要等好久,结束之后继续另一个动作.很麻烦,所以动起了自己写一个游戏辅佐的心思.
这个辅佐自身没什么难度,便是经过不断的截图,然后从这个截图中找出预先截好的能代表相应动作的按钮或者触发条件的小图.
找到之后获取该子区域的左上角坐标,然后经过windowsAPI调用鼠标或者键盘做操作就行了.
这里边最难的也便是找图了,因为要精准找图,而且最好能适应不同的分辨率下找图,所以在模板匹配的基础上,就有了SIFT和SURF的特征点找图方法.
在写的过程中查找资料,大都是C++或者python的,很少有原生的C#实现,所以我就直接拿来翻译过来了(稍作改动).

C#


SIFT算法
publicstaticBitmapMatchPicBySift(BitmapimgSrc,BitmapimgSub)
{using(MatmatSrc=imgSrc.ToMat())using(MatmatTo=imgSub.ToMat())using(MatmatSrcRet=newMat())using(MatmatToRet=newMat())
{
KeyPoint[]keyPointsSrc,keyPointsTo;using(varsift=OpenCvSharp.XFeatures2D.SIFT.Create())
{
sift.DetectAndCompute(matSrc,null,outkeyPointsSrc,matSrcRet);
sift.DetectAndCompute(matTo,null,outkeyPointsTo,matToRet);
}using(varbfMatcher=newOpenCvSharp.BFMatcher())
{varmatches=bfMatcher.KnnMatch(matSrcRet,matToRet,k:2);varpointsSrc=newList();varpointsDst=newList();vargoodMatches=newList();foreach(DMatch[]itemsinmatches.Where(x=>x.Length>1))
{if(items[0].Distance<0.5*items[1].Distance)
{
pointsSrc.Add(keyPointsSrc[items[0].QueryIdx].Pt);
pointsDst.Add(keyPointsTo[items[0].TrainIdx].Pt);
goodMatches.Add(items[0]);
Console.WriteLine($”{keyPointsSrc[items[0].QueryIdx].Pt.X},{keyPointsSrc[items[0].QueryIdx].Pt.Y}”);
}
}varoutMat=newMat();//算法RANSAC对匹配的成果做过滤varpSrc=pointsSrc.ConvertAll(Point2fToPoint2d);varpDst=pointsDst.ConvertAll(Point2fToPoint2d);varoutMask=newMat();//假如原始的匹配成果为空,则越过过滤步骤if(pSrc.Count>0&&pDst.Count>0)
Cv2.FindHomography(pSrc,pDst,HomographyMethods.Ransac,mask:outMask);//假如经过RANSAC处理后的匹配点大于10个,才应用过滤.不然运用原始的匹配点成果(匹配点过少的时分经过RANSAC处理后,可能会得到0个匹配点的成果).if(outMask.Rows>10)
{byte[]maskBytes=newbyte[outMask.Rows*outMask.Cols];
outMask.GetArray(0,0,maskBytes);
Cv2.DrawMatches(matSrc,keyPointsSrc,matTo,keyPointsTo,goodMatches,outMat,matchesMask:maskBytes,flags:DrawMatchesFlags.NotDrawSinglePoints);
}elseCv2.DrawMatches(matSrc,keyPointsSrc,matTo,keyPointsTo,goodMatches,outMat,flags:DrawMatchesFlags.NotDrawSinglePoints);returnOpenCvSharp.Extensions.BitmapConverter.ToBitmap(outMat);
}
}
}
SURF算法
publicstaticBitmapMatchPicBySurf(BitmapimgSrc,BitmapimgSub,doublethreshold=400)
{using(MatmatSrc=imgSrc.ToMat())using(MatmatTo=imgSub.ToMat())using(MatmatSrcRet=newMat())using(MatmatToRet=newMat())
{
KeyPoint[]keyPointsSrc,keyPointsTo;using(varsurf=OpenCvSharp.XFeatures2D.SURF.Create(threshold,4,3,true,true))
{
surf.DetectAndCompute(matSrc,null,outkeyPointsSrc,matSrcRet);
surf.DetectAndCompute(matTo,null,outkeyPointsTo,matToRet);
}using(varflnMatcher=newOpenCvSharp.FlannBasedMatcher())
{varmatches=flnMatcher.Match(matSrcRet,matToRet);//求最小最大间隔doubleminDistance=1000;//反向迫临doublemaxDistance=0;for(inti=0;i<matSrcRet.Rows;i++)
{doubledistance=matches[i].Distance;if(distance>maxDistance)
{
maxDistance=distance;
}if(distance<minDistance)
{
minDistance=distance;
}
}
Console.WriteLine($”maxdistance:{maxDistance}”);
Console.WriteLine($”mindistance:{minDistance}”);varpointsSrc=newList();varpointsDst=newList();//筛选较好的匹配点vargoodMatches=newList();for(inti=0;i<matSrcRet.Rows;i++)
{doubledistance=matches[i].Distance;if(distance<Math.Max(minDistance*2,0.02))
{
pointsSrc.Add(keyPointsSrc[matches[i].QueryIdx].Pt);
pointsDst.Add(keyPointsTo[matches[i].TrainIdx].Pt);//间隔小于范围的压入新的DMatchgoodMatches.Add(matches[i]);
}
}varoutMat=newMat();//算法RANSAC对匹配的成果做过滤varpSrc=pointsSrc.ConvertAll(Point2fToPoint2d);varpDst=pointsDst.ConvertAll(Point2fToPoint2d);varoutMask=newMat();//假如原始的匹配成果为空,则越过过滤步骤if(pSrc.Count>0&&pDst.Count>0)
Cv2.FindHomography(pSrc,pDst,HomographyMethods.Ransac,mask:outMask);//假如经过RANSAC处理后的匹配点大于10个,才应用过滤.不然运用原始的匹配点成果(匹配点过少的时分经过RANSAC处理后,可能会得到0个匹配点的成果).if(outMask.Rows>10)
{byte[]maskBytes=newbyte[outMask.Rows*outMask.Cols];
outMask.GetArray(0,0,maskBytes);
Cv2.DrawMatches(matSrc,keyPointsSrc,matTo,keyPointsTo,goodMatches,outMat,matchesMask:maskBytes,flags:DrawMatchesFlags.NotDrawSinglePoints);
}elseCv2.DrawMatches(matSrc,keyPointsSrc,matTo,keyPointsTo,goodMatches,outMat,flags:DrawMatchesFlags.NotDrawSinglePoints);returnOpenCvSharp.Extensions.BitmapConverter.ToBitmap(outMat);
}
}
}
模板匹配
publicstaticSystem.Drawing.PointFindPicFromImage(BitmapimgSrc,BitmapimgSub,doublethreshold=0.9)
{
OpenCvSharp.MatsrcMat=null;
OpenCvSharp.MatdstMat=null;
OpenCvSharp.OutputArrayoutArray=null;try{
srcMat=imgSrc.ToMat();
dstMat=imgSub.ToMat();
outArray=OpenCvSharp.OutputArray.Create(srcMat);
OpenCvSharp.Cv2.MatchTemplate(srcMat,dstMat,outArray,Common.templateMatchModes);doubleminValue,maxValue;
OpenCvSharp.Pointlocation,point;
OpenCvSharp.Cv2.MinMaxLoc(OpenCvSharp.InputArray.Create(outArray.GetMat()),outminValue,outmaxValue,outlocation,outpoint);
Console.WriteLine(maxValue);if(maxValue>=threshold)returnnewSystem.Drawing.Point(point.X,point.Y);returnSystem.Drawing.Point.Empty;
}catch(Exceptionex)
{returnSystem.Drawing.Point.Empty;
}finally{if(srcMat!=null)
srcMat.Dispose();if(dstMat!=null)
dstMat.Dispose();if(outArray!=null)
outArray.Dispose();
}
}

© 版权声明
好牛新坐标
版权声明:
1、IT大王遵守相关法律法规,由于本站资源全部来源于网络程序/投稿,故资源量太大无法一一准确核实资源侵权的真实性;
2、出于传递信息之目的,故IT大王可能会误刊发损害或影响您的合法权益,请您积极与我们联系处理(所有内容不代表本站观点与立场);
3、因时间、精力有限,我们无法一一核实每一条消息的真实性,但我们会在发布之前尽最大努力来核实这些信息;
4、无论出于何种目的要求本站删除内容,您均需要提供根据国家版权局发布的示范格式
《要求删除或断开链接侵权网络内容的通知》:https://itdw.cn/ziliao/sfgs.pdf,
国家知识产权局《要求删除或断开链接侵权网络内容的通知》填写说明: http://www.ncac.gov.cn/chinacopyright/contents/12227/342400.shtml
未按照国家知识产权局格式通知一律不予处理;请按照此通知格式填写发至本站的邮箱 wl6@163.com

相关文章