AI识虫:林业病虫害数据集和数据预处理方法
林業病蟲害數據集和數據預處理方法
- 林業病蟲害數據集和數據預處理
- 讀取AI識蟲數據集標注信息
- 數據讀取和預處理
- 數據讀取
使用百度與林業大學合作開發的林業病蟲害防治項目中用到昆蟲數據集。在這一小節中將為讀者介紹該數據集,以及計算機視覺任務中常用的數據預處理方法。
林業病蟲害數據集和數據預處理
讀取AI識蟲數據集標注信息
AI識蟲數據集結構如下:
- 提供了2183張圖片,其中訓練集1693張,驗證集245,測試集245張。
- 包含7種昆蟲,分別是Boerner、Leconte、Linnaeus、acuminatus、armandi、coleoptera和linnaeus。
- 包含了圖片和標注,請讀者先將數據解壓,并存放在insects目錄下。
將數據解壓之后,可以看到insects目錄下的結構如下所示。
insects|---train| |---annotations| | |---xmls| | |---100.xml| | |---101.xml| | |---...| || |---images| |---100.jpeg| |---101.jpeg| |---...||---val| |---annotations| | |---xmls| | |---1221.xml| | |---1277.xml| | |---...| || |---images| |---1221.jpeg| |---1277.jpeg| |---...||---test|---images|---1833.jpeg|---1838.jpeg|---...insects包含train、val和test三個文件夾。train/annotations/xmls目錄下存放著圖片的標注。每個xml文件是對一張圖片的說明,包括圖片尺寸、包含的昆蟲名稱、在圖片上出現的位置等信息。
<annotation><folder>劉霏霏</folder><filename>100.jpeg</filename><path>/home/fion/桌面/劉霏霏/100.jpeg</path><source><database>Unknown</database></source><size><width>1336</width><height>1336</height><depth>3</depth></size><segmented>0</segmented><object><name>Boerner</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>500</xmin><ymin>893</ymin><xmax>656</xmax><ymax>966</ymax></bndbox></object><object><name>Leconte</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>622</xmin><ymin>490</ymin><xmax>756</xmax><ymax>610</ymax></bndbox></object><object><name>armandi</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>432</xmin><ymin>663</ymin><xmax>517</xmax><ymax>729</ymax></bndbox></object><object><name>coleoptera</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>624</xmin><ymin>685</ymin><xmax>697</xmax><ymax>771</ymax></bndbox></object><object><name>linnaeus</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>783</xmin><ymin>700</ymin><xmax>856</xmax><ymax>802</ymax></bndbox></object> </annotation>上面列出的xml文件中的主要參數說明如下:
size:圖片尺寸
object:圖片中包含的物體,一張圖片可能中包含多個物體
- name:昆蟲名稱
- bndbox:物體真實框
- difficult:識別是否困難
下面我們將從數據集中讀取xml文件,將每張圖片的標注信息讀取出來。在讀取具體的標注文件之前,我們先完成一件事情,就是將昆蟲的類別名字(字符串)轉化成數字表示的類別。因為神經網絡里面計算時需要的輸入類型是數值型的,所以需要將字符串表示的類別轉化成具體的數字。昆蟲類別名稱的列表是:['Boerner', 'Leconte', 'Linnaeus', 'acuminatus', 'armandi', 'coleoptera', 'linnaeus'],這里我們約定此列表中:'Boerner’對應類別0,'Leconte’對應類別1,…,'linnaeus’對應類別6。使用下面的程序可以得到表示名稱字符串和數字類別之間映射關系的字典。
INSECT_NAMES = ['Boerner', 'Leconte', 'Linnaeus', 'acuminatus', 'armandi', 'coleoptera', 'linnaeus']def get_insect_names():"""return a dict, as following,{'Boerner': 0,'Leconte': 1,'Linnaeus': 2, 'acuminatus': 3,'armandi': 4,'coleoptera': 5,'linnaeus': 6}It can map the insect name into an integer label."""insect_category2id = {}for i, item in enumerate(INSECT_NAMES):insect_category2id[item] = ireturn insect_category2id cname2cid = get_insect_names() cname2cid {'Boerner': 0,'Leconte': 1,'Linnaeus': 2,'acuminatus': 3,'armandi': 4,'coleoptera': 5,'linnaeus': 6}調用get_insect_names函數返回一個dict,描述了昆蟲名稱和數字類別之間的映射關系。下面的程序從annotations/xml目錄下面讀取所有文件標注信息。
import os import numpy as np import xml.etree.ElementTree as ETdef get_annotations(cname2cid, datadir):filenames = os.listdir(os.path.join(datadir, 'annotations', 'xmls'))records = []ct = 0for fname in filenames:fid = fname.split('.')[0]fpath = os.path.join(datadir, 'annotations', 'xmls', fname)img_file = os.path.join(datadir, 'images', fid + '.jpeg')tree = ET.parse(fpath)if tree.find('id') is None:im_id = np.array([ct])else:im_id = np.array([int(tree.find('id').text)])objs = tree.findall('object')im_w = float(tree.find('size').find('width').text)im_h = float(tree.find('size').find('height').text)gt_bbox = np.zeros((len(objs), 4), dtype=np.float32)gt_class = np.zeros((len(objs), ), dtype=np.int32)is_crowd = np.zeros((len(objs), ), dtype=np.int32)difficult = np.zeros((len(objs), ), dtype=np.int32)for i, obj in enumerate(objs):cname = obj.find('name').textgt_class[i] = cname2cid[cname]_difficult = int(obj.find('difficult').text)x1 = float(obj.find('bndbox').find('xmin').text)y1 = float(obj.find('bndbox').find('ymin').text)x2 = float(obj.find('bndbox').find('xmax').text)y2 = float(obj.find('bndbox').find('ymax').text)x1 = max(0, x1)y1 = max(0, y1)x2 = min(im_w - 1, x2)y2 = min(im_h - 1, y2)# 這里使用xywh格式來表示目標物體真實框gt_bbox[i] = [(x1+x2)/2.0 , (y1+y2)/2.0, x2-x1+1., y2-y1+1.]is_crowd[i] = 0difficult[i] = _difficultvoc_rec = {'im_file': img_file,'im_id': im_id,'h': im_h,'w': im_w,'is_crowd': is_crowd,'gt_class': gt_class,'gt_bbox': gt_bbox,'gt_poly': [],'difficult': difficult}if len(objs) != 0:records.append(voc_rec)ct += 1return records TRAINDIR = '/home/aistudio/work/insects/train' TESTDIR = '/home/aistudio/work/insects/test' VALIDDIR = '/home/aistudio/work/insects/val' cname2cid = get_insect_names() records = get_annotations(cname2cid, TRAINDIR)通過上面的程序,將所有訓練數據集的標注數據全部讀取出來了,存放在records列表下面,其中每一個元素是一張圖片的標注數據,包含了圖片存放地址,圖片id,圖片高度和寬度,圖片中所包含的目標物體的種類和位置。
數據讀取和預處理
數據預處理是訓練神經網絡時非常重要的步驟。合適的預處理方法,可以幫助模型更好的收斂并防止過擬合。首先我們需要從磁盤讀入數據,然后需要對這些數據進行預處理,為了保證網絡運行的速度,通常還要對數據預處理進行加速。
數據讀取
前面已經將圖片的所有描述信息保存在records中了,其中每一個元素都包含了一張圖片的描述,下面的程序展示了如何根據records里面的描述讀取圖片及標注。
### 數據讀取 import cv2def get_bbox(gt_bbox, gt_class):# 對于一般的檢測任務來說,一張圖片上往往會有多個目標物體# 設置參數MAX_NUM = 50, 即一張圖片最多取50個真實框;如果真實# 框的數目少于50個,則將不足部分的gt_bbox, gt_class和gt_score的各項數值全設置為0MAX_NUM = 50gt_bbox2 = np.zeros((MAX_NUM, 4))gt_class2 = np.zeros((MAX_NUM,))for i in range(len(gt_bbox)):gt_bbox2[i, :] = gt_bbox[i, :]gt_class2[i] = gt_class[i]if i >= MAX_NUM:breakreturn gt_bbox2, gt_class2def get_img_data_from_file(record):"""record is a dict as following,record = {'im_file': img_file,'im_id': im_id,'h': im_h,'w': im_w,'is_crowd': is_crowd,'gt_class': gt_class,'gt_bbox': gt_bbox,'gt_poly': [],'difficult': difficult}"""im_file = record['im_file']h = record['h']w = record['w']is_crowd = record['is_crowd']gt_class = record['gt_class']gt_bbox = record['gt_bbox']difficult = record['difficult']img = cv2.imread(im_file)img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# check if h and w in record equals that read from imgassert img.shape[0] == int(h), \"image height of {} inconsistent in record({}) and img file({})".format(im_file, h, img.shape[0])assert img.shape[1] == int(w), \"image width of {} inconsistent in record({}) and img file({})".format(im_file, w, img.shape[1])gt_boxes, gt_labels = get_bbox(gt_bbox, gt_class)# gt_bbox 用相對值gt_boxes[:, 0] = gt_boxes[:, 0] / float(w)gt_boxes[:, 1] = gt_boxes[:, 1] / float(h)gt_boxes[:, 2] = gt_boxes[:, 2] / float(w)gt_boxes[:, 3] = gt_boxes[:, 3] / float(h)return img, gt_boxes, gt_labels, (h, w)get_img_data_from_file()函數可以返回圖片數據的數據,它們是圖像數據img,真實框坐標gt_boxes,真實框包含的物體類別gt_labels,圖像尺寸scales。
總結
以上是生活随笔為你收集整理的AI识虫:林业病虫害数据集和数据预处理方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机视觉:目标检测的发展历程与基础概念
- 下一篇: 计算机视觉:单阶段目标检测模型YOLO-