QQ登录

只需要一步,快速开始

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

    - h% _! P. y# m3 u% w; V, p深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息4 N. Y) P  }" V' v: e- s  I# a
    图像标注主要用于创建数据集进行图片的标注。本篇博客将推荐一款非常实用的图片标注工具LabelImg,重点介绍其安装使用过程。如果想简单点,请直接下载打包版(下载地址见结尾),无需编译,直接打开即可!
    5 O0 V3 j& [. C) X1 p: a; o' V# m' z% n; w9 K! `% ?
    , G( ]7 a( Y  a) M% B
    感谢原作者对Github的贡献,博主发现软件已经更新,可以关注最新版本。这个工具是一个用 Python 和 Qt 编写的完整的图形界面。最有意思的是,它的标注信息可以直接转换成XML文件,这和PASCAL VOC和ImageNet使用的XML是一样的。
    " f# B0 n7 k7 w, g# N9 k+ j$ Y+ J0 L$ a- ^, m/ w  z
    2 s- {0 d# G) h9 ?' X4 y+ a
    附注。作者在5月份更新了代码,现在最新版本号是1.3.0,博主亲测,源码在Windows 10和Ubuntu 16.04上正常运行。. V/ U: N7 q  s4 z3 ^* s$ X

    " j/ n3 x$ f2 `6 {: b$ F5 j# ~

    # N1 a. v. ]1 ], Z具体的安装查看Github教程:https://github.com/wkentaro/labelme/#installation
    6 E/ L' |/ u: P' p) J! w5 D
    ) ^' k/ a& @% s, `7 O2 K5 E

    $ t4 V; x- s* a) U7 h在原作者的github下载源码:https://github.com/tzutalin/labelImg
    * x$ Q8 L7 E+ g+ T! R$ a6 v+ u。解压名为labelImg-master的文件夹,进入当前目录的命令行窗口,输入如下语句依次打开软件。+ X! m; [7 O' F4 f$ E! k

    ) q1 x' M( n5 r+ g! M% u
    1 P/ P! r; s2 Q
    python labelImg.py
    " W5 [& s1 z  ^7 L1
    ; M6 {* G. M$ J! E: ^
    , z  s/ }- |8 Y/ I. N

    1 ?$ O$ A- R3 t$ H  i: j4 z) [- |7 W2 P% b: Q. A; Q" Y

    3 ?% z* ^5 \! P2 x具体使用
    - g6 G' l3 r8 h, X. k, {  Q, `( N修改默认的XML文件保存位置,使用快捷键“Ctrl+R”,更改为自定义位置,这里的路径一定不能包含中文,否则不会保存。
    - H7 W) d1 }" v$ F5 \  m$ q; k7 X1 @% |0 Q3 f: h: G  n

    : }. }6 R3 s; F8 }* R7 P. Z使用notepad++打开源文件夹中的data/predefined_classes.txt,修改默认分类,如person、car、motorcycle这三个分类。
    , S( o3 a0 M7 U! L$ U. I4 p$ M4 v4 i
    ! k1 t; C* A2 f+ d0 i
    “打开目录”打开图片文件夹,选择第一张图片开始标注,用“创建矩形框”或“Ctrl+N”启动框,点击结束框,双击选择类别。完成一张图片点击“保存”保存后,XML文件已经保存到本地了。单击“下一张图片”转到下一张图片。
    2 S% u; M9 O  q# M& C- L4 @6 G; y' ~* l. U; y

    1 q8 K$ h: e9 A) {1 \4 X; `贴标过程可以随时返回修改,保存的文件会覆盖上一个。
    , W/ C0 d. e- ]4 ]2 M! J' D9 J2 l) ?+ n: \
    2 O, h9 V- P* w2 }/ q0 _* X5 y6 V
    完成注解后,打开XML文件,发现和PASCAL VOC格式一样。4 q3 f" T! h8 L. r8 O0 i$ s2 j
    7 F& F( [8 V( ^  D& r  F/ z0 ?7 G

    + s( Z2 A# S8 U+ _将xml文件提取图像信息, U2 W0 |: B( `7 P  O
    下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。/ {" D1 V5 N) {7 ~* p
    " P1 ?! @5 u1 U1 D

    * ^3 h  Q8 Y/ o2 q. T( U. z
    0 b+ Q4 |- J) v. f
    $ ]- o/ B) s% h- m% Z  v# m
    下面是images图片中的一个。
    . c/ Z9 {6 X8 {$ r4 L  P$ r! f% d! Q  b4 h6 P
    ) _, T: g  \4 a  m# @  s; D) ^
    下面是对应的xml文件。
    % ]9 {) ]9 V+ _8 \0 k  J% [. C- V$ Q( d/ a, V  Z
    1 b& u; t: f3 E0 \9 O' x& r8 n5 y
    <annotation>$ |% Y3 i& n4 A7 E; o
            <folder>train</folder>+ w9 c5 X3 p2 v& u. }+ t' C7 s& \: |
            <filename>apple_30.jpg</filename>+ l& p5 z4 g* Y+ k2 Y6 a, Q+ ?+ ~
            <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>
    & z1 G/ |0 n6 y9 i        <source>( A/ q6 c# B+ r7 }" ^
                    <database>Unknown</database># ~4 T- L9 `7 z( Y( d' @* ~
            </source>
    3 @- e) d/ I; S, }' R9 Q' m0 ?2 f        <size>: O8 U& A9 V* x2 M8 F1 Y2 c
                    <width>800</width>
    % D3 ?% ?# b* ^! q3 j# `                <height>800</height>) y. W& d2 t9 @1 p; m0 h
                    <depth>3</depth>2 `7 }1 G7 R& }' G1 j% ^
            </size>  }/ K8 k7 k& {/ B
            <segmented>0</segmented>
    . h8 i% ~# G5 F$ u) s6 n1 j        <object>: ^& \' Q$ z! k3 b
                    <name>apple</name>6 p( n5 A  v6 c2 P8 X9 w3 b* t% A
                    <pose>Unspecified</pose>
    2 v* f, j+ l  Z# _* z                <truncated>0</truncated>& O( f4 P% x" u
                    <difficult>0</difficult>, W1 k; \4 {4 y! d
                    <bndbox>* X7 @: X! z7 K; A# l
                            <xmin>254</xmin>
    - j3 m# v' e* Y2 n                        <ymin>163</ymin>2 p$ D( C! C/ y/ v9 l4 ]
                            <xmax>582</xmax>- `( O( f  n& K. q$ |7 D6 l( Y$ R
                            <ymax>487</ymax>
    - E4 H8 B, l1 {                </bndbox>/ F9 w( b: ?% g) E  P
            </object>1 D  m/ a9 ]4 B9 J, R" t% {7 H  ]
            <object>
    9 [# I# p6 {% @$ g0 h, d3 I                <name>apple</name>( _5 Z$ I' z" v
                    <pose>Unspecified</pose>4 g6 d: B! }" N: a
                    <truncated>0</truncated>, o1 c8 x) ~$ {) G3 d  W7 o
                    <difficult>0</difficult>2 r5 Y3 {6 n, P7 P
                    <bndbox>
    - j* ?9 V5 j3 C$ y  X0 n1 i                        <xmin>217</xmin>
    , \! @# H$ m% B                        <ymin>448</ymin>+ L. G5 f. Y0 y6 p3 O$ z
                            <xmax>535</xmax>% f7 U8 u, R+ T$ ~
                            <ymax>713</ymax>
    4 ^) i: D: M2 P3 ]" U+ W                </bndbox>+ U$ r1 k$ f- A+ D/ m
            </object>
    : ^8 _2 |9 E  N) X/ c        <object>
    ! ~% \! K( T) w7 C7 v- ~7 K3 x" Q                <name>apple</name>8 [+ l( D! O! a2 |8 r! k( [/ C
                    <pose>Unspecified</pose>
    ) M- j% z3 p  h+ o) }0 R) y6 X5 _4 q8 B                <truncated>1</truncated>
    . ]9 C& P* z- s- E                <difficult>0</difficult>
    1 f  ^2 W! k. q; M0 _* Y" Z                <bndbox>2 @, u+ l) l9 b4 `' X
                            <xmin>603</xmin>: \$ [; X4 ?# t8 A0 v3 v! U, E
                            <ymin>470</ymin>
    0 d7 _6 C  J6 `8 l5 V; @+ A; g                        <xmax>800</xmax>
    7 T" [$ u0 V) {& E9 w$ W$ [# x                        <ymax>716</ymax>
    0 N' x) w1 X1 a& z8 ?2 C                </bndbox>
    % ?$ G0 Y( o+ w/ b5 j5 K3 ^" Y0 S        </object>( D+ V& u% G; n' N
            <object>/ [. r% E. t: o" _5 z
                    <name>apple</name>/ z$ h. ^8 {0 C0 x
                    <pose>Unspecified</pose>4 j7 u0 s6 d6 g& f( _
                    <truncated>0</truncated>
    % U' i: w5 B8 ?$ i- W9 d                <difficult>0</difficult>
    ( O' `7 c# f9 {" Q                <bndbox>* O2 ^5 E, Z, g: S% M+ _6 f
                            <xmin>468</xmin># A6 x5 O- b* V: R* }
                            <ymin>179</ymin>
    2 F: E( C( f# j7 a                        <xmax>727</xmax>* C" v% J1 B# S; m' P
                            <ymax>467</ymax>6 Q8 ?6 {5 N/ t/ I1 x
                    </bndbox>
    ' G% `9 A/ q" Q* N* }: T        </object>- s9 O: x0 Q" S4 ~
            <object>
    9 J" F' b! v3 j1 G' t                <name>apple</name>
    ( e5 g. h/ G/ t7 y% z% `' e1 K. O                <pose>Unspecified</pose>0 K8 w3 {" g7 G9 U5 Q
                    <truncated>1</truncated>
    2 ]/ N4 G( ~% k' q                <difficult>0</difficult>% j' y1 h* V6 p% [4 Z
                    <bndbox>
    3 g9 S8 A% `' I" \. A( e- F                        <xmin>1</xmin>
    . _1 D5 H6 d6 M( q8 X- b+ Y                        <ymin>63</ymin>
    % _6 A7 N! m% U0 [  L                        <xmax>308</xmax>9 o- e4 g7 d0 r+ [
                            <ymax>414</ymax>, i6 w+ |1 G# [' y6 D& K
                    </bndbox>' k7 ^6 r' f' i; F+ j
            </object>$ d8 y% b* R5 I/ D( Z7 K( `) N
    </annotation>' b. E4 L6 X5 o' q1 I
    1
    , P& l6 x8 ?: V: t2 R2
    ; {  o) Z: S9 Y0 [! q( u% n4 O3, {6 a; f$ l4 |" U3 L: z7 T5 V* f% H
    4
    ' W+ l! d  _* r: N, |5! l8 c$ ~% C$ K* R: g0 o; l
    6; {) m. G# A1 v8 l8 h& m
    7* M, B1 Q; S$ h+ d4 K% h
    8' M  G# h" E( O5 _) a' |5 ]. H7 _
    9
    + i! w" {9 {' H+ y+ N/ {7 P! k5 y10
    5 w5 q# W* k1 o- t8 S3 P116 h0 M% W! r7 {3 C& d+ H
    12  h+ x, ?$ n, V* E" D8 g7 ]
    13$ R3 E' j' K" u" J6 l. j% y
    140 `+ t' p" r/ h- B, g( {
    15# \: H# u/ k0 g/ H( F# Z, d
    16- d& F, Q# s% D% H- U1 ~
    17' J, o( i" ~. t( ~
    182 W) N. ~- N$ P+ j, s2 E6 ?& M6 `
    19
    0 l8 n7 Q, R9 ^  l  K20
    ( N7 I, ~: c* L; J% q, l7 N4 i21! l" q8 `4 T9 ~1 ?9 F* i
    22. F9 X& }/ [0 O) v) U
    23
    - L8 f9 O& _. C' f9 B* Z( ]24
    / u1 S, W2 m. y25# h( [! p7 e' N* M9 g, S
    26% p" Q' N- M3 _" s4 q+ @* p
    27! d8 T7 h# U) l! Q/ ]: U* E, k
    28, r* f) u/ r; b- y1 q
    29
    6 M  f! f( d/ ?! m30
    $ s1 {/ }$ ^( \, \2 }: @31* E* X/ Y5 c# F$ {* J
    32* {/ [+ [8 \6 |
    33! y' Q5 b6 d4 [. l% Z
    34
    9 n# j5 c7 f4 h7 K0 b* K6 e% i35
    + m' k# p0 s" _$ J% I9 L361 ]2 K% i; E0 ~1 }# E0 H" Z) c
    37
    6 Y, V* e" n, M' ]" {38
    # E! Z! ?  n) i0 U% O39. p! P- T& B( _. M) c, B
    40
    * I: ]% E9 S8 i3 ^. |41
    9 v5 i) @. ~. U& _- t* v+ k$ z424 f* n, Z) W1 B6 Y1 N# C
    43
      m, P/ w- j1 ~' o44
    1 u! I$ b, v* [9 V$ G: s/ b45
    & D2 S. {# k- u0 {4 y460 J! {0 w. Q* S1 X( K1 ?' q
    470 x7 X4 k0 L' E( b$ S# c# T! c
    48/ t( J9 b7 m$ N! Q
    497 X5 A  d# S, i/ j9 G' @# x, n
    50: ~8 v( X- S! T/ j& _$ N  V& b
    512 J1 f$ w6 Z) X% j# _" H
    52
    $ ]; R/ i. P. z% g( E# a9 h2 J53
    + N! X7 @$ v) P5 H, q9 W54$ B1 H# C* x+ X( f
    55
    ; w: x! a) |( ~% b56
    + ?; Y$ K8 {  j8 c573 i/ l7 M; `: ^0 f* p. t6 H
    58+ m, u; v0 }7 n: W  l
    594 p( I8 U1 k3 n* O4 p
    60
    : R7 A; W, L$ R. v# X. Y) d61
    ! k' |" _- h0 c62# L+ g! i0 [2 W9 u9 V
    63  h7 H6 V3 r7 Z/ K% y% z: R7 K
    64
    : F7 e) u& Y8 a( x* s1 ^& |1 P65
    & W' Z9 w4 f4 M9 N4 k% m663 F/ b8 _0 Y2 C& o% T/ O8 @
    67" R1 I7 h: p+ E6 e# P+ W
    68
    & P( A% J: Q& m3 r! z69
    9 X% y# q# R$ P% x% }70
    7 L3 Z0 F% g% g7 |& i$ k- l71
    - y- M' ]7 B! t  ^  q% ^72
    8 J/ x9 D* q( ^# C: I739 N( S  ^% @8 g$ R/ U- V
    74# U) j6 U9 v9 ]/ \( B( D' E
    将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。
    % `/ O8 p! h$ S1 f: I/ h
    2 n/ Q( a. c* P/ C  q8 T7 `- v7 V

    9 Y& R3 N+ w, R# v9 W! {( _/ N# himport os6 s( J& ?( ~- o1 f
    import numpy as np
    . ?0 b. [6 M# vimport cv2
    " ~5 G2 X; J3 E+ U3 p5 Q0 r, Wimport torch* }' w4 w+ ^; e$ i& k7 Q
    import matplotlib.patches as patches
    / N; S7 m; n- q. N6 O" P8 j% himport albumentations as A
    ; _0 d3 o0 }! xfrom albumentations.pytorch.transforms import ToTensorV2; P$ S9 H/ r! l8 F
    from matplotlib import pyplot as plt2 c' K, `+ l4 t. H% y, n2 X
    from torch.utils.data import Dataset: {0 {1 q. F) @( Z% J7 c; b5 H
    from xml.etree import ElementTree as et
      I6 L6 J, l( u! A1 Dfrom torchvision import transforms as torchtrans
    0 }. F- {6 R* T$ z; O& [3 U; p8 C4 T4 i4 x+ i9 J- k

    % l( p/ ~' b! y6 |/ j5 G1 I# p) j# defining the files directory and testing directory
    % X0 r7 ~& h$ `0 X+ G+ H5 dtrain_image_dir = 'train/train/image'
    # X) s8 {+ b2 J# e( ]+ c) w4 D0 ctrain_xml_dir = 'train/train/xml'
      a# J& e8 t2 t# test_image_dir = 'test/test/image'
    + y* {7 p5 `4 T# D6 @$ [5 Z( z& Y# test_xml_dir = 'test/test/xml'" T3 |8 r) K8 k* n3 Z5 V

    / V- \6 d& R( A3 k+ [' M0 `; V0 Q' R) J

    1 g$ U8 G# ^  M! x/ Hclass FruitImagesDataset(Dataset):
    ( W! e: g+ a' a% S2 D+ @. Y  L
    % h2 M- L+ O* N2 V  r, s; _
    8 x/ G' p6 v' ]( w" H) K
        def __init__(self, image_dir, xml_dir, width, height, transforms=None):# h% v" S" V" C* n/ y* y
            self.transforms = transforms
    . i: ~) T- T# H  T8 T+ k3 t        self.image_dir = image_dir2 G' O: k! T% A; @) W
            self.xml_dir = xml_dir) ~$ y# R" j4 |3 a0 O- h( `3 x
            self.height = height
    9 R+ J9 Q/ d. d7 t, m        self.width = width4 L) o; [) ^" W9 ~8 Z  u) j# ^
    * B2 T) [7 f5 y) ~
    & R" _# `: B  |# S8 y: S' B% k2 W! V
            # sorting the images for consistency- ^2 \$ u9 J* s( R8 Q
            # To get images, the extension of the filename is checked to be jpg
    ' y6 b% i; j" ~, G        self.imgs = [image for image in os.listdir(self.image_dir)
    - m- A1 ~/ R2 R& Q4 L                     if image[-4:] == '.jpg'], p9 t! }, E7 M+ f
            self.xmls = [xml for xml in os.listdir(self.xml_dir)% v0 a5 {# R$ }0 _' j
                         if xml[-4:] == '.xml']
    3 x1 j6 L4 W7 f4 N6 S, l( Y8 o5 J% u9 n9 l# k
      B* [) e9 x1 q7 E" F3 P
            # classes: 0 index is reserved for background4 v! U# l& u6 j4 K5 p& f. {
            self.classes = ['apple', 'banana', 'orange']; h2 z. p# _/ x, j( A

    ! O0 e1 w0 p- r; I* }0 \" s
    9 Y8 Y, P  Q+ O6 C1 g: [- R
        def __getitem__(self, idx):) Y/ j) j  J3 j& u# t! T+ l

    % R7 j5 r0 a, q

    , ~$ b, T/ I; B. l        img_name = self.imgs[idx]
    4 I; Z: M$ M' N3 }  B  l        image_path = os.path.join(self.image_dir, img_name)
    , P! y6 r# t: R. a' y
    0 W. u2 }" }3 [. j0 B* ]3 `

    . T' N1 U7 z0 u        # reading the images and converting them to correct size and color
    / k3 c/ p7 z: v3 Q: \5 Q1 S7 E        img = cv2.imread(image_path)9 M6 t+ `% \. F% F! d8 X
            img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)
    / K% ^8 C3 ~& D6 j- e" m, {. `        img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)
    # [# x0 r3 \7 ^& ~( P: T! A  D2 p: @        # diving by 2552 ?5 B; |$ }$ b( I1 H) J
            img_res /= 255.0
    1 g9 ^- S: @! d) o+ A$ p/ T7 y2 F4 _; t$ O* A/ N, [) `1 e
    , l8 g: m. `/ O2 l  d, G$ n5 h
            # annotation file
    - e2 v, z4 k/ D3 m+ p9 G        annot_filename = img_name[:-4] + '.xml'" d$ }: n  n. Q" C
            annot_file_path = os.path.join(self.xml_dir, annot_filename)) s( R4 v5 i8 f9 z& i

    ! M! H" n1 a) s1 ^. Y

    ( G: U3 y1 H0 g# w9 f        boxes = []( o% w" [4 f1 K7 r6 \. T% N
            labels = []
    - q/ ?4 L, G1 _& f* \' z8 c/ j        tree = et.parse(annot_file_path)" ~3 @2 ]8 X, K0 z: L/ f
            root = tree.getroot()1 B' d7 h1 _9 Q  r+ m; i

    ! _7 i* h4 G0 ~. y

    ; e5 d0 R# c& n$ j5 W3 M        # cv2 image gives size as height x width% ]; A- R- l6 ^' I) R7 L
            wt = img.shape[1]. i5 p$ G9 x$ @1 M# Y3 W! q6 W8 p+ v
            ht = img.shape[0]
    , y8 w  N! V# E9 o3 k4 S
    : a+ I" e0 _" R8 _% E: k
    8 ?; M) u' p) r2 q) j8 z7 L8 A
            # box coordinates for xml files are extracted and corrected for image size given
    % ^, u; \8 u/ @  [" M6 C        for member in root.findall('object'):+ P* _( f7 r2 x& @+ S$ ]8 t7 T
                labels.append(self.classes.index(member.find('name').text))
    1 F' H# n* l" W) ^. |+ M6 m2 n6 C) G* x$ s

    - u: i' @3 ]& _# I6 O/ B            # bounding box
    7 T) _7 U' ~% A) g- M: ?# v9 l            xmin = int(member.find('bndbox').find('xmin').text)! |+ s, H5 L7 U5 V1 L/ L% r# q2 E
                xmax = int(member.find('bndbox').find('xmax').text)
    1 Y5 v& y' C) z% t7 G4 `/ B7 e" {; U% ]) h& \3 E' O8 f

    3 @) g7 f: e/ g( p( _/ U' {            ymin = int(member.find('bndbox').find('ymin').text)
    3 p# e  S5 G8 s* M            ymax = int(member.find('bndbox').find('ymax').text)
    7 `' Z- v/ _' V1 D# g7 V% S! i- |* [. ]0 K2 B: {; c3 K
    8 _$ o: D+ F1 r6 g: K5 Q" `
                xmin_corr = (xmin / wt) * self.width
    % C1 u7 G" N1 a$ y8 ^# a* b9 ~$ P            xmax_corr = (xmax / wt) * self.width
    0 J) A. D" A) n9 j            ymin_corr = (ymin / ht) * self.height
    3 f3 i; B+ [2 Y0 C            ymax_corr = (ymax / ht) * self.height8 J+ b+ Q9 F  M4 \, f) j
                boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])
    3 `2 V9 n. g6 s# l" i# b( f
    $ k4 `0 W" h( [* h4 w
    - s: e6 I" B! [
            # convert boxes into a torch.Tensor
    1 h( H1 c$ m) z, W8 J- {        boxes = torch.as_tensor(boxes, dtype=torch.float32)! B! s  n* H8 M; V# \7 c* R' }

    9 f  o7 A: _: T: ]8 t
    5 p4 c0 r* C% c9 _
            # getting the areas of the boxes
    + w: o  B7 r* j( r; Z& l9 w  \2 E        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])% C, F! p) ^/ }4 ^; p

    , V; l' \3 ]. O; u5 X
    : K: Q7 P# {9 |  \
            # suppose all instances are not crowd6 w  P5 I/ Z* [. k7 y
            iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64)
    1 V0 ?5 g' |* x$ J& I. z
    0 ?4 Z4 C; u- s) S. f% X4 A5 f2 k
    & l6 l3 d9 E3 w$ K
            labels = torch.as_tensor(labels, dtype=torch.int64)9 f2 Q( _# ^: H: {0 y' y2 U

    3 h: v! [: X  `3 u+ e
    + T9 t* v/ q" {" a: C* I; @
            target = {}
    & m; p" x' [+ w5 V& _        target["boxes"] = boxes) C% Z( v, J, j$ f( w' E  k5 ]
            target["labels"] = labels
    ' _$ u+ r+ U2 [$ p* _" W3 O; a) t        target["area"] = area
      |; J0 N& L& G( Y+ Q1 u        target["iscrowd"] = iscrowd! t" J) n: @+ X; s
            # image_id
    ' S1 t3 z8 e" Z        image_id = torch.tensor([idx])9 g# q7 p+ |0 h! _# m; d
            target["image_id"] = image_id# A6 L7 T. s1 u* {6 z
    9 V# x1 l- g9 P2 n. T* X

    " }* ~8 W. b$ a! y& N3 {        if self.transforms:) d# A1 B$ ]) L* I. u# d+ G' o
                sample = self.transforms(image=img_res,
    $ t6 r/ G& M/ d7 P! b( v/ u8 w                                     bboxes=target['boxes'],
    6 D& e3 L8 U8 |" E2 b5 s/ Z7 s- }* K                                     labels=labels)
    , z5 M9 A, ]; |/ B+ e3 a. e3 @" H5 P* A/ O

    / N9 A3 z5 |, Z- A            img_res = sample['image']5 t( f0 M/ E( |4 Q8 z
                target['boxes'] = torch.Tensor(sample['bboxes'])
    1 D) v+ p6 ^: I/ R( |& X; m$ x% \% ]5 i- Q* p# c7 }- x: E

    ) I4 M* m0 c7 I3 V3 v$ D        return img_res, target  s7 N( ]6 [' o( R

    & y& f/ n$ ^, o' J1 ~8 ?$ s2 L
    4 o9 I) _2 @; D% A
        def __len__(self):: ?0 E. O9 u# W6 h
            return len(self.imgs). h: W* h/ q& X% i9 y  |; p
    , q! N" O9 _8 ?) I" z9 }3 O: n5 r
    $ n9 V: A5 G7 m6 g$ M% `
    # function to convert a torchtensor back to PIL image
    9 W6 N4 ]& P9 W, |def torch_to_pil(img):3 d' L" P. i: m" O
        return torchtrans.ToPILImage()(img).convert('RGB')
    & _( ~' H2 p! G- j! P
    , \, u9 z0 s+ Z( b; J$ Y2 T
    ! g/ }. |& O3 \% |8 L& x
    9 @3 v- h. Z5 Q3 L8 [  k
    : I* e7 t  v, G2 c1 N9 W
    def plot_img_bbox(img, target):
    7 K# m2 f* [; ?. O2 U    # plot the image and bboxes* a. @$ O( [" p! [" }/ e
        fig, a = plt.subplots(1, 1)
    2 {0 H9 u! y* Z( D' a* A% Z& @" T    fig.set_size_inches(5, 5)% F) y" R; b# u; b. |0 X9 ]
        a.imshow(img)
    ; Z& H) D4 v0 B4 i+ w4 z    for box in (target['boxes']):( R+ ?* r( h- t( \
            x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]7 X) c0 a0 L8 B, y
            rect = patches.Rectangle((x, y),
    + e+ M9 d( H% @, B. i( a2 L                                 width, height,0 S$ J5 m# n. Y; ?9 ?; m$ u
                                     linewidth=2,
    4 q$ n4 B8 j8 P* e; D& K0 b                                 edgecolor='r',
    ( g; i8 k, W4 L' p' S                                 facecolor='none')
    6 q# i: l# i+ J  r
    $ y7 l: Z- {6 w
    " N9 p6 Y% m5 i, `2 Z  [
            # Draw the bounding box on top of the image4 I9 s; G  s& M8 m8 E
            a.add_patch(rect)! ^$ @! }- z: B
        plt.show()! i+ Y8 D4 y5 a* q
    " a9 F) M" k% I' J9 \

    ( W5 d0 I% U0 V% }; d" O$ v% D( ]7 N3 f* F0 R( L  I( H
    * j' S$ {9 H; h! K# _
    def get_transform(train):$ G3 p# L& u& r- d7 M6 {
        if train:2 a: F. M* H' {- E' |; G. t
            return A.Compose([5 U) u# b2 ^4 N; z6 P; P
                A.HorizontalFlip(0.5),  B, J+ C$ n5 O5 v, [
                # ToTensorV2 converts image to pytorch tensor without div by 2559 ^" |( B: c6 R$ _
                ToTensorV2(p=1.0)
    ' m9 t8 c, |6 s        ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})# y$ z# l5 G/ S5 s  R6 N: D
        else:; a" C) N9 W: S  i, a. F; f
            return A.Compose([/ o1 B: X# z3 d& M0 [  }
                ToTensorV2(p=1.0)) n) T1 t( j: k6 E& }. W
            ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})0 W6 B0 q5 H  g0 r) i
    ! N1 X1 o# y) F: n* k1 X

    & L4 n* F' D1 L* C& q. L+ E) D: e' r! H3 F
    * [7 s9 K; _( _" _5 {
    / O* L2 }/ \$ D: k' [9 w

    0 c# c# \2 o% t$ ]1 F' l! a1 ~dataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))2 @% U* k# S( |) n% J
    1 U# ^' F4 i& W5 q4 {& k4 [; }

    + V) H' \- C. V( L5 h0 ~0 kprint(len(dataset)). y; ?7 |  v% @+ r/ \* @. Q+ k0 S
    # getting the image and target for a test index.  Feel free to change the index.
    3 m+ K+ C  L( u. e/ l5 Ximg, target = dataset[29]
      T/ I, w) _3 nprint(img.shape, '\n', target): D& L+ A0 Q( J8 b* A0 \' N# J
    plot_img_bbox(torch_to_pil(img), target)% o: J2 {5 H' s7 @6 O: l
    1# p7 a1 K' p7 {  N! l8 a9 v0 z% h; F
    2: D$ s, x, A+ _; Q! ^! U5 B
    3' b8 v4 j3 K5 Z: p; P2 W. O
    4
    4 i3 ^6 T% {) I% [; N$ L- X7 u55 [0 R4 o- {3 J' l: W4 o, M2 @: A
    6
    % I; F, I/ |% {3 h7
    ! N6 ]- Z( S0 W2 T# L  n& w5 M8; d2 H6 j- ?9 w7 U" n: \
    9
    0 O) X* \- O% {7 h$ `( X% V, s104 f! E. ]; k  N
    11
    ! B. O' B8 K2 v) h12
    % a7 e4 }( e" C" t13
    ; K% u+ o8 J  Z14/ |3 O' t; K: Q* _, k( ]
    15& F* v- C3 {- C
    16
    % r7 O& X$ Y: g: b2 b17
    5 \1 n' o9 m. i0 |- |  A18- q1 a' \" E, V7 a. \
    194 d! t4 w/ t* \/ L
    20+ D$ J  x: S* M! |' D
    216 ^( w; O7 a4 ]7 e' Q' k
    22
    & J* M$ t7 N6 j23
    2 [+ O/ f9 [1 E/ W0 B4 V24
    8 p6 d) n$ }# R/ a: I25
    ; B: @& g* B/ g26
    ' Y# _6 Q9 i; ~278 C( X) N  K5 g
    28" l  T6 I  n( W
    29
    $ T) y% l7 Q: N: f$ H9 ^307 }0 V; }2 h& u( D
    31
      J3 M9 S' H9 m2 ~32& ^* \6 i, y9 K
    338 j& W" l5 I; \+ ~5 I
    343 x" S& g; V. w: r3 t
    35
    2 b, w* C+ h8 Y) l/ B36
    1 P: _3 k2 \4 ?" }* }37
    $ d' u; O9 m% q  J- B0 i) X7 U, W38: c) N0 P; V9 k; @3 X3 Q4 a
    39
    ! w+ d3 I# B  Z0 ~40
    ) b! z( r7 {; I1 N- f7 |41
    ! v  h, E/ Y. C4 F' b2 j5 Q420 X& R! t9 U, m, J
    43
    ) @" }8 r' ~" X" e, Q44
    2 m( x4 W* p4 B/ w) f- x" U( H45
    , u, T8 [, m; ?' k46
    2 b% q1 F) J+ k0 T% Y( w; k474 P' J! M; W; x" w: j
    48
    1 C& O& y1 \' t) Z! ^49
    $ z& b6 m, \* _+ e" S( u3 J4 I50$ Q6 \3 {: y4 u
    51  d/ W- E5 M; G9 {) K
    52
    ! H" L( `" {% q. P" O6 ^" b8 D; m6 x53% X/ W( t# j+ _
    54
      b4 ]2 q0 u; z/ x6 O1 B55
    0 l, p2 W! R0 b. {" B5 A" u: D; M56
    $ |4 ^, w( |: y7 X& I& u  U' h57( ^  Y8 p* d+ Y5 P) a
    58! b+ X( \: M( }# f2 ~  k! N6 T
    591 v3 z/ q; d4 _! W0 V3 z
    60
    ( U+ m! ~# n6 @( d61
      V7 g+ r( c) ?- [1 w62
    7 T, ?6 h. x: C- K1 |4 L63  q$ B* A$ @; j/ ^( X
    647 {, k) Z4 X! K6 Y: O6 A% e- j- |
    65
    1 m( N; ?% t/ U6 R) H66
    0 y- z% B2 C- R& ^/ O  y67
    4 w6 z2 m+ o6 c* T' v" {68, l1 f% k, X( A, s& B& V* z
    69" V7 D% X& r6 g$ c* l- ~) E
    70  ^0 r7 b" d( C( }: x
    71
      J5 z1 U- B* _72
    6 z' q! V! s6 g$ ^+ u! [) S73
    ; O: A9 @1 W& t3 f% Q2 B, D741 C( U: s. z4 j- Z" q) Q* G
    75
    * M' K( |, f, R0 f9 l; R: k! y76
    7 v, k' \* w  K* ^+ C# W" F  U77
    5 |0 x; m+ h& q- V3 b1 T2 [78
    - t# Y. S3 x9 g79
    ' q; U7 r. I' `80! Z% P+ h( E: g8 J# a3 O1 |
    817 o, F& o5 m5 e, _4 K& S
    828 o1 \* z" r/ f
    83
    - h7 u1 s1 j0 T; }2 S( V84
    5 X3 W+ F1 z  u+ l" y: Z85; ?6 d: g$ s' |4 J
    867 k7 E$ d- R/ S/ F5 S
    87
    ; e% i( a& k: E  v8 j* p3 e88
    , V" n4 Z; m; u# M89
    0 d% g% [4 _( a0 c907 n7 L: y  F; }/ F9 \
    915 ?# P2 ?! Z0 d' A/ `& u
    926 h0 M( D( }" h* Y5 w0 _2 m
    93
    . h$ W' z, z7 D, r, [; z6 X, Q94
    , A  N8 i! L. q7 i, w0 _95
    # `& S7 K- K9 I9 p. S96
    2 T. ]$ g, R! J$ y97* i- a6 N$ ]& u6 e1 Z0 p6 A1 ]4 h
    98
    - M0 X0 x4 f' u8 |/ c997 W0 D; {$ n" u; h8 h8 S2 r
    100
    $ o! t0 K' z5 C! T0 @101
      {4 T# Q  a5 G2 O- L102
    - g( h  \/ |, w6 C. o, D. z. s103: p/ o5 q& ~; X6 T% R& N
    104
    + L5 e4 O8 C& M9 @( N2 j105
    ; [7 i" Y! Q+ ~5 [3 N1062 V' X4 y" F8 q/ G3 C! `5 @
    1073 P" v. H- j6 X1 W& e( @
    1082 [4 o2 Y' R& {  I; s
    109
    3 J; p" [2 S7 Z! a1104 H7 @7 f, G8 ^# d% M
    111+ Z0 E0 t+ e; f( u
    112) ]# I' y, X) y" g$ v
    113
    1 f5 o* c1 ?; E, R% J: a114- b5 P0 s9 G, d
    115! s; J% l6 \3 K: q# H4 G6 x  L
    116/ Z8 q* `4 \0 A9 p
    117
    : c9 o9 O) ]* w! G- _118
    ) D2 E( o- t7 u% G1 m! ^119: m( E/ A$ `+ d) r" o
    120* t' u. k+ b! B+ r) t  e
    121
    1 M2 Z4 q( S$ |/ D8 C122' S8 C: a! D4 q' H1 r1 E$ f; T
    123
    ! [% G% a( k  w& A$ ~124
    1 G# ]' S- s) J: Z! e125
    & s+ }6 u& y1 w, e126/ L2 n% h; ?4 Y" p) ^) r3 {
    1270 t" P$ \- Z4 A5 \- x/ O' |. |
    1288 L# q3 z. t- J( @
    129/ W- a1 G+ |! r+ M' i
    130
    . p& P2 G9 S2 R; u8 ^4 w1319 |5 D1 L5 E! w  X  D
    132, s0 c+ K8 _: C7 ^9 v# X- Y0 [
    133
    % o' v  b' v, F. ~2 e: {134: H& i# _' J7 v$ Y8 X" D9 j
    135& O& L, A3 T4 g; j+ V
    136
    0 k+ |( V( u& p/ i1 Z# W1376 I0 c9 l* b$ h8 h& c* I, F- M- G+ Z
    1382 z5 k  H1 p7 Q4 ?- Q
    139
    & \, o  K7 L0 i4 e0 w! X- g7 C140
    7 t# D; j% r+ y. x" [141# y8 L; |$ L/ n1 {8 z! Q; l
    142
    2 @' F" q( h. |  y4 G: {1432 _% b2 I6 q* e; t
    144- i2 Z5 t3 A& N+ H0 [
    145& h" N4 S% q. x& u6 K' T
    146
    ' Q9 i  a/ k8 S7 e( l* k147
    * d) z) G, I' z4 c: _% |2 b9 j148  A/ g& u4 a$ B: P8 f, N8 g
    149
    ! \0 Z' O7 ?' f+ j! d( L150
    8 ~% `! \7 i8 o" |151
    3 h8 F% q. N! X( F152
    ' H% V: P/ a8 O* f* @153# W9 k: Q; O* `) A. }2 E% o
    154
    5 ?& t, _" S- Z! i' L# V6 }1550 f, b. a4 J  Q
    156
    7 j0 W! W' y" t9 l. W& S' b输出如下:: A5 ]/ v8 A" t) v% I4 M7 N* ]
    3 T8 Y5 h! C) x1 Z2 F& t

    3 @9 c* q6 ^! X  L$ f0 a* n! h3 ]" gtorch.Size([3, 480, 480]) ( J% M) m" _7 g
    {'boxes': tensor([[130.8000,  97.8000, 327.6000, 292.2000],3 |' p2 x7 h9 J' A" t' |
            [159.0000, 268.8000, 349.8000, 427.8000],( N' y. p' y! M
            [  0.0000, 282.0000, 118.2000, 429.6000],# P  p6 D; H) d- X
            [ 43.8000, 107.4000, 199.2000, 280.2000],) t8 k0 e& ?; Z$ N, u- f9 Y, ^
            [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])}  |$ U- _( k  |
    1- K7 `  t) R) a8 c* o' w
    2
    ; N5 j) I5 ]9 E) U1 S3
      T9 G! J; t0 \# i4* _" l+ C$ [" o" ^! a
    5
    * I, z% i8 [- n9 K# T" r% @6
    + G4 A# L) m1 I7 t) p0 v$ ~1 N# n9 u+ o# q- B$ s7 e

    " s: R6 j$ h; v' S$ p
    3 M: p( j# F! J: f* _8 j" i
    9 G+ h+ b# X: T( C* B5 F
    下载地址" e0 k: R' z  j8 C
    链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw
    9 R  s$ z1 V8 l4 [提取码:srjn
    ' E* Y$ V: S. _$ M6 `, K————————————————+ F( L. ~( B7 \* a3 L8 r
    版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    : ]: J% E- N' ^- p/ _" J原文链接:https://blog.csdn.net/weixin_44510615/article/details/118496273, x8 ~. w; Q$ U" N" U

    - H2 Q6 }+ A, F* R* K+ T* D4 m( e. M5 r) X
    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-31 10:51 , Processed in 0.426256 second(s), 50 queries .

    回顶部