- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 565752 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174948
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
) G* X* h" v$ I( {) {
深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息
0 d+ V8 J/ N: \% w0 V8 q+ Q图像标注主要用于创建数据集进行图片的标注。本篇博客将推荐一款非常实用的图片标注工具LabelImg,重点介绍其安装使用过程。如果想简单点,请直接下载打包版(下载地址见结尾),无需编译,直接打开即可!8 }7 R _% |% ~' V
9 { t9 v* a* h' |5 [; Z
* ~8 O/ T% [4 W感谢原作者对Github的贡献,博主发现软件已经更新,可以关注最新版本。这个工具是一个用 Python 和 Qt 编写的完整的图形界面。最有意思的是,它的标注信息可以直接转换成XML文件,这和PASCAL VOC和ImageNet使用的XML是一样的。
+ P: q" X) j& I" C3 x# G+ w, j9 G) v$ m9 r
, z, B1 \0 f- Q A& j2 H附注。作者在5月份更新了代码,现在最新版本号是1.3.0,博主亲测,源码在Windows 10和Ubuntu 16.04上正常运行。/ J' h5 S5 K( G# _' h0 ]
: A; _! c/ o4 g1 b2 n* r6 _' a
# l. P. Q& Q1 W$ y7 [+ m具体的安装查看Github教程:https://github.com/wkentaro/labelme/#installation
0 \+ ^1 L+ D& s& q# @( O$ s- I# y8 M$ R
/ B% L& `0 { p! ]9 t3 B0 p
在原作者的github下载源码:https://github.com/tzutalin/labelImg
5 Y9 o* s8 g* g# Q" r。解压名为labelImg-master的文件夹,进入当前目录的命令行窗口,输入如下语句依次打开软件。
; T: ~& x; B7 [. W9 l+ E( u
8 @2 z. R3 w" \; [; E- o* c
6 r T: D' m$ z1 y; H" _) B( \/ Xpython labelImg.py
) c7 h$ ?7 P& `0 N: |, U* b6 r K1
, M& l4 t, e5 q' U" ^+ u
- o* m* }0 v& `& W2 \3 _4 [
0 x; n5 T1 ^& H+ n: C1 j' |; \: F3 {5 T8 N
2 G& d* H* I: C6 U! ?具体使用* w! ?: S; Q; }. w, B/ [
修改默认的XML文件保存位置,使用快捷键“Ctrl+R”,更改为自定义位置,这里的路径一定不能包含中文,否则不会保存。8 u4 y9 o+ n) H% |4 v
4 d r! i8 h i& q+ q4 P. {- n! g: E1 [
使用notepad++打开源文件夹中的data/predefined_classes.txt,修改默认分类,如person、car、motorcycle这三个分类。4 T' Q- W" s+ w7 r1 r2 E
# z; L" {! w9 y6 Z. l2 @! w
% U! f# y% k8 G( x5 a/ k- `“打开目录”打开图片文件夹,选择第一张图片开始标注,用“创建矩形框”或“Ctrl+N”启动框,点击结束框,双击选择类别。完成一张图片点击“保存”保存后,XML文件已经保存到本地了。单击“下一张图片”转到下一张图片。6 }3 @/ U. P: q6 i
5 D: |! P7 t/ O+ o; I6 n
0 E2 l0 _# F7 m1 \& G& n7 k贴标过程可以随时返回修改,保存的文件会覆盖上一个。
) F3 g5 h6 G% `3 S# n' i' Z
: N* J! g6 U6 E3 z
; q( c( p7 e! h/ O) D1 E; H" t完成注解后,打开XML文件,发现和PASCAL VOC格式一样。
! ^, g/ B, ]! | s9 Q/ `
9 f" j6 a' K& [. _* E v5 E* w o
6 Q4 _; U5 n- F2 X/ _/ k将xml文件提取图像信息2 k9 m2 x r+ t, q
下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。# |8 N& Q5 |* P6 G$ s, M! S
- n w: H1 E! `
3 v _3 e) l2 `: y/ }) ~# E$ ^* ]7 @/ n7 t# O6 I+ t5 n. ~ Z
* n6 c1 D- ]; d2 V下面是images图片中的一个。
: X7 x; V3 @$ @7 Y! g4 ]: E3 L- G5 ^8 D* P$ m8 \2 X
2 S2 x; q5 V. z+ {& v5 H2 I
下面是对应的xml文件。
( o# N+ a! n u* i' Y
) O7 p. s$ V+ U3 j3 ?- Z& g
- D1 J* Y% r$ }6 ]<annotation>
" Q" K" B9 _6 Y2 `/ n4 V, q1 S4 ^ <folder>train</folder>
% J- `$ W1 L1 n+ a4 B+ ^6 @2 n. N1 Z <filename>apple_30.jpg</filename>
' b7 U. m/ U! Z <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>6 G5 i' |: C; d" D* ]
<source>
. ?7 h: ~/ M( |/ l <database>Unknown</database>
; V; f7 {( m1 m7 p0 i" ]- t2 p </source>
5 C% e! i5 f o% Q <size>" k9 J( W5 [, I; g! j$ Q5 A( ]
<width>800</width>
) j( \" J; s( M <height>800</height>
* s' C' F; J7 H, N5 q6 [" G <depth>3</depth>; a% c6 H! \0 i1 e
</size>* D( S' a4 l9 c2 V# K# \
<segmented>0</segmented>
/ L4 Z' ]& O/ X8 ` <object>* U- c, ]6 t- U1 B/ \6 y0 U* i
<name>apple</name>
& y" P+ ?7 [; ?" s5 w+ x- _ <pose>Unspecified</pose>
# g A! Q, R5 i6 q& v8 T <truncated>0</truncated>
/ C& E4 f1 H& N4 |# S, K* x: ?: [ <difficult>0</difficult>* B& |; J- [1 w3 N0 v6 O0 L
<bndbox>7 z) o) T9 W' P/ L3 R
<xmin>254</xmin>, s' q7 c* J- r3 X& \
<ymin>163</ymin>
* I$ i: d/ C& z4 f% G <xmax>582</xmax>
" |0 b' [1 k2 r6 C3 H& J, G9 e <ymax>487</ymax>
+ U: p+ \" w3 `/ O. N0 x </bndbox>
' ~! \+ y0 N2 L" c; v6 r) g </object>
- f3 g! e1 {: C0 I0 J <object>
% h3 ^1 {; S% F0 W <name>apple</name>- Y( F4 ^: r* x- x( P
<pose>Unspecified</pose># ~! U1 ?% H' H0 n
<truncated>0</truncated>
4 u% u5 G8 }' r. U <difficult>0</difficult>
5 Y9 ?: Q0 g7 F: T7 L# H% B0 } <bndbox>% U4 {: I% T4 X" b) O( Q) J* k; Q
<xmin>217</xmin>+ m3 u! l8 o& V! Y3 L% K
<ymin>448</ymin>$ m% O% N0 y: I
<xmax>535</xmax>+ Q2 Y" r$ b2 ?+ f. J; _$ Z& @
<ymax>713</ymax>5 t8 W/ v% I0 k) m) A5 i& [
</bndbox>* G* x) m6 o( C$ P l, ]
</object>
: |1 ^( ~6 z5 f <object>, n% p" k* N. j7 o Q/ N
<name>apple</name>
: h* g# s( q8 t, E+ y2 P5 E; H <pose>Unspecified</pose>: n7 ]) J/ U& z# u& B) ?
<truncated>1</truncated>
# {& E ]; n5 Z" U% [1 T8 r; E <difficult>0</difficult>% o+ r5 _" A+ N ~. u" N
<bndbox>
& @5 g1 o! p: k4 S" F* ]. u <xmin>603</xmin>
- P. {9 u0 u. u <ymin>470</ymin>) i" J Q9 g; a5 _0 L
<xmax>800</xmax>
! T" H# v! Y: \/ ~0 Y <ymax>716</ymax>
8 k; h5 a7 O7 s+ ?7 _1 U </bndbox>& [# ?# j5 t {1 Z8 s& l0 K
</object>
4 g! t+ \* N5 P+ H% K q1 C' j4 b. B <object>% m7 s0 S- U$ n7 T8 U/ q: w& i2 Y
<name>apple</name>
% M- N- l/ ~) @) H+ B4 c3 B/ k <pose>Unspecified</pose>7 R, |" k* n5 Z. E: I8 f
<truncated>0</truncated>8 d4 J$ K0 J) m
<difficult>0</difficult>
9 _+ u4 _; T5 Y <bndbox>
; N* f( W' G u% P+ z: v: O <xmin>468</xmin>
7 y. G5 T: K _' | <ymin>179</ymin>
# Q) G- |. J/ N& o9 r9 z; z <xmax>727</xmax> J9 h4 X4 [- }9 F/ ~ O# B$ n
<ymax>467</ymax>
6 D& C% P3 C5 [- f </bndbox>
4 T( d$ {1 F1 [ </object>: a0 R; T$ o$ Z( c; `
<object>/ A: m5 ]- F4 w3 O/ w5 ^5 K
<name>apple</name>$ t, k' _5 T7 @6 [! A
<pose>Unspecified</pose>. S8 h$ Q9 A5 e4 d1 q9 s4 P3 E
<truncated>1</truncated>
% X. \0 Z& Q i% Y <difficult>0</difficult>- O4 O7 e# p9 d; @
<bndbox>
) J8 g* p' S0 a3 \6 @ <xmin>1</xmin>
; y$ f& t, o$ `8 |' a! L <ymin>63</ymin>
; i8 ~, R: k: T* k( `0 | <xmax>308</xmax>
) y& H0 w4 E' N$ X <ymax>414</ymax>
3 n% o( M: ~# |6 W/ \2 p( N6 N </bndbox>
5 _) P9 C! M% m& D </object># m1 q& ^, k6 w. u' \# m9 V1 }
</annotation>- Y1 K& n: @1 J& b. z; H
1
" Z) I) X# u" U1 ^1 E. l2
* D7 P" f* j, n4 t1 C3
$ |$ F. Z# S& p7 @46 m& h3 ^; D. S, R% ]+ T
5- R1 t# Z- P1 p, y
6
; S: j1 C( c1 d: W6 D( u- F7; H* H9 d( K( E% V+ @ J& B
8: a+ V; `* ]) V9 ]0 y7 y
9) ]/ _: t# d3 j' [# b8 o* J
10! {) |5 }8 V m2 l0 p* i
11
4 |# ~% Y- t4 S12
' l6 U7 H$ s- v$ K& `1 P13
, T8 B v8 D; r" l14
' x( U ?4 q$ G' m5 m154 T3 w4 F& {; ~: I
169 t E( W/ s4 @4 n e/ ]
17
# L5 u1 r* e: f0 n. |18
7 \ R/ }7 E6 y3 N X& d19! g7 Y, k: ]6 G
20
* s+ l" A& w' F3 L4 w: }21/ U$ X4 p9 s/ Q# a$ u4 P
22; N6 j& p) `. q
238 i# |4 S# o# X' J- h* ?& a! Y1 f
24. ^$ z) K7 w+ o. ~4 F& ]2 p
25
2 r9 U7 k5 M8 p0 z2 h+ u268 }$ Z% O; Y& z; U. p4 q8 ~ p
27
! R$ W2 j; k7 u4 k: M7 U0 a0 |28. A1 M6 g# _1 q$ X/ A2 t
29
7 l8 w" K4 w: Y& g30! b& K! v0 ?! c0 h
31% A0 }8 A) f3 b
32
, R4 ?1 R* N8 x8 }/ E2 a338 z! c3 N5 m: a: U+ T
34
; O( s8 d& B$ W6 \2 H6 m t356 L! l: v5 v$ I' g+ X9 b
36$ |$ m/ o% e) l' @
37
' {8 N- n7 u+ v+ p0 W0 n38- e" W$ V: { Q, C* I
39" s, c5 E. ]% \
40
$ {0 U1 J& |" `7 k: u7 L7 @41
* }' a, J- w6 U8 A9 F42
7 ^* a7 ^! e7 G; B4 N43% W: A7 H- l, _) C( I7 }3 M3 J
44+ A- y3 g2 i6 }# H9 B! ^
45% Q3 v( \! G7 s! f3 U
46
; F9 a& U( I' l/ C+ }# d7 P47
( o/ F% Y, z' y/ `: C48+ }. f2 z9 H# p3 T0 L$ n
49& B( Q8 d1 G$ x4 ^( A. i
50! _1 W) b2 Z8 R; X% A* r/ Y
51
2 h% z# u- _0 W; q2 B52, E ]8 _% w: G7 k/ y
53
4 J F- O% B+ j: M9 |54; l. {3 ~2 f( }$ g6 ~9 j t1 L
550 ?6 O5 Z2 u9 O; n4 X3 a
56& J' @; L$ c1 L! u
57
4 v# M: h [6 e6 p- T9 Z58
- {% ^, S7 Q1 B" R2 r O! e5 O+ G59
. Y- S" ^! R! w/ [0 s600 z) S* `7 y$ m! W' ]* |
61
3 l( {- t0 u; X62
6 X0 ~" {. k9 r# {6 f634 W X& i7 `& j/ ?6 G
64
: s4 s, x. z6 C653 V+ M" F) O1 q
66
0 r6 `/ _) U$ B" L$ O; d67
8 c" j7 R- l- _5 y# M68. O; `1 k4 K2 w- z) ~0 p/ d
69
3 Q% ^! \- ^2 ~3 \+ z6 m9 {8 ~" c# t$ t708 A# k; T; q6 u. ^4 i4 X& U6 n
71. k# J! v6 O$ c% v# y
72
" Y) e7 m# T! i% d# V* K73
% w* \8 B0 |/ P4 N/ m74- l5 H5 Z1 g1 N9 H1 b% K. h$ L* @
将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。
, g: Q4 t/ X8 g" j
- b4 u+ [% [3 Z. l% P, S/ L9 s
import os/ i" |8 F) |/ o( g- ^: Z! ~# w* s
import numpy as np
e4 e! h3 p* J; i: ^& Z% Jimport cv2
' V! x) q& m9 T0 \' Timport torch$ B! w2 R" R# i& X" {9 k
import matplotlib.patches as patches
8 W! \" ]3 a I8 b- v. e F, ^+ vimport albumentations as A
( S; R4 H) ` B, F0 z! Y, sfrom albumentations.pytorch.transforms import ToTensorV27 V3 J0 y1 {5 a' T- Y$ Y9 n' x
from matplotlib import pyplot as plt
$ v/ U9 ?7 j5 z$ Cfrom torch.utils.data import Dataset
5 o+ h* ]) F% ?from xml.etree import ElementTree as et$ D+ B! o3 K0 h; e; X
from torchvision import transforms as torchtrans
_% E0 E5 W0 P2 p( y
3 S) v! F! I- X; y4 D' i
, D }4 M' z; k# defining the files directory and testing directory
' n8 a! e# @- e. m1 ttrain_image_dir = 'train/train/image'0 C& c6 }! s- V# n
train_xml_dir = 'train/train/xml'* n# W" L) p/ Q8 q
# test_image_dir = 'test/test/image'5 N! y# S! w: m3 L r% _
# test_xml_dir = 'test/test/xml'
* y, E( H, @ c4 a1 o1 T) v+ {; O5 E9 G
! v9 Q4 W; @, x! H
class FruitImagesDataset(Dataset):' E2 A' R' x- l8 h
3 f/ H. S5 H1 B+ \! O
* w+ a7 n9 z) B" ?+ H- o& f def __init__(self, image_dir, xml_dir, width, height, transforms=None):
2 f# b( C& h: f' v; v self.transforms = transforms1 B0 \' w( G9 r, f* K6 w7 o8 n
self.image_dir = image_dir
& J% k; k: z) ~6 u self.xml_dir = xml_dir
5 j& H7 X4 Q" n: R9 d4 k5 N* k self.height = height
+ G! C; C2 k0 W" \ self.width = width
* c4 d, F' [4 U3 P( J5 |+ b. p3 p7 D5 C! w- V5 d$ s
: Q8 u3 K' y `4 a; k. m& n
# sorting the images for consistency- U5 l3 {4 b# ^1 `, e2 f
# To get images, the extension of the filename is checked to be jpg8 r" ~6 \0 M7 W5 u- r" E& X9 _
self.imgs = [image for image in os.listdir(self.image_dir)& E" o6 l6 h/ Z! [% }# y3 k
if image[-4:] == '.jpg']- P, ]0 C( g4 i# n" p2 j
self.xmls = [xml for xml in os.listdir(self.xml_dir)& M2 ^$ q& C L, Y
if xml[-4:] == '.xml']8 P8 g7 { ^8 a$ I
' P# {; V& X" k8 I8 z0 w6 B- C
* m- |6 B% K( t/ `6 w- T # classes: 0 index is reserved for background% E' }+ F& X! @2 d
self.classes = ['apple', 'banana', 'orange']
+ i! m8 E/ f7 |! M+ V( q% Q
/ P& Z/ U3 P6 W: i% P) u8 D7 s2 \9 b
def __getitem__(self, idx):
5 Y; O2 W# |4 p Y5 \6 ^2 H( ]8 E8 z) n# {2 R& b% C
. }. y5 U5 x: [# I* c
img_name = self.imgs[idx] s+ M# O" p& F% L9 X+ g# z, @
image_path = os.path.join(self.image_dir, img_name)
0 F8 T/ J/ |# m W# L4 z2 J) x0 n# Q: M5 C, f
! ~5 G% s" g! ~7 Z# V3 T& m
# reading the images and converting them to correct size and color& `' {9 H, w$ |& f- M3 S/ t
img = cv2.imread(image_path)$ U9 V* O$ l! V# u' h2 _
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32). X1 p& z1 T2 A) }
img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)' [" @' N7 e5 ~1 P4 z( j
# diving by 255
! c, q4 _+ Y* k& U6 X img_res /= 255.0
, n9 ?' l# I/ ?+ h( A' u* S" L
; \ g! ~" C/ z6 q# t% B/ V, j9 A0 D L
# annotation file
/ ~* S9 M, o, k. c) s3 P8 V annot_filename = img_name[:-4] + '.xml'
( a# N) \9 w; f% Z. x annot_file_path = os.path.join(self.xml_dir, annot_filename)
1 ?5 F( f$ ~5 i8 l' v1 a* `. l
+ B. J3 f5 ]/ c$ O, h, D$ M" e( z" x W" p& |3 g$ L
boxes = []4 W1 t0 C: C; ?2 ]/ k3 T
labels = []
& D2 r9 E3 N G! c" S/ a tree = et.parse(annot_file_path)# B7 B$ v) C! N
root = tree.getroot(); l! u3 \" Y' P* D% T8 n
- f2 T9 y/ W" c+ k. {& ~* B3 a
4 T3 ^' B1 s+ a. O
# cv2 image gives size as height x width4 S8 p- m% B% o
wt = img.shape[1]
6 A8 g9 N. n9 g- ^! E ht = img.shape[0]/ G1 X2 j! p3 v& O
. D; a" [5 K* a4 z0 w, Q& j- x# q
+ _1 K- L: }# o% t7 J2 n* t' e # box coordinates for xml files are extracted and corrected for image size given- J$ e& |, B6 ]. G M9 K: }
for member in root.findall('object'):
* {# B3 l u. H. Z. a0 g- M labels.append(self.classes.index(member.find('name').text)) ?3 }) N0 Y' W! ?/ i" `0 v
* }( I8 J3 J, f/ D7 t
; v5 D" d$ o4 ?+ ], U
# bounding box
7 m8 ~7 |- [3 D! S# U2 j: R xmin = int(member.find('bndbox').find('xmin').text)' b/ {; Z* P% X7 E
xmax = int(member.find('bndbox').find('xmax').text)& S8 S1 ^" c* K+ W) Y/ d' `- z
2 w, r4 o; O/ _
8 r" r# K4 x& a1 f: n% R- v ymin = int(member.find('bndbox').find('ymin').text)
( K }; h$ l" Q. K% S* B ymax = int(member.find('bndbox').find('ymax').text)
0 [* k: R# S2 L1 D7 b6 f$ U
# r" v& I1 `% [: s* P8 z+ D0 O8 ]/ n, P2 |7 c! ]0 I8 U
xmin_corr = (xmin / wt) * self.width
/ s2 ?+ Z, L0 Y2 { xmax_corr = (xmax / wt) * self.width
- }6 u' p) H7 r, z5 [ ymin_corr = (ymin / ht) * self.height
0 Z: h/ ^8 q1 D" C4 d ymax_corr = (ymax / ht) * self.height# q, X6 E2 B- J4 M+ \
boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])4 G' B4 ]1 r% D# T9 L, W2 j
; y R: R* ]6 H, L5 O, q7 L, j
2 z3 f# ]: m# K! ]* I- i, H
# convert boxes into a torch.Tensor
/ y3 h5 M0 Z0 o: L boxes = torch.as_tensor(boxes, dtype=torch.float32)
: O; P/ ` v! k9 |' h7 C |% P- o5 S u
! x8 v. x. q; L, y: l5 l
# getting the areas of the boxes
; X1 @; S9 K: q8 w' p8 Q Y area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
% ~5 i2 c# E& G \; t: ~5 `: O$ d! Z! p5 ~0 v
M; L! O1 G9 B9 T # suppose all instances are not crowd4 I0 T8 h* E1 G7 t" Y9 ]
iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64)
4 O2 t R; t; n" r' z9 H
" m; J- @5 O: m, n
/ Y5 V h! E0 h) U9 t1 @+ j labels = torch.as_tensor(labels, dtype=torch.int64); a( d4 W% T+ i# u" ^
8 ^# L( U' ]/ I8 }7 |
% e' k, W* B0 U# F8 p
target = {}. ^+ f; p N$ A7 B
target["boxes"] = boxes
: T* I+ t8 I# F, {& H( b target["labels"] = labels
% |& f) v) f+ @5 }! ] target["area"] = area
, [0 r' ^1 h) `+ `; H* f target["iscrowd"] = iscrowd: y* P, x+ G" f f2 @; `" o7 d
# image_id1 j4 [- D4 k8 Y9 s; ]9 v/ v- R% a: L7 H C
image_id = torch.tensor([idx])
! I: i; y: y: }; z) X- \% A% A. | target["image_id"] = image_id8 m& j# a# k7 e; ^+ b/ K
+ C" [7 v# I1 r0 q" W
% b* Z. J$ E, x" }2 E
if self.transforms:
8 v0 W. w" ]3 R& U* e* @# Y: v( a sample = self.transforms(image=img_res,8 P$ m; d2 c( ^* e$ I5 @
bboxes=target['boxes'],
: f& R8 d- [- Q: D3 ^ labels=labels)' h0 x, f2 y, J; ^
7 `0 c# h, b1 ]7 V* K$ T% g6 @( I/ z" j8 c' e6 m4 S% c1 h" D
img_res = sample['image']$ V9 S! j$ n% z; M p8 A* V. s# {
target['boxes'] = torch.Tensor(sample['bboxes']); u* y9 y2 X. H& V
7 v6 S; m% b) ~4 p" @2 e5 I/ V. ^2 u: P6 r* r% R
return img_res, target
) V; w3 M* V7 s2 u3 | }; |6 P
. @" k; m7 B6 X, k I; j) f8 Z0 a* G! @( J) Z5 n' G# G1 N
def __len__(self):6 J j% Z1 l: e& z6 c
return len(self.imgs)
( d5 M( V% U/ N/ \! ]
# V; K6 T, R9 S+ C* q$ h4 P
: ~1 G& a+ g4 U) \' B# function to convert a torchtensor back to PIL image" N8 l! ?4 e* {/ E
def torch_to_pil(img):) Q$ a; j' L! D/ a( ^% O$ q
return torchtrans.ToPILImage()(img).convert('RGB')
. a H8 P* b/ W+ i/ T! t3 O! {3 [# D$ @
& Z. |+ [: X! s5 t
0 @ `* h/ V- J: }6 d
# d- M' T: ?# u hdef plot_img_bbox(img, target):
% i6 T+ g1 v3 F8 T" Y # plot the image and bboxes
6 ~/ G2 F- B0 D fig, a = plt.subplots(1, 1)
* d& s. ~- I: Y \8 h fig.set_size_inches(5, 5)! P3 \6 W6 N* u' U2 @' ?
a.imshow(img)
: r0 Z2 c. u B+ j for box in (target['boxes']):
/ Q H2 p5 V( z% m6 q# p x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]
4 `& b( m9 _9 X$ \* c: u: d rect = patches.Rectangle((x, y),
7 L; }; R5 L1 [2 d7 b; B width, height,
3 r( \) k+ I6 ^, X& h4 h linewidth=2,1 X0 q- j, J( I4 R
edgecolor='r',
- h; G8 ] N! w4 g/ x. P$ t facecolor='none')8 @# f% i' E2 g5 @% E( {
, B5 Y" f% X1 O; p5 i' z; n
5 E! y4 G' F& d, o' O5 L # Draw the bounding box on top of the image
2 |4 s' K) _9 l* q& g& l/ M a.add_patch(rect)
. c" T9 i7 Y' f% Q plt.show()5 F: q) v2 j) P+ o. K& @5 ` \7 T
8 w# _5 J. J2 T/ e3 _. |: q
( _) l: E/ } R% `- t2 a [
4 C& w8 E$ i& c
+ C7 R; A `7 W4 \def get_transform(train):
! B! G: U) y) {4 `0 [ if train:$ ^5 T4 R4 T8 t, I4 }& }4 _/ q
return A.Compose([% Y' I) C r2 n, H2 O9 V/ @. b: ?
A.HorizontalFlip(0.5),
( i7 m0 F) K% M" H4 J! R # ToTensorV2 converts image to pytorch tensor without div by 255
: {1 F% b/ ~/ W2 c. D ToTensorV2(p=1.0)% U7 `: o7 T1 M `; i' w' v1 E5 Z
], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
6 j+ W5 q9 p! F1 P0 X/ }6 i else:
( q+ t* y2 w' [2 | return A.Compose([
# ~, g2 @8 {' i- H ToTensorV2(p=1.0): u6 X: J( ^% N1 O& j
], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})4 d8 I% ^( b- ^, k
( ~( i @# x0 d. U6 ^
3 Q* e; ^1 A+ B
( l& ~5 h+ O4 ]$ N2 X9 e% X4 l8 C8 Q0 [* m, P9 F% Y. Q& n
/ |! v5 P0 O$ C* G* t9 ^5 t7 s" t9 e. ~1 S% A
: `& B U1 _8 f9 ]. ddataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))
2 @) }: P1 q& i# F5 N* a& o3 ?5 l3 l; P8 I1 c- Q- X0 e
0 u* g- B ?) Q! Nprint(len(dataset))- y! ~% K4 A a# m/ [
# getting the image and target for a test index. Feel free to change the index.6 N& m. C+ Y: A- o6 E2 R0 X
img, target = dataset[29]
5 o* K2 o4 m7 h) E! G# r: bprint(img.shape, '\n', target)
# w8 M/ W' W6 ^* [plot_img_bbox(torch_to_pil(img), target)! K8 m. x: [7 Z" b) G$ E' M) e2 T E" W- E
1
' T T0 p r9 [* b, r" l" _2
0 s, P0 F" J% M4 l+ F: {) N. X. |3' g% S6 d: `8 ]/ q* v- }2 `
4
% ^/ Y: k# \- L4 s4 A; T2 p5' d+ D2 R" w, O. n" D3 j: P
6& a, W" l+ x3 O" E; G/ |2 {% f5 j
7- h9 [) h- h7 Q0 ^- c3 F& M( s
8
& L/ R5 ~1 z) }* N: ^ v' {) }96 c- ^: j$ {. p. l/ P" c( o
10
6 P( i5 l9 |9 E* i5 L* N: R118 t. T/ y: v6 e, {0 J L/ f
124 O( J9 H5 @6 c3 w8 K2 O
13/ m. _; X) k( s7 s
14
n( m* E* |9 w" ~# H/ m153 U( r3 ~3 {, M% f/ H
16
- }. B/ ^6 `8 D; Z3 X! l9 P) y174 ]$ K* W, X8 E6 C0 Q
18' s/ P# n" A3 R+ d2 \' _+ y# r2 \+ B
19
: R) | p8 P4 B( I9 A20
: ], z1 C: f" ]8 J r% K; V: n21
3 \$ u0 U) k1 S; H3 h0 v2 x; g4 n22
/ \0 t' V" Y3 X& z23; D& i& l) M4 o. r* p* C1 z
245 ?, o1 _/ Q b* U5 h. B
25
3 a5 R( Y! c, E* C! s6 u4 f$ B8 r26
/ U; P0 o6 h4 ~% p4 E8 V& z' u7 M27
( \9 @9 N3 H8 L$ S& [0 _2 `7 K287 m" {2 N# Z: H, S4 f
297 q W1 W, G" n0 c: T" F& P9 |! b
30
5 X2 y4 {( J$ F' K/ N7 i31
9 p: U; b: q/ E8 Y) P* e& v32" h' g |' `9 P7 n+ G
33: N5 L- k. Z: @* X0 c% ]
34- H- V( c8 c) X' t0 k! M$ E9 o3 N$ z
35
. k" I5 z* L" e8 R. C! y# R36+ E8 s9 F; g# U* y, _0 k5 R
371 M9 T1 a! H) Z8 A9 W/ W- b
38+ ~4 h/ Z) \) R6 F. M: B+ X+ j
39" M4 r# G- ?) k, C3 l- e
40& w/ [0 K6 m# F j+ u) M
41
G8 W2 O* l# s+ M42
% |+ D: B! ?# d43( n5 w& T P K! L/ w; S
44 Z+ ]1 }9 \- _$ p; b! E/ T8 A
45
! F& O7 m. L4 x( d+ f46
& w. |4 J* `8 b- K' _47
) A3 W) L, r+ Z9 G, H- r48
2 N. Q) I4 ]: c49' _) }( [/ p7 U% s* R1 b
50
* O% c7 r8 p- b+ Z, \; c9 W515 S+ }) ]1 B: B8 E2 A
52
3 {+ U: V* G) @2 b53
# K. N; m; f3 \5 u54
1 [1 l7 G. R+ Y' p g- H z555 Y L6 f; z; w+ }( `# Z. o! j
56
1 N, |8 d4 R, g" J% b57
. G6 R& |3 m( R# \, P5 y7 |58% L1 n) f7 ^, w5 b$ M& ^# Z
59* p' I) Z& U& C/ G" w2 ]
60
, V& H0 K9 D8 U, s# L, Y$ g7 P7 X61: D, G: W/ ?2 K& d8 N6 V2 t8 n
62
5 k& F* G( Z3 C3 R7 L9 m63
' H* G/ m0 u3 G2 t649 D0 O; N; S+ Z2 \0 }2 Z
657 i2 I/ |; H) j
662 p2 S1 f& o- ^8 ?3 n# b
67
4 m* C9 s$ L" I4 ^" p8 O* D# L& h68
1 _0 f3 p" i* N: {+ m5 o4 @# D7 z691 C/ c* H0 p! p& i7 w9 s& |+ I
70
5 l9 F) X: P$ i* T, t6 `71
& l/ ?% O' o, Z' E72- G! m1 J L/ Q7 t3 v
73
D- ~1 @$ Q/ F+ C/ o @+ g% D/ X% ?74) w/ }# e! B# l( g0 \$ w
75
# d0 @. r, i+ k x766 d8 c- p1 M* W2 g6 X+ H, F$ n
77. @/ @9 i9 r: M' x _$ V& u
78
, I+ Q" B& Y5 b' G% H79) g! a! d$ j" U5 m" q- w
807 E' ]1 c, C7 z1 Q/ U! B
81
) n" Q" P Z; M821 q" V; @& P7 f) b/ M3 I9 E8 h
83$ \* E" q" C, V! e
84
3 x! J/ I2 j' \% a2 d85+ \( Q1 g# L: o. ?8 f2 M/ \% C
86/ m( C. r0 `7 B5 _) H
87( J, x6 c. o+ s+ k) E7 N
88" i I) Q- B1 p
89
9 h7 k3 K' o* d# c5 I& ?90
7 R( f% O- U, g# a+ V6 R, V91 W0 D/ c% z- ^# }/ A
926 a1 E* B% Y9 C0 V+ Y! u. i/ x* O. c
93
# O( y; u0 T+ [3 `1 i2 ]94) ], V/ M+ k- G. Z3 }6 g& v5 A" ~& q
95
" `( Z8 |. ?/ `; H3 x) c96
Z1 N* ^ r# X& k+ ~972 ~* W: G& z4 K2 \3 U4 Y" N$ M
987 c2 z( `, W0 P% w% I* \
99
0 A3 x! Y6 L3 N, |100/ L6 Y, o0 E8 b- Q1 e2 x
101
; R# M: r; q/ e102: Q; z( }* n% N: D
103
& W! Q; Z! {0 f3 @$ `3 O0 x1041 ~( K2 |8 ~& c( [! G- W3 H7 _
105
9 h5 {5 R" g5 O' X106# d( E$ B: c( k4 @1 C. U
107
K( o& W9 m- J% L9 P* K7 Z% g108
& i! N9 a, t, X, n109) l4 e' ? j- j* H5 I
110- X* \' L) I4 h* l
111
& G* ?' S, n8 z$ e5 C112
' j/ B3 p$ y9 f* p$ B4 W8 \0 ]9 k113
9 m$ j2 U; \& ~6 U- v114
7 E6 w. p4 v S1 Y3 _115
; C% _' `) V' b5 r# l D116
4 ]- D8 z+ f6 Y! j& c3 ?# A1174 \6 Y3 t8 X+ X2 K6 |7 `* g, F8 f
118
+ o) i9 L5 p9 k! B% B119. ^' I9 I1 d) N3 R. A& I! p# y
120
$ x% ]) y$ b g/ Q7 G: g121" R5 Q, i* m; O- G/ V* w* ]0 T2 i
122. I$ x8 Y+ V9 E# {! L
123! i' {8 N8 @. g F! h3 K$ {6 m. L
124
: G, m* T, N" u* m125
/ p7 G B: r" u+ [% L' K1 z+ c126
& k; H0 i- F1 x& e127# n1 b3 H. n+ m6 R6 l+ o1 R$ B
128
3 G% D' b- Y6 s4 [5 B9 q+ d129* _5 y0 Z8 _; T* K9 W
130
1 ^0 M$ x( @9 O/ v# _ ~" M) v& j) J3 J131
3 }, J6 V# ?( b- y% p8 Q132
' x! I/ d# r' w [133
! [, x: t* l* X2 I134 ~( S/ B* |+ Z8 @5 J# J: n! U
135
% Z6 A4 ]8 u9 Q( N- @136, z8 k( F$ j; _% W& l
1371 `+ R: ^% F5 P9 v _7 a
138
7 k: j- g2 G( D9 J139+ k4 ^% ~' h9 \$ h
140
2 I! J6 r4 Y* q6 {2 A1414 @* p6 S1 ^1 B/ V8 h% A+ D
142
* e/ R% J5 j$ E2 D4 v: r143
' J# B M# b$ Y, f$ W$ d144" g# b" h0 z# h$ l; l
145
/ ]8 Q: j' ?/ O8 {# q146
9 @! q! v) W7 `# y& P, w5 ~147 _1 L; v& S& b" h6 ]4 W1 k
148" x2 S+ X: ~0 t" _
149
: F) W" X" M" i& q t2 b' _150
2 J# {) m6 }/ }, d2 Z2 D8 i/ t151
. I+ G' K& b7 d* k! u9 n152* X2 I* J, f; v
153
1 R8 {' I; O1 O, ~, K6 d+ u154( Y& i9 O5 {, J; ?* t7 t
155
/ P& t2 S' d; O5 Z/ m7 Z" `& W( d156
7 Z* @* L% s' y9 |4 u输出如下:
3 x c K7 _+ `
1 c4 c4 k& K* l, _) S' Y# n) u# Q1 J8 I
torch.Size([3, 480, 480])
O( F) Z8 k: b4 F/ I) W, i: I. ? {'boxes': tensor([[130.8000, 97.8000, 327.6000, 292.2000],
! ]1 r1 S* N5 f [159.0000, 268.8000, 349.8000, 427.8000],1 Y8 L$ J. Z8 T! i$ n
[ 0.0000, 282.0000, 118.2000, 429.6000],& ?' z) G# l. Z7 C8 ~
[ 43.8000, 107.4000, 199.2000, 280.2000],5 z* ^, `+ W' B
[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])}& n; H3 ]- a$ n0 L3 P! `: l" Y
1' i! x: ^3 R8 P' M/ k! \' L
2! o' @2 _" `# ^2 l" J. S, z
3
" i" e2 [2 \& u( M" o- W& M41 k! v0 B. Y, v# [6 {- n6 Y' f
5! D8 l ?. u5 k: t. O( ?
6; \5 |( l1 ?4 {4 B: R
) G# J2 }* @0 x4 {6 \ Z
/ n( H7 M* d7 t" ~+ r$ }
5 t; J ]4 J' O1 Y
1 ?; E9 x. |4 Z3 d$ _下载地址
- N; n7 T6 [8 x1 p链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw e1 l0 \8 N$ e
提取码:srjn2 T4 o' h% i; ~/ S
————————————————
8 t8 p- o6 q' p$ c% n+ y% R版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
/ F* {! _+ M9 h9 k u, V原文链接:https://blog.csdn.net/weixin_44510615/article/details/118496273
: A- x: j' c# I% M: |. v
( Y- f0 H8 V8 R) N5 O1 F
) t5 } Q7 z F) ? |
zan
|