QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3513|回复: 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
    0 y) r5 i2 ~1 T: t, m
    深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息; ], V- S: ?( q4 m+ F5 W# g# l' S
    图像标注主要用于创建数据集进行图片的标注。本篇博客将推荐一款非常实用的图片标注工具LabelImg,重点介绍其安装使用过程。如果想简单点,请直接下载打包版(下载地址见结尾),无需编译,直接打开即可!
      V3 Z# l7 I, g+ _( c) I8 B
    . n/ k- a- O, B2 |* ?# [

    ; F9 N+ U( k( [, Y感谢原作者对Github的贡献,博主发现软件已经更新,可以关注最新版本。这个工具是一个用 Python 和 Qt 编写的完整的图形界面。最有意思的是,它的标注信息可以直接转换成XML文件,这和PASCAL VOC和ImageNet使用的XML是一样的。" S: `4 U! E" `, y! m# m( m

    % h- \7 ?+ i+ @2 L. g

    - N) I" @9 J6 G" O# K3 ?# S6 `附注。作者在5月份更新了代码,现在最新版本号是1.3.0,博主亲测,源码在Windows 10和Ubuntu 16.04上正常运行。/ h* J9 b& q' R& h2 \5 B4 E$ [! Z

    1 q5 p) r0 K! e2 U4 U# `2 I. n
    : Q% c/ e! E; D! a
    具体的安装查看Github教程:https://github.com/wkentaro/labelme/#installation0 \( Z7 t  g+ w- _* h/ W( {# C1 Z

    5 [' G* U) Z) f, d
    0 K: G2 P9 g) p# h! E
    在原作者的github下载源码:https://github.com/tzutalin/labelImg
    + I( o7 p4 Z: W7 ~5 h' Q8 I。解压名为labelImg-master的文件夹,进入当前目录的命令行窗口,输入如下语句依次打开软件。- a/ D# [3 f, w, r
    & c! g' t) |$ F( U" k- Y, X
    ) h% o: U. E3 M% v1 k% Q$ c& l4 t
    python labelImg.py6 D$ k3 M; b' K4 z8 d5 l4 e
    10 T) v. T9 Z, M/ e  J' h6 n

    . l, X' U/ z9 `2 O

    5 L1 t& [9 l; x) h. M5 E, @# l! z& y9 {1 H2 [# i

    2 Q5 s  V3 @& {& v! M9 a具体使用( q8 ]# G$ a  {4 G" p8 V3 A4 p
    修改默认的XML文件保存位置,使用快捷键“Ctrl+R”,更改为自定义位置,这里的路径一定不能包含中文,否则不会保存。+ `! t+ h3 r; B4 v: A

    1 b% ]0 h$ t1 _8 d$ l% Q

    - V2 u1 ^6 W! g% X使用notepad++打开源文件夹中的data/predefined_classes.txt,修改默认分类,如person、car、motorcycle这三个分类。! {6 e9 F4 V( v6 H
    , W# `! \# n' w# t( y  N2 }

    " \. V7 d: ]2 Z0 T* s* K6 _“打开目录”打开图片文件夹,选择第一张图片开始标注,用“创建矩形框”或“Ctrl+N”启动框,点击结束框,双击选择类别。完成一张图片点击“保存”保存后,XML文件已经保存到本地了。单击“下一张图片”转到下一张图片。
    9 a5 Y! ]+ O( R7 ^, n" j# y. l2 _
      Q1 h! {. e1 a6 A: }  @
    3 M; C& m; a- N. Q
    贴标过程可以随时返回修改,保存的文件会覆盖上一个。* }- j7 x4 z0 ^& P1 a1 Y% Y
    ( a' n5 s: f% ?& S& C

    5 x  D3 B: {' V/ [% Q/ G完成注解后,打开XML文件,发现和PASCAL VOC格式一样。; O2 }0 E: N" w' v3 ?

    - e$ }4 ?0 n' u" @0 y

    ; R% O, O" p% y/ ]8 i+ c将xml文件提取图像信息: e7 p' R/ t8 a. \- q' r
    下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。+ V) v% G* J% ?9 @) }  _" H  d
    4 F/ R6 d% t7 g1 v% X) [

    ! V' G0 l$ R$ }! I& @
    ! M, b2 ^( U1 W8 Y% R5 L

    0 r& M' }0 r- w1 w8 X下面是images图片中的一个。
    $ [0 G' x# Y4 `* \4 n' a
    ! J1 X, e1 e  r4 P3 O; `6 |

    ! R+ K% G2 ~  ^下面是对应的xml文件。1 B1 a/ x' J' H- U: o
    ( H. u( Z( H& V6 ~
    9 u7 z9 A3 h3 ?+ R1 K1 q
    <annotation>0 m! a+ C& `4 z+ ~+ z, A) p7 a
            <folder>train</folder>$ S1 ^/ {+ z. u) ?# Q  S
            <filename>apple_30.jpg</filename>
    ) T  y9 ?6 J( M        <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>
    # K: L) T- c3 K. ~  T8 c        <source>% n; x/ C9 V  N5 [3 X2 K
                    <database>Unknown</database>
    + h0 s' s9 C9 m, l9 l% Q        </source>, z' l4 c, ]3 c1 a: G
            <size>2 S  u5 ~" a+ D
                    <width>800</width>; T% y- ?* m0 G  i- s/ l3 ~
                    <height>800</height>/ _( f2 A* c* O" P/ j
                    <depth>3</depth>2 ^  [( S) _! w$ i4 T& [% H; M
            </size># a" f) z. T* X+ a
            <segmented>0</segmented>
    5 F5 E1 }1 q/ _4 a* V9 L        <object>
    % ~& w' d/ N3 o4 p7 ?- I# ]+ Y5 I4 U) L                <name>apple</name>
    . f% Y9 b0 p; |5 d( ?: P& q, S& T                <pose>Unspecified</pose>
    - j- K3 I  o0 I8 F! J                <truncated>0</truncated>
    7 V2 V8 Q' m/ p! g2 z                <difficult>0</difficult>  f% y* U0 p2 I- x  U2 L
                    <bndbox>& J5 q, ~, t' l: F! Q. J7 Y
                            <xmin>254</xmin>
    2 m; h( C7 o# f$ S, f                        <ymin>163</ymin>) z, |9 r1 l  V& k
                            <xmax>582</xmax>
    8 m$ \4 d) i3 P                        <ymax>487</ymax>
    2 E; K, O; a6 ~: O                </bndbox>
    1 Q# ]; z* N' z; r        </object>" a% \2 _: ?' r: B2 d  ]
            <object>* {+ h! l; ~0 T0 W  O" r4 ]
                    <name>apple</name>
    % O5 P# i7 h2 }" {* y: w# q                <pose>Unspecified</pose>
    " p# C# X8 M+ E( U9 A* h3 F! Q                <truncated>0</truncated>
    ( i( ~- O! ]* b6 |8 E1 u; v& B                <difficult>0</difficult>
      H! Z2 Z1 e/ t" @                <bndbox>
      G: w. G9 J% t7 ]* v                        <xmin>217</xmin>
    9 c6 q' e; g! x/ k4 g+ T7 Y9 r& P                        <ymin>448</ymin>
    ! U, L/ n( i5 D( v% J                        <xmax>535</xmax>
    5 d+ {4 P! O0 ^6 f) k                        <ymax>713</ymax>& O# ?" x/ s$ [! @( y
                    </bndbox>
    1 n  q3 k" V$ r        </object>
    7 J0 [& k- X: K9 \% U0 X        <object>
    6 j% H1 W; g' n                <name>apple</name>9 r  n/ B0 h% q( ~& ?+ R' f' M4 F- |2 h
                    <pose>Unspecified</pose>2 K. F9 `5 T: o0 L) V: D0 M8 M
                    <truncated>1</truncated>" Y) o2 a& f( x: p; ^
                    <difficult>0</difficult>
    + f$ m7 F! ^% L                <bndbox>6 W# P. _. {7 V$ z5 h, M
                            <xmin>603</xmin>
    ; ]6 c/ X8 A! E8 }! y" g! b9 g3 ~                        <ymin>470</ymin>
    / S$ t! V3 D5 H: k6 L                        <xmax>800</xmax>1 L7 v3 F9 s- |; z7 ~
                            <ymax>716</ymax># Y5 n) o6 X/ d- _2 T
                    </bndbox>
      M/ g( \% D4 T& l. ^3 }        </object>
    6 m2 O9 M5 _' `5 i3 z) c        <object>% Z" B9 d- H- @* r
                    <name>apple</name># x$ }/ z) i/ \% r, a% f2 ~
                    <pose>Unspecified</pose>; |* f# J7 O! [# z5 v6 D
                    <truncated>0</truncated>
    ! k+ X# K5 l( S% x/ B4 c                <difficult>0</difficult>
    + j5 I( V, ]* a; t6 D; ^0 N  @; [                <bndbox>
    $ Y! Y: v8 a9 A; C$ o) R5 O  L                        <xmin>468</xmin>
    3 S) M9 ^) e' Y+ K! B) X9 D                        <ymin>179</ymin>
    7 c9 S2 \, e# W$ c/ G6 I: [                        <xmax>727</xmax>! V0 S1 y+ l5 g5 r
                            <ymax>467</ymax>
    $ c9 a( S4 ~4 ^! @  j3 b/ L                </bndbox>
    ) M, N, x2 l6 X* m        </object>) e5 X+ ^+ |4 j9 T
            <object>- q4 {1 Y. `6 _; ^- O& I9 P
                    <name>apple</name>
    $ w- B. M/ A* U4 p. {3 D                <pose>Unspecified</pose>) X# M! ?& K  Z2 S& d
                    <truncated>1</truncated>9 Q8 s3 O2 \* x- {7 `# }1 R
                    <difficult>0</difficult>
    0 n1 G! F" b+ e1 P$ e8 O8 l                <bndbox>
    6 F2 L* u0 z. T: A1 ^                        <xmin>1</xmin>
    ; m5 Z* {' ?# K8 I- o                        <ymin>63</ymin>: \+ ?1 \5 D: O4 j$ z
                            <xmax>308</xmax>% S1 ]/ z+ i9 h3 e- Q
                            <ymax>414</ymax>
    8 E0 Z, S9 \3 A3 T5 J+ g                </bndbox>
    6 s- J1 z% l! u5 m) ?        </object>0 ^: E' X* w9 Z& Z2 h$ E
    </annotation>
    3 |5 h; g6 z' s( H10 I' V6 G# f( f# ]( |
    2
    % x) f: E9 `' Y4 I3 X, P  m3
    % ?$ q$ E! _7 X* W$ R8 f4
    # G6 A0 O9 m- Z; F; ^7 g( B5
    ) {3 x# H1 @! e: b+ X! r6 \67 M$ _- a: ~9 \
    7
    : q( F3 U# m& L- j8 T8
    ( D2 N2 J% f+ `% f  P9
    & {0 p7 m- [3 C: R10
    ; U. g5 U* X3 L' b- V' U11. C5 u/ G. H7 S- [/ \: S! Q
    12
    : A" U3 f4 t9 Y) l* _, B7 L13
    ! p) m- W: n2 D4 h/ p14
    $ L7 {* P0 O' K# {! J158 f7 U2 `5 ?% m8 h) h, v  P
    16
    ) K+ T% v, R" R3 `! @' J17
    / e( n1 s! Q$ i4 s  ^+ k18  V" D& c0 W! d1 y4 M3 Z! Y9 y
    19
    : t3 t* c6 S* v  I3 m20
    7 q$ F, p4 B8 V# e, v% b21
    6 W: F% _& F$ P$ o22
    & V( I/ `# R! [23
    7 s' ]1 \5 P9 u: ], O9 p24
    0 G* U. I2 y! g! J/ t9 D251 |1 i# L- t. M
    26
    ( |; [( j* p% U% I+ M27
    9 u" |( T/ Z1 V: w# c9 s28
    & h: i! u# r1 w7 h! @" ^29
    # n9 I8 _) p" g7 R: L1 S1 S30
    9 W4 m. b4 b3 O" G: T3 h31% e4 C0 [. M% ^7 |3 ?9 }! d5 {7 B( [
    32
    0 `9 C% d5 w- }  H33: ~7 w1 r7 N0 _$ b* P
    34
    ; g( v8 E& @5 s1 f2 w8 {/ m( i35
    - Y2 a( I+ o- J& w36; _5 f/ p" a+ g$ _% f
    37
    ' T) x7 E# v. {6 t% I38
    9 l% }$ m# h) }/ n$ f' ^4 y. ^39% |! ~- `/ T2 E- o/ I3 I: q7 c
    40- l) H" T5 k# ]" x7 Z
    41
    ! \! M' X+ }, K, `2 O* D429 ]$ ^5 a8 H7 o! @" S3 i
    43
    3 c; O' }7 M9 e7 v44. y5 }$ d% h8 `' |& Y% T6 j
    45
    & v: G: j! O7 r' l3 I; V/ y, l46' L: N' F8 d- L7 w" \
    479 c$ U$ b; J/ F2 R) t
    48
    ; h# }& e% L+ q9 P' h/ i. ^49/ y! R2 M9 G: ^. R4 o* l) R# `7 q
    50
    # q9 \) w  J6 e, R9 z$ r* c  L0 b, w51! C7 p+ f9 T* I
    52
    ( r2 v8 u! S% r- L4 y) t53- w& Q* {# n3 Z5 j/ g" X9 @# N$ n
    54, {+ ], T( a) R, V
    55  p! R/ c. R7 R* N. i! v# _
    56
    ) ?: f! N* j# W. ~0 G. a! p( V# p57
    7 _4 X- L; E/ b* n9 ?6 T584 j! ^3 K& d4 u( x5 t7 [
    59: M$ @) _5 K! G+ t6 j% J; K
    60$ \) w; X5 o1 z! d$ q
    617 R1 U# h, O! [0 o( N
    62) x9 O0 P( w  U: ~
    63
    + L) b# w9 `9 D0 i64
    . j# T0 Z$ t( n% c9 z656 [. D- n) p9 N  I- z
    66
      s8 N6 e9 w1 A) C, @67
    6 g7 z8 D+ Z$ Y2 G* r/ c! U" O68
    ( r: L' D1 `  v/ M+ ]4 [) \69
    : L) R2 ?( r4 x2 U: e6 Q70- H+ v* \+ t; L8 |3 L
    715 C: K2 Q! ?/ p# U1 }
    72
    + C: k. x1 s$ I4 ^6 P73
    , H6 d- T# O7 o1 i74; h% Y" Y! T* s' I
    将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。, m4 i4 l' ~$ C$ r  f; j0 f! j

    " j2 H1 p* b9 X, y$ M# K
    5 L5 B* e; p3 ^
    import os
    ! S3 k3 h- z3 i1 A4 {0 _8 F8 Yimport numpy as np/ ]9 `$ k+ b% z1 I& k: w% L
    import cv2
    & B. k9 R% M$ `& T5 t" ?& {( V" mimport torch7 l; {- j* Q( I( ~% a( {+ u
    import matplotlib.patches as patches
    2 S$ a0 D" k" X& h  k1 M5 Gimport albumentations as A  n/ o" Y# q, D2 j' \
    from albumentations.pytorch.transforms import ToTensorV2' f" I% E7 g6 u" ~/ x, Y9 [
    from matplotlib import pyplot as plt
    . {+ t/ L" a8 U; n5 ffrom torch.utils.data import Dataset! i$ \; X% b# N$ P6 Z2 ^; T# f; }
    from xml.etree import ElementTree as et
    3 Z5 D. F% F) _# P- C' v3 Kfrom torchvision import transforms as torchtrans
    4 I. j9 H7 P6 f( a% T6 ^' g$ B1 f: I" D& ^. Y0 X
    5 K) X; ^$ y' x1 [, ]$ [9 }
    # defining the files directory and testing directory
    # ^6 K5 H7 i! e  X0 }train_image_dir = 'train/train/image': _) V' c( B) l$ H9 r' R4 q
    train_xml_dir = 'train/train/xml'
    7 U' X) S; W. G% Z. j& D, q/ g# test_image_dir = 'test/test/image'+ |6 h' Z; D! \: `5 k
    # test_xml_dir = 'test/test/xml'
    7 o' O' h$ y3 v+ v# W4 r, W4 W5 g. X$ g+ z9 g: n
    7 e7 h2 o! V$ A7 }
    class FruitImagesDataset(Dataset):/ s: e. T; Z0 A7 q  ~# k/ P
    . o# y& x! i3 n
    . m! [4 _) h  h/ N, q" C
        def __init__(self, image_dir, xml_dir, width, height, transforms=None):9 D6 j  e8 m- d; v
            self.transforms = transforms
    / R: R5 @: E. Z( O. r        self.image_dir = image_dir
    6 c$ ~5 M# ~& ^5 u  l        self.xml_dir = xml_dir/ \! G5 \4 g8 N4 v
            self.height = height
    ; u3 z2 C2 N7 _' P2 ]4 W        self.width = width
    ( W- h( Y2 Y5 v+ y, ?0 J4 C3 W1 i  _' B

    ) D) M' @. t1 [2 L  n: U        # sorting the images for consistency' r6 M; z0 b1 o& I" c
            # To get images, the extension of the filename is checked to be jpg
    ) M: p* e5 c, p' c$ t: _        self.imgs = [image for image in os.listdir(self.image_dir)
    9 k  S4 C( e: j8 K1 f' p                     if image[-4:] == '.jpg']
    / i2 A% Z9 h6 \2 a/ J. C! U        self.xmls = [xml for xml in os.listdir(self.xml_dir)
    1 K" U0 ?4 ?& m2 ?2 {# ?; E                     if xml[-4:] == '.xml']
    $ w9 `. z: R* X
    1 C( I5 ^9 \$ e5 p" O+ D
    1 e" w0 o, ~% v
            # classes: 0 index is reserved for background* `' {0 x; N7 `4 x7 g7 \
            self.classes = ['apple', 'banana', 'orange']
    4 N( Q% v9 ^) d5 j1 {
    7 d: [' n; P0 K8 B: k

    ! ], t4 L8 G" ~; G) X& O6 @    def __getitem__(self, idx):5 H4 I; E1 D2 M0 A, p
    % x# R+ _$ f8 j4 t0 r9 W, P

    ( [- d! b, |3 ^( E6 @" V        img_name = self.imgs[idx]
    $ B4 N( a. |) e0 v- P        image_path = os.path.join(self.image_dir, img_name)1 m9 `, y& v7 P

    : @( i6 D; I3 m
    ) |* Q" J- W0 z+ m6 F
            # reading the images and converting them to correct size and color
    ' d: j" B# I$ x1 Z& j  E" v( R        img = cv2.imread(image_path)
    : y, i6 ^3 w+ I; p3 f; @3 X        img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)4 V& W4 B8 O3 m; E9 L
            img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)
    / H' m/ @* Q9 }3 q        # diving by 2552 Z+ K7 E" s* A' u% W
            img_res /= 255.0
    ( k" K+ D4 o+ O
    ! L6 i; f" [8 k) L" p

    8 E$ {2 p4 I5 H        # annotation file
    , g( B5 m1 w$ N$ P+ {        annot_filename = img_name[:-4] + '.xml'
    ( }. x9 F! d! x" d! _5 o4 S- C        annot_file_path = os.path.join(self.xml_dir, annot_filename)
    5 `1 M5 d# D% Y" w0 h, b6 h
    " ?! `$ @! [+ Y

    : C# R$ l+ H3 b        boxes = []6 E( V/ K" H) ^1 B8 w
            labels = []
    " I  ?1 A! M6 z# A        tree = et.parse(annot_file_path)% O, W* g, [" f. m6 t- \% G. d" t
            root = tree.getroot()' Q2 e& d6 b1 Z9 d) ^
    . u, g" F$ B; @2 `# b- U1 i5 P
    / m: P. j3 Z" D5 G5 B7 S
            # cv2 image gives size as height x width
    , i4 r6 L" y% n& z; X        wt = img.shape[1]
    % G0 G. ^# M8 `' T$ C2 k        ht = img.shape[0]- n; }1 }9 {; F* ^4 y: |( a' C

    4 x# F! }+ [3 ^+ l8 e( p! x3 C' L

    ) T% N. w: H) C5 ?5 ^% g! G; U" R        # box coordinates for xml files are extracted and corrected for image size given
    3 y# Q  L+ y5 b4 F        for member in root.findall('object'):# [( D( g  S& K* U- ^) a+ F# N+ T
                labels.append(self.classes.index(member.find('name').text))
    1 h& ?6 f  X7 H4 G! f" O7 m; V" X0 k. l  G! U& B1 B/ a

    # ?# s0 A6 W' d9 g. j1 X0 ]/ j            # bounding box
    " |+ D$ E% P8 ?7 r" C8 g# f' b; l5 M1 R            xmin = int(member.find('bndbox').find('xmin').text)+ k1 k* l: o, L# w  L
                xmax = int(member.find('bndbox').find('xmax').text)
    ) E0 e$ ]/ u: r
    - V/ i: H2 ?+ M# i- s

    7 m" u" U! E% p! r; x# @            ymin = int(member.find('bndbox').find('ymin').text)5 c; q3 ]9 a: q, P" L
                ymax = int(member.find('bndbox').find('ymax').text)7 V# f( w0 D. r; F) B8 U
      J4 j0 X. U( g7 d: _  x4 |, v$ {7 H

    , N7 B7 A6 G* G" e4 G  Y4 h" i            xmin_corr = (xmin / wt) * self.width
    % z$ n# I) {- Q6 R' W( c) c            xmax_corr = (xmax / wt) * self.width( x, f8 z4 m5 u5 F# l
                ymin_corr = (ymin / ht) * self.height
    5 b0 S. A7 O  `% _. \/ A            ymax_corr = (ymax / ht) * self.height& s) x) X" \$ Q- J# B. Z* g) ^
                boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])
    ( z! |6 h; ]5 m. }' R3 {1 @
    , P1 R! P$ Q( x8 ^5 D

    8 h1 j- E6 C' m7 }( h; c( ?* P        # convert boxes into a torch.Tensor* X! e4 D: D- A4 }* ~
            boxes = torch.as_tensor(boxes, dtype=torch.float32)9 [7 |( [9 e) `6 z) w# q
    3 J4 [* ]( n5 |+ w9 f$ L

    " t3 p* _* X+ g9 \3 v/ ]8 h        # getting the areas of the boxes
    * ^" e6 i; O7 }7 L  e  q: m        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
    7 J9 D( |$ `/ Z0 V* u: h- S. y7 G  d' x
      E) |2 W5 F9 ?) ~; I* e
    7 _+ F& _, S9 q  V' S# v% M# R
            # suppose all instances are not crowd
    3 g/ J  A/ e! O        iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64)2 f; Z' [; B6 N
    ' g! ?: x. }" S, R8 ?  i
    + u0 Q1 F0 i/ c; w" k" P5 |
            labels = torch.as_tensor(labels, dtype=torch.int64)8 o9 {( m* }8 E2 ~; C

    - i! @! m/ F8 _8 Z: ~% M* Z  T
    . |' O$ }4 v, }
            target = {}0 [1 u  Z5 C' I5 ~
            target["boxes"] = boxes
    + q: k5 B, E5 F; ]) }) k9 ^        target["labels"] = labels
    $ s3 i+ Z! j, N8 X  e        target["area"] = area
    + {3 W, W. T  F5 F        target["iscrowd"] = iscrowd- V+ X9 ]" Q1 p" p
            # image_id
    * a& q' E0 Y. W7 i" B$ o        image_id = torch.tensor([idx])
    1 P! w* P/ k/ h$ h0 a- V        target["image_id"] = image_id
    & S, z; [  D; b0 K* X
    - D  c, z( c, x9 p+ _; \; M7 W3 o

    " s" x  L& A/ t1 P' r! v0 O        if self.transforms:: l6 |" I8 o5 J, C$ o
                sample = self.transforms(image=img_res,
    2 J5 S* N" N- }2 G+ R5 T                                     bboxes=target['boxes'],( Z5 N/ [# d- @, A  c! @! S! J
                                         labels=labels)7 U3 d+ J6 h5 n4 Q% y: _7 r% X
    9 S/ w" b7 T% q( C
    + X# D# u2 l) W- r
                img_res = sample['image']
    0 i! B$ J0 S1 b            target['boxes'] = torch.Tensor(sample['bboxes'])
    - _) z) h3 s# K6 \5 \) {5 C" e$ }, j( T7 W

      ~0 Q0 s7 O) q' F, V0 @1 C6 C! C+ W        return img_res, target
    0 q% E  b3 J- F7 Z1 \3 M9 p( D# p7 l) f; n5 q! ], p

    - _, l2 E+ X' X. n    def __len__(self):5 d/ h* c0 _9 o5 k' `; c6 P( }
            return len(self.imgs)
    + f4 r  }1 F5 k3 O1 g
    0 U/ [9 P/ B8 ~' w3 D! b
    7 S6 M& K$ x, P1 Y; u) T. K
    # function to convert a torchtensor back to PIL image+ R) h4 ?7 o2 V
    def torch_to_pil(img):, t, V: ^& i! T: N  [/ c
        return torchtrans.ToPILImage()(img).convert('RGB')
    7 _7 Z+ n0 E3 `( L1 T
    , G4 k" |7 H  }4 L
    ! ^- @$ u* O2 J
    ) Z. k; v7 i1 p* Q; n. r$ J
    : l6 v9 M. F. g  @% O7 j8 }' w) B( n1 J
    def plot_img_bbox(img, target):6 E  [% o( o- S" ~! v
        # plot the image and bboxes3 k* y; X6 C$ t
        fig, a = plt.subplots(1, 1)
    4 i( L  C- o( O. \    fig.set_size_inches(5, 5)( f! q0 `8 E; l! l
        a.imshow(img)3 y9 o) Q. t5 z
        for box in (target['boxes']):
    ( }/ }4 j3 Z9 E* ?5 o        x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]
    # C: s  O( l5 c) g  ~        rect = patches.Rectangle((x, y),
    0 a- ^) D2 B1 {: L1 M. s                                 width, height,* W: z( O# B- ]5 l* t+ C2 d
                                     linewidth=2,6 n- a+ f$ _" P; l/ R( V' L) s
                                     edgecolor='r',% `6 w- E6 Y1 z2 U/ ]% n/ x
                                     facecolor='none')7 \% k: y# q; i& d* s0 ?. z% ~
    ! h- S/ b9 r6 @8 p) A" C, X9 d
    : n- j0 ~6 A7 h" s
            # Draw the bounding box on top of the image
    ; _2 Q2 S2 p7 I% p; L        a.add_patch(rect): i: D9 S  y2 Y4 ~3 u
        plt.show()
    1 P3 \/ b2 l2 S* H0 b6 v) J) h# U# B

    1 y2 J2 V- h3 G% H0 s/ d3 p. {; e+ f) {! V: K6 u, E2 Z! c

    3 E& v) F) I3 L4 Y, Ddef get_transform(train):
    ; t& \4 u+ }9 }) ]% E8 C: p- k    if train:
    / _3 h, X4 f/ _  n: e        return A.Compose([. \/ t3 G5 q) ~4 ^' t; {0 g
                A.HorizontalFlip(0.5),. t- D' ?) I2 d4 H+ o. E. n
                # ToTensorV2 converts image to pytorch tensor without div by 255
    4 T$ G- x: Y1 |; U8 h3 o            ToTensorV2(p=1.0)' l9 C1 g; R9 n: n( k
            ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
    3 |& \7 `7 p5 Z8 o- ~/ [$ X    else:
    2 y& b! k+ e+ r  x0 b        return A.Compose([% t( Y4 f- [8 D1 H- Y
                ToTensorV2(p=1.0)! F: Y$ v% Q$ W! `( d7 O
            ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
    9 y1 k1 A+ {0 N1 H& W5 r1 z9 w* J0 C; R" r% F& V

    ' U1 h; C! ~) f" a5 t0 n. \0 J1 n
    % t# X$ S% v5 v' a9 c

    ) [: ^. O2 I$ Z' u0 C  {& w. {6 U9 a* n  u8 w
    6 {4 L4 m0 j5 d) E! }4 S9 c0 `/ p( s
    dataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))/ M$ K% @( A/ j8 E7 P1 p
    3 ~8 W* g( L7 R! v1 }! A

    ) ^% S  y: ?2 g0 x" t4 L) Xprint(len(dataset))
    & _$ \3 [5 A& T, ^$ A# getting the image and target for a test index.  Feel free to change the index.
    $ j+ l$ ~' m0 |( n$ R& [8 Aimg, target = dataset[29]  B% x4 I# d% q. q! r/ ?1 f
    print(img.shape, '\n', target)( }, E# W" O5 T: J; b5 _. m
    plot_img_bbox(torch_to_pil(img), target)
    6 \3 F, U3 `& B+ g5 s13 T1 b/ y# s$ N, X; l5 e
    2" N5 |. v; z1 q+ w& v
    3
    0 V+ V# A0 H. x% I" V( r' m4
    7 `( r9 F0 \) ?; I9 T/ a5
    ( {/ Q% I( ~! i3 A) u- U8 J6
    + I3 c1 u1 f5 h; M+ k7" Y4 t  O  V0 M4 m  E
    8
    & k0 v# J, v- H7 u& }" L" a2 |9
    $ R; ~# j" }/ j10/ J4 @0 l( j, {7 d( E1 d
    11
    " D# W! q& _1 k8 }8 s9 }" z  Q* N8 x4 [12
    ! Y- A) c1 A& J2 o13* G' q7 ~) k4 @3 o8 y+ b" G
    14
    % ^7 ~/ S, M* T6 S4 d8 _15
    / i  d; r: l$ z; r1 x( @16
    ; z3 k* I2 n) N/ Z: S( ?, [17
    6 _: O  l$ e( K% }! C; c4 h18
    ! U* L, o( M: u" Q0 @* \8 g9 H+ S196 e8 m! Y, H! w" Q
    20
    & a; ]" w1 [2 \) r, G; d' N. d210 }& L1 H! n& D
    22' B# ~- d$ P0 @1 P! r6 l
    238 C: \/ P; z( W! c
    24
    + W8 _) t6 ~* A25
    + D, n3 @, d0 _2 q5 J8 b8 Y264 A' A( @. X9 Y
    27
    : s2 Q, d! y& A2 A) T+ |280 ~- @+ E9 K% p6 ^: Q" e
    29
    & [4 m3 L$ P% r' t7 E308 H/ J3 X2 ~1 b& _6 d
    31  [/ a1 j& z4 O  L" {8 f5 v( s
    32
    # ]; P8 ^. z- _33  ]$ e1 q1 T4 _( q
    34. z8 v$ P* O, G8 @3 X8 n5 G7 [
    35* V4 n, @1 \1 O% @' Y  n" L# g
    36
    ; [, p4 ?( Q2 g6 ~3 _" m37
    " d% l. X( h! P* {$ t0 r" g389 K) q3 h* ^/ o9 i# z
    39
    8 C) q4 ?0 C" r3 Z+ M- G3 T40$ I4 H+ q2 h1 {: E4 p1 ?( t
    41
    - Z  y2 o' y( X+ O# `& R42
    # a! C2 O0 T. e; E43) b4 q- X! g2 y/ \+ U
    44
    : g# L4 L( c' a2 r0 n8 L) x* p45
    & f- A$ E0 Q" ?* v0 f2 P46( `3 M+ k% d# g" W, f9 g6 ]. E6 `
    47
    ) G5 J- U* w% K489 [. U5 M' o/ p
    49
    9 \; t! Z) H# v50
    2 M9 ^8 b1 @6 V0 p! B4 B: Z51# l, M) Z8 F8 V2 _; s
    523 d' Q; u. R- O" ^( j( ?
    532 v7 ^# a9 p% }5 p0 Z% ?: @5 R
    54( A5 R' W0 V& b* i% T. b2 u
    55) @* g2 I4 i! q- z7 ]. y$ ~/ Z! O4 {
    563 p: j( I; B+ H. a5 ^2 U
    57
    * o6 g4 o8 U* x: J58
    / x& P' C. s" t3 {! z! ?7 {2 @59. l! s1 r  `$ x( p+ I" ^* r& E/ N$ x; P; Y
    60: T" Y( P6 O$ k  Q$ E* v
    61
    0 I3 {6 e2 s6 b5 y625 R9 L7 k( K  M
    638 }1 j) A+ v; @* h! n
    64
    2 T. _: J8 @+ L+ d. d$ y  {2 \65
    1 j3 N" p1 u7 \2 m66
    / N4 d% s% q; U% Y. P+ {67& a9 I) {) |7 H- L7 t2 v
    68
    , x' I2 r) [4 A+ [; E$ O3 o69
    % z# {9 z, b4 u9 i/ N/ A/ C' ?: R70
    + q6 e$ {1 }# e, B7 z. _718 Y1 N$ p1 q9 l
    723 E, F) j# R4 l7 f1 V! b) O8 K
    73
    * V3 A5 \( r! u  e8 w74
    - W6 Z! |# ~3 r- [9 k( j75% I2 o, @& A9 _1 L2 s
    76
    9 ?0 D0 J" m  W) @4 W, {9 ~77
    6 J' X7 R7 t! N. l78
    7 A0 r: W! }8 }+ K. y79' U6 w' z3 E; m# I* D
    80
    % A" p3 f7 u& B: Z" N81
    8 F' ~% o' M" G  F& c82
    ; W4 G, O; \3 R7 A83. \. J& C& o8 X" O
    84
    : L) J, y8 X; b( N5 V85# N1 o. E6 R7 [$ e# e- @
    865 l) p5 {9 l- K0 s
    87
    + Z7 G' V* L/ F5 v881 D# ?9 K+ p$ W! Z1 M$ o- l
    89' B3 \  ^3 i( E2 \, G
    904 r6 Z) W/ n. l6 h; i$ I1 v
    91
      e0 @% V  K8 C5 ^+ P6 s' N5 o# A92
    " N7 U$ p: K, m! ^6 {3 p93
    - s, u8 z* z( s" N5 A  b94
    7 s  h  `" g: H95% y  P% F- q/ A
    961 h, E. T& K: f
    97
    ' @" W- z& m5 [5 e98
    5 P5 [- c& u$ G+ d( h+ Y% \99
    0 R5 ?2 E# M9 R100/ k1 R2 x8 x: ~7 t) ^
    101+ C/ M" a) t9 m+ z& T" X( Q
    1024 [* l3 T: U/ b1 h1 a' k- ^
    103# b6 \0 T3 a% ?: r+ a
    1042 r  @! Q& o% H, q  ^
    1054 C, p9 D4 F7 B3 V$ I8 L
    106
    1 h# p7 N- j( _- S6 H107
    # u1 B* g9 y' h5 x6 J2 @) J108' g5 N9 R# ~' H( H  @- z% @( t2 A+ I
    109
    % I$ s1 [. ?, |- ~. E7 v110" o0 P3 n7 `3 D
    111
    , k1 g) @+ V- F/ f8 y& I+ G112
    5 a1 \  Y5 W% P7 q1135 p  F3 w, M# H( j2 h. }& x- [$ S
    1148 ]5 c' ^' N3 _2 N: p
    115
    0 s% ?- w( f# C; G" C) I% F, Q$ O116
    2 [/ x" G" e+ A4 s( V3 ^  s% v1172 O7 e. `. C2 C7 U. e6 E' _8 A9 G
    118+ G# e. L1 W# g6 E) @/ Z
    119  J0 Q* Q. x  {: [
    120
    ; q5 S9 S6 V: j7 s3 N3 j1 c7 ?; N121
    , G" P! \; _: L, c0 O9 ~122
    " \9 R4 @2 p2 l" D123! H/ p3 M! H9 V! b$ X6 v/ u
    124
      t8 t) T8 x! @: W: L125* A' }! C) v$ F2 q" V
    126( V4 R1 |1 b/ t! ^
    127
    5 o5 }4 I0 w  C$ [5 j' B3 l* U128. f* g0 B1 j& m  q0 P  }
    129
    6 a" Y+ O5 ?) s' I4 w4 m130+ x# x3 j8 G, y, K
    131
    ' z# ^* [: `9 @. A4 U9 s. r132" k0 A! \; R3 L
    1337 G0 c  f; Z" z5 Z: D1 o
    134( P$ D/ D. |  I  `- I8 j
    135* {# o7 E3 }* \: |+ n2 U
    1367 Y# m3 u' A, l8 h( O! ~
    1370 H7 W/ p" u; z& i& W/ \
    138( p, O) ]/ t+ N4 q7 C
    139; Y- i! f$ K  p  T; N3 S
    140) |8 p" \* O0 M6 |% }
    1413 H) r3 [1 S2 l% @8 D
    142% @3 J$ T1 c3 r6 u6 X" B* h3 }
    143" n: }) }0 X5 ^3 X
    144
    & |. X/ O! T6 R) a6 r' \145
    , U6 o# q% E" ^146
    # D; M4 a1 M# R( T3 V4 O0 e147! R  m( q  X. R$ _6 S3 C
    148
    4 h' ~# {  M% B7 n1 U* `149+ _. \. o& @' W/ _/ h* y
    150+ V9 g  p' v% Q$ |# }
    151
    # `5 ~8 X  H3 R8 R152% _, o& ~- ]4 Q; [. ^; i- ?
    153# u5 n2 I/ h  l: C7 b
    1545 H  [4 |' j% p9 |  F# e
    155
    ! I( b% F5 G1 m' ~# T156
    % `+ p/ y/ x- C; b  y6 K输出如下:
    ( {8 N7 O  u5 w+ T( w" s, A( y# F& g: |  f. q+ V: Z! @

    ! a; o- W3 Y- B- J$ Y+ Storch.Size([3, 480, 480]) * F* W& L: V  `0 p' R% H6 c
    {'boxes': tensor([[130.8000,  97.8000, 327.6000, 292.2000],% M$ B' n! Z% E# D
            [159.0000, 268.8000, 349.8000, 427.8000],
    - w: |2 I) H; x1 a# n" V& b        [  0.0000, 282.0000, 118.2000, 429.6000],
    - I  d+ Q) W. d        [ 43.8000, 107.4000, 199.2000, 280.2000],3 y& y- X- y! f( |) w: l
            [295.2000,  37.8000, 479.4000, 248.4000]]), 'labels': tensor([0, 0, 0, 0, 0]), 'area': tensor([38257.9258, 30337.2012, 17446.3223, 26853.1270, 38792.5195]), 'iscrowd': tensor([0, 0, 0, 0, 0]), 'image_id': tensor([29])}
    " Q" q* f3 L6 L7 N5 {1
    % ^" h9 }& D! V8 C4 m6 {2
    # O$ ]# x1 `4 q# s# N1 @9 r34 e* x" M1 L  b
    4
      W9 U0 X" o: C3 L! x' v7 S2 k5% j9 z0 H- N1 \, e* i
    6
    " j6 e6 }7 W( d5 z! u6 S: h( \1 E$ ?5 a6 K3 q
      `- ^5 H8 O* e/ v1 x/ R& r
    ( i5 Q# h/ |  B% Z/ m( E3 \4 S
    & |) h2 u0 e' ^9 [
    下载地址8 q) Z% Q1 Y* u; e5 f" j: F
    链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw+ f1 h3 M9 S' F7 m- t/ J
    提取码:srjn  t; P' [! p# P/ e7 a
    ————————————————
    ' K5 Y% M3 Z' G/ J8 \版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。3 m, ^0 g! s  B2 m
    原文链接:https://blog.csdn.net/weixin_44510615/article/details/1184962733 a$ m& k7 E4 O$ h
    " j8 q0 K2 a- @1 T1 a
    ! j" L# K9 u2 j5 D
    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-7-28 17:04 , Processed in 2.002815 second(s), 51 queries .

    回顶部