成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C# 使用OpenCvSharp實現模板差異檢測

開發 前端
本文詳細介紹了使用OpenCvSharp實現模板差異檢測的完整方案。通過合適的圖像處理和計算機視覺技術,可以有效地檢測出兩張圖像之間的差異。

本文將詳細介紹如何使用OpenCvSharp來實現模板圖像與待檢測圖像之間的差異檢測。這種技術常用于產品質量檢測、PCB板檢測等場景。上面的示意圖展示了一個簡單的例子,左邊是完整的模板圖像,右邊是缺少部分元件的待檢測圖像。

環境準備

// 需要安裝的NuGet包
// Install-Package OpenCvSharp4
// Install-Package OpenCvSharp4.runtime.win

using OpenCvSharp;
using System;
using System.Collections.Generic;

完整代碼實現

using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OpenCv082902
{
    public class TemplateDifferenceDetector
    {
        /// <summary>  
        /// 檢測結果類  
        /// </summary>  
        public class DetectionResult
        {
            public Point Location { get; set; }
            public double Difference { get; set; }
            public Rect Region { get; set; }
        }

        /// <summary>  
        /// PCB圖像差異檢測的配置參數  
        /// </summary>  
        public class DetectionConfig
        {
            public double Threshold { get; set; } = 0.5;          // 差異閾值  
            public double MinArea { get; set; } = 10;            // 最小檢測面積  
            public int BlurSize { get; set; } = 3;               // 高斯模糊核大小  
            public int MorphSize { get; set; } = 3;              // 形態學操作核大小  
            public bool EnableHistEqualization { get; set; } = true;  // 是否啟用直方圖均衡化  
            public bool EnableNoiseReduction { get; set; } = true;    // 是否啟用降噪  
        }

        /// <summary>  
        /// 執行差異檢測  
        /// </summary>  
        /// <param name="templatePath">模板圖像路徑</param>  
        /// <param name="targetPath">待檢測圖像路徑</param>  
        /// <param name="config">檢測配置參數</param>  
        /// <returns>檢測結果列表</returns>  
        public static List<DetectionResult> DetectDifferences(
            string templatePath,
            string targetPath,
            DetectionConfig config = null)
        {
            config ??= new DetectionConfig();

            // 讀取圖像  
            using var template = Cv2.ImRead(templatePath);
            using var target = Cv2.ImRead(targetPath);

            // 確保圖像成功加載  
            if (template.Empty() || target.Empty())
            {
                throw new Exception("無法加載圖像");
            }

            // 預處理圖像  
            using var processedTemplate = PreprocessImage(template, config);
            using var processedTarget = PreprocessImage(target, config);

            // 計算差異圖  
            using var diff = new Mat();
            Cv2.Absdiff(processedTemplate, processedTarget, diff);

            // 應用閾值處理  
            using var thresholdMat = new Mat();
            Cv2.Threshold(diff, thresholdMat, config.Threshold * 255, 255, ThresholdTypes.Binary);

            // 應用形態學操作來減少噪聲  
            if (config.EnableNoiseReduction)
            {
                var kernel = Cv2.GetStructuringElement(
                    MorphShapes.Rect,
                    new Size(config.MorphSize, config.MorphSize)
                );

                Cv2.MorphologyEx(
                    thresholdMat,
                    thresholdMat,
                    MorphTypes.Open,
                    kernel
                );
            }

            // 尋找輪廓  
            Cv2.FindContours(
                thresholdMat,
                out Point[][] contours,
                out HierarchyIndex[] hierarchy,
                RetrievalModes.External,
                ContourApproximationModes.ApproxSimple
            );

            // 分析差異區域  
            var results = new List<DetectionResult>();
            foreach (var contour in contours)
            {
                // 計算輪廓面積,過濾掉太小的區域  
                double area = Cv2.ContourArea(contour);
                if (area < config.MinArea)
                    continue;

                // 獲取邊界矩形  
                var boundingRect = Cv2.BoundingRect(contour);

                // 計算該區域的平均差異值  
                using var roi = new Mat(diff, boundingRect);
                Scalar meanDiff = Cv2.Mean(roi);

                results.Add(new DetectionResult
                {
                    Location = new Point(boundingRect.X, boundingRect.Y),
                    Difference = meanDiff.Val0 / 255.0, // 歸一化差異值  
                    Region = boundingRect
                });
            }

            return results;
        }

        /// <summary>  
        /// 圖像預處理  
        /// </summary>  
        private static Mat PreprocessImage(Mat input, DetectionConfig config)
        {
            // 轉換為灰度圖  
            var processed = input.CvtColor(ColorConversionCodes.BGR2GRAY);

            // 應用高斯模糊減少噪聲  
            if (config.EnableNoiseReduction)
            {
                Cv2.GaussianBlur(
                    processed,
                    processed,
                    new Size(config.BlurSize, config.BlurSize),
                    0
                );
            }

            // 直方圖均衡化增強對比度  
            if (config.EnableHistEqualization)
            {
                Cv2.EqualizeHist(processed, processed);
            }

            return processed;
        }

        /// <summary>  
        /// 可視化檢測結果  
        /// </summary>  
        public static void VisualizeResults(
            string templatePath,
            string targetPath,
            string outputPath,
            List<DetectionResult> results)
        {
            using var target = Cv2.ImRead(targetPath);
            using var output = target.Clone();

            // 在圖像上標注差異區域  
            foreach (var result in results)
            {
                // 繪制矩形框  
                Cv2.Rectangle(
                    output,
                    result.Region,
                    new Scalar(0, 0, 255), // 紅色  
                    2
                );

                // 添加差異值標注  
                string text = $"Diff: {result.Difference:F2}";
                Cv2.PutText(
                    output,
                    text,
                    new Point(result.Location.X, result.Location.Y - 5),
                    HersheyFonts.HersheySimplex,
                    0.5,
                    new Scalar(0, 0, 255),
                    1
                );
            }

            // 創建對比圖  
            using var comparison = new Mat();
            using var targetResized = target.Resize(new Size(target.Width / 2, target.Height));
            using var outputResized = output.Resize(new Size(output.Width / 2, output.Height));
            Cv2.HConcat(new[] { targetResized, outputResized }, comparison);

            // 添加標題  
            Cv2.PutText(
                comparison,
                "Original",
                new Point(target.Width / 4 - 40, 30),
                HersheyFonts.HersheySimplex,
                1,
                new Scalar(0, 255, 0),
                2
            );

            Cv2.PutText(
                comparison,
                "Detected Differences",
                new Point(target.Width * 3 / 4 - 100, 30),
                HersheyFonts.HersheySimplex,
                1,
                new Scalar(0, 255, 0),
                2
            );

            // 保存結果圖像  
            comparison.SaveImage(outputPath);

        }

        /// <summary>  
        /// 使用示例  
        /// </summary>  
        public static void Example()
        {
            var config = new DetectionConfig
            {
                Threshold = 0.3,             // 降低閾值使檢測更敏感  
                MinArea = 5,                 // 降低最小面積閾值  
                BlurSize = 3,                // 適當的模糊核大小  
                MorphSize = 2,               // 較小的形態學操作核心  
                EnableHistEqualization = true,
                EnableNoiseReduction = true
            };

            var results = DetectDifferences(
                "template.jpg",
                "target.jpg",
                config
            );

            VisualizeResults(
                "template.jpg",
                "target.jpg",
                "output.jpg",
                results
            );

            Console.WriteLine($"Found {results.Count} differences");
            foreach (var result in results)
            {
                Console.WriteLine($"Difference at ({result.Location.X}, {result.Location.Y}) " +
                                $"with difference value: {result.Difference:F2}");
            }
        }
    }
}

使用示例

using OpenCv082902;
using OpenCvSharp;
using System;
using System.Collections.Generic;

class Program
{

    static void Main(string[] args)
    {
        // 使用自定義配置  
        var config = new TemplateDifferenceDetector.DetectionConfig
        {
            Threshold = 0.3,
            MinArea = 5,
            BlurSize = 3,
            MorphSize = 2,
            EnableHistEqualization = true,
            EnableNoiseReduction = true
        };

        var results = TemplateDifferenceDetector.DetectDifferences("pcb_layout.png", "pcb_layout1.jpg", config);

        // 可視化結果  
        TemplateDifferenceDetector.VisualizeResults("pcb_layout.png", "pcb_layout1.jpg", "output.jpg", results);

        Console.ReadKey();
    }

}

圖片圖片

檢測失敗的可能原因:

  1. 圖像對齊問題 - 兩張圖像可能有微小的偏移或旋轉
  2. 閾值設置過高 - 導致小的差異被忽略
  3. 最小面積設置過大 - 導致小的差異區域被過濾
  4. 圖像質量問題 - 如噪聲、模糊等影響檢測效果

總結

本文詳細介紹了使用OpenCvSharp實現模板差異檢測的完整方案。通過合適的圖像處理和計算機視覺技術,可以有效地檢測出兩張圖像之間的差異。代碼實現了基本功能,并提供了良好的擴展性。在實際應用中,可以根據具體需求調整參數和添加其他功能。

責任編輯:武曉燕 來源: 技術老小子
相關推薦

2009-08-14 15:02:24

Service模板C#創建

2009-03-12 13:49:30

DataTemplatWPFC#

2009-08-21 10:28:21

C#異步方法C#同步方法

2009-08-19 17:00:07

C#實現PrintPa

2009-08-20 14:22:17

C#實現 Contro

2009-08-25 17:55:52

C#實現Strateg

2009-08-31 15:55:17

C#實現Strateg

2009-08-25 16:49:44

C#使用if語句

2009-08-14 15:23:10

C#使用ErrorPr

2009-08-31 16:12:02

C#使用Singlet

2009-08-19 14:26:58

C# JavaScri

2009-08-20 13:23:28

C#使用Crystal

2009-08-18 17:29:02

C#使用指針

2009-09-01 09:16:57

C#使用SharpZi

2025-04-03 07:08:05

2009-08-31 17:35:19

C#使用GDI+實現餅

2009-06-18 13:06:59

C#位運算權限管理

2009-09-01 18:29:10

C#繼承C#多態

2009-08-26 09:54:45

C#打印預覽C#打印

2009-07-15 18:25:52

ASP.NET控件數組
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人在线电影网站 | 操操操日日日 | 四季久久免费一区二区三区四区 | 香蕉久久久 | 九九亚洲 | 日韩在线精品 | 亚洲欧美日韩国产综合 | pacopacomama在线| 一区二区高清在线观看 | 久久久久久久久精 | 午夜爽爽男女免费观看hd | 色综合久 | 一区二区三区欧美在线观看 | 欧美精品一区二区三区在线播放 | 亚洲成人一区二区 | 综合激情久久 | 国产成人自拍av | 日本中文字幕一区 | 一区二区高清不卡 | 中文字幕人成人 | 日韩在线中文 | 久久久久久电影 | 日韩欧美在线视频 | av天天澡天天爽天天av | 91欧美精品成人综合在线观看 | caoporn国产精品免费公开 | 精品伊人 | 精品国产乱码久久久久久88av | 欧美精品乱码99久久影院 | 1区2区3区视频 | 亚洲综合色视频在线观看 | 国产99热 | 国产精品久久久久久婷婷天堂 | 午夜久久 | 日韩精品免费播放 | 欧美一区二区 | 日本精a在线观看 | 亚洲午夜精品一区二区三区他趣 | 91激情电影 | 人人人人干 | 99免费精品视频 |