QQ登录

只需要一步,快速开始

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

    7 S. W" P9 _* q* a深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息9 A1 L6 ^1 I2 j: o# n/ J
    图像标注主要用于创建数据集进行图片的标注。本篇博客将推荐一款非常实用的图片标注工具LabelImg,重点介绍其安装使用过程。如果想简单点,请直接下载打包版(下载地址见结尾),无需编译,直接打开即可!0 Y/ U) r9 Z! U3 X- ?; P, @
    ; E  a  N/ K  o9 P, U$ M, Y
    ; o+ n3 r7 b, h# n2 |3 E
    感谢原作者对Github的贡献,博主发现软件已经更新,可以关注最新版本。这个工具是一个用 Python 和 Qt 编写的完整的图形界面。最有意思的是,它的标注信息可以直接转换成XML文件,这和PASCAL VOC和ImageNet使用的XML是一样的。
    6 [  Q) I, s* r, {9 R/ n7 H
    - n. \: t; W; O- V9 u7 _

    & n* M+ n* I: m" t+ C, H附注。作者在5月份更新了代码,现在最新版本号是1.3.0,博主亲测,源码在Windows 10和Ubuntu 16.04上正常运行。. F. L5 W! O, O6 I" ?. J
    5 d; f% n( ?; G: r. l4 N

    6 M6 C/ X1 n7 ]8 L3 i0 o具体的安装查看Github教程:https://github.com/wkentaro/labelme/#installation' n" I: Z( _; L, S; p6 I
    6 y7 ]; ]" x% |# f- {

    " U7 V* w. u) A' [在原作者的github下载源码:https://github.com/tzutalin/labelImg
    ; w+ ^1 E* i  A2 T' f4 N9 [。解压名为labelImg-master的文件夹,进入当前目录的命令行窗口,输入如下语句依次打开软件。6 s8 c/ z( W, l

    . [, _1 _; V" i/ @  \* S6 d- C3 S
    ! K. _4 q& ]% u0 Z6 n  |$ z
    python labelImg.py
    ' _% }! }5 V( n  Z$ L: ^1
    ' p) |$ s& j" T' ~& X* c: p! P- z" o/ b8 O3 y
    7 J0 L. b) H5 f9 [

    2 I. U( f, {# s
    / I- f6 W2 _; ~7 f/ V
    具体使用1 E+ \7 \1 u7 A1 x0 o2 k
    修改默认的XML文件保存位置,使用快捷键“Ctrl+R”,更改为自定义位置,这里的路径一定不能包含中文,否则不会保存。
    ) m0 ^' D' S8 _
    - ?- ?9 N% S4 _0 v5 h) ~) g

    . X) S( J$ b3 Q! U- u使用notepad++打开源文件夹中的data/predefined_classes.txt,修改默认分类,如person、car、motorcycle这三个分类。' _5 k" Q7 S- a7 `4 y

    / p2 d# S/ k4 j% a  k

    ) ~% R8 d4 J) n2 S: l“打开目录”打开图片文件夹,选择第一张图片开始标注,用“创建矩形框”或“Ctrl+N”启动框,点击结束框,双击选择类别。完成一张图片点击“保存”保存后,XML文件已经保存到本地了。单击“下一张图片”转到下一张图片。
    ! r: e0 j/ o4 k, |
    : K- p- H; v/ y( I3 _

    5 M+ V, u# m; p9 ?4 n贴标过程可以随时返回修改,保存的文件会覆盖上一个。. E8 h2 u  a5 e' H7 y. T

    $ @( \. ^$ T8 q8 |. C  d; C, m" a

    2 t# w" ]" ~. T, {5 y, @完成注解后,打开XML文件,发现和PASCAL VOC格式一样。4 [3 n* B9 F0 \: p6 p0 \
    & m% b6 I, U9 q( U$ ^

    - }9 }- s8 `0 t$ Z; ^将xml文件提取图像信息
    # N' k# ^8 N) F- H0 m  Y/ B4 o下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。& H/ w$ }' W% i

    ; s; ^; g  C. A, i0 D: f

    3 U! v- k9 @5 J, v! v0 V' W3 A
    2 S8 A4 V3 d8 i% S9 o
    9 o8 A9 S& B! T' P# ?8 v& b1 P( o& t
    下面是images图片中的一个。% o0 {/ X! C, J! s; h  y

    7 b; k6 o5 ~. G1 Z% G2 U8 y* j/ d
    9 G. Z5 P5 v, @9 J
    下面是对应的xml文件。8 s& A0 h/ v$ z- I9 K
    , @2 c3 c, H/ f) e6 ], y

    3 e) N7 x' ?: [% `8 Y<annotation>
    / p7 d: l( m) D' E6 u        <folder>train</folder>
    ! `3 s" r* ]1 _. q' _        <filename>apple_30.jpg</filename>- r& R/ C3 W% S- J
            <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>; t2 f4 I+ J0 e: J3 P' M3 J
            <source>
    / h1 w( ~# ]# D, U2 ]/ t6 f                <database>Unknown</database>. G/ t- _9 M/ |0 ~+ H  \* ^% Z
            </source>
    % R( v+ d, o' m( j        <size>4 |1 @* S% P! F
                    <width>800</width>; o( o$ r9 j4 n( D( u
                    <height>800</height>
    ; n9 D: b! R' ?                <depth>3</depth>
      \4 \  Y0 ]) R0 w( ^9 ^- t5 k) X5 d        </size>
    , I/ c4 d$ s2 k6 w9 X! ]4 j        <segmented>0</segmented>( M( Y! e, _: J, f
            <object>
    8 E# r/ w5 t$ e( `: |9 q3 j                <name>apple</name>
    4 v7 ]7 ]. W* [: ?4 \8 _                <pose>Unspecified</pose>9 q3 K+ D9 r& @5 N8 G/ r8 r
                    <truncated>0</truncated>  ]6 e/ [& {' f
                    <difficult>0</difficult>/ ^8 W5 c( H* Y- k/ \  I' d7 t
                    <bndbox>8 R  f% w! L; x" S
                            <xmin>254</xmin>
    0 o- _- a' z4 w5 Z6 z3 o                        <ymin>163</ymin>
    5 o( v8 @% Y: M1 P& E0 u9 `                        <xmax>582</xmax>
    & T; L; y) }5 r( G9 z7 Y$ n                        <ymax>487</ymax>
    ( P& |. ^% R% Z2 D* n& x, Z                </bndbox>
    4 g! h2 w- D7 Y* m  r        </object>
    & Z3 r5 J. l/ ~0 q" Y: K        <object>  k; k! f9 `/ U0 f# I8 S
                    <name>apple</name>
    + j7 v6 \" t' w. }6 e                <pose>Unspecified</pose>0 n. b0 c7 G% B: q$ Q
                    <truncated>0</truncated>
    , y7 m0 q: D9 U                <difficult>0</difficult>
    % j2 |# G! i, k/ t% E1 u. D" }                <bndbox>
    ( T9 J9 H: k3 R: A                        <xmin>217</xmin>8 s" `5 C/ a. S: u1 w$ r& b3 j
                            <ymin>448</ymin>2 r( [+ u1 ~; m. Z* W; M& B8 D# R
                            <xmax>535</xmax>4 _2 l/ g0 g. F+ J1 |4 K
                            <ymax>713</ymax>' j9 j% X- a6 ]& G4 P  `$ x6 Q
                    </bndbox>3 Z+ O( [; y+ @* |, G& I3 ~
            </object>
    7 i! e5 V- X5 n, e+ n1 S! F        <object>. {* _$ r8 {" g3 M; |0 V1 X- a
                    <name>apple</name>  u: L+ z( w+ W
                    <pose>Unspecified</pose>. \% V' O: ^7 z- N5 `  o
                    <truncated>1</truncated>( c7 q- K3 m4 X7 g" g0 a, w
                    <difficult>0</difficult>" h1 L' z9 _, V5 h2 U9 @0 L5 `. E# E
                    <bndbox>1 R- v  c2 p6 p/ I" n  v. M, V* w. C$ @& R
                            <xmin>603</xmin># _) Q8 T  q0 S- p" E6 x$ p
                            <ymin>470</ymin>
    ) ]/ h( N, Q, M3 B; L% h/ v                        <xmax>800</xmax>+ _- j4 n# j. d: U1 \9 }) I3 L( {6 ?9 u6 e
                            <ymax>716</ymax>1 c+ b# _! N  Q/ Y- Y. x
                    </bndbox>
    9 Z3 V# x8 J$ ]        </object>. J& Q" ^. Y7 H; @
            <object>
    8 a$ D2 M3 ]" A# V; X& `                <name>apple</name>
    1 X: v9 }- ~& o; e& l6 z; e                <pose>Unspecified</pose>
    7 j- n8 Y! E/ E) Z                <truncated>0</truncated>
    ! J  f" X9 `  _' ?7 [9 X9 m                <difficult>0</difficult># m( q# e, u/ e
                    <bndbox>! r" q: |2 i* q! n; A
                            <xmin>468</xmin>
    5 U+ t/ @2 d) U+ ^) T: y                        <ymin>179</ymin>
    5 g, d* K$ x4 J0 X% _                        <xmax>727</xmax>2 \( H' V! u) K9 w& ~
                            <ymax>467</ymax>! O4 o5 Z! x: X6 v% k
                    </bndbox>
      e* s! l% T& o) N        </object>
    3 U. K. A9 h8 ^# x        <object># Y' M  [+ ~4 j! m0 j& w
                    <name>apple</name>
    " C) T) }  r# A# D0 h                <pose>Unspecified</pose>
      ~. N: _% ?7 Q' a3 x                <truncated>1</truncated>
    9 E' w$ X7 e7 _* C+ w. |( ~                <difficult>0</difficult>
    - E  b* J# s6 n  N& `. o                <bndbox>
    # T& w0 l# u7 B6 B, q                        <xmin>1</xmin>
    4 r4 E* ^3 L5 N5 u                        <ymin>63</ymin>0 c$ p, D+ {8 X' L) |9 [: }
                            <xmax>308</xmax>
    / r% ?. ]% v+ P; d                        <ymax>414</ymax>1 `4 ~+ Q  S2 M1 {$ J
                    </bndbox>
    , u: W& |+ `3 q' l        </object>0 e% ~2 }: ?! N( n( L4 A) G
    </annotation>
    , Z+ i* e( G8 q8 k1
    $ b7 ~- j* B: M* p& U8 r2
    8 [8 N8 k2 h" Z' [4 v3
    " n2 r. o2 @9 [% N7 q+ s4
    % a+ k- p# x  j0 P, e1 R2 x5: |4 u3 q; v) Y; s
    6! y1 _' j# {# Y/ z
    7
    2 I+ I; ?* f3 g# t. n/ Y2 q" I7 e83 i4 G( A$ I1 I/ Y$ P9 l
    9& b7 P9 G+ K2 N& S  y# c
    10# j* ^1 l4 v- B3 k  N$ H
    11
    ; U/ T% L. b/ k. r! S12
    4 `" \! I2 F+ ^! _1 ]1 r( B13
    + k) D6 C' g( X. {14
    - q. ^) V9 ]5 S2 _15: K9 x; E& o5 D7 n% A
    16$ V) C; q# Q; c. r5 p6 Y5 x  u* M
    17
    & l; I. A8 a7 s18
    6 J8 y1 T6 |" ?/ |19  T1 \" c# x8 s& U( _9 Z- f& o* N1 }9 a
    20% h) G' z# E8 f: n6 _- t
    21. }3 a2 m% u5 q+ C+ D3 ?
    22. [6 B% k3 Q6 _% I1 X. V
    23+ `4 ?" o+ C9 f6 j# C
    24
    ( E, t& _) q0 _25
    ; s  ]5 c0 }& j26
    # w: A, @2 Q1 \/ U! k, G27. @" ?# B3 b9 A, ~5 N  a2 {
    280 L( @( E- m6 z6 {- K9 U$ M
    29
    " k0 G& y) d( c$ ~30% ]4 F7 M9 J5 \3 F
    31( l9 g6 q$ |/ t3 M- ]# e- M( h
    32
    6 I: Z* R0 N9 T# X- B  E7 N33: j/ \9 I2 e5 u8 e3 I6 l( |# R
    34" \% o" E: m& @: M
    35- I. W1 a, X! p7 D4 `
    36
    5 a- o0 U+ s- U8 N# [/ A* P5 a37
    9 ?/ b9 Y. ~4 Q38
    & j0 l' B; m6 H: ?" ?- x$ h' N: D39
    ( C& d3 o4 M: Z6 u4 V% w40- `) H5 f, C8 p+ L& U
    41
    " C# p4 Q6 @6 v* w, S6 w7 h* r( D, Z* D42) k8 I' H; m3 G3 T2 Y- z( O
    43
    1 P4 j7 A. b" E% X( o5 _5 j444 f" l! U) B! u% R3 ^) `+ ^' g. B
    45
    1 L. J, {, R- d+ C" G& Z- n46
    " c4 v$ q. d0 W47( g! S% L& p+ E6 U0 ]& b  l2 l
    484 b! f- y' W- q! I7 d7 i7 z- c: B" _
    49" \# ], R1 M3 u1 L( x
    507 v4 f" F8 L9 \, D6 y$ i$ J
    51
    3 X1 ]" ~/ o+ Z) F6 p52# ^- u3 r. p5 P$ u8 G
    53
    : |4 k' p' G( @5 f: E7 i54
    ' a8 d5 P) U/ ~/ ~, g' e& Y' \' V551 s5 Y% J4 S8 ]5 O
    56
    8 B; m6 R9 _9 g+ z) S0 G57
    : [$ t# Z6 {& j# P. @# x8 m) c584 c- M. ~8 n3 ^& W$ m
    59
    : v+ ~8 Z9 ~' O3 {- {) I& o5 E" M0 x60
    $ ~7 n- s: T+ Y+ o6 }( k; L61
    5 W, g8 B: j  n  C9 Y2 b62
    ) M4 ]. b! y9 ?& @) S' |7 S63
    5 z: `( \1 v# _) Q' ~4 i64) M9 a3 C& D+ O! X; A
    657 J( ^- }0 N5 e" W
    668 j. a  j. z3 d% G6 |1 b: d6 U. G4 c
    67( G, S2 @1 ^' F, _" g
    68& A6 n0 K' d1 j. V+ s4 t) G
    69
    # f, z- L/ ~1 L$ V7 ]' V- N  E70
    2 L% r- T- I7 R71* ~0 @0 [# L+ t8 g: H' i
    720 l3 M) C) e) F+ d! ~. C
    73! l1 a/ M7 b5 |& G3 s
    745 z' x5 w1 W6 k# t7 b& j9 M6 K  j
    将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。
    : \  o- U% M7 M% |1 Q) k9 G/ Y$ m4 J( w/ r6 b/ N# q& }
    ' \8 _+ k  @* ?) F9 J# K6 W
    import os) r6 Y* E3 b3 F
    import numpy as np
    & ^% Q# b$ a) U! T2 G9 ~$ nimport cv24 x! ]! Q8 _+ j' x# B
    import torch9 V* g4 L; I. H* q% [1 \+ ]' {$ r
    import matplotlib.patches as patches  h) \' R" ~% D, o  N
    import albumentations as A$ ^  {' G! N" D  W" Z
    from albumentations.pytorch.transforms import ToTensorV2. K$ i' z9 \) n+ [! A
    from matplotlib import pyplot as plt
    2 t$ D* q0 q. t9 Y+ ^+ t- Cfrom torch.utils.data import Dataset
    0 n& x/ U9 g% bfrom xml.etree import ElementTree as et' h4 s, E+ }2 v9 G/ ]
    from torchvision import transforms as torchtrans
    & ^5 [) c7 T# j% d  c6 z* C& K' z; g. I& v3 c, W6 l' F
    # \) e" X" Q" q2 l0 `4 a( U
    # defining the files directory and testing directory
    ! \# g$ s5 m# p, |& Wtrain_image_dir = 'train/train/image'
    " z! m+ ?; R) y$ qtrain_xml_dir = 'train/train/xml'
    : @2 I- V0 X2 ^7 F. {9 p% I5 ]# test_image_dir = 'test/test/image'
    3 J9 L- K' f8 L  _% C! i9 T  N# test_xml_dir = 'test/test/xml'
      c, b  F$ P$ g7 T! `* p& R9 q# W' F2 P6 S: H* n" \, w4 [' m

    3 o3 \1 X5 l# Z3 c: t2 fclass FruitImagesDataset(Dataset):6 U5 n6 J( ^( W1 ^2 U% V+ O
    8 n9 R. E2 |8 P& e$ s1 ~. @* H
    - Y+ P0 F. B3 \8 v+ B7 n
        def __init__(self, image_dir, xml_dir, width, height, transforms=None):
    4 D6 b5 I) w# K7 W+ q        self.transforms = transforms
    9 c: ^: C% l- H, D        self.image_dir = image_dir
    5 `( k( k$ j7 s2 t  A! t        self.xml_dir = xml_dir) m/ r- a' J4 G- \( P7 U
            self.height = height
    ( a+ V; `/ z* @, O. p        self.width = width4 E2 u# [1 I4 M' |! [
    . N# u. v' A  H+ `
    & V: m1 v) ^4 L5 r" B
            # sorting the images for consistency
    # F0 r; k# @* j4 C+ ]8 Z) j6 X# Z        # To get images, the extension of the filename is checked to be jpg2 N2 w+ X- w$ D/ {& C0 U, T# D
            self.imgs = [image for image in os.listdir(self.image_dir): E* S" E: ?7 Y. V' t3 A% b
                         if image[-4:] == '.jpg']
    * ]2 l4 l( _( I        self.xmls = [xml for xml in os.listdir(self.xml_dir)( L2 H( d9 d2 g# k- O0 U' y
                         if xml[-4:] == '.xml']
    2 m8 B; B' Y8 U1 R8 ?. u  k, ~
    2 k" T9 O* }: Q  X
    . X; b1 k/ y, F+ \1 |3 D$ W4 t$ a9 V% \+ c
            # classes: 0 index is reserved for background
    ( \- S1 k" R+ K1 s( J, m        self.classes = ['apple', 'banana', 'orange']5 K3 v6 P+ A: Y' Y/ V
    , \/ a1 `! H' R6 e* k

    9 K' l) r2 J6 f* |6 }/ R4 I    def __getitem__(self, idx):
    5 f3 Z$ W* W2 i; E3 ~, g' P  z- x4 T- C

    - F$ C5 w9 z$ f0 p+ H        img_name = self.imgs[idx]* n  r  T4 L) n6 C& Q3 q9 A
            image_path = os.path.join(self.image_dir, img_name): Q- C9 c. f, ]8 x
    ! c% {8 _( d; ?1 p6 t$ D; P

    7 @& N7 X! Z4 G# a( p, d        # reading the images and converting them to correct size and color( n+ b; y+ n7 D$ s  m
            img = cv2.imread(image_path)9 d) a2 p) n+ I6 v
            img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)
    : m* J, g& U. N4 u        img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)- ?, n+ O+ n. A- [$ H
            # diving by 255, g; }  q8 ]2 n; z. b; a
            img_res /= 255.0/ `1 L# K, P1 g3 Z7 ^+ T
    , [4 z" u2 `  \8 T$ l! P$ u
    9 m1 ]: g2 k9 q: ?9 M) Q) D
            # annotation file- [' k( }6 n! o. A. U- f
            annot_filename = img_name[:-4] + '.xml'
      f+ Q+ r$ U7 a  d" Q% [) |& F8 o        annot_file_path = os.path.join(self.xml_dir, annot_filename)
    1 a* y3 q% k3 q- _, o% {( [0 n: ~# N! Q* A: D$ Z0 r
    5 s& m5 L: Z0 t" [( A; s# `% v
            boxes = []
    3 C2 R# s4 R+ j3 z& N        labels = []
    " I7 R2 {+ W4 ]- v5 J' i        tree = et.parse(annot_file_path)
    # q+ W' _  n% n" y' V& d) U+ U        root = tree.getroot()& @( P: ]4 r4 u  p" l
    . ~+ Z' a0 H$ t- Z$ V; M
    9 I) b' Z& K* i1 ]8 @
            # cv2 image gives size as height x width
    ' c8 ]$ L( ]4 p; _% ]% y1 A        wt = img.shape[1]% J' H# {$ {5 a& \
            ht = img.shape[0]  T" {* p1 b8 l# [6 I, e

    3 w0 Z# u) e$ k( C

    # {, f; X1 w# S4 q        # box coordinates for xml files are extracted and corrected for image size given
    7 M( g; F5 T/ Y, O5 S        for member in root.findall('object'):( H2 R, V6 \: Q! P
                labels.append(self.classes.index(member.find('name').text)): }2 R$ H& w0 L' }  D$ N; z' Y
    # r4 V" j( D0 B* m" r$ d/ a  {0 I

    6 r7 B# h: l/ B9 _! G& @            # bounding box
    4 H  Y; Q' @" D            xmin = int(member.find('bndbox').find('xmin').text)  Y- h* R- I% p( n# Q
                xmax = int(member.find('bndbox').find('xmax').text)4 `1 F: k( y! b  {/ c4 g  [$ n
    / I) s9 n7 l( ~0 l/ C5 s
    - _  E" k! X) m: ^
                ymin = int(member.find('bndbox').find('ymin').text)" P3 d% B0 g6 B( u% J- A2 M) o
                ymax = int(member.find('bndbox').find('ymax').text)
    5 U+ _6 y' V9 b% @: \9 I$ V- |; o
    + I$ L. Z- N* H' ]# [: A' Q. ~7 g

    , C1 Z! K( I% d            xmin_corr = (xmin / wt) * self.width. w, _2 v0 r: f5 E  }; M
                xmax_corr = (xmax / wt) * self.width
    7 O. Q, C6 s/ A            ymin_corr = (ymin / ht) * self.height
    ) o1 V# r7 Z7 I0 _% ]4 O            ymax_corr = (ymax / ht) * self.height9 O  V! D$ y) d% R
                boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])
    2 |6 k* y/ z$ a5 u, C
    3 @! B. W8 s$ `* K( k5 O% V

    3 P9 E6 h! U" T& o3 z/ f2 t        # convert boxes into a torch.Tensor( w( b" h9 M4 }2 ^
            boxes = torch.as_tensor(boxes, dtype=torch.float32)
    2 Y2 {/ V# w7 E$ O" W
    ! Q- T' _# p+ f" W0 V+ b* E
    . b7 `7 U0 r. e( l
            # getting the areas of the boxes2 h2 g" p5 X5 e: g8 e4 E
            area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0]): _* w) j1 e9 J, p5 u: o

    : \; h! X3 R! W( ^, w7 \( \3 g, m

    : h0 a' t9 Z. _2 ^        # suppose all instances are not crowd
    2 R* i* E6 l2 c5 ]        iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64); j4 _' ~8 z$ Y! l. Q9 i! F
    1 D! S6 w& H% G0 g  @
    ; V0 F+ D3 Q0 r/ x2 g7 k1 S
            labels = torch.as_tensor(labels, dtype=torch.int64)* m' q# o6 D' d* S4 i1 Z8 @

    . K/ w. A5 m+ v- n/ I

    2 g9 w- {  ^' O# ~4 M* X& n$ V        target = {}
    + \/ ?" t* N! r% ^        target["boxes"] = boxes5 G1 w  w5 G! B0 |8 @6 ^. g
            target["labels"] = labels9 N2 t0 C0 y& P  J8 ]* s& k; M' m
            target["area"] = area
    0 U( I; _1 Q, \- b        target["iscrowd"] = iscrowd
    7 e1 z! U. Q/ k+ t/ t6 }/ ~        # image_id8 A6 w: Q/ Z/ X+ L- b7 S
            image_id = torch.tensor([idx])% H2 K$ l( s4 p# s
            target["image_id"] = image_id
    & y7 z% [2 g- |" n
    : X- Y1 S8 w/ Q2 l) Z

    5 R: h2 L! E5 O  G        if self.transforms:2 d0 g0 o+ ?  n/ ^; }( S* ]
                sample = self.transforms(image=img_res,
    9 G3 {" ~# z: c* V3 h# z                                     bboxes=target['boxes'],1 S; Z) ^4 o8 H3 B7 D6 `9 C
                                         labels=labels)
    5 i- w0 D+ F( Q3 w5 B7 b5 }& q# F% w) z2 Z5 N$ u. |
    0 \  F' }- T: B
                img_res = sample['image']
    7 P0 k: Q  H/ W! K% b+ \  l; o4 V) n% ]            target['boxes'] = torch.Tensor(sample['bboxes'])3 X$ O  A6 l: J- X$ l9 W" V

    " {8 c& z" u4 v' r) _% }5 {

    / R+ G  k( v6 m, ~3 y$ ?4 \, r        return img_res, target
    ! X' G$ }" f) E  V3 ?3 @
    . s# n$ x5 u5 ~
    ' J$ ]9 g6 H$ v" B: y
        def __len__(self):$ f) c1 i3 v, }* w" {3 w. E, c
            return len(self.imgs)
      }+ r& f5 j; @7 i$ R2 G) E6 E& V) ^+ J1 B
    7 V0 ~$ A% b+ R6 L% H2 g
    # function to convert a torchtensor back to PIL image, [0 C! Q4 V3 h
    def torch_to_pil(img):, K8 D/ E4 a# {! [  i7 Y1 v' M
        return torchtrans.ToPILImage()(img).convert('RGB')
    7 I& m" `6 a) t
    & Y0 U9 ~/ o/ i/ ]: f/ S

    4 h* X5 ?, y, @- R# H4 X9 d/ S: m/ G( Z! |% C
      A2 ^2 m* J( [1 H; x- F! _
    def plot_img_bbox(img, target):
    5 A( {- j) y# l: K    # plot the image and bboxes
    2 t2 C* `; G, @7 ?* t5 }- j    fig, a = plt.subplots(1, 1)
    ) Y& T$ L, r7 M% {5 o    fig.set_size_inches(5, 5)' U0 p2 ^: \7 E9 p2 N0 J
        a.imshow(img)
    8 l+ ]: K* f& P( Z9 `# W( m( q4 W    for box in (target['boxes']):
    4 b7 ~9 ]5 R: k! F& B% C, p! \        x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]
    * ?7 [8 p) e: p- l/ l- A( y        rect = patches.Rectangle((x, y),+ H) f* n$ ?5 T" b% ^
                                     width, height,
    & E- n) A0 }7 V                                 linewidth=2,
    + C, e: |' S8 A; x+ P                                 edgecolor='r',
    8 ^) i; w( \; o5 ~* O, _! y7 D                                 facecolor='none')
    # `. j+ c1 g. Y9 B  m3 S- \2 ~, @  J
    / C1 W- `% ?0 \0 I, A' m. S5 y
            # Draw the bounding box on top of the image
    4 \3 i5 f: c/ E% M! q& e        a.add_patch(rect)
    ( W1 i( }9 i: @0 K    plt.show()
    ) d" A3 e. \" z/ [; a1 @9 o! Z7 c2 T* [2 P' I

    : \# F9 S4 N( N1 k* ?! s: u
    . U" ~5 _, Z) Q- y! i' d" [
    ) V4 s! o7 z4 @3 ?! t0 x
    def get_transform(train):
    * A& f- Z) G3 U    if train:
    * \; J! j" V% K% u6 e* X& @        return A.Compose([& ~) ]! _0 R/ m! d: v
                A.HorizontalFlip(0.5),' Y3 J( j) y) o; |+ K7 ]) b' L
                # ToTensorV2 converts image to pytorch tensor without div by 255+ J, y/ o, O) e9 a5 B
                ToTensorV2(p=1.0)
    . Q; h' Y& B% d' m: a        ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})5 E3 U) B+ U/ W- _$ a
        else:
    . d* N/ T% _  \9 e7 c; Y0 @        return A.Compose([
    ; ]/ e) Y4 H4 ~% V; T8 i0 o            ToTensorV2(p=1.0)9 P2 F4 }1 ?: F, d  V2 m2 o
            ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})2 ~" W: R) |  g, T( v8 m

    ; v1 ?6 h# O/ ^. e; ~
    , G0 I( h( Z# }
    " e! o" }, P* S( ?

    ( Q) z( k, ~4 M$ A+ B  Y  @- l  W' _$ D9 X. y

    - g4 I1 M* [! r' Z% x* I, r. Idataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))
    3 V8 j7 p7 v# q
    " l7 C; C# C& e. S- \* E7 i

    * z* A- E3 z7 [print(len(dataset))
    3 m" a6 F" ?' ?" e( {# getting the image and target for a test index.  Feel free to change the index.
    7 V% p7 n6 \' }img, target = dataset[29]
    $ [6 A7 V9 j# M( G9 ]) j6 iprint(img.shape, '\n', target)
    - G4 M6 `1 |6 m' l2 dplot_img_bbox(torch_to_pil(img), target), J# a- N. D0 k& ?7 f
    1
    - S& x' ^, N# N! J) Q, d29 L, k# A$ F- o1 p1 m
    3# ]/ w* R. p  Z) `) }4 ?/ H
    4
    5 ^1 Y. M9 F; u) x57 j6 \+ \4 l& {4 k, H7 i6 H- Q
    6
    ' H4 Z! K5 P2 ~3 m- P7 s5 S" Y7
    3 j( J. r; z; B. d8  [) z1 f7 e0 c2 i) O
    95 \  x0 F4 @9 g, r
    101 `$ ~8 Y( a8 @4 S
    11
    $ g3 q3 p, [3 A6 n( ~# u) S12
    ( s( w: }8 |$ m/ C" F" [135 S2 x. C. E! W0 w# [
    14$ X! l+ \2 n% T& C. o0 m
    155 @5 f2 \, B$ H- `. e: Q9 x
    162 A% O5 z3 V, S; Z8 n
    17
    * e% `8 n0 W9 `18# z, z, i9 a" m4 L) O' s' @
    19! t9 O  f. V% j" R
    20
    , Y+ F& Z, B  k, a% B& A21
    9 i: W$ h, `3 B2 C6 a2 F9 H22, _9 m$ T' D/ e8 `* s5 |" G
    233 |; s; s0 l( O( W
    24  p3 \9 e" v) ?5 e: U
    25
    6 ?3 `$ O1 }- D26
    4 l2 ^1 f, g4 i1 e# b, \, ~27
    % P& H) F7 ]# \: H, b- j28
    7 i# ?2 y  J) X+ a  U291 W- e7 O& F7 M
    30  J4 d* O. D; s% \1 H2 K& x, \
    31
    ) q5 z# D2 S) i& v1 j. I6 Q32
    - I: u4 Q% N# r+ S  S% g33
    , }; h2 o1 x4 F* v0 M8 i4 V34* @+ W" T* Z' y2 U- S
    35
    % h, ~+ b4 D5 M  y# @$ l& y$ K* {8 ]36: g. D. x: v. S4 W9 M% q  i" C" ?
    37: z9 ^4 y* }/ X: G  x/ \$ c, T
    38
    $ P6 s+ `! K" C' y! z8 n( g39
    1 s8 A$ o9 ^) k% f/ l  a$ A402 q" m, k: K7 F+ x
    41
    6 [) S0 s- x+ h424 K6 P7 g! e+ J
    43) L8 P3 q/ \4 K. I
    44  v' z& V% U. }7 t+ q# {4 u- n  C
    45
    / q1 V$ h$ ]) ~' m8 D' ~46
    0 Y* s, d9 S+ ~6 t) U) r; u( E47
    % E% D+ Z$ h4 O483 o) K9 w! N8 u: q8 O0 a  m+ L
    49
    " k- I( |& y% r- k1 g) P0 {/ b# J50( P& |, S0 x! A- R
    51
    $ }0 D. i' i: J6 K52
    , R: c& m# G: X6 A: d/ d3 c1 T# K53
    , B3 ]0 J3 w* B3 `) J7 N54: @  [5 S  y7 A" h* o8 ~
    55
    & }- U: u7 h' d2 _+ B! }0 s6 j56
    % j- ^( y: ?$ N" z. r1 V57( \, g) {$ ?  G6 j: `( C
    58  d( R) c& k( i3 c
    59
    % g8 J- W% @# c- x# \604 i1 D! I9 V/ g2 Y8 d
    61
    - \. ]; E- `. E; j62
    7 b6 m! v2 c0 s/ Q% R  e3 J3 m63
    9 g  x" s" P# O) x3 ^! d3 c( E64
    ) o  H$ I: k2 `: W% S' K5 @- G656 x2 v' \* a) Q: e4 g4 O; m
    66" a! K* q1 L0 }4 _
    67- y8 `* s' z' U: V; P6 g3 ?
    68
    : U! @- u3 [7 a4 N69
    ! S3 B/ d: q& I1 g- u) k7 U, M: Z: [70) k4 `, P) s( r8 u+ k
    71
      g: J' Y8 u( g: I# {+ z. K72* G( V. p% n# {) k& T" ]3 @
    73
    + A$ T+ K* W. Y9 f( D% z7 ]2 D& B74  C- G. m+ N. z# P
    75+ C0 y  |  q7 P7 X! z
    765 b' m5 s' o$ D0 l
    77
    % L9 v9 s) d% p$ j0 s78
    7 `. ^) W6 O5 ]0 X$ d3 ^7 Y796 w2 O4 \* d0 U% {7 c
    80: a4 I' d+ l8 n6 ^) f
    81
      S, G- y! Y  @% |' P82: B  n  @, n4 f9 k) o
    83/ n- F$ X5 N& F6 I
    84' |  Q2 X: T  W5 O" ?+ e
    853 l) V/ q  L5 g4 l- |& W
    86: [/ }+ @  @% z2 o3 T
    879 p; p2 I8 h& `, Z4 v1 T, T) {
    888 s  Q8 f0 J, m- d1 U
    899 r8 v- P; D1 e4 N3 ]- K  L# [4 K- w
    90* O$ J. A- z! K; \" z$ G! _
    91
    % w0 v- A% }# b92" \* o  \. n5 L5 b) c$ r2 B
    93
    * o8 Z: H" [3 d' `/ v94
    * v+ ~0 ~- X3 G0 P, {# `1 l95
    2 W" \+ ^2 x7 ~1 {: M% E! g96
    , K9 X' R' A# _7 F; Y+ y, s" L97: ~7 |% f* x4 L% f2 {9 `! D
    98
    . I: t2 a% n6 h: N( h3 }1 l99% i7 x3 q+ \# t; K& Z$ w* d
    100  {# I* ]! R/ ?& c) F$ ^
    101
    ; Y' `- \3 a3 y/ X- n6 J3 _102
    ( r# {2 G$ @/ C2 @1 w103! I7 l; U' y( i1 U* q! ]
    104
    2 J3 Z5 A, f* z5 ]% R105/ b; Y1 z0 V5 B. F6 C
    106  t8 P6 A3 ~+ e* g4 L, g6 L
    107: |1 t5 O' _" s" {% ]
    108) U+ C4 D1 E3 F! V5 R
    109
    % v/ \$ F  i- V0 _) D110
    ' R! N$ Z+ M. b  R111
      k3 Q8 p; d  J# X: T7 V112
    $ Q% P. N+ L/ B9 h7 z& Q1 a113
    & m! r4 u, P) f! _) b114; o& c# f( E4 e  L% q! Y
    115
    $ n  @$ w0 a( O6 Q! L% J5 L& a116
    & H4 a- D) P9 X' R  L) t117
    ; }1 K% @9 X$ E: n118, u5 S* _% B3 @+ w9 l
    119# _" G- Y9 G/ a; a  t
    120
    ' e4 X3 I3 Q# ^2 m; y5 O121" h7 M' h7 R, Q& `5 I2 q
    122
    ) a2 ~+ W4 D& x9 H123" l8 b4 U+ g- d0 a7 N
    124. y) z- M+ D$ s* M
    125
    ) h/ r7 q* @9 M4 W1 t1261 O. x5 o$ P/ }) f% O; B+ u. Q4 j
    127
    : @, ~2 q+ U3 s7 s" R1281 _% @1 U8 Y; O* H5 D
    129
    & k" s- a- Z3 D/ T" l130
    , k, z, u# |. m# O131
    1 b! T; z: \4 ^1 I0 V0 N132
    2 Q# Q, F! q( Y+ t( ?133
    3 C, ^% i6 Y( I9 V# K: G% b1 ]1342 ]- P9 e. e) v1 a6 W7 _$ w) A
    135
    . c5 a: j) N( N136
    4 y; E* f* U5 [/ A137
    ! N- b  u" Q5 d138
    5 }- ]! z  X1 V1 y- q139
    - `3 V3 J3 G: l, A, {+ D8 @! K140
    ' I! S% h; r' R$ v! s141' s  z6 y. `2 T+ ^0 {- }
    1420 ^9 N5 F2 P9 P3 W5 _6 W# f
    1434 ~; N; \! s1 n2 W; l
    144' v# r" W" q4 J( h. d- \
    145
    ' X9 x" A7 Q, M8 z( e146
    . d0 v7 G$ D! u. f147
    4 M2 S6 W- K4 f% u' h8 K$ I! e( U148
    : `: y- p" Y7 g, X; n; v9 ?0 m149
    . |  S# e$ V, G1 T) k150/ d7 o: B) K9 G( v/ X4 Q
    151
    & P) V0 R& u9 Z7 b/ c152
    * I" s* J# S7 e/ _; n153
    9 g  |" e6 q$ C/ f+ M( w1542 l7 N) F4 K3 _6 W
    155  b# n* T! E1 w  L
    156* L& ~5 x! v+ t$ a
    输出如下:# _1 }/ H6 J% ^/ }8 u
    . l; A% ^0 W: H1 b

    ! |7 C: C+ n! P9 [/ J+ [torch.Size([3, 480, 480])
    2 u3 a4 e- Z$ L) j5 s {'boxes': tensor([[130.8000,  97.8000, 327.6000, 292.2000],3 }* O( o! w! i8 f/ g( L
            [159.0000, 268.8000, 349.8000, 427.8000],
    ! E. P+ ~/ x6 y0 P        [  0.0000, 282.0000, 118.2000, 429.6000],5 @; w$ }* I) I
            [ 43.8000, 107.4000, 199.2000, 280.2000],
    - c: ~6 Q/ u1 u        [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])}! B% M, ]8 Y% }6 g* G1 s# n: H* K
    1
    : R9 k3 ^8 A5 M- _$ x2
    " M% }5 h: `/ Z+ F; ~3
    & _# j- A- c! d+ e1 c) Y4
    ' {0 B0 A% i$ V4 s  M54 h7 c( [" c5 q5 H1 _, e- x6 ]
    6
    ; Y0 `, R5 K" P7 g" C0 A, a, Q' J, z9 s$ R, H5 A5 V
    8 ^7 c8 p3 X" V- \& p
    5 z0 G+ P' k  u; q+ V
    3 x1 o5 P) x! v' A4 B0 c( \# z* G
    下载地址! e9 t. x$ U+ u, Y
    链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw
    & {/ J  d2 R, ?  x# J提取码:srjn
    , ^# M) F# k9 T; J7 W————————————————
    0 h3 [. o6 u5 G1 D版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    + V/ v5 ^3 v* T原文链接:https://blog.csdn.net/weixin_44510615/article/details/118496273  |" N7 S  K1 q# ?1 q4 i! b

    5 w+ Z; }, w/ d- n+ k9 p# W
    ( k% ^2 |6 K! a/ n0 I; K
    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-9-27 18:37 , Processed in 0.589231 second(s), 51 queries .

    回顶部