最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#中OpenCvSharp 通過(guò)特征點(diǎn)匹配圖片的方法

 更新時(shí)間:2019年09月03日 15:35:07   作者:StupidsCat  
這篇文章主要介紹了OpenCvSharp 通過(guò)特征點(diǎn)匹配圖片的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

現(xiàn)在的手游基本都是重復(fù)操作,一個(gè)動(dòng)作要等好久,結(jié)束之后繼續(xù)另一個(gè)動(dòng)作.很麻煩,所以動(dòng)起了自己寫一個(gè)游戲輔助的心思.

這個(gè)輔助本身沒什么難度,就是通過(guò)不斷的截圖,然后從這個(gè)截圖中找出預(yù)先截好的能代表相應(yīng)動(dòng)作的按鈕或者觸發(fā)條件的小圖.

找到之后獲取該子區(qū)域的左上角坐標(biāo),然后通過(guò)windows API調(diào)用鼠標(biāo)或者鍵盤做操作就行了.

這里面最難的也就是找圖了,因?yàn)橐珳?zhǔn)找圖,而且最好能適應(yīng)不同的分辨率下找圖,所以在模板匹配的基礎(chǔ)上,就有了SIFT和SURF的特征點(diǎn)找圖方式.

在寫的過(guò)程中查找資料,大都是C++ 或者python的, 很少有原生的C#實(shí)現(xiàn), 所以我就直接拿來(lái)翻譯過(guò)來(lái)了(稍作改動(dòng)).

SIFT算法

public static Bitmap MatchPicBySift(Bitmap imgSrc, Bitmap imgSub)
    {
      using (Mat matSrc = imgSrc.ToMat())
      using (Mat matTo = imgSub.ToMat())
      using (Mat matSrcRet = new Mat())
      using (Mat matToRet = new Mat())
      {
        KeyPoint[] keyPointsSrc, keyPointsTo;
        using (var sift = OpenCvSharp.XFeatures2D.SIFT.Create())
        {
          sift.DetectAndCompute(matSrc, null, out keyPointsSrc, matSrcRet);
          sift.DetectAndCompute(matTo, null, out keyPointsTo, matToRet);
        }
        using (var bfMatcher = new OpenCvSharp.BFMatcher())
        {
          var matches = bfMatcher.KnnMatch(matSrcRet, matToRet, k: 2);
          var pointsSrc = new List<Point2f>();
          var pointsDst = new List<Point2f>();
          var goodMatches = new List<DMatch>();
          foreach (DMatch[] items in matches.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}");
            }
          }
          var outMat = new Mat();
          // 算法RANSAC對(duì)匹配的結(jié)果做過(guò)濾
          var pSrc = pointsSrc.ConvertAll(Point2fToPoint2d);
          var pDst = pointsDst.ConvertAll(Point2fToPoint2d);
          var outMask = new Mat();
          // 如果原始的匹配結(jié)果為空, 則跳過(guò)過(guò)濾步驟
          if (pSrc.Count > 0 && pDst.Count > 0)
            Cv2.FindHomography(pSrc, pDst, HomographyMethods.Ransac, mask: outMask);
          // 如果通過(guò)RANSAC處理后的匹配點(diǎn)大于10個(gè),才應(yīng)用過(guò)濾. 否則使用原始的匹配點(diǎn)結(jié)果(匹配點(diǎn)過(guò)少的時(shí)候通過(guò)RANSAC處理后,可能會(huì)得到0個(gè)匹配點(diǎn)的結(jié)果).
          if (outMask.Rows > 10)
          {
            byte[] maskBytes = new byte[outMask.Rows * outMask.Cols];
            outMask.GetArray(0, 0, maskBytes);
            Cv2.DrawMatches(matSrc, keyPointsSrc, matTo, keyPointsTo, goodMatches, outMat, matchesMask: maskBytes, flags: DrawMatchesFlags.NotDrawSinglePoints);
          }
          else
            Cv2.DrawMatches(matSrc, keyPointsSrc, matTo, keyPointsTo, goodMatches, outMat, flags: DrawMatchesFlags.NotDrawSinglePoints);
          return OpenCvSharp.Extensions.BitmapConverter.ToBitmap(outMat);
        }
      }
    }

SURF算法

public static Bitmap MatchPicBySurf(Bitmap imgSrc, Bitmap imgSub, double threshold = 400)
    {
      using (Mat matSrc = imgSrc.ToMat())
      using (Mat matTo = imgSub.ToMat())
      using (Mat matSrcRet = new Mat())
      using (Mat matToRet = new Mat())
      {
        KeyPoint[] keyPointsSrc, keyPointsTo;
        using (var surf = OpenCvSharp.XFeatures2D.SURF.Create(threshold,4,3,true,true))
        {
          surf.DetectAndCompute(matSrc, null, out keyPointsSrc, matSrcRet);
          surf.DetectAndCompute(matTo, null, out keyPointsTo, matToRet);
        }
        using (var flnMatcher = new OpenCvSharp.FlannBasedMatcher())
        {
          var matches = flnMatcher.Match(matSrcRet, matToRet);
          //求最小最大距離
          double minDistance = 1000;//反向逼近
          double maxDistance = 0;
          for (int i = 0; i < matSrcRet.Rows; i++)
          {
            double distance = matches[i].Distance;
            if (distance > maxDistance)
            {
              maxDistance = distance;
            }
            if (distance < minDistance)
            {
              minDistance = distance;
            }
          }
          Console.WriteLine($"max distance : {maxDistance}");
          Console.WriteLine($"min distance : {minDistance}");
          var pointsSrc = new List<Point2f>();
          var pointsDst = new List<Point2f>();
          //篩選較好的匹配點(diǎn)
          var goodMatches = new List<DMatch>();
          for (int i = 0; i < matSrcRet.Rows; i++)
          {
            double distance = 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);
              //距離小于范圍的壓入新的DMatch
              goodMatches.Add(matches[i]);
            }
          }
          var outMat = new Mat();
          // 算法RANSAC對(duì)匹配的結(jié)果做過(guò)濾
          var pSrc = pointsSrc.ConvertAll(Point2fToPoint2d);
          var pDst = pointsDst.ConvertAll(Point2fToPoint2d);
          var outMask = new Mat();
          // 如果原始的匹配結(jié)果為空, 則跳過(guò)過(guò)濾步驟
          if (pSrc.Count > 0 && pDst.Count > 0)
            Cv2.FindHomography(pSrc, pDst, HomographyMethods.Ransac, mask: outMask);
          // 如果通過(guò)RANSAC處理后的匹配點(diǎn)大于10個(gè),才應(yīng)用過(guò)濾. 否則使用原始的匹配點(diǎn)結(jié)果(匹配點(diǎn)過(guò)少的時(shí)候通過(guò)RANSAC處理后,可能會(huì)得到0個(gè)匹配點(diǎn)的結(jié)果).
          if (outMask.Rows > 10)
          {
            byte[] maskBytes = new byte[outMask.Rows * outMask.Cols];
            outMask.GetArray(0, 0, maskBytes);
            Cv2.DrawMatches(matSrc, keyPointsSrc, matTo, keyPointsTo, goodMatches, outMat, matchesMask: maskBytes, flags: DrawMatchesFlags.NotDrawSinglePoints);
          }
          else
            Cv2.DrawMatches(matSrc, keyPointsSrc, matTo, keyPointsTo, goodMatches, outMat, flags: DrawMatchesFlags.NotDrawSinglePoints);
          return OpenCvSharp.Extensions.BitmapConverter.ToBitmap(outMat);
        }
      }
    }

模板匹配

 public static System.Drawing.Point FindPicFromImage(Bitmap imgSrc, Bitmap imgSub, double threshold = 0.9)
    {
      OpenCvSharp.Mat srcMat = null;
      OpenCvSharp.Mat dstMat = null;
      OpenCvSharp.OutputArray outArray = null;
      try
      {
        srcMat = imgSrc.ToMat();
        dstMat = imgSub.ToMat();
        outArray = OpenCvSharp.OutputArray.Create(srcMat);
        OpenCvSharp.Cv2.MatchTemplate(srcMat, dstMat, outArray, Common.templateMatchModes);
        double minValue, maxValue;
        OpenCvSharp.Point location, point;
        OpenCvSharp.Cv2.MinMaxLoc(OpenCvSharp.InputArray.Create(outArray.GetMat()), out minValue, out maxValue, out location, out point);
        Console.WriteLine(maxValue);
        if (maxValue >= threshold)
          return new System.Drawing.Point(point.X, point.Y);
        return System.Drawing.Point.Empty;
      }
      catch(Exception ex)
      {
        return System.Drawing.Point.Empty;
      }
      finally
      {
        if (srcMat != null)
          srcMat.Dispose();
        if (dstMat != null)
          dstMat.Dispose();
        if (outArray != null)
          outArray.Dispose();
      }
    }

總結(jié)

以上所述是小編給大家介紹的C#中OpenCvSharp 通過(guò)特征點(diǎn)匹配圖片,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!

相關(guān)文章

  • Unity3D網(wǎng)格功能生成球體網(wǎng)格模型

    Unity3D網(wǎng)格功能生成球體網(wǎng)格模型

    這篇文章主要為大家詳細(xì)介紹了Unity3D網(wǎng)格功能生成球體網(wǎng)格模型,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • C#各種正則表達(dá)式驗(yàn)證方法整理大全

    C#各種正則表達(dá)式驗(yàn)證方法整理大全

    許多編程語(yǔ)言和工具都包含對(duì)正則表達(dá)式的支持,C#也不例外,這篇文章主要給大家介紹了關(guān)于C#各種正則表達(dá)式驗(yàn)證方法整理大全的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • C#動(dòng)態(tài)生成PictureBox并指定圖片的方法

    C#動(dòng)態(tài)生成PictureBox并指定圖片的方法

    這篇文章主要介紹了C#動(dòng)態(tài)生成PictureBox并指定圖片的方法,實(shí)例分析了C#圖形控件的動(dòng)態(tài)生成及使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • c# textbox的滾動(dòng)條總是指向最底端的簡(jiǎn)單解決方法

    c# textbox的滾動(dòng)條總是指向最底端的簡(jiǎn)單解決方法

    這篇文章主要介紹了c# textbox的滾動(dòng)條總是指向最底端的簡(jiǎn)單解決方法,需要的朋友可以參考下
    2017-11-11
  • C#中var關(guān)鍵字用法分析

    C#中var關(guān)鍵字用法分析

    這篇文章主要介紹了C#中var關(guān)鍵字用法,實(shí)例分析了C#中var關(guān)鍵字的應(yīng)用場(chǎng)合,對(duì)于.NET的學(xué)習(xí)具有一定參考價(jià)值,需要的朋友可以參考下
    2014-12-12
  • 深入理解C#之接口

    深入理解C#之接口

    這篇文章主要介紹了C#接口(Interface)用法,較為詳細(xì)的分析了C#中接口的功能、實(shí)現(xiàn)及使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2021-07-07
  • C#中Dispose和Finalize方法使用介紹

    C#中Dispose和Finalize方法使用介紹

    這篇文章介紹了C#中Dispose和Finalize方法的用法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • C#獲取HTML文本的第一張圖片與截取內(nèi)容摘要示例代碼

    C#獲取HTML文本的第一張圖片與截取內(nèi)容摘要示例代碼

    在日常web開發(fā)的時(shí)候,經(jīng)常會(huì)遇到需要獲取保存的HTML文本中的第一張圖片,并且截取內(nèi)容摘要的效果,例如織夢(mèng)的后臺(tái)添加完詳細(xì)內(nèi)容后就是自動(dòng)讀取內(nèi)容摘要,并保存第一張圖片為縮略圖,那么這篇文章跟大家分享下利用C#如何實(shí)現(xiàn),感興趣的朋友們下面來(lái)一起看看吧。
    2016-10-10
  • C# winform點(diǎn)擊生成二維碼實(shí)例代碼

    C# winform點(diǎn)擊生成二維碼實(shí)例代碼

    這篇文章主要介紹了 C# winform點(diǎn)擊生成二維碼實(shí)例代碼,需要的朋友可以參考下
    2017-04-04
  • ADO.NET實(shí)體數(shù)據(jù)模型詳細(xì)介紹

    ADO.NET實(shí)體數(shù)據(jù)模型詳細(xì)介紹

    本文將詳細(xì)介紹ADO.NET實(shí)體數(shù)據(jù)模型,下面先看看簡(jiǎn)單的單表的增刪改查操作,然后再看多表的關(guān)聯(lián)查詢,帶參數(shù)查詢等
    2012-11-11

最新評(píng)論

精河县| 通河县| 穆棱市| 岗巴县| 池州市| 南汇区| 阿坝县| 随州市| 大庆市| 孝义市| 泽普县| 凉城县| 磐安县| 新宁县| 伊吾县| 丹棱县| 南安市| 藁城市| 昆明市| 清流县| 额敏县| 宁乡县| 南岸区| 娄烦县| 芦山县| 武川县| 巴南区| 秦皇岛市| 陇西县| 潮安县| 沁阳市| 淮北市| 昂仁县| 崇文区| 南华县| 沁水县| 淳安县| 澜沧| 池州市| 吉安市| 石首市|