QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3530|回复: 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
    5 O; G5 u7 w$ t: p! z
    深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息
    - o; m" z+ @$ m, F% Q$ F( s图像标注主要用于创建数据集进行图片的标注。本篇博客将推荐一款非常实用的图片标注工具LabelImg,重点介绍其安装使用过程。如果想简单点,请直接下载打包版(下载地址见结尾),无需编译,直接打开即可!
    0 |6 ?1 U/ o* v0 \6 d) m9 w4 g+ M5 ~/ Q& P. a" r8 D
    * G1 ^! d3 ~0 f8 G
    感谢原作者对Github的贡献,博主发现软件已经更新,可以关注最新版本。这个工具是一个用 Python 和 Qt 编写的完整的图形界面。最有意思的是,它的标注信息可以直接转换成XML文件,这和PASCAL VOC和ImageNet使用的XML是一样的。3 u. c0 ^% r# K* @) A: j0 b: F

    8 }3 b- ^& K% `6 _, v6 J
    ' C5 [. S6 \  k9 y; o
    附注。作者在5月份更新了代码,现在最新版本号是1.3.0,博主亲测,源码在Windows 10和Ubuntu 16.04上正常运行。$ d8 d, f5 P* X# D
    5 _+ Y; t7 ?3 S" F8 E

    $ |) B2 L8 [3 O5 E0 A; C8 C, N具体的安装查看Github教程:https://github.com/wkentaro/labelme/#installation- g, x" U- ?6 [( z# A& I9 ]& G& h
    ) t. D: R* V2 I+ B( [& S
    7 V6 Y+ g) [- ?$ V" B( Q+ O/ k
    在原作者的github下载源码:https://github.com/tzutalin/labelImg
    ( n# q4 l' E: V1 x/ w4 G。解压名为labelImg-master的文件夹,进入当前目录的命令行窗口,输入如下语句依次打开软件。% E2 G+ |! \2 G0 F
    % \/ i# C/ x: F; U# \7 x
    3 {( Y5 g+ r/ n! U1 y
    python labelImg.py
    2 V- g* M( V8 h0 K: u17 c3 K- r- S! b( _0 e. X7 Z+ R

    7 b! W8 z$ P$ Y! ]% t* S, B

    / |6 L* g8 M& k7 ]. n9 p0 D& _: r' O  u" a1 u
    & f* c1 T* s' d
    具体使用
    3 p+ r8 _* K# P  i8 P修改默认的XML文件保存位置,使用快捷键“Ctrl+R”,更改为自定义位置,这里的路径一定不能包含中文,否则不会保存。( y# ], b( J! r2 Y2 G/ Q# c
    ( e1 d- c; _$ h

    2 T* [- e; v' i+ R# p使用notepad++打开源文件夹中的data/predefined_classes.txt,修改默认分类,如person、car、motorcycle这三个分类。
      l2 _" F* p* e/ p! {
    % T  p+ W% G- Y& k9 M' Z1 a
    ' y. z7 Q; E- U. y9 |- g9 o/ Q0 B
    “打开目录”打开图片文件夹,选择第一张图片开始标注,用“创建矩形框”或“Ctrl+N”启动框,点击结束框,双击选择类别。完成一张图片点击“保存”保存后,XML文件已经保存到本地了。单击“下一张图片”转到下一张图片。
    5 f) Y7 e8 p$ A6 g: h
    5 Q4 M. |: I6 ], a4 E

    ! \; u+ V' u5 Q; I0 l贴标过程可以随时返回修改,保存的文件会覆盖上一个。5 @0 P+ k$ r* y& @4 ~+ p0 P0 |

    ) e! x) p& v. v7 @# I; n
    2 o+ k( w2 |% [
    完成注解后,打开XML文件,发现和PASCAL VOC格式一样。( T. {6 A9 F4 Q: f; [; O0 m$ D

    5 L: r; Z, Q' K8 T9 F- L9 a
    ! [: |' a5 P& q7 f
    将xml文件提取图像信息6 \/ W6 m8 E9 e( p- A" H" T
    下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。5 Q) F+ _: E# B! S) m" ?
    & P* F( [8 m+ h" T3 i
      X, M; Q; y6 C

    1 d+ S5 E9 p2 w0 W

    * ^! D- j! _0 J7 j7 H下面是images图片中的一个。# n; U3 `, f, V1 K' W

    2 j; a; F! o( J6 Y3 `

    $ b8 l' p% W9 L. Z2 ~) j' K7 F( z下面是对应的xml文件。
    # m: Y6 N: S0 x' N8 ^; d
    6 y& _( L/ R7 f7 [! D8 Q2 f; O; @

    / V0 }3 v4 k( D8 Q# X/ S; P0 F<annotation>
    % Q: v5 N* E. e! F/ u" I        <folder>train</folder>
    # e( b  A  H7 y8 K  D2 T        <filename>apple_30.jpg</filename>
    1 [$ r# |  b; E2 L6 ]        <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>
    : m& ^# S- B( `# q  O5 `6 |' W2 ~6 L        <source>
    ) [4 g' G  u4 V: Z8 q7 k                <database>Unknown</database>
    1 P0 G* J3 d% Z2 v/ U' o  o        </source>
    , {* n2 v: a: {3 Z        <size>4 e5 V& e# B, y; w) Y
                    <width>800</width>" b# C3 b+ H# |* Q& [3 e+ k
                    <height>800</height>
    4 V/ v8 k- h/ S; }                <depth>3</depth>
    ' N1 W8 ?1 k- n6 Y. J) U        </size>
    ' k( y1 N) ]. s  q: C# G        <segmented>0</segmented>& G: M/ T3 C3 L
            <object>
    & H6 {  n; N) n+ y$ u" x, Z2 ~                <name>apple</name>
    7 V! b( S, A1 S( H                <pose>Unspecified</pose>  O" C- R& L  \, M( x+ s' J$ {
                    <truncated>0</truncated>
    8 u" l  p$ Y+ v& k- v) l9 u                <difficult>0</difficult>. W! e- ?: D7 p4 _
                    <bndbox>, K( d2 Q" `5 X5 W( K$ u' P
                            <xmin>254</xmin>
    % v/ t! E  K  z8 ^                        <ymin>163</ymin>
    0 V  t3 ]  }" j2 @' c                        <xmax>582</xmax>- S" t. x2 w- x2 T- T
                            <ymax>487</ymax>
    3 }6 d( V! y9 t& ~) M8 {                </bndbox>
    9 w& e$ M8 j6 Z# E        </object>. Q, w0 ^$ O+ n$ X9 _
            <object>
    + L1 F" A2 n4 s  Q& |. g+ Q7 s+ A                <name>apple</name>& T: Q  M9 e6 ?3 T5 B' g$ b3 G5 h7 J* H
                    <pose>Unspecified</pose>. M+ h; U* q7 f% M5 S/ R
                    <truncated>0</truncated>
    5 ^7 {1 b  {$ _" a                <difficult>0</difficult>) S: ~, j/ a" u, Q5 _
                    <bndbox>
    2 Q6 j/ ]" h# y7 O' ^                        <xmin>217</xmin>! z( `0 b9 u& T9 _
                            <ymin>448</ymin>
    / f% d. T3 _* Z. H% I                        <xmax>535</xmax>
    : y  U9 N8 Q5 j3 \                        <ymax>713</ymax>
    # s/ Q- t; f! L* E# t                </bndbox>
      Y5 i& L. d, b' V7 L6 ~        </object>
    . @6 f; T9 }, s  w        <object>
    , X2 U  v6 f. M7 e. t                <name>apple</name>, [3 q. k  E' H- s
                    <pose>Unspecified</pose>5 \- i% Z0 h/ B+ }+ z
                    <truncated>1</truncated>
    ) z' P% H* G3 G' D2 A                <difficult>0</difficult>
    , v5 ], E( i2 q; J                <bndbox>3 R, E: P1 {9 k' ]! h
                            <xmin>603</xmin>: P! P; T# j& x  T5 `
                            <ymin>470</ymin>
    4 K* Y# v; w/ {; i$ K" |                        <xmax>800</xmax>
    * I  p6 A  C6 Z  \                        <ymax>716</ymax>
    2 G0 G6 R) d$ t, o, j                </bndbox>5 g& K& V! p' I  E
            </object>7 w2 y& `; }& Q4 D: B+ t7 v
            <object>; m! D+ r! N6 s* j
                    <name>apple</name>
    " J- h$ b, V; ^& n; x. Y                <pose>Unspecified</pose>
    # I; V3 ^/ F4 G                <truncated>0</truncated>/ U3 e/ r8 H% n
                    <difficult>0</difficult>
    7 O& P1 b/ c* c: B                <bndbox>) l2 E# I) J0 e. [
                            <xmin>468</xmin>: g4 k" c# D/ P  s- K& g
                            <ymin>179</ymin>+ k8 H- P$ h/ z5 c# \6 m. v; R2 s2 S6 i* ^
                            <xmax>727</xmax>
    - D6 `% d% B" @2 e3 v& p; _                        <ymax>467</ymax>
    6 `9 ~. p8 A+ I& _4 z0 j5 w                </bndbox>
    / U: }( |% Q: D3 W8 X  l        </object>
    + ~- F& T/ H& G& S, r        <object>
    $ z! x5 A& T- h                <name>apple</name>
    1 |* X+ m/ T+ h) m- q" @                <pose>Unspecified</pose>7 J3 ^" \. c9 h5 r: `. G
                    <truncated>1</truncated>
    ' t* p8 d; q! F                <difficult>0</difficult>& J3 Q1 B  w% [- w' W
                    <bndbox>6 q' Y6 y0 E$ d7 h# Z8 c( h
                            <xmin>1</xmin>
    ( t; b2 W  R# C) u2 g7 F$ I                        <ymin>63</ymin>
    ) ^. o" J6 N4 A% y+ J; p9 T, R                        <xmax>308</xmax>" E$ B( D4 _3 z4 h; S# P" ]
                            <ymax>414</ymax>2 B& w6 u- _, f9 U
                    </bndbox>
    ) I" Z1 z$ b3 [: F2 h5 M        </object>8 Y) d+ N: g# @5 V* m% x
    </annotation># U* S4 q2 J: C- {. S* S( r
    1; y$ k' `0 I; o1 x, R* {! k+ F& O1 a
    21 P1 \, k2 E" ]8 ]: P
    3
    3 Y! j$ n. V7 ^1 M4
    3 Y8 T1 Z  r' ]+ G5& I  E' [6 ^7 Z, N' @
    6
    " u3 }5 s+ p' K% U4 z! ~7
    7 d# q- O+ `3 g( P* I+ ]. o* T! a1 C8
    ' A( X# r$ [8 H. m; r4 y90 `4 y% m% F, `2 C
    105 i$ g. B9 n" w% s4 R) T: X
    11; @9 g& p9 m+ d, G, q
    12
    ; H# g% ]5 |  \2 U# e' K& {13! D6 L# j+ L. @1 S3 m1 F
    147 \* ^' _) ~: U3 c* `) _
    15
    * z$ b7 p" M0 V; O16
    ( B: s) Q  y% C4 A2 H8 A17
    ! g( e' r# ]: w18
    2 s5 V$ {1 R8 o3 B2 u1 Q194 Q' }7 E. K) C; q5 N
    20+ E( y6 m9 j. o0 b( ~- _
    21$ e' q6 n3 _7 M1 y- _8 @
    22
    8 g$ z, W" |9 ?0 A) U+ Z: D232 w7 ?9 _0 ?' a- N8 l
    24  S2 E( y  ?9 K6 d8 s: O5 d; Z
    25" h) z9 |& o- D3 I- F( j
    26: i7 h; U/ z7 I: x
    27
    8 K' r  m1 J& D( X4 G3 L28
    # h  P/ S3 ]/ L8 a- @29
    / N- f+ m, _! k& P+ o7 V30
    : z' @6 e: N' R31* @( ~; }* P" {
    32
    . y- t- U' q- W8 |+ C33( s% P4 E$ b$ A: Q" F0 Q. A
    343 `/ k) b) l) j1 N
    35, ^5 q7 n# m8 a5 V+ t1 s7 O" |- s
    36
    3 f- y+ Q$ Q7 [" H" o- e37
    3 O6 x" m' N  e! x; N38% A& F% R; z) m1 ~
    39
    : Z2 t( M; z$ ]& `4 ?9 `# N40
    " I! \/ r7 v) s) N: j+ M, l" V41
    ) W  C2 {8 ?) x; w: M' ]" h, ?$ \421 a9 t# k- d0 G% m3 J
    43
    * `/ t4 u) c3 U1 [445 H2 |! w  p1 x: F1 H+ {
    45
    : U; ~. V. A  U46
    0 g8 N1 q& b5 L) c. @0 ]# g, `8 ?' A470 g) E: Y5 T+ h1 K" _
    48" [" p* u: [9 E
    49
    % s5 N; f2 E" j$ e: f" c- q  `50* I8 G/ \  s! s+ P
    51
    : m: \; Q4 d. y0 s52
    5 L0 F+ N) G' \. u" T6 |53
    * ^/ b6 W! |% W) J$ V( r54
    - @4 I/ i# y) D/ V& s' {55) v% H5 I6 V# {4 @
    56+ [3 X. @0 F& u* E6 k
    57
    . M' Z' n/ m1 M58
    % S8 ?/ _  h! p+ h59( E5 B( y" j! {" w* q! T
    603 [  e; s. h, g7 ~
    61  H0 e1 J# Q: d: S4 C  |1 Y8 c: ~
    62
    * n7 o3 s$ ]) A0 F* \* u1 q7 y63" }2 y$ M0 L& a! h: W# ~' I
    64& k  q& A! X. V& J* c' T
    65, \+ T5 U1 y1 s4 y! ^9 i$ J5 S
    665 _+ t& l- }: w) G! ]
    67, B1 \) \$ {+ r+ e2 @6 s
    68$ s  r) m) K7 d! D( u/ I5 U3 b
    69
    ; K  u! q# x7 H$ t/ F8 H70
    7 o/ ?5 j* h3 t- |8 w" @3 ]% Q71
    4 `& A* a. E' A' P- H  z3 V, a72
    # p1 z$ E5 }$ m+ V" U73
    6 ], W: b6 d# C' S. [741 `8 V: a( |/ j  F) V1 U7 W- O5 T
    将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。: H( L8 P3 |5 K) A8 B7 Y$ f

    , G9 y; |- Q: K
    % D9 A7 p1 T- l4 d9 S. O
    import os* {* a  ?8 A( w2 H% T4 V) t
    import numpy as np
    # F4 D# |+ |* R$ Timport cv2
    " K7 E8 K8 W/ ]& Q/ rimport torch( B) k+ ^$ g5 x& g' N
    import matplotlib.patches as patches
    ) o' B# D6 h; x! n4 R$ y$ Y3 H2 ]import albumentations as A
    1 w  O5 A- y* R! h1 G3 c+ o( zfrom albumentations.pytorch.transforms import ToTensorV2% f. }9 [% Q% p- S
    from matplotlib import pyplot as plt
    - @1 T% z3 j' L, r' t  D3 Kfrom torch.utils.data import Dataset1 s5 k7 w+ p) o+ J: |
    from xml.etree import ElementTree as et
    * N) u) W5 C0 [+ w( b* rfrom torchvision import transforms as torchtrans; o$ c  E0 e$ O$ f$ n. Z
    / K% Q* R, O+ x4 r1 v6 [. Z- i

    5 A9 V8 q2 y/ r# defining the files directory and testing directory6 J, _9 t- l+ D# o3 E
    train_image_dir = 'train/train/image') C0 u% N; T# @
    train_xml_dir = 'train/train/xml'2 r4 `8 v( y) L
    # test_image_dir = 'test/test/image'# ~6 Q* Y9 @1 z# u) i
    # test_xml_dir = 'test/test/xml'
    * j: k) n- l4 O; i! r  R+ B! ]7 G, y! F

    ) h3 i3 S5 r# V- qclass FruitImagesDataset(Dataset):
    . }5 E5 u& c* r$ @- Q/ j& s! a2 q8 W+ D( |5 f6 r

    4 |: P. B. n" a' o" Q    def __init__(self, image_dir, xml_dir, width, height, transforms=None):$ ~4 |% L7 d0 R, B, c
            self.transforms = transforms
    ( u1 A1 ]0 n) X3 X% p! }0 w        self.image_dir = image_dir( U( c- U5 q4 F0 ^  K% f! {
            self.xml_dir = xml_dir/ P5 _3 ~8 W1 {/ u) A+ ?% S
            self.height = height4 s+ j  E  @( Y
            self.width = width& X$ O$ @1 a6 L: B6 G

    % m# Y4 @' d" F7 Z( x

    + c8 H. I- _1 W% [0 u5 e) E        # sorting the images for consistency) m+ v6 r1 M# N4 K7 B
            # To get images, the extension of the filename is checked to be jpg* b! f) r+ d5 f2 o& [
            self.imgs = [image for image in os.listdir(self.image_dir)
    , z: p2 a! Q6 U3 n- E                     if image[-4:] == '.jpg']
    5 \& {) \+ z( ^: L        self.xmls = [xml for xml in os.listdir(self.xml_dir)
    # k% i, w5 c6 J' W9 d8 Q                     if xml[-4:] == '.xml']
    3 J2 P% v& h, J1 L! c/ H9 ]$ f! P- Y, y7 c/ ?7 B

    5 d5 g$ {* D! T# ?. i& g        # classes: 0 index is reserved for background+ @  u; C" F  D, k6 y. j
            self.classes = ['apple', 'banana', 'orange'], q" b8 t$ K0 D. E) ?( {% \& T
    4 W& v% H2 X1 T
    . H* u8 s1 `9 O7 Y# m3 k
        def __getitem__(self, idx):
    , K& L8 L3 _& O  q2 u0 Q* ^! L8 ?. |4 ~& k1 ^; a

    ( v8 ?  [& g4 J9 L) N& p        img_name = self.imgs[idx]
    3 p+ a1 Z% N* c        image_path = os.path.join(self.image_dir, img_name)9 ~) O) Y' O$ ~" _  W; C; k1 f" n3 E
    / c' s" I& P& s

    ) K# X; h, ^0 G5 G        # reading the images and converting them to correct size and color5 h4 k8 m- I: X* u5 w
            img = cv2.imread(image_path)9 @+ }$ Q% b+ A7 X& o
            img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32); X3 A  d, }- F$ X
            img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)/ J5 v: f) V* O5 Z" l
            # diving by 255
    6 x% i0 U! Q& g& c" P9 g* I/ E" n        img_res /= 255.0
    0 A9 V2 u- M% w  }7 i2 |$ }5 s/ H  N! y4 Q3 C
    2 L8 B/ P: K2 F9 |; F. h9 l
            # annotation file
    6 c+ b$ f* l+ |        annot_filename = img_name[:-4] + '.xml'+ w& i8 \5 f& W: N1 @- I
            annot_file_path = os.path.join(self.xml_dir, annot_filename)* H( K, [6 a" p$ U8 I+ _9 d1 a3 n
    8 X) [9 O. L5 g- _6 M+ o( B! S4 `

    , U& l, F# _7 _( Z+ n4 D        boxes = []
    . z, ]1 R3 d8 I        labels = []. k2 c; \% f1 c6 ~$ [  R
            tree = et.parse(annot_file_path)& y* `( j" e# @
            root = tree.getroot()
    8 ^, X: p! ~6 h3 e! X+ L% F/ `& E4 X. R
    ) `8 K. X" E, M# s& {9 ]
            # cv2 image gives size as height x width
    $ ?5 N4 o$ n3 O0 N1 `+ n0 N        wt = img.shape[1]
    . \$ q/ ]! `) ]) U" Y8 [" E4 u        ht = img.shape[0]
    - |% ~+ x" R# |( ~# p) u" Z2 U9 e. p- L. o1 R2 x, }/ Y
    4 @, u& z9 H$ T
            # box coordinates for xml files are extracted and corrected for image size given8 n+ s+ Z# z/ [( j. d( m
            for member in root.findall('object'):
    ' R& H: f9 ?9 `: P$ o8 `/ J0 X            labels.append(self.classes.index(member.find('name').text))
    , M  i, l: d4 w) G' [$ I1 |3 N" K. y! T4 D/ V; Y3 l
    ; \8 [# i/ y; c/ F7 [, A
                # bounding box
    " [' b5 @3 ~+ L% b' t6 E            xmin = int(member.find('bndbox').find('xmin').text)
    $ T3 h5 x) n/ C- J* y- L            xmax = int(member.find('bndbox').find('xmax').text)
    $ x7 \& G* _/ V
    6 w6 e8 e/ V( E* f# i4 P" F

    . y  d2 I# [% @, C! L/ ]            ymin = int(member.find('bndbox').find('ymin').text)
    + l) L+ l. ]) B7 ?8 G& V+ E            ymax = int(member.find('bndbox').find('ymax').text)1 a, h1 {6 ]6 {: U+ K$ M
    1 l! U4 H; E, |+ C: {( d8 i

    % R% B+ z+ r' B# f6 [            xmin_corr = (xmin / wt) * self.width8 S2 I* W- F, Y; u
                xmax_corr = (xmax / wt) * self.width( E0 k( R# I+ [/ x. U  }- H
                ymin_corr = (ymin / ht) * self.height# z$ f8 q' ~5 \2 I" }6 [' x
                ymax_corr = (ymax / ht) * self.height3 y% [2 P& F& |
                boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr]). O0 f* T9 \( M
      P  ^) x) U+ T5 M6 n. e" F3 Z

    # {' g3 {* ~' e" y8 @% Q( E5 H        # convert boxes into a torch.Tensor; O+ K$ w/ A1 E( o) m* ~2 E0 y
            boxes = torch.as_tensor(boxes, dtype=torch.float32)
    - k# S' R* a' u  ]& R' I5 G8 Y, V7 q" l
    ; {3 [- t& @3 H. H& C& S6 ^% I0 _
            # getting the areas of the boxes. @3 Q/ W7 O9 Q( h
            area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0]): M% \1 S+ z  H4 @" D

    . ]  S6 N: M- Z9 r$ Z

    ( Z5 O. U, m, k" j- ~        # suppose all instances are not crowd
    8 C4 g) N; I  }8 c2 `8 s$ G# y        iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64)
    ) I4 u" ]# \' L) k/ i& v6 U1 e4 e9 X3 }& E! W2 _

    9 m" L/ _8 e* G3 X% Z9 P        labels = torch.as_tensor(labels, dtype=torch.int64)
    + ?$ Z) m& _( n2 `" \' v- e5 Y3 G
    # q% I2 C" f% |( Y! A: A8 W+ F
    " `" o. `5 D9 _7 |* G
            target = {}
    ! E9 i6 H* s- N& t* Z- q        target["boxes"] = boxes  {; c* x# d: p
            target["labels"] = labels# P- L3 t* I1 q3 J5 `- Z$ f# G  ]
            target["area"] = area
    : G1 e# l" f* f- v' K- R( z        target["iscrowd"] = iscrowd
    9 a) B) O2 h# I: D5 L% j        # image_id
    / d; e, e( C6 S7 I; L        image_id = torch.tensor([idx]): n6 {8 D; |( \- a4 M; h
            target["image_id"] = image_id  b' F% ?3 \3 _0 w, w$ D1 f
    7 e7 C. [. K9 K4 H3 _2 G' a1 I

      J! r8 _' n8 h7 ~: N, I        if self.transforms:" Q/ I& p/ C) [$ s) \  \& R
                sample = self.transforms(image=img_res,
    $ }0 |- q0 w: Y% F7 f' |0 S( X                                     bboxes=target['boxes'],+ P" x* d! M! O8 f4 M; ?# o7 k6 W
                                         labels=labels)3 ]" {; K8 }3 O0 ~
    ! B8 p3 d$ q* ^9 q# d* _7 a+ F' A

    + _' s) Q% b# L( t            img_res = sample['image']! |  E; g" _6 T: K& n$ J
                target['boxes'] = torch.Tensor(sample['bboxes'])$ v2 E& M2 _0 \3 l8 N5 {' m5 |
    / Z( t$ J0 t& g# w

    & v# C# R* u# \) V: M        return img_res, target3 m5 C1 E9 g/ |: C" b
    ' q( {: a0 l3 B: d

    5 C) Q% C( Q* h* ^- g6 `2 y    def __len__(self):
    ! j- q- L" _9 P        return len(self.imgs)
    ! \. p( I3 P8 m* C. p$ Q
    / E3 V- k$ H5 a! R; n* N; r

      _) C( x8 R$ P& Z7 A! h  b. K- F# function to convert a torchtensor back to PIL image5 W, F6 @* S5 U' K" d9 ?
    def torch_to_pil(img):
    % {& ~7 p1 n0 T* @: a3 @7 V" X    return torchtrans.ToPILImage()(img).convert('RGB')0 \% a6 X6 F' L+ w

    ' ^8 c8 _) w+ s0 f5 d; K( v5 v
    7 U0 V8 z2 A: H

    + F; z' d/ ?2 r) ~+ K/ |
    6 c3 A4 C' D8 ~0 m' n' L& R4 [! J
    def plot_img_bbox(img, target):& W" n: K  v* u1 Q: ^
        # plot the image and bboxes
    ; p6 t, D/ E) F8 F" z9 ?    fig, a = plt.subplots(1, 1)
    . O! U6 g5 m2 I. [  Y) O0 U    fig.set_size_inches(5, 5)
    * I) H9 x/ f6 I    a.imshow(img)
    6 S" D, z% L6 i3 P    for box in (target['boxes']):
    : s  `6 {" U3 y( l- [1 I# H2 C' f        x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]
    " A) \, O# O( e9 n  D        rect = patches.Rectangle((x, y),  g  J% P* X1 \% p4 v+ u+ n
                                     width, height,
    , f0 P0 ~2 c! L& c( `# B- m2 g                                 linewidth=2,1 i5 x1 L! M* y3 T
                                     edgecolor='r',
    0 H! p+ d2 Y, J8 w                                 facecolor='none')' g7 h; o5 l5 e8 e  v* t5 N) `# ?

    0 h' n) U5 b5 [) o5 B
    $ k  N0 A+ z8 c6 \
            # Draw the bounding box on top of the image2 C) q# @) D1 ^* I7 }
            a.add_patch(rect)' _, R- F) A& U+ |/ D- F3 C
        plt.show()
    * H' A: G$ w& `5 k9 j
    $ v# V" r( {* o2 C4 ]/ r

    ; E+ J+ ?0 \6 q2 m" p
    ( D( v" L( X( g- s2 r

    # w. f7 Y5 q" T5 Bdef get_transform(train):& I; l5 _8 m7 B0 b% q& [
        if train:
    2 a3 ^5 ?+ r. i4 J/ ]        return A.Compose([' d, Q. @, G& D1 U: {3 ]
                A.HorizontalFlip(0.5),. g5 i, j9 k2 d( u& g  B/ @
                # ToTensorV2 converts image to pytorch tensor without div by 255
    6 h0 |5 v  f+ Y. O, B4 a: I0 L            ToTensorV2(p=1.0)
    # u0 {, x. _; q* \        ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
    ' w  x7 @3 {- P5 {    else:
    9 P# G" N$ I, D5 S; d! D- H        return A.Compose([
    1 l* \* s1 @& K! j5 C; b2 i- e            ToTensorV2(p=1.0)
    5 L, v' z2 O  U        ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})$ I  j# H* p7 Z+ T: ]

    7 f' Y0 O) F/ x' E* ~, W- `
    ' {, r/ T, l) \% a
    & ^& z' Y0 @6 w% t
    2 j& T. V* E- h3 |

    : D7 b' s9 N6 E0 `/ S, _
    % y: Z& _1 d) P5 R' R
    dataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))9 ~6 F& e6 J6 c& }. ~6 P# X) M

    7 c0 e# t; w% X0 V
    ; D! s, b$ J% e) e. r
    print(len(dataset)), _! ]  T8 p, u5 `4 Y8 p
    # getting the image and target for a test index.  Feel free to change the index.; q' R# ]9 e1 s
    img, target = dataset[29]
    2 L( t' [+ y- ^5 Nprint(img.shape, '\n', target). v2 x* k5 q. Y+ E
    plot_img_bbox(torch_to_pil(img), target)
    7 S7 Y5 a- |, D1. J; d3 l2 b" m# N5 z
    2
      c. ~6 Z. S7 B37 @6 a4 s$ W4 j1 b% G- [: a
    4" w) U* n* b" s5 i3 }
    53 G( b& E) u. I* m
    6: `% [: G) I- h- I- D  @$ h
    7
    # n: G3 `1 n( x4 d/ j, j8
    ' r! y; [# I( J. I& y, _9. j4 N: M1 s) M3 a$ P0 S9 ~
    10  ~( h: ?8 q0 \2 R
    117 c3 h! ~( ~5 J  Q& H* q
    12' A% Y5 j: p9 ~8 P2 U
    13
    3 B8 q- j2 R3 u) y8 }2 k$ ~14
    , j. C, c9 p5 E; G; k156 j( Y' a3 C# e, }0 c
    16$ r5 C) {8 w( p# ?
    17
    - }0 m+ v& r5 F18" g) D! \1 x! ], L% _
    19# B: j& n1 g. k) {( {% t8 y1 u, E
    20) ~( L5 ~5 f/ a/ L% n
    21
    5 m' t# D' h' U/ i  a5 r4 ]222 d7 X/ c5 ]9 t: R
    23
    3 _9 K0 |/ r6 I: g24
    ( N. ^  T. U. P1 N& N9 Y* e( h. O0 f& X25% H6 O3 q+ o" o4 r4 E; w0 X6 f
    26* @# @6 b! I3 z/ p0 n, g
    27/ d& R# ]- H; k1 r8 c$ X9 `
    28
    ( ^+ y& M5 M1 z) z29& K) Q  Q4 q  {, U
    30* O. \# t2 ?: c3 E, [9 T. n
    31
    ! y" c5 Z+ @0 z/ C  h6 L327 O/ p: J1 B) o/ c' ?
    334 a4 U1 j# p4 A' y' h: {+ q# t3 {
    34) i. Z: C* M- H- {9 B
    35: N$ s+ }1 h% m4 e: Q4 ]" A
    36$ }1 v  v/ p9 D$ @
    37' S: T% v8 ]1 P, R+ `& X5 x
    38. G( e6 e$ X! q  R7 d
    39
    ) k$ u: a- R3 E1 [9 ]1 k7 x40
    # C" M0 n  _' x+ f41
    6 T0 k7 q. I9 l* r4 N42
      X3 r& h. w1 R- W1 x) N/ }3 ?43
    " ?9 f7 l* o* ^7 [: f2 E44
    9 Q, m% G) I! v( h2 t45
    5 Y8 ?5 u: l" u461 `! b+ @: G3 W$ D" D
    47
    , d1 v* ?1 U* X! o; \3 K) j* B48
    3 d& [% T% c9 t- G& N# ^' S49/ {$ S3 j# k. x% ?% l: `* Z  o
    50  t( I) s6 P% N! C6 p
    51
    $ h: u9 }, N7 u. Y/ j7 i52, ?9 r9 L# T) u5 |0 M4 c
    53- U: j# x3 W% ^: u3 j+ p
    54
    / [  W/ Q9 Q: k9 N3 `. \! T* j55, ?4 s3 ^, B4 M
    56
    ' m, F3 u3 W3 y' T57; ~' E+ ~* ?5 O3 V3 A
    58
    0 o# _) y3 E: U4 O  E" N1 D  c59  R" n2 Z2 y6 a% E: G3 R
    608 p. A( V+ T( @$ G/ V% Z8 o  w: R
    61$ k! B# i% [+ c
    62+ {2 }! z5 ^" I* t$ _
    63# X2 Z3 Q$ M- c5 u8 ^
    64& d( y1 z5 i9 G. g1 E5 I1 L) _
    65
    % a3 b  ^# p3 o66
    3 S% Q& J, [1 P7 A& p$ C67, ?: j, R/ k) \7 Q, d  X
    68
    : D$ N- F% R- `69
    ' O9 M/ [$ V5 i) x70
    4 Y8 ^% N* e( P$ s9 z7 s71
    8 x& _. T2 l. S* K72
    " i' p: d4 Z6 N+ ]/ H8 x5 R73* h. S, B" g1 M* t3 _2 |" `
    74
    % X& z% C6 |+ S5 X3 u3 c" ~75- F1 I# r" q; F( k8 _" N
    76) Z9 A4 G8 o: w
    77
    2 Q1 E# i' Q' g5 w& `, g( j2 B78
    * Z1 ]* A0 w  z( x3 A" O) \& O1 A793 B! P# G/ w( n( R7 E
    80
    * @. P2 w0 P. N( }; Q81
    . y& K+ |: w/ }+ z) O8 l82- c# w4 R0 _! C) p: t6 ]
    83
    , K: b+ u$ _% d9 A' o, r" a84
    - X& v. y+ G9 n: [85: l1 d; g4 S; V8 w
    869 \8 O6 D3 T! s1 G7 U; w; |3 Y" Z
    87. ^1 b; e/ U3 _  M/ l$ s
    88
    5 [+ `* T+ H3 n4 O2 C- q2 c89
    / c: J+ \2 W/ S; J90
    $ C# B0 y' p8 N1 i; X' r# X! k91% X2 U2 j. F: x$ d0 \' l
    92
    6 |3 J, H8 _/ Y0 U93
      S  c4 u- d% h+ g1 O& k94
    9 n2 x2 Q- o; |95/ h' o8 y0 C0 b; N8 z% H
    96
    " e4 J" T4 V! Q4 T  Q97( f# t+ o, @% X  y5 t) q9 o
    98
    3 ?4 r6 P1 B7 h: W/ T99( B( i8 W0 I6 \! X& A
    1000 z( V( x: \9 B8 h, [7 s
    101
    * Y. l! W$ q/ W2 |+ _, T1021 P$ h1 ]" j1 w& C4 r
    103* }  a1 T4 p. h6 V% x% C
    104  `  [. J7 D! T" X: P$ q2 Z% k
    1056 `$ z+ e+ a" g( i: ?
    106
    : j) Z- B4 j! ^1 I) W1 N" d107
    " P. Q" C  }" w  r  }1089 ~  V! B& y/ @
    109, F+ z8 x3 Q4 x9 P, X
    110
    + S3 W# R& B  E* m# t" @& L111! ]" \# [" ?% Z7 |+ I
    112
    ) ?# U8 b2 _  ]+ E/ Q$ Y! |113
    6 W( q0 A# x5 B! e7 R114# H7 t% g+ ]) t# x8 |
    115
    : O9 G! t0 V. ^& U; M  C4 p  P116# H4 C# T* \7 C9 C( b( _+ K) w
    117  W5 l% n. w1 t- u9 M7 l+ t
    118+ F, v. Y7 W9 ]7 h3 {/ J4 {# Q
    119& [0 x3 U+ f6 s% v9 q
    120
    - Y* X) Q9 i, |, O6 T5 Z; m121
    ) C' Y; p! b1 c% Q7 t122. V6 S  c  z% v; Q2 \
    123
    $ C" l. ~# e' j! `( E124
    4 E( l( J* r( E8 F3 M125
    & B! _- b+ p/ V9 i126
    - d( F( ~# V* {7 o! Q; N; L127, w' \3 V# q5 w4 V1 L8 u( ]
    1289 h7 R; L7 j3 ?
    129
    5 r% Y1 k: O1 @" @1 S  s( q130
    ! _  {6 M  X: d9 l# R% O1317 `# K  d$ ^& b8 M8 G
    132
    # q- D7 T* T/ z" Y133
    % n. G3 w3 Y; E* ?134
    * g$ b# B. a  X& ?2 V135
    9 _- d& L/ G: v% R' D  A136. c, Y: d- b& T* E/ G
    137" p3 l( y' q! j" u/ s$ L  i. i
    138
    5 X( S! a* ~$ q0 B8 F$ C# s  `139' A' Z5 a5 M4 I6 g( d* J: @9 k1 g
    140
    6 i$ H+ Y3 u( B7 d9 I1 T% A1410 x4 k4 Q( I+ a8 C4 o3 R4 B# x
    142
    0 R: y3 U3 D% v- X# r% Y8 v' J143
    5 x! b: o$ I2 s4 i144
    ( n- D9 N; o* H/ |% ^+ y145: D: k+ }/ U* i
    146
    0 ~9 O- N( C8 E- \; s0 J, M147- }; g* S4 s* I- [( I8 M
    1486 {  J  z4 ^( j  O4 b4 v
    149+ _* h8 @) @5 ?4 ?0 J3 s+ K6 j% c
    1502 Z+ d. Y" T% c* A+ Z
    151: d  M6 k. s7 `$ X4 h5 i
    152
    & {& L( x5 N& u# j' i153; U5 ]2 y/ z; u, \( }" J* i' Y
    154
    ) M3 o( m6 w' M& v0 W9 I1550 i4 a: y6 k3 z8 f0 ^3 G2 G
    156
    ' F7 Z* I0 G3 ?- c1 |8 g, @- b输出如下:
    6 f) V& H$ I4 j4 ]
    ! e: y! ^) {: r; d
    / Y4 O7 [1 M( s  h/ z, R
    torch.Size([3, 480, 480])
    9 i8 E2 Y, a& a# v7 u/ T  N' v' }( f* { {'boxes': tensor([[130.8000,  97.8000, 327.6000, 292.2000],
    5 S2 X1 |7 h* Q  ]# D4 t9 s) @        [159.0000, 268.8000, 349.8000, 427.8000],
    # C- b3 M$ D4 R3 p$ j) q8 i        [  0.0000, 282.0000, 118.2000, 429.6000],
    ! @5 b- J( ?$ C" `) a        [ 43.8000, 107.4000, 199.2000, 280.2000],3 ^8 x* o( Y7 q& \2 L3 j! b3 d
            [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])}
    : Y8 B8 u0 ]% b1 J: p) U13 o- W. g# @/ d' {
    2% o: ^* f( s7 @% b
    3% W: q; t1 y  R8 B
    48 C3 F9 P' J# a6 H2 E3 m" e" q
    5
    2 z+ ?7 {+ v( B: S+ u( w+ h9 r# n6' C9 u3 J# f& x; x3 p
    9 m& w+ v/ E4 y) o& p2 S- v
      N3 S$ h. u9 ?& r6 t
    ( O4 B0 B0 x- z
    / c6 i- `5 z9 Y1 V/ G; B
    下载地址
    % G$ G  y+ \; m8 {7 d$ c4 X链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw
    ) i1 m, q9 X) @0 s# ^# E  \提取码:srjn8 Z1 l9 a  h! Q. w
    ————————————————! q# m7 g( c9 e3 k
    版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。+ w& Z& h4 v9 ~8 l# S! e
    原文链接:https://blog.csdn.net/weixin_44510615/article/details/1184962734 Z# {8 `! j) |( t  e

    0 s' S% f/ e  n  a$ ^  b4 |/ e+ x* B* k! ~5 r
    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-8-4 13:05 , Processed in 0.334639 second(s), 51 queries .

    回顶部