QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3473|回复: 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

    1 q/ @) ]4 q( a8 d8 V) x+ c深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息
    & a8 R( p) z# G8 x图像标注主要用于创建数据集进行图片的标注。本篇博客将推荐一款非常实用的图片标注工具LabelImg,重点介绍其安装使用过程。如果想简单点,请直接下载打包版(下载地址见结尾),无需编译,直接打开即可!
    8 z9 d$ M( z) N  X) E1 s  q
    # y: @2 A6 u0 h9 q5 ~

    , ~- ]- f- x5 H, z感谢原作者对Github的贡献,博主发现软件已经更新,可以关注最新版本。这个工具是一个用 Python 和 Qt 编写的完整的图形界面。最有意思的是,它的标注信息可以直接转换成XML文件,这和PASCAL VOC和ImageNet使用的XML是一样的。
    8 i! k$ C6 M4 \3 P! Q- g: Y: c2 }
    8 f/ t. M3 ]0 _3 w  {$ R
    附注。作者在5月份更新了代码,现在最新版本号是1.3.0,博主亲测,源码在Windows 10和Ubuntu 16.04上正常运行。
    ! Z. P# N, R1 H% j6 |2 j
    ( v! n: H2 q1 h6 }" G
    6 }& _: ?! K/ B4 }1 t$ T0 _
    具体的安装查看Github教程:https://github.com/wkentaro/labelme/#installation
      ~3 m7 {7 F) t5 z% `8 }8 m# _5 A2 }4 j, h6 ~0 d
    # }% c0 ^0 @: D3 [
    在原作者的github下载源码:https://github.com/tzutalin/labelImg" s! O4 u" U$ f& p7 }2 K
    。解压名为labelImg-master的文件夹,进入当前目录的命令行窗口,输入如下语句依次打开软件。
    & Z3 W" \# `) S3 o+ z3 K$ ^* Q- N; q$ G0 m. x

    % p1 Z! C7 _" }2 \: I. o1 t$ o( \% I/ S3 spython labelImg.py9 A+ P0 g. ?. q0 G+ c# F
    1+ B# a; T6 d. o& b. f! Y- F7 m
    / N# _8 ~+ s4 V( T1 o
    3 x7 ~, K: m, m2 G1 l

    ; x' S2 V3 R1 y5 L4 c' Q! c
    - Y4 F" f) e) D. F% r& k
    具体使用9 I( T. m- Y# L; X- g: ]$ @3 W
    修改默认的XML文件保存位置,使用快捷键“Ctrl+R”,更改为自定义位置,这里的路径一定不能包含中文,否则不会保存。
    5 _  g* x$ S8 X# ~, ], C7 X
    8 P- f) q( i$ T6 P# w: D( ^: r, `

    6 g  w& W0 B6 I使用notepad++打开源文件夹中的data/predefined_classes.txt,修改默认分类,如person、car、motorcycle这三个分类。$ p% ]. a# `4 U% n' ~% ^
    2 l7 ?: f3 P+ v" A7 J9 d  ?

    / V$ N3 L" L8 Y% g“打开目录”打开图片文件夹,选择第一张图片开始标注,用“创建矩形框”或“Ctrl+N”启动框,点击结束框,双击选择类别。完成一张图片点击“保存”保存后,XML文件已经保存到本地了。单击“下一张图片”转到下一张图片。- W5 U- R9 m- g- P+ K
    ' N, {* ]' B5 v5 [* `
    9 ?- h# ^9 r3 b* K3 L
    贴标过程可以随时返回修改,保存的文件会覆盖上一个。
      \* P. b, t1 C# N' B7 A. {, ~3 G9 G. T8 i* T6 G
    ! [, d$ }! l: F$ E& P7 K/ D; j5 @9 a
    完成注解后,打开XML文件,发现和PASCAL VOC格式一样。( c, l" Z/ n1 \  m
    . G. k; g3 ?* k# G. i  A+ E! @

    , }7 D( m0 {1 U, _. j- r2 w将xml文件提取图像信息
    - U; Y* e9 v" s: p, K- U& p下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。
    + ~3 k( Z' \- z, X) x" v
    % Q. A4 r- J; B. l

    ; q- P$ d2 I, Z* F3 A6 f- ~8 Z6 b  i% i0 s& t; b; ^" k, }
    ; J5 x- l& B2 V" D7 {
    下面是images图片中的一个。
    " H8 P- E6 f6 h& X: t+ B# c& P, r0 g, {( T3 a! Q

    ; C( @* A1 ~* R0 Q2 L+ R& c6 ~5 x9 l: E7 O下面是对应的xml文件。
    ; p9 _9 a4 q9 h' X# C5 ~/ Q$ w
    / i6 i. J2 [! a: {9 y% ~
    ! W. D: y) Q; s) @3 X( a
    <annotation>  ^1 R3 R; n# Q5 ^' l
            <folder>train</folder>
    8 o6 o# G. }/ L$ ^) c) q7 h        <filename>apple_30.jpg</filename>
    : e. I0 T) k1 ]6 {% t: Z& r$ r# u1 c        <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>
    5 a: ~8 g% J9 e! K& d        <source>
    $ E0 X- B8 A; J, [5 G* ]                <database>Unknown</database>
    $ p; E+ V* U0 \+ G- Y        </source>
    , V2 j$ k# F3 \4 V+ l; _/ T8 ]: K        <size>
    ) C: P3 F& h9 r$ G! m- k- S8 B                <width>800</width>0 ^* W' o9 }( c. ?. l
                    <height>800</height>
    * E! C. }+ q( n  x/ G) }                <depth>3</depth>- y3 L+ F) C8 m( p- k6 {$ q
            </size>3 y* l- h: Q% J4 z- O1 y. [
            <segmented>0</segmented>* S4 ?. W. E+ x9 \9 r
            <object>
    0 [/ d" A" G9 x, G                <name>apple</name>
    : y* K3 R0 Q$ W7 }& }, m                <pose>Unspecified</pose>3 u' c" G0 v2 @9 n1 X- y
                    <truncated>0</truncated>& x7 j" H2 V) K. u% b$ t
                    <difficult>0</difficult>& U9 q+ }3 f: o  u2 x% x
                    <bndbox>
    $ {; e: l0 ~# `, L  P$ Q. F. |. ~                        <xmin>254</xmin>
    & l( f% d; G1 c+ @) B6 ], t                        <ymin>163</ymin>) Y3 E7 n! A3 z+ N, {
                            <xmax>582</xmax>1 q8 {9 ^. ~% k& L
                            <ymax>487</ymax>! ^! K% H1 R/ f6 W! c
                    </bndbox>
    0 @3 C' K3 k) N0 y% h; O        </object>
    # A. o- ?( O$ l% u0 u' B        <object>
    - \7 t: K5 M5 q! b) D( L6 ]! {) `8 O                <name>apple</name># N) ]; J; u, {( P
                    <pose>Unspecified</pose>
    1 `2 M% G7 g3 h( w1 |. @1 D5 i                <truncated>0</truncated>
    & E; T1 R# Q2 e6 X. A- ?0 S) e                <difficult>0</difficult>9 P6 q* S+ o. \! _* i
                    <bndbox>6 \% u+ x' C- p% x7 ~
                            <xmin>217</xmin>6 \5 \- O% K3 m* A
                            <ymin>448</ymin>
    & I0 D2 @6 E2 \# D+ [                        <xmax>535</xmax>
    4 S) r: D6 I& q+ u$ |( P7 q                        <ymax>713</ymax>
    4 e2 X# N8 M( t$ }                </bndbox>
    ( g: |, s& O2 o5 F$ s7 @        </object>. V# }8 ?9 r* @: a% n1 I
            <object>
    8 P$ B* q1 [" u5 [6 }! c" w                <name>apple</name>
    ; x) e' _, j( R0 ?  O- Q% h/ f                <pose>Unspecified</pose>
    0 i) \9 S7 \) c! n+ T1 f                <truncated>1</truncated>
    ( d! b) E' h( G2 ^0 [* ?/ \                <difficult>0</difficult>8 g+ Z* w8 e0 m0 F- @# I
                    <bndbox>* z: q) X- Y- O& l% w/ G+ r; N. ^
                            <xmin>603</xmin>
    / Z5 v; e; l( t& z! v, z                        <ymin>470</ymin>
    2 p+ l2 {8 |+ v. p0 a8 ]9 w                        <xmax>800</xmax>
    % b' J: [! i5 o                        <ymax>716</ymax>
    + i( {) U+ h' p4 ^                </bndbox>
    1 I- c. f7 r  A  X( M        </object>
    8 x7 @) `' @. p  C; o0 b# M        <object>0 V  e( [! t( t  y7 u8 m
                    <name>apple</name>) P5 W: W- h& H3 j& R% Q  }4 O+ j
                    <pose>Unspecified</pose>
    & _9 A3 f- t$ ?. J3 @: B6 e' @                <truncated>0</truncated>! U2 p2 C1 [+ {
                    <difficult>0</difficult># l" v( J  E' c' b/ [1 F
                    <bndbox>/ `+ ?7 e9 Y% {7 E1 r
                            <xmin>468</xmin>
    2 q: d9 ~. p( ]( \( y# i; j                        <ymin>179</ymin>
    ) a; T) k" w2 X# Z$ x# A0 ^) ^* s( p                        <xmax>727</xmax># W: n/ Z# {; y
                            <ymax>467</ymax>
    3 N" F4 |7 }& ^: [7 g, U1 B                </bndbox>& o3 ^7 Q4 [, }4 d; B% [
            </object>% p9 X, x+ I. M4 f- f) T3 z+ ~
            <object>
    8 {0 f1 k; K) P; N+ |1 Y                <name>apple</name>
    4 n) r4 S, y, m                <pose>Unspecified</pose>/ c9 W4 [; Q, F+ a; k5 Z+ ]4 A8 S
                    <truncated>1</truncated>" z4 e& z5 F9 f
                    <difficult>0</difficult>1 p. V2 ?2 d8 H2 q
                    <bndbox>
    $ r0 C$ I, K/ A* t; r                        <xmin>1</xmin>
      C2 o$ m9 g4 d* `8 s; t                        <ymin>63</ymin>
    . }  `( ?, V3 O* L' r% s                        <xmax>308</xmax>' l5 f- X9 b! u* `' `& g. J
                            <ymax>414</ymax>
    1 o! T4 P, C6 n                </bndbox>  E( [$ c6 C. Q, F7 W4 j/ {
            </object>
    ! n: r% p! E" `; \0 j' B) v8 [</annotation>
    9 z" P6 C; I) }7 g5 |15 h/ [/ S' V; K' T9 H
    2& z1 K' V# {; U; C/ w2 O; }
    3
    4 w5 X+ c8 x* v& L4: [7 b2 L6 l* W  Q5 O0 D
    5# C5 y/ y' l- h( _# M- V9 X$ \3 L
    6
    6 v8 A" P3 P) v$ m3 s74 ~% H- f; R8 E* a
    8- y6 U% V2 ~) n) [) J
    9& f6 h* H* r. J  M% p( ?& n
    10
    - i' ]7 Z/ k3 S6 _6 z11) Y. C' ], V6 K& v* M) Y# I( |
    12
    " c3 s; ?$ @3 f13, n0 h" b2 m# x
    14
    , c* F2 K# e+ a/ h# E% t15" I1 @! k1 g- C! ?8 g
    16
    # W8 Z2 p3 q- Q: j. Y# @17
    2 r( G' m. c4 c" [( Z, S6 _! T$ e180 k: p1 x1 t* o+ O) Z8 m  ]
    19! y) m7 Z$ s9 P( c
    20
    ! C* H( O0 {/ C# L; [0 s21
    * j6 V4 @9 h) n* H2 F22
    / h; Z3 q3 L( b; R8 h234 a% _8 _& I) ]% o5 L6 ^( [. N
    24
    7 R' C3 t8 a( l% B25
    . C' P% G& H  S3 f' R8 U2 d26
    0 I6 d' U* ]% [271 G& m: d- a  n6 }. g/ ^9 L6 ~
    28
    9 c/ s+ m" Y( e2 P+ e297 u. L8 ]/ ?" i+ @3 e) m! e
    30
    , h+ d+ U# h& `2 V$ c; v31! b$ C( ^$ Y+ I4 a2 O, b8 o
    323 u# f* A) [* P1 e+ A" X6 x7 l
    33
    9 q6 z% n3 q$ H! c- K4 b34
    , G" m# S6 {. l3 H35
    6 s4 f0 ]0 ^+ [. M: r8 e$ I36
    * E3 q0 T: G- O37
    $ n& c. l. {4 {) s) _' M7 F386 p$ [1 \7 ]! l# O
    39
    # b0 L1 k- a# _* ^: B40
    ( H3 i! X0 |5 _! J3 l7 P6 p5 }41' {, O  _- W) }1 e. R
    42
    % M; M3 L; d" t+ y. |' |43
    9 ^7 N/ R, f, W440 a. B5 y: T  O+ \! _* q
    45
    4 t) T& S7 f3 E3 l0 p! M$ e1 T46
    ' s% L7 N# D) U47
    / S2 r, d/ z1 S/ B! ~48
    , K' c# j& {4 h& F! y4 \498 H( T, j+ E$ D( P3 u
    50  q: g: Q/ S2 g& C
    51/ Z& D( Y. e2 M) p* b! L4 u
    52: i: ~" f6 K1 l; _
    53
    5 N# {( P5 N! q+ \! v, u# M3 ?54
    ( `/ a* L1 P% {' f9 q; Q55
    7 }" O/ f- Y* d) u9 P; L1 J56
    * K6 U; U! Q" U0 Q3 [, _9 s" l1 p0 o57
    " ?5 U  f0 D$ U1 s$ q; x58
    & J/ O, R  P. \# P9 p) I  k597 K4 T" `, d( T9 I1 t9 j0 P
    609 i: G; v2 h# D9 q
    61: L: V. d+ U- u2 ]  {9 p8 c. \
    62' Y" l# z3 Y# g4 Q& M8 D5 |
    63. D* a, Z& \8 G) C; m$ T8 L
    64
    % D/ e) M4 j# s' ]3 r% x65
    " m6 g- D: P- f0 B3 |# A# M9 c* M66
    3 v- A$ s! P7 o& V6 K0 `673 h. P# U/ E5 q# C. ^! |( u1 b; u
    68
    & U7 Y; a' H# A; T# }69
    * R4 o  x2 y: ^0 s( U. t) X) w70# }; L5 Z+ {, J1 C5 W) W
    71, v0 w2 d# q7 ?- o, x% X
    72
    0 D" e' d5 j9 g8 k. Y' s73
    $ u; R2 N* |  S( s. E74
    3 j2 w/ M( s9 m0 h8 i. h# [) d将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。; n: a4 T8 u% L3 |; v# p9 u6 Q3 z

    ! ?; D" J) m, h5 O/ [2 O6 l5 \
    ( h/ R- N8 G7 M
    import os8 N2 m$ _' I2 C) M
    import numpy as np
    0 |3 d" Z3 e) G/ M1 F7 F( eimport cv2
    ! ?" [( X) M& u- p' K$ c$ L  s' I1 fimport torch
    2 C+ z7 \, {; F8 [0 \8 C8 dimport matplotlib.patches as patches
    " @0 C4 Y' E' H: q5 g  o% simport albumentations as A
    2 O0 J  d. O8 M& e* t# Bfrom albumentations.pytorch.transforms import ToTensorV2% T8 ^" L9 H  E. e" N% g/ l' B; x
    from matplotlib import pyplot as plt& B6 y3 v5 ]' h0 D
    from torch.utils.data import Dataset
    + G5 `+ U) J; r6 E0 Rfrom xml.etree import ElementTree as et5 k, y- X2 `/ D9 [; H3 M8 W
    from torchvision import transforms as torchtrans
    & C& P# B, r% @2 m  C$ O6 ]" r3 K' H2 C) J9 t
    1 z+ r& ^- r" B
    # defining the files directory and testing directory3 ]* @8 U1 M; d2 P8 ?
    train_image_dir = 'train/train/image'8 P- i+ B2 b9 ^& Y" J  C
    train_xml_dir = 'train/train/xml'0 j4 v7 p8 q* K4 P) ^" M
    # test_image_dir = 'test/test/image'5 w3 {) |. |4 j  `
    # test_xml_dir = 'test/test/xml'
    5 V( w; e+ Q: k, j4 P+ X) C( Y0 f! x# r/ {, ^, n' z
    + U7 Z: B: \! |9 ~
    class FruitImagesDataset(Dataset):
    * M2 x! B' a& N+ n: |6 H' t$ Q- q: z. C; Z
    4 x6 _6 d( @- t
        def __init__(self, image_dir, xml_dir, width, height, transforms=None):
    ' a) g& }# a2 y7 `( I- L/ [8 b5 ]9 `        self.transforms = transforms
    6 Y2 {! f9 y# {, e; @" A# c* b4 ^        self.image_dir = image_dir5 X: h! T3 n) ?! w
            self.xml_dir = xml_dir* Q3 I9 f- e3 \( [4 u9 h) N' g! h$ N
            self.height = height
    3 Z& q4 r$ V- i* |        self.width = width
    ; F' I, u% l1 H( I+ `- m8 _$ Y% `! X3 _! }% [1 {6 n* K) x
    , {: _0 o1 m! F  H6 B* ~. a. }, z9 `
            # sorting the images for consistency
    0 K2 n0 y8 i  Y6 _        # To get images, the extension of the filename is checked to be jpg  V* ~) V1 f, |5 u! V
            self.imgs = [image for image in os.listdir(self.image_dir)
    ; X- C6 F& \* A/ _, X  N                     if image[-4:] == '.jpg']
    1 [( U4 b. Q) c6 J3 }        self.xmls = [xml for xml in os.listdir(self.xml_dir)) s6 m0 p0 j6 s& u# Z
                         if xml[-4:] == '.xml']
    ( @2 l3 k: u  s2 ?$ y  ^: n8 ?' C' c+ @# t" Q

    # V4 ^2 J' B+ v8 c2 n' ~        # classes: 0 index is reserved for background
    6 b: m7 S# m$ g+ r) S        self.classes = ['apple', 'banana', 'orange']( u* a3 @% ]# Q: z2 T2 {

    , X' n. U+ w& Y7 Q, A+ A) y+ Q

    & [  Y5 j* q1 m$ S4 f3 f- I    def __getitem__(self, idx):2 H+ [' d7 B5 q* ^4 d+ m
    % \4 ]* H' @9 |7 ^, \

    - u9 ?" s; V4 K  p, i  }        img_name = self.imgs[idx]: w3 r& H6 v* d2 |" ]
            image_path = os.path.join(self.image_dir, img_name)
    * H7 d( Y: Q" K- a% D# h: m6 N5 }2 E5 E2 n0 k. n
    6 v8 Q$ r! y% l" `. H* U6 }& q  x% k( y
            # reading the images and converting them to correct size and color
    - r, w) Q( s6 V% P8 ~7 w        img = cv2.imread(image_path)
    * |. ~% A) b. W        img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32); M1 M' y6 C3 {( N) F  F$ e
            img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)* b7 a. v( y/ [; f
            # diving by 255- n+ _+ h  K+ h3 |8 m' B
            img_res /= 255.0
    8 G1 O2 I; Y+ V3 k8 |8 `4 w! o  b7 E# R5 ~( ?3 e7 h+ i4 l* k
    % V9 d2 R) }# c# t
            # annotation file0 A: O! w' u; ]+ n, N: y* O0 _
            annot_filename = img_name[:-4] + '.xml'# P- s+ b- [  |( s. t
            annot_file_path = os.path.join(self.xml_dir, annot_filename)
    " L& L2 K: x+ B+ _. n4 {1 @  o0 S* u5 x  G8 z1 }0 {  p
    ' m9 ]2 e" ~1 E  ?1 M: b% D. |9 M; N
            boxes = []
    + G5 L- k( J4 N        labels = []; z& S6 y# [+ M7 c+ q. ^
            tree = et.parse(annot_file_path)
    2 `9 n" b8 S0 ?        root = tree.getroot()
    ) D  U7 x( ]: j2 w7 i  n
    # {1 A" n% m+ R! j7 x) I; B: }
    $ x3 a. i) ~: s& b9 r2 E& b9 m
            # cv2 image gives size as height x width) f0 Y, M. H  O( K& f0 {$ t
            wt = img.shape[1]! H0 Z% [4 n/ N/ u9 i1 j3 {0 W# d
            ht = img.shape[0]3 `! a; d2 a" h2 K- H9 j0 y
    4 c. G4 s. s7 O. T0 `' F- F0 L
    & ]2 w% ?: F, N0 m: _# N  P
            # box coordinates for xml files are extracted and corrected for image size given7 S3 v% E6 m. A, O$ k; V: s
            for member in root.findall('object'):* M9 ?* N# a/ |) [+ B
                labels.append(self.classes.index(member.find('name').text))
    ) Q1 L( b9 \6 @/ S1 m/ D8 u; Q* X  q, G& _! ?6 p

    , ^; ~8 Y  i3 g6 S+ w# n            # bounding box0 I5 y0 E5 P3 F" ^0 k1 R
                xmin = int(member.find('bndbox').find('xmin').text)! y; S0 `) w- b$ L% U
                xmax = int(member.find('bndbox').find('xmax').text)$ N& H. ~; n- |, b4 n6 a
    * b5 q& x  U$ y3 `( ?* l

    % @: x$ K4 w* K            ymin = int(member.find('bndbox').find('ymin').text)
    & U" S& s; l( `' d0 t0 a- c            ymax = int(member.find('bndbox').find('ymax').text)
    4 I, b# C( P9 B: G# }/ o
    - O/ t/ v" R; R" R" O) r5 K

    ) k9 K. Q: G1 v5 l/ T/ b8 \# Q            xmin_corr = (xmin / wt) * self.width. \- z0 v' Y4 o- n6 W. _
                xmax_corr = (xmax / wt) * self.width
    7 k+ v; G$ o! y3 V$ z7 Y) m            ymin_corr = (ymin / ht) * self.height
    1 D  A& l3 n# H, [% m9 x8 d            ymax_corr = (ymax / ht) * self.height% s. i+ `7 U! |# g9 E3 x* A
                boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])+ C, K! [7 Z- ~0 G3 A
    4 i2 O" o1 K1 \( M5 f6 C- h
    % ?" }! J3 q$ `$ C" ]! G) k
            # convert boxes into a torch.Tensor
    ! ]5 y- y: j& x3 D" [9 L. q        boxes = torch.as_tensor(boxes, dtype=torch.float32)
    : c$ ~  v! p$ I! p) a& M% R  B: {. q5 V6 x5 Q
    . o8 S4 l" y% T' c7 s
            # getting the areas of the boxes0 z$ F6 c% A  R, x' Y! _# U
            area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
    & [% ~+ v2 j7 J0 u( W1 f* q' M0 g) ]/ P9 E' h; g7 u8 m3 |: D

    . S0 U6 u" d, c4 {) W- H9 H        # suppose all instances are not crowd$ |( f6 z  Y: j9 g. J
            iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64)" |5 l2 \2 b, O) v* \7 I8 e1 w; ~# h

    & A6 j2 ~: O- k5 `
    / w( K% p# _5 J1 p' Z) K; u/ U, d' a
            labels = torch.as_tensor(labels, dtype=torch.int64)$ K/ b7 J" s$ G; ]
    . Z1 Z6 ~4 w2 Q! A: z# u3 K

    . r4 q, ?1 Z2 O, t        target = {}) L' Q- B: K# Z2 B
            target["boxes"] = boxes
    7 Q, M4 L, m/ n! q* H        target["labels"] = labels
    ' r1 r$ ~: q5 J' X        target["area"] = area7 y. H6 h% C  r) ^) H2 }- s
            target["iscrowd"] = iscrowd! ~! k$ z% x  w0 T) H, l: R
            # image_id* o7 _2 k) ]% P' o* e( x; ]+ U
            image_id = torch.tensor([idx])
    & i$ v* U, @* a0 m, I        target["image_id"] = image_id
    # }1 q' u' K3 J9 ]$ a1 ]3 U- K) R$ ~3 {
    - _/ t+ ?# c4 E1 q- \# w
            if self.transforms:
    4 I1 t3 r) b% C6 Q            sample = self.transforms(image=img_res,4 i5 i5 f4 G' R! c+ _
                                         bboxes=target['boxes']," f% C( o) d& [& e
                                         labels=labels)
    5 \  v% \6 X/ C
    2 Y  Z. ^5 ]& U* C& ]
    & P& g& l! p) w* m
                img_res = sample['image']& t% O; I! e3 [, V5 V1 U* y
                target['boxes'] = torch.Tensor(sample['bboxes'])( j0 ^$ [# `& i* Z5 M- k

    ( [, B% E7 t; ]1 ]

    8 a& C& p0 p. `; ^' t5 w6 H2 M# @        return img_res, target
    , O: w, j, [0 b2 g' C, a8 t1 f0 H5 f7 L9 d, e

    ' [. T( C- Q6 E    def __len__(self):9 U% {6 F! e& X& r$ _
            return len(self.imgs)7 u% D0 [: D; S% F) F/ [" r& s

    ) d& I/ c$ ?8 S0 K3 z: }
    ( Z) e" Y: s, r& w3 l9 a5 V. b
    # function to convert a torchtensor back to PIL image% ^7 {4 D! Q- T- @) I' E' A
    def torch_to_pil(img):
    - R. H% d* F; E! G1 x    return torchtrans.ToPILImage()(img).convert('RGB')
    6 e# V/ R2 L* F
    - I) m4 O/ b& [( `1 L  J) r: q' D  R

    ; j: U: ~( ~! t1 {9 P/ w% _. j9 q
    0 s- e  e0 @- A9 p0 }) F& y
    # A  A! }+ {2 k1 i. \
    def plot_img_bbox(img, target):
      c/ Y- ]7 E; r! Q    # plot the image and bboxes
    8 O2 Q) |/ Z( H8 _$ ?) }1 F5 L# f. _    fig, a = plt.subplots(1, 1)) l! @( o5 e% ^0 N1 @9 d
        fig.set_size_inches(5, 5)" y, u3 ]/ v8 Q4 g1 I: j2 |
        a.imshow(img)
    7 P3 N5 [) q8 B  z9 ]- |7 l    for box in (target['boxes']):
    0 q& F% O7 i/ e. \0 b0 |+ g5 l7 D        x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]' f8 C6 z: K( K; g
            rect = patches.Rectangle((x, y),
    ! J( @# j4 L% z/ L% G                                 width, height,& C: i# o6 t. N6 R* K- e
                                     linewidth=2,
    - I/ Q& x* p; \- b1 F                                 edgecolor='r',
    2 Z" K+ o5 w$ S: p% ]                                 facecolor='none')' V3 m& |- j4 {" R, ?* U5 Y* ?

    ; D2 R. C8 L- u7 i; U  E( ]

    0 d9 H6 E0 c2 z- a3 w* v        # Draw the bounding box on top of the image" _9 I  g; W! D: F
            a.add_patch(rect)5 M) ^0 y2 s5 F4 \, [& n$ `
        plt.show()" {+ T  H, f/ ~9 Z8 a3 |

      }( k/ u0 u0 ?6 o1 H
    7 c/ d( b1 e) t4 n& d  w; D8 Z
    % J. z8 m8 S' T
    ' g& _9 \0 S0 p$ v/ B4 y
    def get_transform(train):
    5 `0 ?) c* _0 \- i& b    if train:
    $ p3 y- l  C+ ]; H. y3 W/ h        return A.Compose([
    ; H: v+ {; G2 c; [# N            A.HorizontalFlip(0.5),
    : J+ q. W7 c+ M# Q+ R            # ToTensorV2 converts image to pytorch tensor without div by 255( f3 s( l' t# o8 j0 r# h# \
                ToTensorV2(p=1.0)8 {: N& I# P) n  G6 s' u
            ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})6 s& l8 g2 ]. S+ k8 v& n
        else:& m$ C, a4 ]( R2 w
            return A.Compose([
    : M) E2 u8 s( W+ d# O            ToTensorV2(p=1.0); o4 n: C! K+ \' A
            ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
    1 h. f3 _! G3 H* H' T
    ( K. A& b" u+ G" O: D
    2 v8 G' ^. w2 g" a+ x3 a: |1 a
    " u/ y5 O8 y- Z, V) M# W

    ( e) I# w6 P8 B. Q" S4 _3 }) g$ h
    ( X& S3 j* J3 s8 W9 Y4 n
    ( [& B( t  h, r& F( F0 Q. }$ Q
    dataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))
    : {3 }1 }# @$ d) e+ y$ Z# F, S% D  E1 c+ p% |1 `. j* @

    7 `# X4 ~8 ]0 U0 t+ ?% Rprint(len(dataset))% o9 ]" l$ ^# D! |
    # getting the image and target for a test index.  Feel free to change the index.
    ' h1 x; r1 T% x' E  F; Rimg, target = dataset[29]$ v/ X0 D( D) A3 Z7 J4 c/ Z
    print(img.shape, '\n', target)+ T) E  n- W. o5 u6 z3 F
    plot_img_bbox(torch_to_pil(img), target). A" [$ K1 {5 g8 M) M! g3 x
    1
    - F( l* i0 F) T* b0 V/ x2
    ' l' n" x/ F2 s, z) v' k3  f" ]5 ~0 ~+ s* K
    4
    8 C7 y$ a! N* d7 ^' _3 E5 ~5
    " H6 S  o+ {' D: e& _6' U, E  C" W* {" F9 b
    7+ x' T& q$ @$ X# I# M
    8/ p* W1 P9 w4 ]) A
    9
    : R% w: ]" i  l; O10
    ( |/ D; Z4 c% d11
    * I+ M& u6 ^& p+ u8 E3 N3 i% @9 Y129 _( O+ H" r) l/ b# d" f
    13
    ) S: W1 c; W! ]2 Q6 K6 f# s14
    8 G+ u7 e% k. ]; S! ]8 G15  v; a: B7 f+ S! R( f% J
    16* k5 V' G( Y5 I" K- s8 p6 Z
    17+ E0 {3 a& n& O7 [4 X" f4 f
    18* L0 M, ~4 h+ Q  |+ n$ |2 D' w
    195 I2 A* i5 K+ O
    20
    # G) v! f, H$ G6 x21
    ! k( U) t+ @1 c; b& \* r7 m* K22
    ; D! F+ J# n: e) b6 _239 q& M1 K5 @1 n. o* f
    24
    0 k6 [# d5 x! n* r4 R! {25
    & h+ d( m: f, c- D7 `+ T* W26
    0 D- r7 D$ U8 P1 x: R; z0 t27" F- @' Z$ K  S& M/ T: Y0 m
    280 L% p$ A* g: N, e  d5 H
    29
    ! R+ [  l2 a5 W( ]* H5 l303 a4 m/ Q) {0 S
    311 s5 L: h  U. `( p
    32- a8 K' l4 h5 E6 A% t! u# K
    33
    6 d- I/ {. a& y6 V34
    9 N+ r. g0 k9 v4 `35
    7 n, @  N" N6 ^4 B1 V36
    3 I3 o, ]& a! G* P37
    9 ]* P% _1 I5 O38
    0 }, U7 |* M" m/ t  b5 U6 Z390 U5 L0 N0 i! A) z' M% A
    40
      j0 X) z- g0 J& `41! W0 V7 j& D" o  ~5 V
    42
    3 \7 i: m. P$ v43
    2 s7 T! i8 r% `  H44& \: [' u" R0 J; \
    45
    " z) f% A& a- {4 f' `" s7 n/ n46
    % p: N% W% U' z# W4 M47
    8 J/ u" x: K- s# x! |48
    - o5 E; R6 Q$ f49
    8 c; I) l# |. n50; Z+ @! c$ u  u' W7 G1 a
    51- }! b. E3 Z8 t9 k! W9 F+ n4 |- M
    52) Q0 M5 t1 v9 D3 G4 t. ~+ C
    53
    " I2 C) n( Q3 J7 M, s  ]54
    5 u5 \! e# R# x* A* E55; [. P9 _" V2 a
    56
    6 p& S9 t; i+ Y  a  e7 H( H57
    $ P: l5 V9 x- l4 @58
    3 q5 d3 C# N1 R3 i3 p9 a# {59* ]- ]! B4 L1 |. K$ Y( i* u3 f. v
    60- a0 e2 w" ^  p$ ^/ E2 }! i
    61) `) P4 j! x& v
    620 [2 |" U7 D: P' U, Z
    63
    " t+ G  Q1 l# g' k% O64' e4 ^& \; X. J. |7 d" Y
    655 T  }; A- ~7 k* X9 p
    662 I- I  o7 o" [! D7 ]
    67& R6 I$ Z& d, L! [
    68- w  [- }: k; M0 i3 i
    69
    $ W" L, t0 b0 U( \1 a- Z70
    . u& M+ d  m/ c) c0 T) J0 F2 x715 ~8 k" `9 d7 ^2 j4 W1 }
    72& p+ p, c( J/ T( A
    73
    0 h! k  G" U8 b6 w, h745 \5 O6 g7 W1 R7 {% m; L$ K
    75
    5 P, ~& ?* X( n  @. P+ N, U76/ y5 o% u- G- e+ L0 C
    77% F9 O2 ~. }& z7 T  y4 J
    78
    8 E  V' E- ~4 S7 ^79
      I/ f- B+ I/ l$ M; @# ^) |  f80
    / D4 {  _3 ?; u' y" p9 _# D81
    . k! c" a6 l! V7 f) B# r& i5 s82% Q- A% |$ {7 e  O
    83
    2 y/ [5 }0 R' b; x0 D  V) z84! b8 U1 B0 M" X" ?6 H
    85) Z, h1 `4 Q& F2 M3 N6 y0 W9 x
    86& X. ?. Q/ H, q7 H
    87
    ! `% K! B+ i1 j& k88  W5 r( D* r/ {+ A* d
    89
    1 _4 |( }# O- g- P; |906 I6 L( {  I+ U. J- j' k; D( ?5 x- a; R
    91$ `% a  X0 u# E+ s
    926 p5 u4 [& J* y
    93
    ( v6 b  Z5 T# Z1 }* ^# O94
    1 u4 g4 B/ @% t. ]95
    & g2 \3 L4 O. Z! P) H6 E3 x: t96: Z! F' |" n) Y" x# T
    973 d, j, s: _2 j/ }% {1 A" r
    98
    & L& B8 d4 E; k1 Z' |99
    6 W; N. J, J6 V100
    ; a6 s# {; L  _$ g101
    5 w  L' L) b2 F" T1 c102
    $ w# R& l0 p$ i; x4 I; O1 @" x) C" g5 B* X103
    / M8 e9 z0 ~2 i/ p& N8 m104
    . @/ C8 a: I3 S# m5 Q5 H, O1053 k  z/ @$ T: s0 ]
    106; H- D+ l7 @& Y
    107/ {/ ~! f% g% n& u  i7 l
    108
    ! f  }# ?) ?' \/ @$ T2 z! f( t6 a109
      @; y. G( T1 v7 n' E6 Q. C( _110
    4 L- Q% ~  _. y# \' `111
    $ g/ X9 K. d, b7 l; G4 [" k- D112
    : k  k) m  c6 P113# j/ J: ]9 Y' b* `
    114, \" ?: w( u1 ?( d) E8 B
    115& m+ n2 j2 ?/ a2 @( x
    116* y$ |" a4 n; {, E5 @0 n
    117) y$ V7 L4 D+ t4 {* s- n& B  ?2 |
    118
    : H! X7 n& U& a: ?+ o1194 x7 m: R9 L- A) A
    120
    5 ?8 B* L0 D- s* l$ g* K; k$ W121
    7 C1 ?7 Z5 g( g" L122
    0 |, H) l( I) X) z123: }& V8 s" Y$ v; S" q/ O. _
    1241 b4 ^$ {. g, u- l( J9 J
    125
    % e& }; L7 {" b; ]8 _) j, }3 A2 i' W1260 \  I- {, `( j- i9 T
    127
    # ^6 s0 a( W/ t- H0 b( x128
    : T3 ^9 B& \  Y$ \, H# f1 c, G129
    , G8 ^+ u2 e* P8 e0 j# `1302 T' ]6 w, B: M8 I
    131/ \* {, }0 ^9 U" n4 u& S
    132
    ; ~0 }1 e, L5 `- z6 R3 {2 A133
    8 j6 l# b$ c* @' m4 f, }! A134$ U& `5 r8 B7 p: ]* O
    135* r& Y$ T9 q/ }; d/ u$ C8 \
    1363 X* r& H! b$ ?" g3 r2 Q
    137
    5 d7 D+ y, {$ u6 l/ L' O- A138
    # I: Q0 k3 X7 g139% [! A) z7 t0 `) t& B/ [
    140; O7 x* Z# D6 p3 p
    1415 L0 d) `( I- m8 T% l. P4 ?5 g
    142$ T5 b# h, _  k5 i- v; \
    1437 d) X& w) ~! _8 v0 J
    144- e' ^/ k9 p; [& C$ [- }2 z* h
    145. ~# M$ T/ M, V! Q
    146. U7 i0 i7 N: Z  Y  D
    1472 s, f1 i9 T* u4 r* y
    148) g$ O( t( E6 L4 x. t$ d6 \4 J
    149, e. J6 R' c3 x; Z
    150" a4 @7 O' t2 Z$ c+ P7 ~
    151
      P# m" q0 ?9 V/ P152
    ' `" N: K! z5 H* W$ j6 D153# z7 M8 R( v1 o9 h9 ~
    154
    8 b8 F1 g$ K+ \" t( X& |155
    * P* d- k# W/ l4 Y+ S$ S" E/ s1 a: h156
      w4 q2 m  ~, }6 L# P输出如下:
    3 F: n6 D: I$ H' K- I# ^4 p8 O0 r4 k' H

      t2 N; p; J; x# Z+ m  L0 m7 ntorch.Size([3, 480, 480])
    7 f- g- j) `5 A {'boxes': tensor([[130.8000,  97.8000, 327.6000, 292.2000],
    9 ^/ L5 s$ |+ }        [159.0000, 268.8000, 349.8000, 427.8000],
    4 o! ~& F- {4 _) x, a6 A        [  0.0000, 282.0000, 118.2000, 429.6000],+ T8 v2 f$ W' c! E- P- D. f
            [ 43.8000, 107.4000, 199.2000, 280.2000],
    1 q$ [# s+ L% X& a4 R        [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])}
    5 h- z' W  i# n8 W. w1
    $ b3 a( _& j0 c# A! `28 w& U! p/ ?: @; Z7 I
    3) A6 q# j) ~% h# n; a2 @" I$ U- x
    42 i8 |( F' \5 Q0 T( k3 V# k. r
    56 D: o+ s( S) W- ]- u
    6
    * O# a; `- m% c4 i" Z; p3 I' z" Q6 B. M
    " m6 q1 _0 R3 G- j* T

    ; S0 I1 d6 V* c9 l7 N" l: A. n
    " L& m, V( x4 @, c, V4 W
    下载地址9 G; ?% f! ^* a; L
    链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw
    3 c5 ^. A2 D! ?/ O提取码:srjn
    8 a" r/ W8 C- N. r6 K: t- }; V————————————————
    ( Q+ t  T% z% ?; Z版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    3 X% L0 e8 w0 u0 y原文链接:https://blog.csdn.net/weixin_44510615/article/details/118496273
    , y3 L- E3 y( A* \9 }$ g) v( t- v) J7 v
    4 x% v- D. _- |! R: x
    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 18:41 , Processed in 0.441194 second(s), 51 queries .

    回顶部