【算法介紹】
基於YOLOv11的齒輪缺陷檢測系統,是針對齒輪製造與維護領域開發的高效自動化檢測工具。該系統依託YOLOv11目標檢測算法,利用其增強的特徵提取能力(如C3k2塊與C2PSA模塊)和優化的檢測頭設計,實現對齒輪表面缺陷的高精度識別,可精準定位“break(斷裂),lack(斷齒)與scratch(劃痕)等典型缺陷類型。
系統支持單張圖像、視頻流及實時攝像頭畫面檢測,滿足不同場景的檢測需求。數據集採用Pascal VOC與YOLO雙格式標註,涵蓋7000+張齒輪圖像,標註框總數超1.6w個,確保模型泛化能力。
系統界面基於PyQt5開發,提供直觀的操作體驗。該技術方案顯著提升了齒輪缺陷檢測效率,為製造業質量管控提供了可靠支持。
【效果展示】
【訓練數據集介紹】
數據集格式:Pascal VOC格式+YOLO格式(不包含分割路徑的txt文件,僅僅包含jpg圖片以及對應的VOC格式xml文件和yolo格式txt文件)
圖片數量(jpg文件個數):7742
標註數量(xml文件個數):7742
標註數量(txt文件個數):7742
標註類別數:3
標註類別名稱(注意yolo格式類別順序不和這個對應,而以labels文件夾classes.txt為準):["break","lack","scratch"]
每個類別標註的框數:
break 框數 = 2620
lack 框數 = 2568
scratch 框數 = 11045
總框數:16233
使用標註工具:labelImg
標註規則:對類別進行畫矩形框
重要説明:暫無
特別聲明:本數據集不對訓練的模型或者權重文件精度作任何保證,數據集只提供準確且合理標注
圖片預覽:
標註例子:
【訓練信息】
|
參數
|
值
|
|
訓練集圖片數
|
7146
|
|
驗證集圖片數
|
596
|
|
訓練map
|
98.5%
|
|
訓練精度(Precision)
|
96.9%
|
|
訓練召回率(Recall)
|
98.4%
|
【驗證集精度統計】
|
Class
|
Images
|
Instances
|
P
|
R
|
mAP50
|
mAP50-95
|
|
all
|
596
|
1329
|
0.969
|
0.984
|
0.985
|
0.702
|
|
break
|
190
|
190
|
0.997
|
1
|
0.995
|
0.689
|
|
lack
|
186
|
186
|
0.997
|
1
|
0.995
|
0.747
|
|
scratch
|
220
|
953
|
0.913
|
0.951
|
0.966
|
0.67
|
【測試環境】
windows10 x64系統 VS2019 netframework4.7.2 opencvsharp4.9.0 onnxruntime1.22.0
注意使用CPU推理,沒有使用cuda推理因此不需要電腦具有nvidia顯卡,無需安裝安裝cuda+dunn
【界面設計】
using DeploySharp.Data;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FIRC
{
public partial class Form1 : Form
{
public bool videoStart = false;//視頻停止標誌
string weightsPath = Application.StartupPath + "\\weights";//模型目錄
YoloDetector detetor = new YoloDetector();//推理引擎
public Form1()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;//線程更新控件不報錯
}
private void LoadWeightsFromDir()
{
var di = new DirectoryInfo(weightsPath);
foreach(var fi in di.GetFiles("*.onnx"))
{
comboBox1.Items.Add(fi.Name);
}
if(comboBox1.Items.Count>0)
{
comboBox1.SelectedIndex = 0;
}
else
{
tssl_show.Text = "未找到模型,請關閉程序,放入模型到weights文件夾!";
tsb_pic.Enabled = false;
tsb_video.Enabled = false;
tsb_camera.Enabled = false;
}
}
private void Form1_Load(object sender, EventArgs e)
{
LoadWeightsFromDir();//從目錄加載模型
}
public string GetResultString(DetResult[] result)
{
Dictionary<string, int> resultDict = new Dictionary<string, int>();
for (int i = 0; i < result.Length; i++)
{
if(resultDict.ContainsKey( result[i].Category) )
{
resultDict[result[i].Category]++;
}
else
{
resultDict[result[i].Category] =1;
}
}
var resultStr = "";
foreach(var item in resultDict)
{
resultStr += string.Format("{0}:{1}\r\n",item.Key,item.Value);
}
return resultStr;
}
private void tsb_pic_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
if (ofd.ShowDialog() != DialogResult.OK) return;
tssl_show.Text = "正在檢測中...";
Task.Run(() => {
var sw = new Stopwatch();
sw.Start();
Mat image = Cv2.ImRead(ofd.FileName);
detetor.SetParams(Convert.ToSingle(numericUpDown1.Value), Convert.ToSingle(numericUpDown2.Value));
var results=detetor.Inference(image);
var resultImage = detetor.DrawImage(image, results);
sw.Stop();
pb_show.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(resultImage);
tb_res.Text = GetResultString(results);
tssl_show.Text = "檢測已完成!總計耗時"+sw.Elapsed.TotalSeconds+"秒";
});
}
public void VideoProcess(string videoPath)
{
Task.Run(() => {
detetor.SetParams(Convert.ToSingle(numericUpDown1.Value), Convert.ToSingle(numericUpDown2.Value));
VideoCapture capture = new VideoCapture(videoPath);
if (!capture.IsOpened())
{
tssl_show.Text="視頻打開失敗!";
return;
}
Mat frame = new Mat();
var sw = new Stopwatch();
int fps = 0;
while (videoStart)
{
capture.Read(frame);
if (frame.Empty())
{
Console.WriteLine("data is empty!");
break;
}
sw.Start();
var results = detetor.Inference(frame);
var resultImg = detetor.DrawImage(frame,results);
sw.Stop();
fps = Convert.ToInt32(1 / sw.Elapsed.TotalSeconds);
sw.Reset();
Cv2.PutText(resultImg, "FPS=" + fps, new OpenCvSharp.Point(30, 30), HersheyFonts.HersheyComplex, 1.0, new Scalar(255, 0, 0), 3);
//顯示結果
pb_show.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(resultImg);
tb_res.Text = GetResultString(results);
Thread.Sleep(5);
}
capture.Release();
pb_show.Image = null;
tssl_show.Text = "視頻已停止!";
tsb_video.Text = "選擇視頻";
});
}
public void CameraProcess(int cameraIndex=0)
{
Task.Run(() => {
detetor.SetParams(Convert.ToSingle(numericUpDown1.Value), Convert.ToSingle(numericUpDown2.Value));
VideoCapture capture = new VideoCapture(cameraIndex);
if (!capture.IsOpened())
{
tssl_show.Text = "攝像頭打開失敗!";
return;
}
Mat frame = new Mat();
var sw = new Stopwatch();
int fps = 0;
while (videoStart)
{
capture.Read(frame);
if (frame.Empty())
{
Console.WriteLine("data is empty!");
break;
}
sw.Start();
var results = detetor.Inference(frame);
var resultImg = detetor.DrawImage(frame, results);
sw.Stop();
fps = Convert.ToInt32(1 / sw.Elapsed.TotalSeconds);
sw.Reset();
Cv2.PutText(resultImg, "FPS=" + fps, new OpenCvSharp.Point(30, 30), HersheyFonts.HersheyComplex, 1.0, new Scalar(255, 0, 0), 3);
//顯示結果
pb_show.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(resultImg);
tb_res.Text = GetResultString(results);
Thread.Sleep(5);
}
capture.Release();
pb_show.Image = null;
tssl_show.Text = "攝像頭已停止!";
tsb_camera.Text = "打開攝像頭";
});
}
private void tsb_video_Click(object sender, EventArgs e)
{
if(tsb_video.Text=="選擇視頻")
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "視頻文件(*.*)|*.mp4;*.avi";
if (ofd.ShowDialog() != DialogResult.OK) return;
videoStart = true;
VideoProcess(ofd.FileName);
tsb_video.Text = "停止";
tssl_show.Text = "視頻正在檢測中...";
}
else
{
videoStart = false;
}
}
private void tsb_camera_Click(object sender, EventArgs e)
{
if (tsb_camera.Text == "打開攝像頭")
{
videoStart = true;
CameraProcess(0);
tsb_camera.Text = "停止";
tssl_show.Text = "攝像頭正在檢測中...";
}
else
{
videoStart = false;
}
}
private void tsb_exit_Click(object sender, EventArgs e)
{
videoStart = false;
this.Close();
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
numericUpDown1.Value = Convert.ToDecimal(trackBar1.Value / 100.0f);
}
private void trackBar2_Scroll(object sender, EventArgs e)
{
numericUpDown2.Value = Convert.ToDecimal(trackBar2.Value / 100.0f);
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
trackBar1.Value = (int)(Convert.ToSingle(numericUpDown1.Value) * 100);
}
private void numericUpDown2_ValueChanged(object sender, EventArgs e)
{
trackBar2.Value = (int)(Convert.ToSingle(numericUpDown2.Value) * 100);
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
tssl_show.Text="加載模型:"+comboBox1.Text;
detetor.LoadWeights(weightsPath+"\\"+comboBox1.Text);
tssl_show.Text = "模型加載已完成!";
}
}
}
【常用評估參數介紹】
在目標檢測任務中,評估模型的性能是至關重要的。你提到的幾個術語是評估模型性能的常用指標。下面是對這些術語的詳細解釋:
- Class :
- 這通常指的是模型被設計用來檢測的目標類別。例如,一個模型可能被訓練來檢測車輛、行人或動物等不同類別的對象。
- Images :
- 表示驗證集中的圖片數量。驗證集是用來評估模型性能的數據集,與訓練集分開,以確保評估結果的公正性。
- Instances :
- 在所有圖片中目標對象的總數。這包括了所有類別對象的總和,例如,如果驗證集包含100張圖片,每張圖片平均有5個目標對象,則Instances為500。
- P(精確度Precision) :
- 精確度是模型預測為正樣本的實例中,真正為正樣本的比例。計算公式為:Precision = TP / (TP + FP),其中TP表示真正例(True Positives),FP表示假正例(False Positives)。
- R(召回率Recall) :
- 召回率是所有真正的正樣本中被模型正確預測為正樣本的比例。計算公式為:Recall = TP / (TP + FN),其中FN表示假負例(False Negatives)。
- mAP50 :
- 表示在IoU(交併比)閾值為0.5時的平均精度(mean Average Precision)。IoU是衡量預測框和真實框重疊程度的指標。mAP是一個綜合指標,考慮了精確度和召回率,用於評估模型在不同召回率水平上的性能。在IoU=0.5時,如果預測框與真實框的重疊程度達到或超過50%,則認為該預測是正確的。
- mAP50-95 :
- 表示在IoU從0.5到0.95(間隔0.05)的範圍內,模型的平均精度。這是一個更嚴格的評估標準,要求預測框與真實框的重疊程度更高。在目標檢測任務中,更高的IoU閾值意味着模型需要更準確地定位目標對象。mAP50-95的計算考慮了從寬鬆到嚴格的多個IoU閾值,因此能夠更全面地評估模型的性能。
這些指標共同構成了評估目標檢測模型性能的重要框架。通過比較不同模型在這些指標上的表現,可以判斷哪個模型在實際應用中可能更有效。
【使用步驟】
使用步驟: (1)首先根據官方框架ultralytics安裝教程安裝好yolov11環境,並根據官方export命令將自己pt模型轉成onnx模型,然後去github倉庫futureflsl/firc-csharp-projects找到源碼 (2)使用vs2019打開sln項目,選擇x64 release並且修改一些必要的參數,比如輸入shape等,點擊運行即可查看最後效果
特別注意如果運行報錯了,請參考我的博文進行重新引用我源碼的DLL:[C#]opencvsharp報錯System.Memory,Version=4.0.1.2,Culture=neutral,PublicKeyToken=cc7b13fcd2ddd51“版本高於所引_未能加載文件或程序集“system.memory, version=4.0.1.2, culture-CSDN博客
【提供文件】
C#源碼
yolo11n.onnx模型(提供pytorch模型)
訓練的map,P,R曲線圖(在weights\results.png)
測試圖片(在test_img文件夾下面)
特別注意這裏提供訓練數據集