QQ登录

只需要一步,快速开始

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

    ) G+ d/ Q8 d! _  A1 ~- S深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息5 k5 c5 C' P2 O# N
    图像标注主要用于创建数据集进行图片的标注。本篇博客将推荐一款非常实用的图片标注工具LabelImg,重点介绍其安装使用过程。如果想简单点,请直接下载打包版(下载地址见结尾),无需编译,直接打开即可!6 N. f% _9 f# i6 L

    + P  p/ V) l8 w  Q" C4 E

    ) h. H' t6 `7 i) `+ h2 j: d感谢原作者对Github的贡献,博主发现软件已经更新,可以关注最新版本。这个工具是一个用 Python 和 Qt 编写的完整的图形界面。最有意思的是,它的标注信息可以直接转换成XML文件,这和PASCAL VOC和ImageNet使用的XML是一样的。! P2 z% R& z6 c% X3 I- f1 k

    & x' H  M( h- H( U9 g# I
    4 g, Y! m1 Y4 y  D+ ^6 [; k+ [
    附注。作者在5月份更新了代码,现在最新版本号是1.3.0,博主亲测,源码在Windows 10和Ubuntu 16.04上正常运行。; ]  f) L% _/ o) L

    # K0 w2 {7 H5 n4 v* ^/ ?9 V
    7 b( o( ]0 E9 \# n: T& D0 w0 h% h2 j
    具体的安装查看Github教程:https://github.com/wkentaro/labelme/#installation3 y: o/ E! h- k* A/ }4 Q6 e

    8 F7 y4 `. ]# s' g* N3 Q. h2 ^3 h, {
    7 ~! Y) i+ i8 `
    在原作者的github下载源码:https://github.com/tzutalin/labelImg
    ( `7 i, x5 e$ F* k。解压名为labelImg-master的文件夹,进入当前目录的命令行窗口,输入如下语句依次打开软件。
    8 d" L: R( j' Z7 j4 S
    7 S4 {$ H' N' _' z+ Y

    : u$ q3 P; i) A7 O2 r7 F; s. f; Lpython labelImg.py* f4 F. J7 D  U
    1# L7 p- _% M4 F6 P2 ^+ n% M3 G
    3 Z8 A: [  G1 Y# v/ y

    & R5 W; C0 A8 _) H- U3 b" q1 Q- T' z, l/ ?% s' p% r

    % m0 P. a: [! u具体使用( n; e8 w' `: L/ Y: U! ~. J; r7 N
    修改默认的XML文件保存位置,使用快捷键“Ctrl+R”,更改为自定义位置,这里的路径一定不能包含中文,否则不会保存。2 s! I3 t/ w1 L% M

    8 b0 C0 [8 t$ B$ ]; D/ K# w
    8 C# |5 d. @! ^# g* \5 `
    使用notepad++打开源文件夹中的data/predefined_classes.txt,修改默认分类,如person、car、motorcycle这三个分类。
    3 }. C6 U0 x# R  @) m( h/ n6 X" f6 e: b- j: M3 Z7 z

      H2 k9 R7 c2 j/ U2 ?$ b# x( E“打开目录”打开图片文件夹,选择第一张图片开始标注,用“创建矩形框”或“Ctrl+N”启动框,点击结束框,双击选择类别。完成一张图片点击“保存”保存后,XML文件已经保存到本地了。单击“下一张图片”转到下一张图片。; l* J' M* Q' ^. X
    1 i, S% C+ t) u8 {6 ]

    7 N+ S, P0 x' K贴标过程可以随时返回修改,保存的文件会覆盖上一个。
    * U* }3 Q; k& d! h  x
    ! E. r) w5 @% u+ u' @% `* |9 D
    8 |( s% R4 Z. `4 L
    完成注解后,打开XML文件,发现和PASCAL VOC格式一样。
    2 @( E+ _$ G* L5 [% S1 l
    0 @$ Q" ?) a2 l6 d' x

    ; z; C: [! n5 t  u4 v" i. m将xml文件提取图像信息$ X( f7 G5 l) G
    下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。  T9 O! B# z& }  {. A5 W) @3 R
    $ M, j- T5 H' d! \$ J5 {
    ) H7 ~2 `! ?. f5 J! O
    , w4 ?. }1 S* m2 y3 f! v$ r
    4 T' F" A9 k+ o+ m3 }
    下面是images图片中的一个。: e) h. _$ J5 A0 Z* s. N

    3 j% s4 q9 T6 c
    : _& g0 b7 g* S7 u) A/ w2 [( e. E
    下面是对应的xml文件。' _$ Z& n& ~! E

    ' G* |9 f% S3 E# |& B+ `* |

    7 L2 b, S% x5 I) X<annotation>
    / f; L6 ]$ q" T4 c9 p9 m1 j        <folder>train</folder>
    & ~* ?4 A! `% m        <filename>apple_30.jpg</filename>
    , i* E2 n% j* C        <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>3 J7 s+ B+ s: @* x
            <source>3 t4 B  Q$ Z5 U6 A! h6 Z8 v
                    <database>Unknown</database>  L( |5 G5 J) U$ K% o! w2 d
            </source>$ m& @9 X1 D& S* i; ~
            <size>
    + X' m4 b  f0 ~+ b0 j! I8 z0 ?                <width>800</width>
    ; ]' V/ F1 s2 P1 q* v                <height>800</height>2 D( ]2 M. F! d( L
                    <depth>3</depth>
    9 H7 @  t7 Y+ Q* S        </size>
    ! c9 x- x6 ]4 V        <segmented>0</segmented>( A2 C$ q& V3 i& ]; ]* z7 c2 L
            <object>- [' E1 i0 I/ F
                    <name>apple</name>
    5 P$ M: J. p( |/ y                <pose>Unspecified</pose>
    ' `6 d  `2 `1 Q- r* s7 H9 S" b                <truncated>0</truncated>
    ( }: C$ f" \# z4 k* D2 [, x* k                <difficult>0</difficult>9 q  ^, [9 `& y3 A0 }& b
                    <bndbox>
    & L, m7 z3 |' Q0 M, B/ u                        <xmin>254</xmin>. R; i- m0 {6 C8 l) D  B  b
                            <ymin>163</ymin>
    9 K  V* K& h1 _8 ]                        <xmax>582</xmax>/ ]. d; y0 |) z8 H
                            <ymax>487</ymax>
    ' F8 m1 A4 ^: h% F- {! X) [                </bndbox>0 P, w1 j7 g) Y0 n
            </object>
    2 m' N, m! z- p7 n3 i. Z        <object>2 _2 ^* ^5 L' |0 `* y( C
                    <name>apple</name>
    ; i: V. B: y  r9 y3 G2 K* s5 P8 N                <pose>Unspecified</pose>+ T+ P$ \8 Z$ N( [5 \, O, m6 ~
                    <truncated>0</truncated>
    + H0 G$ `9 V% f1 J) U- b1 R5 B+ Z  m                <difficult>0</difficult>
    , E2 ^4 u7 s5 k& |6 o                <bndbox>' }* s% }$ E' }# m9 ^0 o
                            <xmin>217</xmin>
    2 }% p. i  X( E7 Q                        <ymin>448</ymin>/ G$ _; d4 q0 `% q. m& n
                            <xmax>535</xmax>* {/ O& |' j3 W( ~- c- Z+ o
                            <ymax>713</ymax>
    # c5 `% t9 i! h: }2 C                </bndbox>
    1 S" {+ X. I6 M( o: J        </object>
    / h/ l4 X* f7 @# _9 d3 C, c! n, N( O        <object>: `9 V( r( z  h, o
                    <name>apple</name>  H2 z! o$ ]% ]4 m, v' u; t5 s
                    <pose>Unspecified</pose>
    3 }& s) ?0 Z7 T7 n                <truncated>1</truncated>3 y+ ~3 E% F- d% z2 e0 t- n
                    <difficult>0</difficult>% I/ K, j0 c8 J0 \
                    <bndbox>
    3 J# B9 V; A, H                        <xmin>603</xmin>
    ( T- q; s6 a- @0 q. Q; o" H                        <ymin>470</ymin>
    : B: G5 Q5 J8 Q' P4 l5 J                        <xmax>800</xmax>/ s5 z6 {! @$ O6 J$ A1 b5 w
                            <ymax>716</ymax>
    # q7 n' ?- i  f' U/ ~                </bndbox>
    1 }' I+ G! G( H) K' ?        </object>
    . z7 C3 Q2 ~# U2 H        <object>
    $ a, @/ O  q8 ^. Z* w                <name>apple</name>
    ; N6 ?1 \" F# j; ?, f                <pose>Unspecified</pose>& @" k: Q( y: \. \  [
                    <truncated>0</truncated>
    . m2 d2 L5 G: ]9 H1 o                <difficult>0</difficult>
    0 {4 M0 |% ^6 }1 b+ z7 k; G                <bndbox>  c' ~5 L' S  [# n
                            <xmin>468</xmin>( _; H3 m0 V/ g' M' K3 J9 s
                            <ymin>179</ymin>$ s7 ^. }3 {" `) z1 b! B
                            <xmax>727</xmax>
    5 M. U6 Z0 [: z5 U                        <ymax>467</ymax>
    + V8 w7 E& G' m, U7 s0 A% P, k                </bndbox>4 |  C: u1 T5 D; c
            </object>
    ) R/ g1 S' J) ~' g5 ]        <object>
    . [" e! z$ v! Z. `* }3 Z% B                <name>apple</name>$ U# u6 A( O" m- K1 L1 l8 d" e
                    <pose>Unspecified</pose>  x. e9 v1 s& w: @  \; D
                    <truncated>1</truncated># p5 t1 f9 E: i5 v) k3 @
                    <difficult>0</difficult>7 Y, ~8 s/ O4 o0 @, W' I( ?
                    <bndbox>
    * ]4 v! [* G9 G- ?7 E                        <xmin>1</xmin>
    9 Z( k' g' N$ I) u9 |                        <ymin>63</ymin>
    1 @  s7 a) ~% S. v                        <xmax>308</xmax>+ P- s8 ?8 ^& B, K6 b6 E5 p
                            <ymax>414</ymax>
    1 }0 C) T) ~" _5 L+ Y6 z( }                </bndbox>- b- a+ s# i, l" x% Q! U
            </object>
    # I7 W! ?' |; D5 p  |; Y5 g</annotation>. `1 Q+ z' t5 e% d3 z. s8 [8 e
    12 f6 {; U4 o: |) C3 _$ ~" D% A
    26 X  W* n9 B# Q5 ^* ]9 R; j
    3
    & l( ?: N2 h( |0 m3 Y" {4& U6 D3 Z. A# W% M2 s" ?1 h
    52 ~! o3 U. U- `6 K7 {
    6
    , r' J; Z+ u4 e' @7
    $ \3 ~% @9 v* f) u  C8- O/ Y% R  `  ~
    9# e3 U$ R( s- H& c% w0 E2 _
    10
    - R% N+ C1 n( t4 P, \/ z- b119 X- y  p- k3 I% J$ _5 G
    12
    * F' ^/ p# R0 n" S0 Y" P  ~  `13
    7 ?) G/ Q9 f% K1 h14/ t# k/ T& r# L
    154 F3 t2 y& _( V5 Y9 U
    16
    : X7 k. W% L6 G$ H177 t$ g! O, g! e3 @0 |0 ]( s
    18$ a  c% t4 @3 V1 B
    19
    , i* L; E* w* m2 Z. d205 ?7 t9 S! y: T7 c! M# f9 A' N
    21) ]1 p' L% u/ z' T
    22( e) Z9 x4 O2 G$ E0 M* ~6 S
    235 s* o' T7 X0 v% ^
    24
    ' p8 L+ {2 u' W( R1 Z. ^. r  ?% o. h25
    / @' H% t' h4 h- h( S26, f# O* L0 f$ d# w. K5 D# a
    27
    7 S& R) _3 F$ b& F3 x2 r28, s$ L4 m9 f( Z
    29
    6 n; A6 W* v( w: k, I3 E) m30
    : C: o1 U$ i0 v% s31# f! S( E# R. v5 I; H
    32/ c( a7 j* W* z
    33
    5 `, ]+ d# a. j- O34
    ; o0 p' r$ g5 }2 d35) k. |9 m4 f) h% k! [
    36+ o% e% ~4 H6 m( x% T6 n2 l
    37
    0 i! r1 N3 _4 v/ h* ]9 }38
    9 l* O. h+ ]+ \: y5 R39
      B! A4 l: v3 }9 r9 q- T40
    ) y$ d7 T1 S6 z2 i$ j# [( V41
    0 F* t- b' A( \1 R428 v0 D5 ?1 _9 U' m" I8 K' b3 R9 T
    43
    1 G0 a  Q2 D; |, j( n44
    5 `, q1 z6 k+ j- p3 ?, i45# f4 y+ S6 q8 J
    46
    2 Y0 _/ [4 B7 e, o47
    7 g6 w) M% O+ y6 _5 \48
    ) M5 L8 o! z- q9 O49
    ' Z( C9 q0 w* c+ ^7 W' D50
    8 g- S5 l* N' p* V, C3 x51
    4 F0 c+ i& r0 K. e52) T! B5 l: z3 H6 W
    530 A5 Y8 U( Z1 `- V& `  k
    54$ ]: T, ~+ Y& b
    55) P  R9 d1 Q) U# C5 K
    566 b) [, N+ T+ G/ ]' m# J
    577 |0 H7 F" Z: Y! Q1 I/ C: _
    58' I! A/ [5 K5 F, w, Z- N
    597 F) `$ p; [" K9 e: m) j1 s+ w
    60& U3 ?- {- Q0 z2 @$ g5 `4 J& U
    61
    1 l/ m6 @9 O+ u62
    + [$ ?. i/ A  c  X- y63( j" o" v% b! @1 Z  {4 u* M
    64% ?/ r# n4 ?9 P" t& r9 i
    65# b$ r7 w$ o! v, u) k
    668 z% [/ I1 U( i1 V
    67
    . g& n  U9 q% |68
    6 H9 W/ v( m. ?8 j69
    7 a# N3 ^6 }- r9 s1 _/ K' S70
    5 s! d3 L3 ~* r$ i7 u710 M0 W" g/ }8 C1 ]0 h
    724 }/ ?% f  A& v$ |; q9 ]
    73
    $ y6 q; N7 b9 F% r* }- `74" E1 I- [& l/ r( N  X( R
    将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。
    8 I9 j. `) c+ R
    9 D3 x: Z' ?- D# Z- S

    2 |0 v% A+ M8 m! h& @, g* \% x  Wimport os
    " e, Z/ O# j9 L; fimport numpy as np
    * D$ S: v1 [& |9 E, D# rimport cv28 `; a8 r3 Z; p- L! G) F! q
    import torch6 H9 f9 f' x% ?. a& ?- ^
    import matplotlib.patches as patches+ n* j* v8 ~; s
    import albumentations as A
    9 x- m) h+ ]4 c# j. ]( Gfrom albumentations.pytorch.transforms import ToTensorV2
    " k+ h* c" [4 z, U$ Wfrom matplotlib import pyplot as plt
    . ^9 ^! b! g7 i; E- rfrom torch.utils.data import Dataset
    4 Z% I+ D9 R/ qfrom xml.etree import ElementTree as et! j% D5 {9 R& ]  G( T& ?% K
    from torchvision import transforms as torchtrans+ R! M) K4 ~: a: ~2 c
    ; S8 ^: S2 k$ o6 \

    & ^) h# N3 a8 x& M3 T7 T# defining the files directory and testing directory9 s6 M) w% W# v$ X- [* }$ w- {
    train_image_dir = 'train/train/image'$ ]( F# m% x2 ?7 x
    train_xml_dir = 'train/train/xml'- g9 z% r3 ]3 p8 N  f: G
    # test_image_dir = 'test/test/image'% k; e& H1 M: ^1 i/ O
    # test_xml_dir = 'test/test/xml'
    # V0 }! z0 b# P8 K. H" o- z3 E, ^( E3 j" ?, a) a
    * n9 L# h# w. ~5 I5 x; y8 ]7 `
    class FruitImagesDataset(Dataset):
    ' ?: o  m- N6 }0 n; ]$ _& y. w
    6 ~1 ?* y' L& e) f/ E% B; ?' N& L
    . x! `: ~5 t" }1 g
        def __init__(self, image_dir, xml_dir, width, height, transforms=None):
    ' t7 [% `8 I' m2 K        self.transforms = transforms
    2 y# E/ S5 q% p) B# G  F        self.image_dir = image_dir8 k* t% G+ N; W+ h9 G$ W; V: S
            self.xml_dir = xml_dir5 W% G  }- Z8 F1 J; m6 s5 W
            self.height = height
    4 Q' i2 D# o' h6 I, x4 H; ~& |' k/ N8 y        self.width = width4 k+ i, j; k9 [# L/ U4 Y/ Y0 `
    & s! a) S! b1 B3 e0 n2 [6 z( f- W
    & S  g. H" y  R' O: C
            # sorting the images for consistency5 @( @: j7 ?0 t  z  C
            # To get images, the extension of the filename is checked to be jpg
    ! [% h4 E- ?/ ]$ |        self.imgs = [image for image in os.listdir(self.image_dir)
    0 L; J+ \; E* S2 G) U% b- ?                     if image[-4:] == '.jpg']) t* d# v) k1 k+ ?2 Z0 \9 t
            self.xmls = [xml for xml in os.listdir(self.xml_dir)
    $ \! ~: A! g! {' q                     if xml[-4:] == '.xml']) i/ F4 \- e2 b0 j
      e! F* F2 u2 t# b0 |( s: Z  Q
    ' t7 G, J- v2 Q: n. z. H
            # classes: 0 index is reserved for background& f8 b# [1 k8 Y0 @
            self.classes = ['apple', 'banana', 'orange']
    % u( j+ {8 r+ a
    ' b6 l, a" t; f2 l" h/ a9 a
    % W2 N0 ~* ]" N* h) J* N% G
        def __getitem__(self, idx):
    4 h; f7 ?5 p/ @/ {, F- Q! N  p! P' l8 Y3 u" V
    + d1 U& J6 G/ H
            img_name = self.imgs[idx]3 p6 [$ L: Z5 i7 E: L2 G- \0 l
            image_path = os.path.join(self.image_dir, img_name)+ g# y% a* J" o3 T; M- T" d1 w3 a

    ' A) J6 O; x$ U6 g

    0 R- y2 b- R$ h" c        # reading the images and converting them to correct size and color
    5 w! _0 h, _9 Z6 V! l/ E3 B. w3 W        img = cv2.imread(image_path)$ y" V# V% b+ u) g* A# h! p3 d
            img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)
    0 r2 r; L: W- e4 V  S4 w        img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)% C$ T7 a, k* J3 }; Z3 A% E3 E6 U
            # diving by 255
    3 l) X& n& J3 {9 q5 I3 u2 E        img_res /= 255.0
    , F: C! V3 R* [+ M! m$ }
    8 X9 u0 q' R  N3 \. W6 ]

    8 K" ~3 E9 c3 l( ]        # annotation file% q8 G7 K0 U5 o6 ^* ^1 Z# I
            annot_filename = img_name[:-4] + '.xml'
    8 a5 {; Q1 U9 v( r9 Z$ w5 ]        annot_file_path = os.path.join(self.xml_dir, annot_filename)
    2 `7 c% \4 q: \/ }% P
    * u# l; B" N% U3 v5 v
    0 b" O. Z2 c, e/ R
            boxes = []
    4 l& U" ]% b0 L. r        labels = []
    9 [* H+ n1 H8 ?2 v$ Y) R+ |. V/ j4 z        tree = et.parse(annot_file_path)
    + {" _7 l5 O5 D* x( N& {% x        root = tree.getroot()9 }+ x9 R. D5 |, [/ \! [
    & J& R% z' }& W: ~7 k4 I; g
    2 g" ^# |$ {. `5 n6 n* [
            # cv2 image gives size as height x width2 x9 b% K0 h8 k3 J, r
            wt = img.shape[1]
    3 h$ F; q2 C: h; F+ S. C& H) g/ n        ht = img.shape[0]( c$ |+ ?# Y& p" p4 r2 ?8 m

    . j. G' H6 C) d: l5 g  q0 @
    " D' i, ?& I2 ~5 I3 b* T
            # box coordinates for xml files are extracted and corrected for image size given6 N1 @9 _$ D/ ^! h, v/ {. l3 W
            for member in root.findall('object'):* D! \# v0 @5 `/ \) S! O
                labels.append(self.classes.index(member.find('name').text))% {. n) X- O- I

    5 ?4 t8 m8 U! n" }

    . b! |  C( w; [            # bounding box
    5 L3 h& m+ g; Q& [            xmin = int(member.find('bndbox').find('xmin').text)
    1 \! |: ?# a) p: H4 ]: T; Q  z            xmax = int(member.find('bndbox').find('xmax').text)
    : W0 {; ?( A0 ^2 I2 y$ J& n+ z1 w
    3 f% ~. F6 v' E, m; _; l
    8 o5 A8 K, E0 y/ Y  n! O# a; e
                ymin = int(member.find('bndbox').find('ymin').text)# M# n! a7 u. i' Y
                ymax = int(member.find('bndbox').find('ymax').text)
    % f# w* [, f: _- u5 y7 @' s! S2 u9 E4 ], D, n4 G

    % ^" G" R6 c* g, `2 A' ~            xmin_corr = (xmin / wt) * self.width! d2 ]: M) z! T7 \& B' F, v; `+ @* j
                xmax_corr = (xmax / wt) * self.width
    $ f  x  h$ ]' p' U$ j& b$ |            ymin_corr = (ymin / ht) * self.height
    ) h: N" I7 W5 a1 b9 r            ymax_corr = (ymax / ht) * self.height
    9 d/ b* D- d6 S& c1 b8 F            boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])7 l& S+ d: c5 X4 D# |. E8 y

    ( G5 G& X/ K+ v& ]4 E4 @7 D! m# R

    : c3 m" q- a' ^        # convert boxes into a torch.Tensor2 Z$ i3 ~* _$ ]3 |
            boxes = torch.as_tensor(boxes, dtype=torch.float32)
    : W, L6 @( J  m# Y: j& D. ]4 i  d- F6 d( h* _/ k  K3 h/ |
    7 h. K4 A6 ?+ k# l+ Q
            # getting the areas of the boxes; W) Z! M6 v/ l/ r1 w
            area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0]); @  ^* [; f; k9 v
    6 ^/ G9 k7 t) K: K8 F/ r: M+ y5 `

    1 n- _, D. k( ]0 P        # suppose all instances are not crowd1 [+ c4 u& n+ V! p8 ?) f4 b, }
            iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64)
    : X3 n( w+ Q2 S3 q/ J; K% \) A- n8 G
    0 B* l3 d- V. f% n. z
            labels = torch.as_tensor(labels, dtype=torch.int64)
    4 z6 Z6 R' d$ y/ Q( |. s7 V) s
    4 a3 @' k) O9 L7 r, W# t3 s* E" p& k

    # H' G( p) j5 K        target = {}7 P: C1 U- `0 o( P/ V2 p, c
            target["boxes"] = boxes  I- b( q0 i% o9 \9 \: U
            target["labels"] = labels# J9 L2 P2 O: J1 L- V
            target["area"] = area* N5 u' N/ a& Q- k: o
            target["iscrowd"] = iscrowd
    2 L) h, }5 O6 z) J3 s) _        # image_id
    ; _& @1 {: b  d& G3 V, }) a. }% M" z# r        image_id = torch.tensor([idx])
    ' _  x6 H; n4 |        target["image_id"] = image_id
    / @! x* J" c6 Q; @+ E' ~
    " Z* z7 {1 T0 Q' }

    2 O5 G3 m4 d- p        if self.transforms:2 C3 [: R8 }$ b, J- D0 V
                sample = self.transforms(image=img_res,3 i6 e5 n/ i" F- I0 s+ e
                                         bboxes=target['boxes'],; G% \1 s) ?( Y/ g6 |, n
                                         labels=labels)
    7 d* J- L- i" |
    : s8 F& c: ]8 Z! f" r) p. j& D
    / _. @& x* t3 T, t6 g+ t
                img_res = sample['image']
    1 S5 J- M* d9 S( X, c( ]+ Z4 [            target['boxes'] = torch.Tensor(sample['bboxes'])6 F6 O) O- N  S, ?4 @

    ' X, V5 `" C2 i9 K8 r
    $ u& @- E4 _! u, E) R
            return img_res, target- ~9 y3 H& @. t, D4 X, k# v+ s& A* {
    0 [( |! _, d6 D5 O0 j5 ^) L

    * m$ D0 q; C# X' y3 a) x& f0 j    def __len__(self):
    5 T! u$ @3 S$ V8 o        return len(self.imgs)( b- m* a6 F) ~6 m0 M5 h

    # j0 K( n0 ]. T; f, G

    / P$ [( f0 ~3 F# function to convert a torchtensor back to PIL image
      X, O1 e* h2 C, |def torch_to_pil(img):
    0 f/ k7 K# b1 J$ A6 O' ?    return torchtrans.ToPILImage()(img).convert('RGB')( q# B1 E; T6 i5 h5 Q3 c

    3 p! ]9 o/ ^/ ?+ r" t
    & H1 r9 X: H1 k
    7 R: M5 r/ O& U& ]1 a: a
    $ V- ?  C4 E% f
    def plot_img_bbox(img, target):0 V' I" h# J3 u* `1 l
        # plot the image and bboxes2 ]+ l2 Z( B7 j! ^
        fig, a = plt.subplots(1, 1)3 d  x; g( {; @5 A/ y$ z
        fig.set_size_inches(5, 5)
    , [# ~7 t& }$ B" a  Q6 V    a.imshow(img)
    , P: D2 }% z' p6 }( u    for box in (target['boxes']):4 U; g' h) e& W' N0 w& w1 P" u
            x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]; P7 f) F5 ~' |% ]3 j8 k  ^
            rect = patches.Rectangle((x, y),
    3 ~# `! X' L0 A3 g' T! F4 ]                                 width, height,8 s) {& m' H: a, S
                                     linewidth=2,- K2 N/ ?" h8 V8 [
                                     edgecolor='r',1 M' n  p5 ?7 X& o- i# Q9 w
                                     facecolor='none')
    ; G/ C( d5 Y" g: H) u) x7 h3 A( T- [; a: T- Z

    & a' \; M$ C' |# w8 h3 P2 X6 W3 u        # Draw the bounding box on top of the image" p" z7 R$ g; k* @* q
            a.add_patch(rect)  y2 m3 w3 U" F/ L" g
        plt.show()
    : c" [+ M. W% z5 x. D) y2 [/ {3 X! s" u
    ) X1 S- J* v, d" i- P
    6 q3 x( _2 o3 n' s) W, e" f

    # G( w' H# @) mdef get_transform(train):. `, [% S$ D; M! X) I& M3 V
        if train:
    . u" H) o; H  N, G        return A.Compose([; q0 T# f$ F1 Z4 [) t* z8 v
                A.HorizontalFlip(0.5),( S; e/ {& X( K" m; k+ p
                # ToTensorV2 converts image to pytorch tensor without div by 255
    8 t7 Q7 a3 Z* a3 w6 I: M            ToTensorV2(p=1.0)# A4 k- ]1 o* }; L4 }4 B8 R. C" s2 n
            ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})9 v% p# N( E# H7 q  T) j# a
        else:1 W0 M' ~- k1 _
            return A.Compose([+ Y5 J  ~3 s! V: B
                ToTensorV2(p=1.0)
    - f; u' ^; b/ y# Y* u        ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']}): {) x4 J2 C% p3 k+ f  K: G3 o- m: R

    ; {4 M+ M3 {+ \

    2 V% F$ t& B$ S5 \
    , Z, @1 c+ F. \% V7 x" t
    ! L- E1 g4 j% u% j& A

    $ @9 y0 W* s* ^  K4 W. r$ @
    # t: ~/ d  N, ~% w/ B* c! O
    dataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))! S( U! K. V  X- E, r3 u7 _

    ( P' D9 T8 l6 T; f/ p/ X8 s) R

    - n* z+ j7 O8 Y4 iprint(len(dataset))8 `( f# A3 _+ \( U* U9 a
    # getting the image and target for a test index.  Feel free to change the index.* x* D9 C" U* b- X
    img, target = dataset[29]+ U7 Z6 J5 ~+ C# ?
    print(img.shape, '\n', target). Y- O9 @# V7 Q
    plot_img_bbox(torch_to_pil(img), target)
    * n- ^# C7 E  U# e- ^3 e1
    , U1 b8 h0 C  x. b5 X2
    $ {; C0 x0 C- k5 z4 k2 D& x3& M- a" k$ H% F( f7 Y
    4
      x5 J" p) c% U8 W9 t5
    ; g5 Y4 W- y+ s6
    5 R: g4 |; I6 r9 o2 t  e7
    / N' c' U7 G, x+ c; E' ~; Y88 Q. o4 M; r1 E
    9  e1 y) b. v. v# T, E$ S+ C
    10
    0 `. {% }  I0 h& z6 Y11
    + V7 Y& p/ ~4 z  o128 B: S0 z; j) F. P
    13
    + Z- H  e; _' _! d+ z14
    1 b5 `+ K8 R. E, t5 N7 l; f15  O5 K8 [4 K: D3 z) [& w
    16
    & Z( H4 N0 l4 x. z  ~" k17* P4 T, j, T) G
    185 N8 C0 b0 \" C5 O" \
    19
    + T9 [# h- C) _) Q20
    ) t+ z- p  Z, \! d. x8 K/ z21: L1 L8 x0 C2 U8 g" E& f
    221 d/ F1 [: z, T4 x  S
    23
    8 V9 O. A. G2 w# W  M24
    % v& {: K7 S/ q( v" D4 d* t25
      d+ _7 c4 o' u& ~% ?26
    6 n7 c' a# ^) d) X+ J8 F: O: e274 M0 A# q. g0 ]6 q4 Y/ W, W
    289 r; O) O6 C) o3 V& f
    297 c, t1 I6 `8 P; O* J
    304 o7 z+ U* E- ^- W! w
    310 n! C  E( A: G3 ?, l
    32
    5 b7 u5 C) G& o' u) F4 P33
    : K5 p# c( d2 T34
    2 E: E# _2 D$ C) u2 P356 O- c' U5 {$ x$ x5 V
    36. Q# K% {& G  t# |
    377 h, C6 T, X5 J
    38
    * r' d$ j  I) r& o' y7 a& ?2 d39* p# |6 o$ S: b, b4 r8 _- _
    402 c; F2 G* @) R
    41' A0 c* p! Z$ J
    42  _" [$ A7 S& V  G8 I& \
    43
    0 B0 L$ N5 w$ Q; }: _1 d# R44
    6 d2 y3 j, R" l  i2 c4 K45
    ( c" K, I% O, L6 t/ H461 X) h5 {9 i0 s3 }/ E; w
    47
    ' d# x' @* X% a/ o' r: V48% j# L  X/ o! a! s9 s7 Y; C
    49
    7 {# S: _; t$ o! n- a50  c$ N5 _( T  W5 D" j
    51
    4 j7 i$ D* r; G6 V52, k, |! |3 @2 }) d  d
    53
    - \, g# a9 B2 y0 z54
    4 |9 H* N8 i8 Q/ P2 c& `$ Y) C8 m2 e55
    1 \# n0 p2 K, c0 d+ _56
    1 J& P3 i$ j" e! L' [; b7 f57
    " S, p' z9 {* B. P7 [5 x3 l586 e5 Z/ C6 ]' A
    59
    " u5 ^! Q! b0 Q6 R/ f4 B9 {- M60
    # L8 ]' N  R  u( e0 P+ F61( W4 ^/ B) z! f1 i4 j
    62
    9 f% `, r$ ~4 Q: z63
    & J7 F; y5 [0 g% ^, e7 J649 @7 q$ F% y0 b$ W/ n
    65
    4 o0 |9 c2 M1 }8 [3 A  T/ ~66
    . ?( }" ?/ q$ ^67
    - J$ J$ o  l9 T: r68
    7 c9 i9 R8 \" M69! Q3 f" j- |2 `2 }2 O
    70+ ^" I9 ^2 h# _' G" Y3 X/ |
    71
    ) ^4 M" t6 O/ {72) L# y$ E# Z9 R3 V: H9 |
    73
    8 ]. R5 }. A8 ?* U74" \3 e% D% Q! u8 E5 u& M& t
    75
    * U; J5 M* x* l1 L* j$ P  z76
    ) I* Q" p3 H+ g4 u/ S+ j. u77
    5 f  A$ h8 ~; F) ]4 s78. r, `/ i' c+ d
    79" x  j; w3 d* `
    805 T& T8 j5 @& d1 H1 h+ f7 ?
    81: r$ v8 Y  Q; p: d6 ?4 n0 E
    82: o+ d5 H" P1 Q3 w" w' u& b
    83
    - l+ K( |6 k* Y; o844 T& n. x: r5 n. Q% k2 C8 f
    85
    8 v/ g4 T4 ^6 k8 T" y- E86
    # @) k' ~" e% g87
    ; e- |+ [" Y! _2 ]! G1 \88
      ?9 U' S$ o4 T2 v89
    * b" F! k* w( n1 G906 I" L3 x+ h$ W4 g8 R, g, _3 p
    918 t3 k$ Q1 q( J- j( H. j: G
    92, w8 f/ J( u6 T/ T+ F
    93" t* |0 c9 [# C9 A, d9 m8 @: O9 y
    946 K* F% ^3 c8 K) v! I9 A
    951 l8 Z0 _9 t3 \6 }( V# y$ x
    96
    ( k# P$ [$ i( D+ u5 E97
    * J" J/ N1 W8 u- g* q98
    4 n7 }5 e! ~: t5 @. y7 E6 y997 E' R$ o/ E# l" {* a# a! k
    100
    5 ?; q- B# b$ c7 S  x7 r101
    1 P3 e2 r$ W( L7 k6 d4 y102
    7 E& M! h- `7 V" k2 A% T  l( G103* n" @' `4 Z  I5 a; @/ n
    1043 J! n; j: C( u" l# R  H: a
    105
    : S0 F" ]0 y( ^106
    / a! u& }7 a! g4 M. \1 i! d! ]% ^107
    ) p+ d: `( x1 Y2 X3 l0 l8 |1088 k/ O0 e5 b9 N& K0 |" g" }
    109
    % Q8 h6 w9 o+ w) Y! v1 ?4 V1109 x- H. {1 w0 {: y- \* p
    111
    3 a+ m9 x  b/ ~  ?( O112. S- N; M( T6 Q  P' p
    113& _$ C" k) _2 z
    114
    ) A4 q  ^2 o: @8 ?% W9 w/ c- U( u115
    2 {& v. \; R& B1 B% H9 M/ n# x116
    ; M) G+ A/ G8 `5 v' f& @! ~117
    7 O3 s8 h* O% g0 \118
    & n) {" b& y/ W! a1197 i, e9 \4 _% D4 m7 z
    1204 p* ]" A0 t2 Y9 X- M, E
    1219 |# \2 D3 z# n& R
    1222 L8 [7 T* [% W1 [5 E! R
    1239 Q; g, o6 [. c6 |
    124
      v, B( X  a" u3 I, E125
    - n8 b' X" F- d; e1262 ^! n' l( h7 ~3 q; w6 Z. n
    1276 S# L* j: \& `+ f1 L7 x
    128
    * @$ O# w8 L  u$ y. p1 ~0 m% u! A129
    3 ~2 K" C+ M; Y4 D  D130
    ! a3 h6 ~% S6 p9 H131
    3 q% W0 ?* s4 Y9 e; j132
    9 u) o+ i8 ?! B, y2 d) I$ `# c1333 _& P5 @/ y& F  E
    134/ u+ A0 N$ ]. S' o6 D" x
    1358 D$ z+ I( g+ }) K, w" k: {5 U
    1367 W- v8 Z: _9 H$ m) k5 n$ N, Y, z
    137
    $ G/ r; ]- X  N9 F$ W3 M( k138. J7 U( l' {7 r3 V& Q. r6 L: }  h
    139& ~) O+ S( x3 K( r/ w
    140# m+ [4 ^; ?' C5 C8 q) n0 K
    141
    : c$ ~5 w5 _; @* @142
    / f) q# R7 p: I# k6 E# W143
    $ J# O, s" E- {  V1447 }' z9 V6 \1 L% L# A
    145
    5 }/ W3 n! I/ a1467 ~. n3 t) u9 W# r6 u" z% W( V
    147
    9 |& i. r  o9 V2 i1484 z: V, |; f3 h# ]1 O7 i' E0 ~5 k7 w
    149. z1 e6 w) ?( Z) F& d
    150/ C( L* l+ q- K3 Z4 X- }1 N1 g
    151% B7 F0 B" j) D( K& d& Y
    152
    3 y  c: T) {; I+ t2 b153
    5 m! P. Q5 \5 E; q154
    * K# T( e/ f& ?( Y; U% r0 h! Y9 W# q155
      N4 N; U2 M. \$ J. S( X156
    1 J7 ?9 d, L* l4 B* A* i输出如下:7 x/ }" j  W# i" F

    2 R. }% A: A$ S" {

    $ K) |2 y* T" o6 {torch.Size([3, 480, 480]) ; D& C: [4 O, D) u, Y+ k
    {'boxes': tensor([[130.8000,  97.8000, 327.6000, 292.2000],, p2 _- V% `# u8 g# \( ~
            [159.0000, 268.8000, 349.8000, 427.8000],' Z( Z% S, @4 A/ C8 X" {
            [  0.0000, 282.0000, 118.2000, 429.6000],* s- q: l2 J" B% w! S7 [
            [ 43.8000, 107.4000, 199.2000, 280.2000],0 [* @4 y; n/ _
            [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])}
    & ]3 s/ Q# [% c( S. a9 ]# O6 o% l1
    ; z# l- q( C! h2
    ' e: b! F" U% o8 j) S+ H. h+ R30 O- M! ^% f! r
    4
    6 B3 {' l" O. S$ w5$ q4 ?. M4 Z% ?! @& X3 R9 i
    6
    / `/ r+ M9 j, X# B8 F2 S: I
    % I1 X) _* A- a7 l; ^2 a  {
    9 U- @* w0 v: M3 w7 }  X

    : A* m! v$ g+ B" R- V- j. [
    / d% C1 w, l  ~4 ^
    下载地址1 t8 \' l! f1 `1 |$ G; z' l9 Y
    链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw( C6 |+ e7 G5 v3 `5 f$ i- B' K2 Y
    提取码:srjn) ^7 h# s6 d8 K- n' L
    ————————————————( p$ N, x. w: q, n- o
    版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    2 J- m/ L4 ]( z" f6 q原文链接:https://blog.csdn.net/weixin_44510615/article/details/1184962738 [  n- ?4 @' |# z8 T$ H( T3 H
    7 }7 U' h4 U" E7 q% P

    7 Q' d4 {4 E% C0 q1 X) Z
    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-4-16 07:55 , Processed in 0.417529 second(s), 51 queries .

    回顶部