日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于YOLOv5的PCB板缺陷检测

發布時間:2024/1/1 编程问答 66 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于YOLOv5的PCB板缺陷检测 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、數據集介紹

印刷電路板(PCB)瑕疵數據集:數據下載鏈接,是一個公共的合成PCB數據集,由北京大學發布,其中包含1386張圖像以及6種缺陷(缺失孔,鼠標咬傷,開路,短路,雜散,偽銅),用于檢測,分類和配準任務。選取其中445張圖像進行了訓練(下載了別人的)。

數據樣本示例:

二、環境配置

1、github官網下載yolov5源碼:https://github.com/ultralytics/yolov5

2、Anaconda安裝(省略)

3、創建新的環境(python=3.6就行)

4、安裝pytorch:https://pytorch.org/get-started/previous-versions/

文章安裝的是pytorch1.7版本

pip install torch==1.7.1+cu110 torchvision==0.8.2+cu110 torchaudio==0.7.2 -f https://download.pytorch.org/whl/torch_stable.html

5、根據下載的yolov5中的requirements.txt進行安裝(缺啥補啥)
【注意:具體安裝以yolov5的readme.md為主!】

進入文件夾cd …/yolov5-master

pip install -r requirements.txt

三、構建訓練數據集

1、先構建數據集文件夾

格式如下(官網下載的PCB數據可能是按照缺陷類劃分文件夾的,需要手段復制到Annotations等文件夾中):

├── data │ ├── Annotations 進行 detection 任務時的標簽文件,xml 形式,文件名與圖片名一一對應 │ ├── images 存放 .jpg 格式的圖片文件 │ ├── ImageSets 存放的是分類和檢測的數據集分割文件,包含 train.txt,val.txt ,trainval.txt,test.txt │ ├── labels 存放label標注信息的txt文件,與圖片一一對應├── ImageSets(train,val,test建議按照811比例劃分) │ ├── train.txt 寫著用于訓練的圖片名稱 │ ├── val.txt 寫著用于驗證的圖片名稱 │ ├── trainval.txt train與val的合集 │ ├── test.txt 寫著用于測試的圖片名稱

2、訓練數據生成,分為兩個代碼(訓練集劃分代碼與用于yolo訓練的txt格式代碼)

(1)訓練集劃分代碼

用途:主要是將數據集分類成訓練數據集和測試數據集,默認train,val,test按照比例進行隨機分類,運行后ImagesSets文件夾中會出現四個文件,主要是生成的訓練數據集和測試數據集的圖片名稱,如下圖。同時data目錄下也會出現這四個文件,內容是訓練數據集和測試數據集的圖片路徑。

import os import randomtrainval_percent = 0.9 train_percent = 0.9 xmlfilepath = 'D:\\Dataset\\PCB_dataset\\data\\Annotations' txtsavepath = 'D:\\Dataset\\PCB_dataset\\data\\ImageSets' total_xml = os.listdir(xmlfilepath)num = len(total_xml) list = range(num) tv = int(num * trainval_percent) tr = int(tv * train_percent) trainval = random.sample(list, tv) train = random.sample(trainval, tr)ftrainval = open('D:\\Dataset\\PCB_dataset\\data\\ImageSets\\trainval.txt', 'w') ftest = open('D:\\Dataset\\PCB_dataset\\data\\ImageSets\\test.txt', 'w') ftrain = open('D:\\Dataset\\PCB_dataset\\data\\ImageSets\\train.txt', 'w') fval = open('D:\\Dataset\\PCB_dataset\\data\\ImageSets\\val.txt', 'w')for i in list:name = total_xml[i][:-4] + '\n'if i in trainval:ftrainval.write(name)if i in train:ftrain.write(name)else:fval.write(name)else:ftest.write(name)ftrainval.close() ftrain.close() fval.close() ftest.close()

(b)用于yolo訓練的txt格式代碼

用途:主要是將圖片數據集標注后的xml文件中的標注信息讀取出來并寫入txt文件,運行后在labels文件夾中出現所有圖片數據集的標注信息

# xml解析包import xml.etree.ElementTree as ET import pickle import os# os.listdir() 方法用于返回指定的文件夾包含的文件或文件夾的名字的列表from os import listdir, getcwd from os.path import joinsets = ['train', 'test', 'val'] classes = ['missing_hole', 'mouse_bite', 'open_circuit', 'short', 'spur', 'spurious_copper']# 進行歸一化操作def convert(size, box): # size:(原圖w,原圖h) , box:(xmin,xmax,ymin,ymax)dw = 1./size[0] # 1/wdh = 1./size[1] # 1/hx = (box[0] + box[1])/2.0 # 物體在圖中的中心點x坐標y = (box[2] + box[3])/2.0 # 物體在圖中的中心點y坐標w = box[1] - box[0] # 物體實際像素寬度h = box[3] - box[2] # 物體實際像素高度x = x*dw # 物體中心點x的坐標比(相當于 x/原圖w)w = w*dw # 物體寬度的寬度比(相當于 w/原圖w)y = y*dh # 物體中心點y的坐標比(相當于 y/原圖h)h = h*dh # 物體寬度的寬度比(相當于 h/原圖h)return (x, y, w, h) # 返回 相對于原圖的物體中心點的x坐標比,y坐標比,寬度比,高度比,取值范圍[0-1]# year ='2012', 對應圖片的id(文件名)def convert_annotation(image_id):'''將對應文件名的xml文件轉化為label文件,xml文件包含了對應的bunding框以及圖片長款大小等信息,通過對其解析,然后進行歸一化最終讀到label文件中去,也就是說一張圖片文件對應一個xml文件,然后通過解析和歸一化,能夠將對應的信息保存到唯一一個label文件中去labal文件中的格式:calss x y w h  同時,一張圖片對應的類別有多個,所以對應的bunding的信息也有多個'''# 對應的通過year 找到相應的文件夾,并且打開相應image_id的xml文件,其對應bund文件in_file = open('D:\\Dataset\\PCB_dataset\\data\\Annotations\\%s.xml' % (image_id), encoding='utf-8')# 準備在對應的image_id 中寫入對應的label,分別為# <object-class> <x> <y> <width> <height>out_file = open('D:\\Dataset\\PCB_dataset\\data\\labels\\%s.txt' % (image_id), 'w', encoding='utf-8')# 解析xml文件tree = ET.parse(in_file)# 獲得對應的鍵值對root = tree.getroot()# 獲得圖片的尺寸大小size = root.find('size')# 如果xml內的標記為空,增加判斷條件if size != None:# 獲得寬w = int(size.find('width').text)# 獲得高h = int(size.find('height').text)# 遍歷目標objfor obj in root.iter('object'):# 獲得difficult ??difficult = obj.find('difficult').text# 獲得類別 =string 類型cls = obj.find('name').text# 如果類別不是對應在我們預定好的class文件中,或difficult==1則跳過if cls not in classes or int(difficult) == 1:continue# 通過類別名稱找到idcls_id = classes.index(cls)# 找到bndbox 對象xmlbox = obj.find('bndbox')# 獲取對應的bndbox的數組 = ['xmin','xmax','ymin','ymax']b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),float(xmlbox.find('ymax').text))print(image_id, cls, b)# 帶入進行歸一化操作# w = 寬, h = 高, b= bndbox的數組 = ['xmin','xmax','ymin','ymax']bb = convert((w, h), b)# bb 對應的是歸一化后的(x,y,w,h)# 生成 calss x y w h 在label文件中out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')# 返回當前工作目錄wd = getcwd() print(wd)for image_set in sets:'''對所有的文件數據集進行遍歷做了兩個工作:1.將所有圖片文件都遍歷一遍,并且將其所有的全路徑都寫在對應的txt文件中去,方便定位2.同時對所有的圖片文件進行解析和轉化,將其對應的bundingbox 以及類別的信息全部解析寫到label 文件中去最后再通過直接讀取文件,就能找到對應的label 信息'''# 先找labels文件夾如果不存在則創建if not os.path.exists('D:\\Dataset\\PCB_dataset\\data\\labels\\'):os.makedirs('D:\\Dataset\\PCB_dataset\\data\\labels\\')# 讀取在ImageSets/Main 中的train、test..等文件的內容# 包含對應的文件名稱image_ids = open('D:\\Dataset\\PCB_dataset\\data\\ImageSets\\%s.txt' % (image_set)).read().strip().split()# 打開對應的2012_train.txt 文件對其進行寫入準備list_file = open('D:\\Dataset\\PCB_dataset\\data\\%s.txt' % (image_set), 'w')# 將對應的文件_id以及全路徑寫進去并換行for image_id in image_ids:list_file.write('D:\\Dataset\\PCB_dataset\\data\\images\\%s.jpg\n' % (image_id))# 調用 year = 年份 image_id = 對應的文件名_idconvert_annotation(image_id)# 關閉文件list_file.close()# os.system(‘comand’) 會執行括號中的命令,如果命令成功執行,這條語句返回0,否則返回1# os.system("cat 2007_train.txt 2007_val.txt 2012_train.txt 2012_val.txt > train.txt")# os.system("cat 2007_train.txt 2007_val.txt 2007_test.txt 2012_train.txt 2012_val.txt > train.all.txt")

label文件夾中某文件內容如下:

四、修改配置文件

1、數據集方面:…\yolov5-master\data文件夾中,新建一個yaml文件,內容設置如下:

train: D:\\Dataset\\PCB_dataset\\data\\train.txt val: D:\\Dataset\\PCB_dataset\\data\\val.txt test: D:\\Dataset\\PCB_dataset\\data\\test.txt # Classesnc: 6 # number of classes names: [ 'missing_hole', 'mouse_bite', 'open_circuit', 'short', 'spur', 'spurious_copper' ] # class names

注意:路徑,類別、標簽名字(與標注文件中一致)

2、網絡參數方面:…\yolov5-master\model文件夾中,對yolov5s.yaml(根據自己選擇的模型而定)文件內容修改。

# Parametersnc: 6 # number of classes depth_multiple: 0.33 # model depth multiple width_multiple: 0.50 # layer channel multiple

更改其中的nc即標簽類別數目。

3、trian.py修改

主要用到的幾個參數:–weights,–cfg,–data,–epochs,–batch-size,–img-size,–project,-workers

重點注意:–weights,–cfg,–data,其他的默認即可(batch_size,workers根據自己電腦屬性進行設置)。

我的–weights,–cfg,–data設置如下:

parser.add_argument('--weights', type=str, default='yolov5s.pt', help='initial weights path')parser.add_argument('--cfg', type=str, default='models/yolov5s.yaml', help='model.yaml path')parser.add_argument('--data', type=str, default='data/PCB.yaml', help='dataset.yaml path')

五、訓練及tensorboard可視化

1、訓練

兩種方式:pycharm中運行或者終端cmd運行(看個人喜好)

2、訓練過程可視化

啰嗦一句:yolov5-master文件夾中一個runs文件夾,其中有檢測結果和訓練結果,如…\runs\train\exp\results.txt中保存了每個epoch訓練信息,如下所示(第一排屬性是我補的):

可視化操作:

a、打開一個新的終端,激活環境
【注意:使用tensorboard不需要安裝tensorflow,直接pip install xxx安裝了即可使用,yolov5安裝文檔會通過pip install -r requirements.txt自己安裝上,若沒有再嘗試單獨裝!】

b、cd …\yolov5-mater

c、tensorboard --logdir=runs或者python -m tensorboard.main --logdir=runs(我的前一種報錯了,換的后一種才行)

d、復制其中的網址,去瀏覽器中打開(推薦谷歌)

e、可視化結果如下(能夠邊訓練邊觀察):

3、在GTX2070super8G顯卡訓練結果如下(batch_size=32,workers=4):

4、訓練權重在…\runs\train\exp\weights文件夾中,有兩個權重文件best.pt與last.pt(一個最好的epoch,一個最后的epoch),其他訓練結果和訓練過程可視化結果也能在exp文件夾中找到(真為yolov5作者點贊)

注意:可能…\runs\train文件夾中會有多個exp文件,如exp1,exp2等,這是代表每一次新的訓練。

六、效果測試

在CMD終端運行:

python detect.py --source ..\01_short_02.jpg --weights ..\runs\train\exp24\weights\best.pt

測試結果如下(好像效果不咋地,可以更換其他yolov5系列的網絡試試,或者聚類重選anchor):

注:在pycharm中運行檢測,只需更改train.py中的def parse_opt()函數中的–source與–weights即可。

七、遇到的BUG

1、UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0xaf in position

問題:文件保存時編碼類型原因,這里只支持encoding=‘UTF-8’

解決措施參考:https://blog.csdn.net/qq_35034711/article/details/108448465

2、測試torchhub時報錯

解決:降低了下requests版本就可以了

3、tensorboard --logdir logs Fatal error in launcher: Unable to create process using…

解決:logdir定位錯誤,另一個方法可以使用python -m tensorboard.main --logdir logs

參考:https://blog.csdn.net/Aa545620073/article/details/89374112

八、測試下torchhub(只需要幾行代碼就能完成檢測)

# ValueError: check_hostname requires server_hostname 請降低requests版本,這里requests-2.21.0import torch# Model model = torch.hub.load('ultralytics/yolov5', 'yolov5s') # or yolov5m, yolov5x, custom# Images img = 'https://ultralytics.com/images/zidane.jpg' # or file, PIL, OpenCV, numpy, multiple# Inference results = model(img)# Results results.print() # or .show(), .save(), .crop(), .pandas(), etc. # results.show()

PCB訓練數據資源下載(可以直接訓練,跳過第三步):

鏈接:https://pan.baidu.com/s/1t_94ONtT6jx6RdwEvn7PMg
提取碼:zik0

代碼與訓練權重

鏈接:https://pan.baidu.com/s/1z_VTXwyxjnX-HwuvZWvQVQ
提取碼:ngcc

參考資料:

YOLOV5官網:https://github.com/ultralytics/yolov5

YOLOV5貓狗識別:https://blog.csdn.net/oJiWuXuan/article/details/107558286

YOLOV5訓練自己數據:https://blog.csdn.net/qq_36756866/article/details/109111065

總結

以上是生活随笔為你收集整理的基于YOLOv5的PCB板缺陷检测的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。