QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3426|回复: 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
    8 H; W7 T8 `* K
    深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息: n1 E) ^* F# X' ]) ]% e5 H
    图像标注主要用于创建数据集进行图片的标注。本篇博客将推荐一款非常实用的图片标注工具LabelImg,重点介绍其安装使用过程。如果想简单点,请直接下载打包版(下载地址见结尾),无需编译,直接打开即可!; i+ ?/ ^1 j- R0 G/ Q) L
    7 F/ W4 I/ b: {3 G+ X) g
    ; L% G8 [& E2 J$ U1 J/ P
    感谢原作者对Github的贡献,博主发现软件已经更新,可以关注最新版本。这个工具是一个用 Python 和 Qt 编写的完整的图形界面。最有意思的是,它的标注信息可以直接转换成XML文件,这和PASCAL VOC和ImageNet使用的XML是一样的。) c$ K4 k% t) z/ O! ?3 N

    / `) J1 p: ?  B. @) _, y" {  M* c
    3 C+ D9 Z/ D! M
    附注。作者在5月份更新了代码,现在最新版本号是1.3.0,博主亲测,源码在Windows 10和Ubuntu 16.04上正常运行。
    3 S. x8 H4 i# H) |7 ]/ L+ I, H, G# H0 p. f" |7 _  n1 l: U
    4 j! F9 c& q+ \6 r
    具体的安装查看Github教程:https://github.com/wkentaro/labelme/#installation
    . c) F8 J: u1 S) ^$ K
    5 j7 Z. j5 Z( _) q  A- F. T, ~

    ) z5 E4 K; W' ?/ I. l在原作者的github下载源码:https://github.com/tzutalin/labelImg
    ) o& A% Z( t& }0 b$ l# l。解压名为labelImg-master的文件夹,进入当前目录的命令行窗口,输入如下语句依次打开软件。
    . A% N5 i& b0 }! J# f' n
    ; p; A% x+ v8 d0 |' g

    ! f; \- E4 q9 j! e- ]/ bpython labelImg.py
    / r7 G" ~, i2 H, g1! A  w3 B9 {7 ]0 {, A+ u% ^
    3 z. Q: p4 p7 p9 I+ P* L* h
    ! P0 l' C3 z7 `4 v! \) `

    + p6 }% E+ z2 p& U

    * t) s3 [4 C& ^; S, ^具体使用
    ; d5 r0 _$ l! d# H$ b修改默认的XML文件保存位置,使用快捷键“Ctrl+R”,更改为自定义位置,这里的路径一定不能包含中文,否则不会保存。$ @0 J4 d3 u8 ]0 _. |; B- i! n

    , c9 k# p- l' Q3 b0 A, e

    - C6 S) W# R5 F: {4 F) Q3 o# D$ W. y使用notepad++打开源文件夹中的data/predefined_classes.txt,修改默认分类,如person、car、motorcycle这三个分类。
    # w. r# L1 A7 U  [+ E* @6 y$ q
    ( `4 D- q- o: z+ E
    * K3 m1 g2 ^* O3 z- z/ {' [7 i
    “打开目录”打开图片文件夹,选择第一张图片开始标注,用“创建矩形框”或“Ctrl+N”启动框,点击结束框,双击选择类别。完成一张图片点击“保存”保存后,XML文件已经保存到本地了。单击“下一张图片”转到下一张图片。0 e2 R3 Q4 \5 w8 i% P9 l

    8 r1 z+ y# M5 p

    5 e' X4 h2 ]! u# q4 r( n6 v贴标过程可以随时返回修改,保存的文件会覆盖上一个。) y4 E8 i2 c+ e" F, E4 l, L: w, ]  i

    + U; \9 x( w# w0 k
    ! H1 w" _: n: R* ~9 X
    完成注解后,打开XML文件,发现和PASCAL VOC格式一样。
    - e) Q, T" o6 X/ x/ f! C9 o2 X7 W* N) _9 \. n% `7 _4 V7 X* v
    1 ?7 D. c/ \1 e" i! I' p
    将xml文件提取图像信息' M8 `8 {0 J3 K5 F0 ^. F( _% d, G& p
    下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。; y7 _# m' U4 C. o
      ~7 G6 h9 [& y0 n8 e6 e

    3 u8 C/ }/ M3 d+ g; I6 R
    * I- d+ h" T: Z0 j7 s  W

    ( d+ G8 h% u" _# U( m3 E下面是images图片中的一个。
    7 P. Y5 {# Z- q% ?: B
    # D# m2 L. e: E" H9 m6 e
    ) q" q' ~2 S9 n
    下面是对应的xml文件。" ?# n2 J9 q4 R: I7 w

    % I! N- k9 b# c- ?' R+ \0 ?/ M

    ! [: j% U+ {9 @' U: h; F8 k<annotation>8 A. R) V' \+ A. g# |
            <folder>train</folder>
    & U/ [/ j1 R6 a- S/ z5 C7 G$ P& B        <filename>apple_30.jpg</filename>. ]7 Y4 i: ^& q+ M9 q) w: S& H
            <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>
    % ?5 A) ]% R$ s7 P" I8 X& p: ^        <source>0 e. j( j7 I1 P6 ^# w
                    <database>Unknown</database>. N: h1 K( I) P) B4 b
            </source>
    ) H& d2 p5 U, d        <size>9 @7 q$ g2 W. c/ I/ e3 Y% w
                    <width>800</width>
    $ ?3 C3 u! O; f4 R                <height>800</height>
    $ w8 B  {+ J# n" o1 u2 w! [                <depth>3</depth>8 }# w8 w- A! }3 e) [4 |2 B
            </size>
    " \8 c0 i3 A' R* G; J( x: C        <segmented>0</segmented>$ M9 X1 ?' |) o* V" p) M. o7 I
            <object>7 Y: {0 t2 R/ y8 Z8 o/ l9 v& g
                    <name>apple</name>
    $ P7 w; _4 H* i: N# W' O                <pose>Unspecified</pose>/ Q. f9 I  @7 E! ^/ y
                    <truncated>0</truncated>
    9 \, Y/ ^/ M( E7 _0 y                <difficult>0</difficult>
    " V8 M& [+ P8 g- |( F4 n0 m# _                <bndbox>
    % N) Z) p' C# q                        <xmin>254</xmin>$ Y; {/ `9 S5 l0 U8 m2 M
                            <ymin>163</ymin>
    2 `& o; e" {! U0 }. U  m+ L. i                        <xmax>582</xmax>' j3 \5 f5 ]( ^$ s2 ~2 C
                            <ymax>487</ymax>
    $ k# d  C* M) M1 a6 f' Z                </bndbox>
    " a- p7 G7 D8 @        </object>
      z# L' \" j/ k7 R1 {        <object>
      l  P1 s- O" e9 j) h2 D# ?                <name>apple</name>1 W7 d1 ^. u) }! v! p" A
                    <pose>Unspecified</pose>
    8 u* Y  R& y8 D$ G# Q+ w                <truncated>0</truncated>
    " l3 T) f: u4 _+ Z; C                <difficult>0</difficult>% G6 P& M# N* [1 K! ^6 [: R. Y( s4 B
                    <bndbox>8 S- L" s5 W% _; t1 ~
                            <xmin>217</xmin>
    ( Q8 r% e/ P+ _" m1 ?$ F# f' _                        <ymin>448</ymin>* ^  v$ ?8 ^7 G* L
                            <xmax>535</xmax>5 ^4 z+ J' D6 R  r3 P3 G
                            <ymax>713</ymax>* i& c' ]& n; Q( z4 |7 @
                    </bndbox>
    + y& H+ z, U; c4 |        </object>4 O' m4 f$ f. K* e# B
            <object>: W' z% J6 c! K9 X  V$ K' b
                    <name>apple</name>  Z% y4 t5 f; [' z
                    <pose>Unspecified</pose>: V8 j' g6 {5 t% L0 }! Q# `8 ?) ?
                    <truncated>1</truncated>" y* f9 f6 M8 s/ x7 Z- Q% W& g
                    <difficult>0</difficult>3 @8 K4 Q9 ?/ }! P# N
                    <bndbox>% `9 _& `7 e3 u, _
                            <xmin>603</xmin>
    - Y2 u) s7 B$ j  U( ~5 p; d                        <ymin>470</ymin>4 s: P2 F/ e; T4 ^) I- @3 @4 u) S
                            <xmax>800</xmax>
    5 T* p" Z/ _& k2 ?4 k7 P                        <ymax>716</ymax>! ]$ @( s* ^9 F: f  I( q! s5 D" `& u% a
                    </bndbox># d3 y5 J& @8 |; H. M! w, Z
            </object>
    ' S/ X6 _* h/ b' k5 y# e) c& }        <object>) }* i+ l  H8 R  r3 [, W
                    <name>apple</name>* n* h7 ~4 e- f8 R
                    <pose>Unspecified</pose>0 H8 V) s& g- k6 V+ l( G2 k
                    <truncated>0</truncated>
    8 w" A+ I5 f9 w" {1 `) g& v                <difficult>0</difficult>' C1 h/ }0 W4 G# e: J  s
                    <bndbox>
    6 W9 C* K3 a2 B  k/ e0 k/ w  g8 N                        <xmin>468</xmin>) O, U8 V# q5 Y' u/ d9 R
                            <ymin>179</ymin>8 C0 f$ D! p4 F* S7 r4 u! R9 z
                            <xmax>727</xmax>
    7 m2 J' {' Q( t" _% `                        <ymax>467</ymax>
    $ e. A9 Q7 I7 |3 ]& k' ^0 [                </bndbox>% E$ N& M/ {( k+ V, ~
            </object>( O, l* ^( p( T$ C
            <object>
    # S' Q: e' W* H; i; L                <name>apple</name>
    , f6 s( m6 m3 V4 q                <pose>Unspecified</pose>
    1 R. @9 m- H" f3 ]                <truncated>1</truncated>
      X2 z5 Q/ J2 h. k                <difficult>0</difficult>
    % X1 j/ t( `/ a7 ?1 Q0 T! H; ~, t                <bndbox>
    ; q9 X+ E. M; i" ?+ c9 M- Z                        <xmin>1</xmin>. L6 a; C; q( z8 I# R' i$ X: I1 g
                            <ymin>63</ymin>" c! H/ C+ ]- x0 g
                            <xmax>308</xmax>) j4 P3 J2 E, p; i+ l5 I
                            <ymax>414</ymax>
      s- t6 a- w; q5 z                </bndbox>( j' d3 ~" B2 R; M
            </object>
    ) h5 P; T& y8 }" K2 V3 K</annotation>
    9 C& L/ D/ V; E( E& j0 l1
    3 C! r& [9 r/ ~4 L4 |. K& n1 i2
    ( Q; f# B6 _9 h1 c2 M! s3
    , u3 w9 k+ X: N2 A$ V4
    ) R* P4 W, e( e$ Z5
    7 ^" L5 J, ~' V+ ^2 N, a* Q6
    ' {8 I2 _- p2 P1 V; ?75 h, W& h, x( p" }8 M. W& \, T+ J5 C
    8
    * h# _6 X. A, Z5 ~2 h0 \9* ]( l7 D) m5 U$ Y* @
    10& y' A6 x8 U+ A* S
    11
    9 j* Y9 l3 V% n12
    * Y) \0 l& Q/ Q! O& _" N' z; S4 x7 C13, [; C) I. O% h* @. ]# q
    14% O* ]3 D+ L- B8 O0 U6 \
    15
    + j; ?; x9 r0 N16
    6 j: \9 ]1 T/ T/ y" X& N. g17$ J3 |5 E/ Q& i; M+ X' n/ K
    182 d% |& @) \+ `! G
    19
    8 [9 S2 G' a; A205 }" L0 [! Y' V( ~. R
    21  i3 p0 @# A6 W8 L1 K8 V
    22+ q6 j9 d: Z6 v, h
    23
    ! }5 W) _5 R- w6 T9 X5 p2 E( m24+ u0 [" B0 Z3 b; Z* Y
    250 T1 c) Q+ Q* X
    26
    * k! W' C! }$ V8 r! H27
      k9 Y+ `. D" K1 j: Q& ]. l* q28% t: R# O1 p, Z: R+ r3 \* s. T
    29
    0 U$ W. N% C6 E# O30
    * r$ x* r7 i5 X; ?) n0 r31
    ; |3 R# q* Y! e+ X  L& G- q/ {32: ]6 g/ x- [0 \: X
    33
    7 A- I# d9 {+ s% B% j$ G- i34) d2 z; S$ \1 D& F# {' H
    35
    9 \5 P3 X8 x) g3 \& N+ Y36
    4 F, O. F+ @0 \; ^% t& n6 `37
    . `2 J9 x& J: p2 n3 U- E* j38
    7 ?* Y& E' i2 T# E  ~& f$ o390 Q+ P& ^/ q2 @1 D" W7 W
    40
    * Q% l& Y6 ^" H7 A0 v9 |41) e9 v9 d: D7 F
    428 \1 ~6 y' P- M
    43( m% P+ b# V0 s$ ^, K7 H* u3 b
    44% n) X$ ~# _$ T% t4 d" y
    45/ D' U$ n' U. T6 Z  F
    46
    + y  q" Z3 F( j" B& Q# U47
    4 U/ T1 C/ O( O1 Y0 A484 M: I2 E2 L/ d: {" Z5 Y" |
    49
    0 Y6 _5 A1 z6 p$ q50
    7 a$ ]! S* x* q( d6 g4 M% W# Q51
    4 V; [- b7 ], b1 Y: F" f5 j52
    $ d- E; }: Q  j+ D53
    - |. Y5 a' |: o548 e+ M* l& w+ Z3 {6 G
    55. t! W) ~$ \$ v
    56
    ' A7 }% A" F5 z* @' @+ Y57
    9 R. A2 b! E# X7 U( V1 ^6 ]58
    # q6 x- k/ K& a+ U6 ?2 X) W0 I59
    ' @9 M; F1 ?+ ?0 h) {2 u( j% N# K60
    * a5 K2 I" J. w- S# n) }# _) f61
    2 M# R1 r3 Q* W! H% w; J# B62' J, y5 b  @, A; ~# I5 ^
    636 k* C* G9 }2 N8 X
    64! j  Y) D7 i7 V
    65( h9 V  @( H* O+ U6 ?2 l6 B$ Q8 C
    66
    3 q5 Z5 O- o$ L4 m# T* j671 x# c) b/ e! A! p6 ~+ Q
    680 ]: u' c. b' x( m8 m4 t3 R
    69' ~% i" @9 ~, t- F8 q
    70
    % `2 v+ X( E/ ^+ _/ ~; W+ X$ L  e. F; W711 e$ q& L3 U4 _+ q* h
    72
    " f: j  R$ R! |% @" Y4 d73
    ; K7 c8 l9 j. r1 T$ g74' k# [4 j2 Q( D: O
    将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。- t6 ?# L- X$ o

    2 M) J& [: x; g

    / y: \6 o2 N1 qimport os8 I& S4 Q6 _% }, ~
    import numpy as np* l$ |8 v' B5 B% ~7 p, g" p. `) I
    import cv2" {4 G0 y$ M( A- K- Q7 \
    import torch
    * z/ B( Y/ q. q, x+ h( d5 timport matplotlib.patches as patches' b* H" C7 u/ P: c- I/ W6 g/ t
    import albumentations as A
    * k; w4 Z! t9 X* t; n3 ?from albumentations.pytorch.transforms import ToTensorV2" y* I& M+ i9 Q& q; ]4 _3 L* [
    from matplotlib import pyplot as plt/ [2 y$ ?3 v* F' L  j
    from torch.utils.data import Dataset4 _: ~6 h  {; [& t
    from xml.etree import ElementTree as et
    + Y8 F( {# W  I! z- ufrom torchvision import transforms as torchtrans
    3 k' V4 ~" O6 D4 k5 y' S. V! ]; T3 [) V, ?: a; }

    ' ?$ y) ]  F% W1 Q) |8 p4 \' y# defining the files directory and testing directory0 @6 U  f  m( B: j- K9 C5 I
    train_image_dir = 'train/train/image'
    2 E3 O  M/ e5 Z! Z. S% F; l: z) Xtrain_xml_dir = 'train/train/xml'
    # A# v. i- l2 I0 U- _8 P# test_image_dir = 'test/test/image'( b/ ~6 b1 T; P1 a1 v( ~: C0 e' x
    # test_xml_dir = 'test/test/xml'. \4 l8 r3 C- Y. c6 T4 ~5 l, x0 h8 ^

    ) O. y8 H7 ~8 g- H

    . ~( G& _& K. t% A, N. |3 q: o1 Zclass FruitImagesDataset(Dataset):
    6 C3 C2 z" m; ]0 n/ C) h
    / e& o' j; t" ]
    + |# V- w5 s  P- f
        def __init__(self, image_dir, xml_dir, width, height, transforms=None):" ^5 v* |' q! x, j) D+ Z# o
            self.transforms = transforms; I8 J* W" K# g( }
            self.image_dir = image_dir( l( V6 b* b9 Y2 u8 Q( F- ]
            self.xml_dir = xml_dir5 ?6 P0 E" ~" q/ a' S" C; O
            self.height = height
    ; I& T* k" H' N9 W        self.width = width
    ! V" N) {; o3 Y5 W* q8 i7 Y- ?! e# ^3 E; o7 ~, J* M* R: \$ t

    . }2 K) t% j4 V% z. Q+ r$ o        # sorting the images for consistency/ [1 p/ I* e9 }' {# x) v* h& Q2 O
            # To get images, the extension of the filename is checked to be jpg9 _: z/ M7 o& E: X
            self.imgs = [image for image in os.listdir(self.image_dir)
    8 G# I& R+ R, `( B, c                     if image[-4:] == '.jpg']
    ( D: L: l3 u3 U! q1 K- c/ z5 Q        self.xmls = [xml for xml in os.listdir(self.xml_dir): a- s  ]5 d( d% M1 Z% o  ?1 m3 N# [
                         if xml[-4:] == '.xml']0 {9 D  q" p3 ?* D( a

    3 g+ ^+ l) h( m8 ^7 q* P

    - V" F+ @# P7 p1 i% ^. w        # classes: 0 index is reserved for background5 _: w3 @6 g3 I& ]8 t& N
            self.classes = ['apple', 'banana', 'orange']+ H0 l; g' Q" d$ a6 S' q- o* W
    3 e. b' m8 q7 g5 Z
    4 a8 [3 H( T% \1 }" \- _9 \9 a5 b- e2 j
        def __getitem__(self, idx):3 ?4 r& V' ]' P! Y4 i
    ( T% D% ~7 v; b
    7 t5 ?8 ], F; X+ u& ~3 v6 f$ {
            img_name = self.imgs[idx]6 u% e* k2 T! h
            image_path = os.path.join(self.image_dir, img_name)  C+ b* P  t; O5 k/ {

    7 j4 v( x! K' z' y

    ! ?' L+ r( [$ Y) X" G        # reading the images and converting them to correct size and color
    * _" j0 f+ K- S5 r+ E# q1 y1 z( N        img = cv2.imread(image_path)# g& |0 O+ g( z: v
            img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)! y; Q/ k) b' c( ^- E
            img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)
    , ^. y4 c5 v) r        # diving by 255
    . X  R4 a0 z# l& @9 J) R        img_res /= 255.04 ^4 p9 L# T! X

    4 E# g! ]- _; L% p& i

    ( r/ f6 E/ q+ `% p        # annotation file% @& L1 b# _4 C- h/ Y
            annot_filename = img_name[:-4] + '.xml'9 b3 |  V/ c+ w
            annot_file_path = os.path.join(self.xml_dir, annot_filename)0 }, G2 f9 n* t8 M( }6 c% @
    6 V1 g) B$ L( F
    # z- z* M) g9 B8 a7 U! g
            boxes = [], L1 `" s  J% s& r) P6 A% V
            labels = []; L) S1 ]1 L0 U, `% j
            tree = et.parse(annot_file_path)
    + Z- k$ s+ j* ?2 J        root = tree.getroot()
    8 `# Z7 N, {$ h+ e1 x6 B, [1 u
    & X# e7 u1 X" f6 p; e

    8 D) ?' `1 r: |! i8 _7 U9 U9 ^        # cv2 image gives size as height x width
    2 X7 K" [( Q5 m9 d0 u& \        wt = img.shape[1]  Q/ p3 [) p+ Z; e5 t9 i
            ht = img.shape[0]0 z" d" l6 \8 S, a! [' X  F4 s* J

    # W5 p: s! k: v
    4 I" ~# e( c4 }: ]( |. J5 x. U
            # box coordinates for xml files are extracted and corrected for image size given
    1 V0 Q. f9 h7 v" y9 K4 B5 `' E1 E        for member in root.findall('object'):
    1 p& z+ s# p5 Y% K, D            labels.append(self.classes.index(member.find('name').text)), V: N0 x8 L2 ]+ l
    * p7 n' J  a# }% Q' u

      K# e/ @) ?4 s) z2 b            # bounding box+ ?8 H* L6 u8 y# K1 q7 U  |6 k
                xmin = int(member.find('bndbox').find('xmin').text)
    6 U4 P. `# N/ k6 h: ]            xmax = int(member.find('bndbox').find('xmax').text)
    % I: |( A: @6 P" p8 ^7 t
    2 O. k, k+ z+ l7 u, u  d1 N# P) h
    & B) O4 K( K/ @/ B
                ymin = int(member.find('bndbox').find('ymin').text)
      C  l3 A+ F4 X; A4 ]" ?! v9 Z7 b            ymax = int(member.find('bndbox').find('ymax').text). c' m& \- f- e% D1 r( p9 [

    1 g( f  L  A9 N; Z. Z5 v! B
    " |9 B) y. p( R: U  q; K4 q! w! t
                xmin_corr = (xmin / wt) * self.width  e* l. y/ M; {- K- V6 C
                xmax_corr = (xmax / wt) * self.width
    " y  l. v% c0 X0 M# V' C  N- q! C            ymin_corr = (ymin / ht) * self.height
    % o% C8 g$ A, ^6 `& ^            ymax_corr = (ymax / ht) * self.height
      C/ D! C" q3 x8 q1 O& D, V            boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])0 K4 |5 u7 i% b, ^. c
    * r: e4 I* n2 t

    4 T# W! d! u- j# P+ T9 D        # convert boxes into a torch.Tensor
    . A! E9 C$ ~) |/ E3 a% F        boxes = torch.as_tensor(boxes, dtype=torch.float32)5 N" S# G! B: g6 a4 d
    . K8 J4 P7 N+ s) d& s
    # I! N5 M4 _7 F" Y, @: N
            # getting the areas of the boxes
    9 z! K8 j! v% L. Y, x1 R+ I: A  e2 j        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
    % Y, N- |% h) n6 D6 h4 ~
    0 B6 o: I( L1 t

    8 c, `( b1 m# ]+ h        # suppose all instances are not crowd2 U! l" |, i. G, J
            iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64)
    0 u( x. q% q6 U! D! y. e+ P; b! ]& h# b9 x( _

    0 x+ _, D4 e- S5 J% o        labels = torch.as_tensor(labels, dtype=torch.int64)
    9 x/ [+ r. t8 q6 p6 X- W
    , K0 |% n: W! y) c

    : X/ w( L8 b2 U6 x( Y% y8 M0 |  D5 s        target = {}
    6 T$ Q1 l- a4 u, }        target["boxes"] = boxes0 {. T5 o$ q7 R& ]( V
            target["labels"] = labels& w8 |# q) b, r, X7 B
            target["area"] = area) y3 |/ q3 C( E0 |+ D
            target["iscrowd"] = iscrowd
      K- b7 a9 Z. k" [+ q, ?1 m        # image_id
    - w% S& \+ C+ ]3 O: M7 z        image_id = torch.tensor([idx])
    , O0 u4 I4 d+ [+ i/ h5 U        target["image_id"] = image_id
    # n4 v' W" C8 [3 B$ D
      F, e$ g3 y5 X# N% g$ o4 u! q  l

    3 A7 V+ |( L* \! \1 _) {( b, n/ t. r1 L        if self.transforms:
    . r, ~& O1 j! o8 u  j  W+ a( G( U            sample = self.transforms(image=img_res,
    * b3 M2 O# h; o- G0 I9 K                                     bboxes=target['boxes'],
    * Q7 y5 b9 M5 m- g  ~. F0 F1 O                                     labels=labels)' l" N  [0 l. M/ O  `

    . F8 _& j% g5 B/ F% \3 n" l5 `
    ! \& G$ m- W; I4 C4 ?8 H- X
                img_res = sample['image']5 F3 T  I2 h- q; ]; O# W2 c0 s
                target['boxes'] = torch.Tensor(sample['bboxes'])
    ; A) o+ V+ s) ?: W0 K0 \5 Q' X2 n$ ^5 {  l

    : l& ~8 ]  V! Z* m5 V4 W, L        return img_res, target
    8 o6 O. P( B. |* g& f( ]4 k' R2 {) b2 x0 G. |9 Z9 @1 a

    2 ~4 q9 l; P$ ^$ E    def __len__(self):5 f! i0 j4 u' O: Z9 K0 {
            return len(self.imgs)
    / Q6 Q. {2 x9 G- j7 }5 Y8 Z, N# }3 Q* \+ N0 |# ^

    9 j; R# f! C6 a9 |& T# function to convert a torchtensor back to PIL image9 T* B# e; r. o6 l2 |
    def torch_to_pil(img):
    ' V: v" w% L) W( l8 u3 a    return torchtrans.ToPILImage()(img).convert('RGB')
    1 }3 P* N% l  {8 P0 V, U
    $ y+ s  \5 Q+ }
    + @% V6 n% @# `$ O- n: R% N$ D6 R
    7 w, f3 F! H# z2 t6 f) d

    ( t+ _- O3 `9 x. u6 @+ F3 X# bdef plot_img_bbox(img, target):
    1 w* L- h# _' g) C    # plot the image and bboxes
    * t% ^- V% d+ I5 w' N+ B$ \, p7 h    fig, a = plt.subplots(1, 1)
    , A4 c4 D+ M4 a# o5 _$ L    fig.set_size_inches(5, 5)
    & A2 {- F! z5 |    a.imshow(img). D# |- X: X- f0 X* R5 K
        for box in (target['boxes']):
    $ x2 J- G& w8 p9 N$ y% X# A% V        x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]
    * p$ M" [3 v0 @0 N7 `6 e0 c& `# i  @        rect = patches.Rectangle((x, y),& i$ d* u# z% M6 z# o, I
                                     width, height,
    / v# k) S) A4 e8 l; K4 F1 K                                 linewidth=2,
    # _# a& r$ N2 y                                 edgecolor='r',
    6 h, ^8 ^; w* J                                 facecolor='none')
    $ q3 t  x, W: C4 |% o8 a9 ~/ i' |- c. p* g% T6 e* M

    2 ^2 n  Q. h0 {- O; F) b        # Draw the bounding box on top of the image
    * \4 N  E! }6 j$ y5 S        a.add_patch(rect)% {7 y7 ]/ R- u8 t, r8 ~
        plt.show()1 O% K) q* g$ X
    ; O3 W; X2 ?  Y, l1 p, ^6 n; ?
    % `7 Q4 P* T" |  w% z; P8 p

    * q8 m' b; u# Y- P  h0 P* v# F
    . V( M# V. X+ K! O: |
    def get_transform(train):
    2 L3 j; T8 n# o  U3 B; X    if train:) B$ m% P7 i+ x
            return A.Compose([
    : E% j- M& |; F4 i2 M% N3 E8 d) {0 A4 c            A.HorizontalFlip(0.5),
    ! ?- _; n9 G: O5 \; r$ E  |            # ToTensorV2 converts image to pytorch tensor without div by 255! ?, k' y; s% e7 a8 Y$ {* a- }  e
                ToTensorV2(p=1.0)& X3 I% a$ E; J! z# D1 b
            ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})' ~: W% M8 b$ p/ L+ |# I' ?2 B
        else:
    $ H* u2 G0 {. @3 Y# \& \3 R8 J        return A.Compose([
    2 \( o8 ^9 O$ C) ]/ E( g            ToTensorV2(p=1.0)  ~8 M  R% G0 `" D. @1 {
            ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})* w8 n( E5 Y# u( Z
    / J# z$ y  L6 W  _3 f) ]2 d

    ; w5 F' `; |1 E, I, v, J
    ) I- w* \$ B% B% d4 T0 b
    " a( h# r- m0 E$ U6 o% I. ]

    ; r& O- R% c/ y6 P" Y: \

    # T4 V* q6 C& n7 m0 J6 k+ ~dataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))
    $ P2 B5 U& m& S# a1 t; n2 K; g  D- M3 z! N1 v
    8 c0 J( j4 Q; v0 X; o8 F
    print(len(dataset))
    3 _" `- ]! o1 C9 r' ~6 Q# getting the image and target for a test index.  Feel free to change the index.+ E, C. `& R6 w, @3 }
    img, target = dataset[29]) I" A7 _: ^3 x
    print(img.shape, '\n', target)$ {% {& r; O# G
    plot_img_bbox(torch_to_pil(img), target)
    # }4 u5 A2 s8 {1 U# a5 s, t1! S7 K& k9 k% ]) D% ^6 h( F, j& b
    2+ F( l( u; ~  B# H% D0 [
    3& k+ o( Z. ?2 O2 `# q, @
    44 B7 M/ Z: n" @7 \
    5# ~, \' q, q- a0 U8 h8 N; }3 H
    6
    8 G3 l5 T8 `7 c- @* r3 r0 \7
    + v6 U) e4 v$ C7 t9 u: d5 E9 y8# r9 V# W- a, d) Z1 w
    9
    & N, r( @# Z' P& @, P& C+ g' ^- d1 U# ~10
    " }5 f$ w( D: I" X5 r( G# ^11
      x7 m- E" A: U- O1 e4 n12% P# @: X  b; c4 y. M4 h! ~
    13' j$ N* e: F; @- o+ d! R* t4 w
    14) x; f/ Y4 o  Z) f7 e; s- V" {2 P. D
    15
    7 T0 G1 M$ I8 y* U; V4 ~# N16
    4 s2 ^8 y! P0 x" p* m' [* [; ]174 P( }, B) f# Q' A' E% n; e7 Y
    18, h* F4 K" B( N8 u8 @
    19
    3 ^' k+ |' C; @9 D2 X( c( F20
    9 P6 N+ W- A+ f" y% G7 K+ h21% m. l) y- D& q) U- E
    22
    5 T( z) b/ k+ v- [' i23
    1 w3 x' o% G; y" `24
    ) R3 }8 R8 j' ~257 H/ |! t- \! @, S* D' u
    26
    0 l) V. c! z0 N272 ^* A7 J9 D2 f3 r, \# F
    28% {0 @$ O, [" T- V. V$ z1 A. T2 o
    296 s: F( r) _1 Q$ A& G' e
    30
    1 ?7 P; ]! ]# |  j3 C31  y' s. n. Q; B6 q. g
    32: t- q3 ]5 W" n; u  R
    33
    - v$ r, t4 C  p: h) i1 X7 n* U2 F34- a- J) D* \$ b, z) t8 g. k! u
    35! }: I. }( R/ |
    36
    " V7 |8 b8 r' n1 ~) s370 X, k% u  B$ `+ G
    38' Z, Y/ I5 X6 c& Y! p  I9 S
    39: P9 B* M9 D! Z# a" k/ a. x
    40) p! v, m" N' @* x' t3 e' @
    416 j8 ?7 Q1 Q" x, y$ W2 f8 P
    42
    6 `' Z0 h! ^5 A' _9 D* n# y2 p! Q6 D, Z438 D. @' P6 d% k' b
    44
    2 v0 g5 b6 _  ~9 f9 E  s, n45* d5 C+ i/ b+ e4 v
    461 n$ ^. \, {6 x8 ?
    47
    ; C: Y1 h+ _) M4 B! Y5 l1 j  `486 p* k3 l# P. \
    49* u. x5 n, e5 `% m
    50- Z+ n6 i( R. z. _* s2 S
    51# v( M" U, K& [9 b8 ?
    52
    * r3 B; l  L4 j* F5 C8 }) g534 [: a0 s7 e9 @  W% a% Y. {6 N
    54' a$ p  D& S' F' ]: q7 O0 w
    55+ t. s8 c2 \$ s/ V# V( I  K. B
    56
    ' ]! h1 }8 R  b3 q57" o) r& g) }$ Q6 Q
    58
    $ ^; E  E9 e5 C, a$ `4 ~591 x+ {. y8 y4 S* D$ J  B* b4 x
    60
    0 a. F7 r5 N0 ]# `1 D- g% P6 e3 g61
    # k8 ~/ z" B( ~/ e) G& ~  r1 J) w- o62( @' \. M! ]9 c' m/ d7 u
    63
    , T5 |- v% B4 x5 ]- @646 B2 u1 R5 K1 ^; L- d1 I
    65- d" m0 f  z0 q8 H, P  E9 m* o
    660 X/ s6 B; X0 F1 x+ F6 e
    67
    ( d* _1 c: Z$ j. o, O, \68
    - v4 J5 X9 y3 o2 S& ?; A69
    . G% h+ q! l2 X4 j, U; X7 r: M  F+ N& t70# i: O6 h# U7 e8 Y0 b
    712 l! T% C1 H; k* O# M
    72$ p) E4 i* D! i# a# Q
    73
    & f$ P1 X& W+ ?% `) ]74
    $ y% k6 y" p) S4 B75
      ?4 x4 D6 }0 ~# ~# Q; Y76
    1 v* p1 v. I6 K+ g7 U77
    # T8 A; i& j7 u0 ?( C- M) ^. z78
    5 Y0 C5 V; n! Y1 G79  }% y8 c9 n# y  x! J
    80
    ; u, m+ H! I8 c- e' U9 ~81
    0 p5 R7 j, i- |$ x( H" [1 N82
    4 S# I) s( ~2 A" N$ J8 C83
    , d3 b) q$ M8 W- L84
    7 ~: ~% s: T; p  e857 ]5 g4 k" ~& z" ]
    86
    ) ]' e2 k, a6 G6 K; f* o87, G- Q; l4 ]) ^5 `0 p8 c
    88& Q9 g0 s% r0 \+ \1 A
    89# l' b7 K4 @8 O9 I# H2 a0 l
    90
    ! W' `3 u9 F4 z. q5 _- Y9 U; W91
    $ F+ e4 }8 D1 i5 S$ @. V1 H% }92
    ( L$ g" h6 Y3 I4 f+ D) l8 Z. T+ V% H3 b938 i/ P6 }: U- U# }3 A% ?
    94* }: t2 _$ y( t4 p5 q! B& K8 m5 f% U
    95
    2 Z! l& }5 y; @: T96
    / F! l7 G! F' O$ ^$ R97+ B. b" T1 m0 |) q+ i4 Y% {
    98
    9 g& m% x! t0 r0 b2 W1 ]. D0 z. R1 h99
    & @8 D3 U' C& \3 G1007 {! g4 h! o1 V
    101
    ( O$ }( I( ~! S102% ]: R+ P" j5 o! I/ U
    1037 [' S4 D: s5 P" ^9 x
    104
    3 v( I) A! `- C0 o9 s: y- ?1054 }; K6 |8 j7 M  N  C8 X
    106
    + [( ^7 ^* t: l$ h! Q# K; F9 [& h- p- y107; X, P& T. ?7 @$ w  L
    108
    0 ^0 s. L/ g, K, P- l1 I% A; j, q109
    : `6 Y5 M5 K, Z3 B: F110/ r! J9 g% B0 ]! ]* i
    1118 f% H8 V3 r6 ]6 O/ h' g, q" ^
    1125 K. C$ f# ^( L) R' z! U
    113
    ( I5 J7 S' i4 q2 A+ C# `1145 E7 z# ^: V$ B2 U: [- J+ a& M1 U
    115* D$ o1 Y! f* D+ \/ B# V
    116! s$ f8 Q; V; D- v8 ~
    117: f5 G: r/ j+ m$ `8 T
    118
    1 w* O/ T9 D; Z7 |3 E& V& w119
    9 H5 M+ ]7 Y. M7 r+ y120# {" e& n/ y' v5 [. C: {
    1219 c$ d# _# V$ \2 J( R6 A9 l9 R3 o
    122+ T* i; k( P" g4 D4 Z
    123
    - K1 W3 @5 D, |$ x124
    / V/ [: q+ H9 `, J125" `2 Y/ E( S9 H5 b4 R" a! A
    126
    ( @0 z) L, r1 ~; c1 R( r127- H/ f5 F6 C* J1 ?
    1285 N2 v/ M- {3 I7 I. x; i2 N# x
    129
    " ^; a5 D6 ^  O, x; K1301 F$ d5 I  l3 C; t1 f, |7 X
    1318 @  f" r: M( U8 k3 X
    132' y; @2 ~$ N, y# v. Z6 b
    133" P6 W3 p# [( A, m! s
    1348 I1 {/ A. l8 U! C( r0 j
    135" x9 B4 Q4 P: r4 r( T
    136
    2 G8 P* r! s. \: g137
    % V* Y* m: N+ S& k8 A138
    # |  U7 u; y# |  e  R4 Q1395 }) X( E0 c( d( v. C" K
    140# u) i: t; R1 |! X! @* o4 _, H2 v
    141  X% o- C6 `4 |$ O" h# Z6 b9 t
    142: n+ I3 k3 c$ d% _* H
    143& R; @; i$ Q: |; Z& ^
    1440 A. U" G7 Y5 l3 `+ `$ J+ J; _
    1454 `6 y& L% C+ S  H/ Z5 i( i4 e2 r' M
    146$ p6 N, H+ R# D- p, L8 L
    147
    " i: x& o; q: w; t' }7 c148
    0 H! Q4 i$ M5 I" A( v$ `! ^149- K+ ?; m, u& P' J! d& x# U
    150" M3 J* _5 D( T% s
    151
    6 `& d! }5 ?1 w1 e, O+ k+ N2 ?3 E1528 z& ]. L- o; K& ?4 i
    153% o, m3 t$ f6 U9 |" [1 q* q' m$ r
    154
    8 W/ q* }9 M  y7 J' w. ]155
    # w' v$ C+ S, p! ]9 z5 B9 b' A156
    % v4 e; n2 K9 I$ O输出如下:
    - R  k: j+ K" A( e4 _. \- j7 V- C4 U7 l% n# d& y- v

    0 t+ y( z3 i- k$ f( r, w( vtorch.Size([3, 480, 480])
    7 o- c$ t6 B$ U! D# d3 u7 l6 P {'boxes': tensor([[130.8000,  97.8000, 327.6000, 292.2000],
    $ M2 D3 P( Z( s: r: A* S        [159.0000, 268.8000, 349.8000, 427.8000],
    # w  W4 m# d8 r* g1 E+ O        [  0.0000, 282.0000, 118.2000, 429.6000],- r3 n/ W+ d  F: v5 ^5 k( _
            [ 43.8000, 107.4000, 199.2000, 280.2000],2 k9 k' f" X' A
            [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])}/ e2 k8 k0 q5 w
    18 ^# z3 m1 C# E( ?1 p6 D
    2
    9 L8 ~5 W, y! W3
    6 L) s# Z% q4 m: I5 u- g- D" v8 N48 G. T( w% j' o4 @9 U
    5
    0 F6 L" j7 @+ g" d" s6" z5 S1 b4 G" ]' N, R- v5 ~, k

    ) j# d4 L( {. n0 w

    2 f- S" x! x% G( t: ~+ e
    : g8 L- E0 I& e: R
    9 ]( b, z" ?) S8 b
    下载地址
    5 Q1 F; \9 a( M* a% S链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw3 B( ^0 x0 _( |' _2 H9 H& Z
    提取码:srjn) x) a/ S% v& T0 M
    ————————————————
    ' {; G6 |+ V+ q# u: S版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。  x% B7 h1 l% \" H
    原文链接:https://blog.csdn.net/weixin_44510615/article/details/118496273. n6 x8 f- ^( ]$ J$ w* V8 u

      X2 C( P0 t7 y  j2 F: Y" d/ E' n2 j
    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-4-15 02:28 , Processed in 0.467460 second(s), 51 queries .

    回顶部