志在指尖
用双手敲打未来

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();
}
}

未经允许不得转载:IT技术网站 » OpenCvSharp 通过特征点匹配图片
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

志在指尖 用双手敲打未来

登录/注册IT技术大全

热门IT技术

C#基础入门   SQL server数据库   系统SEO学习教程   WordPress小技巧   WordPress插件   脚本与源码下载