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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > 目标检测 >内容正文

目标检测

深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息

發布時間:2024/10/8 目标检测 178 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

@Author:Runsen

圖像標注主要用于創建數據集進行圖片的標注。本篇博客將推薦一款非常實用的圖片標注工具LabelImg,重點介紹其安裝使用過程。如果想簡單點,請直接下載打包版(下載地址見結尾),無需編譯,直接打開即可!

感謝原作者對Github的貢獻,博主發現軟件已經更新,可以關注最新版本。這個工具是一個用 Python 和 Qt 編寫的完整的圖形界面。最有意思的是,它的標注信息可以直接轉換成XML文件,這和PASCAL VOC和ImageNet使用的XML是一樣的。

附注。作者在5月份更新了代碼,現在最新版本號是1.3.0,博主親測,源碼在Windows 10和Ubuntu 16.04上正常運行。

具體的安裝查看Github教程:https://github.com/wkentaro/labelme/#installation

在原作者的github下載源碼:https://github.com/tzutalin/labelImg
。解壓名為labelImg-master的文件夾,進入當前目錄的命令行窗口,輸入如下語句依次打開軟件。

python labelImg.py

具體使用

  • 修改默認的XML文件保存位置,使用快捷鍵“Ctrl+R”,更改為自定義位置,這里的路徑一定不能包含中文,否則不會保存。

  • 使用notepad++打開源文件夾中的data/predefined_classes.txt,修改默認分類,如person、car、motorcycle這三個分類。

  • “打開目錄”打開圖片文件夾,選擇第一張圖片開始標注,用“創建矩形框”或“Ctrl+N”啟動框,點擊結束框,雙擊選擇類別。完成一張圖片點擊“保存”保存后,XML文件已經保存到本地了。單擊“下一張圖片”轉到下一張圖片。

  • 貼標過程可以隨時返回修改,保存的文件會覆蓋上一個。

  • 完成注解后,打開XML文件,發現和PASCAL VOC格式一樣。

將xml文件提取圖像信息

下面列舉如何將xml文件提取圖像信息,圖片保存到image文件夾,xml保存標注內容。圖片和標注的文件名字一樣的。


下面是images圖片中的一個。

下面是對應的xml文件。

<annotation><folder>train</folder><filename>apple_30.jpg</filename><path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path><source><database>Unknown</database></source><size><width>800</width><height>800</height><depth>3</depth></size><segmented>0</segmented><object><name>apple</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>254</xmin><ymin>163</ymin><xmax>582</xmax><ymax>487</ymax></bndbox></object><object><name>apple</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>217</xmin><ymin>448</ymin><xmax>535</xmax><ymax>713</ymax></bndbox></object><object><name>apple</name><pose>Unspecified</pose><truncated>1</truncated><difficult>0</difficult><bndbox><xmin>603</xmin><ymin>470</ymin><xmax>800</xmax><ymax>716</ymax></bndbox></object><object><name>apple</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>468</xmin><ymin>179</ymin><xmax>727</xmax><ymax>467</ymax></bndbox></object><object><name>apple</name><pose>Unspecified</pose><truncated>1</truncated><difficult>0</difficult><bndbox><xmin>1</xmin><ymin>63</ymin><xmax>308</xmax><ymax>414</ymax></bndbox></object> </annotation>

將xml文件提取圖像信息,主要使用xml和opencv,基于torch提取,代碼比較凌亂。

import os import numpy as np import cv2 import torch import matplotlib.patches as patches import albumentations as A from albumentations.pytorch.transforms import ToTensorV2 from matplotlib import pyplot as plt from torch.utils.data import Dataset from xml.etree import ElementTree as et from torchvision import transforms as torchtrans# defining the files directory and testing directory train_image_dir = 'train/train/image' train_xml_dir = 'train/train/xml' # test_image_dir = 'test/test/image' # test_xml_dir = 'test/test/xml'class FruitImagesDataset(Dataset):def __init__(self, image_dir, xml_dir, width, height, transforms=None):self.transforms = transformsself.image_dir = image_dirself.xml_dir = xml_dirself.height = heightself.width = width# sorting the images for consistency# To get images, the extension of the filename is checked to be jpgself.imgs = [image for image in os.listdir(self.image_dir)if image[-4:] == '.jpg']self.xmls = [xml for xml in os.listdir(self.xml_dir)if xml[-4:] == '.xml']# classes: 0 index is reserved for backgroundself.classes = ['apple', 'banana', 'orange']def __getitem__(self, idx):img_name = self.imgs[idx]image_path = os.path.join(self.image_dir, img_name)# reading the images and converting them to correct size and colorimg = cv2.imread(image_path)img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)# diving by 255img_res /= 255.0# annotation fileannot_filename = img_name[:-4] + '.xml'annot_file_path = os.path.join(self.xml_dir, annot_filename)boxes = []labels = []tree = et.parse(annot_file_path)root = tree.getroot()# cv2 image gives size as height x widthwt = img.shape[1]ht = img.shape[0]# box coordinates for xml files are extracted and corrected for image size givenfor member in root.findall('object'):labels.append(self.classes.index(member.find('name').text))# bounding boxxmin = int(member.find('bndbox').find('xmin').text)xmax = int(member.find('bndbox').find('xmax').text)ymin = int(member.find('bndbox').find('ymin').text)ymax = int(member.find('bndbox').find('ymax').text)xmin_corr = (xmin / wt) * self.widthxmax_corr = (xmax / wt) * self.widthymin_corr = (ymin / ht) * self.heightymax_corr = (ymax / ht) * self.heightboxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])# convert boxes into a torch.Tensorboxes = torch.as_tensor(boxes, dtype=torch.float32)# getting the areas of the boxesarea = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])# suppose all instances are not crowdiscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64)labels = torch.as_tensor(labels, dtype=torch.int64)target = {}target["boxes"] = boxestarget["labels"] = labelstarget["area"] = areatarget["iscrowd"] = iscrowd# image_idimage_id = torch.tensor([idx])target["image_id"] = image_idif self.transforms:sample = self.transforms(image=img_res,bboxes=target['boxes'],labels=labels)img_res = sample['image']target['boxes'] = torch.Tensor(sample['bboxes'])return img_res, targetdef __len__(self):return len(self.imgs)# function to convert a torchtensor back to PIL image def torch_to_pil(img):return torchtrans.ToPILImage()(img).convert('RGB')def plot_img_bbox(img, target):# plot the image and bboxesfig, a = plt.subplots(1, 1)fig.set_size_inches(5, 5)a.imshow(img)for box in (target['boxes']):x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]rect = patches.Rectangle((x, y),width, height,linewidth=2,edgecolor='r',facecolor='none')# Draw the bounding box on top of the imagea.add_patch(rect)plt.show()def get_transform(train):if train:return A.Compose([A.HorizontalFlip(0.5),# ToTensorV2 converts image to pytorch tensor without div by 255ToTensorV2(p=1.0)], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})else:return A.Compose([ToTensorV2(p=1.0)], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})dataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))print(len(dataset)) # getting the image and target for a test index. Feel free to change the index. img, target = dataset[29] print(img.shape, '\n', target) plot_img_bbox(torch_to_pil(img), target)

輸出如下:

torch.Size([3, 480, 480]) {'boxes': tensor([[130.8000, 97.8000, 327.6000, 292.2000],[159.0000, 268.8000, 349.8000, 427.8000],[ 0.0000, 282.0000, 118.2000, 429.6000],[ 43.8000, 107.4000, 199.2000, 280.2000],[295.2000, 37.8000, 479.4000, 248.4000]]), 'labels': tensor([0, 0, 0, 0, 0]), 'area': tensor([38257.9258, 30337.2012, 17446.3223, 26853.1270, 38792.5195]), 'iscrowd': tensor([0, 0, 0, 0, 0]), 'image_id': tensor([29])}

下載地址

鏈接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw
提取碼:srjn

總結

以上是生活随笔為你收集整理的深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息的全部內容,希望文章能夠幫你解決所遇到的問題。

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