皮革表面劃痕檢測(cè)是質(zhì)量控制中的重要環(huán)節(jié),利用計(jì)算機(jī)視覺技術(shù)能夠快速、精準(zhǔn)地識(shí)別皮革表面的缺陷。本文將詳細(xì)講解如何通過OpenCVSharp實(shí)現(xiàn)皮革劃痕的自動(dòng)檢測(cè)。
實(shí)現(xiàn)方案
環(huán)境準(zhǔn)備
首先,確保安裝以下NuGet包:
- OpenCvSharp4
- OpenCvSharp4.Windows

完整代碼實(shí)現(xiàn)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenCvSharp;
namespace AppScratchInspection
{
publicclass LeatherScratchDetector
{
/// <summary>
/// 顯示圖像處理的每個(gè)階段
/// </summary>
/// <param name="imagePath">皮革圖像路徑</param>
public void DetectScratchWithVisualization(string imagePath)
{
// 讀取原始圖像
Mat originalImage = Cv2.ImRead(imagePath, ImreadModes.Color);
ShowImage("原始圖像", originalImage);
// 圖像預(yù)處理:轉(zhuǎn)換為灰度圖
Mat grayImage = new Mat();
Cv2.CvtColor(originalImage, grayImage, ColorConversionCodes.BGR2GRAY);
ShowImage("灰度圖", grayImage);
// 圖像去噪
Mat denoiseImage = new Mat();
Cv2.GaussianBlur(grayImage, denoiseImage, new Size(3, 3), 0);
ShowImage("去噪圖像", denoiseImage);
// 邊緣檢測(cè)(使用Canny算法)
Mat edges = new Mat();
Cv2.Canny(denoiseImage, edges, 50, 90);
ShowImage("邊緣檢測(cè)", edges);
// 形態(tài)學(xué)操作:膨脹和腐蝕,突出劃痕特征
Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(11, 11));
Mat dilatedEdges = new Mat();
Cv2.Dilate(edges, dilatedEdges, kernel, iterations: 2);
ShowImage("膨脹處理", dilatedEdges);
// 查找輪廓
Point[][] contours;
HierarchyIndex[] hierarchies;
Cv2.FindContours(dilatedEdges, out contours, out hierarchies,
RetrievalModes.External,
ContourApproximationModes.ApproxSimple);
// 過濾和分析輪廓(劃痕)
List<Point[]> scratches = new List<Point[]>();
Mat contourImage = originalImage.Clone();
foreach (var contour in contours)
{
double area = Cv2.ContourArea(contour);
// 根據(jù)面積和形狀過濾可能的劃痕
if (area > 50)
{
double perimeter = Cv2.ArcLength(contour, true);
double ratio = 4 * Math.PI * area / (perimeter * perimeter);
// 長(zhǎng)條狀特征判斷
if (ratio < 0.5)
{
scratches.Add(contour);
// 繪制每個(gè)檢測(cè)到的輪廓
Cv2.DrawContours(contourImage, new Point[][] { contour }, -1,
Scalar.Red, 2);
}
}
}
// 顯示最終結(jié)果
ShowImage("劃痕檢測(cè)結(jié)果", contourImage);
// 輸出劃痕數(shù)量
Console.WriteLine($"檢測(cè)到 {scratches.Count} 個(gè)劃痕");
}
/// <summary>
/// 封裝圖像窗口顯示方法
/// </summary>
/// <param name="windowName">窗口名稱</param>
/// <param name="image">待顯示圖像</param>
private void ShowImage(string windowName, Mat image)
{
// 調(diào)整圖像大小以適應(yīng)屏幕
Mat resizedImage = new Mat();
Cv2.Resize(image, resizedImage, new Size(640, 480));
// 顯示窗口
Cv2.ImShow(windowName, resizedImage);
// 等待按鍵
Cv2.WaitKey(1000); // 每個(gè)窗口停留1秒
}
}
}
調(diào)用
using OpenCvSharp;
namespace AppScratchInspection
{
internal class Program
{
static void Main(string[] args)
{
var detector = new LeatherScratchDetector();
detector.DetectScratchWithVisualization("example.jpeg");
// 保持最后一個(gè)窗口直到用戶關(guān)閉
Cv2.WaitKey(0);
Cv2.DestroyAllWindows();
}
}
}

Cv2.Canny 函數(shù)參數(shù)
void Cv2.Canny(Mat image, Mat edges, double threshold1, double threshold2, int apertureSize = 3, bool L2gradient = false);
參數(shù)說明
示例
在您的代碼中,您使用的參數(shù)如下:
Cv2.Canny(denoiseImage, edges, 50, 90);
這意味著:
- 任何梯度低于50的點(diǎn)將被拋棄;
- 任何梯度超過90的點(diǎn)將被標(biāo)記為邊緣;
- 凡是介于50和90之間的點(diǎn),只有當(dāng)它與一個(gè)標(biāo)記為邊緣的點(diǎn)相連時(shí),才會(huì)被視為邊緣。
注意
- 根據(jù)實(shí)際產(chǎn)品表面特征調(diào)整參數(shù)
- 光照和拍攝條件會(huì)影響檢測(cè)效果
- 建議采集大量樣本進(jìn)行算法訓(xùn)練和優(yōu)化
結(jié)語
通過OpenCVSharp,我們可以構(gòu)建一個(gè)高效的產(chǎn)品表面劃痕檢測(cè)系統(tǒng)。結(jié)合計(jì)算機(jī)視覺技術(shù)和實(shí)際工業(yè)需求,可以顯著提高產(chǎn)品質(zhì)量檢測(cè)的準(zhǔn)確性和效率。
閱讀原文:原文鏈接
該文章在 2025/3/24 17:01:33 編輯過