QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3472|回复: 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
    # M, v/ z) Y  {. D
    深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息1 `+ t/ u$ j$ x
    图像标注主要用于创建数据集进行图片的标注。本篇博客将推荐一款非常实用的图片标注工具LabelImg,重点介绍其安装使用过程。如果想简单点,请直接下载打包版(下载地址见结尾),无需编译,直接打开即可!
    6 x- B4 n. u% E/ l  v9 w/ [- C/ [0 w6 N% ]
    * a$ e" u+ p8 K, X' O9 t
    感谢原作者对Github的贡献,博主发现软件已经更新,可以关注最新版本。这个工具是一个用 Python 和 Qt 编写的完整的图形界面。最有意思的是,它的标注信息可以直接转换成XML文件,这和PASCAL VOC和ImageNet使用的XML是一样的。
    . K: f) u7 b; X; R
    ' ^# N3 n) O) g7 g: O

    ; D' @* F  |! E附注。作者在5月份更新了代码,现在最新版本号是1.3.0,博主亲测,源码在Windows 10和Ubuntu 16.04上正常运行。5 t+ T  j" }4 X- f, Y4 o1 m

    - O/ t' e8 G9 F) E& z0 t
    2 A9 O# Q2 Q! J) H8 q
    具体的安装查看Github教程:https://github.com/wkentaro/labelme/#installation7 S6 I' }+ R  L2 O8 a
    % C. l. X  w/ J. Y

    4 |* ^# j' a8 k  f7 `9 B在原作者的github下载源码:https://github.com/tzutalin/labelImg5 I' [, Z' [, @
    。解压名为labelImg-master的文件夹,进入当前目录的命令行窗口,输入如下语句依次打开软件。
    2 C* q5 u+ ^/ `
    # t8 h, D& m  \

    2 k9 S+ }7 O7 g# p# n9 fpython labelImg.py
      I$ w/ x! t" A* v8 i2 k% Q7 ]17 f# m/ b4 Z1 h) o" P

    1 H" C% e* E$ I7 f) k- I& J
    2 P% `( U6 b1 K) ^) k

    : D/ w  W( \; e% V; B3 B" o

    ( l8 I+ ]0 r' H+ k, ?8 D! U4 B) Z* E具体使用
    : _) |& J9 k; c5 H修改默认的XML文件保存位置,使用快捷键“Ctrl+R”,更改为自定义位置,这里的路径一定不能包含中文,否则不会保存。/ t8 K% X! }# A/ `
    0 g8 n- P& D/ b- V
    " Z8 d* v: }# V
    使用notepad++打开源文件夹中的data/predefined_classes.txt,修改默认分类,如person、car、motorcycle这三个分类。
    * F: N" @$ g1 I& v. u( q! t4 x5 D
    1 y$ b8 h7 r; p
    " B; E. i7 X+ v
    “打开目录”打开图片文件夹,选择第一张图片开始标注,用“创建矩形框”或“Ctrl+N”启动框,点击结束框,双击选择类别。完成一张图片点击“保存”保存后,XML文件已经保存到本地了。单击“下一张图片”转到下一张图片。+ V. ~1 r  K; M3 ~
    ; q3 D4 `8 ]3 M
    ! ~$ v: u0 L9 Y3 v  p2 m
    贴标过程可以随时返回修改,保存的文件会覆盖上一个。9 o8 D' I' U& M1 _+ q

    ' m9 [, r: Z$ M/ K
    . c2 q: A9 {0 B7 q6 [% \/ ]$ {6 [
    完成注解后,打开XML文件,发现和PASCAL VOC格式一样。
    2 c) Q0 }% @1 ^1 k$ e. K7 X8 r+ S* D3 l3 r4 Z% O2 L

    9 |  f# I' x8 k. T& ]: F! u& x将xml文件提取图像信息
    6 g% V9 T/ l; @8 S. V: \; N下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。
    3 g7 |) p% `/ T) f* f: o% C) j" {! r5 R# o  \

    : n( m8 V1 \! L7 w6 ^3 |- F( u1 P. A

    $ t) G+ R( o5 d" e4 q$ Q下面是images图片中的一个。3 ]' c$ c9 z3 V) a* Q
    7 Y* f2 F( R0 K/ O" b7 }
    * B8 L4 l1 w, i1 k+ F7 F9 O
    下面是对应的xml文件。
    3 J5 Z9 h5 U7 `' B& k
    ; c6 A( q" Q% f) d: M7 m
    / U7 V: a0 Q- I0 b/ v! b9 @: T. G3 S7 a
    <annotation>
    ' n1 B1 U1 _$ T: x- v        <folder>train</folder>" t: `+ [: p3 q8 G2 c
            <filename>apple_30.jpg</filename>
    0 [8 c  h% A' Q, j' u9 P' G) G        <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>& Z- |% S. N* ~" ?$ ^  W9 m
            <source>1 l4 c" L' Z; i0 M0 e! v
                    <database>Unknown</database>0 ^# Z& K; F5 q& I
            </source>
    $ l" U4 P* s' A9 _* c+ G+ f9 j5 n        <size>; e5 J, S% Q5 K* P& f
                    <width>800</width>
    ' ^0 i! @/ L) b1 V1 h                <height>800</height>3 j3 T& R& u: x( k/ S
                    <depth>3</depth>
    0 m: j$ n4 K/ G6 H  H4 E8 }        </size>
    7 X5 l4 O! }  @% G" O0 V+ Y$ g        <segmented>0</segmented>, N) \9 _4 \" s3 W: p# @
            <object>+ d* O$ R1 e2 G
                    <name>apple</name>
    9 h8 k  k) k7 v' n0 s- x1 ~* L                <pose>Unspecified</pose>
    . p+ m8 o& }( `' T$ G4 g                <truncated>0</truncated>
    ! b2 y* ]3 b5 T: N3 s! K# s                <difficult>0</difficult>
    8 K2 W! R( e- D) ?8 w; `                <bndbox>
    ( m- t# |7 y2 B* Q+ _; F                        <xmin>254</xmin>. `* f* ^: G0 Y$ s6 M% i5 v
                            <ymin>163</ymin>
    9 k# O  E" F7 o9 `; n) @                        <xmax>582</xmax>* ?& Z4 ~, O# q. I( ~. d
                            <ymax>487</ymax>
    9 o& \) w$ X) [. X- J                </bndbox>+ A# F- D  D! t/ i& }) n2 l
            </object>
    : c  d4 F1 D, z5 f, y$ T$ _        <object>
    0 D: P5 t* ~$ U                <name>apple</name>
    ! N* \( b/ Y, [" w7 b                <pose>Unspecified</pose>
    7 g: Q2 V  U# Y( H5 Y$ v2 C1 `                <truncated>0</truncated>5 k5 o# ^  K! c
                    <difficult>0</difficult>$ a& V1 h& h% }8 z: @
                    <bndbox># v( f' i+ f4 c9 K. ?
                            <xmin>217</xmin>
    3 Y) f* d/ {/ Y0 N                        <ymin>448</ymin>
    # z" w" g* L# U5 N8 A5 J                        <xmax>535</xmax>
    % Z# G' f) I- M. x; A                        <ymax>713</ymax>% S2 o, S* a* G( e6 s
                    </bndbox>
      e' c& X( K$ A- b$ P$ h8 Y* u        </object>& `. ?6 |! u. O* C. z5 M1 i: j; p
            <object>
    3 e' B4 k$ s. l: @                <name>apple</name>1 @3 j+ u' c: x; f
                    <pose>Unspecified</pose>' a* ^; K1 P8 ?" }- S! Z* P
                    <truncated>1</truncated>. e: ]! U0 {" e
                    <difficult>0</difficult>) S" \. r2 _2 s9 S
                    <bndbox># _* T, ~$ f3 u7 v0 Q$ S, v% y
                            <xmin>603</xmin>
    " g& {0 `; W% b; _                        <ymin>470</ymin>
    2 M! v0 V* f$ k# @5 z( c; l+ U$ S& j                        <xmax>800</xmax>! k9 [5 P* S- t  l8 w
                            <ymax>716</ymax>5 Q# O) E1 b: G; r  m
                    </bndbox>
    : ?; X: w8 Q$ X9 M        </object>
    " A+ q$ i% I0 f$ P4 d; [. Q5 `# \        <object>; T/ m6 x6 ]4 W; m6 E+ I7 K
                    <name>apple</name>
    & }2 Z, D/ b2 k7 i6 }9 j                <pose>Unspecified</pose>; l5 Q; A* a( Z* V$ v, ~% a+ q
                    <truncated>0</truncated>7 B- K+ ?7 ?/ @2 f3 g8 r+ M
                    <difficult>0</difficult>
    1 w6 e/ m: a% `                <bndbox>: W! ~7 h5 w+ O' P; _# s: ?, `
                            <xmin>468</xmin>
    : N( o* M  V: I$ b! Q5 Q6 N                        <ymin>179</ymin>* y6 a- G6 ~. o
                            <xmax>727</xmax>
    ( Y/ P8 W4 S% y: J2 i                        <ymax>467</ymax>0 w% Z& q( S% I& X
                    </bndbox>0 L3 W# Y: L1 a* t- z
            </object>
    , H1 ^7 R% ^1 j1 _# ~        <object>- n0 z. [; Z3 [; M4 R4 ]! H) v
                    <name>apple</name>
    & \. I+ a$ ^, z3 s7 H                <pose>Unspecified</pose>
    3 F7 w9 ^/ f  ~" e5 N                <truncated>1</truncated>
    , `6 i' c, Y3 R! d2 |( D& d8 s                <difficult>0</difficult>
    7 C- @* j8 m( W  |) {, L7 N                <bndbox>4 y9 e' ~3 v3 }
                            <xmin>1</xmin>: e1 W) k/ [# ]( a9 Z8 C
                            <ymin>63</ymin>
    , j( q2 T6 r% q- e) d                        <xmax>308</xmax>
      u) |' l% [+ a! Y                        <ymax>414</ymax>" l" j6 N1 E( H
                    </bndbox>3 ~* T1 \# C2 C1 G& ^& m- U
            </object>+ `8 O. j7 _2 A6 j
    </annotation>( w" ]7 d& J( u& b6 l* b8 U
    1
    , {: z8 ?+ L+ S! U+ O28 [6 ?" @- ]' J7 |, j) r! E
    3
    & o% j* i; n# W  X* J+ v& f* {42 u5 D& x$ B; I6 _
    5
    ! }' s: p4 d# x65 ^" u+ D, M$ @# e- @
    7# [8 O9 x$ s* z
    8
    1 D7 g' t" O% T/ \! ~# z9
    # ?( P2 e# l1 q# P) ~; Q10
    ! ^/ M0 G5 L( U- u11
    ( z% J( K& f- p12, A' `, r% [- ^2 V  d
    13
    5 x" v/ g5 V1 l# U& R# l4 A8 J: o14
    . u, z& [- _1 F. y" |$ H157 N( U+ b6 \3 P) u+ {' ]
    16
    % N% V. n& c( d# Z  p. [2 M) _17, R; S1 D8 `: `" C9 I
    18
    ( ]9 f9 G7 [# p# H7 l$ L19
    & M) B' @  g% y3 n& M3 Z  {20; |0 G9 z: E9 e6 F3 d- J: G+ t( u
    213 R$ U6 s# X/ g+ P( f) Z
    22
    - Y) k+ m" V- w+ ]- E# s$ z4 ^23$ Y9 [$ z, }6 Q6 B; v
    24
    ! x4 V! C. a$ `8 q- B8 r& v25$ W' O9 B% C+ E1 }, P8 W
    26+ Z3 r' ~& J) c( ], N1 s- [
    27
    ! ]8 x" C( d/ i4 h283 b$ T/ v1 r" W! u% J
    299 }- k- b2 ^/ o% A
    30
    * z# g6 K( t0 h3 p+ P31
    ( ~* ^- Q$ b+ q4 {# M32# A5 M4 ?% ^8 c0 s: B) q
    33
    # t# c) I# D1 q8 x3 S6 p. ^3 O- m34
    8 r! l# E# |( {+ }$ b6 D35
    # E- v9 L" G5 w2 \36
    + L; Z* V9 y- r  F/ n* K% ^* o37
    % [# L  X# z) Q1 u" S) d: Y2 C38& L- g# h+ _- V/ }) P8 q; c
    39
    ! N7 I/ p( _3 D4 K7 b# u40* X; _6 _. e; U- d$ d7 }0 A
    41/ v6 e! H2 \% Q% D+ \9 N. t
    428 x3 h, L& h( u2 S4 R- C4 B
    43; u! g; `( t5 G! a1 M
    44
    ' [8 }4 m5 |$ y45  q% O: w& j$ X* A
    463 t7 ~7 \' m- O3 K2 t3 x& R
    470 _/ b: b! n& Z# h* l0 H+ {+ c
    48
    9 Q  Q' J; k0 R! a% t& k, t49
    $ z# M2 v8 @3 T& A506 ]( z! G0 Q' k0 z8 o- X' ^
    51
    + T% Y: ~/ t- u% U! K" \529 I6 D* s* Q- I- ]! b/ f
    53
    $ F. @2 ?- w- ]) y- [/ u3 ^. [! j, k54) S2 h* l7 v3 W+ }4 q! C% }
    55
    - P! S" C' I7 F. \0 x  @  E56
    0 |. f% r( W: O! Q- @57
      v& c. I5 v2 ]8 s4 ^1 R58
    / u9 V; P" @2 H# G( j597 c" E" i8 x( x+ p, Q2 v! ?
    60
    ! v. x& a2 C3 x& V7 ]' z* |61
    $ R" w; j/ W* u: K62
    2 q: w6 i! u4 L* y4 z4 r632 L+ }! r& C) p( Y
    64! W6 T: E% ?/ E7 R' ?3 B3 U
    65  h& i6 X0 W* N# J
    660 M+ n+ d0 A1 ~3 o2 N1 S
    67
    ; D- \* w5 u) A, ^8 A/ K68( q, z# }% i/ I! f: ]
    69' |2 F% y! H- {6 x+ I$ \8 w
    70
    ! h$ T" a7 L( j+ {  s, R71- t) p6 s* o) O8 v
    724 d: _- b/ S7 `
    73
    ( }  g9 K. E0 h* g3 l& M. H742 p$ T8 {" o6 a
    将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。6 @; `* h& n2 i; E$ k# @

    6 |4 W1 a) Q6 U$ {' k

    + S/ D( ^/ A2 A( j- limport os! R# q5 n  U0 S6 C6 C
    import numpy as np6 h8 S% @; L( N+ ^+ T
    import cv28 M/ i1 w8 {9 W; ]0 ?, l  v
    import torch3 S3 x7 t" }  N& U( {5 I  O# Q  C
    import matplotlib.patches as patches$ Z* h9 V; e0 W. l4 C7 J
    import albumentations as A+ x, ?: ~6 s3 ]- H! V, M
    from albumentations.pytorch.transforms import ToTensorV2. ~7 p. G8 h$ Z( _7 z) I2 g4 l
    from matplotlib import pyplot as plt# a+ F& e0 P1 D/ y$ ^; `
    from torch.utils.data import Dataset7 G5 ~/ w6 `% V) v
    from xml.etree import ElementTree as et, P& Q* Q, K* V0 e+ q/ C
    from torchvision import transforms as torchtrans+ B2 B5 [( @: F! b0 c9 D" f9 H/ S4 N
    ' Q( H' G/ K4 Y

    ' v- X- b8 g: |1 V  |0 X# defining the files directory and testing directory
    & Z- }' \' ]9 z# Q" ~$ p! Jtrain_image_dir = 'train/train/image'# b# `( W' L" y/ r' S7 \; }
    train_xml_dir = 'train/train/xml'% M$ ^$ C9 e- {- h% p2 d
    # test_image_dir = 'test/test/image'
    6 W  B+ X. A6 o- i3 I/ ]5 `3 Z3 {5 c& ~0 v# test_xml_dir = 'test/test/xml'7 O( `! y2 K5 x* O0 x7 G

    ) G$ B  ^8 ]* A) x* [

    , A4 X% K& M# uclass FruitImagesDataset(Dataset):5 j* ]$ E6 H4 U: M9 u* U0 [% x
    / r: \$ a! y/ d1 k8 \) [
    3 ?+ R  G. D' P/ v  S( n
        def __init__(self, image_dir, xml_dir, width, height, transforms=None):5 _' o2 l" u% @  U' m9 H
            self.transforms = transforms
    $ x3 L* `: d' R8 f/ G: g        self.image_dir = image_dir  g5 F! W% K( Q- n! N0 S
            self.xml_dir = xml_dir
    / b. T. P, q: n" B# n        self.height = height/ B9 K% c" {6 u3 A: G% B/ \) j
            self.width = width% Z6 y) J* |" Y% J* s+ \  k
    3 D- {7 `# ~3 ~$ ?

    0 o4 l2 P" M; E8 ~( C3 R$ G9 B. M        # sorting the images for consistency
    % C1 J% w* Q' e1 M        # To get images, the extension of the filename is checked to be jpg+ m* p5 L# k4 R2 q% }
            self.imgs = [image for image in os.listdir(self.image_dir)4 Y+ }7 z; {1 M0 S
                         if image[-4:] == '.jpg']- d0 i5 M/ K! T; E. B
            self.xmls = [xml for xml in os.listdir(self.xml_dir)
    1 n. W  K5 Y- F2 g! l! ]                     if xml[-4:] == '.xml']
    $ b  G2 a+ @5 p+ x
    - D& }2 P( q# g$ C

    4 L4 s  |) H- f) `# T# ^        # classes: 0 index is reserved for background  |$ t! u$ {0 N& F3 D9 ]
            self.classes = ['apple', 'banana', 'orange']
    . j, g9 V8 C2 \; ]! H" e, P3 Y
    ! G5 k( H  X; y: I3 G' K

    4 @" x! B' X" O+ w    def __getitem__(self, idx):
    " U* B3 _. d0 B1 Z# Z
    ) X' E4 b7 t5 |1 t+ @: b

      @6 q: A+ \- h  |/ K& @/ G        img_name = self.imgs[idx]
    0 K: k/ Y2 z1 N        image_path = os.path.join(self.image_dir, img_name)* X. r- R4 W$ r. R1 Y
    - v" G  U6 i) {; U- c

    % L# G% g" |8 ~4 [+ h' x" _. h        # reading the images and converting them to correct size and color  o1 P# ~# P& S2 W. y
            img = cv2.imread(image_path)5 @8 L9 {( @, J  R* L- O
            img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)& s$ l. ~! U  N- a1 @
            img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)/ d& X3 p# g+ f
            # diving by 2558 n9 n1 M. j7 [
            img_res /= 255.06 N; b. N. \8 U! k3 n# d
    , g( P4 ?: R; y: a
    ( m; B( G4 e" |; X: y) y; @
            # annotation file
    & L% q3 H2 r' e9 H) v( |        annot_filename = img_name[:-4] + '.xml'  j9 H7 t7 M: y/ a* H5 E/ l
            annot_file_path = os.path.join(self.xml_dir, annot_filename)9 R5 G  R6 U( w7 K' ^3 X
    6 |0 C2 u  R1 o3 b" ~
    ( l! ?7 R, u: l5 B7 {+ l) v
            boxes = []
    , J- w) r* Z# l: m* c        labels = []
    , C: G' e1 Z  r2 j" p0 {. V        tree = et.parse(annot_file_path)# d9 W% F2 @' d7 Z7 d9 N# }
            root = tree.getroot()
    / U+ {9 q1 O; a( T4 E
    1 d; v' v2 D. o
      q5 P/ }2 H% |& }7 o! _7 ?3 ^
            # cv2 image gives size as height x width8 t. D# [0 W0 T& b0 N
            wt = img.shape[1]
    ; h% B' g. Y' i, D+ S. t& D        ht = img.shape[0]
    $ v8 g. [9 B  t) r' E' U/ _: Q- G- V6 ^0 Z9 G4 g

    $ q' x8 ?# K, J& t3 P        # box coordinates for xml files are extracted and corrected for image size given
    # v) L0 o6 {- ?4 w+ `        for member in root.findall('object'):
    ' a8 M4 c- b+ @* u            labels.append(self.classes.index(member.find('name').text))8 r/ s0 ^: L$ o: A0 E

    ( V6 W1 q4 @# g, i7 o) F+ Y) |5 i$ Z

    6 M" [& [# v8 s0 w* Z            # bounding box+ d# D/ o4 d+ U8 X7 s( {
                xmin = int(member.find('bndbox').find('xmin').text)
    " ]% y& [0 F4 g4 a! |' ~            xmax = int(member.find('bndbox').find('xmax').text)3 I- s* G5 N. e5 q" @# t
    : s' s5 F9 v/ G9 e. D5 @
    9 f) w, _  Z- k- {7 C; }
                ymin = int(member.find('bndbox').find('ymin').text)
    % \$ t; k$ Z" J1 H) B            ymax = int(member.find('bndbox').find('ymax').text)
      c! H/ E4 y" D7 [7 k: z$ u) L% A  }& L$ n  `( I' s
    + f) \, f% W7 ~* `
                xmin_corr = (xmin / wt) * self.width
    " j6 Y! J1 {0 y6 q0 p            xmax_corr = (xmax / wt) * self.width
    4 I0 ]( @+ g  q0 F5 U# h2 \" p5 Q( d            ymin_corr = (ymin / ht) * self.height4 S1 V2 H2 e# c
                ymax_corr = (ymax / ht) * self.height2 ^/ j0 e: G$ h8 ^+ Y- S7 m& s, o
                boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])
      j  a2 u( J9 L) @5 A$ D& N0 N
    $ ]2 q; c1 K& S% T! ]

    . X7 J0 A5 g: N. I* r        # convert boxes into a torch.Tensor9 E1 P  p- u# e1 Y2 ~
            boxes = torch.as_tensor(boxes, dtype=torch.float32)
    9 y' Y4 U3 T+ K7 S5 n0 X6 {* i6 ~2 Z0 U' n$ \( _% _4 `
    0 F# E  n+ L% y! W" C8 v
            # getting the areas of the boxes
    4 ]5 z3 W: R: \. u4 u; J4 i; i" f; d- t        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
    9 J' T  w; O4 W1 @) b# O3 [
    ; t. p: o+ [, ]
    ! o8 F5 Q6 ^+ ^1 K* D+ k
            # suppose all instances are not crowd
    . s+ J; W3 \; w- s        iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64), s  m, f! d* e; ~9 D& ~
    " m) e( n+ ]* ^1 s# P

    : G7 ?: Z, L7 ?        labels = torch.as_tensor(labels, dtype=torch.int64)
    ! Q3 @$ e% _9 ]4 \9 M  ~9 f% ?# k6 d9 x5 r! F  P

    * m, X  p8 I) B" U; E# }- T        target = {}
    & @/ z4 D' t9 N0 M3 d2 R3 _        target["boxes"] = boxes
    9 ]. ?* n2 ]- S6 u4 a        target["labels"] = labels# U9 C/ x$ g3 J6 w9 G
            target["area"] = area3 ~$ j$ {' A1 ~: ~9 C
            target["iscrowd"] = iscrowd
    ) h% O6 e. j4 M6 E  l1 E- v* ?! `        # image_id
    + \$ T/ _7 b* M/ r9 J5 |' \+ z3 J        image_id = torch.tensor([idx])
    4 i2 y6 f( v$ w0 h, U1 B3 ~% z        target["image_id"] = image_id
    , o4 O5 H8 a8 `9 K
    ! B% a$ F# }( L, M7 C

    2 h' x, e" W2 r4 q1 P        if self.transforms:& x; ?7 @; ^$ t* ]. h
                sample = self.transforms(image=img_res,
    ; ?6 L) k  n! c9 B" O2 h                                     bboxes=target['boxes'],7 g) ^- p! ?3 V+ @  P$ F
                                         labels=labels)$ p4 c" c0 \8 E! k) h
    / H( q5 H. @/ }7 _; P

    0 h1 E" g# Q. {            img_res = sample['image']
    6 I) Q2 l6 S, \            target['boxes'] = torch.Tensor(sample['bboxes'])
    5 g% m) x9 k6 u; ]  k3 v8 F6 U' t7 B9 `# r  y+ M

    6 d7 O: ?0 Z  u% {/ r3 i        return img_res, target
    5 _* S; {4 ~0 d, x9 A1 @" k' g8 U6 I' T( X9 d; A2 s

    * O" D" i' @1 c2 }    def __len__(self):7 T; X% m' ^& e9 F+ m$ m/ ?
            return len(self.imgs)
    * e% a' z/ E9 @( s! @" E# a  M4 c; W# c% v6 }9 ~
    0 x0 [2 v. i  p
    # function to convert a torchtensor back to PIL image! q; s% T+ o2 ]) A5 E9 {. g8 ^! g
    def torch_to_pil(img):; t3 e& j* Z1 I: [8 W- m# o7 ?4 K# l
        return torchtrans.ToPILImage()(img).convert('RGB')( e  c8 M% o# C( {, L

    & u0 p  x" S: h1 x% @

    7 k, H0 J+ F6 e0 Q& Y" [+ W3 {% v, T" D  B5 x
    , w, G% ~5 O; K$ S0 M
    def plot_img_bbox(img, target):/ F* z) y5 |% H4 T. b
        # plot the image and bboxes( Q6 x, x: N" g% Q* }3 J
        fig, a = plt.subplots(1, 1)
    0 \6 L; v! u( c& e# m/ T    fig.set_size_inches(5, 5)
    4 D: [4 Z. L3 y; S0 S1 G, i    a.imshow(img); k' W1 F0 e( M# d0 B
        for box in (target['boxes']):
    : X. P. k+ j* F) i9 e        x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]
    . A/ W9 h  D; p; \0 i8 j        rect = patches.Rectangle((x, y),6 {; B# j; Q, O5 u) I
                                     width, height,
    4 T; X8 G( l- \" ^                                 linewidth=2,
    3 h+ [% m! F5 t                                 edgecolor='r',/ Q/ J7 u" T/ z2 n) V# [& H& B
                                     facecolor='none')  ^( W- w! Y, z% T: f2 H4 K9 p
    6 Y2 D- w* I1 R0 `
    - E. c) w' N' r/ v- l/ ^% m
            # Draw the bounding box on top of the image
    ! |3 W+ H+ m7 f9 N        a.add_patch(rect)  f( T8 f  B! ]! y3 i2 h
        plt.show()
    + l4 }  I& q" m  [4 R1 w6 j3 Q
    # k2 W' d! A( y* x, r

    ( @( q$ B! v- R
    , r4 p) b' m- U6 G4 X, S& b
    - P. m# @+ H! Z+ F. o' P
    def get_transform(train):
    / N2 l* m! l( }4 H/ ^2 ]; [3 Q3 }6 D    if train:, o* |6 @* Y; |' J& Q2 n
            return A.Compose([
    ! w% }; N8 v* e  }            A.HorizontalFlip(0.5),- l, ^' @+ N1 i& r& J( s9 D
                # ToTensorV2 converts image to pytorch tensor without div by 255
    * A3 w& _- ?# q5 ?            ToTensorV2(p=1.0)
    : _2 o+ K& A/ y! |) ^        ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})/ t8 }9 p. |$ D* b/ D# k
        else:
    . \( r0 `# m; H8 X2 T        return A.Compose([- W) X% x8 s8 _8 d
                ToTensorV2(p=1.0)5 Z, I' ]! K7 ?, P4 T- R3 s5 ~% V
            ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
    " n1 N7 E# I& ?# S0 C# k0 @; @* t" K- H6 P, g1 T

    " j) j9 z9 `* ~' A2 ~. A
    & l( B9 I' V1 L8 H" ?5 t8 }

    $ k+ s7 H4 F6 [8 E3 x) i" T: w$ i, h
    ; O4 J2 S7 d6 O, q3 N1 _
    dataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))+ F. ^' k7 R* e7 q* s7 L% d

    5 ]9 c% b+ ]' Q- H6 ]
    2 t6 `! Q: T1 e) I  o
    print(len(dataset))
    6 B8 Z. T1 `) t4 W# getting the image and target for a test index.  Feel free to change the index." R$ l; A# g: l8 [& U9 N: o
    img, target = dataset[29]0 r  w9 q' b% n/ q" p9 m: ]
    print(img.shape, '\n', target)
    ( T( Z* A0 L3 }. i" M: t" b6 Mplot_img_bbox(torch_to_pil(img), target)
    % c0 U4 d1 f  ^1
    5 h/ \& @3 ?& c2% m% r8 N0 t) _2 ]% I2 P
    3
    3 q2 b+ u. z8 ]5 r; ]4
    % G6 I, L& y1 i; ?2 ]  A9 m0 K- `, e57 c1 p1 {+ d5 m+ v. d
    6% _4 Y8 \2 r$ H# _
    7
    " d7 l  m* Y' q9 h2 X/ m83 A1 y5 D& E+ V/ h+ [6 w
    9
    - P0 d7 O# O! B! i- i* z/ s9 I10
    7 F' A+ ?" ]3 q7 S. F1 L118 o# p* g) E/ f+ w, {. l  C
    123 L( v: }* \5 }$ C* V
    13) a+ ^2 \  \' V
    14; {3 n; Y" a3 x; m
    15/ Y: Q4 e9 s$ _' Z. ^0 F
    16: d5 s+ `$ ]' c3 ?
    177 m9 Q6 {8 U  E) M
    18
    3 U' ?! \; c5 d) d# {& J7 e19
    4 \$ B" |% g( K& _20, E( G; i- T0 |( X
    21; Q: C5 S4 |: o2 b( k, d
    22
    % U0 Y2 H. K5 W- L( C9 [9 X$ f239 W6 o4 c) r% M6 t- U) F/ G% V
    24( t2 Y3 E9 L, h
    25; j7 J6 I6 y% ~; G9 j
    26
    2 J1 W* g5 s" H8 O4 _27
    9 ^4 s; [+ w" ^& m6 P+ t+ b28
    " E  [; ?' d- O- A( c6 l. Q% {290 V6 U8 b. s& Z! L
    30
    9 C, I9 ?/ W0 y5 r8 p31
    9 f/ w7 f, }, n, `5 Y32
    7 w4 r; U' {7 o8 [# Z5 Q33
    5 f5 M4 B2 ^, t0 U* ?347 D. ]( @7 x% V1 g5 x$ i% @
    35
    0 `' M( G5 ^" u  ]" T1 Y, s4 {365 l1 |4 ^7 F0 R- X" Q7 ^4 W
    37
    * M+ u0 S/ J. n; n+ N% M& m38( P# ^; D7 \  N4 V. x
    39
    " x. F7 i' O$ @: E: e/ ]+ m40; Q$ a6 g5 I1 Y) k$ r+ L8 n9 |& |
    41
    + F% X- p9 e) G: T% s- n42
    8 j/ q  G% {( F" x0 F9 k) b43
    % I9 d9 I. ~* z# @* g% q, _44
    0 Q2 I+ h; ]$ f/ E/ k% j45
    # K( d: Z0 c. n& {46
    8 i/ b& ?. _: u2 D( F* s47
    , q9 k7 v2 Y' f48$ n9 f& m+ c) J
    492 P8 I4 P1 _; C, `( {& F
    50
    # N% s& h/ z5 O, `6 a, [3 }" z51
    3 p, ]; F; D% e( I+ {/ ^8 i/ I" T52
    . g) s" M4 o  G# o% `5 H, n53# D: Z% Y1 R3 n3 X+ A, K
    54
    . h% C2 L; x" b55
    - \% w2 H: |5 @8 S( T* i567 e$ `+ ^! ^; n4 |) Y2 L
    57' x: w3 A: W6 J( u- h! S- z
    58, W  k! i) T% [0 Y
    59& J7 @9 v: ~( v+ n! v; c
    60, x# `$ m8 T4 w4 }5 \, _
    61
      q; O$ E* l4 N62
      n6 e# Z5 J5 u2 j63
      |; W9 `! L" ^! B3 F" _) V5 l64/ Z# Y5 J0 X: B, q5 ^0 E5 D
    65
    $ P/ g/ |. ]( }; M9 ]66. K1 ~- l) g3 ^
    67
    # L- p' j# C0 s68
    " _8 q5 ]5 ^0 {) M/ z% k$ ~69, M7 Q2 ]% `  c5 B" I
    70( q& }9 ]" s' t( J
    71  l+ F* {0 [. R7 _5 d
    72$ z4 R# _. e! W( ~. L( }  m
    73
    6 ~; t# T6 w) |! l74
    0 v( {3 X6 X  ^  ^75  }6 n  I  G9 G$ ]
    76
    4 ~. @3 R2 `, f  T& D; ~, @% K77
    $ s$ g0 N3 N# O, R# Y# Y7 T( b2 }78
    9 |  ]: }9 ], Z4 v8 _( y79
    + k. b" _2 ?/ z0 T803 ^/ m; |) P) @1 R! n
    81
    1 s+ h8 f% B: \9 {( `5 V82( B( r/ p. t) ^/ F% `4 @/ R4 s
    83
    + I+ r8 d) ~( i) ~/ z( ?84
    ( F, q& ?, I& P) C/ t85
    ' y, k' }( V$ Y: m# _86
    $ z9 P9 D1 e3 r$ w87
    7 G4 ^3 e  f) j% a/ I6 P, D1 ^88/ Z" i9 U+ k7 `3 A7 G6 n, n
    89' G5 b2 T, Q' v& |& a4 m& n) f
    90
    . I1 a- z  M( t  S9 x91. H3 [/ \' j  R% L# g* k" p2 R
    92
    . Y! d, g, T8 D: N, _" f932 F% C1 v0 @+ @4 S. [
    94) M, e/ ^- N- I9 m$ w/ S
    95
    0 D) ~7 ]$ N/ @) p: ]' m6 q967 h6 R/ K8 m3 i
    97
    & T& V3 j$ ?0 s- W98
    . B) `3 K9 F6 e0 {' J1 ]- f* l+ J99% D' \; X: S$ l% B, k2 o7 G
    100
    8 a  A6 K% ^' ^$ C7 L2 N) W101( e9 b- N( g" N# m
    102+ |2 y% H( o+ R9 h/ l* q
    103
    0 R% _7 L8 @# c! Y! N, w; [: a104) q3 u* d1 ^* h9 f) b$ v- y
    1051 K: h8 `3 a" |4 L3 U2 k2 [% m
    106/ c4 Y/ ~- K2 s' V
    107* J7 t" V! F+ w7 t1 e! L1 S
    108
    * c! P4 d9 f* u" Z109
    - Q; U! a& F3 ?( L, R/ o- E1101 w3 E- j+ s" V. G
    111
      |5 Y! P& X1 e112
      f# b- g0 v3 d2 J. w' }113  S5 w& s! g* ]- Q) s* ]) V
    114
    - `; v$ b+ L9 m; r! H115& o6 ^" u3 |: o, R! u7 N! I2 }& U
    116
    & J$ @& U9 T2 x4 I117
    ) S! m! ~" [: M1 p8 M118% Q0 i8 j* `7 M+ b5 V% _  x
    1191 p6 L0 w% t5 f: i
    1200 _& }# ~  r* N3 \
    121. ~: u6 z/ m6 w5 ?3 R2 Q
    122
    3 ^- x5 _3 D' `+ C/ H( k+ ]+ K/ ~123% V9 b/ I# }, L) m  E
    124+ M, z) i) }9 L0 n$ v* o' M" n
    125
    3 y2 C6 t. b; s, V126
    - z. ~  g9 Y$ K+ C# V127
    5 x1 S) z: h1 Q, Q, f, {  b128
    5 c/ o/ ^4 m: b+ C$ G, y9 y129  U" S) @0 @$ {6 U) h7 l! h
    1303 b9 \" o! R$ c4 h+ i0 O, r7 a
    131
    : B$ p# Q' p' E. s8 n8 I132
    ) ^& s  g* O! N6 ~133
    6 d0 b4 K% ?' ~3 r) R134: t6 T9 E' b- j2 o  v3 _
    135
    8 G  ?, W1 {. D+ W& {136
    - h' m) j! N' U/ \% m( m2 `/ |9 W137
    6 t0 u+ ^6 q' ?! a7 G% U- i' _138" F+ v4 Z; l0 a  q+ L6 u" ?0 b8 y6 }
    139
    2 U2 e) a$ W, R; G7 k140
    ; j; \8 z2 {. H6 Z  d141# o! j& t5 g, B
    142, f7 d5 X1 Q5 Q' {* |$ J
    143% [. H, f# Q5 l7 ]3 N
    144
    0 p2 v) l! g5 h# E9 G1456 c/ k" f6 C  F
    146
    4 T5 }* l3 z; v. N" e147' ]* B; E$ N' R, J, p$ o
    148
    3 o' N. {* U$ T. j/ n149
    7 W+ Q$ r2 t; o  m' B6 s2 M150, }- y) s) ], Z" K% M, `
    151/ \' e# k) ^: k# I% n  \
    152: D% |  P9 y0 C) Z6 u+ b) }
    1535 S$ Y! D- i6 k- j# ~1 N; D5 T
    154
    8 ]1 V- b& e* R8 [1556 K: R$ o6 p+ |* t' E. ~! G
    156# b. w9 d( I; A: @% z
    输出如下:
    6 D  ~  T* C$ H# F+ Z3 [& n* F
    , k+ u5 D: B' j% k. I. o. @

    + k6 z9 A( L# m; y. btorch.Size([3, 480, 480]) ( ]5 G' B; G2 A$ q' N- ?
    {'boxes': tensor([[130.8000,  97.8000, 327.6000, 292.2000],
    ' C9 H5 L9 i0 z        [159.0000, 268.8000, 349.8000, 427.8000],
    # W2 V9 l' l+ |! G2 [1 f7 X        [  0.0000, 282.0000, 118.2000, 429.6000],- H& j2 w; c8 l. l- s% _) X
            [ 43.8000, 107.4000, 199.2000, 280.2000],+ r% ^3 g5 O3 u# c
            [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])}
    8 c+ ~, ]% v, c1
    0 {1 J& z7 \! m# z+ G5 Z- ~- g, }7 {3 M2
    - ~& g% g6 A, }- X4 l6 w6 D' y3
    $ v8 S6 c0 D/ G0 {' W0 \4
    4 w0 F* `4 D- a: q: K( D$ g5
    * v2 R5 A0 Q1 z6
    4 n6 k+ i" d9 A/ ^6 Z# q$ r7 [) ~1 c8 L) b8 I% a- M1 Q

    ' @1 k, k$ @* u; f0 a9 ~: b6 w, \
    5 \( z  J" O- ^  Z: B4 b
    , Q2 n' M! ^$ G' l$ O3 l: l4 |; c  c
    下载地址8 \& U) o( ]; g/ }4 e) k
    链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw
    ; k0 U/ o0 P9 m0 O1 i: i# D( p6 l提取码:srjn8 F# }( }6 D1 u: w: v; q2 T
    ————————————————
    2 c& {7 w* `3 ^, ^- _版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    6 Z. ?2 O8 r7 Y" k: N6 N& g原文链接:https://blog.csdn.net/weixin_44510615/article/details/118496273
    * _- a, N6 d" v2 ]1 _3 @9 ]! J5 e( z7 ^& x/ q3 r
    1 I7 ?6 j* {9 b) L/ x: Y
    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-6-16 17:15 , Processed in 0.600469 second(s), 51 queries .

    回顶部