QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3425|回复: 0
打印 上一主题 下一主题

深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提...

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2021-7-14 15:18 |只看该作者 |正序浏览
    |招呼Ta 关注Ta

      N4 ?; D6 X, p. {0 b深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息
    6 w+ Y; I2 `; n: ?7 ?' o: O% E图像标注主要用于创建数据集进行图片的标注。本篇博客将推荐一款非常实用的图片标注工具LabelImg,重点介绍其安装使用过程。如果想简单点,请直接下载打包版(下载地址见结尾),无需编译,直接打开即可!  E# J- X+ r+ |( ]" Y

    $ T5 H8 T+ E$ `) `3 I) K( W

    1 Y5 @! t! T2 L! E) d  s感谢原作者对Github的贡献,博主发现软件已经更新,可以关注最新版本。这个工具是一个用 Python 和 Qt 编写的完整的图形界面。最有意思的是,它的标注信息可以直接转换成XML文件,这和PASCAL VOC和ImageNet使用的XML是一样的。4 r& ?9 F% ?4 k1 _0 E2 \* z

    0 H3 c: p% d5 x* r# M, ~7 k5 ~
    0 Q% L5 n1 b( y+ e
    附注。作者在5月份更新了代码,现在最新版本号是1.3.0,博主亲测,源码在Windows 10和Ubuntu 16.04上正常运行。* E! G% N: Y. U- S1 Y% A
    2 k& r, }- g: C* g" u
    + E5 z  A* C# g" p- x: r9 z( b
    具体的安装查看Github教程:https://github.com/wkentaro/labelme/#installation3 d% h' s* X; n+ J# w
    7 C- m+ v. n& {

    ! n" e+ z2 @1 _- M; T  D# {在原作者的github下载源码:https://github.com/tzutalin/labelImg& r2 u0 w: T$ E" ~" O
    。解压名为labelImg-master的文件夹,进入当前目录的命令行窗口,输入如下语句依次打开软件。
    # E( t( E7 ?& o, ?, C7 ^
      Q8 ^6 \( m% F8 Q
    . h# f3 c: q4 `% n4 h  V
    python labelImg.py" Q( `' h6 G* B0 }$ l( z7 [$ x
    1
    8 F/ H3 s" n3 }$ w; w
    / A- b6 d* O! d. v: }% t5 ]

    / [. S4 G) n; b1 l. ]3 I9 L( h* z7 v# S$ [# A. b

    0 A/ @+ x0 ?( c  T, D具体使用
    9 M0 h: I7 n/ }# S; e4 e修改默认的XML文件保存位置,使用快捷键“Ctrl+R”,更改为自定义位置,这里的路径一定不能包含中文,否则不会保存。( C% c5 \9 z7 ~4 N/ ]- C  y2 q

    8 p7 M1 c) c  \+ _9 I

    1 f3 z8 @% V) y( L  Q$ y使用notepad++打开源文件夹中的data/predefined_classes.txt,修改默认分类,如person、car、motorcycle这三个分类。0 y/ l0 e) q; `* Q
    2 i. i, J8 L1 x
    * o. U! B" c. i; n* g% G
    “打开目录”打开图片文件夹,选择第一张图片开始标注,用“创建矩形框”或“Ctrl+N”启动框,点击结束框,双击选择类别。完成一张图片点击“保存”保存后,XML文件已经保存到本地了。单击“下一张图片”转到下一张图片。$ D4 E/ g( x, A. E, `: V; W, X' U7 K
    # `  k& [& F, S

    2 e. _  K6 G' Q: F" \贴标过程可以随时返回修改,保存的文件会覆盖上一个。5 S5 U0 w; n* y( P4 `

    & z& R: ?6 `: t' B' ^2 n$ ]7 X
    & Y& U4 I6 Y3 T
    完成注解后,打开XML文件,发现和PASCAL VOC格式一样。  }5 Y, Z$ p# e% M0 y

    % K4 _% [: b( _7 g. ?: z' d

    ! [1 u, D( `& b将xml文件提取图像信息/ y5 P' A2 y$ {# ]5 x. q5 Z
    下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。
    $ _2 J- E0 g8 a2 }+ l% D3 g3 L; x6 Q6 M. q( H9 n/ w' U

    ) s  j9 @9 I7 |
    % X# [% F( y/ j

    7 y; ]: t3 Y- H2 q下面是images图片中的一个。* E6 K) ~2 @) [: J2 o  A4 ?* @6 \& G
    4 R5 Y& U0 Z6 U

    0 ?8 s7 m' w# u2 s* L- T) ]7 t下面是对应的xml文件。
    5 C, Q0 V2 J% u+ i- o4 e3 r. f0 r
    7 l- j6 n) |1 Y7 F
    % O2 E: _; ^! B$ D/ W4 v/ y, b
    <annotation>9 G, ^3 U8 I, D' [# J
            <folder>train</folder>& {* s& k( [9 v7 ^, f
            <filename>apple_30.jpg</filename>
    " L, [, x6 i0 o! r7 K) O        <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>" x, J5 o6 w. p4 n
            <source>
    5 k* l, v! z5 U- U7 s( x+ V& n                <database>Unknown</database>; \( P/ ]# N2 D" Y7 z
            </source>
    + x: _* _7 s, o) A) g        <size>/ w7 ]3 ^* U% R6 Y& h* |: K9 m% M
                    <width>800</width>
    6 I2 H" X" K; C4 j- V6 F                <height>800</height>
    : V0 _: d& |  Y                <depth>3</depth>. i. a; c' p' E
            </size>& j2 e4 _( r5 V% p2 a% a
            <segmented>0</segmented>- z  H0 @9 _& ], Z7 e" {# a
            <object>
    ; Y7 n0 S: D( u6 }% n8 U7 s; Q                <name>apple</name>' Y' c9 o& h# \- p: e
                    <pose>Unspecified</pose>3 Q, U* e7 @% u! P1 K  i& }+ ?$ J! B
                    <truncated>0</truncated>1 \5 a/ Y; P: z; M' O) E
                    <difficult>0</difficult>. l% O6 c' W1 h0 ?; |* \3 d
                    <bndbox>* U! w* B# }$ [: @! u% _: J. U
                            <xmin>254</xmin>
    & [# e) ?6 I4 z7 M) v: F                        <ymin>163</ymin>
    8 b3 g0 @; O7 x& D( H  s4 }                        <xmax>582</xmax>9 m# n& {/ E0 l; V, y2 I
                            <ymax>487</ymax>
    9 V( b! L9 _$ M1 e                </bndbox>5 |, Z0 @, r. l; Q$ i- d! |
            </object>
    + L9 t: {2 R& H& [7 w+ h; n        <object>7 x% Q2 \, n4 F1 Z! Z/ K. V
                    <name>apple</name>
    ) d6 ]! [) Q: u" I! H% T) }7 d                <pose>Unspecified</pose>
    ' h. b, H5 ?6 E1 _2 t                <truncated>0</truncated>" i0 u, _* [5 `$ F) m  b9 g. c
                    <difficult>0</difficult>
    2 d+ r' D$ B* U" p                <bndbox>; U0 b, d1 i  s! v) Q
                            <xmin>217</xmin># J  V7 p4 W$ R! a/ M0 |( c: P
                            <ymin>448</ymin>+ y& S! y) s4 [! c/ ~, v$ _2 X. \0 K/ w
                            <xmax>535</xmax>! i6 D" Z. a# w: C$ N
                            <ymax>713</ymax>
    5 U0 L, l5 _# e# n9 X$ |/ s  ^. _4 G" y9 n                </bndbox>6 q0 ?$ ?6 J5 G
            </object>
    5 x  g! Q4 Q+ g( z- A        <object>
    0 X0 v0 U( \1 d1 X3 b, u# c7 W                <name>apple</name>
    2 t& l! f+ \' i5 t! R                <pose>Unspecified</pose>
    7 K2 Q! Q/ q/ T( I' A& G+ o: ^8 o                <truncated>1</truncated>
    # _& r( H* J2 m: d: o                <difficult>0</difficult>
    ; w7 n* Q8 D. o+ c3 O: t* S                <bndbox>
    7 G  v  @5 v% K" D, [" m" M+ k                        <xmin>603</xmin>
    9 `8 ]; X; o8 ?  g                        <ymin>470</ymin>3 L5 R& |1 p; I! [4 {( j6 z& t
                            <xmax>800</xmax>
    3 L& W2 m. K3 I- [                        <ymax>716</ymax>% w" u. a! I9 v- `3 B
                    </bndbox>
    7 S% Q6 Y& n: q7 `6 U        </object>3 Y* w1 L; A5 X$ M& P1 _+ }7 G
            <object>
    ) Y- L% C3 U  J8 l                <name>apple</name>: x; m! e8 h4 r
                    <pose>Unspecified</pose>( D, A8 }: K6 h. ~7 Y  |7 @( N
                    <truncated>0</truncated>4 h4 T6 s! e, N$ b" f
                    <difficult>0</difficult>- P5 v3 X* n* ?* m4 R' E) @
                    <bndbox>/ m) K4 ^4 X( g% k: W
                            <xmin>468</xmin>
    9 a. o7 h  o8 K/ ?                        <ymin>179</ymin>
    : a' s7 c4 S( K% l                        <xmax>727</xmax>4 _- B3 ]' g4 N* }
                            <ymax>467</ymax>
    $ g1 ~: e/ l( d' P* X+ ]. Y9 j                </bndbox>
    & r; Q: ^* V1 V, S/ E6 U5 A. J        </object>
    ( O' X' W: F! B5 x3 V' x; ?        <object>
    3 \0 |1 i$ L# \                <name>apple</name>. m7 u9 I" \, o' w: K; s* e
                    <pose>Unspecified</pose>
    / W. l( q( M' H- [2 C5 d' o; N) U' b                <truncated>1</truncated>
    7 D, ^' Q4 f; V9 i                <difficult>0</difficult>
    " @. _& S' p: ]% k8 z) U1 P                <bndbox>" q6 G7 Z& R& S
                            <xmin>1</xmin>
    4 }/ T4 g, ^+ A* |& I                        <ymin>63</ymin>) G( T& m( v/ S
                            <xmax>308</xmax>" V- p. R3 n0 a' E: b3 D
                            <ymax>414</ymax>/ Y' H: P# E5 d- _
                    </bndbox>
    & F" X$ d  X  ~5 z( m7 t* G0 ^        </object>
    % l' g7 o: ^: E1 N</annotation>
    8 Z9 e" q/ x4 L7 u) k4 E1' [+ ?& h0 Z" t
    2
    5 M7 U0 Q' ^0 j4 z  h2 h1 G# v3
    . ~9 R: n) G9 F0 ]- Y41 d  K$ _* k/ [, I, H
    5% A( a) n% n- E9 N
    69 H% G6 t! ], @/ [; w8 t
    71 n) r3 [( j: y8 K0 V
    8
    ; G/ d% t  W8 e, Z7 E6 u9
      C: x. `9 G6 f' {$ k10
    $ a- G8 G4 d1 P( _; {1 C11
    & E6 X% G/ P" i! {. g; r; T12
    . K% P! d7 k7 O- ?/ c: [  _* C135 E) v  d/ V* Q
    149 @6 v6 Y- _+ K+ z9 H8 J* D; g
    15
    ( |6 {+ M8 `: x1 T2 y16$ v2 R2 V/ T# p6 o$ ?/ h
    17
    . A  [0 E! r' O( A0 s5 J: _" X18
    : {+ N1 y/ b: t& _# T" m0 [19# ^7 r7 p4 D- Z/ a4 z; J
    20
    . E0 @: R# B) H1 F( ^2 W+ f215 I+ O8 E; r' h& r: B9 E: a
    220 `. O8 r$ b# i. o7 L
    231 F, d, G* {2 l; d1 ]- a8 m
    24
    % T9 M8 j3 d6 K, t5 D7 t2 U# o25
    ; R. |  c3 |! q( B- X26
    : b5 R4 e9 R7 f27" J/ w9 [9 ?% i8 @( `
    28
    % ]% l4 I: j4 o* j0 B7 f' _29
    . x" E$ F  k, \5 K2 H30* C  Y" G$ |( C! w
    31- t* x: q: \. h, t2 F
    320 U0 Y& `9 L) r  W2 k
    335 j0 F9 O/ _, p' J. v0 O
    34
    & ^5 s  B* X  Z( e35! f( S: ?- q! [  }
    36
    $ h& m+ d* _/ X+ X) |* }$ G37
    + D& u5 \0 Q: T, Z7 n" u38- z9 b5 E2 `4 z+ w, l5 v
    39
    % q( f& n0 u( b$ j+ q( ~40
    ' m& `6 s' ]1 T3 x, O" q41
    & g# g( d# v, l- A7 S( y42
    " h! P% W: g3 Z7 ?5 P# k/ s43& Q5 F! f9 ^! M5 j; ?( j! R
    44
    * h; V4 K% k1 \& p45
    ) [8 D2 i0 L, p' j1 @' h+ S$ z1 I46
    9 z" @! r5 K* {7 H! [& V1 D* q47
    - q, n/ S3 U8 y  n9 |- e' p48: ?! W! }8 T8 Y3 U$ D- X
    49" E  ~$ n. w1 O3 l
    50* I7 Y7 `. h0 h6 m- F. \9 e
    51! z8 E+ L( C9 u* `, e" p
    52! y" {) y" t+ I4 M  D! \/ a8 ?
    537 V/ h' z) d& Z% z/ P* X
    54' y# x' U9 r( C" I3 {
    55
    : m$ i# ^5 a9 j1 G# ^4 W4 H2 ~56
    ' B% ?* o: ?9 W' L+ p6 i' Y57) W4 o! F" y& J: k- O
    58
    , T/ C2 @( Z2 {$ ^59* R+ F: b# Z* B# e4 Z8 j/ A1 ]
    60; k" u4 e4 R3 U" Z$ ]/ D2 q/ h" _
    61
    & R+ r1 `, k+ v62: a9 H. T- Y7 w( H# \0 j( D2 m
    63; q* e; p2 Q2 ^! x, E" H$ Q4 S
    64
    6 P$ a- _/ ], X: E1 ^3 l" {4 R65
    + {2 ]5 O0 Q8 V3 @66, e0 w3 Z+ y; b: h- I$ m
    67
    - t4 u- t0 k% o3 ]( Y8 @' M68- c2 G" l# U( v! T" Q
    696 ~/ V7 t: E+ T1 f( I7 ?
    70. `' ?% ~# L0 c, U1 Q- ?5 p
    71
    ) V, t( I7 Z  t8 |72- E+ B1 X9 O. g, i5 a  z
    73
    0 [7 |( o- S/ b1 ~3 ~  p74
      I5 F1 u5 t; p将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。; j% B7 g7 E; U5 k

    , T+ N$ {9 e/ K' V0 Q3 a

    3 L4 [0 E8 x. `1 `import os
    $ E3 V2 f. ~/ x2 C5 p; Gimport numpy as np
    6 x) n9 m7 L2 @( |import cv2
    & r7 F0 q# u4 T" q+ H3 Y( qimport torch; c% Z7 Z  c. [2 s4 d( Y
    import matplotlib.patches as patches; g* j6 ]) }# U9 y( i. c
    import albumentations as A0 g) O( [  c2 i9 f
    from albumentations.pytorch.transforms import ToTensorV26 E: W: D, u9 I& I4 Q* `9 u( [, Q
    from matplotlib import pyplot as plt+ J) [/ c9 M4 `( e( U
    from torch.utils.data import Dataset; w# T; f/ k/ ]9 r* t. f
    from xml.etree import ElementTree as et3 ~* p1 X! g, v/ F/ Z3 S
    from torchvision import transforms as torchtrans
    4 v( q2 u, K  t* \" A+ E; Q! t# @/ E( l
    6 r  n1 a. P. M2 \' m$ _
    # defining the files directory and testing directory' `( F; e5 C: ]8 n' X2 H/ |
    train_image_dir = 'train/train/image'
    / H1 a3 _7 R2 x. p, [train_xml_dir = 'train/train/xml'
    ' Z" k8 C& m* D# \+ w$ b+ t  H# test_image_dir = 'test/test/image'
    . _0 l3 h) \5 {6 l# test_xml_dir = 'test/test/xml'
    8 k* q9 Q3 L. R2 w# e( r6 j/ p& R: c2 X6 e) h. @  ~& b" D7 _- O
    8 I' v2 y: e" z9 `- O
    class FruitImagesDataset(Dataset):
    / ]+ H2 f/ V  N; x. b* [/ u7 k  i2 n# t! O
    & j* F% Q2 G; u  O8 e+ J, s
        def __init__(self, image_dir, xml_dir, width, height, transforms=None):3 v, n3 E& s+ t+ g+ ]
            self.transforms = transforms/ d; v/ v& g: `6 ^" Z- ?
            self.image_dir = image_dir
    2 c8 X3 g1 @) u0 s) c        self.xml_dir = xml_dir' }* l/ ^2 }) X
            self.height = height
    " k& a3 x% j# ]/ ]" N        self.width = width
    " o. a% t1 S. |! s
    9 q$ c8 M9 h" o1 u6 \$ {! g
    . g  D# j- g6 c# i% o7 q' P
            # sorting the images for consistency) E9 P1 ], i; M' P, n- @9 R  D& L
            # To get images, the extension of the filename is checked to be jpg. w- y2 |" S3 \. ]
            self.imgs = [image for image in os.listdir(self.image_dir)" N: G1 t( ^! e) v
                         if image[-4:] == '.jpg']
    4 Z) [( D. F; }# A0 x: B5 A        self.xmls = [xml for xml in os.listdir(self.xml_dir)6 [0 `3 J, a* t( C7 p. s2 G
                         if xml[-4:] == '.xml']- x" K! l, X0 o$ g

    & d* Z* v& I  e; c

    6 L/ y% R% f' h! Q3 Q% U9 k4 z9 X6 c        # classes: 0 index is reserved for background
    2 J8 g4 E8 J' [# R& ~' D- @; [  @& ?; C# H        self.classes = ['apple', 'banana', 'orange']
    / z2 Z! }, d6 B* a  D  q% \
    / ^, D1 f# J) W8 l! @, L7 S" X* ^9 b

    ) f' o  P2 `0 f3 e    def __getitem__(self, idx):
    2 }: H. c6 ~/ _; u% M" M( S& }* b8 e" l
    1 v) X2 D( e% b8 N$ @. `
            img_name = self.imgs[idx]7 |9 ]1 t" A) f, r3 r1 Q5 t
            image_path = os.path.join(self.image_dir, img_name)% T2 _( `1 ]5 f; H% O8 a0 D
    ! D; T7 I; h$ V( I

    9 b/ H2 {- K( k6 i& |- u' p        # reading the images and converting them to correct size and color5 s( q8 T  p( {$ A- l: P" T
            img = cv2.imread(image_path)- |  z# P6 S( R
            img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)% d  Z0 V% [+ p: A7 @4 V
            img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)
    7 {: ~( {$ U8 Q+ @' ]        # diving by 255! {$ t3 c: X4 p* D
            img_res /= 255.0
    + K2 E' y/ W, D- E
    - d) w+ {2 q! E) ~7 N# f
    / k. L* h: L1 M, g
            # annotation file
    " P2 Q1 a& ^; ?, c        annot_filename = img_name[:-4] + '.xml'
      B' O$ r, y* x+ w* _        annot_file_path = os.path.join(self.xml_dir, annot_filename)
    % f  P/ o8 |, m7 N. r% q, f) y2 o4 i4 s# Q1 |8 [% R7 g% Z

    3 [! w' _: w# l1 [* c+ b$ W        boxes = []
    $ ~2 ?$ {3 {2 t, _0 |        labels = []
    * X5 `0 H+ N6 s% b# U        tree = et.parse(annot_file_path). I) J) |4 Z& r& @$ F
            root = tree.getroot()6 A& T2 ~2 e, U5 \  J
    5 g# ]; ?- s6 b1 F
    ; M$ {$ T5 {/ s( z1 h
            # cv2 image gives size as height x width
    / P) J5 B/ K7 F9 N" M0 t        wt = img.shape[1]8 F+ o/ w; ^! w* x9 Q
            ht = img.shape[0]
    % ~  ]( i! u7 U* k: g3 |
    ! r  g" o% U' N; p" O" W, K! e
    * m4 g8 T/ u# V
            # box coordinates for xml files are extracted and corrected for image size given! x  Z; g; r  V- Y8 Z
            for member in root.findall('object'):
    & `. U5 p' r! Q1 ^7 V            labels.append(self.classes.index(member.find('name').text)); t5 E* B9 u! L% N/ N# u, J
    3 r1 E4 y# @" k( C* _* X) K% {

    ! G4 h1 J- t  u- y6 ?- D9 v            # bounding box- N( H* d# ]) ~9 r5 Q: K5 z
                xmin = int(member.find('bndbox').find('xmin').text)# B( I4 ^6 [7 `+ d9 t4 Y/ j
                xmax = int(member.find('bndbox').find('xmax').text)2 }( E$ i# J6 _. I$ F! M" ~

    ' r& N9 R. ^1 b, C, i9 y
    2 |% \8 e$ I. D9 I. K& a/ A1 I) ~
                ymin = int(member.find('bndbox').find('ymin').text)
    1 s/ p  a  M. |- f& D, R( [% ?0 h            ymax = int(member.find('bndbox').find('ymax').text)1 x) K) D6 L- x, M  r7 Z
    % G, R) R/ Z% }7 ^# q# n
    , A% T, H% o* n$ u% j" A) x
                xmin_corr = (xmin / wt) * self.width
    $ c% q( @4 Y8 ~            xmax_corr = (xmax / wt) * self.width/ C9 Z9 ^6 C: `3 Y8 [
                ymin_corr = (ymin / ht) * self.height
    ; j. W: K5 |# }! d            ymax_corr = (ymax / ht) * self.height1 E. J! [& X7 _
                boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])  m# b+ U  b' |' U5 J
    , {% a: ^9 A5 `' K, S

    7 c( `( z2 R# O$ ?3 P/ V3 U+ ~        # convert boxes into a torch.Tensor
    # ^+ w0 k! M/ ]" g- m# ~' i        boxes = torch.as_tensor(boxes, dtype=torch.float32)
    " V. {& L( ]: |, t  ~9 B* E% X) r# G% E3 e* X; `

    7 R/ [2 @7 ?! U9 j        # getting the areas of the boxes
    + @" G4 e- R9 U7 g6 L  e* f" I        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
    , @8 l5 b6 O4 P6 c
    6 }4 R/ x2 P+ {* I' J4 d/ w
    , z, v2 A% t& Y: M. n
            # suppose all instances are not crowd
    : ], A9 ]# M* |' f3 ]        iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64)5 `5 Z0 ^0 Z2 o! r8 ?# H- Y& p2 \

    % E# S7 S! K& |+ @9 E, n0 E8 G- W9 Y

    6 G. s) Z- |% j        labels = torch.as_tensor(labels, dtype=torch.int64)
    ' o$ [  M6 P1 M4 [9 i$ I
    / @# N: F0 e5 L+ l/ r
    9 ?6 C/ y/ Z0 z# ]8 {
            target = {}, f9 s8 M* m: `* j, g4 [; P
            target["boxes"] = boxes% `4 Z; t8 W7 s7 B$ ?
            target["labels"] = labels
    . Y. r" H+ T! G7 A9 C  H& f        target["area"] = area3 y5 j# B: `2 r9 v, d- e/ @
            target["iscrowd"] = iscrowd
    2 d* w! n% Z  ]  Z        # image_id
    - m' b) q& I0 V7 N. T* m5 S' c        image_id = torch.tensor([idx])) h' d( d( z/ o
            target["image_id"] = image_id
    # J( v* D1 i) ~) g2 i& g* S$ E+ q% x7 X1 f! Q

    , |8 G+ W' M+ D, n* d9 W        if self.transforms:
    * ]( Y( M. }! G' t$ V& x6 S            sample = self.transforms(image=img_res,! G5 I8 v+ a  O0 K" y
                                         bboxes=target['boxes'],( `! y) n% a. [* T, W! a; B
                                         labels=labels)$ J) g" o* F0 q% z( z

    # b3 u6 m% y2 C9 Q. f6 q  N5 b
    7 U# q+ m4 ?6 {% U
                img_res = sample['image']: K, E% S% ~9 V; J/ L8 z# Y
                target['boxes'] = torch.Tensor(sample['bboxes'])- n6 B3 s' l- Z2 t7 z. ]
    5 @9 k- ?+ Y2 n* A8 K
    / p; D8 T! _. Q. j
            return img_res, target/ e5 m+ E; y% j! J: o) r' Y
    " t" K/ L0 D3 ^" n" f1 c- S7 Q

    9 b: P1 N/ a) R    def __len__(self):
    0 u  x; [) P& K' g4 a7 R        return len(self.imgs)
    % L0 w9 s# p* N$ F# Y5 ~# ~7 v6 a% g* \6 X
    4 u; W: k" o1 D. ^5 ~
    # function to convert a torchtensor back to PIL image3 a5 l0 x, l! H4 ?# R
    def torch_to_pil(img):: w0 ~3 F% w7 g( Y; G$ i1 h
        return torchtrans.ToPILImage()(img).convert('RGB')
    6 x: I1 t5 Y- {: \9 K6 s2 U9 D* \2 M. [; y1 j
    % H. c: h3 s4 N! l) e' o

    ' U6 }' R; q4 k3 T$ ?
    6 I" p- v; n' W! w) d( \: F
    def plot_img_bbox(img, target):& C1 {: S6 G2 l. t* o- \
        # plot the image and bboxes  G: Q; B4 k! K6 g
        fig, a = plt.subplots(1, 1)
    - ]. e# M7 @' W, w7 @' Q. e# l    fig.set_size_inches(5, 5)
    & z+ ]. q* ?4 u, M" e    a.imshow(img)) C0 c. L& o5 Z8 B
        for box in (target['boxes']):
    - c1 ^: ], x0 {- T% P        x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]# X, v. w: L; }1 i3 ^
            rect = patches.Rectangle((x, y),
    & Y  `: U* N: b: h6 Y' y9 t                                 width, height,
    ( V( B' y' i6 a* z% O% s* ]                                 linewidth=2,# h" z1 h1 I  w- P6 k/ w
                                     edgecolor='r',
    8 _  f0 Y2 I  e0 H9 p                                 facecolor='none')$ ]2 Z* W% ?0 O) S- ]" C

    1 W- b$ P$ l+ Q$ z# o- V- U$ K" ~
    3 z4 C5 B$ [0 ?; O. \
            # Draw the bounding box on top of the image( B2 t( p! E- m; l5 p
            a.add_patch(rect)
    - O- Q/ o2 P# y8 S% j/ E    plt.show()
    $ u' U& o& P" B3 @# g
    5 f) ]: A. y4 r/ \2 v) Q* d
    % h( @# t) D* ^6 w( m  ]1 A
    + z4 X& N0 K/ z, B+ A1 L

    ' h% k$ J8 f4 n+ k4 d$ R7 Zdef get_transform(train):
    : w- Q. o8 I  \8 D( K6 s    if train:- |7 N) h" n. T( ?
            return A.Compose([
    + a4 B/ q4 h; f$ _+ C. U, X% r, |/ W            A.HorizontalFlip(0.5),% Q- {- p) t4 K+ [  c9 J& T
                # ToTensorV2 converts image to pytorch tensor without div by 255# l. D6 v" w2 k) b0 W* P
                ToTensorV2(p=1.0)
    8 B# R8 ^+ f  O# ~( C) ^( K/ ~        ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})  ]; |2 t7 c* N/ o! D( s% k
        else:# r! L' W; ?# [/ W  }
            return A.Compose([
    ) v6 A% w  v3 |& ]7 w+ d            ToTensorV2(p=1.0)2 e/ K$ N* e2 B+ B4 ~
            ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})3 o% \  n# ^1 N8 s. M* x1 j
    " w8 K! l/ G4 ^5 C( X
    4 j6 I$ O( z5 A: N

    ! l. x+ P3 ]2 m7 ]5 V' ^) E: F8 Z

    3 s  B+ Z  x  [# c
    6 u3 Y" U  W0 S% a6 a
    ) N$ c) h. K) C8 s
    dataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))# T* y) o# Y( \4 n1 _2 q

    * k- e( Z8 }. L6 r4 c3 o
    # F* W8 w& O/ L# n; x" c
    print(len(dataset))
    / R: h# C, d3 x# getting the image and target for a test index.  Feel free to change the index.
    ) Y2 c4 V5 r- W5 H) W$ l7 G, Limg, target = dataset[29]* n& n9 P, e! U
    print(img.shape, '\n', target)
    0 z$ z! d/ w; Z$ X' V0 P$ Wplot_img_bbox(torch_to_pil(img), target)& `0 U8 w; P( Y# D% I8 D  [8 u  y
    1
    , C; l/ I! ?  f2
    6 R. L! p: \+ J5 e7 y' Q' s8 V3, c0 d9 e' c9 }4 r
    4' j( f' J& s& t9 H* L
    51 e* _2 H; m7 {$ O5 I( M8 X
    6
    + B# d3 Y: u6 W1 f" z5 I! y7
    + `6 v$ h& U2 n- ~" `8
    ! C* l* }$ K, ~7 T9& k  s+ i4 @7 N# k( R
    10
    , Y2 [7 I: x. b11
    + V7 {, w0 O5 `  Y; r12
    ; C' q* [: S! U/ c13
    ) \' n# `) _5 F" B$ _# }  G6 v6 V148 q8 L9 L, `8 A# o' U3 v
    15, I& O! [8 ~- }! z( {& s
    168 c% _2 ?0 _! F5 T- u
    17; i7 x: i; b% d' Z/ M7 u+ n
    18. w+ v8 Q0 |8 g  |  C
    19
    ; X% G& r; ^* z; o/ \# ^: w20
      M- D4 I8 r6 x+ D21( Z7 a" [4 P( ?1 ^2 m- S- s' w
    22
    / v- j6 S  ~2 E' [/ }235 ^$ D( }& B6 b3 }, C& j
    24
    % U3 V3 |7 W' @9 m6 t: D. s25$ a0 _! E: h% S
    26' f( M2 u$ [4 N. C# h) K- n6 j
    27
    $ w% V6 k. W7 S( J7 I5 Z" U28" ?6 G. W! s1 n# W4 B
    29! J9 N- ]3 J9 s' i& K% M- l6 e% [' s
    306 {9 ?& b" R/ P
    31
    / b; ?8 }- K9 j$ Q; ~32
    * x8 I: a1 x4 G5 Z8 a33. m% G% B3 b: w
    34
    " d% e5 J3 H. f; k" ^* s. K+ @350 x5 u; l$ s7 U" e0 {; Y
    36
    0 f" m& W" b, U3 M4 J3 U37
    9 J) T* |9 ^6 g1 a5 n5 p38
    ! Y4 f, i) Q3 Q39
    8 L2 K* p! }7 H( z40+ H* t+ |7 a( |5 s, E
    41) J4 F6 H4 l9 _' _: V
    42
    * O; F- d( C( E! n" m' d. v43$ X7 A6 `0 }; v6 Q$ c' y
    44- l1 d: _) k! o9 p& v
    45
    : F, ]" ?4 W: C' o  H! _460 z+ d8 ?6 q# o
    47% L1 P0 Y. g& y0 P! x8 f( Q
    481 x# u/ l' D+ Z0 s2 s2 G
    49* Z! ?' S- a0 E$ }) r: p- ^
    50+ ?/ q4 F# x1 q% G$ c
    515 R% F0 i+ l1 ]$ q. V0 @* f
    52
    ! e; u( h7 _7 J( x53% x. N* i& ?6 k9 v* K
    54
    1 M7 X9 T) [5 B( O; c550 y$ _& e; X$ B4 d
    56# o0 F: S2 j8 V- o; J, A' K$ |* B
    57
    8 |. z9 q: R; b2 o2 o2 C5 ^58
    ' a1 T/ n3 y3 R8 x59/ O. ?) H2 _( H
    60% ~4 w& Q, M" u  v* b4 j
    61
    & p. n/ g& a" @62! j- c3 I1 n1 i1 o3 I6 N9 ^4 h
    63
    # y  ^, C  g6 N64
    ) h4 t5 S9 h: ^0 l4 }* |65
    1 ?2 Z+ \7 P/ x: n  m66
    ! R6 H( ?- a  C- @. z674 j" p/ t2 a0 h8 M& o/ J9 _
    68
    7 T4 ?% j) [9 D( F69) k- p3 I  U% {9 E( r3 d, y
    70
    6 @" W/ `3 B2 y: L716 k. Y3 w4 h2 F: C* T$ t0 C
    72
    9 W7 d( ]* s9 E) S1 U% B  P/ h73) e! k2 H9 o: l- l% W' a/ w
    74
    ( L" [; p8 V2 X" ^. `753 O6 ?3 a2 C4 l, A( _
    76
    , n$ l6 D( B5 y" d: W3 |77
    6 h0 H! A1 a! n" E+ K& p78$ J5 {/ }; z9 Y* `. r0 A! T
    79
    - s* h+ m4 }+ j5 C/ S80
    & N8 S2 ~2 B( s( @0 G# k3 i" P5 l' i81; N" ]* L+ V& l
    82
    2 Q; p! m3 y) W4 E" b837 a# P. F* _" R6 ]. K& z
    843 g$ i& T+ u% Y* W* M3 N$ t6 @# r
    85- Z$ X3 }7 [; W" a0 _
    86& Q% d- _' \" N# e9 T' r! g2 }9 L
    87# y2 t# y" g; N- R% H  U0 `/ t) Z$ k# h
    88. h; B  u$ N9 q3 k; n" a" x0 _
    89
    ) U& O5 A$ s5 r: }900 ~1 k1 k/ _$ z3 F
    91
    : V+ d2 k! {8 r& e2 F- U! m7 [6 O& Q92- x. k. v$ ^+ j. x6 r4 o
    936 n* u+ t. @9 c+ Z
    94
    ' R3 j9 J4 }! ]95
    ; o, Z4 l; l. g8 b( e( q& r% j96# p- H4 D( P: m8 b8 _# P; I
    97/ E1 e$ w% x: K( b5 ?1 A1 z
    980 ]. d. P+ o2 d" k- g
    99
    + u  K' u6 k6 ^( o5 q/ ?100
    * W- X3 W: F+ u101
    ' c- U2 {+ l. s# m' E102) K! t4 S6 C5 N, \. {" l
    103
    3 p' n( ]( h8 \+ q1 `104; X3 n& r; w9 W! F
    105
    # L- Q1 ]: v# ^+ S$ U0 R  n& b2 ^106
    9 w( C' y6 t3 ~' d* R3 ^" Q0 g107
    . S( H# d; ?, z9 @# {, K  ]' n108
    & T/ c4 P  m2 J6 c6 L5 |9 l- g109  k; p, ~3 v. q/ R. _! o# y
    110* B# W$ h5 f+ N# `# }
    111' Q( i4 F3 _! y7 W* ?0 O# r& r+ F
    112
    & H1 i8 e. H. s& _0 N0 l9 }* `113
    # Q! n: k( E. W# j3 b114( o- K' {3 I8 W4 `
    115( e  g. @; A6 R3 }0 y' {% ?
    116
    : A9 O: z  q. p* j117* A6 q- r& ]- b, q2 b7 R9 K, T5 C/ K
    118
    3 P+ }1 V7 A$ F" V6 h- u4 \119, @; T* k* u. W7 f! p
    1203 L3 X2 R4 ]; E  Q6 _' h
    121
    7 G4 u! t4 Y4 y( W& E, X5 G$ R5 Y! c" w122
    + K0 H" q, r/ q! p2 H9 y; R123
    3 u* M# w* X( S124/ a3 ?5 j( ?8 {5 s
    125! G; T* R) ~6 g# G
    126: q- t7 \" M- z' S% B  @
    127
    ( j- E2 D: \- q" Z128$ s6 ~$ G2 S% Z! p, F2 ^1 ~
    129
    5 ?2 s: `6 z* e( T: ~3 J1309 x$ l3 u8 n3 `
    131. p2 _% S0 a" R6 i5 |# T
    132! |" U. z8 P* w# U. o& v4 T: Y
    133
    7 l2 Q: e! i  L+ F134
    3 U# X( @1 o3 O% _135. h( `& O5 S4 N+ v& C/ c- i
    1365 Q4 X9 V/ V% x4 V- I! E8 y
    137" ]- Q: j) v& @; t; H
    138
    ) V# ~1 K0 @1 J# x' l) t  v1395 t- x1 Z( H/ y, `1 t% ]) V2 V
    140
    4 K" [* \8 _& Q9 m141
    ! j: b% A" k8 j142
    ! Q2 [' Y0 \9 V$ R3 U9 _143+ r, h. H9 {. L6 p
    144
      `  ]# s3 V) W+ I* D6 s2 C145
    6 Y2 [: Q+ f& k. Y" ~1 r+ G1461 d. `+ M0 _. K5 q
    147
    2 }3 u% B- ~0 I7 P% ^148
    * S% ~1 p. E/ y& |6 d0 }, Y7 G4 \149+ j& ?/ o2 G# _: e
    150* B/ g2 ?9 |& p' D( p
    151
    1 a! s. c- E3 {( M152, |) j5 L4 K4 n- G( Z
    153" {9 c0 J0 L- _. j! b# r' Y
    1549 o' @$ _# F$ ~, u3 c0 L" p
    155, _6 v* V% |9 o+ U
    156" w, B% }% x( F7 J2 [
    输出如下:
    2 u+ a/ i0 o4 W$ }2 {6 X+ Q
    - `, g, E. z1 }3 Z! H' u. Z

    3 m& ]& d. s* ^: J1 b6 storch.Size([3, 480, 480])
    * i- X' p7 v* E* P {'boxes': tensor([[130.8000,  97.8000, 327.6000, 292.2000],
    $ N8 c% P5 X9 b/ C, [        [159.0000, 268.8000, 349.8000, 427.8000],4 t4 H8 s4 o6 Q9 d" f7 h0 J9 M& ]
            [  0.0000, 282.0000, 118.2000, 429.6000],
    ! Z* e1 e6 s* b        [ 43.8000, 107.4000, 199.2000, 280.2000],
    & w% Z4 O: X/ h$ X, ~4 L+ |        [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])}0 b/ o8 Q2 [5 N# F" l( u( j
    1
    ' E3 V; h( i+ ~2
    8 z: t" G2 ^( x% J4 b3
    . V5 y- z# h) \4 j2 w) N7 H$ y4) N) I4 }# [: T3 |2 z( h+ L
    5
    ! o# y4 e! V. x9 l, n! ?, S- v6
    0 U; ~5 @5 v9 S3 C7 u
    / e: `% n/ ~. w6 E+ x8 m

    9 Q9 f4 E0 B! X' J5 f( l
    ) p9 O4 `* S, D5 O: p
    * ~6 ^1 D. k8 w
    下载地址
    4 F% N5 R& x& R6 o, T: w链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw
    , P  ?! N% m5 {, B2 Q0 h& i8 g提取码:srjn5 }) v' w+ }: a" v: I2 x
    ————————————————
    4 c% H* V' d6 x6 |8 p版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。- V, \- K: i; n/ l5 O( y$ w7 D6 c
    原文链接:https://blog.csdn.net/weixin_44510615/article/details/118496273# c8 r! f. f2 \* C8 p

    ' ~8 C! K. K5 I/ S2 e
    2 ~' D: K2 f! r. [* i8 W; U* |
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-4-14 10:48 , Processed in 0.410148 second(s), 52 queries .

    回顶部