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