@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文件提取图像信息相关推荐

  1. 深度学习和目标检测系列教程 4-300:目标检测入门之目标变量和损失函数

    @Author:Runsen 目标定位 图像分类或图像识别模型只是检测图像中对象的概率.与此相反,对象定位是指识别图像中对象的位置.对象定位算法将输出对象相对于图像的位置坐标.在计算机视觉中,定位图像 ...

  2. 深度学习和目标检测系列教程 6-300:目标检测Fast-RCNN架构

    @Author:Runsen 使用 R-CNN 进行对象检测存在一些缺点. R-CNN 消耗了大量的时间.存储和计算能力. R-CNN 有一个复杂的多阶段训练管道(3 阶段--对数损失.SVM 和 B ...

  3. Kaggle深度学习与卷积神经网络项目实战-猫狗分类检测数据集

    Kaggle深度学习与卷积神经网络项目实战-猫狗分类检测数据集 一.相关介绍 二.下载数据集 三.代码示例 1.导入keras库,并显示版本号 2.构建网络 3.数据预处理 4.使用数据增强 四.使用 ...

  4. 基于深度学习的恶意样本行为检测(含源码) ----采用CNN深度学习算法对Cuckoo沙箱的动态行为日志进行检测和分类...

    from:http://www.freebuf.com/articles/system/182566.html 0×01 前言 目前的恶意样本检测方法可以分为两大类:静态检测和动态检测.静态检测是指并 ...

  5. 基于深度学习和模糊逻辑的葡萄黑麻疹疾病自动检测与严重程度分析(受控背景)

    研究内容 葡萄黑麻疹可能是所有植物病害中最著名.研究时间最长.破坏性最大的一种,它最终会降低产品的生产率和质量.及时.有效.准确地评价葡萄黑麻疹病是田间管理的重要环节.本文提出了一种基于深度学习和模糊 ...

  6. 视频教程-深度学习与PyTorch入门实战教程-深度学习

    深度学习与PyTorch入门实战教程 新加坡国立大学研究员 龙良曲 ¥399.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 APP订阅课程,领取优惠,最少立减5元 ↓ ...

  7. 『深度学习项目四』基于ResNet101人脸特征点检测

    相关文章: [深度学习项目一]全连接神经网络实现mnist数字识别 [深度学习项目二]卷积神经网络LeNet实现minst数字识别 [深度学习项目三]ResNet50多分类任务[十二生肖分类] 『深度 ...

  8. 基于深度学习和3D图像处理的精密加工件外观缺陷检测系统

    由于精密五金加工工艺特殊.零件形状复杂,表面存在金属材质纹理.加工残留纹路以及加工工艺的干扰,如切削液.油污.电镀.喷砂.氧化处理不良等.这样的金属加工件外观缺陷难以使用普通2D视觉检测系统进行高效检 ...

  9. 机器学习深度学习高阶内容系列-kaggle广告点击欺诈识别实战

    机器学习深度学习高阶内容系列-kaggle广告点击欺诈识别实战 中国是全球最大的智能移动设备市场,每月有超过10亿台智能移动设备投入使用 .TalkingData是中国最大的独立大数据服务平台,覆盖全 ...

最新文章

  1. 赛思信安携手太极 助力《甘肃省公安厅大数据警务云》项目
  2. HDU - 4858 项目管理
  3. S5PV210开发 -- I2C 你知道多少?(二)
  4. 【讨论】拿什么来维护原创作者的权益?
  5. [AH2017/HNOI2017] 大佬
  6. [转载] python迭代器、生成器和装饰器
  7. TCP VS UDP
  8. Linux学习总结(30)——优秀程序员喜欢用Linux操作系统
  9. python课程-天津Python编程课程
  10. 照片尺寸及像素对应表
  11. MIT 18.01 单变量微积分总结
  12. mysql分库分表中间件6_数据性能改善——分库分表中间件
  13. 该怎么复习安徽省考计算机专业课
  14. 台式电脑如何修复计算机,台式电脑没有声音了怎么恢复(在家用这两个方法轻松解决)...
  15. JavaScript实现输出100以内含7和7倍数所有数
  16. Android百度地图屏蔽油站,怎么用android百度地图api获取离当前位置最近的加油站...
  17. 社区保密计算机使用制度,社区保密制度
  18. JAVA简介及其编码规范
  19. python seo编程_「SEO及应用编程」开课!
  20. Java导出excel并下载功能

热门文章

  1. TCP/IP / 如何进行流量控制( flow control )?
  2. go java web框架_java程序员10分钟可上手的golang框架golang实战使用gin+xorm搭建go语言web框架restgo...
  3. 初识python评课稿_开平方函数 python
  4. 查询oracle中用户的角色,oracle中用户角色的查询和授权
  5. Linux 信号可靠性,同步,异步,多线程信号等介绍
  6. mysql left join on_mysql,left join on
  7. buck电路pscad仿真_典型电路—电容10UF 和0.1UF并联使用的技巧常见于电源电路中,你知道其中的原理吗?...
  8. php wp foo,【翻译】WordPress WPDB SQL注入攻击(技术文档)
  9. java 可用内存_总可用内存java
  10. modbus通讯失败_技成周报38期 | SMART PLC Modbus通讯、组态、模拟量等常见问题