如何用Python讀取xml檔案後,裁剪標註圖片和擴容資料
因為想用yolov5演算法訓練自己資料集識別數字“0-9”,一開始用labeling標註了圖片,生成了大量的xml檔案。因為圖片中0,1比較多,而其他數字偏少,標註到後面,就忽略了大量的0,1。後面發現,漏標註會導致訓練時把目標識別成背景,嚴重影響演算法識別的準確性。然後,我也不想重新去標註圖片了,就想著寫個Python程式根據xml檔案,按照標註框,把目標都裁剪出來。
1、裁剪圖片
首先是根據xml檔案把對應標註圖片,按標註框,裁剪出來。我在參考部落格的基礎上實現了裁剪圖片按類別儲存到對應資料夾裡面,並在該類別下按順序編號
# 匯入模組import cv2import xml.etree.ElementTree as ETimport osfrom pathlib import Pathimport numpy as npimport random
# 原圖片、標籤檔案、裁剪圖片路徑
img_path = r'D:\yolov5-3.1\cut\c_1'
xml_path = r'D:\yolov5-3.1\cut\xml'
obj_img_path = r'D:\yolov5-3.1\cut\c_3'
# 宣告一個空字典用於儲存裁剪圖片的類別及其數量
Numpic = {}
# 把原圖片裁剪後,按類別新建資料夾儲存,並在該類別下按順序編號for img_file in os.listdir(img_path):
if img_file[-4:] in ['.png', '.jpg']: # 判斷檔案是否為圖片格式
img_filename = os.path.join(img_path, img_file) # 將圖片路徑與圖片名進行拼接
img_cv = cv2.imread(img_filename) # 讀取圖片
img_name = (os.path.splitext(img_file)[0]) # 分割出圖片名,如“000.png” 圖片名為“000”
xml_name = xml_path + '\\' + '%s.xml' % img_name # 利用標籤路徑、圖片名、xml字尾拼接出完整的標籤路徑名
if os.path.exists(xml_name): # 判斷與圖片同名的標籤是否存在,因為圖片不一定每張都打標
root = ET.parse(xml_name).getroot() # 利用ET讀取xml檔案
for obj in root.iter('object'): # 遍歷所有目標框
name = obj.find('name').text # 獲取目標框名稱,即label名
xmlbox = obj.find('bndbox') # 找到框目標
x0 = xmlbox.find('xmin').text # 將框目標的四個頂點座標取出
y0 = xmlbox.find('ymin').text
x1 = xmlbox.find('xmax').text
y1 = xmlbox.find('ymax').text
obj_img = img_cv[int(y0):int(y1), int(x0):int(x1)] # cv2裁剪出目標框中的圖片
Numpic.setdefault(name, 0) # 判斷字典中有無當前name對應的類別,無則新建
Numpic[name] += 1 # 當前類別對應數量 + 1
my_file = Path(obj_img_path + '\\' + name) # 判斷當前name對應的類別有無資料夾
if 1 - my_file.is_dir(): # 無則新建
os.mkdir(obj_img_path + '\\' + str(name))
cv2.imwrite(obj_img_path + '\\' + name + '\\' + '%04d' % (Numpic[name]) + '.jpg',
obj_img) # 儲存裁剪圖片,圖片命名4位,不足補0
2、圖片擴容
只是把標註框裁剪出來,跟單網還會有一個問題就是,每個類別的數量不一致,0,1的圖片多,其他數字少,作為訓練集可能不太好。我想,要是每個類別的圖片數量都一致就好了。於是我繼續把裁剪圖片進行擴容,這裡只是透過給圖片增加噪點來擴容。
# 新建一個圖片加噪點的函式
def random_noise(image,noise_num):
img_noiseimg = cv2.imread(image) # 讀取圖片
ows, cols, chn = img_noise.shape
for i in range(noise_num):
x = np.random.randint(0, rows)#隨機生成指定範圍的整數
y = np.random.randint(0, cols)
img_noise[x, y, :] = 0 # 0代表黑色,255代表白色
return img_noise
# 圖片擴容
max_Numpic = max(Numpic.values()) # 提取裁剪圖片中,類別下數量最大值for name in Numpic:# 遍歷每一個類別
for i in range (Numpic[name] + 1, max_Numpic + 1):# 把其餘類別的圖片數量擴充到,與數量值最大的類別相等(我的資料集裡面“0”這個類別數量是最多的)
Noisenum = random.randint(1, 20)# 生成隨機的噪點數
Num = random.randint(1, Numpic[name])# 隨機選擇該類別下已存在的一個圖片
Noicepic = random_noise(obj_img_path + '\\' + name + '\\' + '%04d' % Num + '.jpg', Noisenum)# 給圖片加噪點
cv2.imwrite(obj_img_path + '\\' + name + '\\' + '%04d' % (i) + '.jpg', Noicepic)# 儲存圖片
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69946337/viewspace-2745835/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 如何用python分析xml獲取資料?PythonXML
- 利用html5 file api讀取本地檔案(如圖片、PDF等)HTMLAPI
- QDomDocument 讀取和編輯xml檔案XML
- 03 #### 讀取靜態檔案-圖片
- php獲取xml檔案內容PHPXML
- C#讀取Xml檔案C#XML
- Java系列:讀取XML檔案JavaXML
- python中按照資料夾中檔案的排列順序讀取檔案內容Python
- Java 圖片裁剪,擷取Java
- Python批次裁剪圖片Python
- 如何用Python讀取開放資料?Python
- phpSpreadsheet 讀取圖片並另存為檔案PHP
- python讀取兩個excel資料檔案輸出整理好以後的excel資料檔案PythonExcel
- 呼叫系統檔案管理器選擇圖片,呼叫系統裁剪AIP對圖片處理,顯示裁剪之後的圖片...AI
- labelme標註後的圖片切成小圖和小jsonJSON
- FileReader()讀取檔案、圖片上傳預覽
- python讀取json格式的標註PythonJSON
- 讀取資料夾檔案
- python檔案建立、讀取和寫入Python
- phpSpreadsheet Artisan command 讀取圖片並另存為檔案PHP
- pandas讀取csv檔案資料並使用matplotlib畫折線圖和餅圖
- java檔案相關(檔案追加內容、檔案內容清空、檔案內容讀取)Java
- mybatis讀取properties檔案內容MyBatis
- Java 獲取Word批註所標記的文字和圖片Java
- 使用yaml檔案讀取資料YAML
- python讀取大檔案Python
- python小白檔案讀取Python
- python 讀取文字檔案Python
- 在讀取資料時拼接圖片域名
- 【Python標準庫:fileinput】優雅的讀取檔案Python
- python opencv讀取網路圖片PythonOpenCV
- python 裁剪圖片;位深度不變Python
- python實現修改xml檔案內容詳解PythonXML
- vue專案新增圖片裁剪元件Vue元件
- [work] python讀取txt檔案最後一行Python
- 用Python寫一個圖片標註工具Python
- 怎麼裁剪圖片?PerfectlyClear Complete裁剪圖片的方法
- python如何讀取大檔案Python