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