QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3531|回复: 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* X* h" v$ I( {) {
    深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息
    0 d+ V8 J/ N: \% w0 V8 q+ Q图像标注主要用于创建数据集进行图片的标注。本篇博客将推荐一款非常实用的图片标注工具LabelImg,重点介绍其安装使用过程。如果想简单点,请直接下载打包版(下载地址见结尾),无需编译,直接打开即可!8 }7 R  _% |% ~' V
    9 {  t9 v* a* h' |5 [; Z

    * ~8 O/ T% [4 W感谢原作者对Github的贡献,博主发现软件已经更新,可以关注最新版本。这个工具是一个用 Python 和 Qt 编写的完整的图形界面。最有意思的是,它的标注信息可以直接转换成XML文件,这和PASCAL VOC和ImageNet使用的XML是一样的。
    + P: q" X) j& I" C3 x# G+ w, j9 G) v$ m9 r

    , z, B1 \0 f- Q  A& j2 H附注。作者在5月份更新了代码,现在最新版本号是1.3.0,博主亲测,源码在Windows 10和Ubuntu 16.04上正常运行。/ J' h5 S5 K( G# _' h0 ]
    : A; _! c/ o4 g1 b2 n* r6 _' a

    # l. P. Q& Q1 W$ y7 [+ m具体的安装查看Github教程:https://github.com/wkentaro/labelme/#installation
    0 \+ ^1 L+ D& s& q# @( O$ s- I# y8 M$ R
    / B% L& `0 {  p! ]9 t3 B0 p
    在原作者的github下载源码:https://github.com/tzutalin/labelImg
    5 Y9 o* s8 g* g# Q" r。解压名为labelImg-master的文件夹,进入当前目录的命令行窗口,输入如下语句依次打开软件。
    ; T: ~& x; B7 [. W9 l+ E( u
    8 @2 z. R3 w" \; [; E- o* c

    6 r  T: D' m$ z1 y; H" _) B( \/ Xpython labelImg.py
    ) c7 h$ ?7 P& `0 N: |, U* b6 r  K1
    , M& l4 t, e5 q' U" ^+ u
    - o* m* }0 v& `& W2 \3 _4 [

    0 x; n5 T1 ^& H+ n: C1 j' |; \: F3 {5 T8 N

    2 G& d* H* I: C6 U! ?具体使用* w! ?: S; Q; }. w, B/ [
    修改默认的XML文件保存位置,使用快捷键“Ctrl+R”,更改为自定义位置,这里的路径一定不能包含中文,否则不会保存。8 u4 y9 o+ n) H% |4 v

    4 d  r! i8 h  i& q+ q
    4 P. {- n! g: E1 [
    使用notepad++打开源文件夹中的data/predefined_classes.txt,修改默认分类,如person、car、motorcycle这三个分类。4 T' Q- W" s+ w7 r1 r2 E
    # z; L" {! w9 y6 Z. l2 @! w

    % U! f# y% k8 G( x5 a/ k- `“打开目录”打开图片文件夹,选择第一张图片开始标注,用“创建矩形框”或“Ctrl+N”启动框,点击结束框,双击选择类别。完成一张图片点击“保存”保存后,XML文件已经保存到本地了。单击“下一张图片”转到下一张图片。6 }3 @/ U. P: q6 i
    5 D: |! P7 t/ O+ o; I6 n

    0 E2 l0 _# F7 m1 \& G& n7 k贴标过程可以随时返回修改,保存的文件会覆盖上一个。
    ) F3 g5 h6 G% `3 S# n' i' Z
    : N* J! g6 U6 E3 z

    ; q( c( p7 e! h/ O) D1 E; H" t完成注解后,打开XML文件,发现和PASCAL VOC格式一样。
    ! ^, g/ B, ]! |  s9 Q/ `
    9 f" j6 a' K& [. _* E  v5 E* w  o

    6 Q4 _; U5 n- F2 X/ _/ k将xml文件提取图像信息2 k9 m2 x  r+ t, q
    下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。# |8 N& Q5 |* P6 G$ s, M! S
    - n  w: H1 E! `

    3 v  _3 e) l2 `: y/ }) ~# E$ ^* ]7 @/ n7 t# O6 I+ t5 n. ~  Z

    * n6 c1 D- ]; d2 V下面是images图片中的一个。
    : X7 x; V3 @$ @7 Y! g4 ]: E3 L- G5 ^8 D* P$ m8 \2 X
    2 S2 x; q5 V. z+ {& v5 H2 I
    下面是对应的xml文件。
    ( o# N+ a! n  u* i' Y
    ) O7 p. s$ V+ U3 j3 ?- Z& g

    - D1 J* Y% r$ }6 ]<annotation>
    " Q" K" B9 _6 Y2 `/ n4 V, q1 S4 ^        <folder>train</folder>
    % J- `$ W1 L1 n+ a4 B+ ^6 @2 n. N1 Z        <filename>apple_30.jpg</filename>
    ' b7 U. m/ U! Z        <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>6 G5 i' |: C; d" D* ]
            <source>
    . ?7 h: ~/ M( |/ l                <database>Unknown</database>
    ; V; f7 {( m1 m7 p0 i" ]- t2 p        </source>
    5 C% e! i5 f  o% Q        <size>" k9 J( W5 [, I; g! j$ Q5 A( ]
                    <width>800</width>
    ) j( \" J; s( M                <height>800</height>
    * s' C' F; J7 H, N5 q6 [" G                <depth>3</depth>; a% c6 H! \0 i1 e
            </size>* D( S' a4 l9 c2 V# K# \
            <segmented>0</segmented>
    / L4 Z' ]& O/ X8 `        <object>* U- c, ]6 t- U1 B/ \6 y0 U* i
                    <name>apple</name>
    & y" P+ ?7 [; ?" s5 w+ x- _                <pose>Unspecified</pose>
    # g  A! Q, R5 i6 q& v8 T                <truncated>0</truncated>
    / C& E4 f1 H& N4 |# S, K* x: ?: [                <difficult>0</difficult>* B& |; J- [1 w3 N0 v6 O0 L
                    <bndbox>7 z) o) T9 W' P/ L3 R
                            <xmin>254</xmin>, s' q7 c* J- r3 X& \
                            <ymin>163</ymin>
    * I$ i: d/ C& z4 f% G                        <xmax>582</xmax>
    " |0 b' [1 k2 r6 C3 H& J, G9 e                        <ymax>487</ymax>
    + U: p+ \" w3 `/ O. N0 x                </bndbox>
    ' ~! \+ y0 N2 L" c; v6 r) g        </object>
    - f3 g! e1 {: C0 I0 J        <object>
    % h3 ^1 {; S% F0 W                <name>apple</name>- Y( F4 ^: r* x- x( P
                    <pose>Unspecified</pose># ~! U1 ?% H' H0 n
                    <truncated>0</truncated>
    4 u% u5 G8 }' r. U                <difficult>0</difficult>
    5 Y9 ?: Q0 g7 F: T7 L# H% B0 }                <bndbox>% U4 {: I% T4 X" b) O( Q) J* k; Q
                            <xmin>217</xmin>+ m3 u! l8 o& V! Y3 L% K
                            <ymin>448</ymin>$ m% O% N0 y: I
                            <xmax>535</xmax>+ Q2 Y" r$ b2 ?+ f. J; _$ Z& @
                            <ymax>713</ymax>5 t8 W/ v% I0 k) m) A5 i& [
                    </bndbox>* G* x) m6 o( C$ P  l, ]
            </object>
    : |1 ^( ~6 z5 f        <object>, n% p" k* N. j7 o  Q/ N
                    <name>apple</name>
    : h* g# s( q8 t, E+ y2 P5 E; H                <pose>Unspecified</pose>: n7 ]) J/ U& z# u& B) ?
                    <truncated>1</truncated>
    # {& E  ]; n5 Z" U% [1 T8 r; E                <difficult>0</difficult>% o+ r5 _" A+ N  ~. u" N
                    <bndbox>
    & @5 g1 o! p: k4 S" F* ]. u                        <xmin>603</xmin>
    - P. {9 u0 u. u                        <ymin>470</ymin>) i" J  Q9 g; a5 _0 L
                            <xmax>800</xmax>
    ! T" H# v! Y: \/ ~0 Y                        <ymax>716</ymax>
    8 k; h5 a7 O7 s+ ?7 _1 U                </bndbox>& [# ?# j5 t  {1 Z8 s& l0 K
            </object>
    4 g! t+ \* N5 P+ H% K  q1 C' j4 b. B        <object>% m7 s0 S- U$ n7 T8 U/ q: w& i2 Y
                    <name>apple</name>
    % M- N- l/ ~) @) H+ B4 c3 B/ k                <pose>Unspecified</pose>7 R, |" k* n5 Z. E: I8 f
                    <truncated>0</truncated>8 d4 J$ K0 J) m
                    <difficult>0</difficult>
    9 _+ u4 _; T5 Y                <bndbox>
    ; N* f( W' G  u% P+ z: v: O                        <xmin>468</xmin>
    7 y. G5 T: K  _' |                        <ymin>179</ymin>
    # Q) G- |. J/ N& o9 r9 z; z                        <xmax>727</xmax>  J9 h4 X4 [- }9 F/ ~  O# B$ n
                            <ymax>467</ymax>
    6 D& C% P3 C5 [- f                </bndbox>
    4 T( d$ {1 F1 [        </object>: a0 R; T$ o$ Z( c; `
            <object>/ A: m5 ]- F4 w3 O/ w5 ^5 K
                    <name>apple</name>$ t, k' _5 T7 @6 [! A
                    <pose>Unspecified</pose>. S8 h$ Q9 A5 e4 d1 q9 s4 P3 E
                    <truncated>1</truncated>
    % X. \0 Z& Q  i% Y                <difficult>0</difficult>- O4 O7 e# p9 d; @
                    <bndbox>
    ) J8 g* p' S0 a3 \6 @                        <xmin>1</xmin>
    ; y$ f& t, o$ `8 |' a! L                        <ymin>63</ymin>
    ; i8 ~, R: k: T* k( `0 |                        <xmax>308</xmax>
    ) y& H0 w4 E' N$ X                        <ymax>414</ymax>
    3 n% o( M: ~# |6 W/ \2 p( N6 N                </bndbox>
    5 _) P9 C! M% m& D        </object># m1 q& ^, k6 w. u' \# m9 V1 }
    </annotation>- Y1 K& n: @1 J& b. z; H
    1
    " Z) I) X# u" U1 ^1 E. l2
    * D7 P" f* j, n4 t1 C3
    $ |$ F. Z# S& p7 @46 m& h3 ^; D. S, R% ]+ T
    5- R1 t# Z- P1 p, y
    6
    ; S: j1 C( c1 d: W6 D( u- F7; H* H9 d( K( E% V+ @  J& B
    8: a+ V; `* ]) V9 ]0 y7 y
    9) ]/ _: t# d3 j' [# b8 o* J
    10! {) |5 }8 V  m2 l0 p* i
    11
    4 |# ~% Y- t4 S12
    ' l6 U7 H$ s- v$ K& `1 P13
    , T8 B  v8 D; r" l14
    ' x( U  ?4 q$ G' m5 m154 T3 w4 F& {; ~: I
    169 t  E( W/ s4 @4 n  e/ ]
    17
    # L5 u1 r* e: f0 n. |18
    7 \  R/ }7 E6 y3 N  X& d19! g7 Y, k: ]6 G
    20
    * s+ l" A& w' F3 L4 w: }21/ U$ X4 p9 s/ Q# a$ u4 P
    22; N6 j& p) `. q
    238 i# |4 S# o# X' J- h* ?& a! Y1 f
    24. ^$ z) K7 w+ o. ~4 F& ]2 p
    25
    2 r9 U7 k5 M8 p0 z2 h+ u268 }$ Z% O; Y& z; U. p4 q8 ~  p
    27
    ! R$ W2 j; k7 u4 k: M7 U0 a0 |28. A1 M6 g# _1 q$ X/ A2 t
    29
    7 l8 w" K4 w: Y& g30! b& K! v0 ?! c0 h
    31% A0 }8 A) f3 b
    32
    , R4 ?1 R* N8 x8 }/ E2 a338 z! c3 N5 m: a: U+ T
    34
    ; O( s8 d& B$ W6 \2 H6 m  t356 L! l: v5 v$ I' g+ X9 b
    36$ |$ m/ o% e) l' @
    37
    ' {8 N- n7 u+ v+ p0 W0 n38- e" W$ V: {  Q, C* I
    39" s, c5 E. ]% \
    40
    $ {0 U1 J& |" `7 k: u7 L7 @41
    * }' a, J- w6 U8 A9 F42
    7 ^* a7 ^! e7 G; B4 N43% W: A7 H- l, _) C( I7 }3 M3 J
    44+ A- y3 g2 i6 }# H9 B! ^
    45% Q3 v( \! G7 s! f3 U
    46
    ; F9 a& U( I' l/ C+ }# d7 P47
    ( o/ F% Y, z' y/ `: C48+ }. f2 z9 H# p3 T0 L$ n
    49& B( Q8 d1 G$ x4 ^( A. i
    50! _1 W) b2 Z8 R; X% A* r/ Y
    51
    2 h% z# u- _0 W; q2 B52, E  ]8 _% w: G7 k/ y
    53
    4 J  F- O% B+ j: M9 |54; l. {3 ~2 f( }$ g6 ~9 j  t1 L
    550 ?6 O5 Z2 u9 O; n4 X3 a
    56& J' @; L$ c1 L! u
    57
    4 v# M: h  [6 e6 p- T9 Z58
    - {% ^, S7 Q1 B" R2 r  O! e5 O+ G59
    . Y- S" ^! R! w/ [0 s600 z) S* `7 y$ m! W' ]* |
    61
    3 l( {- t0 u; X62
    6 X0 ~" {. k9 r# {6 f634 W  X& i7 `& j/ ?6 G
    64
    : s4 s, x. z6 C653 V+ M" F) O1 q
    66
    0 r6 `/ _) U$ B" L$ O; d67
    8 c" j7 R- l- _5 y# M68. O; `1 k4 K2 w- z) ~0 p/ d
    69
    3 Q% ^! \- ^2 ~3 \+ z6 m9 {8 ~" c# t$ t708 A# k; T; q6 u. ^4 i4 X& U6 n
    71. k# J! v6 O$ c% v# y
    72
    " Y) e7 m# T! i% d# V* K73
    % w* \8 B0 |/ P4 N/ m74- l5 H5 Z1 g1 N9 H1 b% K. h$ L* @
    将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。
    , g: Q4 t/ X8 g" j
    - b4 u+ [% [3 Z
    . l% P, S/ L9 s
    import os/ i" |8 F) |/ o( g- ^: Z! ~# w* s
    import numpy as np
      e4 e! h3 p* J; i: ^& Z% Jimport cv2
    ' V! x) q& m9 T0 \' Timport torch$ B! w2 R" R# i& X" {9 k
    import matplotlib.patches as patches
    8 W! \" ]3 a  I8 b- v. e  F, ^+ vimport albumentations as A
    ( S; R4 H) `  B, F0 z! Y, sfrom albumentations.pytorch.transforms import ToTensorV27 V3 J0 y1 {5 a' T- Y$ Y9 n' x
    from matplotlib import pyplot as plt
    $ v/ U9 ?7 j5 z$ Cfrom torch.utils.data import Dataset
    5 o+ h* ]) F% ?from xml.etree import ElementTree as et$ D+ B! o3 K0 h; e; X
    from torchvision import transforms as torchtrans
      _% E0 E5 W0 P2 p( y
    3 S) v! F! I- X; y4 D' i

    , D  }4 M' z; k# defining the files directory and testing directory
    ' n8 a! e# @- e. m1 ttrain_image_dir = 'train/train/image'0 C& c6 }! s- V# n
    train_xml_dir = 'train/train/xml'* n# W" L) p/ Q8 q
    # test_image_dir = 'test/test/image'5 N! y# S! w: m3 L  r% _
    # test_xml_dir = 'test/test/xml'
    * y, E( H, @  c4 a1 o1 T) v+ {; O5 E9 G
    ! v9 Q4 W; @, x! H
    class FruitImagesDataset(Dataset):' E2 A' R' x- l8 h

    3 f/ H. S5 H1 B+ \! O

    * w+ a7 n9 z) B" ?+ H- o& f    def __init__(self, image_dir, xml_dir, width, height, transforms=None):
    2 f# b( C& h: f' v; v        self.transforms = transforms1 B0 \' w( G9 r, f* K6 w7 o8 n
            self.image_dir = image_dir
    & J% k; k: z) ~6 u        self.xml_dir = xml_dir
    5 j& H7 X4 Q" n: R9 d4 k5 N* k        self.height = height
    + G! C; C2 k0 W" \        self.width = width
    * c4 d, F' [4 U3 P( J5 |+ b. p3 p7 D5 C! w- V5 d$ s
    : Q8 u3 K' y  `4 a; k. m& n
            # sorting the images for consistency- U5 l3 {4 b# ^1 `, e2 f
            # To get images, the extension of the filename is checked to be jpg8 r" ~6 \0 M7 W5 u- r" E& X9 _
            self.imgs = [image for image in os.listdir(self.image_dir)& E" o6 l6 h/ Z! [% }# y3 k
                         if image[-4:] == '.jpg']- P, ]0 C( g4 i# n" p2 j
            self.xmls = [xml for xml in os.listdir(self.xml_dir)& M2 ^$ q& C  L, Y
                         if xml[-4:] == '.xml']8 P8 g7 {  ^8 a$ I

    ' P# {; V& X" k8 I8 z0 w6 B- C

    * m- |6 B% K( t/ `6 w- T        # classes: 0 index is reserved for background% E' }+ F& X! @2 d
            self.classes = ['apple', 'banana', 'orange']
    + i! m8 E/ f7 |! M+ V( q% Q
    / P& Z/ U3 P6 W: i
    % P) u8 D7 s2 \9 b
        def __getitem__(self, idx):
    5 Y; O2 W# |4 p  Y5 \6 ^2 H( ]8 E8 z) n# {2 R& b% C
    . }. y5 U5 x: [# I* c
            img_name = self.imgs[idx]  s+ M# O" p& F% L9 X+ g# z, @
            image_path = os.path.join(self.image_dir, img_name)
    0 F8 T/ J/ |# m  W# L4 z2 J) x0 n# Q: M5 C, f
    ! ~5 G% s" g! ~7 Z# V3 T& m
            # reading the images and converting them to correct size and color& `' {9 H, w$ |& f- M3 S/ t
            img = cv2.imread(image_path)$ U9 V* O$ l! V# u' h2 _
            img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32). X1 p& z1 T2 A) }
            img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)' [" @' N7 e5 ~1 P4 z( j
            # diving by 255
    ! c, q4 _+ Y* k& U6 X        img_res /= 255.0
    , n9 ?' l# I/ ?+ h( A' u* S" L
    ; \  g! ~" C/ z6 q# t
    % B/ V, j9 A0 D  L
            # annotation file
    / ~* S9 M, o, k. c) s3 P8 V        annot_filename = img_name[:-4] + '.xml'
    ( a# N) \9 w; f% Z. x        annot_file_path = os.path.join(self.xml_dir, annot_filename)
    1 ?5 F( f$ ~5 i8 l' v1 a* `. l
    + B. J3 f5 ]/ c$ O, h, D$ M" e
    ( z" x  W" p& |3 g$ L
            boxes = []4 W1 t0 C: C; ?2 ]/ k3 T
            labels = []
    & D2 r9 E3 N  G! c" S/ a        tree = et.parse(annot_file_path)# B7 B$ v) C! N
            root = tree.getroot(); l! u3 \" Y' P* D% T8 n
    - f2 T9 y/ W" c+ k. {& ~* B3 a
    4 T3 ^' B1 s+ a. O
            # cv2 image gives size as height x width4 S8 p- m% B% o
            wt = img.shape[1]
    6 A8 g9 N. n9 g- ^! E        ht = img.shape[0]/ G1 X2 j! p3 v& O

    . D; a" [5 K* a4 z0 w, Q& j- x# q

    + _1 K- L: }# o% t7 J2 n* t' e        # box coordinates for xml files are extracted and corrected for image size given- J$ e& |, B6 ]. G  M9 K: }
            for member in root.findall('object'):
    * {# B3 l  u. H. Z. a0 g- M            labels.append(self.classes.index(member.find('name').text))  ?3 }) N0 Y' W! ?/ i" `0 v
    * }( I8 J3 J, f/ D7 t
    ; v5 D" d$ o4 ?+ ], U
                # bounding box
    7 m8 ~7 |- [3 D! S# U2 j: R            xmin = int(member.find('bndbox').find('xmin').text)' b/ {; Z* P% X7 E
                xmax = int(member.find('bndbox').find('xmax').text)& S8 S1 ^" c* K+ W) Y/ d' `- z

    2 w, r4 o; O/ _

    8 r" r# K4 x& a1 f: n% R- v            ymin = int(member.find('bndbox').find('ymin').text)
    ( K  }; h$ l" Q. K% S* B            ymax = int(member.find('bndbox').find('ymax').text)
    0 [* k: R# S2 L1 D7 b6 f$ U
    # r" v& I1 `% [: s* P8 z+ D
    0 O8 ]/ n, P2 |7 c! ]0 I8 U
                xmin_corr = (xmin / wt) * self.width
    / s2 ?+ Z, L0 Y2 {            xmax_corr = (xmax / wt) * self.width
    - }6 u' p) H7 r, z5 [            ymin_corr = (ymin / ht) * self.height
    0 Z: h/ ^8 q1 D" C4 d            ymax_corr = (ymax / ht) * self.height# q, X6 E2 B- J4 M+ \
                boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])4 G' B4 ]1 r% D# T9 L, W2 j
    ; y  R: R* ]6 H, L5 O, q7 L, j
    2 z3 f# ]: m# K! ]* I- i, H
            # convert boxes into a torch.Tensor
    / y3 h5 M0 Z0 o: L        boxes = torch.as_tensor(boxes, dtype=torch.float32)
    : O; P/ `  v! k9 |' h7 C  |% P- o5 S  u
    ! x8 v. x. q; L, y: l5 l
            # getting the areas of the boxes
    ; X1 @; S9 K: q8 w' p8 Q  Y        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
    % ~5 i2 c# E& G  \; t: ~5 `: O$ d! Z! p5 ~0 v

      M; L! O1 G9 B9 T        # suppose all instances are not crowd4 I0 T8 h* E1 G7 t" Y9 ]
            iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64)
    4 O2 t  R; t; n" r' z9 H
    " m; J- @5 O: m, n

    / Y5 V  h! E0 h) U9 t1 @+ j        labels = torch.as_tensor(labels, dtype=torch.int64); a( d4 W% T+ i# u" ^
    8 ^# L( U' ]/ I8 }7 |
    % e' k, W* B0 U# F8 p
            target = {}. ^+ f; p  N$ A7 B
            target["boxes"] = boxes
    : T* I+ t8 I# F, {& H( b        target["labels"] = labels
    % |& f) v) f+ @5 }! ]        target["area"] = area
    , [0 r' ^1 h) `+ `; H* f        target["iscrowd"] = iscrowd: y* P, x+ G" f  f2 @; `" o7 d
            # image_id1 j4 [- D4 k8 Y9 s; ]9 v/ v- R% a: L7 H  C
            image_id = torch.tensor([idx])
    ! I: i; y: y: }; z) X- \% A% A. |        target["image_id"] = image_id8 m& j# a# k7 e; ^+ b/ K
    + C" [7 v# I1 r0 q" W
    % b* Z. J$ E, x" }2 E
            if self.transforms:
    8 v0 W. w" ]3 R& U* e* @# Y: v( a            sample = self.transforms(image=img_res,8 P$ m; d2 c( ^* e$ I5 @
                                         bboxes=target['boxes'],
    : f& R8 d- [- Q: D3 ^                                     labels=labels)' h0 x, f2 y, J; ^

    7 `0 c# h, b1 ]7 V* K$ T% g6 @( I
    / z" j8 c' e6 m4 S% c1 h" D
                img_res = sample['image']$ V9 S! j$ n% z; M  p8 A* V. s# {
                target['boxes'] = torch.Tensor(sample['bboxes']); u* y9 y2 X. H& V

    7 v6 S; m% b) ~4 p" @2 e5 I
    / V. ^2 u: P6 r* r% R
            return img_res, target
    ) V; w3 M* V7 s2 u3 |  }; |6 P
    . @" k; m7 B6 X, k  I; j) f8 Z
    0 a* G! @( J) Z5 n' G# G1 N
        def __len__(self):6 J  j% Z1 l: e& z6 c
            return len(self.imgs)
    ( d5 M( V% U/ N/ \! ]
    # V; K6 T, R9 S+ C* q$ h4 P

    : ~1 G& a+ g4 U) \' B# function to convert a torchtensor back to PIL image" N8 l! ?4 e* {/ E
    def torch_to_pil(img):) Q$ a; j' L! D/ a( ^% O$ q
        return torchtrans.ToPILImage()(img).convert('RGB')
    . a  H8 P* b/ W+ i/ T! t3 O! {3 [# D$ @
    & Z. |+ [: X! s5 t
    0 @  `* h/ V- J: }6 d

    # d- M' T: ?# u  hdef plot_img_bbox(img, target):
    % i6 T+ g1 v3 F8 T" Y    # plot the image and bboxes
    6 ~/ G2 F- B0 D    fig, a = plt.subplots(1, 1)
    * d& s. ~- I: Y  \8 h    fig.set_size_inches(5, 5)! P3 \6 W6 N* u' U2 @' ?
        a.imshow(img)
    : r0 Z2 c. u  B+ j    for box in (target['boxes']):
    / Q  H2 p5 V( z% m6 q# p        x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]
    4 `& b( m9 _9 X$ \* c: u: d        rect = patches.Rectangle((x, y),
    7 L; }; R5 L1 [2 d7 b; B                                 width, height,
    3 r( \) k+ I6 ^, X& h4 h                                 linewidth=2,1 X0 q- j, J( I4 R
                                     edgecolor='r',
    - h; G8 ]  N! w4 g/ x. P$ t                                 facecolor='none')8 @# f% i' E2 g5 @% E( {

    , B5 Y" f% X1 O; p5 i' z; n

    5 E! y4 G' F& d, o' O5 L        # Draw the bounding box on top of the image
    2 |4 s' K) _9 l* q& g& l/ M        a.add_patch(rect)
    . c" T9 i7 Y' f% Q    plt.show()5 F: q) v2 j) P+ o. K& @5 `  \7 T
    8 w# _5 J. J2 T/ e3 _. |: q
    ( _) l: E/ }  R% `- t2 a  [
    4 C& w8 E$ i& c

    + C7 R; A  `7 W4 \def get_transform(train):
    ! B! G: U) y) {4 `0 [    if train:$ ^5 T4 R4 T8 t, I4 }& }4 _/ q
            return A.Compose([% Y' I) C  r2 n, H2 O9 V/ @. b: ?
                A.HorizontalFlip(0.5),
    ( i7 m0 F) K% M" H4 J! R            # ToTensorV2 converts image to pytorch tensor without div by 255
    : {1 F% b/ ~/ W2 c. D            ToTensorV2(p=1.0)% U7 `: o7 T1 M  `; i' w' v1 E5 Z
            ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
    6 j+ W5 q9 p! F1 P0 X/ }6 i    else:
    ( q+ t* y2 w' [2 |        return A.Compose([
    # ~, g2 @8 {' i- H            ToTensorV2(p=1.0): u6 X: J( ^% N1 O& j
            ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})4 d8 I% ^( b- ^, k
    ( ~( i  @# x0 d. U6 ^

    3 Q* e; ^1 A+ B
    ( l& ~5 h+ O4 ]$ N2 X9 e% X4 l
    8 C8 Q0 [* m, P9 F% Y. Q& n
    / |! v5 P0 O$ C* G* t9 ^5 t7 s" t9 e. ~1 S% A

    : `& B  U1 _8 f9 ]. ddataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))
    2 @) }: P1 q& i# F5 N* a& o3 ?5 l3 l; P8 I1 c- Q- X0 e

    0 u* g- B  ?) Q! Nprint(len(dataset))- y! ~% K4 A  a# m/ [
    # getting the image and target for a test index.  Feel free to change the index.6 N& m. C+ Y: A- o6 E2 R0 X
    img, target = dataset[29]
    5 o* K2 o4 m7 h) E! G# r: bprint(img.shape, '\n', target)
    # w8 M/ W' W6 ^* [plot_img_bbox(torch_to_pil(img), target)! K8 m. x: [7 Z" b) G$ E' M) e2 T  E" W- E
    1
    ' T  T0 p  r9 [* b, r" l" _2
    0 s, P0 F" J% M4 l+ F: {) N. X. |3' g% S6 d: `8 ]/ q* v- }2 `
    4
    % ^/ Y: k# \- L4 s4 A; T2 p5' d+ D2 R" w, O. n" D3 j: P
    6& a, W" l+ x3 O" E; G/ |2 {% f5 j
    7- h9 [) h- h7 Q0 ^- c3 F& M( s
    8
    & L/ R5 ~1 z) }* N: ^  v' {) }96 c- ^: j$ {. p. l/ P" c( o
    10
    6 P( i5 l9 |9 E* i5 L* N: R118 t. T/ y: v6 e, {0 J  L/ f
    124 O( J9 H5 @6 c3 w8 K2 O
    13/ m. _; X) k( s7 s
    14
      n( m* E* |9 w" ~# H/ m153 U( r3 ~3 {, M% f/ H
    16
    - }. B/ ^6 `8 D; Z3 X! l9 P) y174 ]$ K* W, X8 E6 C0 Q
    18' s/ P# n" A3 R+ d2 \' _+ y# r2 \+ B
    19
    : R) |  p8 P4 B( I9 A20
    : ], z1 C: f" ]8 J  r% K; V: n21
    3 \$ u0 U) k1 S; H3 h0 v2 x; g4 n22
    / \0 t' V" Y3 X& z23; D& i& l) M4 o. r* p* C1 z
    245 ?, o1 _/ Q  b* U5 h. B
    25
    3 a5 R( Y! c, E* C! s6 u4 f$ B8 r26
    / U; P0 o6 h4 ~% p4 E8 V& z' u7 M27
    ( \9 @9 N3 H8 L$ S& [0 _2 `7 K287 m" {2 N# Z: H, S4 f
    297 q  W1 W, G" n0 c: T" F& P9 |! b
    30
    5 X2 y4 {( J$ F' K/ N7 i31
    9 p: U; b: q/ E8 Y) P* e& v32" h' g  |' `9 P7 n+ G
    33: N5 L- k. Z: @* X0 c% ]
    34- H- V( c8 c) X' t0 k! M$ E9 o3 N$ z
    35
    . k" I5 z* L" e8 R. C! y# R36+ E8 s9 F; g# U* y, _0 k5 R
    371 M9 T1 a! H) Z8 A9 W/ W- b
    38+ ~4 h/ Z) \) R6 F. M: B+ X+ j
    39" M4 r# G- ?) k, C3 l- e
    40& w/ [0 K6 m# F  j+ u) M
    41
      G8 W2 O* l# s+ M42
    % |+ D: B! ?# d43( n5 w& T  P  K! L/ w; S
    44  Z+ ]1 }9 \- _$ p; b! E/ T8 A
    45
    ! F& O7 m. L4 x( d+ f46
    & w. |4 J* `8 b- K' _47
    ) A3 W) L, r+ Z9 G, H- r48
    2 N. Q) I4 ]: c49' _) }( [/ p7 U% s* R1 b
    50
    * O% c7 r8 p- b+ Z, \; c9 W515 S+ }) ]1 B: B8 E2 A
    52
    3 {+ U: V* G) @2 b53
    # K. N; m; f3 \5 u54
    1 [1 l7 G. R+ Y' p  g- H  z555 Y  L6 f; z; w+ }( `# Z. o! j
    56
    1 N, |8 d4 R, g" J% b57
    . G6 R& |3 m( R# \, P5 y7 |58% L1 n) f7 ^, w5 b$ M& ^# Z
    59* p' I) Z& U& C/ G" w2 ]
    60
    , V& H0 K9 D8 U, s# L, Y$ g7 P7 X61: D, G: W/ ?2 K& d8 N6 V2 t8 n
    62
    5 k& F* G( Z3 C3 R7 L9 m63
    ' H* G/ m0 u3 G2 t649 D0 O; N; S+ Z2 \0 }2 Z
    657 i2 I/ |; H) j
    662 p2 S1 f& o- ^8 ?3 n# b
    67
    4 m* C9 s$ L" I4 ^" p8 O* D# L& h68
    1 _0 f3 p" i* N: {+ m5 o4 @# D7 z691 C/ c* H0 p! p& i7 w9 s& |+ I
    70
    5 l9 F) X: P$ i* T, t6 `71
    & l/ ?% O' o, Z' E72- G! m1 J  L/ Q7 t3 v
    73
      D- ~1 @$ Q/ F+ C/ o  @+ g% D/ X% ?74) w/ }# e! B# l( g0 \$ w
    75
    # d0 @. r, i+ k  x766 d8 c- p1 M* W2 g6 X+ H, F$ n
    77. @/ @9 i9 r: M' x  _$ V& u
    78
    , I+ Q" B& Y5 b' G% H79) g! a! d$ j" U5 m" q- w
    807 E' ]1 c, C7 z1 Q/ U! B
    81
    ) n" Q" P  Z; M821 q" V; @& P7 f) b/ M3 I9 E8 h
    83$ \* E" q" C, V! e
    84
    3 x! J/ I2 j' \% a2 d85+ \( Q1 g# L: o. ?8 f2 M/ \% C
    86/ m( C. r0 `7 B5 _) H
    87( J, x6 c. o+ s+ k) E7 N
    88" i  I) Q- B1 p
    89
    9 h7 k3 K' o* d# c5 I& ?90
    7 R( f% O- U, g# a+ V6 R, V91  W0 D/ c% z- ^# }/ A
    926 a1 E* B% Y9 C0 V+ Y! u. i/ x* O. c
    93
    # O( y; u0 T+ [3 `1 i2 ]94) ], V/ M+ k- G. Z3 }6 g& v5 A" ~& q
    95
    " `( Z8 |. ?/ `; H3 x) c96
      Z1 N* ^  r# X& k+ ~972 ~* W: G& z4 K2 \3 U4 Y" N$ M
    987 c2 z( `, W0 P% w% I* \
    99
    0 A3 x! Y6 L3 N, |100/ L6 Y, o0 E8 b- Q1 e2 x
    101
    ; R# M: r; q/ e102: Q; z( }* n% N: D
    103
    & W! Q; Z! {0 f3 @$ `3 O0 x1041 ~( K2 |8 ~& c( [! G- W3 H7 _
    105
    9 h5 {5 R" g5 O' X106# d( E$ B: c( k4 @1 C. U
    107
      K( o& W9 m- J% L9 P* K7 Z% g108
    & i! N9 a, t, X, n109) l4 e' ?  j- j* H5 I
    110- X* \' L) I4 h* l
    111
    & G* ?' S, n8 z$ e5 C112
    ' j/ B3 p$ y9 f* p$ B4 W8 \0 ]9 k113
    9 m$ j2 U; \& ~6 U- v114
    7 E6 w. p4 v  S1 Y3 _115
    ; C% _' `) V' b5 r# l  D116
    4 ]- D8 z+ f6 Y! j& c3 ?# A1174 \6 Y3 t8 X+ X2 K6 |7 `* g, F8 f
    118
    + o) i9 L5 p9 k! B% B119. ^' I9 I1 d) N3 R. A& I! p# y
    120
    $ x% ]) y$ b  g/ Q7 G: g121" R5 Q, i* m; O- G/ V* w* ]0 T2 i
    122. I$ x8 Y+ V9 E# {! L
    123! i' {8 N8 @. g  F! h3 K$ {6 m. L
    124
    : G, m* T, N" u* m125
    / p7 G  B: r" u+ [% L' K1 z+ c126
    & k; H0 i- F1 x& e127# n1 b3 H. n+ m6 R6 l+ o1 R$ B
    128
    3 G% D' b- Y6 s4 [5 B9 q+ d129* _5 y0 Z8 _; T* K9 W
    130
    1 ^0 M$ x( @9 O/ v# _  ~" M) v& j) J3 J131
    3 }, J6 V# ?( b- y% p8 Q132
    ' x! I/ d# r' w  [133
    ! [, x: t* l* X2 I134  ~( S/ B* |+ Z8 @5 J# J: n! U
    135
    % Z6 A4 ]8 u9 Q( N- @136, z8 k( F$ j; _% W& l
    1371 `+ R: ^% F5 P9 v  _7 a
    138
    7 k: j- g2 G( D9 J139+ k4 ^% ~' h9 \$ h
    140
    2 I! J6 r4 Y* q6 {2 A1414 @* p6 S1 ^1 B/ V8 h% A+ D
    142
    * e/ R% J5 j$ E2 D4 v: r143
    ' J# B  M# b$ Y, f$ W$ d144" g# b" h0 z# h$ l; l
    145
    / ]8 Q: j' ?/ O8 {# q146
    9 @! q! v) W7 `# y& P, w5 ~147  _1 L; v& S& b" h6 ]4 W1 k
    148" x2 S+ X: ~0 t" _
    149
    : F) W" X" M" i& q  t2 b' _150
    2 J# {) m6 }/ }, d2 Z2 D8 i/ t151
    . I+ G' K& b7 d* k! u9 n152* X2 I* J, f; v
    153
    1 R8 {' I; O1 O, ~, K6 d+ u154( Y& i9 O5 {, J; ?* t7 t
    155
    / P& t2 S' d; O5 Z/ m7 Z" `& W( d156
    7 Z* @* L% s' y9 |4 u输出如下:
    3 x  c  K7 _+ `
    1 c4 c4 k& K* l, _) S' Y
    # n) u# Q1 J8 I
    torch.Size([3, 480, 480])
      O( F) Z8 k: b4 F/ I) W, i: I. ? {'boxes': tensor([[130.8000,  97.8000, 327.6000, 292.2000],
    ! ]1 r1 S* N5 f        [159.0000, 268.8000, 349.8000, 427.8000],1 Y8 L$ J. Z8 T! i$ n
            [  0.0000, 282.0000, 118.2000, 429.6000],& ?' z) G# l. Z7 C8 ~
            [ 43.8000, 107.4000, 199.2000, 280.2000],5 z* ^, `+ W' B
            [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])}& n; H3 ]- a$ n0 L3 P! `: l" Y
    1' i! x: ^3 R8 P' M/ k! \' L
    2! o' @2 _" `# ^2 l" J. S, z
    3
    " i" e2 [2 \& u( M" o- W& M41 k! v0 B. Y, v# [6 {- n6 Y' f
    5! D8 l  ?. u5 k: t. O( ?
    6; \5 |( l1 ?4 {4 B: R

    ) G# J2 }* @0 x4 {6 \  Z

    / n( H7 M* d7 t" ~+ r$ }
    5 t; J  ]4 J' O1 Y

    1 ?; E9 x. |4 Z3 d$ _下载地址
    - N; n7 T6 [8 x1 p链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw  e1 l0 \8 N$ e
    提取码:srjn2 T4 o' h% i; ~/ S
    ————————————————
    8 t8 p- o6 q' p$ c% n+ y% R版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    / F* {! _+ M9 h9 k  u, V原文链接:https://blog.csdn.net/weixin_44510615/article/details/118496273
    : A- x: j' c# I% M: |. v
    ( Y- f0 H8 V8 R) N5 O1 F
    ) t5 }  Q7 z  F) ?
    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 14:53 , Processed in 0.365036 second(s), 51 queries .

    回顶部