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

C# OpenCvSharp實現(xiàn)通過特征點匹配圖片

 更新時間:2023年11月09日 10:37:01   作者:天天代碼碼天天  
這篇文章主要為大家詳細介紹了C#如何結(jié)合OpenCVSharp4實現(xiàn)通過特征點匹配圖片,文中的示例代碼簡潔易懂,具有一定的學習價值,需要的小伙伴可以參考下

SIFT匹配

SURF匹配

項目

代碼

using OpenCvSharp;
using OpenCvSharp.Extensions;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using static System.Net.Mime.MediaTypeNames;
 
namespace OpenCvSharp_Demo
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
 
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
 
            Mat matSrc = new Mat("1.jpg");
            Mat matTo = new Mat("2.jpg");
 
            var outMat = MatchPicBySift(matSrc, matTo);
 
            pictureBox2.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(outMat);
 
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            Mat matSrc = new Mat("1.jpg");
            Mat matTo = new Mat("2.jpg");
 
            var outMat = MatchPicBySurf(matSrc, matTo, 10);
 
            pictureBox2.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(outMat);
        }
 
        public Point2d Point2fToPoint2d(Point2f point) => new Point2d((double)point.X, (double)point.Y);
 
        public Mat MatchPicBySift(Mat matSrc, Mat matTo)
        {
            using (Mat matSrcRet = new Mat())
            using (Mat matToRet = new Mat())
            {
                KeyPoint[] keyPointsSrc, keyPointsTo;
                using (var sift = OpenCvSharp.Features2D.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對匹配的結(jié)果做過濾
                    var pSrc = pointsSrc.ConvertAll(Point2fToPoint2d);
                    var pDst = pointsDst.ConvertAll(Point2fToPoint2d);
                    var outMask = new Mat();
                    // 如果原始的匹配結(jié)果為空, 則跳過過濾步驟
                    if (pSrc.Count > 0 && pDst.Count > 0)
                        Cv2.FindHomography(pSrc, pDst, HomographyMethods.Ransac, mask: outMask);
                    // 如果通過RANSAC處理后的匹配點大于10個,才應用過濾. 否則使用原始的匹配點結(jié)果(匹配點過少的時候通過RANSAC處理后,可能會得到0個匹配點的結(jié)果).
                    if (outMask.Rows > 10)
                    {
                        byte[] maskBytes = new byte[outMask.Rows * outMask.Cols];
                        outMask.GetArray(out 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 outMat;
                }
            }
        }
 
        public Mat MatchPicBySurf(Mat matSrc, Mat matTo, double threshold = 400)
        {
            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>();
                    //篩選較好的匹配點
                    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對匹配的結(jié)果做過濾
                    var pSrc = pointsSrc.ConvertAll(Point2fToPoint2d);
                    var pDst = pointsDst.ConvertAll(Point2fToPoint2d);
                    var outMask = new Mat();
                    // 如果原始的匹配結(jié)果為空, 則跳過過濾步驟
                    if (pSrc.Count > 0 && pDst.Count > 0)
                        Cv2.FindHomography(pSrc, pDst, HomographyMethods.Ransac, mask: outMask);
                    // 如果通過RANSAC處理后的匹配點大于10個,才應用過濾. 否則使用原始的匹配點結(jié)果(匹配點過少的時候通過RANSAC處理后,可能會得到0個匹配點的結(jié)果).
                    if (outMask.Rows > 10)
                    {
                        byte[] maskBytes = new byte[outMask.Rows * outMask.Cols];
                        outMask.GetArray(out 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 outMat;
                }
            }
        }
 
    }
}

到此這篇關(guān)于C# OpenCvSharp實現(xiàn)通過特征點匹配圖片的文章就介紹到這了,更多相關(guān)C# OpenCvSharp匹配圖片內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C#實現(xiàn)的pdf生成圖片文字水印類實例

    C#實現(xiàn)的pdf生成圖片文字水印類實例

    這篇文章主要介紹了C#實現(xiàn)的pdf生成圖片文字水印類,結(jié)合完整實例形式分析了C#針對pdf文件的創(chuàng)建、添加文字、水印等相關(guān)操作技巧,需要的朋友可以參考下
    2017-09-09
  • C#泛型編程介紹

    C#泛型編程介紹

    泛型:通過參數(shù)化類型來實現(xiàn)在同一份代碼上操作多種數(shù)據(jù)類型。利用“參數(shù)化類型”將類型抽象化,從而實現(xiàn)靈活的復用
    2013-09-09
  • C#對集合進行排序

    C#對集合進行排序

    這篇文章介紹了C#對集合進行排序的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • C#實現(xiàn)偽裝文件夾功能

    C#實現(xiàn)偽裝文件夾功能

    這篇文章主要為大家詳細介紹了如何利用C#實現(xiàn)偽裝文件夾的功能,文中的示例代碼講解詳細,對我們學習C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下
    2022-12-12
  • C#實現(xiàn)SMTP服務發(fā)送郵件的示例代碼

    C#實現(xiàn)SMTP服務發(fā)送郵件的示例代碼

    這篇文章主要為大家詳細介紹了如何利用C#實現(xiàn)SMTP服務發(fā)送郵件的功能,文中的示例代碼講解詳細,對我們學習C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下
    2022-12-12
  • WinForm中KeyDown,KeyPress和KeyUp的順序與區(qū)別解析

    WinForm中KeyDown,KeyPress和KeyUp的順序與區(qū)別解析

    這篇文章主要介紹了WinForm中KeyDown,KeyPress和KeyUp的順序與區(qū)別解析,對C#初學者來說很有學習借鑒價值,需要的朋友可以參考下
    2014-08-08
  • C#使用iTextSharp操作PDF

    C#使用iTextSharp操作PDF

    這篇文章介紹了C#使用iTextSharp操作PDF的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • C#處理TCP數(shù)據(jù)的方法詳解

    C#處理TCP數(shù)據(jù)的方法詳解

    Tcp是一個面向連接的流數(shù)據(jù)傳輸協(xié)議,用人話說就是傳輸是一個已經(jīng)建立好連接的管道,數(shù)據(jù)都在管道里像流水一樣流淌到對端,那么數(shù)據(jù)必然存在幾個問題,比如數(shù)據(jù)如何持續(xù)的讀取,數(shù)據(jù)包的邊界等,本文給大家介紹了C#處理TCP數(shù)據(jù)的方法,需要的朋友可以參考下
    2024-06-06
  • C#刪除文件目錄或文件的解決方法

    C#刪除文件目錄或文件的解決方法

    本篇文章是對C#中如何刪除文件目錄或文件的解決方法進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • Unity3d實現(xiàn)Flappy Bird游戲

    Unity3d實現(xiàn)Flappy Bird游戲

    這篇文章主要為大家詳細介紹了Unity3d實現(xiàn)Flappy Bird游戲,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12

最新評論

称多县| 新疆| 勃利县| 阿克苏市| 石嘴山市| 礼泉县| 徐州市| 盐山县| 游戏| 筠连县| 德阳市| 石城县| 宁武县| 安西县| 眉山市| 元氏县| 迁安市| 察隅县| 临江市| 太康县| 依兰县| 罗田县| 上栗县| 泗水县| 涟源市| 阿坝县| 文昌市| 梓潼县| 武陟县| 庄浪县| 莱芜市| 家居| 上思县| 太白县| 海伦市| 苗栗县| 南充市| 嘉鱼县| 佛坪县| 五华县| 壶关县|