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