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