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