圖片預處理
首先,根據Detectron官方介紹,數據集一般為jpg格式,分辨率一般為800*600左右。
在這里我們可以photoshop批量對圖片進行處理
使用labelImg對數據集進行標注。
安裝labelImg之后,打開文件目錄,找到data文件夾下的predefined_classes.txt並打開,修改里面的內容,將自己定義的標簽名添加到下面,這樣在標注圖片的時候,就會顯示標簽供選擇。
打開labelImg
Change Save Dir 為你選擇保存XML文件的目錄,Open Dir 為你需要標注圖片的目錄。
點擊Creat RectBox 在圖片上畫框,選擇標簽的名字。
點擊Save對其進行保存,點擊Next Image選擇下一個圖片進行處理。
XML文件修改(不是必須的)
因為我后來又通過高斯模糊、加噪聲等方式對圖片進行了擴充,需要重新使用labelImg對數據集進行標注,而加入噪聲的圖片和原始圖片分辨率以及框的位置都是不變的,只有文件名需要修改,於是可以通過簡單的python腳本對xml文件進行批量修改。我的python腳本如下,僅對我的數據有效(僅供參考)。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
#修改文件夾、文件名等內容
import os
import os.path
import sys
from xml.etree.ElementTree import parse, Element
def test():
path="D:/Train_Object_Detection/Python_Rename/labelXml/"
files=os.listdir(path) #得到文件夾下所有文件名稱
#s=[]
for xmlFile in files: #遍歷文件夾
if not os.path.isdir(xmlFile): #判斷是否是文件夾,不是文件夾才打開
print(xmlFile)
pass
path="D:/Train_Object_Detection/Python_Rename/labelXml/"
newStr=os.path.join(path,xmlFile)
dom=parse(newStr) ###最核心的部分,路徑拼接,輸入的是具體路徑
root=dom.getroot()
#print root
part=xmlFile[0:6]
part1=part+sys.argv[2]+'.jpg'
newStr1='D:/Train_Object_Detection/'+part1
#root.remove(root.find('path'))
#e=Element('path')
#print root.find('path').text
root.find('folder').text=sys.argv[1]
root.find('path').text=newStr1
oldName=root.find('filename').text
root.find('filename').text=oldName[0:6]+sys.argv[2]+'.jpg'
# #打印輸出
print ('path after change')
#print n0.firstChild.data
# print '修改后的 pose'
# print p0.firstChild.data
# print '~~~~~'
dom.write(newStr, xml_declaration=True)
pass
if __name__=='__main__':
print (sys.argv[1:])
test()
(安利!!!)使用《拖把更名器》批量對文件名進行修改。
突然發現有一些別人制作的數據集不正確,在這里我也寫了一個腳本對其進行修改。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
#新建filename節點 將標記的錯誤float的數據更改為正確的int數據
import os
import os.path
import sys
from xml.etree.ElementTree import parse, Element
import xml.etree.ElementTree as ET
def test():
path="./data/"
files=os.listdir(path) #得到文件夾下所有文件名稱
for xmlFile in files: #遍歷文件夾
if not os.path.isdir(xmlFile): #判斷是否是文件夾,不是文件夾才打開
print(xmlFile)
pass
path="./data/"
newStr=os.path.join(path,xmlFile)
dom=parse(newStr)
root=dom.getroot()
part=xmlFile[0:5]
part1=part+'.jpg'
print(part1)
element= Element('filename')
element.text=part1
root.append(element)
width = root.find('size').find('width')
new_width = str(int(float(width.text))+1)
width.text= new_width
for obj in root.findall('object'):
xmin = obj.find('bndbox').find('xmin')
ymin = obj.find('bndbox').find('ymin')
xmax = obj.find('bndbox').find('xmax')
ymax = obj.find('bndbox').find('ymax')
new_xmin = str(int(float(xmin.text))+1)
new_ymin = str(int(float(ymin.text))+1)
new_xmax = str(int(float(xmax.text))+1)
new_ymax = str(int(float(ymax.text))+1)
xmin.text = new_xmin
ymin.text = new_ymin
xmax.text = new_xmax
ymax.text = new_ymax
print ('path after change')
dom.write(newStr, xml_declaration=True)
pass
if __name__=='__main__':
print (sys.argv[1:])
test()
划分數據集
根據個人設置,將數據集划分為train、val、test等
下面是一個簡單的隨機划分和批量移動文件腳本
##深度學習過程中,需要制作訓練集和驗證集、測試集。
##先把JPEG文件擴展名改為 xml,這樣就和 annotation一樣了,隨機種子可以一塊給移動了
##之后再重新改回來
import os, random, shutil
def moveFile(XMLfileDir,JPEGfileDir):
XMLpathDir = os.listdir(XMLfileDir) #取xml&圖片的原始路徑
XMLfilenumber=len(XMLpathDir)
rate=0.2 #自定義抽取圖片的比例,比方說100張抽10張,那就是0.1
picknumber=int(XMLfilenumber*rate) #按照rate比例從文件夾中取一定數量圖片
random.seed(0)
sample1 = random.sample(XMLpathDir, picknumber) #隨機選取picknumber數量的樣本圖片
random.seed(0)
print (sample1)
print ("```````````````")
for name in sample1:
shutil.move(XMLfileDir+name, XMLtarDir+name)
print (XMLfileDir+name)
shutil.move(JPEGfileDir+name, JPEGtarDir+name)
print (JPEGfileDir+name)
return
if __name__ == '__main__':
XMLfileDir = "./XML_train/" #源xml文件夾路徑
XMLtarDir = './XML_val/' #移動到新的文件夾路徑
JPEGfileDir = "./JPEG_train/" #源圖片文件夾路徑
JPEGtarDir = './JPEG_val/' #移動到新的文件夾路徑
moveFile(XMLfileDir,JPEGfileDir)