91网首页-91网页版-91网在线观看-91网站免费观看-91网站永久视频-91网站在线播放

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

【C#】OpenCvSharp實(shí)現(xiàn)PCB板拍照對(duì)比缺陷檢測詳解

admin
2025年3月1日 22:21 本文熱度 691

PCB板缺陷檢測是工業(yè)視覺檢測中的重要應(yīng)用。本文將詳細(xì)介紹如何使用OpenCvSharp實(shí)現(xiàn)PCB板的缺陷檢測,包括缺陷、斷路、短路等問題的識(shí)別。

環(huán)境準(zhǔn)備

// NuGet包引用
// Install-Package OpenCvSharp4
// Install-Package OpenCvSharp4.runtime.win
using OpenCvSharp;
using System;

完整代碼實(shí)現(xiàn)

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

namespace AppPcb
{
    publicclass PCBDefectDetection
    {

        private Mat templateImage; // 模板圖像
        private Mat testImage;     // 待測試圖像

        public PCBDefectDetection(string templatePath, string testPath)
        
{
            // 讀取圖像
            templateImage = Cv2.ImRead(templatePath, ImreadModes.Color);
            testImage = Cv2.ImRead(testPath, ImreadModes.Color);

            // 確保圖像加載成功
            if (templateImage.Empty() || testImage.Empty())
            {
                thrownew Exception("圖像加載失敗!");
            }
        }

        public void DetectDefects()
        
{
            // 1. 圖像預(yù)處理
            Mat templateGray = PreprocessImage(templateImage);
            Mat testGray = PreprocessImage(testImage);

            // 2. 圖像對(duì)齊
            Mat alignedTest = AlignImages(templateGray, testGray);

            // 3. 差異檢測
            Mat diffMask = DetectDifferences(templateGray, alignedTest);

            // 4. 缺陷分析
            AnalyzeDefects(diffMask);

            // 5. 顯示結(jié)果
            ShowResults(diffMask);
        }

        private Mat PreprocessImage(Mat input)
        
{
            Mat result = new Mat();

            // 轉(zhuǎn)換為灰度圖
            Cv2.CvtColor(input, result, ColorConversionCodes.BGR2GRAY);

            // 高斯模糊去噪
            Cv2.GaussianBlur(result, result, new Size(77), 0);

            // 自適應(yīng)二值化
            Cv2.AdaptiveThreshold(
                result,
                result,
                255,
                AdaptiveThresholdTypes.GaussianC,
                ThresholdTypes.Binary,
                13,
                2
            );

            return result;
        }

        private Mat AlignImages(Mat template, Mat test)
        
{
            // 特征點(diǎn)檢測和匹配
            var orb = ORB.Create();

            // 檢測關(guān)鍵點(diǎn)和描述符
            KeyPoint[] templateKeyPoints, testKeyPoints;
            Mat templateDescriptors = new Mat();
            Mat testDescriptors = new Mat();

            orb.DetectAndCompute(
                template,
                null,
                out templateKeyPoints,
                templateDescriptors
            );

            orb.DetectAndCompute(
                test,
                null,
                out testKeyPoints,
                testDescriptors
            );

            // 特征匹配
            var matcher = new BFMatcher(NormTypes.Hamming, crossCheck: true);
            DMatch[] matches = matcher.Match(templateDescriptors, testDescriptors);

            // 提取匹配點(diǎn)對(duì)
            Point2f[] templatePoints = matches.Select(m => templateKeyPoints[m.QueryIdx].Pt).ToArray();
            Point2f[] testPoints = matches.Select(m => testKeyPoints[m.TrainIdx].Pt).ToArray();

            // 計(jì)算變換矩陣
            Mat homography = Cv2.FindHomography(
                InputArray.Create(testPoints),
                InputArray.Create(templatePoints),
                HomographyMethods.Ransac
            );

            // 應(yīng)用變換
            Mat alignedTest = new Mat();
            Cv2.WarpPerspective(
                test,
                alignedTest,
                homography,
                template.Size()
            );

            return alignedTest;
        }

        private Mat DetectDifferences(Mat template, Mat test)
        
{
            Mat diff = new Mat();
            Mat diffMask = new Mat();

            // 計(jì)算差異
            Cv2.Absdiff(template, test, diff);

            // 二值化差異圖
            Cv2.Threshold(
                diff,
                diffMask,
                30,
                255,
                ThresholdTypes.Binary
            );

            // 形態(tài)學(xué)操作,去除噪點(diǎn)
            Mat kernel = Cv2.GetStructuringElement(
                MorphShapes.Rect,
                new Size(33)
            );

            Cv2.MorphologyEx(
                diffMask,
                diffMask,
                MorphTypes.Open,
                kernel,
                iterations: 2
            );

            return diffMask;
        }

        private void AnalyzeDefects(Mat diffMask)
        
{
            // 查找輪廓
            Point[][] contours;
            HierarchyIndex[] hierarchy;

            Cv2.FindContours(
                diffMask,
                out contours,
                out hierarchy,
                RetrievalModes.External,
                ContourApproximationModes.ApproxSimple
            );

            // 分析每個(gè)缺陷區(qū)域
            foreach (var contour in contours)
            {
                // 計(jì)算缺陷面積
                double area = Cv2.ContourArea(contour);

                // 獲取缺陷邊界框
                Rect boundingRect = Cv2.BoundingRect(contour);

                // 判斷缺陷類型
                if (area >= 20// 面積閾值可調(diào)整
                {
                    Console.WriteLine($"發(fā)現(xiàn)缺陷:");
                    Console.WriteLine($"位置: X={boundingRect.X}, Y={boundingRect.Y}");
                    Console.WriteLine($"大小: {area:F2}平方像素");

                    // 在原圖上標(biāo)記缺陷
                    Cv2.Rectangle(
                        testImage,
                        boundingRect,
                        Scalar.Red,
                        2
                    );

                    Cv2.PutText(
                        testImage,
                        $"Defect: {area:F0}px",
                        new Point(boundingRect.X, boundingRect.Y - 5),
                        HersheyFonts.HersheySimplex,
                        0.5,
                        Scalar.Red,
                        1
                    );
                }
            }
        }

        private void ShowResults(Mat diffMask)
        
{
            // 顯示結(jié)果
            using (new Window("Template", templateImage))
            using (new Window("Test Image", testImage))
            using (new Window("Differences", diffMask))
            {
                Cv2.WaitKey();
            }
        }
    }

}

?

代碼詳解

圖像預(yù)處理

高斯模糊(Gaussian Blur)

Cv2.GaussianBlur(result, result, new Size(77), 0);
  • result
    : 輸入圖像,經(jīng)過模糊處理的輸出圖像(可覆蓋)。
  • new Size(7, 7)
    : 高斯核的大小,必須是正奇數(shù)(例如:3, 5, 7 等)。越大則模糊效果越明顯。
  • 0
    : 標(biāo)準(zhǔn)差 σ。在 X 和 Y 方向上的標(biāo)準(zhǔn)差。如果設(shè)為0,函數(shù)會(huì)根據(jù)核大小自動(dòng)計(jì)算。

自適應(yīng)二值化(Adaptive Thresholding)

Cv2.AdaptiveThreshold(
    result,
    result,
    255,
    AdaptiveThresholdTypes.GaussianC,
    ThresholdTypes.Binary,
    13,
    2
);
  • result
    : 輸入圖像,經(jīng)過二值化處理的輸出圖像(可覆蓋)。
  • 255
    : 閾值的最大值。當(dāng)像素值超過該值時(shí),將其賦為最大值。
  • AdaptiveThresholdTypes.GaussianC
    : 自適應(yīng)閾值的計(jì)算方法,這里使用“Gaussian”方法來計(jì)算局部閾值。
  • ThresholdTypes.Binary
    : 閾值類型。在這里使用的是簡單的二值化(黑和白)。
  • 13
    : 領(lǐng)域大小,即考慮的鄰域像素的尺寸(必須為奇數(shù))。
  • 2
    : 從每個(gè)計(jì)算得到的閾值中減去的常量C,用于調(diào)整二值化效果。

圖像對(duì)齊

使用ORB特征檢測和匹配實(shí)現(xiàn)圖像對(duì)齊:

  1. 檢測特征點(diǎn)和描述符
  2. 特征點(diǎn)匹配
  3. 計(jì)算單應(yīng)性矩陣
  4. 透視變換實(shí)現(xiàn)圖像對(duì)齊

差異檢測

二值化差異圖(Thresholding)

Cv2.Threshold(
    diff,
    diffMask,
    30,
    255,
    ThresholdTypes.Binary
);
  • diff
    : 輸入圖像,通常是差異圖(例如兩張圖像之間的差異)。
  • diffMask
    : 輸出圖像,即二值化處理后的結(jié)果。
  • 30
    : 閾值。像素值高于此值將被賦值為最大值(255),低于此值將被賦值為0。
  • 255
    : 閾值的最大值。當(dāng)像素值超過30時(shí),輸出結(jié)果將設(shè)為255。
  • ThresholdTypes.Binary
    : 閾值類型。在這里使用的是簡單的二值化,結(jié)果只有兩種值(0和255)。

形態(tài)學(xué)操作(Morphological Operations)

Mat kernel = Cv2.GetStructuringElement(
    MorphShapes.Rect,
    new Size(33)
);
  • Cv2.GetStructuringElement
    : 用于創(chuàng)建結(jié)構(gòu)元素,用于形態(tài)學(xué)處理。
  • MorphShapes.Rect
    : 指定結(jié)構(gòu)元素的形狀為矩形(也可使用其他形狀,如橢圓或十字形)。
  • new Size(3, 3)
    : 結(jié)構(gòu)元素的大小,這里為3x3像素。
Cv2.MorphologyEx(
    diffMask,
    diffMask,
    MorphTypes.Open,
    kernel,
    iterations: 2
);
  • diffMask
    : 輸入圖像,通常是經(jīng)過二值化處理的圖像。
  • diffMask
    : 輸出圖像,表示形態(tài)學(xué)處理后的結(jié)果(可覆蓋)。
  • MorphTypes.Open
    : 形態(tài)學(xué)運(yùn)算類型為開運(yùn)算(去除小物體的噪點(diǎn))。
  • kernel
    : 用于形態(tài)學(xué)操作的結(jié)構(gòu)元素。
  • iterations: 2
    : 操作的迭代次數(shù)。設(shè)置為2意味著將在圖像上執(zhí)行兩次開運(yùn)算。

缺陷分析

分析檢測到的缺陷:

  1. 輪廓檢測
  2. 計(jì)算缺陷面積
  3. 獲取缺陷位置
  4. 在原圖上標(biāo)記缺陷位置

總結(jié)

本文詳細(xì)介紹了使用OpenCvSharp實(shí)現(xiàn)PCB板缺陷檢測的完整流程。該方法具有以下特點(diǎn):

  • 自動(dòng)化程度高
  • 檢測精度可靠
  • 代碼可擴(kuò)展性強(qiáng)
  • 實(shí)現(xiàn)相對(duì)簡單

通過調(diào)整參數(shù)和優(yōu)化算法,可以根據(jù)具體應(yīng)用場景提高檢測效果。


閱讀原文:原文鏈接


該文章在 2025/3/3 16:00:11 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲(chǔ)管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

主站蜘蛛池模板: 日韩最新无 | 精品一二三区不卡 | 国产精品官网 | 成人伦理动 | 最新热播电视剧大全 | 国产又粗又爽视频 | 日本到成人免费网站 | 乱仑图片 | 成人一区精品视频 | 精品国产高清自 | 91视频网站入口 | 区二区三区三 | 丝袜国产精品亚洲 | 91影音午夜| 日韩熟女激情中 | 福利导航视 | 国产精品美女久 | 国产精品成人免费福 | 国产又粗又 | 岛国精品在线 | 91熟女偷窥 | 国产亚洲制服免视频 | 国产精品人妖 | 欧美日韩精品福利 | 92看片淫 | 92看片| 精品日韩国产 | 成人欧美国产在线 | 欧美日韩国产伦理 | 国产a级网站免费看 | 中文字幕在线影院 | 日韩精品不卡自拍 | 91探花在线观看 | 国产精品欧美日 | 国语在线看免 | 精品91视频网站 | 日本大片免a | 91福利国 | 日韩国产精品一区 | 91九色在线观看 | 国产精品欧美福利久 |