QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3528|回复: 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
    ( E! R3 Z. W2 K. ~) e8 b
    深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息7 T! Y. W/ l" W2 Z- {9 G# Y
    图像标注主要用于创建数据集进行图片的标注。本篇博客将推荐一款非常实用的图片标注工具LabelImg,重点介绍其安装使用过程。如果想简单点,请直接下载打包版(下载地址见结尾),无需编译,直接打开即可!: U; a, F% P1 s3 Q5 I
    ! z8 f6 U' B4 u; E
    " B/ t8 M- I4 K0 Y
    感谢原作者对Github的贡献,博主发现软件已经更新,可以关注最新版本。这个工具是一个用 Python 和 Qt 编写的完整的图形界面。最有意思的是,它的标注信息可以直接转换成XML文件,这和PASCAL VOC和ImageNet使用的XML是一样的。9 Z1 \" D  }* s" q6 a
    ' K: G/ l; t- k) o5 s

    ) Y6 g. j4 y4 G9 H- f5 h( {  v附注。作者在5月份更新了代码,现在最新版本号是1.3.0,博主亲测,源码在Windows 10和Ubuntu 16.04上正常运行。1 |" R% Y0 l. Z6 O' I: m- }

    4 G% Y' G, u- t6 {. {9 E. e  V  m

    ' X2 l; Z$ ]3 |9 I具体的安装查看Github教程:https://github.com/wkentaro/labelme/#installation
    5 I8 c# @9 n- M4 H$ l% }, R
      c+ X  {, U: ]* l6 d2 d6 J4 i

    6 e6 m$ ~9 _. R/ m在原作者的github下载源码:https://github.com/tzutalin/labelImg1 E# W# w7 P/ @) z! Q; t
    。解压名为labelImg-master的文件夹,进入当前目录的命令行窗口,输入如下语句依次打开软件。
    4 c) A: {% P: o% j
    & R" O3 U/ ~- o$ V( ^

    $ p: u# N( y( Q% Wpython labelImg.py
    5 K  b- M. N) \4 b' m' ^* r17 W- x- `1 M' J

    ' Y" n. `3 x- z3 g

    8 ]6 h" c5 {5 M; J; A! w
    6 d6 z. b$ k& h; K$ X
    ; n; \" s% J& a4 v, a
    具体使用+ m: D/ G# T; {0 J( G
    修改默认的XML文件保存位置,使用快捷键“Ctrl+R”,更改为自定义位置,这里的路径一定不能包含中文,否则不会保存。
    , w  P( Q! L' a3 d. N& O+ ?3 d; o- j- }/ I# ~$ ?- k  I9 ~

    ! P! \9 e- o# @* w6 X5 D使用notepad++打开源文件夹中的data/predefined_classes.txt,修改默认分类,如person、car、motorcycle这三个分类。
    9 S+ l& x0 o- u* E
      |: \. f% ]% p3 r; g$ B
    4 |& j5 z$ z1 M) S" Q& V/ H
    “打开目录”打开图片文件夹,选择第一张图片开始标注,用“创建矩形框”或“Ctrl+N”启动框,点击结束框,双击选择类别。完成一张图片点击“保存”保存后,XML文件已经保存到本地了。单击“下一张图片”转到下一张图片。
    7 V' f) o, P3 B1 [0 X& `" y8 C. G) A) ^/ b' w0 Y

    ( ~2 _# R$ N# V$ b5 o9 R" t+ P贴标过程可以随时返回修改,保存的文件会覆盖上一个。! m1 `# n) ^1 B  V$ r

    : ]$ b: n0 g4 e: |* N0 O/ _

    7 E0 {  U+ w9 c* O! k( r完成注解后,打开XML文件,发现和PASCAL VOC格式一样。
      o& K; v% C: l5 N& c' ]7 t
    ) S, m5 z+ T" b1 ~
    8 B- T& p, ?; |; h. _
    将xml文件提取图像信息$ B" L- P( o& w3 @
    下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。
    7 @! u0 B) X' Z. h7 U) \$ b
    . h3 H- }) Q+ h5 [

    - n+ h+ b$ }4 s4 e% q; m7 F
    0 i! o* J2 @: }, {

    2 f' c& }9 H0 v1 B1 ~4 @3 `下面是images图片中的一个。
    5 D, c  I2 y) ]1 E8 Q; ]. W' Z* ?4 u0 W( ]

    4 g# |0 Q+ I5 u' X下面是对应的xml文件。
    * S1 k  e" p( ~, L; N  r" O2 c9 p" }9 a4 c* N* c$ n* ?0 F, o7 t

    5 o! A8 i# z+ f4 R$ i' Q<annotation>( ]6 s2 j* r' ]. c3 e
            <folder>train</folder>  P6 G5 k. W) j
            <filename>apple_30.jpg</filename>7 u& r  \8 Z6 C0 F$ b) _3 Q
            <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>
    $ N) B  A. C; t0 V1 r( U0 H! `  c6 f        <source>
    5 C! _1 C  {2 V1 P                <database>Unknown</database>
    9 g% [1 Z0 Z) m, ?  `% @        </source>
    , R6 ?6 X8 D9 z" s6 [) @        <size>% r$ t6 @  {, w; X
                    <width>800</width>) r* d& ~; A8 x, p7 ]) V
                    <height>800</height>
    ( S. i. I" q: g7 C( ~+ M0 e; v                <depth>3</depth>  K3 G' @4 n" s  v7 [
            </size>& k, c; B% O0 w. W# {$ |' X# v
            <segmented>0</segmented>( p* [* a; G, S( c. u( i
            <object>
    + l- t/ L+ {% f$ F$ z& @" |                <name>apple</name>9 r% _- ?2 q- @1 u+ M
                    <pose>Unspecified</pose>" F) ~3 v4 {$ [5 {9 m6 X
                    <truncated>0</truncated>
    5 B) A5 R" }: i3 C" i7 u; D                <difficult>0</difficult>
    : y+ B8 b8 W2 Z# g- g9 F" r                <bndbox>
    $ L, l8 v" k/ l& @% ~) i  G  F                        <xmin>254</xmin>; R' T4 w* L( |/ {  S
                            <ymin>163</ymin>
      M8 }/ f% _- k5 t4 ?/ |* N                        <xmax>582</xmax>
    : |* i# q( A: g5 t- }( r, S                        <ymax>487</ymax>  u. u+ a! @" B  [' j9 b# W. H, d
                    </bndbox>
    # J; W& O7 p9 z, o3 T2 H) t        </object>. a) ?  Z, w+ C& p- P; X
            <object>' g+ m, E& V5 [- D4 {- J" }
                    <name>apple</name>
    & L- I) V. C$ V/ [; r- M/ n8 a" D                <pose>Unspecified</pose>) k# V, `- e; w) }9 i1 X/ Z
                    <truncated>0</truncated>
    - ~* g9 ?1 \/ ?* k                <difficult>0</difficult>
    # l3 N" j& T! p7 @5 \& z( R                <bndbox>
    ! y' S2 h5 H- ~# U) x# \! T                        <xmin>217</xmin>! h- v  v- x9 L, }) h
                            <ymin>448</ymin>
    8 d  L0 ^$ s# h3 z' y; y# i                        <xmax>535</xmax>
    , C2 u0 {; f, t  t                        <ymax>713</ymax>
    : _2 F* v) m6 ~; c5 c                </bndbox>
    6 Z; a4 [2 s# o4 H: F% H5 ^        </object>
    / J/ U7 x5 \0 K, p0 M        <object>
    + L, w8 e& c2 `: P                <name>apple</name>
    / _; [4 ^9 P5 w1 T, O, W                <pose>Unspecified</pose>
    5 K/ H2 ^1 `8 X) v0 P7 l, ~                <truncated>1</truncated>
    * j1 S% l9 Y2 X) \$ G                <difficult>0</difficult>' o  O; M" m/ j3 a/ l
                    <bndbox>2 ]& c# C9 \9 T) N
                            <xmin>603</xmin>
    ; v. o5 u& F5 m, N' B) b                        <ymin>470</ymin>: H) O8 ?8 \5 {  V
                            <xmax>800</xmax>
    3 n! ]- j# z6 h7 M                        <ymax>716</ymax>1 a; Z% a$ i0 P$ w7 A9 Y- ~
                    </bndbox>( r4 W! U! t5 K
            </object>, z; o' u+ q2 n
            <object>
    % f8 ]0 I! T/ q  {, c' g8 y$ q                <name>apple</name>
    ' g! ?. y$ C) m8 j  i                <pose>Unspecified</pose>: }3 u1 j6 T  a0 q, r( F
                    <truncated>0</truncated>
    + \$ f# E& D# O' o                <difficult>0</difficult>
    ! w" \! b4 @( F1 z% H7 c. c, Z                <bndbox>1 m- S2 u1 B, C- }" y- B. M0 J
                            <xmin>468</xmin>
    * L& t) |  k1 ~1 @' P7 h4 k4 A. l2 H                        <ymin>179</ymin>" B1 g' }. }8 k3 f. o8 ]
                            <xmax>727</xmax>6 `  M3 p$ R) [% j. B/ X9 z
                            <ymax>467</ymax>; V; r+ J2 m6 n6 O
                    </bndbox>$ U9 v0 n' K7 F; N: \3 ?
            </object>! O( P0 S2 ^/ I1 Q" U$ p& o# p* g
            <object>1 {& T6 m! w" ]  G# T& W
                    <name>apple</name>$ e( p2 X/ {' O" n! o
                    <pose>Unspecified</pose>6 P/ K3 T# M( G5 `% U% f
                    <truncated>1</truncated>2 I0 F( X8 A9 Y$ J( j% y1 _: b
                    <difficult>0</difficult>
    / T+ r+ [' d; D- @                <bndbox>1 N4 _" z$ G7 y4 _
                            <xmin>1</xmin>
    , ^1 l  q/ p# g& _  r3 K1 e                        <ymin>63</ymin>
    : I+ u' V1 m; M% T% |' D" ?. P/ N                        <xmax>308</xmax>" M5 F9 q9 `9 p- C' ?, z1 m. A
                            <ymax>414</ymax>: J. ^* n/ `; t5 S6 h; F
                    </bndbox>
    ) X% _; q- T2 E7 Y8 ^) j% @        </object>; A" D, o3 [. y- [
    </annotation>4 r7 }4 @% M5 i9 w  C5 ~
    1# l4 h; H8 `% D! V& S0 g- W
    28 E: j+ F  e+ R3 t; V& T
    38 F! I0 T( q% p
    44 t! D! ?% B/ O- u3 P$ Y
    54 b9 z  p! [; C- a! N1 G
    6
    # h1 _: Y  B- s5 }: ~. {7$ G" ]6 R+ F( j) h1 y
    8
    4 r4 z2 G( r! K2 _5 N* x3 f9/ G. x! [. r3 {7 J/ [
    10
    0 R, l" ?8 Y3 W$ Z11
    " {  w# B- u$ ?: r! a7 a. j: B0 ~12( s3 _* C0 a% H% B, i& @
    13
    ! A/ n/ f( `& B14
    ' V8 m' d3 Z. j7 _0 {+ Y15' j* h5 K5 K. ]: C. \5 u
    16
    5 `$ F: i+ v3 d9 h6 {( ?8 H/ `177 p1 X) s7 s  ~
    18) N" y' J/ ^* H. K  g9 n& ]
    19
    & u  {) Q8 Y, s3 t' T9 B20. W. _6 u! {. D- p- Q9 {
    213 U( I* ]( A, |' s, i
    22
    1 @" _/ }9 _2 M5 W23) s( O  p5 v3 C- b2 H; n. O( T' ~
    248 w6 s* s2 i, q) u, J
    25' [) C2 p- h9 H- a& I/ n; |% }) _
    26
    # a7 @2 _3 Z" E- {" z27
    $ m+ i2 _9 U1 d2 v28
    & |2 r3 v6 Y) I5 Y29
    - p0 _1 t& ^) M; I30
      s9 o+ s3 Y9 [1 U/ P31- y& U: N- G4 y0 [8 d" W: f% T5 n
    324 N( A( q3 G6 a% a4 u4 i
    33
    1 ^* i$ r& X- D) a# ~+ i( V34& C' C" U0 g& S
    35
    3 \. \) f( o, E3 }# e( i" Q36/ c7 |9 Y" m. j
    37- v, w5 s  N; ]5 G6 o4 ^* C3 S
    38
    9 [5 z: n1 q8 h1 j9 N* V) G39
    1 T+ t9 u: o$ G8 E7 n. M40
    9 Q) U9 n, a, h4 ^3 B- a& T) ^414 |! G" I5 H8 K0 B( ^
    42" M  h; }. h, b' N; v6 Y
    43
    8 N% @6 l7 @3 j3 Q" A0 u44
    : R' g& D" N. R4 B# Q5 z% }45
    / i5 M: m1 N* ~% L: {. _46
    " V; p% i6 X5 v6 n7 w47
    # ?1 o2 ?$ F+ g0 d/ f3 }$ O48
    ' B1 w! w* [  E$ V: b( i7 v499 d6 V" u$ |1 t. k& ^8 k
    50
    ; N% e" t# {" b6 c+ j  G* T( i51. {) m( E  X! e. T$ c0 ~  e3 `5 b
    520 H! C/ j8 F" i9 B" Q- e% Y
    53
    1 r# m: _$ x$ y- O) F54
    ( _, H2 T5 y4 k4 a4 o3 k* ?, U55
    4 ~- H9 S! t9 c; k) Q* }! W9 k56
    7 N: |) L+ m8 [" O' _. [  E576 R: G# @, X; S
    584 n0 U0 E$ n" e4 V
    59
    # f/ ?1 I7 N0 b7 }$ h' s609 o. D; K; [2 O5 n
    61
      y. u/ l5 `. t3 u) k. p62
    1 J0 d" z$ a- l: r* S5 _* ?( c63
    ( h6 n2 g  }! `3 t642 g' {) g3 m% c( v% v5 F; b" @
    65
    3 L- z' g0 Q- S& i) |! f) v! D66
    8 L* M3 n% m3 V9 Z1 ]& h" F' ~0 s; K67
    3 {2 |1 R$ C, N$ x. ^+ M0 }68: K5 u: K# B. U* Q
    69
    ! e; X7 K( N+ s4 T2 C2 g, {9 M70% H$ S. g& |/ n; n+ `$ \6 a2 x8 b' m
    71
    ! L. [& g2 o+ k# j  @727 X% d+ L7 ]6 X' D* Y
    73' x* D( d3 o! E- F
    74
    + g2 t$ t2 d5 u* s0 U: v将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。; J  q+ V' o, q: l: O  c( ^( o

    9 v. ?# z/ F7 w

    + Y' z2 l- R; @5 U9 s+ P2 p; Fimport os2 H4 @+ _) }! R( |- F5 Z3 d& N
    import numpy as np; o* |7 j/ b/ j. Q3 C) N
    import cv21 \* J) p3 h( s. F
    import torch* k- \+ j9 c/ H4 s
    import matplotlib.patches as patches
    7 M/ N8 u- l1 g* L! Pimport albumentations as A) W! m+ J* Y! f) ~3 H" X4 \
    from albumentations.pytorch.transforms import ToTensorV2
    ) c+ [6 u4 z6 ?$ mfrom matplotlib import pyplot as plt
    & X% H8 Z) n5 Q, I& afrom torch.utils.data import Dataset* Z# |, c4 s* n. W
    from xml.etree import ElementTree as et
    - h; p. U1 Q; O# M% x; O5 A6 hfrom torchvision import transforms as torchtrans
    2 x& K6 E0 g$ H. m# f$ u
    , V( p" L# s; ^5 n9 q' p( j
    0 H& L5 ^- F- \# a& u+ p, P( z
    # defining the files directory and testing directory
    & t$ O- ~: e/ \( C8 V0 K! D& Otrain_image_dir = 'train/train/image'
    ( G: c6 {! R6 o: u) U9 mtrain_xml_dir = 'train/train/xml'
    . `3 K( e+ m; A# e' ?4 @# test_image_dir = 'test/test/image'  ~( a6 S3 t0 K  H) G
    # test_xml_dir = 'test/test/xml'
    : t1 g9 l9 H1 v+ C: Z& B$ j9 [5 `# G1 D
    " l$ E  u: n3 s* R4 \& l1 h+ e
    class FruitImagesDataset(Dataset):/ F% W+ }. i+ j' k8 l/ C* P

    3 M  G! }3 H5 ?. b' [3 K2 }" R4 l8 B

    8 m' Q# ~. ?/ }5 `    def __init__(self, image_dir, xml_dir, width, height, transforms=None):
    # M% a3 N' z- ~7 l( D        self.transforms = transforms
    ) n7 J" J# Y: {* g9 Z        self.image_dir = image_dir3 }7 K5 P$ O: e7 x' d
            self.xml_dir = xml_dir2 Y" }6 n% e2 W& _/ @
            self.height = height
    / Q6 @3 |" {; x+ p% Q% x        self.width = width4 P3 u- A8 y( Q- _% _1 u: O' r
    4 t% E$ f! m# J& ]$ Z% q. \& p3 Z
    0 T0 ^1 {+ R) A: Q
            # sorting the images for consistency
    : V, M6 H. o0 B0 b3 N- ]0 }1 H9 I        # To get images, the extension of the filename is checked to be jpg
    2 u/ B9 o* V0 {# i( X$ T3 ~3 A6 Q4 g8 O        self.imgs = [image for image in os.listdir(self.image_dir)
    % j& A1 [- R: G                     if image[-4:] == '.jpg']$ K7 u+ Z4 H" A0 P8 P
            self.xmls = [xml for xml in os.listdir(self.xml_dir)
    : k& L% D3 {) b3 C: p( `                     if xml[-4:] == '.xml']$ H7 v: j4 f1 Q& r2 F+ V0 ~

    ( [( K5 w9 D6 U( \8 Z, \" D

    + i/ ], r: X9 P: C        # classes: 0 index is reserved for background8 U8 c9 J2 O1 L# c* h$ N
            self.classes = ['apple', 'banana', 'orange']- p: Y5 `( i, b! U1 _

      h4 S; d' `3 g, m1 m9 H4 O5 ~4 E9 J
      }( I) j/ W/ n5 |* p& C7 h& ^
        def __getitem__(self, idx):# W5 `( V! r9 v8 z3 u- B: J2 k- n
    & D4 X' P3 T0 p$ G

    4 R3 S; t' H. h* P) q        img_name = self.imgs[idx]3 X- a0 d3 L( Z7 W% r* o" t( l
            image_path = os.path.join(self.image_dir, img_name)
    # A+ A* k- N( G# K- M( R. q' d

      A& L0 Z3 A2 l7 o' q, s        # reading the images and converting them to correct size and color1 j( d$ E9 p" B/ o+ s: t
            img = cv2.imread(image_path)# R2 D4 Y; @0 e) R) h; A( c- c2 k
            img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)2 ^  d7 V& H; }% [' @* z3 V2 t+ G, g8 T, C
            img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)6 }2 U8 |5 k" S
            # diving by 255! i0 J8 i9 K4 B& l+ |: q' v9 @
            img_res /= 255.0
    6 |: Y! P/ w% I
    $ d; W" @" D/ ?1 i) G. U* V
    2 J! y+ k( C- G* u3 ?
            # annotation file' y4 y" B% K8 c% N4 m
            annot_filename = img_name[:-4] + '.xml'( N& G! d' Q( g1 {
            annot_file_path = os.path.join(self.xml_dir, annot_filename)
    ; i$ \! U' q5 h, q- f
    ) g& ?2 P1 G) y( [' l; M

    * v/ l; |1 i" @! ~        boxes = []
    / Q% i; K3 A, M1 e! W        labels = []
    4 v0 G/ d, }8 X        tree = et.parse(annot_file_path)
    " Z% v+ G$ T1 K. D% u+ m( A        root = tree.getroot()9 R4 _5 L+ Z  \8 V( q& Z
    ) `% c+ d1 J8 F6 m( F8 B) s
    6 f* y  B- J8 w3 M& P1 w
            # cv2 image gives size as height x width# Z# O- V$ x0 r. S5 v0 N
            wt = img.shape[1]* }- _2 l8 W1 u6 h; l. U; Z
            ht = img.shape[0]
    2 P7 P  Z, p2 A$ n" I3 ]9 _' I. ?& G2 t) v2 F: C. t

    6 `/ ]1 m4 J  n8 ]$ {" N5 E# T8 [        # box coordinates for xml files are extracted and corrected for image size given
    $ z- G8 w$ A. l4 c6 x        for member in root.findall('object'):
    8 ?! ~$ J& x1 }/ }& T. w            labels.append(self.classes.index(member.find('name').text))
    : X! g- b% N. {% D* y, H
    / q& E! L# D# S: l; b! o5 W8 z
    + N. O) o3 B0 m- b' S
                # bounding box
    . {4 h: l, e% t0 |            xmin = int(member.find('bndbox').find('xmin').text)
    ( p  R0 i1 g- T) D1 \. Q% \            xmax = int(member.find('bndbox').find('xmax').text)
    * R. D) J1 ?( C8 n
    9 i- ?  V( g% S0 O, O

    ( R  P# i' N8 `' h! ^- ^, J            ymin = int(member.find('bndbox').find('ymin').text)
    ; z( Q+ b( [/ C5 t/ S; i7 [            ymax = int(member.find('bndbox').find('ymax').text)
    & i0 V* R, @4 I/ G# t2 O" x
    0 D: v4 E& U$ ?& W" w: ^" v& G7 n
    - _$ H4 W$ ~7 [% r* `* j- x
                xmin_corr = (xmin / wt) * self.width& ~1 H9 L1 Z2 D8 b9 B% t
                xmax_corr = (xmax / wt) * self.width  L* g# i0 w& @0 i- E/ T
                ymin_corr = (ymin / ht) * self.height
    9 l- y+ K* H( J; o            ymax_corr = (ymax / ht) * self.height( R$ T! c. z- {- U& E1 U% b/ `
                boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])
    * Z$ u9 D; J( ^* h7 J7 o  G4 w; n6 R& t, ~/ V" f

    7 g+ m; K6 i' t2 a/ ~3 p4 Y4 Z# b        # convert boxes into a torch.Tensor
    ( `7 Y* K+ e6 h# X- Y/ Z        boxes = torch.as_tensor(boxes, dtype=torch.float32)/ G% @0 n1 L) L

    1 f! v- ?! N# N6 L

    1 z# i6 ~$ W) i4 y0 A& k7 W4 H; M# X        # getting the areas of the boxes
    $ K" u* p6 t  K& a6 Y3 q( j7 [8 o. p        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0]), q1 k& L! Q4 m" M3 u1 l# _, l2 w

    & h6 @# s' `3 b( P( S- o
    ' z* a) H/ W0 s& A& l" o" p
            # suppose all instances are not crowd7 g" R4 R) ~6 \# k( P9 a
            iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64)
    ! C% ?' |) K& B5 K' z* _4 \, D
    9 q- o2 x9 a9 K7 o% n! M6 p
    9 L% p0 I1 z* H- f
            labels = torch.as_tensor(labels, dtype=torch.int64)/ W: l* M, I8 f

    7 k; K# X; w: u: Y. {2 Q! Q
    : S- ?8 F% |/ h# b
            target = {}
    & p* M2 Z  M" f6 }- a  T        target["boxes"] = boxes3 }1 p' `" @2 V7 m+ g  Z( c5 w
            target["labels"] = labels( W' K% l( }7 G; X; b: u3 k; Q* M
            target["area"] = area/ j: `7 h; k2 R9 [
            target["iscrowd"] = iscrowd
    2 y6 @  f2 a4 W9 {" A4 S9 X+ P        # image_id
    5 [( e. C7 {+ L2 W2 y( B! i5 ?        image_id = torch.tensor([idx])
    " X) Y* W0 X$ J. t' ^        target["image_id"] = image_id, x5 E! S) R: O8 V2 E* T& K8 @
    9 T' o8 D+ i6 M5 B  r
    4 _) g; T4 e$ l& @; k- `: `
            if self.transforms:
    ' H( ~7 w; s! c6 W            sample = self.transforms(image=img_res,0 `2 u2 I- R6 w, q: f, Q/ B
                                         bboxes=target['boxes'],
    . q3 Y* O+ `% H7 m, }                                     labels=labels)1 ], b: S& @9 E5 y5 {1 |

    $ p& w9 q- y: p1 `2 k4 {
    % ?' m$ ~! S! x! h' @+ a. ]
                img_res = sample['image']8 y; s: K  j& g  m. A
                target['boxes'] = torch.Tensor(sample['bboxes']), [2 E7 f0 A" z+ {( a8 }
      I, {1 {$ [$ q8 u* d4 A! E2 p# v
    ; x  z  b3 j! D9 B' z! i: g
            return img_res, target
    / k& `1 f/ n; t
    5 E5 y5 X1 {6 g! i' B' r6 ?# B
    * r) g  I1 A) v
        def __len__(self):8 j) l/ b7 \0 f8 A4 E; r, y
            return len(self.imgs)
    - a" |9 v, R, A8 [/ `: o) v7 R& [
    9 m0 l. w* D' x- v% `: O

      V, Y3 P# w; [6 E0 P# function to convert a torchtensor back to PIL image
    ; B7 Y1 _2 ^( P' x# T# S3 odef torch_to_pil(img):
    ( d3 B3 \( B! E    return torchtrans.ToPILImage()(img).convert('RGB')
    * U* l2 |/ c. t, F* `+ B( I: Y
    $ c; E- s* E- n+ y6 ]

    4 e' j+ {  J3 Z0 m3 T- K8 D( _4 Y" D) w8 a! c1 V

    ; Z# O0 k( P7 R0 y* `def plot_img_bbox(img, target):1 a% J6 p! [! T' W0 ~
        # plot the image and bboxes- c( g* k! I% U% c2 x) @$ {+ d. [7 @
        fig, a = plt.subplots(1, 1)/ D- u- r8 J; V$ k0 L1 ?
        fig.set_size_inches(5, 5)6 v- s( J5 T8 y
        a.imshow(img)
    2 Z7 }! P$ n/ F1 K    for box in (target['boxes']):
    ) }6 D; x# V+ Q# F        x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]
    ( G9 w  _. V+ _8 {( l: d        rect = patches.Rectangle((x, y),
      D  S( p* v6 u6 l1 o6 `7 w) I                                 width, height,
    * F5 N- u5 Y5 N/ [* e# u8 x9 D/ c: z                                 linewidth=2,) m2 \4 L( l. X- l: Y8 E! N
                                     edgecolor='r',
    4 J0 T& L7 b+ x: [; L                                 facecolor='none')
    9 U. u1 f& P5 |+ R+ [* H, r& v+ F- p/ B$ A! ?3 l
    4 ~8 \( Y# h6 A2 v
            # Draw the bounding box on top of the image
    $ C$ G. P$ Y9 O6 w4 Y/ |: K* f: ?9 g2 F        a.add_patch(rect): t. X  ]1 s2 t. ]! E  }
        plt.show()8 B3 a# y: A( f

    ; ?- D. q8 |4 p" r) i+ u

    ; _( T+ s/ g$ s  F* T' @0 F4 v
    9 B+ M& r8 r3 F
    9 p  B% ?. k) e5 g1 e, T
    def get_transform(train):
    4 R9 T4 u& K6 G' l1 R3 w    if train:( u, w4 p/ w5 M5 T, B3 e
            return A.Compose([7 W* G( Q0 T- K* \# E/ Y! ?) a. y
                A.HorizontalFlip(0.5),0 y, l. a& @* o. K( q$ ~0 ?5 ]
                # ToTensorV2 converts image to pytorch tensor without div by 255+ _8 T. q9 ]: x& ?5 v; [3 ^
                ToTensorV2(p=1.0)( C  ^4 [! c- |1 m5 k) J) \' z# |! B
            ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})6 R' O8 p- [' _9 V% i) c5 T( \: G; J
        else:
    * f! |5 L3 \3 B  v; q        return A.Compose([
    & P0 c/ g- o, g( Q6 i0 y0 P7 Q            ToTensorV2(p=1.0)
    - ]/ I3 _) M; L( \1 }, L        ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})1 m# I" I3 b. Q0 V) T$ I* a
    ) K* H$ I5 P& k
    $ l& x- k( W& D

    ( O  `& a4 x1 m8 B" b& z
      q; I; s9 _+ S! m; Q, u' a

    * c) P& o4 g, Z1 `- t7 X% T4 Z6 S

    # T# ^$ r' r6 W; fdataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))$ ?0 a5 F' \6 x& |; G

    . ^* i5 i" e+ J6 e9 N! M. O* v

    0 b5 T8 x! J2 ~/ |+ H1 Q5 N9 Xprint(len(dataset))* G2 |& A( `; H4 H% `
    # getting the image and target for a test index.  Feel free to change the index.
    # J/ N. p& m! e5 [# s% _img, target = dataset[29]
    ( K1 [3 v3 m& J2 b4 @& fprint(img.shape, '\n', target)
    & g) v1 N# `/ Z- I7 j' aplot_img_bbox(torch_to_pil(img), target); ~" r3 c% C4 R
    1
    7 V/ u, _5 \. k& {- z  [* a2: k. E& l+ c% U( G
    3' N6 C4 P( X- x
    4
    ! \1 F' D# |' C: c. e5
    ! [2 P( |) k0 M! k- T# s' Q6, c  h* G  {0 |& P% \: x
    7
    + r2 O& |9 V) O0 u& D' |# g80 u" }) [0 b& V1 D; a- x
    9
    3 B% L) s" u0 |3 g3 b10
    * b7 E% |8 d6 Z/ q, ~3 i) K3 y" ^11& W/ n( j* I' A7 Q7 K" o: r! J
    12
    9 x* P+ h& U: ~8 b$ \1 ?- A13
    ) `( U# o  X- g149 [  B# g( T) p* f4 z5 D
    15
    * a6 X( T% D( v/ c8 B16  m6 ^, ]! \& K+ k9 H
    172 b8 \; ?8 E. h, p
    182 S/ G2 z2 N2 _8 J7 z- d7 s
    19( u$ ~9 U- y. o" @2 k( d
    20
    6 K" \: B! E, A' p+ G212 Q! Z. L: v) n3 e' D( K' v
    22! I+ I5 y* |. {% r; A- H
    23* x, E  R) e4 H3 |/ g
    24
    ; c2 L8 g6 o. |% A1 a8 J25' f3 f1 G# o+ d& i: f7 u: S9 |
    26
    ) B5 U% R/ t8 y" W8 m! ~273 Q* F$ m1 ^  g  c  A  t" `
    28. {, K" `1 m5 x; l: ~
    292 r3 T4 W/ |) ^" u- o4 M& H3 M! _
    307 b8 |8 @6 V0 S, V0 P" U3 z
    31
    + l$ L' }5 z! Y32
    5 d9 r* q2 Q) G! _' G33, _+ ^5 \- P% B
    34
    % x% ?; B1 o; t357 H6 w9 O; q' X+ k2 K- ?1 `8 n
    36! i. d- a0 r& s2 u4 ]) ^
    37& w1 I, {' p; F& }
    38
    * g. F/ x  Y2 Q5 R  g) m39
    ) t1 a3 t: f6 T6 a40/ b- K" Y( X9 U: x: V- @
    41$ w: _4 l4 z4 b
    42; O  b" y5 ~. u6 v0 n
    43
    - [. u! M# b& ]% k8 \44& G+ j% i3 A6 S' r; B* ?7 p
    45
    1 z. x6 k! p6 l& t0 _46
    % x. @, Y8 c/ ]/ o47, l; m+ n! a: B0 K: ]# X% s
    48
    2 w, G2 s7 o/ }49
    0 t4 s3 s9 S2 k; n0 U) I50
    6 w' N, z& e2 ]& h51
    * i. f, R9 x( i8 {52
    , X/ k" W. k, @- N( B4 m- f53
    & ?; l# y$ ]2 ^3 v6 l1 m54
    ( G; Y# X$ s5 s8 {8 l552 t  u1 h6 f! W
    56! ~0 i. S4 A4 l" _, G% l6 |
    572 B0 a, S7 V. C1 I0 Q4 G2 A
    58. W" l7 _  x  Y7 J2 ]
    596 d: q/ G' Z& z( J0 I
    60/ g, L& \$ B) |5 J/ y' X2 d2 e" P
    61
    7 S. r  H, {! m9 c. X2 t% n. M& S62. @/ F8 C( [; A9 F# i) Z
    63& |) V2 O' V$ L7 v, n+ p. b
    64' P/ P" o/ }# S! T: `# ?
    655 Z7 |9 @4 I8 A
    662 D9 a# A5 @9 K7 G
    672 E& K; J* E" X) j; O) a
    68
    " V! S* V/ k+ C* H1 R693 u4 S2 T$ p% O* V
    70% v, w' v% e8 l6 {# e8 N) s
    71
    7 n+ b' `) D% Q! _7 D  z72& C. J* w: M* G# k2 @7 |* R; ?
    73' w( [( y! m: O& q9 i, [* X) n
    74
    2 W  G1 O# B( F8 |. s$ p" {759 ~- Q/ _4 s9 P  e
    76
    , F* c# @2 B( o  U& g77; l: O" x& o! e3 X
    78
    . g1 V: a; g$ n  q795 ?8 U  ?- B  O1 q+ c  b
    80
    ' L0 q4 ]; Z  P) v  s! n! V4 n81
    ! \" Q5 ]+ S% L( s1 f: ~82
    + F( t# P, z% `- e% x83$ v1 w$ {% [+ w! a. G8 S9 o
    84- z0 a4 s& e& D- A2 p
    85
    5 j+ M- x  h! H4 a" U863 R* f! ~% c- _1 K
    87
    $ h& Y0 H% U3 C* z" ^88
    ! Q9 n2 A, r$ ?' w$ \899 E# k8 D3 u: [1 I9 U7 y* {
    90
      V/ I2 ~; e9 g: b6 ]91
    7 @6 [9 L$ d0 d92
    % @5 X/ h* c; z9 h4 c) Z1 k% L0 i936 o/ o5 `- }% @+ x5 ]9 a
    94& c' f, W" A2 W' e/ ?. b3 s1 u
    95
    3 ^4 P- y* S; q! v96
    . H2 C7 F& X2 Z, @* u971 \$ a8 B- X+ ~- Z4 \
    98
    6 _9 ^3 t9 x, @991 i8 {0 |# X+ r+ l; M: |5 i
    100, v5 W4 _/ r3 [* \
    101
    : ?$ R8 B1 F+ @1 i1 _* e102  C/ ^" Z5 g, [' O( d0 E
    1034 s4 w: G6 {# N# q% ~
    104; R6 P( n4 l- ^) A! K
    105
    ' ~4 J$ J: \" l- c! Y106
    ( w" L$ o: H: n; S0 X! B+ M107
    # Y. X0 a! v% ~6 v4 R* p% K2 E3 C108. s% O: Y: c6 r% e& Z) C
    1097 z# \" }. x3 M8 _
    110
    # d5 P1 e' L& L! D111- W  r/ y. o3 A7 Z4 r
    112
    - |! s; K. e( A3 s1 d3 d113
    2 `: M! s$ P- ~9 {9 x9 |! v8 N114
    . K5 C: Q' t8 p* ?115; n# B# l. M: g1 t
    116
    / }8 S4 [3 N4 W9 P: ?7 ?% P117, S5 T* b- |1 F+ B: I$ x2 c
    118# M- t$ l' L* `: D2 M5 J, ?
    119
    : e7 t) Q- H+ X& ?& I6 j6 O120  ?$ Q! F1 z+ u; O$ I( U0 h
    121
    4 y7 o- E1 ^) G: t4 \+ _. F122
    7 h; ?" _+ j3 `, S# t  X123
    % N, T- J- E: i' ~124
    : ~# o% `3 }* L; K9 l3 J1255 v' s$ [* C# G3 g: [. W( q
    126
    6 Y4 r  M: V1 k- q) C/ X127
    % E% J& t8 o* e: ?128" g: E0 ?- d* y$ ^$ o; n, V
    129
    $ z& D% s( a+ _4 a8 i/ w5 o  A5 r130" T% C7 V% Q% r7 Q5 ?
    131
      [- a8 e+ W/ o4 z132
    - s1 C( H- X+ F- O' e6 C: {- j133) |# N. n* O' {
    134* U' z5 T6 _$ d2 X! g
    135
    & v$ w6 y/ z9 \) t136  m+ z2 b- V8 a5 b
    1370 C+ J( }2 j' s
    138
    % Z5 x1 A% ?6 t8 m& {139
    & {% x5 J) ?& B, ]1409 ?! k1 R( I. U/ q  ~# O2 Y
    141! G+ F+ o1 E% g1 Y
    142
    & z2 ?* I  Q! Z/ Q( b7 f5 u: ~143
    - w4 [9 `; P) b) \, y4 P% i* @7 t144
    0 `- f7 D6 d# z- h1450 Z' w% y" {0 s+ k- X
    146
    + O, O9 p  {  N( G1471 n7 m! l% J$ D( i5 I0 m: y1 o
    148
    " O- b- u% w& ?- \' p, i, G149
    ( M8 Q/ S" _$ _" t% `150# h) Z* l% {6 V0 t2 Z
    151
    , D7 F$ N8 a( X: y% H, I. J152
    ( L) R# N+ `" E; T/ K7 b& @' o153
    2 ^# L2 s9 ~$ Q1 w154
    . X7 h0 v% E7 u# r; z3 n, O155; h" ^, X" W# B
    156& S* V; y4 |/ z% h. k% ?- m
    输出如下:1 Y9 x) R) K- k$ Y; _
    , O6 y9 F6 @2 ~
    / i% }9 Q  x1 z
    torch.Size([3, 480, 480]) , t3 I# g7 Y' Y1 J: U
    {'boxes': tensor([[130.8000,  97.8000, 327.6000, 292.2000],+ {2 b5 E/ m9 B7 {( T. A' I
            [159.0000, 268.8000, 349.8000, 427.8000],. E/ i# j1 h7 R7 N- S7 W
            [  0.0000, 282.0000, 118.2000, 429.6000],
    4 {; ]! c+ o+ K' F* ~        [ 43.8000, 107.4000, 199.2000, 280.2000],4 w$ q" ^. v5 u( j( L* {; 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])}) c( X7 S% @" O, B
    1: w3 ^7 y0 h0 e
    2! @5 ?; i- [& f! W  M6 t$ ]
    3
    4 X3 [$ h) C$ D  l4
    " X6 I; x- x0 x, A5/ B! W8 d! k$ U+ f7 ~6 W
    64 [3 ]7 ~* k4 ^: k
    : o1 j% r" r% A! c" D
    . {) i" P& ]) k4 T: H% z* I+ l# U

    % e* ]5 D! U1 V  [

    5 K% m2 ?; q# z/ ]9 C下载地址- W4 n3 c: _3 K3 H% C  @
    链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw4 ?& U* Z$ M3 w$ B1 z& F9 k7 z9 Y
    提取码:srjn1 t4 G. H' l: ?) h* w
    ————————————————
    8 k, `: Y% ]8 c( v, X2 f1 t版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。( z6 |3 i: W$ ~! v* Y
    原文链接:https://blog.csdn.net/weixin_44510615/article/details/118496273
    7 ]! i1 W" r, D$ J  V% U' A8 S" t( @* e6 b1 b; a) F7 I9 f
    ) l7 L9 B2 B4 i  G- o
    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-8-2 07:28 , Processed in 0.392826 second(s), 51 queries .

    回顶部