QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3081|回复: 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 y8 f$ C( m) m( Z6 }; F" Q& o
    深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息
    ) S+ j7 c# I9 s$ y) y- k图像标注主要用于创建数据集进行图片的标注。本篇博客将推荐一款非常实用的图片标注工具LabelImg,重点介绍其安装使用过程。如果想简单点,请直接下载打包版(下载地址见结尾),无需编译,直接打开即可!' M1 A, s& J/ z  U8 s
    ( y1 _$ z9 |; R2 h' E

    # X' I. x8 w* N! [' Y感谢原作者对Github的贡献,博主发现软件已经更新,可以关注最新版本。这个工具是一个用 Python 和 Qt 编写的完整的图形界面。最有意思的是,它的标注信息可以直接转换成XML文件,这和PASCAL VOC和ImageNet使用的XML是一样的。
    , ~- x4 {/ L8 a0 |" k' I# f; _& q) t  E7 f* J" |) t6 H/ K* m( M

    # W1 W, k. R; P/ e8 Y$ O/ g附注。作者在5月份更新了代码,现在最新版本号是1.3.0,博主亲测,源码在Windows 10和Ubuntu 16.04上正常运行。7 K% k; W5 M, o! x

    5 R% F; l9 T# ^

    " w7 o- t6 b8 R$ a4 i具体的安装查看Github教程:https://github.com/wkentaro/labelme/#installation
    8 Y. v4 {0 P) o" H7 \) J
    - O; T8 N8 E% c& K$ c# r( p

    0 F; e2 }+ B% }  o' b在原作者的github下载源码:https://github.com/tzutalin/labelImg
    7 Z, f1 e* g3 E5 F3 A9 _' s1 {" ?。解压名为labelImg-master的文件夹,进入当前目录的命令行窗口,输入如下语句依次打开软件。
    ) J& |' Y# P$ ]
      r* W+ ~6 a( r  U. }( j( Z( @
    - x8 v" g: c6 b8 E! a* K
    python labelImg.py
    ( B" c0 y0 n' E2 ?2 G! C1
    / R$ C& k" D( y( E0 M0 K, V3 u- C  R4 c% y5 o
    8 T! ^; v5 A: w

    " `2 K+ A7 v2 B9 D' [# Z5 P3 j
    6 Y5 h- K7 y2 t- J1 i9 F' |
    具体使用
    0 z6 D% c# ~( _: j; v% Y: a修改默认的XML文件保存位置,使用快捷键“Ctrl+R”,更改为自定义位置,这里的路径一定不能包含中文,否则不会保存。* n. I; p8 H( t7 C# }
    3 V+ x# c! B- Q8 d

    4 M  f. `1 p; [% g: O% N使用notepad++打开源文件夹中的data/predefined_classes.txt,修改默认分类,如person、car、motorcycle这三个分类。5 J( l/ I& R6 a( d
    & {2 \7 U# s8 O" G
      Q& s( t4 Z: U5 _- `# E: G
    “打开目录”打开图片文件夹,选择第一张图片开始标注,用“创建矩形框”或“Ctrl+N”启动框,点击结束框,双击选择类别。完成一张图片点击“保存”保存后,XML文件已经保存到本地了。单击“下一张图片”转到下一张图片。$ R) `/ B: c" d& N( {

    + s4 ?6 T8 g3 o( h

    + X$ h/ k6 q. N0 d& t贴标过程可以随时返回修改,保存的文件会覆盖上一个。4 a, Y. h% }9 Y+ `$ D
    0 ~5 n- ~4 [6 x# N7 D4 M

    : B3 }. u: P% M% T# o" S% T8 `+ K完成注解后,打开XML文件,发现和PASCAL VOC格式一样。) Q) b3 a+ [, P/ A
    3 C7 B3 I; n6 b" e
    $ B- ?/ Q6 ]& V3 J/ Q$ H) {4 m
    将xml文件提取图像信息
    . `4 E: s% U3 V# z6 c* c& i下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。
    ! |( j8 w* D7 p2 w# E
    7 q/ r1 f# _: _7 H+ Y

    1 K! N- V. ?% j: K5 D% r
    ( o! ~7 s) g, e+ n0 Y$ V! {8 s5 g
    6 t" B" K) _) M# W7 l* [; K) H1 K
    下面是images图片中的一个。3 y& @0 o: t3 |) h8 H
    # V% G* m" e3 ]0 }8 W

    0 g+ A( b; B4 Z9 h. q. Q2 O0 `下面是对应的xml文件。0 A" d6 H7 Q# s: O& b% q
      k7 x' }" _8 L6 z2 U* G+ d  V

    " f9 q9 t9 D/ x- i5 [0 D4 A<annotation>" M( ]0 w6 M' ]( W+ i5 Z2 O' c
            <folder>train</folder>
    5 M* r( @9 K  m! V        <filename>apple_30.jpg</filename>: J6 N( D( J* l7 f: V9 i9 D1 X7 W
            <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>
    - d6 g$ L, r( k; f; B6 d4 k" A        <source>
    2 b0 F/ u( W5 k5 ]( k                <database>Unknown</database>
    + |4 m8 ?, V4 i: G) G  A, t* A        </source>8 q" n! c( ^) D" }& [
            <size>2 |( Q  p) M/ a* _
                    <width>800</width>5 X, Q' [) W5 a. G4 A. r9 h1 d7 M
                    <height>800</height>
    6 x. F8 S1 b/ `9 a                <depth>3</depth>
    - e: [5 j5 H4 R        </size>+ U: ?' T3 N0 n" ?, n' X
            <segmented>0</segmented>
    ) L" r( a; G2 I6 R. a. o  Z3 t        <object>/ Z0 I/ a4 N% q* M7 ^
                    <name>apple</name>
    , M, P- c$ `% r6 P0 U                <pose>Unspecified</pose>/ t1 |. B7 `. _: y& F
                    <truncated>0</truncated>2 k5 t8 `) O% a9 w$ F5 S
                    <difficult>0</difficult>2 S. S0 N" k* G" e; u, y
                    <bndbox>
    : y& H' F! [7 F3 s6 i2 S; ?                        <xmin>254</xmin>- l3 @( k) t7 S6 L& u( W9 [
                            <ymin>163</ymin>
    % j2 v3 ?% S- g! ~* b                        <xmax>582</xmax>' a) \+ ^1 {0 N2 T# D* y  \5 k
                            <ymax>487</ymax>9 Y' _3 S; E( c6 s
                    </bndbox>- w4 ^# h5 P. U: Y2 m
            </object>% v* Q+ D+ b3 G
            <object>
    ! h9 K1 W+ D% W& ^" S. d- d                <name>apple</name>3 Z6 C( k  q3 S2 l6 ~* q" u
                    <pose>Unspecified</pose>$ P2 ^) E# ]5 M- A* H4 s
                    <truncated>0</truncated>
    ! I$ E; l$ F" i+ t1 _                <difficult>0</difficult>6 ^7 J8 U( V, r$ m0 J: _% K+ f
                    <bndbox>
    + `& K. i4 x4 I. l& {                        <xmin>217</xmin>
    ; h+ O' e4 \) O$ O: x. j: a4 Z                        <ymin>448</ymin>
    4 W  T# C4 M$ ?; q                        <xmax>535</xmax>
    0 n, X& s) w5 B& I; d" }0 E. M* ^                        <ymax>713</ymax>
    0 I9 G8 ]( t$ Q7 L( K2 G! Y                </bndbox>1 G& a+ C! E! v' T
            </object>
    ) K( k8 w! X, w6 t        <object>- h0 U  Y' z6 F0 j: B1 y1 }
                    <name>apple</name>
    & c  j8 k" B/ ]$ N, z                <pose>Unspecified</pose>
    8 z* f& h5 i3 E! s6 _8 V                <truncated>1</truncated>( g8 y1 D$ ~8 n0 q- Q6 [6 [1 W2 Z
                    <difficult>0</difficult>
    ) G+ M7 Q8 N2 m$ I                <bndbox>
    ! a3 n# k: K2 [  q! f! p- Q8 @9 i+ y                        <xmin>603</xmin>
    2 U! a5 a! Q5 ?& R" r1 U- N                        <ymin>470</ymin>
    ; M7 u3 i5 h+ D# L- `, F                        <xmax>800</xmax>
    6 p) R# m$ m+ a; j0 j                        <ymax>716</ymax>. `& r! t* ~  A# L; F
                    </bndbox>1 y7 N. x; V% k* b" c$ v' }
            </object>
    2 B$ R5 L! v: @4 w6 `9 k        <object>
    , j: F, I6 B% ^: l6 N! ^1 N, P                <name>apple</name>
    : \  H3 n6 u' Y' X  R- n" P                <pose>Unspecified</pose>9 N7 g& q1 H) k- I' ~$ A* f7 z
                    <truncated>0</truncated>
    0 m' C* f3 Z9 r( o6 P                <difficult>0</difficult>& Z$ ^  g/ q9 P( e* b
                    <bndbox>
    3 ^4 k1 s% O6 V( {                        <xmin>468</xmin>3 C4 I6 ?" Y4 V
                            <ymin>179</ymin>0 g' ]9 d. r  g6 W
                            <xmax>727</xmax>
    * ]3 j( ?3 Z2 p% x  I                        <ymax>467</ymax>
    + B! m$ Q- Y" @' [* b4 E                </bndbox>
    2 h5 e; k: d6 G& r- F. f  p2 B        </object>
    0 ?4 F/ F# e6 b+ B2 S8 {; f; W        <object>7 [- N% u% x; A# P* J8 n. T& k4 k2 m
                    <name>apple</name>
    3 c$ D; Y" J1 n. r                <pose>Unspecified</pose>
    * M9 Q3 y" D& Z                <truncated>1</truncated>
    ; I9 h% y  I- z- ^- f2 U                <difficult>0</difficult>
    $ E( U. n( k- N                <bndbox>
    6 k7 a5 \8 |% ^                        <xmin>1</xmin>
    $ n8 ]1 I, I, D; X' o                        <ymin>63</ymin>1 s8 k% t# h+ W3 k: k
                            <xmax>308</xmax>
    0 M2 ]( r1 E7 D2 [. G                        <ymax>414</ymax>5 ^# g* v6 k" |2 |) n; l% P! N
                    </bndbox>
    + a  u& f, T: R* E7 P' O5 s        </object>+ s6 m1 F& z' O) e
    </annotation>0 x5 \( Q8 x# H+ u# @
    13 n. s  k: o# X" v; G
    2
      D  @$ s" w: }$ n$ H* `, e- ^. h3
    + i5 B5 s+ g  Z6 Q) X$ M" O4% h7 Z' \* ~  H* X; k
    5
      l6 J' ?( Q8 J  M6
    $ m% l0 e2 }! F% m7
    - F  i( }: u- @( I8
    2 }$ ]3 e% a2 [( w9- s3 a2 o) q5 t! Y
    10
    , @7 C: |- Y. T" Y: b2 b* s( b/ A11# p4 Z0 D( x9 j7 ~6 l9 |2 N
    121 y; M0 u# k' l
    13
    ; R3 ~- h) B' H14
    3 y: j; a" S7 U; L15
    % F/ J& f& |" z, f  ^. d; \) k16( m, Q" i# x7 _1 a$ u! V
    17
    ( ^! V3 J- f4 K3 S% ~189 Y& y5 z, T" o' L# k; S
    19
    : R% J- k. L2 ~3 h# p20. E7 p2 Y+ \( t) [* t$ `' l
    21+ B" t$ O3 S7 ^9 Y' b0 {
    225 V7 U- `% g8 n( I
    23+ c3 ^5 Q. z0 h. C3 i$ A* D+ T
    242 @* m: D3 V* q1 v- d! t0 K
    25
    ; C2 W# }! P4 l26
    + `) l( l4 _7 x, J( p$ W27" j7 [1 P7 i: {0 a2 p* k
    28
    9 l  }5 |( i8 T- v4 _# B29# T6 G( q. z* Y, E: f6 j
    30
      G/ {+ g' _0 ]6 M- V" q31
    4 ^5 A, W9 s) j: B6 ^% ]) @( n32: T! m% b) |% e6 v2 k: @7 e
    33
    . V! ~- l+ Z* {, }5 _34
    ( [1 k5 C( ^. ?9 m4 h5 |( P4 `35: U: X( K6 c% h( T$ O
    36% y' v  r, F$ N4 o) k
    37
    3 j: k; O" i/ Z, W38/ h9 V* m- C! b" ^# y
    39. A. p, F. x, S0 W  d2 G; X6 H; W
    40+ ^1 m% [: \. K1 F$ i+ _
    41+ k  L! L9 G+ H' u! N# G
    42
    ' D- }5 e. G, B. r43# ?- ]7 y$ C/ y
    449 p$ v) S# w6 Q  W7 G9 O4 F, F( T- j
    45
    % r5 j/ c( U6 D# E, v0 l46! t8 U) ]3 W; y/ c" _+ Z; Q1 J* s
    470 J, a9 Y7 U2 s" W2 q/ P
    486 f) g+ q: H3 g0 x- F1 Y
    49
    & d  S) G& }5 \50
    : d8 I! l' w$ r3 ]51$ o) C3 P7 r) l+ s4 b' ~
    52
    5 j. x9 @% T6 h  y( m: q53
    6 C7 _' W8 v& f* [9 g54% A. f" p) z- B, X6 m: h) F
    55
    8 s2 R, H+ q8 R6 `# p+ Z) e/ D- P56
    * |# d. q% C# P574 B/ m7 g; S5 n  r! _
    583 W7 j2 z  J# T% J5 C
    59
    7 @% w2 [" s" a  k; z6 L' C60
    7 k1 t4 c4 c7 {61
    4 R+ `3 X/ r2 X, ?; O62
    ! z+ @3 l: X' I: Z9 H" m63
    # N; m4 v! Z3 K1 W+ z64; p! [, F4 Z$ A/ v
    65
    : q( ~; o7 t5 j8 M' J" X2 s$ k668 R" q! B; x- D' e. E
    67. z7 W  @' O4 a- n
    680 c$ u4 J+ v2 ?; Y% b" \2 X. U  n1 o! y
    69
    ; z: V% L$ ~3 j9 T70# _( j4 o3 w5 K$ n
    71. A3 w4 e$ d. p- @/ o5 P
    72+ E0 i. F& u2 l3 B
    734 z. U! v6 x9 z( |' w
    74
    , I4 e; f) ]# w; u% u- o7 n) m' Z将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。
    * L- g  d6 ^3 q# i# g9 _
    ! y  N# r( k6 E3 o, X
    ! X* }6 @' k9 M0 y% m' G  `
    import os$ _/ O8 N& I8 A- f/ @/ K
    import numpy as np2 }/ E+ g/ Y* T/ j! Q; z" Q
    import cv29 U( V9 R6 Q$ ^' E" I* d$ h
    import torch! N7 c) N1 s. }- y
    import matplotlib.patches as patches
    / [, I0 I7 ^: I% Z% N+ ^import albumentations as A3 ]: y) O& D, f; D0 a3 q9 I! {
    from albumentations.pytorch.transforms import ToTensorV2( D5 u# p# Y: C2 e1 v* z- B- O
    from matplotlib import pyplot as plt
    5 a) o+ W7 g2 xfrom torch.utils.data import Dataset/ b/ N" t) K7 ?
    from xml.etree import ElementTree as et
    ; {0 ]- ]1 S. Z* q8 [from torchvision import transforms as torchtrans
    . X2 Z+ r% R; {* f& `/ {5 O4 S
    # ?% Z8 k1 \- ~* y
    1 [/ F- \4 Q1 ^
    # defining the files directory and testing directory$ ?& w$ H5 z+ o( F) S
    train_image_dir = 'train/train/image'6 S* c$ {0 Z9 m+ `( G) ?
    train_xml_dir = 'train/train/xml'
    ' H0 C7 n+ z: a+ O4 x, o4 d8 r# test_image_dir = 'test/test/image'& |; z& t) F5 Q, P3 u9 H
    # test_xml_dir = 'test/test/xml'
    1 B& a5 V7 a/ U+ y# z2 \+ @
    & G" Q+ `4 E* h( E3 h# f6 }
    2 `$ v9 [. Q( a' A, R
    class FruitImagesDataset(Dataset):
    / X! q7 V' k9 L9 N
    & I$ g/ L! f$ W0 f

    2 b6 R* g& e7 c& Q5 d    def __init__(self, image_dir, xml_dir, width, height, transforms=None):
      Z8 P* `. p% k9 g, m1 @        self.transforms = transforms
    2 F& v" O% ~5 ~8 m        self.image_dir = image_dir
    / B. j5 L1 v8 N9 g        self.xml_dir = xml_dir
    ) {1 b* O6 S$ l        self.height = height; I. Y$ _3 K1 v
            self.width = width
    $ |, K7 `# J% k
    0 D1 N: H3 U2 ]- r3 \  _

    - b- Z7 J* Z7 U: W        # sorting the images for consistency" W3 F8 C4 i! Z4 N2 n: [) ^
            # To get images, the extension of the filename is checked to be jpg  t7 U) O7 U. ]4 X: g2 B
            self.imgs = [image for image in os.listdir(self.image_dir)
    ' r. S0 a7 y9 T( ^8 G1 ?6 j                     if image[-4:] == '.jpg']. [5 Y. ^2 r; q5 ~6 e
            self.xmls = [xml for xml in os.listdir(self.xml_dir)# n. g! a% O8 t6 Y. p; I, }
                         if xml[-4:] == '.xml']
    " w/ }8 E$ h  N  o  W* y1 K! H" ~) M7 u* [" @& H

    + v$ d: s5 t; z5 L* T+ Y        # classes: 0 index is reserved for background' W( l5 Y6 p& p/ U! L
            self.classes = ['apple', 'banana', 'orange']
    3 {* i  @& b" w/ R1 |
    5 E9 z: k9 _. @: V0 `
    ) u  [: A( K7 ^2 J9 |
        def __getitem__(self, idx):
    1 A) c2 \- p4 D+ _0 u+ J5 d; I) P% e+ s  _7 X6 V' v

    4 V2 i) H" V% O% e/ n        img_name = self.imgs[idx]6 `8 Y' X4 K' w% s0 S. N) m( W9 l
            image_path = os.path.join(self.image_dir, img_name)1 {& y% |0 U) ]1 Z7 C3 k
    # b1 b2 V5 s: s" [

    9 `& e3 d. z' I& c0 t7 L0 ]2 t7 R4 z0 G        # reading the images and converting them to correct size and color
    / u, K* H' R) c5 {# `8 y6 z$ L/ [' R        img = cv2.imread(image_path): W  E* o  u# G5 Q- r: i- V
            img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)' C, v4 y6 p5 P- j/ G' `
            img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)
    + E  Z% B" E5 P  _3 V        # diving by 255
    - e3 X  V# E4 T5 j( K% I        img_res /= 255.0
    7 h% S: B- t3 r- V1 Q
    6 m( y) }; e# q' W+ S0 o5 I9 G

    # Y9 N! s0 \8 H! l        # annotation file
    % q$ j# W  u/ A        annot_filename = img_name[:-4] + '.xml') L  d, _8 X- ~+ O, Z9 \
            annot_file_path = os.path.join(self.xml_dir, annot_filename)
    % D  F$ T7 p! g+ n8 P- W6 w& k5 ^0 f, c! p6 E  L0 K
    ' G" O) A9 @* p1 C& g
            boxes = []7 [! Y( j: a( U0 u" z7 x6 M
            labels = []2 }& y. _' [" P7 s; x1 u' s$ Q
            tree = et.parse(annot_file_path)
    ) f3 c3 v2 a  G4 u, h        root = tree.getroot()' Z) c) I' z: e0 b7 O
    - V+ l& K7 k$ Q6 X" s0 [3 F

    - i' z9 C0 U8 {" {* ]        # cv2 image gives size as height x width
    * O5 b* U4 {/ {8 o        wt = img.shape[1]! x5 @% r: Q& t0 C% X5 D3 W2 g9 a
            ht = img.shape[0]' |% M5 [: i5 o: M5 K: O* I

    8 x) ^% A( ]/ d4 a

    4 I# k( |4 z. D4 Q        # box coordinates for xml files are extracted and corrected for image size given) l  k7 y* x( y9 s$ y
            for member in root.findall('object'):4 i9 t9 I8 t% L, @
                labels.append(self.classes.index(member.find('name').text))! [0 {, o, z/ J3 B7 S# b
    ; `) f" O/ G; y8 T/ K0 a

    " U4 m! e2 I" K. d, \2 V" q* n8 u            # bounding box% ^, y  z9 a, R! M' i
                xmin = int(member.find('bndbox').find('xmin').text)
    # w" ?6 }9 ~( v  _            xmax = int(member.find('bndbox').find('xmax').text)) [, E" w6 i3 M( a( O3 o  F+ p) T

    . m2 E( }1 E7 H

      ]: S5 Q: B: K$ R            ymin = int(member.find('bndbox').find('ymin').text)
    1 T; u; z3 Q4 U9 N- K; C            ymax = int(member.find('bndbox').find('ymax').text)+ N+ e: {" D& L' M8 v
    ! y* v5 P  h0 l
    + ^) `0 B2 O* J8 _: `% `
                xmin_corr = (xmin / wt) * self.width
    + T. d6 [1 R6 h) |- K            xmax_corr = (xmax / wt) * self.width
    - v0 [4 ]2 u: m% j- Z# N1 u            ymin_corr = (ymin / ht) * self.height1 D" i5 N( Q# D( B7 N) p: m
                ymax_corr = (ymax / ht) * self.height
    + Y4 [  D; |+ b            boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])3 |3 i( A8 z0 }: K7 E/ X2 ?

    4 X/ f! w1 z3 @& ~

    . b: z: z7 k9 z' W        # convert boxes into a torch.Tensor6 S6 U, C* y, v
            boxes = torch.as_tensor(boxes, dtype=torch.float32)2 i8 b2 @& E- f8 C# `7 P5 p+ [

    " t# W! m/ c, K+ D' U) d& F& c, \
    + j3 s3 Y. X' W0 e6 v$ r
            # getting the areas of the boxes
    6 F  \/ t! k# L4 y: l) ?4 t        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
    - ?/ u& A+ ?+ F) h3 z$ n& t8 I* e# f- |7 c( ]- _% g

    ( D3 {# R( z7 A9 y        # suppose all instances are not crowd
    1 m- }, y( k9 s7 v        iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64)
    % Y7 v( b" }5 o; v. j/ }
    & A6 ^* L" \/ T7 x1 g; B6 L

    4 g- O& ?" y5 V; C% _        labels = torch.as_tensor(labels, dtype=torch.int64)
    & J4 O3 Y- Y% g9 O7 @. t/ c( c, l: U$ X, \- _  a
    8 N8 g; M3 A4 E, f5 F- d
            target = {}0 Z, O3 m3 F9 Q& ?0 P
            target["boxes"] = boxes
    . m* x. R+ w2 f# F        target["labels"] = labels
    4 n' a$ s# `: i7 @* [        target["area"] = area6 I* e+ N; k  C( K* s2 J
            target["iscrowd"] = iscrowd
    . c* ?- d9 g! Q+ c        # image_id
    # {7 ^5 e' R6 h/ }1 ~        image_id = torch.tensor([idx])0 c8 `0 y, n) M) f/ z
            target["image_id"] = image_id; y/ B9 ]: l4 _/ ]) F7 F  K) ]+ Q

    ; w0 ]$ ]; s  T$ s7 D& v
    7 Y7 L3 Z+ F2 Y- F( J
            if self.transforms:& O6 a% L% L' G+ P/ R
                sample = self.transforms(image=img_res,5 i: o; w( C/ I8 O2 ]2 S
                                         bboxes=target['boxes'],
    ! r& G, d6 G) m  ], ]3 ^; Z# _                                     labels=labels)
    ( l: ]) ?) }% o, X/ Q1 Y) ~! [' E' g( e  U: B! g& K  @
    9 b) D) w+ o1 K) `6 ~) K5 i
                img_res = sample['image']
    1 v: ^+ L& W/ p# n4 M- N" X            target['boxes'] = torch.Tensor(sample['bboxes'])% P6 Z" G. c' j8 t2 \

    5 g: A" W9 ^6 Y* t6 N

    3 [7 A, \& w! j9 T& r5 ]        return img_res, target
    - [$ o& {6 i$ Z# k! [: j8 D: O
    : O3 s6 ]9 [9 w9 H2 `

    + [7 ]) H6 p! m# [8 l    def __len__(self):
    6 }$ r: N6 L6 v; S+ O/ C0 d' c( T        return len(self.imgs)
    3 t' w. Q1 |! \" t7 r0 d
    6 D8 L! A9 n* _2 \$ k8 s% }
    # V7 \3 Q* r& T: t+ B1 ]9 c% K; [
    # function to convert a torchtensor back to PIL image0 N" ?' @8 v: T& i* C
    def torch_to_pil(img):
    5 e2 a2 O; q6 J8 O; F+ d    return torchtrans.ToPILImage()(img).convert('RGB')1 H% \& m% i' n2 q8 u
    6 `8 p) s7 [" F/ S* ~% M
    ' k* d0 V6 G0 H, j: ^' D( y# L: J

    ! B& b( t- j2 w# Z6 L+ ?
    6 H4 t/ ]$ e# p
    def plot_img_bbox(img, target):" @' C$ B: [( {7 [9 _
        # plot the image and bboxes
    1 w$ L) }; s& ~    fig, a = plt.subplots(1, 1)
    8 n$ c+ U' g" e, t    fig.set_size_inches(5, 5)7 M" V; D, s& p6 S
        a.imshow(img)) R7 Q9 n, j, a, |4 L7 h4 j1 O* B
        for box in (target['boxes']):
    / a' h- y+ [# N        x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]
    # B; J1 q2 G* m' s3 V7 ^* ?8 Z: C        rect = patches.Rectangle((x, y),9 b8 m6 l  K, I9 H! U
                                     width, height,1 C! h8 d- X8 C
                                     linewidth=2,. d( f9 _4 Q; u: Z- d' g4 g
                                     edgecolor='r',
    $ R; t1 Z; ?0 A4 ?- m                                 facecolor='none'); \+ u) s3 C6 a

    # {/ D  d- O3 n, Z
    : [! e: ~- N) o; j5 g8 W- c' v4 k+ h3 R
            # Draw the bounding box on top of the image; n9 _2 Q- q1 G2 w1 P: Q
            a.add_patch(rect)
    0 V, f: m  t4 r" Z. {. v    plt.show()
    ' A# G* P( n# m/ w) R6 G, l9 ?5 Y, G8 j# X' M7 P: P
    ' \$ m: G; l- r5 g% O7 m) p* r  n) [
    4 Q6 ?, v9 ]5 T
    ; S& K. S! ^, q2 c$ s" g2 Q
    def get_transform(train):
    " E6 x8 r7 T- @/ R; k! [3 z8 m    if train:7 Z# t9 c' G# M0 e
            return A.Compose([* A& [, A5 A& O7 d/ g
                A.HorizontalFlip(0.5),2 p! z& Z. @6 l
                # ToTensorV2 converts image to pytorch tensor without div by 255
    ( [. t, c& P  G3 A) r- T  }0 F            ToTensorV2(p=1.0)  o- h; d- u0 r  M) H; }, m) V( i
            ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
    5 S7 {' ~3 l7 `; U    else:' m  s* ~- `6 s1 z- V
            return A.Compose([2 p1 \( M5 @( I( o
                ToTensorV2(p=1.0): A/ R& _1 `# \9 }
            ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
    " F3 ~/ L' j1 S1 o$ J! a8 h4 Z% J- z0 l/ w" I) ?0 O7 n
    6 [- l! u) I/ ^0 [! ]
    ( ^& Y; h+ ?" ]& a( V
    2 l! |  T# i2 T6 F: @. Z- x
    - d/ T0 P& J* u& q" e- E$ j
    2 h& v' E- p1 L& G& |
    dataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))
      @. w# L& w' M. j6 f: a0 y" C; V. s) ?8 m) x0 l

    " e! {* @3 e, ]: E5 Z1 _print(len(dataset))
    # h' U( r& K3 X6 q: w# v% s' U) m# getting the image and target for a test index.  Feel free to change the index.8 |) b- k; Q5 m; e+ J1 [
    img, target = dataset[29]
    3 T/ D/ O5 j9 |4 T7 f% N' Oprint(img.shape, '\n', target)
    , t% d, s: X0 Z* [6 jplot_img_bbox(torch_to_pil(img), target)
    , n4 c- Y% P' U0 m1 P1
    % t# `* I4 J- e; x# \2
    4 J4 N# `- b: _  I( y3
    ( z+ t: Z- B6 ?# r  x$ m4
    2 v  a4 Z2 H+ X( C( E' `: R5
    " N5 w0 v  l& T6# L! b0 ~- ]9 e: P5 D$ z5 E
    77 o$ L9 O, J! @' `- r+ K
    8% `1 Q# |( V! M
    9
    2 Q7 ?4 |4 H1 d3 m7 p- j10- s8 p) V7 ]1 f7 n0 K+ q0 v7 Q7 }
    11* B) |8 {/ n. d8 }) V4 ^  I4 k
    12
    . ^- t8 G- [7 {0 d/ Q; J; u13: M/ @; ]0 P' j& B6 f
    14
    # |1 \! q  ]5 L15
    - l/ ?& V1 p  ^! S/ \- ~, T16$ n! \" V8 p1 \
    17, A! a$ o( |6 L1 G! I: m
    18
    : O( o- F5 L6 a0 P: \199 f6 n" W$ R% r) I( E
    20
    1 J* @/ e6 u% k; R3 O21
    * \3 n' N& W. ?. s) w$ A  R9 {22/ M7 U# [- l( `5 a- S$ Y  u
    23
    ' a3 V' x& g- }! U: X24) \' J1 c5 i4 c
    25
    7 d1 s$ ]4 Y% M) O4 x. N26
    : v7 b" B) `: i7 a0 l: J  w- m270 x1 R+ i* Q& C& y9 U
    28. N4 n; \* D0 F/ C: y8 w! y+ M
    29
    : g: I* T+ y2 T/ O. ^1 d30
    3 F  F7 a6 o6 g# {7 O! [31
    1 ?0 C/ Y  L8 j, G( _, V& s32
    * C: L5 L& w; j: E2 g  T33/ n- C" w( |: Z0 V6 l; a) q0 h2 l6 U& t
    34( ^! S  O; p8 y
    35+ O3 c  n2 E+ v) @3 l) @
    36
    : ?7 M' S; v' P6 d5 t8 f37
    & N/ V4 v5 z- @. F. e38
    ' e  o' h! G, e0 h39% q6 u5 [# F# d" N2 f* }+ I' T
    40
    3 y! S$ x5 a. }: |: E; S8 R410 E( }% s& b5 o
    42
    : g/ m, \  p! d" Q& K# e43
    6 ?  T# C8 d. U: k/ N  X: E1 X44
    : y7 M3 K7 _; ~3 i3 L45
    " A1 {) G) h/ T- E46
    * l7 i* \9 _; s/ O9 l& ~47
    ) e2 m  {! S0 n" f1 ^& g5 o! l48: k, O8 T) P+ `
    49
    , _) Z/ q. o8 v, h! c/ _50- E) W' ]* O$ W. m6 ~/ S
    51
    - D! y; c! P  w7 N' l" C52; U( `5 ^+ J" B/ L1 c0 b  I5 z' I
    53( p1 e, C( S) t% u. k3 ?
    54
    8 [& b$ M0 S) [: k" b55
    / E$ ^" g8 }' a; ]4 @$ H# y56) Z/ K* y2 l7 C
    57
    5 W5 m9 o/ I4 ~/ e/ k58
    7 G. g' S: W: E2 c8 B590 y* c8 ~# L2 e5 X( X! a/ E
    60
    9 k. L! _$ M; `; D0 N: J61
    - `0 U& S8 a! e( P" Q# d62
    0 I  A5 j: `$ d63
    / U7 u7 X0 G8 \  l64+ v( q7 k& e( M. ^
    65* y/ O- z1 d6 s3 \6 B7 v3 u
    66
    6 x7 i' t/ T. R' R67
    % Q3 ?$ j# S8 @/ `' |0 `. `68
    , I1 D8 b& ^' `/ n" k6 n699 w. v9 w4 v# L$ i. n; A
    70  A0 w7 t( o/ c# k, J
    71; ^$ e. j# L8 i- ~
    72
    : P& x/ t. \( r4 n/ J9 H73
    " E! r3 N) X8 b' ], z. ~74  O" U1 _, t0 S: ~0 z' ]- g
    75
    & K7 Z5 \9 g$ u76
    / Z2 x3 W/ ?2 X77
    $ a, [4 K" k- L78, Q8 N8 o( J4 a* B7 p* f
    795 a* Q, a/ J/ U' p& t  L
    80
    5 v# ]6 P' m3 {' Q5 e* m817 I6 O+ Y% j2 v/ A2 K7 K
    823 J% }' ]  l8 X; y% r1 X8 ?
    83% O- A9 [, G! @" I5 l
    84( \2 T* c/ q. Q$ r* ^8 g
    85/ I1 K8 Q9 S% P# O3 O
    86) X" a) a( Z! m% W6 _3 L
    87  v1 t4 d4 Z; q' I
    88
    4 z2 ~) p& a* ~. I( N6 V% F* s89
    0 D  l9 P% P: u3 B) V: J90- U& J# V: B, j  B6 C# D: V  f! A
    91
    % F3 J: i) G; ~, u7 y1 a92$ j% b0 v, }. V* X
    93
    ( V+ `* u) a. ]7 G/ j4 A# J94
    , @# X0 g& ~! [/ X! M% x959 u) {0 Q$ t1 h2 Y/ p( }. {
    96; W6 V& B0 @$ X. f+ j. H: J
    97: o/ i7 y  }2 k7 R  F4 {2 X! k
    981 @6 g1 v1 a! e" D( W! e
    99
    ( Q) f1 Y3 ~+ d) }100
    2 F9 L5 n5 d/ D0 G1017 p7 h  s$ x/ K' h8 O& G. `' D- }- H
    102
    3 B5 G4 j' t5 P. s1034 Q2 Y* }/ A' P
    104$ U6 d" o" W/ J
    1057 f. c$ O0 a1 e, O9 P- j
    106
    . @0 D( r8 B3 e% O) e  P107
    , F  v1 u' @9 |9 i5 ?/ O1084 G2 C& c3 k0 [+ A; M* k" v. i
    109
    # p7 F! w# j5 H# _110
    ! e& O' u5 s. d4 X+ `111
      j/ g; X. @! ^8 e5 v% B: a$ d112# C3 S+ I! ?8 r* ^6 A' L7 G$ Z; `
    113
    & C5 M, I$ K  d3 [, i114$ C, g; l& A9 z, R1 C- B$ w
    1159 k" N! J% m- G/ z: }! q
    116
    $ e6 P& T0 @, f5 q117; F# ]- a( v, T  O2 W7 v5 M' f
    118
    2 o2 q7 ]1 H9 }/ a& Z8 A" f8 {119( O" b% _% f/ b8 p
    1205 _# X: n0 c7 G
    1215 o& `# U3 W+ ]0 `/ N. U
    122
    & v1 ~9 z5 V, P4 Y123- j; a; r9 ?# E& @, y
    124: u2 S! j8 {( g5 q" S1 H
    125! t5 P! H, F% G
    126
    * i! G3 h) X7 k+ C- z7 ^127& v% j* ^2 g- {. _
    1283 G; ^8 ~: p" \) D% Y9 y
    129% e0 m- q0 w6 Y
    1303 [% h. i  v& i6 M- q8 s5 l0 F
    131
    2 s0 c* @4 Q4 j  y% Z$ @( F132: o* x3 B6 g; X8 l( G
    1338 @4 z, @' v& N- k9 G
    1340 O4 y( R2 X6 ?( D- k+ V. h) I! I
    135
    3 ^0 f6 c0 Q5 I. w* L) o6 F1367 ?: P$ \# i+ [9 I4 q6 l. @" @
    1376 c7 {- U/ h2 z9 \: w+ }/ Y
    138- d; b" Y+ [' I5 f1 B# Y; A  Q3 |
    1391 T/ Z9 Y1 x6 q- y% j& P& A8 C
    140
    0 q1 V# y' X4 ?+ j6 J% E: E141) V  M' @4 W6 s
    1429 C- n! _8 @  X/ b
    1432 J6 m1 }4 u$ J& o4 w5 r
    144
    % |+ H1 L; @# p( c145
    3 D& ^2 h) @0 u1 G146
    ! w6 \+ @* ?* O2 C7 v147/ L" T* c" I$ N& C$ m
    1488 p- q1 @0 q3 L) w
    149
    6 D$ j9 t8 L1 S150
    & J8 ~' y) z! x0 B% e151
    0 J) ]2 r$ f! |152
    + {/ ~) i- Z: f1535 W& ~8 z! I4 V3 s% c0 U0 r! J
    1546 K4 ^3 Q( i0 Q4 o
    155
    & I! L6 K* S* s156
    9 ?/ N7 u* d5 |) O1 X6 M' `  C输出如下:
    8 U1 {" M' X! h, G; x' I
    % B* Y# i* V/ x9 k0 N

    , s8 C" ?- k4 o  O* \torch.Size([3, 480, 480]) / M( D3 y# i6 h& ~7 a" y# a
    {'boxes': tensor([[130.8000,  97.8000, 327.6000, 292.2000],( y, L0 Q* D) z1 p5 j+ o" h
            [159.0000, 268.8000, 349.8000, 427.8000],3 _5 x. K! R6 l  d
            [  0.0000, 282.0000, 118.2000, 429.6000],
      _% U* t& G& Y        [ 43.8000, 107.4000, 199.2000, 280.2000],3 d* t* m0 E' W; [+ G. Z
            [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])}# J4 E3 X" C3 y- u0 b- G
    1
    , \7 S& q6 [) N; o6 G0 P" |7 ]2( D: s. {7 C/ w; T
    3& x& q* e+ M1 G' E
    4' y7 G( d0 }+ y0 ~" G( j- S7 L$ b
    5
    " |( w5 m2 V0 ]/ X: O" [6 v5 v; r6. T1 L( z- o2 T0 g

    * e5 J& v4 n3 R. D/ [/ P

    , t3 c7 j/ S7 f/ R  r( p  `7 \* ~2 o; J
    , P* v) Q9 h1 v  I; X8 k. [5 p+ m
    ! C9 l6 x4 b3 P3 K1 ^
    下载地址! R3 D" z9 T) d4 T% r0 l0 W5 J; e/ G" r
    链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw& T( t5 \$ N' E
    提取码:srjn3 _+ d6 {& a- N% Z6 q. o. r3 U( q
    ————————————————7 O: o- h! |1 [: c6 X% g
    版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。2 Q0 R, Y) L3 {
    原文链接:https://blog.csdn.net/weixin_44510615/article/details/118496273
    . ?8 y' {2 p% F4 f! y# q8 z- [5 R9 p# `4 K
    / B5 s# E1 b6 l: p
    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, 2025-9-22 23:03 , Processed in 0.648717 second(s), 51 queries .

    回顶部