QQ登录

只需要一步,快速开始

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

    / p7 D; k; ~9 D* H" k# w6 t深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息
    ( V2 O: X% r" J* v# r( O图像标注主要用于创建数据集进行图片的标注。本篇博客将推荐一款非常实用的图片标注工具LabelImg,重点介绍其安装使用过程。如果想简单点,请直接下载打包版(下载地址见结尾),无需编译,直接打开即可!
    6 _: w  K' @' F) Q9 j. R/ w# a0 k5 P9 ]4 l' L1 J$ C
    ! @# |+ {' h. N4 A* `9 Y  s( ]. e
    感谢原作者对Github的贡献,博主发现软件已经更新,可以关注最新版本。这个工具是一个用 Python 和 Qt 编写的完整的图形界面。最有意思的是,它的标注信息可以直接转换成XML文件,这和PASCAL VOC和ImageNet使用的XML是一样的。4 I: k( ]% ?1 d, ^7 ]/ x" h

    ( Y. Q0 \2 t. j; z6 d2 P: B

    % v& q2 ^( c2 r, e0 R- u附注。作者在5月份更新了代码,现在最新版本号是1.3.0,博主亲测,源码在Windows 10和Ubuntu 16.04上正常运行。% _- W( w: ~  I* i2 c8 I
    . N4 t* p# [6 g) s
    ! e2 W( e2 _! y( u
    具体的安装查看Github教程:https://github.com/wkentaro/labelme/#installation2 n* j$ J5 ?4 ]0 {7 d: Y
    9 i, o: W: N0 L, f* H5 G, c; ^
    9 j8 z2 y; `7 r% o4 o
    在原作者的github下载源码:https://github.com/tzutalin/labelImg3 s8 z: j4 s2 u: H- D
    。解压名为labelImg-master的文件夹,进入当前目录的命令行窗口,输入如下语句依次打开软件。
    2 b: Y& j3 [5 Q- C+ f8 ?3 P' r/ e! }& _! D- H( O9 t. `

    ! y9 e. a( b$ ~& H# j! Tpython labelImg.py% i1 t% g+ W  b& G' u& f, V
    1- R- d; _! a$ A# g' W

    " t& M/ }1 t# O/ q, Y# a! {! g
    ( z+ w  z, S$ X" e$ C) {% Q
    6 @6 ]" G+ F4 ^, C: q
    , u' T; a: v# h; B# E- O9 M+ F
    具体使用6 m& a; k( }3 U& r, r9 s; L
    修改默认的XML文件保存位置,使用快捷键“Ctrl+R”,更改为自定义位置,这里的路径一定不能包含中文,否则不会保存。) O' B% m2 ~! k; i4 ]; {

    # w2 c+ d/ Q  I- P. H
    7 O% z: O0 t- g- g
    使用notepad++打开源文件夹中的data/predefined_classes.txt,修改默认分类,如person、car、motorcycle这三个分类。
    , n! z. Y$ [& s/ V0 c
    : ?) A* h$ @+ W9 `7 U1 {- I
    & D9 y& Q5 z" l. _
    “打开目录”打开图片文件夹,选择第一张图片开始标注,用“创建矩形框”或“Ctrl+N”启动框,点击结束框,双击选择类别。完成一张图片点击“保存”保存后,XML文件已经保存到本地了。单击“下一张图片”转到下一张图片。2 m6 R% j5 J  v  n! Y" C* }

    0 C& `- B9 y2 B  W( j$ w
    4 _8 L5 ~7 h4 H  V  u7 K
    贴标过程可以随时返回修改,保存的文件会覆盖上一个。
    / h% t0 W" |7 E/ r' H4 o0 Q4 ?$ X! R3 }; G, H2 x

    ! E4 a5 V1 B/ l. l完成注解后,打开XML文件,发现和PASCAL VOC格式一样。
    2 A1 m, _1 n% w& @& ^) t' ]9 Y6 [+ Z3 j9 Y0 c/ K
    + x" f, Q, C5 W7 o) ]4 v# Q
    将xml文件提取图像信息' w* k1 p; W8 p4 B' f8 \
    下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。$ s( U; r% K3 D+ q' A- }

    " f: W! j0 j; [" g& K9 b& m3 ^

    1 S7 c' f( `: n9 u
    2 m: M" a; Q5 s
    7 r# W, u  Q6 X8 H$ ^: h% d
    下面是images图片中的一个。4 h+ i1 G7 o# v, o: R& a
    ; V( H7 `! V$ e! u7 ^$ m) Z7 v: a! @

    ( ?' Y* [: X% V8 s- N0 |下面是对应的xml文件。
    + ?$ F9 a: b0 g# V$ [9 U8 ]" H& T9 [% D7 |2 z2 F

    1 M. F" ~1 \6 ^9 ]<annotation>
    - s; F6 f1 s/ m7 D. n' s1 Y        <folder>train</folder>
    6 f; p5 Z! y( P: l* ]4 h$ x        <filename>apple_30.jpg</filename>
    ( x4 v# X  I3 E) V        <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>
    . y" v, O, i1 p- a7 D; X% o% U* m% I        <source>% K% _+ m+ R& m- K' t
                    <database>Unknown</database>
    # @- X( n" T+ Y" k* f+ X        </source>2 P4 Y; T: X  ~$ f  p
            <size>
    1 o- q# u- J' j0 E2 q3 v1 ?                <width>800</width>! `; y; l5 l( z
                    <height>800</height>
    # p) J. k; p0 b( e                <depth>3</depth>( Z; h0 s1 E6 L7 r* @
            </size>
    1 c+ f/ B0 U1 C" m8 }        <segmented>0</segmented>
    : i- S0 Y( ~( t# L6 Q& T. f        <object>0 Y1 b1 P  |/ ~  g" r- C
                    <name>apple</name>/ F6 E$ [" X0 T8 L6 C+ y+ P8 s
                    <pose>Unspecified</pose>& k  |) H: w/ L) c  c
                    <truncated>0</truncated>
    % r5 u* n: P& I5 c" `7 E8 b1 W                <difficult>0</difficult>+ j! @7 ?9 ?1 p" l$ G
                    <bndbox>
    3 Z1 c4 A2 @4 ?5 h  b6 T, g                        <xmin>254</xmin>, F- V) d  |) Q7 G+ h
                            <ymin>163</ymin>$ h3 o/ h, O: h# y! s: z8 q+ m
                            <xmax>582</xmax>  K' n& s$ Q* h% R' Q6 k2 p
                            <ymax>487</ymax># J( a: \1 z- s$ ?' v
                    </bndbox>6 k1 c: q% t$ P8 K5 I7 r8 i3 B
            </object>
    7 a5 U3 M# J- b+ Q        <object>4 ]+ P. M. D9 |+ `" q, [' N; A
                    <name>apple</name>( a4 l3 l# u# h, x' v
                    <pose>Unspecified</pose>
    1 Y: S7 ~6 G% \) a                <truncated>0</truncated>
    ) `! _& B# }# S' x: t                <difficult>0</difficult>$ s8 G& u, A9 H* ~) O
                    <bndbox>
    . D- K% J- \) Q2 z3 M3 e! q  m                        <xmin>217</xmin>
    * r; y; n+ I) q! D- V! N                        <ymin>448</ymin>7 Y: ?& M4 s( S' a" g$ G) |
                            <xmax>535</xmax>0 s9 X5 F% d+ ~6 S/ G, e+ b% T
                            <ymax>713</ymax>
    $ o, b6 O% U. D% B9 G6 C                </bndbox>
    2 ?- n! J6 j$ t8 L+ Y6 ?        </object>. C& i( X% J( A% C1 R. ~( W
            <object>
    1 q5 ?& x5 w: F5 |7 U                <name>apple</name>, f6 o+ }( H7 X% I+ ~: _; a# M
                    <pose>Unspecified</pose>
    ' |- a1 R* o; v& G9 S2 B                <truncated>1</truncated>
    - c1 a. I) B& d$ y! W* [9 U: e                <difficult>0</difficult>- w- G$ q% L; W& _3 `% Q7 F
                    <bndbox>
    1 q( y6 Y; Z" H: ]7 \$ k8 P7 E                        <xmin>603</xmin>
    3 m% H# ^: ~3 l7 x                        <ymin>470</ymin># n0 P6 m, X% ]  ?
                            <xmax>800</xmax>
    4 U2 A, [7 T+ I+ y                        <ymax>716</ymax>4 t, s/ m0 }! e: m
                    </bndbox>
    3 l. @2 T$ I5 R5 {+ ^* o/ n        </object>
    4 V; f2 ^% K6 |3 M& ^        <object>: C& A8 v3 X8 p$ o" O5 _3 q4 z9 L- `
                    <name>apple</name>4 m# @- x7 b4 ~2 \$ Q4 |
                    <pose>Unspecified</pose>( s3 A- n1 `3 D. p% \; o5 t9 a% x
                    <truncated>0</truncated>
    3 ?) x: W7 l( e- a. p                <difficult>0</difficult>- Y' p$ j1 t% ?% r+ j7 z
                    <bndbox>
    : V  z; a: i6 G( K* v2 w8 O/ _. r                        <xmin>468</xmin>
    % D. v) x' D0 H5 n                        <ymin>179</ymin>
    " O+ n/ V) X6 q! T" z" m, x                        <xmax>727</xmax>
    & _/ S' O2 Q7 _' ?$ I                        <ymax>467</ymax>' g3 k# s  A& z2 T0 C' p
                    </bndbox>
    . t! a4 ^) i4 |( |        </object>+ \1 S& h$ @, a& u; f2 P5 A
            <object>
    $ I& b) x' |* f8 A! g5 ]0 N7 u% {! X0 C6 i                <name>apple</name>
    5 @0 ~' |! D1 B                <pose>Unspecified</pose>8 S/ V) H; ~* l( x
                    <truncated>1</truncated>, D1 I0 c! H  A1 n
                    <difficult>0</difficult>7 X* p8 P  E% ?( J5 }
                    <bndbox>( ]/ @2 H& E: ]8 O% z# S1 O% n
                            <xmin>1</xmin>
    1 [  B6 l7 w" e6 h7 g9 R# J                        <ymin>63</ymin>) K/ ~/ ^/ u. Y& j
                            <xmax>308</xmax>$ T0 Q  F0 |, O) B% s
                            <ymax>414</ymax>
    * A) L6 l+ r! @; ]                </bndbox>
    - g7 R4 N* ?/ V: e' ]% k  w4 b        </object>
    , {' |# M  P) Y5 [</annotation>
    5 n2 B$ \7 x+ W4 g/ s' t& X1: ?! ^; N: T+ M6 O- b- |, S
    22 F6 n2 w$ z. \2 ?( {* v4 @
    3: R+ ^6 j/ c+ p% p1 s  A7 ]
    4$ ^. l4 C1 \) Z' ~, h/ F
    5
    $ W- c. t) t- o6
    . J1 `( C: \' R) {+ U  a5 ~$ E+ q7
    ; @. G5 R3 U" e/ U8, y3 K% Z  J, N/ |* ~
    9, G; H" {6 P" W) A7 r7 A+ n3 I
    10
    $ o' }' a& ^" A" m* z' M11
    7 r3 `( A7 E0 i12
    * _: `) e- v9 r" k6 u) o13
    2 ^# h5 ?1 O+ a, D14
    0 @( d* e* p* {: l, A15
    : L3 C  F9 Q9 b5 N& p3 d* B16) |* [! t! h6 N4 S
    17
    7 [# U" {: u) S0 D$ v; E" h182 y+ W! r" ]: {0 \: b: T
    19
    - \* W7 f) Y9 V* m; P: c9 K3 W20
    * P! W7 o, e# t' o$ M* W21
    3 g6 G7 x( ^* t* s# i& H( W22! {' j! Z" T2 i9 u" P) `; G, C
    23% u: u1 G9 J2 E( k$ E! o9 w) [
    24
    0 [3 Z, G! F- j25
    + }( b+ V0 g" x, ~; t3 e26
    % t8 v: g4 F9 z! t1 G27
    ' W& [9 Q/ r7 b28
    8 G! s5 I& I$ J, n1 b29
    6 h! o9 w) F# H30
    ! c1 \6 j3 A+ V31
    1 g+ z: c3 X2 C' T. N32; D; E, P8 \4 k6 W) P! V# C6 b
    337 l% {% x9 j8 I6 B6 g
    344 w. c% I1 ~7 g* S
    35, q; Y; `! f' `  [4 N' b
    36
    * }# [5 b- V; |37
    , t' ]0 B$ U2 ]" N38* [0 u9 n2 d  E8 X: p" I
    39
    ; E" }8 \% E! @2 z* e40+ Z5 A5 ~$ ]+ ?1 q# @0 ~
    41; i" N( f: |+ X$ ^: k
    42% K) R, _8 W9 @) j% k
    43# r4 G! g) v5 ?. ~# t
    44. H3 o+ V3 R: G4 `- v& w
    45  V( u$ x+ B3 Z9 J
    46% B1 B, ]) D4 O* A) o
    47
    ) O4 y- p3 h' O( C480 Q: U. d& f) e5 S6 R2 W: ?1 |
    491 G) e, X4 e" _5 ^$ v) e) x
    509 q: P7 s, n' ~
    512 q+ L$ z7 @7 s& `8 b- \
    521 g% m. o6 p& }
    537 S" A: d3 T3 A. w+ ~/ n
    54
    1 A' U6 ]+ i5 a4 ~! h& F55
    & N. a) k  Q6 s' Q- c+ p0 h56
    3 V, g# l1 K% S* @0 w. A57
    8 {, v# W% O& ?! f. ^! m58: a  h2 ~/ ]( D4 }  x! M
    59+ H8 `, q: d# h# ]; k
    60
    0 ~& H( U( @1 P1 c- r; v) L4 u61. g: _0 E* u9 w  x7 U& N, Y
    621 j  I' Q! s7 W& C; T- t
    63. U! B+ ]6 l# B& B  O
    64
    ; l# X2 [6 g# ^" A  t65& U+ b% W( ?& Y( \& g0 b
    66
    # D9 O& O# g7 d  }7 u  I- w67' G. e! K9 Z6 l  m+ L9 u# ?
    68: C$ W8 |4 T1 V" n# L- |0 I0 Q: ]1 b
    69# f1 Y: Y, u0 ^5 F* p: U; C. Y
    70
    3 S- R; X* `4 o" M6 L  A. T71
    # j6 J6 f9 Z. ]- n* x72
    7 E: T& v+ @  O730 ]+ b# M8 F+ A% l6 T( O
    749 {! ]0 b4 Q: W9 |0 Q2 t
    将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。
    * l3 p2 p/ V; L1 M$ u' g" G) i
    0 e+ a$ ^7 M1 t6 D

    ; d/ {( S, o, v1 q( S; ximport os
    ) [% [( G; L- ?8 N; aimport numpy as np
    0 D( X" Y+ }! V! _2 _import cv2% N! b! F; ~1 g: h; }' r3 w
    import torch
    ( Q7 P: E# a* S/ ?import matplotlib.patches as patches
    6 }0 H& {% Z0 i2 y6 s; F, Limport albumentations as A
    ! ^/ L2 x8 ]& h1 m, jfrom albumentations.pytorch.transforms import ToTensorV2
    3 L- @; a5 E2 q! C9 n6 U& _3 Z% a2 [from matplotlib import pyplot as plt: ?% M! t( F' a9 F6 x
    from torch.utils.data import Dataset! l+ {! ]- a, S0 T
    from xml.etree import ElementTree as et: I- v. a5 [9 F
    from torchvision import transforms as torchtrans" Y3 H4 w- x) ?! Y2 S
    + k( h% o5 h) L
    # M* S3 u' X5 r2 ~* Z
    # defining the files directory and testing directory1 X1 [% M$ N+ @( u* D( M
    train_image_dir = 'train/train/image'
    ! Q/ v! Y" r$ `  k5 h2 t. atrain_xml_dir = 'train/train/xml'
    5 u0 A4 P  s* `4 N+ ?- \5 P: |# test_image_dir = 'test/test/image'
    2 W9 E! a' Z4 Z" M$ H$ r- P' p. p& X# test_xml_dir = 'test/test/xml'
    - T8 ~+ O1 F2 K4 G! G3 v8 `, ^4 @, s, v

    1 s* G* f6 s+ H5 F% v/ p- A- i/ wclass FruitImagesDataset(Dataset):2 i) y9 o8 ?) w0 H- h+ _

    , q% s8 r7 y! |

    5 M; _: p6 I9 P& V- Z2 i    def __init__(self, image_dir, xml_dir, width, height, transforms=None):* \: ?9 q7 z  ^# X' q/ m
            self.transforms = transforms
    1 P, J; _5 E6 u( `" p1 {0 q- p        self.image_dir = image_dir
    & m. Y) W; ~) @        self.xml_dir = xml_dir
    9 ]4 f" u0 d: r/ C' B# w- w0 \        self.height = height* t' p8 S; f( ?8 t
            self.width = width! y. ^' }% ^% H/ |0 i# Z% ^' w# ]7 k
    1 x4 g8 d; E! d$ ]$ {" U+ r
    * D/ ]% |$ S0 @! c7 a7 @$ Z
            # sorting the images for consistency
    / j! Q# z2 ?3 t/ s8 ~9 p  Z        # To get images, the extension of the filename is checked to be jpg  ^' w9 F& j5 f
            self.imgs = [image for image in os.listdir(self.image_dir)
    $ K* e9 f! r: D                     if image[-4:] == '.jpg']
    : n( }8 o1 D% l. ?) {  R! L        self.xmls = [xml for xml in os.listdir(self.xml_dir)# f8 a: f3 `1 D+ T# m9 ~( f! k
                         if xml[-4:] == '.xml']
    6 l! E5 E8 n2 w5 a( c7 @
    7 [! D; ^5 K( r/ P
    " |% Y$ e* p3 f
            # classes: 0 index is reserved for background7 c0 q2 X1 E; t8 X* n1 k4 s9 P4 u
            self.classes = ['apple', 'banana', 'orange']+ o) `  f1 I, \! z$ \5 b

    6 k$ E& Y% h7 s

    + P/ w. c& R, J1 Y# R- {$ Y    def __getitem__(self, idx):
    7 Z: m; j9 G$ Q; n- W+ H* M) p+ G( g  P( m
    & p$ g' F* u: l4 s5 B0 f8 k! D
            img_name = self.imgs[idx]
    3 Q- t0 \) ^- F- w        image_path = os.path.join(self.image_dir, img_name)
    9 Q, ^: o5 q+ z$ O
    5 J  w& C0 X5 q+ n1 ?$ z

    ) K) h5 D! M% D0 K* P7 |2 T7 J7 @) R/ X        # reading the images and converting them to correct size and color) ^% s3 ^  w% d
            img = cv2.imread(image_path)7 P% Q* k; @! x9 c5 ~$ D* ^1 _
            img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)
    ! |; ~3 r; L3 _$ U" E6 s1 l        img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)
    " i( v6 F0 Z8 a& D        # diving by 255
    : t. ]# |3 i1 x% v2 W        img_res /= 255.0
    - N  Y* U  q6 N  k( Q5 K$ ]
    9 s5 W' W' i1 v6 S5 u) N
    0 k0 t6 _: k4 K( D0 x
            # annotation file2 q$ M8 v& j& C+ R7 _5 ?3 T7 y
            annot_filename = img_name[:-4] + '.xml'
    ! X. K& s# H3 o( h# ]2 W        annot_file_path = os.path.join(self.xml_dir, annot_filename)
    . A& X0 F1 V7 L; R8 M7 Z: \5 W% V# f! d, u$ t+ ?  D+ X

    # j: W; S; w, A        boxes = []
    5 A6 G$ }' D' V7 t3 `        labels = []
    1 i' Z, ?5 a! X7 J5 r* J        tree = et.parse(annot_file_path)
    " r) P) d3 _9 i% @9 H! I% f, ]9 `        root = tree.getroot()
    2 d4 `6 j) j4 S. f3 ]6 n" G% B7 |0 H4 H; \5 C. E

    ! d, p* ?) ]( N2 ^0 G! I- X7 T! M9 u        # cv2 image gives size as height x width
    7 n5 |( X9 I1 [, G4 T        wt = img.shape[1]
    6 g* c, |- ~8 o- l0 Y        ht = img.shape[0]
    8 o! ]1 u& u$ n7 q: V2 B$ x6 _% z- i- c. @' |" K
    * o; x6 a8 j& e. W! p; q% x0 z
            # box coordinates for xml files are extracted and corrected for image size given; H' J7 D9 y: T5 T, u2 q
            for member in root.findall('object'):% f6 A: |- ?1 W4 c+ ~: g# {; M
                labels.append(self.classes.index(member.find('name').text))
    4 i) v7 @  }6 `
    - d* ]* }5 M" H; d; c  N% A% m
    6 V6 W' S( s$ r# H* w" ^1 [6 O
                # bounding box
    - M4 @" ~: x8 j% B$ K& o            xmin = int(member.find('bndbox').find('xmin').text)
    5 _& K1 o6 F+ d) a) e' F3 J9 ^            xmax = int(member.find('bndbox').find('xmax').text)
    1 w# w" k% r9 |8 W+ \. d% R; F% d. R$ U
    ) V0 v) F* r  j+ v3 M2 n+ ~
    8 b0 Z3 ]9 F; V. {. O; j
                ymin = int(member.find('bndbox').find('ymin').text)1 T1 a/ |* ^- F7 W% l- V
                ymax = int(member.find('bndbox').find('ymax').text)8 G( b& s& f0 y2 c) H
    ! C8 Y! s1 m3 d/ C
    " M: l% X* @& H& Z6 K2 @; F' T
                xmin_corr = (xmin / wt) * self.width. E7 ?# Q& i8 w) I
                xmax_corr = (xmax / wt) * self.width  q* C# C. }$ D( n% I9 n
                ymin_corr = (ymin / ht) * self.height
    ' `8 L: Q- A" ?" M' N& T% W: [            ymax_corr = (ymax / ht) * self.height0 r  h4 Y( B) z
                boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])3 a( Q5 Y/ |) V. W# U8 G

    / `* d4 P" l& Y- S
    & W( b/ ]" O9 X7 o# x% v
            # convert boxes into a torch.Tensor( y; h' w: E& \0 p0 k+ f0 n
            boxes = torch.as_tensor(boxes, dtype=torch.float32), R$ H) d7 p" ]; E3 d! e( t% Y" V8 A- \
    # ~+ y* K* R4 E0 v
    * z& i4 D' [+ V3 R$ Y! N( Q3 g% ?; ^% _
            # getting the areas of the boxes1 x7 a, V% V, z  W, g
            area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
    / s/ [$ D5 B! {) q& \- H4 u% P
    9 `' i& e( a# t5 }: L2 L, y4 d4 j
            # suppose all instances are not crowd# p9 y4 F: x8 h' n. V  r" i  F) T
            iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64)
    2 `% E6 E$ D3 \4 ]3 t
    2 O- R2 H4 |8 b8 e
    & i$ [5 D! r' n! t1 S
            labels = torch.as_tensor(labels, dtype=torch.int64)
    4 Y! N) Y  G' o4 b0 m. k' B, B7 z' f
    - t* r6 V" i  e& r
            target = {}/ v% b+ \! c+ B, t3 T
            target["boxes"] = boxes/ F9 I, D2 M9 N- E
            target["labels"] = labels
    7 k3 r; a3 I- ^# k6 M: J        target["area"] = area1 ^$ d/ k3 `. P) ^+ M
            target["iscrowd"] = iscrowd
    5 k9 r$ W& C0 d" `        # image_id
    + K# q5 B  A8 {. ?+ n, {        image_id = torch.tensor([idx])
    2 m$ ^- ~: S' d+ ?        target["image_id"] = image_id
    ( D4 [1 H2 ]  n' Y+ ]3 i! }* r) r' }  E9 ?8 H: X: [
    " @: V" }; f2 R5 d) |; u$ `4 g4 N. A2 W
            if self.transforms:
    & y1 `. z/ U: C* n            sample = self.transforms(image=img_res,
    0 Y/ I7 @5 X. ^; ?! ]' M                                     bboxes=target['boxes'],' \% s* \- A" R- y/ f3 o
                                         labels=labels)  }, W* Y! V5 H, J

    % f) r* u# g7 q9 o7 n! c

    . m; }/ W4 P4 e: v9 _/ A$ _            img_res = sample['image']7 K, d. y. L* c
                target['boxes'] = torch.Tensor(sample['bboxes'])" o; o/ V7 q5 R. T" r

      A+ c# P: |! O

    # e4 i% J3 O, V9 d+ c        return img_res, target5 C* O5 y& |& K8 y( T3 U
    + M' A0 _! r: w, `
      z) x1 L) C2 d/ H( \
        def __len__(self):
    " @% U/ U. y$ U% Z5 d3 u/ J6 |        return len(self.imgs); Z4 r+ Y9 d  u; R' f4 B1 I

    ) a6 [! ~( ^) R$ {5 a. c
    / a$ ?9 D8 z# G+ \- G
    # function to convert a torchtensor back to PIL image
    + X% k4 ?: P. Y  m2 E; F3 c: bdef torch_to_pil(img):% P7 q! u' h. h; Y! R  Y6 e5 |9 F
        return torchtrans.ToPILImage()(img).convert('RGB')
    2 p1 p' \; L: J5 p1 Y
    . U: _# L3 `( l- y& N/ N

    # ?( X+ b/ |! A) {2 L
    ! H* G5 D5 w9 ~2 n" v+ y$ y; N3 {
    7 |8 p% |+ V: r/ t: o' q" D
    def plot_img_bbox(img, target):: \" }) Z' [* B8 G
        # plot the image and bboxes
    ! W8 K, B9 g4 E% W    fig, a = plt.subplots(1, 1)
    % Y3 y/ N' p) j: }    fig.set_size_inches(5, 5)
    % \2 p& e! X( M1 I2 D; g1 d    a.imshow(img), i5 s- y& @  f* {/ ~2 ?& {8 B
        for box in (target['boxes']):
    * [* s) T- J4 w" |  |        x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]$ l* R# S% }: f" C
            rect = patches.Rectangle((x, y),
    $ z2 F; s/ B- V/ j& N: f3 \2 l                                 width, height,7 p! [* k  O6 G9 ^+ _
                                     linewidth=2,
    ) T2 _* f4 B7 x: @9 q* ]$ m                                 edgecolor='r',1 m5 Z) f6 p( u: ?/ h' f
                                     facecolor='none')$ j$ q& k/ I9 a+ l+ R( [, O

    - }/ p; t; v3 w) a1 ?

    7 P- i& s! I4 F$ P        # Draw the bounding box on top of the image
    : ?" M2 V, D' [: j$ f  V1 ^6 F. w        a.add_patch(rect)
    8 Z2 H5 y+ J; X1 o    plt.show()4 Y6 _9 l! n9 X/ j1 T. k9 M2 s
    ( m* ?) F" i9 ?) e1 q$ f

    6 u1 _3 f# k$ @) w) R
    3 m3 F; t( j- d7 n  ]4 j8 P# `0 B
    - g  G% N3 @1 G" U- f; O
    def get_transform(train):3 |. ]9 K  ^* V% S# Y
        if train:& g! J' K) t3 j9 @0 w
            return A.Compose([2 B/ _) f& F& v  p1 K! u
                A.HorizontalFlip(0.5),
    6 V3 N, i( E) F# I4 m- G& ?            # ToTensorV2 converts image to pytorch tensor without div by 255+ [& ]2 J* D7 m* ~5 i
                ToTensorV2(p=1.0)" `% k7 e' X' k) A8 f
            ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']}). c% w$ |1 K7 ^9 m9 A
        else:
    4 Z; k9 F+ V/ l* S        return A.Compose([( j+ k0 F: k/ ~( S" W
                ToTensorV2(p=1.0)5 C' h" w4 k$ u: Q3 k3 K
            ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})& K& t2 g2 p# p) ^/ l
    1 A, g* ]3 i0 l! D% K# v

    " i& ^. @! z9 N  z  O
    5 @, x( z8 F+ W: e

    ) n5 B% C2 q  F" N
    ! @! v0 @4 d' i: F0 l9 [
    0 l0 C" w4 a4 ~4 K" k3 G! J! Q
    dataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))9 @& S0 k. H. h3 W. t5 y( j7 J
    5 d7 w: ~& f/ A( l1 M

    5 U) v/ r# }- y( }4 G# Kprint(len(dataset))
    ; k: ?: ^; k4 I. e! [1 i# getting the image and target for a test index.  Feel free to change the index.
    0 i0 ]7 F  s% ?9 O9 Uimg, target = dataset[29]) M  J" a" N9 L/ @5 q
    print(img.shape, '\n', target)6 u  m" y1 Z9 \& Q
    plot_img_bbox(torch_to_pil(img), target)
      Q- {$ _. a0 V1 @$ x$ q. Z$ b3 l1
    # k- s. J2 C0 }" g3 _2 g2
    ! ^* X% |! C% G36 A6 J( w6 H6 b( q8 Y$ ]: r0 S
    46 k* L: a7 y9 W/ E! N4 ^# O) A
    5/ c/ @' s* g( {% Y( m2 Z  `, O
    61 \- M8 Z* d& k
    7
    . s! E0 P  m3 k9 K1 y# G8 @: u" z6 q8' f7 |! |- D$ C. }6 s
    9; n  w' d) U2 W- y) w: U
    10
    / H; I) A8 x/ A' U% M) l117 L" u% }0 ]. k5 C
    12
    1 z1 z  J  |4 l3 o% }13
    ' F$ [8 T# B+ f" {5 z3 X: o! U: O14
    4 \! H; a# G. Q0 d' n  z. a154 j/ J# I3 E9 m
    16; Y; T, d1 d* G; y6 c
    17, y, v- o1 ]/ ~; w4 h, A9 k7 f
    186 x2 {# G9 W  y; d
    19+ C, j4 \: I3 {0 A% l
    20
    ; C0 ~5 r5 }/ j! e, W, r21) D1 K# `$ e  \
    221 I# V( r' D+ j2 n
    233 G& B" Y; Y9 M& v; R( {, y
    24
    . q8 n+ q4 i' t* ]2 P/ |0 V0 a4 o. \253 l: J' c8 y0 I5 D; ?
    26
    ; x# [) A. s9 ?* c. b0 r: {9 @27
    2 o2 x7 D" _1 M& n28' w0 {4 T+ z3 f4 \6 H/ Z( x5 i7 ?
    29
      s0 x0 k# U  ?: ?' i30% [, e$ Y/ r! x( w+ O
    31
    + g  b4 @0 u- \$ Q32* I/ w: O+ h* N
    33' d8 @' n, I# b& a
    34
    & Y$ S+ r- u: F* T4 V35
    ' D  H3 {! [1 E3 b: _9 h, u36
    1 u- ?: P% [) Z6 a, L: {% R37
    9 D5 ~& z  I# }7 E3 Q38& w! V( B- y# T+ \9 i) E
    391 u+ z: _- W3 D+ c2 q
    40
    ; M/ j$ W0 i: W& M8 _) C( E41! V$ k& M: S) J
    42
    6 X# v3 y+ ^$ G& t43
    * ]: w- z. O8 x# u% B44
    8 G5 H- U& y& P1 L45
    3 O7 ~& Y; ?2 Y3 k+ l46
    $ q! f# s& F, E* R! f7 v47- g% K( L  k# \  ^
    48, Z  \9 U% o4 R: B4 m5 ]
    49. C2 g: N  b" C
    50# H5 M  b7 d9 S# [0 g2 B$ d
    512 x% J9 p+ K# _; L0 D. m
    52
    / G( W8 y. E; y8 i53
      i6 G/ L2 s& w2 y; E$ ~+ M. i54
    $ Y/ f8 Z) V% E) S$ A: e/ K) o9 p55
    ! t/ X. ?; o$ ^7 X6 t56
    7 M- X- H( f$ b" R( b) C7 w571 ?# k3 p3 {& L, }* S6 v( X! l' I/ D% D5 y
    581 r3 r; N0 Q1 l. H
    598 ^8 G4 }) t  h6 X: R: i
    60
    0 k, |: f, T& j+ p61* L. [4 V* l$ ^
    622 x  C5 f, V+ I$ b: b# w
    63
    5 M; U8 {; Z- F; \6 y( d( E; _. b& T% D64
    $ `% z, p7 b: T2 C% B# I: K6 F65
    ' C' O' N* O0 x0 K# D- l% P1 z66! Y& e$ H4 N4 \  }
    67
      a% Z; h" H6 [- K  T3 g1 s$ O683 x. q- S1 A( v$ m
    69; T3 s' y0 a% X8 l3 {0 W
    70
    5 g; U2 ~: j, m4 ], E+ j71
    2 I  {; C( t6 u' `2 B3 j) i' g* a: R72: E4 D+ }( Y7 X+ }
    73! \- L! H# {( [2 t' {
    74
    # y2 V* B* D. P: w$ J752 E) Y7 b6 c9 d8 L+ C
    76
    2 k) S( ^& Q4 A) N77
    $ H  _! i* ^/ ?7 C1 a+ {& F78
    2 C2 o; n- a# o: H6 E79
    & v: {# L. [: p% W2 h* T( E80! l( ^6 H: n: ^
    81& a5 ?3 P3 n1 o- ^* C: ?
    821 K9 r) k* K* t* g6 T; m1 l
    83; v! y# W  v( ^# u- a# ]1 W! N
    84! n$ m" ?5 p$ R. }% c& z- l
    85: }" @6 X  q$ R4 w# X' h
    86
    - c) N+ I  b- u# U: G- Z3 B% f87, s/ z8 s8 J* `2 h; o6 m8 N
    88$ t, O( r; d, z/ j' G; M% f) f
    89
    8 z' U; s" M( {# S3 _- n90
    ( o. q% u; W7 x, I91
    - O& Z  W( q: `' B92! w& ^7 J# @5 ]( W
    930 y4 H$ b) @! h
    94
    0 q; T* k3 b- L" ?; w" w* f95
    5 L. ~1 l& @4 c! t( b6 \; U% x96
    0 z: p( ~' I8 Z( K* f* U& g* G8 v97
    / q, S0 C5 y7 N+ P0 K3 W8 |+ L98
    8 d8 G- T# l, K% R9 z! S& H! a99
    . ^* R' R% _- |) Q+ N  A" Z& i- |, L) L100; Y4 y" P. ]) O& }3 m7 e- I
    1016 F1 o+ w* w& K, N# w" [/ F1 G
    102
    ( w6 Z5 |2 k/ \+ V# v103. c, k+ K/ R2 @; z% b
    104" l! t4 h) L+ ^# z
    105/ `+ @- ~( K$ s& h: P: a$ `$ g
    106
    & P8 J' b3 k6 R107
    - @* |, X( [7 [* M) d/ f$ a) M# d108
    7 ]$ j  N8 D) I- z. u; a1091 u/ ]& |! P' d/ Q, V5 y- ^
    110. H$ O8 c/ P1 {$ L8 E& H
    111) c, E, X8 m& S* \& U- v
    112% b$ u2 B$ B( t' Z  N. J' t6 \/ s
    113
    ; F- S- w" C) ^# h: U1142 w6 b' ^3 l% t- m
    115' _" k4 M% r) P1 }# Q/ U
    116) m7 S( R( _7 s
    117
    ) C- A  r) O# ~( z118
    - P7 w5 B& f* J. P1 n' ]119! f/ Z) g2 i% K  b4 m
    120  s% r3 b8 v5 h) v, u( v# I
    121
    : \: [( u# t/ F: l, {7 ]6 V7 z8 E122
    1 G$ O6 {6 X' G- ]1 J123
    ' V) |3 ?: [1 \* U124
    . e- O4 O% _* E0 `4 w125
    - G2 [, X' r- _- e) h7 [; G: h1265 a; m- _" S3 P2 g7 v  @( \
    127
    1 {  p# R+ L: [0 M/ B4 ]  q1288 m$ y' q  A* m& Q" [: P
    129
    " h# e+ ?. ~% ^* k130
    ' k6 f$ _6 A: K0 v# k2 K1311 C) `0 g$ I$ y6 n: X3 j# g
    1328 v# h! m. j& N) D
    133* h# @4 L/ I* V- c1 I5 s- U* ?
    134  |0 h; y( U9 A# s  }
    1352 o8 v9 s  |+ x- h
    1369 p+ y5 A/ }& }. j/ n2 f
    137
    ' E  l0 R  e* J( k! P' B1389 Z4 ^; }' j9 s$ s
    139
    # d3 N7 j4 e% D+ r# o+ W# S1406 T. {* k9 s- K& H  W5 \
    141
    : i% A1 R5 p& n* E( B- `) |0 B142
    ! w/ g% z# J7 U8 a+ k3 D( D1432 v, A" o) T5 u
    144: i) N( |1 c& c* z6 P
    145  S$ j# S) o' K; R
    1460 |& p7 p3 @9 m" h0 _, g  M
    147
    ' G4 _2 I1 r; _. f" ~0 F5 p! C148
    + s' g' f6 Y& Y! |0 h2 G149
    9 l# ^1 f1 u! ~, s" ]' D& Q150- B, y+ A7 {7 h, t* m, C/ @8 P$ L
    151$ B$ r$ v3 a% g- P
    152  @. j% M& ]6 h  O' Q. S
    153: O! q# ]' }& u/ }, @, q$ _* v
    1547 i  p& N) f9 R% `
    155- R# s8 @4 l! M' i+ J/ U8 s
    156: e: Y) W  ~. w) S$ a
    输出如下:
    $ }7 O  z" D, c# I; X6 h- V+ z, V0 a& o, \/ \& l1 d

    ( V/ O/ B% d: {torch.Size([3, 480, 480]) 3 Y* l2 x0 X& k# H
    {'boxes': tensor([[130.8000,  97.8000, 327.6000, 292.2000],* N6 _' N% |* C% d4 i
            [159.0000, 268.8000, 349.8000, 427.8000],
    $ G& D+ v8 @) k2 U# ^        [  0.0000, 282.0000, 118.2000, 429.6000],( y  n" g& V) ]' `: l9 C9 E
            [ 43.8000, 107.4000, 199.2000, 280.2000],6 J" x. b4 N( `& j
            [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])}
      v* j% Q$ |5 e6 Y; w1
    3 E* ~  o) y2 a2
    * ~6 [% \. L  M; o. d2 P7 c3
    1 O5 c' |) z( R0 o4" E9 X0 B3 g! e
    5
    ; R  s8 [( f' V/ q' p1 L. q, D6- j% |: f7 L/ M1 b. v. Z
    : ], h# z, i1 d1 d5 B

    3 B' j6 x7 g6 V' E$ s- S2 T
    6 ^! r' [  i: _  `- Y
    5 N: b: l% A! G( K* x. t
    下载地址8 q6 u/ d6 \; i! y. O
    链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw3 h6 C# m$ B  f
    提取码:srjn
    : A0 {8 B: R& z————————————————# V' {+ Y% h) O# S
    版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    1 i% @6 _; b4 P! e0 k原文链接:https://blog.csdn.net/weixin_44510615/article/details/1184962730 a1 b6 v, X9 f8 r

    . U3 }% a0 S' P0 l- }( `5 `3 p2 @
    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-6-16 05:05 , Processed in 0.470112 second(s), 51 queries .

    回顶部