Faster R-CNN pytorch源碼血細胞檢測實戰(二)數據增強

Faster R-CNN pytorch源碼血細胞檢測實戰(二)數據增強

文章目錄

  • Faster R-CNN pytorch源碼血細胞檢測實戰(二)數據增強
    • 1. 資源&參考
    • 2. 數據增強
      • 2.1 代碼運行
      • 2.2 文件存放
    • 3 數據集劃分
    • 4. 訓練&測試
    • 5. 總結

1. 資源&參考

Faster R-CNN pytorch版源碼調試過程參考:Faster R-CNN pytorch源碼血細胞檢測實戰(詳細版)
數據增強源碼參考:voc數據集對有標簽的數據集數據增強
其它參考:
imgaug使用文檔

2. 數據增強

在Faster R-CNN pytorch源碼血細胞檢測實戰(詳細版)的基礎上,我們完成了對Faster RCNN pytorch版代碼的運行,并且基于公共血細胞數據集實現了對多血細胞的檢測。現在,在前文的基礎上,我們對數據進行增強,并基于增強后的數據對Faster RCNN進行訓練,進而測試應用數據增強技術后的訓練模型的檢測精度。

2.1 代碼運行

數據增強源碼參考了這篇voc數據集對有標簽的數據集數據增強,如下所示:

'''
Author: CodingWZP
Email: codingwzp@gmail.com
Date: 2021-08-06 10:51:35
LastEditTime: 2021-08-09 10:53:43
Description: Image augmentation with label.
'''
import xml.etree.ElementTree as ET
import os
import imgaug as ia
import numpy as np
import shutil
from tqdm import tqdm
from PIL import Image
from imgaug import augmenters as iaaia.seed(1)def read_xml_annotation(root, image_id):in_file = open(os.path.join(root, image_id))tree = ET.parse(in_file)root = tree.getroot()bndboxlist = []for object in root.findall('object'):  # 找到root節點下的所有country節點bndbox = object.find('bndbox')  # 子節點下節點rank的值xmin = int(bndbox.find('xmin').text)xmax = int(bndbox.find('xmax').text)ymin = int(bndbox.find('ymin').text)ymax = int(bndbox.find('ymax').text)# print(xmin,ymin,xmax,ymax)bndboxlist.append([xmin, ymin, xmax, ymax])# print(bndboxlist)bndbox = root.find('object').find('bndbox')return bndboxlistdef change_xml_list_annotation(root, image_id, new_target, saveroot, id):in_file = open(os.path.join(root, str(image_id) + '.xml'))  # 這里root分別由兩個意思tree = ET.parse(in_file)# 修改增強后的xml文件中的filenameelem = tree.find('filename')elem.text = (str(id) + '.jpg')xmlroot = tree.getroot()# 修改增強后的xml文件中的pathelem = tree.find('path')if elem != None:elem.text = (saveroot + str(id) + '.jpg')index = 0for object in xmlroot.findall('object'):  # 找到root節點下的所有country節點bndbox = object.find('bndbox')  # 子節點下節點rank的值# xmin = int(bndbox.find('xmin').text)# xmax = int(bndbox.find('xmax').text)# ymin = int(bndbox.find('ymin').text)# ymax = int(bndbox.find('ymax').text)new_xmin = new_target[index][0]new_ymin = new_target[index][1]new_xmax = new_target[index][2]new_ymax = new_target[index][3]xmin = bndbox.find('xmin')xmin.text = str(new_xmin)ymin = bndbox.find('ymin')ymin.text = str(new_ymin)xmax = bndbox.find('xmax')xmax.text = str(new_xmax)ymax = bndbox.find('ymax')ymax.text = str(new_ymax)index = index + 1tree.write(os.path.join(saveroot, str(id + '.xml')))def mkdir(path):# 去除首位空格path = path.strip()# 去除尾部 \ 符號path = path.rstrip("\\")# 判斷路徑是否存在# 存在     True# 不存在   FalseisExists = os.path.exists(path)# 判斷結果if not isExists:# 如果不存在則創建目錄# 創建目錄操作函數os.makedirs(path)print(path + ' 創建成功')return Trueelse:# 如果目錄存在則不創建,并提示目錄已存在print(path + ' 目錄已存在')return Falseif __name__ == "__main__":IMG_DIR = "./JPEGImages/"XML_DIR = "./Annotations/"AUG_XML_DIR = "./AUG/Annotations/"  # 存儲增強后的XML文件夾路徑try:shutil.rmtree(AUG_XML_DIR)except FileNotFoundError as e:a = 1mkdir(AUG_XML_DIR)AUG_IMG_DIR = "./AUG/JPEGImages/"  # 存儲增強后的影像文件夾路徑try:shutil.rmtree(AUG_IMG_DIR)except FileNotFoundError as e:a = 1mkdir(AUG_IMG_DIR)AUGLOOP = 5  # 每張影像增強的數量boxes_img_aug_list = []new_bndbox = []new_bndbox_list = []# 影像增強seq = iaa.Sequential([iaa.Invert(0.5),iaa.Fliplr(0.5),  # 鏡像iaa.Multiply((1.2, 1.5)),  # change brightness, doesn't affect BBsiaa.GaussianBlur(sigma=(0, 3.0)),  # iaa.GaussianBlur(0.5),iaa.Affine(translate_px={"x": 15, "y": 15},scale=(0.8, 0.95),)  # translate by 40/60px on x/y axis, and scale to 50-70%, affects BBs])for name in tqdm(os.listdir(XML_DIR), desc='Processing'):bndbox = read_xml_annotation(XML_DIR, name)# 保存原xml文件shutil.copy(os.path.join(XML_DIR, name), AUG_XML_DIR)# 保存原圖og_img = Image.open(IMG_DIR + '/' + name[:-4] + '.jpg')og_img.convert('RGB').save(AUG_IMG_DIR + name[:-4] + '.jpg', 'JPEG')og_xml = open(os.path.join(XML_DIR, name))tree = ET.parse(og_xml)# 修改增強后的xml文件中的filenameelem = tree.find('filename')elem.text = (name[:-4] + '.jpg')tree.write(os.path.join(AUG_XML_DIR, name))for epoch in range(AUGLOOP):seq_det = seq.to_deterministic()  # 保持坐標和圖像同步改變,而不是隨機# 讀取圖片img = Image.open(os.path.join(IMG_DIR, name[:-4] + '.jpg'))# sp = img.sizeimg = np.asarray(img)# bndbox 坐標增強for i in range(len(bndbox)):bbs = ia.BoundingBoxesOnImage([ia.BoundingBox(x1=bndbox[i][0], y1=bndbox[i][1], x2=bndbox[i][2], y2=bndbox[i][3]),], shape=img.shape)bbs_aug = seq_det.augment_bounding_boxes([bbs])[0]boxes_img_aug_list.append(bbs_aug)# new_bndbox_list:[[x1,y1,x2,y2],...[],[]]n_x1 = int(max(1, min(img.shape[1], bbs_aug.bounding_boxes[0].x1)))n_y1 = int(max(1, min(img.shape[0], bbs_aug.bounding_boxes[0].y1)))n_x2 = int(max(1, min(img.shape[1], bbs_aug.bounding_boxes[0].x2)))n_y2 = int(max(1, min(img.shape[0], bbs_aug.bounding_boxes[0].y2)))if n_x1 == 1 and n_x1 == n_x2:n_x2 += 1if n_y1 == 1 and n_y2 == n_y1:n_y2 += 1if n_x1 >= n_x2 or n_y1 >= n_y2:print('error', name)new_bndbox_list.append([n_x1, n_y1, n_x2, n_y2])# 存儲變化后的圖片image_aug = seq_det.augment_images([img])[0]path = os.path.join(AUG_IMG_DIR,str(str(name[:-4]) + '_' + str(epoch)) + '.jpg')image_auged = bbs.draw_on_image(image_aug, size=0)Image.fromarray(image_auged).convert('RGB').save(path)# 存儲變化后的XMLchange_xml_list_annotation(XML_DIR, name[:-4], new_bndbox_list, AUG_XML_DIR,str(name[:-4]) + '_' + str(epoch))# print(str(str(name[:-4]) + '_' + str(epoch)) + '.jpg')new_bndbox_list = []print('Finish!')

建一個新的python文件,命名為img_augmentation.py,放在faster-rcnn.pytorch-pytorch-1.0\data\VOCdevkit2007\VOC2007目錄下即可。
用命令python img_augmentation.py運行上述代碼,會在VOC2007目錄下生成一個AUG文件夾,里面存放好了JPEGImagesAnnotations文件夾,如下圖所示:
在這里插入圖片描述
而這兩個文件夾則分別存放了包括原圖和增強圖像在內的2184張圖像(384+384×5=2184),具體生成多少張,應用怎么樣的增強,可以修改上述代碼來實現,這里是對每張原圖生成5張增強圖像。

2.2 文件存放

正常來說,應該是將增強后的圖像單獨存放在faster-rcnn.pytorch-pytorch-1.0\data\目錄下,并寫一個讀取該目錄的類,但是,最近沒啥時間來專門coding了,所以這里為了求快,直接按照以下懶人版方法修改文件即可。
2.1中生成的AUG文件夾,直接用該文件夾下的JPEGImagesAnnotations文件夾替換faster-rcnn.pytorch-pytorch-1.0\data\VOCdevkit2007\VOC2007JPEGImagesAnnotations

3 數據集劃分

建一個新的python文件,命名為img_split.py,放在faster-rcnn.pytorch-pytorch-1.0\data\VOCdevkit2007\VOC2007目錄下,代碼內容如下所示:

import os
import randompath = './'  # 設置path為VOC2007文件夾即可,也就是當前文件夾
trainval_percent = 0.8  # 訓練+驗證占80%
train_percent = 0.75  # 訓練集占訓練+驗證的75%,也就是0.8×0.75=0.6xmlfilepath = os.path.join(path, 'Annotations')  # xml文件保存地址
txtsavepath = os.path.join(path, 'ImageSets/Main')  # txt文件保存地址
total_xml = os.listdir(xmlfilepath)  # 解析
original_xml = [f for f in total_xml if f.endswith('.xml') and len(os.path.splitext(f)[0].split('_')) == 2]
# print(original_xml)num = len(original_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(os.path.join(txtsavepath, 'trainval.txt'), 'w')
ftest = open(os.path.join(txtsavepath, 'test.txt'), 'w')
ftrain = open(os.path.join(txtsavepath, 'train.txt'), 'w')
fval = open(os.path.join(txtsavepath, 'val.txt'), 'w')# 獲取所有圖像文件(原始和增強)
image_files = [f.replace('.xml', '') for f in os.listdir(os.path.join(path, 'JPEGImages')) if f.endswith('.jpg')]# 用于記錄已經寫入的圖像名
written_images = set()for i in list:name = original_xml[i][:-4]  # 獲取原始圖像的文件名,不包括擴展名# print(name)if i in trainval:ftrainval.write(name + '\n')if i in train:ftrain.write(name + '\n')# 找到對應的增強圖像并寫入訓練集for k in range(0, 5):  # 假設每張圖像有5次增強augmented_name = f"{name}_{k}"if augmented_name not in written_images:ftrain.write(augmented_name + '\n')written_images.add(augmented_name)else:fval.write(name + '\n')else:ftest.write(name + '\n')ftrainval.close()
ftrain.close()
fval.close()
ftest.close()

用命令python img_split.py運行上述代碼,會在faster-rcnn.pytorch-pytorch-1.0\data\VOCdevkit2007\VOC2007\ImageSets\Main\生成劃分數據集的txt文件。
注意img_split.pyimg_augmentation.py是對應的,可以看到我在img_augmentation.py中對每張圖片都增強了5次,所以在img_split.py中也是每次讀取原始圖像的5個增強圖像文件
為了防止數據泄露,所以在img_split.py中,只用增強后的數據來對模型進行訓練,而不用于驗證和測試,可以看到在img_split.py中的這幾行:

# 只有訓練集中添加了增強后的圖像
if i in trainval:ftrainval.write(name + '\n')if i in train:ftrain.write(name + '\n')# 找到對應的增強圖像并寫入訓練集for k in range(0, 5):  # 假設每張圖像有5次增強augmented_name = f"{name}_{k}"if augmented_name not in written_images:ftrain.write(augmented_name + '\n')written_images.add(augmented_name)else:fval.write(name + '\n')else:ftest.write(name + '\n')

4. 訓練&測試

在開始訓練之前,還需要把之前訓練產生的模型以及cache刪除掉,分別在下面三個路徑下:
faster-rcnn.pytorch-pytorch-1.0\output\res101\voc_2007_test\faster_rcnn_10\
faster-rcnn.pytorch-pytorch-1.0\data\cache\
faster-rcnn.pytorch-pytorch-1.0\data\VOCdevkit2007\annotations_cache\
之后,參照Faster R-CNN pytorch源碼血細胞檢測實戰(詳細版)中即可。

5. 總結

這次代碼調試過程還是讓我學到了很多的,由于pytorch版Faster RCNN源碼的實現和運行比較復雜,因此點到為止,只要求能成功復現實驗,并且了解了怎么調參即可,代碼的實現細節可以參考其它的開源倉庫,據我所知好像mmdetection對Faster RCNN的實現就比較簡潔,且易于運行。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/213691.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/213691.shtml
英文地址,請注明出處:http://en.pswp.cn/news/213691.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

靜態SOCKS5的未來發展趨勢和新興應用場景

隨著網絡技術的不斷發展和進步,靜態SOCKS5代理也在不斷地完善和發展。未來,靜態SOCKS5代理將會呈現以下發展趨勢和新興應用場景。 一、發展趨勢 安全性更高:隨著網絡安全問題的日益突出,用戶對代理服務器的安全性要求也越來越高…

AcWing 3425:小白鼠排隊 ← 北京大學考研機試題

【題目來源】https://www.acwing.com/problem/content/3428/【題目描述】 N 只小白鼠,每只鼠頭上戴著一頂有顏色的帽子。 現在稱出每只白鼠的重量,要求按照白鼠重量從大到小的順序輸出它們頭上帽子的顏色。 帽子的顏色用 red,blue 等字符串來…

c#下載微信跟支付寶交易賬單

下載微信交易賬單 //賬單日期只能下載前一天的string datetime DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd");string body "";string URL "/v3/bill/fundflowbill" "?bill_date" datetime;//生成簽名認證var auth BuildAu…

nodejs 異步函數加 await 和不加 await 的區別

在 nodejs 中,異步函數加上 await 和不加 await 的區別在于函數的返回值。 當一個異步函數加上 await 時,它會暫停當前函數的執行,直到異步操作完成并返回結果。這意味著可以直接使用異步操作的結果,而不需要使用 .then() 方法或…

什么是私有云和私有云計算?

私有云也被稱為本地云架構,部署在企業的內部數據中心。如今,越來越多的提供商提供自己的私有云服務,以增強甚至取代企業自己的私有云環境。 美國國家標準與技術研究所 (NIST) 對私有云的定義是:“云基礎架構為單一組織置備并為其…

【華為鴻蒙系統學習】- HarmonyOS4.0開發|自學篇

? 🌈個人主頁: Aileen_0v0 🔥熱門專欄: 華為鴻蒙系統學習|計算機網絡|數據結構與算法 💫個人格言:"沒有羅馬,那就自己創造羅馬~" 目錄 HarmonyOS 4.0 技術介紹: HarmonyOS三大特征: 1.實現硬件互助&#…

Appium 并行測試多個設備

一、前置說明 在自動化測試中,經常需要驗證多臺設備的兼容性,Appium可以用同一套測試運例并行測試多個設備,以達到驗證兼容性的目的。 解決思路: 查找已連接的所有設備;為每臺設備啟動相應的Appium Server&#xff1b…

docker的資源控制:

docker的資源控制: 對容器的使用宿主機的資源進行限制 cpu 內存 磁盤i/0 docker使用linux自帶的功能cgroup control grouos是linux內核系統提供的一種可以限制,記錄,隔離進程所使用的物理資源 control grouos是linux內核系統提供的一種可…

CSP-202309-2 坐標變換(其二)(模擬,c++,vector建二叉樹)

計算機軟件能力認證考試系統 問題描述 試題編號:202309-3試題名稱:梯度求解時間限制:1.0s內存限制:512.0MB問題描述: 背景 西西艾弗島運營公司近期在大力推廣智能化市政管理系統。這套系統是由西西艾弗島信息中心研發…

DAPP開發【11】IPFS星際文件管理系統【簡介,實踐看12】

IPFS(InterPlanetary File System)是一個點對點的分布式文件系統,旨在創建一個更快速、更安全和更開放的 Web。它不同于傳統的 HTTP 協議,因為它不需要使用一個固定的地址來訪問文件,而是通過一個基于內容尋址的系統&a…

HeartBeat監控Mysql狀態

目錄 一、概述 二、 安裝部署 三、配置 四、啟動服務 五、查看數據 一、概述 使用heartbeat可以實現在kibana界面對 Mysql 服務存活狀態進行觀察,如有必要,也可在服務宕機后立即向相關人員發送郵件通知 二、 安裝部署 參照章節:監控組件…

S32K324 UDS Bootloader開發-下位機篇-App軟件開發

文章目錄 前言ld文件修改增加編譯文件CAN發送與接收發送接收函數調用UDS協議增加校驗算法Hex文件合并總結前言 本文參考NXP官網的S32K3 Bootloader,移植實現UDS刷寫功能。本文是APP軟件的修改 本文參考NXP官網的S32K324 UBL,其中有一些Bug,也有一些和上位機不兼容的地方,在本…

每日一博 - 圖解5種Cache策略

文章目錄 概述讀策略Cache AsideRead Through 寫策略Write ThroughWrite AroundWrite Back 使用場景舉例 概述 緩存是在系統中存儲數據的臨時存儲器,用于提高訪問速度。緩存策略定義了如何在緩存和主存之間管理數據 讀策略 Read data from the system: &#x1f5…

vue3原生方法滾動列表

效果圖 代碼 import { ref, onBeforeUnmount, onUnmounted } from "vue"; //定時器初始化 let timer ref(null); //ref綁定初始化 let roll ref(null); //等同于vue2中的beforeDestroy onBeforeUnmount(() > {//清除定時器clearTimeout(timer.value); }); //等同…

AGI時代探導開發的智能化落地之路:中國企業低代碼及無代碼應用價值報告V6

今天分享的AGI系列深度研究報告:《AGI時代探導開發的智能化落地之路:中國企業低代碼及無代碼應用價值報告V6》。 (報告出品方:甲子光年智庫) 報告共計:47頁 點擊添加圖片描述(最多60個字&…

機器學習與人工智能:一場革命性的變革

機器學習與人工智能:一場革命性的變革 人工智能的概述什么是機器學習定義解釋 數據集結構機器學習應用場景 人工智能的概述 1956年8月,在美國漢諾斯小鎮寧靜的達特茅斯學院中,約翰麥卡錫(John McCarthy)、馬文閔斯基&…

數據鏈路層的作用和三個基本問題

目錄 一. 數據鏈路層的作用二. 數據鏈路層解決的三個問題2.1 數據鏈路和幀2.2 三個基本問題(重要)2.2.1 封裝成幀2.2.2 透明傳輸2.2.3 差錯檢測 \quad 一. 數據鏈路層的作用 \quad \quad \quad 光有鏈路不能傳輸數據, 還要加上協議, 這樣才是數據鏈路 數據鏈路層的作用就是負責…

RHEL8_Linux虛擬數據優化器VDO

本章主要介紹虛擬化數據優化器 什么是虛擬數據優化器VDO創建VDO設備以節約硬盤空間 1.了解什么是VDO VDO全稱是Virtual Data Optimize(虛擬數據優化),主要是為了節省硬盤空間。 現在假設有兩個文件file1和 file2,大小都是10G。file1和 fil…

.NET 材料檢測系統崩潰分析

Windbg 分析 1. 到底是哪里的崩潰 一直跟蹤我這個系列的朋友應該知道分析崩潰第一個命令就是 !analyze -v ,讓windbg幫我們自動化異常分析。 0:033> !analyze -v CONTEXT: (.ecxr) rax00000039cccff2d7 rbx00000039c85fc2b0 rcx00000039cccff2d8 rdx000000000…

洛谷P3807 Lucas定理

傳送門: P3807 【模板】盧卡斯定理/Lucas 定理 - 洛谷 | 計算機科學教育新生態 (luogu.com.cn)https://www.luogu.com.cn/problem/P3807題干: 給定整數n,m,p 的值,求出C(nm,n)?mod p 的值。 輸入數據保證…