QQ登录

只需要一步,快速开始

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

    ! F5 E/ [" h3 L' h: c. p2 {& _% {深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息
    , N, Z- n" m. ^4 }3 ~& }% E4 }3 X图像标注主要用于创建数据集进行图片的标注。本篇博客将推荐一款非常实用的图片标注工具LabelImg,重点介绍其安装使用过程。如果想简单点,请直接下载打包版(下载地址见结尾),无需编译,直接打开即可!
    ! j1 R0 a& y# {: J
    . y& }1 n/ V1 M2 o7 Z' d5 v/ m

    ) k) e. D1 ?; H( A感谢原作者对Github的贡献,博主发现软件已经更新,可以关注最新版本。这个工具是一个用 Python 和 Qt 编写的完整的图形界面。最有意思的是,它的标注信息可以直接转换成XML文件,这和PASCAL VOC和ImageNet使用的XML是一样的。
    : O; v- y. a# l+ z( s, u9 F. Q$ s/ x, ~4 u. {

    9 f" Q  s9 V. D# A附注。作者在5月份更新了代码,现在最新版本号是1.3.0,博主亲测,源码在Windows 10和Ubuntu 16.04上正常运行。9 V: P  {( O/ d! [$ r
    , x) o( D0 t/ w7 J" a

    9 y: J; T# e$ S  J3 r4 M具体的安装查看Github教程:https://github.com/wkentaro/labelme/#installation5 X# a4 a  M5 ~0 }
    7 z, r+ ]( Q$ y; e% q

    - u" g. X% r, |' Q9 h0 e在原作者的github下载源码:https://github.com/tzutalin/labelImg
    8 W3 ~& U1 ^+ S) A  J) |. Y。解压名为labelImg-master的文件夹,进入当前目录的命令行窗口,输入如下语句依次打开软件。2 D' h% J( G. y) [/ r

    5 A) y$ k+ T9 ~9 {+ E
    : C) J9 I4 E7 b1 W
    python labelImg.py; c7 ~" ^. L4 P. |9 u# C/ L5 I7 p
    1! L+ G1 B7 D) B
    , ]  F+ g( U1 f. ~

    1 U$ X. D- Y  K; b! _2 {) V6 z5 x$ ?5 W

    + M& n" u0 \# p$ L! C' g0 [具体使用  b/ _; {2 x5 t# l
    修改默认的XML文件保存位置,使用快捷键“Ctrl+R”,更改为自定义位置,这里的路径一定不能包含中文,否则不会保存。& x5 O( b1 k1 s7 D

    7 N+ V& Z9 T% [- P7 g
    6 B6 Q- I3 c% M* {( c5 d* H
    使用notepad++打开源文件夹中的data/predefined_classes.txt,修改默认分类,如person、car、motorcycle这三个分类。% F& g2 F+ _3 p  w) l

    0 a8 q0 u# Q' ?# V; H

    " k1 ?  y- {- \+ x9 x) S; x“打开目录”打开图片文件夹,选择第一张图片开始标注,用“创建矩形框”或“Ctrl+N”启动框,点击结束框,双击选择类别。完成一张图片点击“保存”保存后,XML文件已经保存到本地了。单击“下一张图片”转到下一张图片。0 b# j9 F* w+ z1 ]4 j( Q+ V( C
    & f9 e! s& n  M2 ], m) M. _9 h* {
    / _: I+ Z5 F% e- |# Q7 M$ }4 `( N8 X
    贴标过程可以随时返回修改,保存的文件会覆盖上一个。
    " ~* ?+ F# K+ Z3 r7 X9 W& Q. S+ u/ i$ Z, Z. H1 c3 O5 E1 @* e6 [
    0 y/ N8 C; s& k" l; \: J8 v
    完成注解后,打开XML文件,发现和PASCAL VOC格式一样。" ~" R6 Y. w1 B0 C
    # m! ~0 |% i/ J

    2 w% C6 e( U' @& S( O- {: x将xml文件提取图像信息1 k3 t& `  d3 z; b; S1 F: |& Y+ h$ Z
    下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。
    * f/ i) X0 c3 g5 ^" r6 N, N' k4 Y8 b5 o

    / H% b8 _9 K$ D) ]0 i  ]) z: d! ?  b5 G
    ! O' U' o* B' R
    4 p- q& U  ?! b
    下面是images图片中的一个。
    6 D! z2 Y" E. h
    " Q3 N: m7 R5 g  Z- N/ E# m

    / k, b+ h! _8 q" P& E! u下面是对应的xml文件。+ D  ^/ e: c9 R9 C! I

    $ i, m) E  W2 F( C5 g7 z

    % W2 M* V8 `& \$ J( {5 u; R; m0 F<annotation>
    4 g9 F4 M8 H# Y+ q! Q) D4 g7 Y- q        <folder>train</folder>
    & j3 Z1 X. Y8 Z7 G        <filename>apple_30.jpg</filename>
    ' `9 K( d" o2 @* W: a; @        <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>
    7 E/ o9 i" `8 d        <source>! E+ v6 J$ d$ S( P, F
                    <database>Unknown</database>
    6 o. s1 c  n0 e% n" b  U        </source>" _* b- A  F7 Q, L
            <size>
    3 ^' A2 M, b6 V: ~                <width>800</width>
    8 h& {$ y- z, y. L                <height>800</height>, o/ Y  E5 F6 ^' M
                    <depth>3</depth>
    ' i# `- F; n8 Y( Z        </size>
    / c! n$ Q* q4 z: h5 w        <segmented>0</segmented>4 ?, R4 N$ x. q- a
            <object>7 ^' Z2 O; D" P( |; P# e
                    <name>apple</name>
      p& p1 B2 i  X6 L                <pose>Unspecified</pose>) R: \8 [, |# p2 n* ]( u
                    <truncated>0</truncated>: R* t" W" p# z8 A3 r1 M8 K
                    <difficult>0</difficult>
    3 |/ r7 p! U5 U/ o- s* P8 n/ o                <bndbox>
    8 {% d/ H0 p# R8 z& \                        <xmin>254</xmin>5 y- d; I( F& j
                            <ymin>163</ymin>
    & ?9 w4 c: R& ^. D+ p/ ^! ?1 H/ w                        <xmax>582</xmax>/ K7 y4 N7 ?- B4 Q/ n. E, y0 c% ~
                            <ymax>487</ymax>- f9 \; e- F6 X  b  T. B; W8 X$ X
                    </bndbox>5 \9 V. J" j! h/ S; i  |0 Z7 U& \
            </object>% f2 ^4 W* m' L2 i6 r. C
            <object>) F8 C1 Y  u! e4 M, D- F0 I
                    <name>apple</name># a6 f, N9 Z1 e4 v8 G8 [6 p+ N
                    <pose>Unspecified</pose># T* D1 G( [2 c( m3 y% @. D
                    <truncated>0</truncated>
    . c; U9 Y7 [1 I$ u7 Z' d. C5 f                <difficult>0</difficult>5 ]* _$ t  D) Y9 e4 H
                    <bndbox>
    ; M. w( s1 s  p; Q4 c) Z6 ]                        <xmin>217</xmin>* r6 o9 N1 P" {% u' ^0 x
                            <ymin>448</ymin>
    0 y( o8 V4 L- q1 A8 @2 b8 N                        <xmax>535</xmax>
    . _# {. n5 E( _2 `                        <ymax>713</ymax>* y  w7 T; y, @
                    </bndbox># v* ~2 e7 }7 U8 _
            </object>
    ) N( {1 r) n/ e/ x        <object>
    8 m  c' _$ w" h% i2 @2 l, t                <name>apple</name>4 ?1 I& S$ e1 h: x$ Y& T; U% `
                    <pose>Unspecified</pose>
    * u8 t  D3 E' t: F                <truncated>1</truncated>+ ]% q% v) {( Q8 a
                    <difficult>0</difficult>
    8 A8 X) H8 y# b8 d! j                <bndbox>
      K6 A: \8 v: c8 K+ n; W' s) ^) Q                        <xmin>603</xmin>
    $ B( l: o6 @# o7 @                        <ymin>470</ymin>
    ' H% N& E* E; d0 N' \. N                        <xmax>800</xmax>
    . h; j; {$ o6 Y" @                        <ymax>716</ymax>" ^' E/ n% d6 I# K6 i& {
                    </bndbox>* i, \  [( O$ S
            </object>
    ; l- N* P1 E4 U9 K% _2 x        <object># V; D4 _; \5 O7 U0 _6 k0 v
                    <name>apple</name>
      b8 A7 T( J: Q/ B& v1 s  y                <pose>Unspecified</pose>; Q/ Y# b$ k5 M
                    <truncated>0</truncated>. p! t* _: p6 v8 s* B
                    <difficult>0</difficult>
    4 U7 D6 D! d5 j4 Z# m! g2 f" i                <bndbox>9 N  D4 X9 j7 N( G* @% A
                            <xmin>468</xmin>
    5 U( Y0 h1 v2 _5 x9 v8 n" p                        <ymin>179</ymin>
    5 @5 b7 a" Q( m  |0 J. u                        <xmax>727</xmax>
      b$ M# B* N- }2 H: b% f; Z                        <ymax>467</ymax>: s" N# |9 T! Y
                    </bndbox>
      F$ ^) q* a: R* Z1 F/ s: F( {! u1 h        </object>
    1 T5 u+ N+ A) y" h, E; L# u        <object>
    : c7 F' \! B/ G+ H: L9 ~/ M                <name>apple</name>
    8 L0 P4 p( {! h, H                <pose>Unspecified</pose>, X$ L1 C! G5 ^% q# G6 }
                    <truncated>1</truncated>% _. F% M8 d$ x& Z4 Y7 t& I
                    <difficult>0</difficult>
    % K& J! ^, V, K, W1 S( w1 s                <bndbox>
    , c0 B3 B, F- t8 p1 c5 b                        <xmin>1</xmin>; ]- ?( `, p! ?( E- r
                            <ymin>63</ymin>
    3 @& L3 R; w3 d                        <xmax>308</xmax>
    ' m. D$ l8 J; y0 T  }) p                        <ymax>414</ymax>
    + N" j& p& v! r6 ]" [                </bndbox>+ u# I2 N8 `: L# J( Y  n7 \, D) s
            </object>
    # Q' s* [2 Z0 v$ I1 y7 T- J# ]' T</annotation>& Y7 y2 ~6 K1 v4 U" [' V
    1
    " @. [! a7 ~9 f/ ?9 N21 z) d! r" c  ~( P% Z
    37 ?- l1 W! ?* D
    4% g) Z& U+ Y5 H; v1 u: N+ ?
    5
    3 c/ L1 G) |( V' w  @/ z6% U. L# b0 N6 [/ a2 t
    7: f) ~. C, J+ K( a$ Z# k0 F
    8" Y8 U! J( a8 Y4 b& z, }1 o( r9 o
    9! V8 u' b) ]9 J( h9 \0 A
    10( T$ {3 _/ q5 a2 E6 t  y6 v
    11
    ' a: f0 K9 p$ q# c12% N/ U/ N5 h- k3 O( I
    13
    6 ?" m  h% ]: z0 }% n143 c" u: J; C3 G$ [. p  {" \' a, @
    153 J+ v. @7 u* g0 a0 z
    16& @$ X, Z- s4 R" \3 m# G
    17
    % b! R3 z6 k7 @. G! ^* K4 V) }18+ D1 h/ ?4 B8 t- C8 V- \1 C" {4 _! ^
    194 b5 ]  v) G3 ]1 E' n
    20
    , X7 ]3 w& ~' a4 ?% z3 i21  n: Q, I1 a2 j. s
    22
    " h1 U: p/ ]" t- L) R) J+ `: L23. H  l8 f7 K7 j& C* [
    24
    , o/ g1 S- Q" a6 S. @+ Z25
    & ?$ u8 O* C" n8 G+ }26$ v8 g7 N# J, t) h+ q* M
    27
    9 g8 c% n& p  V2 s% e* h5 P0 c28
    , S# ^- E, d( H* b% u: g: p29
    & V0 r4 x3 t: z3 f30& x) Y( g. e3 n1 U& |( B+ D
    31
    ' [5 Z4 H2 k4 D32
    - F/ m2 P( R0 T8 x33; p8 d, z% X1 e* y9 ~$ V
    34
    5 W0 j3 p; @. @; I3 G0 J9 H: n35
    6 J+ l% d% k; T5 O! q2 \: X8 J36
    9 |; j* Y9 m0 s& ~# J375 }# E6 ^2 f4 {: r7 P8 i/ F# y
    38. [6 `, I6 H7 _# [, v$ ^
    39+ E  f% J( T8 o: B: u9 q/ d
    403 X; `3 l5 ]& g( g8 d
    412 a8 O& D$ H+ k
    42
    : u- h0 v7 `" \0 A% t5 E# d43# _  G; e. M8 M. b
    44) [! p+ l: E9 Z1 l
    45: n, M& |! q" C1 O% P
    46
    + Y! @, f) M2 v/ m% d$ h5 m. R47
    & p' X# L; y% J0 t48# \! B% m+ f3 Q  c( ]8 _. b1 m
    49
    3 Q5 }7 J9 L$ P& `& l: ]( U! y( I" o# G50" n4 N7 Q' X7 Q% F1 z7 T
    51
    # q3 p5 ]' y0 T5 n# U522 Z# ~6 H# r  ~& e
    53" g  }, K$ k% g* A
    54$ L0 i/ `& u+ p5 b5 h4 W  A
    55* `! m3 F+ [1 A. i! k
    56
    ; B6 m8 t0 k% }! a57
    . C% w+ Y+ A: n$ N- f. A, W58
    $ L! N& T7 N2 j59
    " ?; _1 O+ g' _& T7 j; X5 A: y60
    % r6 _6 e% Y; ~" w6 [# \61( f# M) s2 l* ]7 @! C; q
    62
      h  f: N& P# C! M+ M, _/ _63
    2 f" L5 O3 ^$ N8 R# }5 m; S64$ F( E7 Y: d; C+ r( ~
    653 Z% o* ]% Z7 \  C" t1 P
    66
    5 t! {4 E; [& X4 `% Q1 h67) n  t0 ]! @0 W6 t. s! h) b. Q% D' C
    68
    4 R1 `9 }' Q4 k7 G. B9 x691 a* V/ E0 h& x" q% ^. Z, }
    70
    2 Q0 g+ I4 d; n6 P! ]0 }. a0 U71, u7 M. |& l1 |, S, W3 ]) o
    72
    3 z8 e) M1 n  o: F2 y# J) d73
    + q* R- g- P! N: X" l0 R- J742 {5 ?* D/ c; [5 G3 N
    将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。) l. }9 z3 ~0 a7 X. w% |5 U7 K) x

    . {1 J# X4 ~! z; V! F* y9 J; \/ K( a
    % y' Y9 s/ w9 V  A2 X, M
    import os
    2 p" e: `( A  N) u- A4 h0 rimport numpy as np
    / W: f) F! h. V3 l5 {( Yimport cv2- c$ R9 l+ W3 W. ~6 c3 }) e
    import torch4 m: F. _" l4 ?9 ^) K
    import matplotlib.patches as patches
    9 ~, ~7 l0 S% I/ Limport albumentations as A+ x( z5 X+ H8 u
    from albumentations.pytorch.transforms import ToTensorV23 t+ A3 G7 O3 R9 ]* e( p: o
    from matplotlib import pyplot as plt
      k( E* h2 K1 Z/ Y5 Ifrom torch.utils.data import Dataset
    7 s- f- b' m) \. J( t) f. S& ~from xml.etree import ElementTree as et
    ! J3 w' }" b* R7 Wfrom torchvision import transforms as torchtrans2 o$ H1 N1 I/ S$ h6 |/ m3 z) B

    # ~7 A4 c* Y3 `# s% O( i9 C) V
    7 K+ b& ^0 @1 L) [9 T
    # defining the files directory and testing directory! a6 w) C! w4 J6 W2 t+ @+ P4 E
    train_image_dir = 'train/train/image': G; C0 h; v/ Q1 [9 J; N- j& i" v
    train_xml_dir = 'train/train/xml'
    : L; U+ Q7 r5 u9 y! B# test_image_dir = 'test/test/image': {8 P$ b" Q0 O( |6 N% n
    # test_xml_dir = 'test/test/xml'
    1 ^# _( g, e! }- g
    ( Y+ _/ J# N1 A  ]1 Y8 D+ }
    0 ]: ]1 U1 I/ S. N  P; G
    class FruitImagesDataset(Dataset):$ j* K; @& O2 Y  N+ N; p. i
    % Z: T! z1 J; X* i" e1 T& L

    8 {% o& S/ y; h7 K$ H; |: V    def __init__(self, image_dir, xml_dir, width, height, transforms=None):# D" p8 K' U7 _3 W* E
            self.transforms = transforms
      l( h" f9 b, D        self.image_dir = image_dir
    - A+ p. E- v  p        self.xml_dir = xml_dir
    4 E/ I( K- G8 Z( J0 ~3 D        self.height = height" q* p- v# ~1 z  ?* U
            self.width = width
    " B) K9 H. l1 O& f* E$ H) O+ G) s: b$ a* @! u, H
    5 \! _: |. W) `2 T6 Z
            # sorting the images for consistency
    ! n0 E& q7 I. h9 W$ F        # To get images, the extension of the filename is checked to be jpg, H  p/ P3 \, e9 f' U
            self.imgs = [image for image in os.listdir(self.image_dir)
    ( {5 {* h- r7 k( ]: F% Q8 t                     if image[-4:] == '.jpg']* ]7 ^8 }  z6 L) ?
            self.xmls = [xml for xml in os.listdir(self.xml_dir)
    1 [2 ?2 |0 h6 ^4 {' w                     if xml[-4:] == '.xml']( a( m! @& M/ v# c

    4 ~6 H- @) ?/ C, o6 _- d( N) k

    5 n: {+ V( f: Y" R0 [        # classes: 0 index is reserved for background
      z1 @+ a  U  ]( [( U$ F        self.classes = ['apple', 'banana', 'orange']5 X3 K6 Z6 x$ w: ~9 m

    - w8 w! o: c) f- P! N
    5 n4 K4 p+ x2 D/ e- j
        def __getitem__(self, idx):
    # j6 k6 o* d  j' }5 K
    , K& l# H0 r7 m8 W0 x  K
    . L0 H! c$ C4 Z
            img_name = self.imgs[idx]
    0 }" z; S7 O* C2 }. v8 T  v0 e& ~        image_path = os.path.join(self.image_dir, img_name)
    8 R1 _, V/ ^+ Y* U6 h
    9 u" g+ B8 j* T! N/ u- L4 u
    % L; N, d4 S5 S, M9 \1 L  G. Q
            # reading the images and converting them to correct size and color
    ; _0 Q6 _0 X1 ]        img = cv2.imread(image_path)
    9 T$ ?, O3 b% i5 x. g        img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)+ a8 U) {! P3 v+ n. W! ^
            img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)
    7 k3 T9 l& @. \        # diving by 255
    " z6 n" [* Q# ~- B" E9 |; A' T! ~1 L        img_res /= 255.0
    . {2 B' Y- o% p# n9 V* G" l2 K7 D. Y0 A* D( k/ b2 f; W, ~/ i0 w
      s+ O- v9 ~. O+ @0 \6 E  ?
            # annotation file# O4 }0 n0 p: }% Y
            annot_filename = img_name[:-4] + '.xml'
    - T8 Q8 h5 e% k0 x8 ~& n  V8 A        annot_file_path = os.path.join(self.xml_dir, annot_filename)
    , v" J. ^8 A7 ~0 `+ V* Q( C  \+ U! o3 q% d

    " d. v- \* B& y1 k        boxes = []8 r0 g4 x6 U6 n/ I9 N# `
            labels = []
    # J; D/ B3 B( H& m4 b5 h8 C. J# x        tree = et.parse(annot_file_path)1 P& L2 d* K# ~0 a& ~8 K8 c
            root = tree.getroot()
    3 z6 E/ O' R$ u- {" z* R3 Y; M8 ^" ]7 ~; A4 v

    : H$ O% ?% |- w+ |/ |: y/ u        # cv2 image gives size as height x width
    - S0 A) q% d- r        wt = img.shape[1]
    1 a5 I1 `; ]1 X# ]        ht = img.shape[0]2 ~/ {5 b8 b, P. n) _2 o

    7 X- R+ _. R7 o' i( _; u5 m

    ' V9 k/ ?0 y" R7 u# r' j        # box coordinates for xml files are extracted and corrected for image size given( D7 m  N1 _, B9 s/ q5 D, O
            for member in root.findall('object'):
    1 T. B5 t  R8 Z9 ]+ `0 H/ y            labels.append(self.classes.index(member.find('name').text))
    4 F% [2 o# U- V* H9 ]+ u/ ?; R2 t0 v  g- A' q4 H4 n+ W  Z
    3 q# @; {7 C4 K$ J5 Z
                # bounding box* s- D( x5 y0 l% C
                xmin = int(member.find('bndbox').find('xmin').text)+ J9 |4 k1 v' h; ]) N
                xmax = int(member.find('bndbox').find('xmax').text)3 Q9 ~7 `& R- n" U2 V7 N

    ( G1 ~* ~4 l: {/ D; m
    # \. H! |. B3 D0 R$ k; M
                ymin = int(member.find('bndbox').find('ymin').text)
    : t; ]0 W$ U5 E9 G6 v            ymax = int(member.find('bndbox').find('ymax').text)
    & O  {1 S" n" [4 p
    , e9 q. k7 g0 P$ H
    ! N. a) ]  `9 ^# M* ~. `: F
                xmin_corr = (xmin / wt) * self.width
    4 @. [/ G. p& y* ~* Z  Y            xmax_corr = (xmax / wt) * self.width
    3 s; h3 }/ a0 M  e            ymin_corr = (ymin / ht) * self.height
    9 Z, j7 R) ?  A+ V" B: U1 ?8 |2 j  B# N            ymax_corr = (ymax / ht) * self.height
    6 D# S! Y# S7 v) U$ \0 P* t- ?            boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])
    / }1 h4 ]) ~4 c% H. v( A' f! b; W
    ; g$ k8 _( o: ?5 s+ p  P

    / n# y# ]& Y  {$ ~4 x" i6 {        # convert boxes into a torch.Tensor$ s3 O& S$ }% U" s5 D
            boxes = torch.as_tensor(boxes, dtype=torch.float32)
    5 O4 {( \( W& i; \; m  Q% q- A  F" J) `6 S# x
    0 t" S8 m' t. p/ J# v" [% N- ]
            # getting the areas of the boxes6 {7 ^  w$ H/ f# E# m
            area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
    + H% R8 d# V1 _- V8 J& h' H: [& P) `

    ( W% f5 B. `4 v        # suppose all instances are not crowd
    1 f" J2 u4 Y5 |: J) N5 P        iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64)9 u8 j- O) Y# f- h" D# r
    / Z5 H* d* C1 ~/ Z" [5 a) r

    - o4 q5 C: y- @+ r$ l7 A        labels = torch.as_tensor(labels, dtype=torch.int64)5 `( d8 G0 T: ^4 P2 V7 X  z
      U+ K: s! a% ~7 L6 f& n

    8 z& d0 F" G1 ~- O: y; o) w9 r        target = {}, u7 T0 c' y/ `2 O( F
            target["boxes"] = boxes8 l& f8 b' P5 P) a
            target["labels"] = labels0 V0 A5 s# J) T& Z
            target["area"] = area
    ! j) ^+ o: {/ F% B5 ^        target["iscrowd"] = iscrowd9 `$ `8 M  X- m, y  Z: _% W
            # image_id
    . K$ g/ v& `# j; i7 S* H( P, r        image_id = torch.tensor([idx])
    0 b8 E2 w& l7 [  ~  x& ^        target["image_id"] = image_id! I) _$ s& h. m& c1 a# \5 G4 U

    & R1 A  `* }3 C

    * c7 J! r1 Z9 F( R* P7 G4 u        if self.transforms:3 Q- N2 Q! E: m3 k' E
                sample = self.transforms(image=img_res,
      T- D/ M& O1 Q# K) z                                     bboxes=target['boxes'],1 r) A. F/ _3 ]9 r, }( ?
                                         labels=labels)
    : g5 y8 Z+ z9 e- k
    & [8 ~7 @7 W8 e
    ; `8 O0 j+ q5 D+ |" M7 W" \
                img_res = sample['image']. `* i% H# R% d3 Y$ S2 R5 n( Q
                target['boxes'] = torch.Tensor(sample['bboxes'])
    - H: \* k3 z* i0 h6 o4 b3 U* W
    & e3 `1 \* u0 f+ \) I1 L
    ' I% O- ?$ Q, u6 l: z
            return img_res, target
    & X6 v. K( s/ J' G' I3 r4 ]0 o$ d$ M2 ]' @  K8 \" w
    * j- B. j" @' l
        def __len__(self):
    6 V0 Q3 H  X1 I( S# L        return len(self.imgs)
    # B% ]; `2 O! J" ^% E, D: h" j! j( e

    0 F( n" S2 x3 A. t, y% k# function to convert a torchtensor back to PIL image
    . _% ~, j! D/ x" v$ Udef torch_to_pil(img):
    / F" e7 \6 m4 \! v    return torchtrans.ToPILImage()(img).convert('RGB')
    4 t" s# Y$ S9 n7 W/ A) g! Y$ ~: p& h  Y: C
    5 u$ ]! n3 `% B' e
    0 X" Q  F* J# U/ j0 b$ ]
    ! H$ W5 S- J; O# q4 x% Y) }6 M, n) o+ N
    def plot_img_bbox(img, target):' I% E# Z0 j* W" R% ?$ h
        # plot the image and bboxes4 @: p  q0 n  z/ A$ V7 u& Z
        fig, a = plt.subplots(1, 1): f. M; B# K; n4 p$ ~" e
        fig.set_size_inches(5, 5)+ ?4 y2 R( d: w2 b! ~
        a.imshow(img)
    & ^* |5 @- B. O% ^    for box in (target['boxes']):
    8 i; i9 t1 c: S& Y        x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]( ?2 ]  C& o& [1 ]' k! b: v1 L
            rect = patches.Rectangle((x, y),
    : U& X& U1 m% n$ H                                 width, height,
    ( R# y; E- \1 F; B7 ~1 b, s/ d                                 linewidth=2,  V; C3 A* t8 k( @
                                     edgecolor='r',3 \% _6 f! r! w4 M
                                     facecolor='none')
    7 s' c7 m/ Z6 E, I8 W- P
    ) }9 s8 Q7 [) ~2 r
    & j5 _+ c1 y; y9 S9 I) I. y- V
            # Draw the bounding box on top of the image
      H7 q. i) _# o8 K        a.add_patch(rect)8 b+ d' {1 ?2 P( U
        plt.show()
    5 [2 p6 z; c9 [7 K, _! n
    0 @! Q& J' U' b. }1 M

    6 p, F, T" v4 d! }) M# l2 f
      c; u0 g8 c9 ^' j4 b' y3 Z0 U) \
    + s& S7 F: g5 i! T6 H
    def get_transform(train):
    8 `4 {# N% O; T  O7 v0 A/ C. r: j    if train:
    " o* k  [6 \; N( G3 j0 b. W        return A.Compose([
    6 \. x" }' B' X# [            A.HorizontalFlip(0.5),
    . ]# l( f7 N( w  A% }/ c% j            # ToTensorV2 converts image to pytorch tensor without div by 255( I; O) K1 _) m, L
                ToTensorV2(p=1.0)
    & R% E3 ^& K1 L2 P        ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']}), O0 V; v1 X& x2 c2 L* ^
        else:
    ) v) ~5 ^( {5 q0 ]- P        return A.Compose([3 X- B3 p& p  l# w; t8 P' |0 _) L
                ToTensorV2(p=1.0)
    ' E. V3 a7 H5 {! i        ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
    # f, v- k; t  A: R: h# z5 z6 _! Y' D9 X- n

    , s6 O: A% Y: I9 x4 o% p  P7 C! o, C+ D
    ) Q  C1 w. }, ?/ o' M' _
    6 M! J. j9 a6 g" A7 i8 q

    ; P; E6 i7 z: A; v4 N$ \, N: u3 kdataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))
    ! h( r8 j# t9 S7 E' ?- N- `( l  s) \8 G& c+ M) o, Z) t

    / q/ P* k/ S. c+ B4 D, Kprint(len(dataset))
    4 u9 R8 o( \! R! v8 S* N# getting the image and target for a test index.  Feel free to change the index.* y/ v0 n( r3 f! ^
    img, target = dataset[29]7 s( F, j+ i4 `: ]$ S. r
    print(img.shape, '\n', target)# X) m3 s* B9 J% x
    plot_img_bbox(torch_to_pil(img), target)
    5 p: ]5 n0 ^1 P( ^1
    $ F5 m. E- E/ |( i# d- k2) f" n  t. ~$ \( s5 b) E  v. H% t
    3
    ! r* s# h2 m9 Y5 Z7 q) o4) W- M6 u' m8 y' b
    51 z" _- L1 I6 n" Z2 ~
    6/ T  v8 m9 n3 `6 a3 |' s, ]: [
    7+ _) f$ T" B1 d6 W$ f
    81 \- k; g" \9 ]  w& [5 m
    90 z3 M6 ]) j: C! t6 z; O
    10
      G/ d3 u  J/ i) A+ ~% h118 L8 ]( ]6 I& v4 Q0 {: r
    12
    6 Y) d" x8 a7 q13' f. L( g: y& ^4 D, T6 H9 f
    145 ?) m  M* V8 b* u* m2 S3 F( t
    15
    1 W# a8 {: |8 ^; |/ x+ H165 U/ `+ |1 H/ d7 `* o' [
    175 t5 \1 A- a* A- \& ]% H
    186 V: g3 d4 Y! I' \  U
    194 G1 W! x; b; ~1 X+ ?( |! B
    20
    % a/ y+ ^4 C# b21
    8 T& K) `" F" [' P22, H6 a- F; f, |6 J5 T
    23  J7 Q  |  f. v* m
    24( A3 H% Z; [' t
    25+ q% n) `& ~) \, W  D
    26' y/ u/ L9 G: ]& l4 F# U1 A$ L
    27
    8 ^2 D" S9 j* j: R9 V2 z& m  O" I6 q28
    0 ~: H" o2 a$ W& L1 w' f$ t29
    / ~2 x! R: E' E+ D- B30
    7 r1 n1 k7 p' v* n7 G+ E  f, z9 w31, l, [2 E4 V! q3 X( p8 ?
    32. Z' z6 q  F' M4 `
    33" y1 f* n; m8 K! r0 F6 J: {6 R/ V
    341 \7 s9 i8 Z' P
    35" |1 ?, J7 s# q) Q7 b: B
    36
    6 Z3 m. ^  r( Q+ P4 j375 d% l) f( g2 Z6 M
    38
    - |# Q3 A7 q. T5 i7 I: c; G398 h6 U' O. {" f" f
    40
    - K- l9 d0 K& a+ c41
    4 m# {% [. S1 z42
    " U6 T4 n# E$ |+ }  u4 p0 r43
    . z3 O2 d( H: L+ G" B& _44
    ( ]# W; J& H4 l3 o- @, r45
    , P7 E- c9 d: b+ \& a6 x46
    4 t! K6 s" F& m* u1 q; l1 J47
    2 h- R9 @: R. I( c$ z3 z! x0 ?48( s$ a  `5 F1 a0 ?/ q* A# v# e/ T
    49
    5 X- I# B6 F( ~50
    / U- t' N. ]  {  K/ \  O/ p51
    9 z2 M; L1 u1 M8 O  Q! W523 v. o: B" \5 j3 o0 Y$ M$ j% e; ?
    532 k! K% V$ D9 Z/ S
    54
    ( P" _! V  J7 q  B& E( r55
    7 V/ l+ W7 |. ?56! a5 [# a- l# \; b
    57: }! y( Y8 G# P- F$ [: [
    58
    ! W5 [' ?8 L. S3 q. M; L) Y59
    & l4 g% `- Z5 h% }60
    - h1 X0 B8 M( L61" V. ~" Q# w1 P# |8 Z
    62* M, Q; w% C" k! M
    63
    ; n$ c- M5 C. E4 Q$ V. D" \64. R" H% D) a) G# U& @1 Z
    650 f) q$ O2 H+ R) }$ ?- V- H* _
    662 T+ z8 f3 y+ k9 p+ C* m' z3 ^
    67
    : N8 }& Z1 q0 g68* J7 ]" D, L( n5 x% ~- J
    69: M; J5 Z* y8 A# j8 p
    70
    # p+ N2 j: i  w1 J2 V; C5 V* p71
    + N0 z% }* K+ |' O3 e3 c72% j, [3 T- X4 H. O6 L9 H
    73
    - S! G& f' O: Z# U2 j% h745 o+ V1 z% s, H" Y8 e: i$ k' Q% k
    75
      k2 o5 K7 z3 M+ t76+ A3 A$ l# ]. W! f6 Z1 v
    77
    6 [8 m! W6 t$ B8 r8 E8 e& o1 c789 B( O% Q/ `+ N$ I- i6 [9 ?+ f
    79
    9 C0 H1 |  t6 a1 P* e809 R" `3 U+ k+ h8 o# m
    81
    ) I$ X4 ^$ }( s9 n" K! x82' N; D4 \- w  c# z& l9 k/ n2 g
    83
    3 e% b0 n  [9 m# M( e9 m) o84
      h* c; C9 \. A& V. [2 M851 `1 U& _  t* M+ o# e: O- P
    86% n, B: E. {; h% E
    87. n6 A0 \# m% t2 l
    88
    5 H6 `, [3 k1 S: s89% v% F2 W8 u; r
    90
    ' D2 G: I( K& G, O+ V7 J8 q- i91- `* w# i& F0 N- |
    922 ?  c+ }$ F8 P
    93
      a- k8 ^# h5 s- l94
    " s7 O, N( ]6 T! O954 t# \0 `, C$ O; W
    96& ~0 G/ i, I: T8 b8 P' `
    97
    4 B2 D5 Z7 c. x98
    & p  U' l" n& z% u: {995 }5 m$ d* `3 P( U9 m
    100
    ; w" v4 e& o% @, z  s7 w: [101
    - }* w0 p8 n" }9 r/ i! n  P% f. m$ X1029 K/ `5 X! K' ~: V" z7 }3 g
    103
    3 s& e# I0 Y3 c! k, Y104) x- V& Y8 k# t
    105+ S% ^* [6 [; i" ~& ~/ \
    106
    $ s. r- h) m" x/ o6 q4 I2 K107
    8 g9 C+ q2 i! k% @$ X: k108
    ) L& f" R* D+ U! f$ P/ v) B7 R109
    3 x$ g  P6 y- j( B9 g6 q: u110! G2 T; f- w6 \6 }, e" ^
    111
    ' F9 q  I2 _/ A, b( Q+ ?" Y% v$ [112
    / z8 @* w) @9 K7 k7 S5 ^( E113
    0 h- x, L8 q' F! ~/ t1 g1143 q# I1 Q! M4 {% p$ @) L
    115
    : G3 ]: R  S* d# R3 ^& h116
    ( `5 `; }' Z( |, q7 G117
    ; P6 c2 b/ D# v0 U- C118. u- I2 v4 z" x4 a" \7 c
    1190 }1 F. H+ P+ z
    120
    + J+ E) O! K% R& V7 i" b) i121
    : T! h+ I% p9 [3 |, i122
    ; Z  ?) x( m$ W) r9 {9 {1234 X) }% ^' A' A% Y% M0 ]+ q% \! I
    124
    0 v9 i( P& t2 i125
    ' _% Q% I( P& Z9 @' o# x126$ r0 [- t! |- n& q
    127
    8 A' n6 x8 z/ [" q8 b; u( u8 Q: E9 Z2 X1287 M: V- ^3 C# E/ G/ b" G7 p$ e7 c
    129
    1 o5 s0 o/ Y6 y. m% c2 W7 H9 T130
    / t% w% i- E1 Q# M) D7 t131
    " c# Q- x& g8 q6 A5 u9 C8 Y) ^1322 N9 R" \  d! g; O- \* x5 [
    133
    3 U6 B1 Q. X- k" U134+ y5 [6 T6 v% Y1 d% K2 e: s- @
    1359 M3 `/ [' R8 e5 G' b% Z  f
    136
    9 G+ A( ?2 |% O( D+ j137
    / h) l4 n, I) d2 R138
    $ V# h" N% |9 D: M  J139
    ) `. I8 V( \" z4 r* B140
    4 U7 q( _+ D3 E; N' X1418 Y: o5 F, m* }5 ]
    1427 X( Z7 J2 s( V. {6 Y. V
    143; P: M( A$ V! B% z3 `" C
    144
    8 R  y- C9 }" M3 I2 H( B1452 [2 K. y" K) P" L" Z* [' m
    1463 `  s' o1 M  l7 n9 u# o) e6 S+ P
    147
    7 O" {% g" x8 p( Y9 g148$ C1 y! t: ?5 C0 r
    149# j( c* t9 d! k$ t, M8 U! F
    150& @* i& q8 u: O; L4 y
    151
    1 c8 L+ m1 e7 ~0 p  E152
    ( c* u; J; M0 t7 E. s2 v153
    $ Q9 w( m; v, u9 y6 P5 k1541 f/ j7 ?, J# S) H" c) p
    155$ k; I2 Z3 v+ \' T7 C& H
    156( S/ U. N8 N6 k3 Y9 I+ ^
    输出如下:
      w& o+ p0 z' H- V' s" @; f& u, u9 _4 _8 @

    0 x3 S( U5 S/ Z& Z- ctorch.Size([3, 480, 480])
    / ]" ^: j5 L4 W/ i) x  n {'boxes': tensor([[130.8000,  97.8000, 327.6000, 292.2000],0 `0 Y/ ?! a) A' t1 `5 V# v! }+ q
            [159.0000, 268.8000, 349.8000, 427.8000],
    3 Y6 W- ]& D+ _        [  0.0000, 282.0000, 118.2000, 429.6000],
    $ e8 M# M) x- T- E        [ 43.8000, 107.4000, 199.2000, 280.2000],
    % C( a/ s* d. M( u6 q        [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])}
    # a- H3 g, Z, J2 e* L# @4 B1% l! l8 C1 {! V8 x
    20 ]6 t+ Y/ V$ l# {
    3
    $ R1 H& E; m+ T% z4 L& X4 q0 j) k4
    ! m' |& ~! K) g5
    : a6 C  N5 q6 C. q% t7 }0 w- i4 {6
    6 D# G& I  @' M. ]+ g8 w' q- |4 k8 Y2 |/ K; m: U1 C

    - |6 o; d; M/ S0 @; A! r* G; T5 E) m/ E) G
    : j7 L0 |' w' z; b" J: F
    下载地址
    $ `  r2 i+ x/ R3 m( {+ w链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw$ X7 M) D# W5 f. B) d  ]
    提取码:srjn, g2 L' l$ y0 Y# |1 m: ~1 ^& w% Q
    ————————————————& p4 t" |0 W# \1 ~! `
    版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。, k& {# s. D( U! s4 D
    原文链接:https://blog.csdn.net/weixin_44510615/article/details/118496273
      G) X# {( [2 T( o# Y% v6 \& j
    9 Y! Z% Z3 N% O/ N5 c" q( C  m" p3 v  N8 n" J
    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 01:46 , Processed in 0.463247 second(s), 52 queries .

    回顶部