QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3566|回复: 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
    9 r# n: N  v8 E8 p$ x
    深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息
    8 Y% w7 [, r4 v! {, T图像标注主要用于创建数据集进行图片的标注。本篇博客将推荐一款非常实用的图片标注工具LabelImg,重点介绍其安装使用过程。如果想简单点,请直接下载打包版(下载地址见结尾),无需编译,直接打开即可!
    9 h+ g( [% X  i% s3 Y; B' W9 P
    4 M# j5 {# R# w$ d& u9 r( Q

    1 K' }% |, d# M3 Z感谢原作者对Github的贡献,博主发现软件已经更新,可以关注最新版本。这个工具是一个用 Python 和 Qt 编写的完整的图形界面。最有意思的是,它的标注信息可以直接转换成XML文件,这和PASCAL VOC和ImageNet使用的XML是一样的。6 q. J+ z! g8 o" V$ ?* G" i- v& U6 g

    " C, ~' [9 T' z+ p

    " y2 r) h: v& m; `3 j  O" y9 ~附注。作者在5月份更新了代码,现在最新版本号是1.3.0,博主亲测,源码在Windows 10和Ubuntu 16.04上正常运行。  n0 p) ?+ Z( V" F5 L- Y

    4 z+ }  K" u! F

    & @+ b, \1 N, u' S5 e0 M2 m/ O具体的安装查看Github教程:https://github.com/wkentaro/labelme/#installation
    5 n; T( `" |2 J
    $ v  Z% Q9 H  V. z+ g

    ) X* t: ?- |# s# m: o6 J在原作者的github下载源码:https://github.com/tzutalin/labelImg  V/ x* m+ Y, R/ y
    。解压名为labelImg-master的文件夹,进入当前目录的命令行窗口,输入如下语句依次打开软件。
    0 g) v# N; N1 z8 B2 @3 Y: z1 e, v1 R5 ^

    6 f! h* v% }! kpython labelImg.py, k2 r9 @1 d$ ]) R1 H6 U( z
    1) @& N/ _% |  e

    2 g& O, y! k, F3 \

    ; s3 K2 g! }$ R% |0 @& n1 ~$ M  h6 ?8 s' p( c2 m" N( k

    . \$ r: c4 h* o9 g2 |具体使用
    2 r% e& t9 g; L4 F% a! {, u修改默认的XML文件保存位置,使用快捷键“Ctrl+R”,更改为自定义位置,这里的路径一定不能包含中文,否则不会保存。! Z& N0 K' G$ b, p; N

    # p9 H" Z, [7 s, ?. y# w! K

    0 P0 v7 F$ L1 l" ~6 l3 N使用notepad++打开源文件夹中的data/predefined_classes.txt,修改默认分类,如person、car、motorcycle这三个分类。& m' e7 z6 k$ X8 M
    . j, A* E9 F# e5 a$ f9 z
    * _* b7 N" @/ P4 J: f7 V( S
    “打开目录”打开图片文件夹,选择第一张图片开始标注,用“创建矩形框”或“Ctrl+N”启动框,点击结束框,双击选择类别。完成一张图片点击“保存”保存后,XML文件已经保存到本地了。单击“下一张图片”转到下一张图片。1 Z( n: u/ @9 ]; K. `- u) m

    * S. w3 _7 F7 ^0 R% q1 s8 r. F

    ; I. y% y; y+ E! G/ Y$ D贴标过程可以随时返回修改,保存的文件会覆盖上一个。
    ! o" \& G8 |. i1 o6 L5 r* o+ W+ k! ^: ?8 c; j7 H
    : }" D  i& ~9 I7 u; B: ~
    完成注解后,打开XML文件,发现和PASCAL VOC格式一样。- Y" c9 D3 D  Q8 o" V5 J% X4 n
    4 I6 m, n* \& ?$ b$ a/ r% i) v4 o

    0 M$ v6 {: M9 Y  V将xml文件提取图像信息# B, Z2 e* w4 U4 T
    下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。  M. B+ V+ a6 V  U6 K  X* }6 {! z
    + T) q: {& \* h( g$ h4 X
    4 r$ x! [# ]$ ]+ J; j+ ^7 B
    4 k8 b+ ^( K9 J# M

    ; z2 s7 k2 R- L2 R下面是images图片中的一个。9 b1 F" m. ?$ [) ^( a  |
    / a; D9 P! X3 e5 p+ j

    4 c; q( {" [5 f0 S1 V$ d5 h下面是对应的xml文件。; y$ w& v7 l  r; P& a2 x+ e9 k$ |' G: ]

    # u2 |: e% t( E( {% N" u& o

    * ~: I% l6 A* Y/ b. B- t<annotation>
    " x( h( D2 s) M3 K& z% O! c5 T2 ], Z        <folder>train</folder>  r) _6 Q5 s6 d) K% e3 _
            <filename>apple_30.jpg</filename>
    " k) z% @" [: \8 n1 R        <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>
    ( _8 F2 `: x2 W- W: {) `2 j) p. y        <source>& j: y4 t9 o# l/ i4 q, V8 I. o
                    <database>Unknown</database># P9 r" L* Y5 u+ |
            </source>. X  A" R" W- o, Y' {/ Q1 k4 ^
            <size>
    7 w, C( Y  L7 N/ A0 G9 O5 x5 t                <width>800</width>9 ~' ]% P6 g2 C) k) F7 d$ ?/ C! P* S+ V
                    <height>800</height>5 W7 T2 R: A* |
                    <depth>3</depth>' |9 f; a! m( L7 }+ K% W
            </size>% }8 v  W. H6 x$ e
            <segmented>0</segmented>
    ) v1 V7 Y) }, n4 i; ~. \" K7 L        <object>) `) s4 Q/ [1 m  h% z( D
                    <name>apple</name>
    9 d! c& k  D, f$ S5 F1 g0 B' u                <pose>Unspecified</pose>
    8 J/ Z) ?! `% D7 I* X% h                <truncated>0</truncated>
    * |, h( A* e0 |1 A. d                <difficult>0</difficult>) i7 v/ y, b0 ]9 M' [1 R9 P- ]
                    <bndbox>
    & s# }8 k# L5 A0 w                        <xmin>254</xmin>
    & W2 l" k2 _* _/ h! M                        <ymin>163</ymin>
    3 p  b: j: P" u+ f' b' q7 M- ~                        <xmax>582</xmax>& j4 u# Y  H4 R, C- r1 a
                            <ymax>487</ymax># n4 Q# q. M+ P) J6 b
                    </bndbox>5 T3 A1 }6 e8 x0 B" e; n% r
            </object>$ q1 ?: T, v9 J8 x
            <object>
    " V% |" Y. B, r                <name>apple</name>
    & o: n, z- [& q                <pose>Unspecified</pose>+ S; T9 P7 L+ P8 y3 ^. P: d
                    <truncated>0</truncated>
    ' x# x" D- A! f                <difficult>0</difficult>
    & u& R# n: \4 u                <bndbox>
    2 \6 f! r% u3 Z- o# @0 B2 n                        <xmin>217</xmin>
    5 N) V! i9 l/ {                        <ymin>448</ymin>/ T& j  L7 R* G% i, l3 M
                            <xmax>535</xmax>" d6 t4 e( P- E, Q* _6 B* R
                            <ymax>713</ymax>
    2 t+ d- N8 I& R" i5 C; V                </bndbox>
    3 J- @8 \/ L6 O% l: u; `! i6 S        </object>% R2 [$ j2 b, d  y, I: X( V
            <object>
    2 {  @* g# c! O, E+ T                <name>apple</name>4 w( s* b) f9 M4 g+ k9 n
                    <pose>Unspecified</pose>
    ' y  P- n1 L) }! ?' D                <truncated>1</truncated># Z/ _7 F3 _$ N5 o
                    <difficult>0</difficult>- L& c7 h' V( E1 ~5 w5 y9 D# |
                    <bndbox>+ q/ U  t  f" K5 Q. v6 F8 R5 z
                            <xmin>603</xmin>- {% ~6 v4 I8 {; q
                            <ymin>470</ymin>
    & S1 J3 B2 d- B: ~/ I+ k                        <xmax>800</xmax>/ z( O9 t) F/ ?
                            <ymax>716</ymax>
    / Z6 Z0 m% l9 X; i                </bndbox>
    2 W( C5 n# l5 g0 c/ q! l        </object>
    / }; L. Y. G9 ?1 R- X3 R        <object>7 _4 E( S% Z: x3 m! O8 Y7 j
                    <name>apple</name>
    / J# z) V6 G, y0 S. R' R                <pose>Unspecified</pose>, K- D8 K, H! o2 @# s  f$ |
                    <truncated>0</truncated>
    / ^  k4 \5 P5 T  S$ V/ H% e# G                <difficult>0</difficult>' ]7 t2 {. Q8 s. n& h) Z/ I
                    <bndbox>
    * e6 ?6 r. S4 ~- @                        <xmin>468</xmin>
    # c; @$ Y8 R; a3 r7 d                        <ymin>179</ymin>" J1 n6 v" j! J" f6 ^
                            <xmax>727</xmax>; L& L# \: K; ^
                            <ymax>467</ymax>% c5 `5 F! O1 s4 d' E, G% m
                    </bndbox>
    2 C& F; p# `  D# I  ~2 E' G        </object>
    " O& C9 {2 D" y$ x        <object>
    ' W% k# P3 \) r/ O: E                <name>apple</name>% m) b/ j: ^6 A. I) R: [% K& V
                    <pose>Unspecified</pose>
    ) S2 L# y. }( ^3 `                <truncated>1</truncated>! r$ T& ~/ ]- o- L% Z! Y% U9 ^. e
                    <difficult>0</difficult>' c8 M( d: ~4 {6 Z' k1 f
                    <bndbox>
    4 P' g9 Y; T1 ]+ R  j& g( p% v                        <xmin>1</xmin>8 [( I! \& h5 J+ a2 M0 v
                            <ymin>63</ymin>2 v  U1 }  p  v( W' f$ [
                            <xmax>308</xmax>( z- }) F! }1 b  ~% Y
                            <ymax>414</ymax>
    * n1 o/ w0 G' D" c0 X' V: D% W                </bndbox>1 [8 T* Q% k5 Q3 C
            </object>( S' B6 z/ j  L( L5 M+ m
    </annotation>
    0 W/ k: O$ W* \12 n6 W& a# F/ ?' Z( K5 w+ y
    2( }; T6 a" R* @/ j2 V7 Y9 o
    3# x  z8 f: g- S, K2 M  V. M
    4
    ' q9 T. X1 T3 p6 x' Q. X5. b3 ]% x" ]0 d7 \
    6
    2 y& j6 r1 `# `9 R) t5 W! _76 K$ I8 W+ f; @/ _& X7 t+ ^
    8
    . O. [/ @$ L1 b9% g' o5 P6 L1 S' O% {9 O/ B; f
    107 r. |6 r" ?* d* }* l- N. p
    11
    / j6 t" C$ O) @; `12
    * q% I, ^% _# I+ J7 r  Q13
    7 {% Q* M9 V( K& L. B( ]* u' |14$ [5 d2 _0 X- z9 w. b2 I
    15: x" t7 ]0 t9 ~- c
    16! |  d$ e$ M2 k4 @  ~
    17
    4 r& n  B% y6 c9 S2 W' P18$ A/ L8 B& ?  Z9 a
    19
    6 s8 T7 E& d' j- P& D* z4 m207 [9 y, x8 O9 U# n% `# l
    21
    / D$ C8 O& X4 a22/ M* w) `# V9 q/ g) x
    23# D; t6 }4 A8 r% U
    24
      f8 F! i5 N0 s2 e) V8 `7 D25
    ; ~% E4 `# F* H: {! ?5 p! G* x( \26
    & z. s  S9 d0 o! @) q: Z271 m7 |# d- T4 r, P
    28
    2 r3 E, `% N$ D) G* F* ?297 l* G' F- l- E$ b
    30! ^1 _' ~" I* G% r0 p
    31
    0 H% t2 e, g6 E! i- y32
    $ j7 p3 D4 }1 j' ~" s  q! C33
    3 u; @7 H! W/ k6 |! |4 q34
    : K! q% V( V7 U7 M/ m35
    5 [" I8 ?, ]9 s! r. O; S/ Y/ q36
    ) e5 w  X6 x, p; j37
    8 r6 L0 e. a9 u/ c1 B; i38$ E$ n& X- X2 [, n. b
    399 J/ I* v, l3 O/ b
    40
    # |/ ?9 u$ L5 L4 |+ ?2 C41
    4 l/ Y1 u0 P" _( L1 D42
    ; R5 k! v% {, u+ A43
    8 H# V6 e0 w- O44
    ) w7 g% y6 b3 ]3 q. R8 ?452 ?% ]7 j/ f: b
    46' y; p7 [( G; B2 R( n
    476 R. z8 u2 J' c0 G3 `8 T0 H
    482 I. [6 y; z- G+ x$ a0 D; R
    49
    7 ?2 |# ~3 w6 x3 X1 S* ]50
    - |7 t; a6 M1 |) f& E6 `. P/ }51
    5 f2 A0 w7 e$ W/ t52
      x; V2 W7 F1 y- _7 i: L9 x( A; Y53: }, d$ j5 B+ s4 G; Z& f
    54
    0 q6 x6 M( x2 X55
    - c8 {2 b, D' l- ?" V56
    3 ^# a* _3 {" K" Y57( }! ?& q6 p% X
    58" \4 @+ A. i" S6 t% E) v! l
    59* ^/ C  X( }1 d; Y- N$ J
    60
    $ [" a4 Q. l  B' W) e5 _61$ p# H2 s6 l; Z2 W& \
    62
    0 K, f" x% e2 j7 m63
    9 a- w2 Y2 k9 S9 W& |/ Q7 r643 b5 c; L8 d) h  g$ z$ B
    651 t. d, v5 Y  C( R; D- R+ E
    669 p9 G" _' y6 T8 C3 B: Y* B" O- R) d
    67
    9 ?' W  _, a1 W  x68$ {" g8 {: a& L! N
    690 Q' s( R; i& M- G. \5 V
    70
      W) w( |% n2 y0 E% r71
    , K% p2 y- {2 b/ X: A! A" J, s723 F1 c, X: j0 ^& l6 I7 k$ j
    73
    1 z- ]% z$ K. z9 ^/ B74
    * I; Q; j* i1 q1 [" D5 {+ d. [- @) F将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。
    % j* `+ ]9 Z! j0 \' c* z8 @6 k- V: [

    ' j' b. S1 c: c* {import os
    ; A! e% ^' j# }import numpy as np
    + j3 x( m! x; C9 ^import cv29 z, h% i: ?  N9 e% \2 @& b
    import torch
    3 f9 R! j4 Q2 v: ~2 ]. i( ~import matplotlib.patches as patches+ |2 x4 @5 G$ G- u5 b4 P# a/ J+ L
    import albumentations as A
    3 d3 `# v, w( j0 e4 F1 b# gfrom albumentations.pytorch.transforms import ToTensorV2# ~6 t2 y& _, s% R6 y$ C+ d; R
    from matplotlib import pyplot as plt, V2 u: g0 w7 t: ?4 z: N
    from torch.utils.data import Dataset& A5 G( v8 j$ n. p
    from xml.etree import ElementTree as et+ M; \# j% o8 v
    from torchvision import transforms as torchtrans
    1 @2 E" T& v+ x8 r4 j. [# ~
    # j! b% e: z' H( g2 O: v8 a

    9 ^$ x3 B7 N9 D+ m, H5 p# defining the files directory and testing directory
    ( k. E' K3 X3 [9 ~. S- ^$ l6 Strain_image_dir = 'train/train/image'4 n' S6 O( V( f- A- ]" [
    train_xml_dir = 'train/train/xml': ]! t6 c# w7 A% X8 z9 Q8 X
    # test_image_dir = 'test/test/image'
    + K9 M8 l- E3 m" ]9 C' k# test_xml_dir = 'test/test/xml'- n. e: T% S2 [2 H. w
    $ k( W/ z! y; i: D

      ~& i' g" H7 [class FruitImagesDataset(Dataset):
    ; [( V8 P) Z4 P6 l8 y6 q6 @9 v8 K: P: L( b+ b
    ( f9 V% C. H3 }5 z* ~
        def __init__(self, image_dir, xml_dir, width, height, transforms=None):
    ; o( ?+ x7 B3 V4 [1 h$ M9 ~: K        self.transforms = transforms+ S) r1 l# K0 \, q+ Z1 n  x
            self.image_dir = image_dir; P* V$ e- C' x% \% W7 A
            self.xml_dir = xml_dir, C2 e! w0 @9 B) K1 c
            self.height = height
    7 M7 Z% ^6 g5 O  L% C6 c1 c! Z& w; _        self.width = width, i7 I9 E4 x0 O( m

      ~( l  ~* ?: Y* Y4 A( }4 h
    # X3 d% Q, l' N1 ~; ^
            # sorting the images for consistency
    * b+ }7 q( `! U1 w        # To get images, the extension of the filename is checked to be jpg0 Y. M# K% x( o0 v7 [! A! V
            self.imgs = [image for image in os.listdir(self.image_dir)
    & p9 J" k  x+ U0 c                     if image[-4:] == '.jpg']$ _5 O& ~0 `8 s- ~1 [+ e6 N- G
            self.xmls = [xml for xml in os.listdir(self.xml_dir)
    ) T0 L1 z( p  c  F3 j- M) i                     if xml[-4:] == '.xml']
    & ~2 N4 `( b. p& h1 c' |, c6 ?; Q8 m4 @1 M- i  p% B$ p
    2 j: Z, \4 z+ ?4 W6 }
            # classes: 0 index is reserved for background# e8 r; }# Z2 j. o
            self.classes = ['apple', 'banana', 'orange']2 l& K) ~! F: }7 s# e; z

    2 D8 y# s/ Y. v* S: ^% \- d, e

    ! C7 P8 E' t2 y: [# h    def __getitem__(self, idx):/ E" [! B' e& o6 S3 c$ a$ X

    * y6 _1 Q$ Z& n+ `8 @$ m, y
    ' {4 C5 U) K; c5 Y% r' e+ Z
            img_name = self.imgs[idx]
    8 w6 s  t  t  u. i        image_path = os.path.join(self.image_dir, img_name)8 T' J1 |% X; F9 H

    + u5 ?! i3 }  |  c

    7 N' u: J5 I% m        # reading the images and converting them to correct size and color
    # W( \* w! m( ~$ v6 W        img = cv2.imread(image_path)
      @6 F& s: T4 d9 ^3 ~6 Y$ o        img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)
    3 j( d+ R7 @' H: C! _+ x# p        img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)" y$ j4 h9 G) T
            # diving by 255
    ' {2 G' r  Q. ~0 y$ H/ I6 J        img_res /= 255.0& @+ A2 W3 J3 i+ P9 X+ t+ q
    3 @8 ~1 Q& F; r- G( j6 W  t
    ' E3 s" N, r, F& _* Z: w
            # annotation file
    ( P. D. Z5 Y- E: X& @        annot_filename = img_name[:-4] + '.xml'/ a: V6 z! X, z4 r
            annot_file_path = os.path.join(self.xml_dir, annot_filename)
    : A( f) ^9 O4 h9 ~
    ! L3 ?. U! D6 f4 _
    8 p0 N, `8 `# E( Y
            boxes = []) l5 g+ ~4 X  x" d& C9 @- ]7 d
            labels = []
    3 V; }% J* |* B% {4 X* x7 V        tree = et.parse(annot_file_path)8 f0 [6 ~) C' d1 \- O) g, ?+ _
            root = tree.getroot()
    ( G- n. K6 ]. S; P( ]
    4 J% N# e, t, z- D/ n
    " K: ]. N% n4 U4 M- A- c
            # cv2 image gives size as height x width
    0 v1 V" Z8 p( v: w* j" M$ n2 W& E        wt = img.shape[1]
    $ }+ L9 C" ?1 e        ht = img.shape[0]
    2 h. M2 R" e  P: I2 J0 W# G) [% F4 }" V* N

    : t2 P$ }7 g. w) v        # box coordinates for xml files are extracted and corrected for image size given
    ) D; G# W8 M$ \        for member in root.findall('object'):
    2 H' ?0 k$ W1 m- ]6 K            labels.append(self.classes.index(member.find('name').text))( {. f2 y: D! {/ _! t
    6 U9 |/ D. e3 c5 Q# I5 r
    7 U/ v' K  w* F9 s; l8 B% M( f
                # bounding box+ }  Y8 R. o, W. `5 c' k
                xmin = int(member.find('bndbox').find('xmin').text)  N$ h" j8 i7 t3 ^' h
                xmax = int(member.find('bndbox').find('xmax').text)
    8 k& z/ j, v) B4 C+ {: _# C5 @2 ?. v3 M( v$ `& K3 @8 z
    * E  N6 I; O1 `! b6 u! C, {$ u
                ymin = int(member.find('bndbox').find('ymin').text)
    4 _& A9 M: T3 I' p  M, v* e            ymax = int(member.find('bndbox').find('ymax').text)
    # }; N) P  [& y! M$ L: L9 m1 w8 ?
    , B7 _" J; t( `7 }7 W, o# h
                xmin_corr = (xmin / wt) * self.width# ]9 W+ {1 ]  B
                xmax_corr = (xmax / wt) * self.width  G; v1 P3 x) G' |+ ?
                ymin_corr = (ymin / ht) * self.height7 J& l* I- x: N2 t( o0 n1 [
                ymax_corr = (ymax / ht) * self.height/ ^/ D/ k  y+ D! R3 e5 \) d8 O. Z
                boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])$ ^$ T7 K6 H- V
    9 T" I  j, s; n4 A  z
    , j8 ^$ W$ u) F/ l. q* e
            # convert boxes into a torch.Tensor1 \0 A& a& L3 P+ {7 Q
            boxes = torch.as_tensor(boxes, dtype=torch.float32)
    , K7 J  a8 ]1 V/ q! }: R+ a
    : M: ]1 s5 J) I7 s0 B) U
    + \) J8 m! L! o/ l8 W0 q: _
            # getting the areas of the boxes
    9 s4 t+ F* R) M& v! }        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
    * v5 ~$ A4 Z( p: X! {: t+ W7 _: L2 J; [$ _; a+ Z5 ~" m

      Z) e$ \0 Z; T9 R  o; S        # suppose all instances are not crowd. Q( `7 z9 v( b# _, N% }
            iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64)/ J5 Q, Z) A& ^* K9 z! o
    8 c7 W5 W* U5 Z) ]& f6 o0 U
    , |" a+ u- g; s, }
            labels = torch.as_tensor(labels, dtype=torch.int64)  Z9 i  r- c/ A! b7 W6 O
    0 K2 _. V9 o. r$ Q! w4 c+ Y' _% m
    6 h8 j! h. N9 ~
            target = {}& W1 v3 K4 Q# l7 ?4 D& h1 b0 e
            target["boxes"] = boxes
    # U$ k, F! j  i6 B5 x4 I        target["labels"] = labels
    % ^7 b/ C- ^6 _) `        target["area"] = area
    $ s4 P8 W8 D0 u4 ^. u. O' ~* J* D        target["iscrowd"] = iscrowd
    7 P6 J4 I8 f, J! S; F, z0 U# m        # image_id0 Z2 H, ]4 ^/ Z" X
            image_id = torch.tensor([idx])
    * n  E5 G- K; Q- a' h8 o        target["image_id"] = image_id/ x1 n! E/ W/ G! u
      }! Y$ z& l4 L. H2 U% P& s( G
    + x7 q: X( _: G+ j5 z. G
            if self.transforms:
    : @, `' H! N$ C0 z; w            sample = self.transforms(image=img_res,
    4 k: n; n( X; H3 E. h; ~                                     bboxes=target['boxes'],
    & E3 N, o- G& C                                     labels=labels)
    : e) L. L1 v# S0 G$ O0 n5 p0 m5 g8 t: f! n5 O

    4 p5 b8 N+ ]+ ?8 ^& Y' E* T! J# g            img_res = sample['image']. _! D( F+ j3 S
                target['boxes'] = torch.Tensor(sample['bboxes'])
    ) f, u# [# K' r5 k( Y4 B$ K2 U: U
    " v7 y8 |9 l6 r8 o2 N5 l
    # O! l) q7 T3 j# j7 O1 V
            return img_res, target# j" q" q$ |# i( W& u

    4 }- h  B9 p, r
    % _" u( U6 |+ s7 {9 i( ~4 M
        def __len__(self):% X" V; [4 d& m- g
            return len(self.imgs)
    : R* A2 K/ l2 r" K1 R: Q8 F
    3 n( X8 S% R: H7 U; B$ w
    - R( j; L, Y8 D3 v* q/ U$ [7 Q
    # function to convert a torchtensor back to PIL image# ?; `1 q9 _: H1 q# n5 C
    def torch_to_pil(img):
      @4 @; r% P1 Y6 X4 n    return torchtrans.ToPILImage()(img).convert('RGB')
    $ g/ W7 _3 ]+ \5 @4 ]0 W# P6 s% d  o8 S3 c  k
    + x) E' a% r4 T9 T5 h

    0 G# c2 n  ], b/ T* L
    ( I7 [" s; \6 x
    def plot_img_bbox(img, target):
      {# h+ y) q" B+ D5 Y' g    # plot the image and bboxes; e, b% [5 Q  `1 ~6 r) `0 J' H) J
        fig, a = plt.subplots(1, 1)5 \( f9 z) V4 h1 M4 j! |* i9 V# V
        fig.set_size_inches(5, 5)% h. F/ v; S: e: U: x
        a.imshow(img)
    / j" m9 E- D+ |/ i  b% y    for box in (target['boxes']):
    . M1 S+ ^: A) s5 C% d9 p/ c        x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]
    $ f( e' }" `) _8 S0 Q7 r        rect = patches.Rectangle((x, y),
    0 w/ u  @3 f* ^4 i& G0 |' d9 K                                 width, height,
    ) N. W& P, _/ q4 c                                 linewidth=2,, D9 h5 ^) C3 P: S% z
                                     edgecolor='r',
    ' h2 C% T" ?% R. V                                 facecolor='none')5 }0 ~2 c( b5 n

    : k$ L9 Y& e) p0 P4 q) c

    % z& I, _9 u7 }$ c0 @        # Draw the bounding box on top of the image' v, _" Q6 c; B) g9 a8 Z, w
            a.add_patch(rect)* y  G4 X& N% o& p- n9 C
        plt.show()
    , z( k; T/ {" B; E" t  \$ x1 B% O
    " j# i1 q8 V$ X: q. K
    / P) p- n/ a' v1 O; Y0 \

    - N$ C  r+ \& z! a  i, {: b' r
    1 o' Z$ d( m. f. v0 Q! i1 u5 C( ^' I
    def get_transform(train):4 [( B6 T9 p7 }7 {0 E$ Q
        if train:* r4 @& C5 y& X; B9 r4 q! L
            return A.Compose([
    6 q1 x; v4 M* v0 V2 z            A.HorizontalFlip(0.5),
    7 f! G. Y, H; |( `! J* x) }            # ToTensorV2 converts image to pytorch tensor without div by 255) ~4 T. T1 `3 K0 U6 o( g9 O
                ToTensorV2(p=1.0)
    ) J0 s' h5 ~: l4 u; d        ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})4 G' W' c# J  W5 ?1 ]" G
        else:  K- ]! M5 O' @+ p" J
            return A.Compose([
    7 _% ]# H9 K' O. q5 U            ToTensorV2(p=1.0)
    ' t/ J1 H* F* k+ Z        ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
    ' W" H' G& u% g* M, V8 {$ D" A
    , ?! L* R  U+ q& ?" r; l

    % Z* y9 _% u! \7 ^) o) B- [( g) K( f5 l
      Z& c, A$ k$ ?, |' ^1 V! q
    1 S  D1 ~' N0 v+ s1 |& V+ `

    . c2 n/ k  ?$ ~3 ^3 rdataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))$ Y6 C; `, Z7 m& C) ^

    2 e) d, `: M2 `, Q1 s

    ; ?4 F! f& o5 I6 Rprint(len(dataset))! n' i: T/ N* f% i6 L! [
    # getting the image and target for a test index.  Feel free to change the index.
    & H: C7 a  ~4 P! C" eimg, target = dataset[29]
    9 u$ Y: m0 M8 X( [print(img.shape, '\n', target)# N' \6 c7 O) C' t  w8 Y
    plot_img_bbox(torch_to_pil(img), target)" A% h7 X1 V2 c' q3 f2 S
    14 g) c3 E: Q* L8 ?  Y
    2
      c1 t$ |( i& w# W3: g9 y* a7 b! ~7 t, B/ a
    4! \- K6 J5 S9 o8 h! G
    54 S3 Y, |6 P; C* G8 O- {# E3 ?* ]% e
    6
    4 V( |$ w6 H' f7 T+ }7 ]7% i9 l, n: Z! E- G% T
    8  f1 G3 _6 w' J5 x( h# N9 n
    9
    5 \, t4 V) w( }- Z' q10: V2 G+ w/ c; I: ]' @( H' x
    11
    9 z. A  {$ E( U: M+ m4 {1 X12
    % s3 o, r. R; j7 Z, i13
      a/ G1 ?8 e( x; }, o0 p# h5 o# I- ~14
    ! A2 }- ~& s6 G1 k3 L( ~8 b15! L( ~7 ]% c7 c( s. \- l8 Y* `
    16
    4 y0 K; t7 ^% E2 O17
    3 \8 \1 ]! H7 \9 ~6 D18" A3 Z/ }! ?! {/ H) E6 f3 d$ c' z
    19: j" C: _4 r4 Y3 \5 ^" L' t3 T9 t
    20
    0 ^/ Q* B) Z# }- Y9 [21) `6 R6 z. f+ q, Q8 Z$ ^
    22
    ' f: r) K4 d4 D! T- `) d) h$ `23
    * K* {+ I0 H) o* H* x6 I7 }6 n24
    ! W3 y5 v2 Z  v258 b5 `$ ]2 G4 E% [  y+ @
    26
    1 S5 t+ Y+ h: g3 o) b7 c271 n* A+ S6 i  ^* Z
    28
    , t0 J! B3 H, P+ k29! ]9 i7 {6 }% \9 L# t
    30& N+ Q( C- s8 m6 a  T3 `
    31
    9 g( Q2 W% I% L) x1 W32
    $ G  S$ A$ ^4 t5 |' m, ?4 f33; c/ ]: N" t; [
    347 R1 m3 w( |' v; N
    35* t+ v0 S) f& }. O$ E
    36
    1 q% U! p! K' p8 o37
    9 ]9 P3 S- Z+ j, [1 V! a38- L  J; J# L$ @4 {& y
    39
    , ~) R+ @4 U# w' }3 C' U2 q5 h* Z; y40' |6 Q$ v0 g$ R. p. L% [' H/ [
    416 ~+ S5 p  f% ~4 E
    42
      @8 v, G$ }; t5 _; U9 H4 a438 r) M) e7 b) n" S
    44
    1 ~2 ?! X$ m- u# I$ R45
    % ^  j9 ~; g6 u% S) @& _46) A; T3 S6 Z( m+ l& l  A% t" ?
    47; `( J( _8 [- n7 ^/ O
    48, u8 P, P" j5 H5 G7 q$ y
    49
    8 ^  W1 S0 f6 J; R0 [/ V9 j1 y5 O* ]" e50$ s+ g) {2 C, |! o, d2 x+ R  l  _
    51
    & o4 E$ |! p9 Q522 G* W* n5 g2 `% W$ f. Y, ~" h# i
    53/ X* g$ E; u( t2 i, V! J
    54
      x! I, y' D; x; \% T8 Q0 L55' p$ m) ?) _8 X
    56- s; k! E5 g* v0 \0 }& e
    57
    # T/ P' d9 i4 c; x) d# G. j58% _5 G0 a4 P& i2 I. ?
    596 W8 Y  l, q: ?/ y, M
    60: A$ [; z* H  A, w* ]  Y% T
    61
    , k! [* |6 Q: B62
    . B; z* @3 `$ r0 B" H63- C! t2 N& x# y' R6 Z& d# l& q
    64, }% A) W# {$ U- r  W2 v4 R/ S
    65
    , U& T* a! s( I66! K) z; `0 \5 U! ]# j, a5 t
    67
    6 S: h! d4 J& @5 [7 I  G+ R) l1 v68
    5 Z* u; T  j% v) H, z$ d( |4 f69
    ' e  j' r$ Z- |9 C$ ], S2 y/ `0 \# X7 `70! M# a9 t. _  {5 U& Z9 x( J
    71$ K* S) e2 Q- A) I
    72
    1 J5 d# [" A% ?* r5 G( U% e73. ~. a/ ~2 ]+ N% F) B* r
    74+ Y: v- J1 E6 ^: |
    75% ^1 a; v; W# F- W7 c
    763 H* a7 K) Q# _9 v  m+ C
    77: j4 ]* Q8 w& X" N  v
    78/ d7 v, P$ S/ A; t
    79# o, ]0 u  t! l( x( ?
    80: I; E# Y7 i" e9 w
    81
    5 _2 @/ s! C& W; J" Z8 z* W. }82
    9 v8 h0 Y2 K- }7 B$ Y, T83
    / s' \/ n. K' j" V4 D# ~843 I4 ^6 f) p: b- B7 f3 v; L0 d
    85. k& F7 j" k8 k  H( G
    86
    * l" ~+ y+ C0 T& u- T6 W87. ]4 a& q, ^' z2 ~, U/ n; d
    880 y- Y0 ^4 [( r2 x( b- ?
    892 u3 L( M. z* o6 l- e
    90
    $ w. o# W" E) ^2 y' ]& I6 A91! y- s5 r# \' f8 c1 c2 X
    92/ ^: @8 i  O( ?. G3 q
    93
    & q2 v; N' t' c) {3 G940 C: x' }9 G% a1 E( r6 v
    95
    9 j1 ~* o9 R% d96
    $ n& r( c; I5 w5 [+ y97
    9 v  t! X- K; I: ?! n6 O98
    7 ]( G! ^4 |! o( y: X% e99
    ) B) `9 |: J9 N! U8 [100! ?0 y! N) x+ L) @0 }
    1013 t4 U5 ^0 G$ Q5 F' i- _) C$ Q2 d
    102, ~* U& }) @: p- A6 t1 x
    103$ t; [, J2 S% J" x
    104
    8 C/ p( o5 B  n: |1059 W7 O& @+ Q( P; Z* l" I! p& h
    106% }- x6 g, z; k+ {1 |
    1072 }( R. O, p0 t5 @; |  _0 y$ u1 r8 f
    108
    % Z" O( X" r0 m% r* f109
    * R& ]0 @$ x  j; E' y: a4 ?1107 p7 l5 q+ I% g% @5 m
    111
    9 z$ }( J$ ]& b. n6 o1 }+ Z112, `) g6 n8 c7 K" ]$ v
    113
      g4 h& Y) E5 _" m114
    + a2 u' x5 E3 O) c8 o115
    2 g7 z/ a2 E  Z* d116% _+ q4 p( a! X8 I
    117
    8 e. k$ c, Y; g% v9 ]118' b, Y4 u& c$ S! x6 ~
    119
    # j) d1 K3 J/ X5 t6 q* h6 J, f' T120
    , f. P  O9 ^0 U  q121
    1 o7 Z0 P7 M  @6 v/ z122' a. l0 \0 j* i4 D6 V
    1233 u5 x* `4 A3 F( g6 \
    124! y- j3 H, O3 P9 \! n4 z
    1257 g% a. d1 M, g5 X# {' D, C
    126
    * I, q" k# E# b0 E3 G% w127
    * @# m* N( ]6 a, _  P% g: i) Q128
    . j3 E2 [1 o0 P) e! F0 Y* V129- |6 \. k3 t2 I! H
    130, F8 j; n7 Q7 ^; q/ J" f; `3 h( {
    131
    5 N  {: w" ?0 |$ K, z# W* M132
    4 m. l' f  w% ^, I133
    " m1 p- E% J% U1 K8 ~! s+ S134
    . S9 `& |5 o. P6 b135
    ; i) O" M& Z6 D) ~. B; Y) l  j136
    " I) \7 |1 X" b+ y$ j137* {$ [2 J. i- `% M3 \
    138
    ) ?! A9 F% w  L" I. {1398 D( J6 S) s( l3 r
    140  s4 w- E) M, v" K, i9 \
    141. J- N% b; l# m% M6 {
    142
    , a' U6 X" ?! h1431 K/ m6 S2 Q0 {& E8 X
    144
    4 v& M9 j) [* t1 _+ b2 d7 o145
    / K: N! Q# S1 u! C# S1469 i' `# e  [4 e$ g# u3 p( r6 j) ^
    147- i, b/ }. v$ _5 d' \7 W- D! e
    148
    3 w& X  x, t) W149
    " e" a$ o4 d6 [0 |6 H) x) \+ ~2 @5 c150
    9 n& _2 M$ Z/ g  M9 S1519 [3 ]9 }6 B8 q- S2 M0 l  m& e3 m
    152
    3 i" H6 t* n2 {( ]) l. A153
    . t) t0 W' K; c$ p! }154, A* g/ O/ \* F# r+ e9 B: u
    155
    " T9 U3 H9 ]: ?% G; J4 E% O* E( a156; ^( c% Q: `, u; ^( S
    输出如下:. V! w/ a4 P% Q( \
    1 |) T0 @, e8 U$ F) o5 z9 s

    + e: {! [" L3 F3 r3 Z7 t9 t# L. ctorch.Size([3, 480, 480])
    . N- ~* ?) I+ X4 Q( S8 H) L {'boxes': tensor([[130.8000,  97.8000, 327.6000, 292.2000],
    : B+ I) @8 X  ?, B9 R2 I9 y        [159.0000, 268.8000, 349.8000, 427.8000],0 M; b5 }  b- A8 @
            [  0.0000, 282.0000, 118.2000, 429.6000],' ?1 q2 j& ~5 D. p# X
            [ 43.8000, 107.4000, 199.2000, 280.2000],& a- @* ?" l! k
            [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])}
    $ ~1 C3 s3 P6 W4 x+ ?9 Y2 _1/ G9 l  I* c5 n$ v
    21 ^- V" p! _0 d
    39 p  @0 m4 u. z% D3 j
    4
    * w" N+ T7 ^& u& i5 d( t5
    $ L0 j7 u* j$ g  x5 l* y62 O5 m, ~; [! X$ k0 B- \0 Z) R
    % c4 z2 Q8 Y9 {! f0 T9 ?1 f
    - b) p, V6 T" O
    " |! D& x2 Z6 l/ g7 U

    ) i# D* p/ j4 V* l2 L下载地址
    ; k: K2 Y( n# }链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw) P1 \& J3 p4 D* p
    提取码:srjn
    ' a8 g  A! T  b7 n( k0 R. J————————————————% z: U0 O  _8 x2 y
    版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    % d  i# f* e. B% n# h: F原文链接:https://blog.csdn.net/weixin_44510615/article/details/118496273
    ) b) Q6 ^% ]0 C8 ]7 C$ G. p
    ; F6 [4 R; |' k- Y
    4 b/ F3 m5 H. F" Q# Q' ]
    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-9-13 21:05 , Processed in 1.455754 second(s), 51 queries .

    回顶部