QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3422|回复: 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 u- o8 J& @& }. }深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息
    7 R3 J5 n8 O2 ?' ^1 b6 M8 u3 M图像标注主要用于创建数据集进行图片的标注。本篇博客将推荐一款非常实用的图片标注工具LabelImg,重点介绍其安装使用过程。如果想简单点,请直接下载打包版(下载地址见结尾),无需编译,直接打开即可!
    # g* U+ e+ M8 S; O( o& A
    " r4 q+ }9 v* d# C8 d

    5 O0 R* X8 ~9 y感谢原作者对Github的贡献,博主发现软件已经更新,可以关注最新版本。这个工具是一个用 Python 和 Qt 编写的完整的图形界面。最有意思的是,它的标注信息可以直接转换成XML文件,这和PASCAL VOC和ImageNet使用的XML是一样的。7 z. n1 L+ I* p  m' j" r( g

    . _% i6 o* s! l% `) o+ d

    " H4 S* y: {" B0 e附注。作者在5月份更新了代码,现在最新版本号是1.3.0,博主亲测,源码在Windows 10和Ubuntu 16.04上正常运行。
    ( B! C# j3 Y$ k" L
    ( \9 b2 i4 c# R, H1 i5 V
    $ Q% q2 _8 c1 Q: \8 E
    具体的安装查看Github教程:https://github.com/wkentaro/labelme/#installation
    . N) e0 G' Q; v
    # V2 `3 V& _$ v- _* |( I; I" g

    ' T8 r+ d' l! F6 Y9 z9 d6 d: x' Z在原作者的github下载源码:https://github.com/tzutalin/labelImg0 C1 |( J! s# j' q# P. h7 N/ v
    。解压名为labelImg-master的文件夹,进入当前目录的命令行窗口,输入如下语句依次打开软件。- ^6 [( Y# S# k& Q6 P1 H  N
    ) R$ P- V. {4 \5 |1 ]0 o
    * f# g) g, p! V0 f1 |; v
    python labelImg.py  W. r, j1 p4 }# f; k( g
    1% z( [) U5 n, j" z! |4 B- R- N

    " x; u! J( o" b: v0 K- q
    " u( X0 g% W. }9 g+ \! _! [

    6 l* {# s1 ]# g9 y/ ^3 J
    , a* \! q/ _+ X! H: ^
    具体使用
    / C  w' }/ F. j: f. ]; ]3 P/ M修改默认的XML文件保存位置,使用快捷键“Ctrl+R”,更改为自定义位置,这里的路径一定不能包含中文,否则不会保存。
    - _9 o, `4 z  O0 M6 j8 q
    $ h: g* \4 Q9 O

    $ ?8 z, a1 r3 T  x9 h4 Q- o* K) ]使用notepad++打开源文件夹中的data/predefined_classes.txt,修改默认分类,如person、car、motorcycle这三个分类。
    ! w) }$ H, w9 ?1 {6 V, I# N! R# L
    : b" u. f2 h% b0 l) E6 j

    ' I6 @) R4 B0 l( T6 a* Y( i  h) d“打开目录”打开图片文件夹,选择第一张图片开始标注,用“创建矩形框”或“Ctrl+N”启动框,点击结束框,双击选择类别。完成一张图片点击“保存”保存后,XML文件已经保存到本地了。单击“下一张图片”转到下一张图片。( P8 Y  ?1 X8 q2 a
      T2 A) Q8 b# H

    ( p* j3 z: k9 j8 V! d贴标过程可以随时返回修改,保存的文件会覆盖上一个。
    " J+ @3 {# ~7 }- q
    $ R% C7 V& @- P3 m

    0 Y+ z% x, m4 W& x完成注解后,打开XML文件,发现和PASCAL VOC格式一样。# n* r' @# D+ p" H: q" _
    + T5 `) S4 L+ \$ u9 X
    ; |4 z! W. i' Y0 S! F1 h3 d
    将xml文件提取图像信息& l# O/ C0 s0 j! v+ I" ~
    下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。
      w* L* I% ~6 ]) P/ A1 d
    7 W1 L8 |4 ]- a4 _4 T6 _
    4 \; A6 W* {# j
    + M) o+ s9 c! Y6 W6 }6 Z& y! D
    5 p0 O; |# X. w0 c5 r
    下面是images图片中的一个。7 f7 u+ Q+ s/ P% z' Y# a5 u% H1 g5 |

    ) b! D* N  q( d8 A: I+ C, s, n
    0 j0 r, |, ^5 w+ _: K5 n0 L6 x; l
    下面是对应的xml文件。
    ) Z7 M$ ]0 d. P5 Z( _& ?, G; W" I' |2 |+ m$ C6 T9 I0 K
    6 t2 o1 ?. n; A6 i/ G) S
    <annotation>
    & T; s8 N8 m5 O1 [& ^$ N* x  B        <folder>train</folder>
    8 t$ u0 C0 q: x8 z4 w5 g        <filename>apple_30.jpg</filename>8 S+ A: [0 m) z$ }& Y
            <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>
    / A; W2 Y% k2 J- N  D" _        <source>* Q8 M- L9 Q, K- j# c
                    <database>Unknown</database>9 O0 l1 _; k+ |% e$ |% z
            </source>
    / G4 \- Y9 i/ z3 R        <size>
    # P  n# i0 Y! w                <width>800</width>2 Y& {& g0 K2 d. Z/ z
                    <height>800</height>
    9 ^0 S7 J0 p9 z; }  H- ]# u                <depth>3</depth>
    2 ?+ ]. d4 [+ b3 C+ }4 z2 P        </size>+ m! v( h7 x7 d+ U: n
            <segmented>0</segmented>$ H, l2 r. M9 s7 b, u
            <object>0 `/ ~+ E4 m" h( a2 Z: }) W
                    <name>apple</name>
    % @9 ]; Q# D7 j6 P# Y# e- P                <pose>Unspecified</pose>' s: y" o0 |# @
                    <truncated>0</truncated>
    / _8 G# g& E4 Z: S( H( @                <difficult>0</difficult>4 G6 _" i# K" q  B8 [1 l# g% B
                    <bndbox>7 E9 R3 [! n  p* X1 u  v
                            <xmin>254</xmin>
    5 R' b* j4 i# }4 r                        <ymin>163</ymin>
    & v/ n: ^3 N0 ?2 [                        <xmax>582</xmax>
    . j9 G9 O5 x) [- ~$ z) F) S$ E/ i                        <ymax>487</ymax>! |' k- ]* y( `1 [8 B+ b
                    </bndbox>
    2 a$ Y, E1 k# Q0 L, Y8 l        </object>
    8 A. Z" q! W3 f+ l# j+ h. P        <object>% _8 j7 `* i, O7 F) q3 [; Z1 O/ S3 }
                    <name>apple</name>
    3 _+ ?& H% L% s  h                <pose>Unspecified</pose>5 i; o: t7 p8 i/ n6 t4 U
                    <truncated>0</truncated>
    3 p9 Q8 D9 M  o- ~2 K: e3 P                <difficult>0</difficult>8 m% h, d2 ^% k( L
                    <bndbox>
    9 D% D* ^) b( }2 y) X7 F  |, \                        <xmin>217</xmin>- `9 ~" f% H" C! v2 I9 h* P
                            <ymin>448</ymin>% Z  `+ E" R! o) H! D# t( D: e
                            <xmax>535</xmax>
    ( r/ N% p- U  l' e' M$ q                        <ymax>713</ymax>/ t8 H  J( V7 m9 I) b$ U: _/ M; f6 e
                    </bndbox>
    9 }# J: K' |( S% E. J6 g        </object>
    - f9 b' q8 r2 f3 n  e# c, r6 d( x        <object>& J$ y6 {8 ^5 I
                    <name>apple</name>
    + o- \! H& K4 z                <pose>Unspecified</pose>" R: c( f4 G. u# B( g# `2 _
                    <truncated>1</truncated>
    1 c1 t* A* t: v7 H+ G+ G                <difficult>0</difficult>
    1 j0 y) I/ i. a( d/ w                <bndbox>
    ; I0 F7 S! J. X% F: U9 Z                        <xmin>603</xmin>
    / l1 R0 C+ v  e. {* J                        <ymin>470</ymin>
    / H# T5 w; a; \0 y0 T) W6 C% E                        <xmax>800</xmax>
    2 e% p9 R/ o+ k                        <ymax>716</ymax>
    ; N# d- d# Y+ I* J                </bndbox>9 i- u8 \' p7 w5 f3 G; T2 c
            </object>
    1 G3 r- }' n5 B3 V9 [6 f7 Q        <object>7 n7 p; }" d9 J
                    <name>apple</name>
    5 p# W8 C3 O# |                <pose>Unspecified</pose>
    ; a3 c+ I4 |; I. n) Y+ H  \% ~                <truncated>0</truncated>
    / S# A% z/ F$ f6 U  d! ?                <difficult>0</difficult>
    5 E; l) S$ j3 x- j, Z                <bndbox>- M- m- |' G1 ], X' O' C; I2 A
                            <xmin>468</xmin>& b+ p9 i8 y' I( s5 b+ g, ]
                            <ymin>179</ymin>1 z2 p$ l' y/ O) q. M% P4 ]
                            <xmax>727</xmax>
    , w5 L( Y+ U' |" r3 Q' L                        <ymax>467</ymax>
    , o1 `$ J4 i5 N5 t+ w                </bndbox>- z( C. _/ P9 s" [
            </object>* Q) l3 q5 F+ @6 T
            <object>3 S9 h, z( _! @7 L
                    <name>apple</name>
    9 Z' L" B, E) ?2 |8 F& L4 f) O- K4 H# u* l                <pose>Unspecified</pose>
    , e7 M) a* Q. b! p. ^2 k                <truncated>1</truncated>
    2 C$ x( F, @, S% \. ~6 X                <difficult>0</difficult>- n0 _, j4 b" D
                    <bndbox>
    : M4 ], ^- G; @                        <xmin>1</xmin>
    8 W8 R9 v' [( Z2 V7 q5 H; U4 [                        <ymin>63</ymin>" Y5 E  b/ D+ M, v. P. ]0 t
                            <xmax>308</xmax>8 B; z. i: l! W' v; Y
                            <ymax>414</ymax>$ r+ H) S# Q, |/ ]
                    </bndbox>
    # {3 }$ B& J+ l6 {; P8 w        </object>
    ' U2 }/ k, Q7 \1 B( k3 F</annotation>) C, B# L/ @/ I
    1# H' ~0 s  K  g' R1 U
    2
    0 J. o( {4 W$ h8 G6 z3
    % Y& V& A% p) M) P* H+ Z' K" |41 N1 p8 I$ Y1 }5 `& V! h4 v
    51 \" a: ~: n5 n1 {6 |! T( I* p
    6( V6 ^( s  U6 \) Q3 m% f. L' b2 Q  n
    7
    0 M; f1 c& B2 y- f9 S8
    ! Z( F# r: a4 z+ V' V0 w+ I9 W9& K/ [' {0 Z3 b' X. k
    108 q6 O$ |7 M8 y+ z2 Z- U
    11
    6 @1 l) l) ?2 Z0 G9 P12
    4 H  |' A0 o% I# ~; d13' O+ S" r: o$ S- M( M( F
    141 _* c  l/ s" U  w4 \6 m7 u" u
    15% g+ h# u6 g# v
    16: _: A& {( |- _  d4 C
    17
    $ C$ e. Q/ t7 R& P+ ]( B9 I, [18
    ; `1 S7 M7 E0 C( z7 S19' j3 h3 d9 W# N6 \) M
    20, k( ^& w" l! f
    21# q* Z. Z/ S6 q0 f6 K! V/ d1 i
    22
    % B) P7 P: _9 g" f1 x, m. d! k23* K( ~6 _0 P' v1 r
    24
    7 U" [8 e' z) b/ A/ |25
    0 c( e+ P; W; {0 j3 a2 U26# E! c/ ^/ `4 V# l2 f7 c% y
    27
    ! R8 w: F( X" }( e! W2 C# ~28! {2 k% S0 r- L- r5 g  W- S
    29
      b6 N7 P  k3 o. R# G3 H30
    2 t3 w" v) c/ Y9 f: A6 ?2 j31
    - V& ^! v5 T- x6 s323 X& p4 C7 O/ c4 p. {5 H
    336 U, U+ {+ {$ [. b1 h
    34/ t8 u8 {4 U$ Q  N7 l+ d- S
    35- w* Z- Y9 P! W+ O& J7 i- J
    36$ R; c" J& c3 {, {# n
    37
    ! o3 t" z) F8 K# a! j) y6 [382 _) g6 N5 d" ^# w3 @8 R
    39
    9 z. v$ w/ ]* k; x9 `+ j4 v40+ C/ n  T2 c+ d& u8 w/ u: S) l/ t
    41
    . w. ^2 y3 N/ y7 m- g428 x2 l4 M$ S. _3 a4 w
    43
    % l/ B! p6 e  p. j) b( f44
    1 X' H% ]9 g2 P8 E( J1 K5 b7 ]458 X$ o1 R, J( j, _
    46' K5 w1 y4 H8 K! J. G1 E' y: [
    47
    + E( J$ m! |/ ?48
    # o) B' ~. p$ `) D4 t493 y) P1 K( S1 w9 m" u
    50
    / \- h( ]2 F- ^1 C. C51
    + D$ f, q# N3 k3 _- a52
    ) g* q7 `7 I+ i7 ?% ]6 j53  ^4 J: a3 p. C9 P/ F" W' v
    54
    0 @; _  G2 Y: J8 J: ?5 Q55
    % b1 f# ~3 u( a/ ^& k' O56
    7 H- S  S; P) l# m! V- G57, V/ q4 W5 \4 Q
    58
    ( b" [9 F2 M: ]2 T4 V2 V59
    & `0 U# w* }* |% R. u; d/ ]# t60
    + g$ b& b  `% {1 T/ R6 O) w* z61
    6 C* b  g' u/ D5 _' f5 h4 R6 i62
    0 h% G6 F; x* c5 `63
    8 [/ b2 k, @$ g) F! J64
    1 o! m6 K" L& T. n65
    6 ?: `& P5 s) i4 q$ x666 w/ N3 y  i+ e  h
    67! v) V0 i) [- a9 W' b' J4 d8 q5 v6 L2 f* ]
    68
    : A  N1 B9 N  a8 p3 j+ j9 r, S69
    % H! @7 a" k! R  Y; m; S) _70; ?) x/ ~* E- V) Y6 T; U
    71, Q/ {; V( _4 n
    72
    " w) J9 i! X- K1 a2 R8 L73( @8 |+ q& v; O: ?3 {
    74
    5 L% D% _* f' k" K" z将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。
    . [; B. j; W6 y! o$ I1 V9 E; K7 P2 w4 [7 W( B2 V
    / I1 s4 ~9 R% n$ ]5 r
    import os
    + e, {: F( C5 p  C  f! ~import numpy as np& T* q; u0 V' [& G( `
    import cv2
    ) S6 T0 ~0 Y- Uimport torch
    . O* E+ M( }9 h# _* q- j5 Y/ fimport matplotlib.patches as patches* h: I$ K& [  n, e3 Y6 p
    import albumentations as A) g5 E5 `4 c& e% s
    from albumentations.pytorch.transforms import ToTensorV27 A8 k6 k! J1 K1 ~3 e
    from matplotlib import pyplot as plt2 F: a+ k  r, L. V" X4 U
    from torch.utils.data import Dataset
    " S. m/ P' t% v! E6 u5 @2 Tfrom xml.etree import ElementTree as et
    0 d4 W' k. J9 d2 _9 K, i- ?from torchvision import transforms as torchtrans. M; H% C0 q2 o; z3 W; ?) s7 i
    # B3 N& C, d8 H( r. ?* u

    7 T+ n6 I; d1 d4 r- M# defining the files directory and testing directory
    / y- V+ c* I! Jtrain_image_dir = 'train/train/image'
    0 f4 ?  S$ o5 D) i# atrain_xml_dir = 'train/train/xml'. l4 g0 _7 x0 l4 x$ s
    # test_image_dir = 'test/test/image': P* l$ R9 U6 w- `3 s3 f; `! h6 e
    # test_xml_dir = 'test/test/xml'
    $ O. k  Q3 Z% L2 U8 ?* T$ `+ z" N
    0 t3 z, q+ c2 c- A# ?* p' d, \

    8 b) _- q2 j4 c$ R1 E, {class FruitImagesDataset(Dataset):
    # @1 {- @5 D* T3 ?& O. B1 Z
    + Z% o5 I8 G5 o
    & p; Y4 V! \5 k7 [+ m; f" u
        def __init__(self, image_dir, xml_dir, width, height, transforms=None):' W) s! o6 a9 B; z- W
            self.transforms = transforms; U3 Q  B" t5 S$ s9 m0 C
            self.image_dir = image_dir1 W2 ]& x! V! U+ f7 [
            self.xml_dir = xml_dir2 r6 [5 |0 R1 @
            self.height = height) W4 G' ?$ _, e. A, y( E
            self.width = width6 `2 k2 b- i% |. a6 M$ |) I/ C: ~
    & i3 X3 l& P. K4 B( g, G
    0 v" }4 D9 \& B. i
            # sorting the images for consistency
    ( Q$ G4 s& w+ X- s8 L8 g' K. X        # To get images, the extension of the filename is checked to be jpg5 }- Z. q% v/ U7 }: n& p
            self.imgs = [image for image in os.listdir(self.image_dir)
    ) I  ^0 l2 ~& B, g. c" q! D                     if image[-4:] == '.jpg']
    ) l; f) K. f8 B5 @        self.xmls = [xml for xml in os.listdir(self.xml_dir)/ U4 K. m+ C. ~# o
                         if xml[-4:] == '.xml']
    - J- n1 O% j+ M' f5 z# h2 R
    + M9 @5 @3 t. d0 a0 G( [

    4 i' a, l# v" E, E        # classes: 0 index is reserved for background; n/ d' w( O/ M0 C; L1 u
            self.classes = ['apple', 'banana', 'orange']' b6 v2 I, n  C* ]& [
    ) q$ ?8 d% O) O8 S

    " C5 |  f) K% c( W. Z6 G    def __getitem__(self, idx):7 Q1 q; V$ ^9 ~, e6 k

    + b2 i1 ]' f* k- d# i
    9 P1 z3 D* x1 I7 |' C8 ~) N; {
            img_name = self.imgs[idx]
    ) L& R6 g4 Y" a( {9 O9 o0 a        image_path = os.path.join(self.image_dir, img_name)
      [: J* C! b8 t/ K! ]1 S* c5 G0 g+ Z, J% D
    0 p6 ~7 e# g% e7 `
            # reading the images and converting them to correct size and color  p! V  z5 N3 C2 X5 w# s7 I
            img = cv2.imread(image_path)
      m: h. }4 R% j        img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)
    5 O/ O6 b1 o' c2 y1 Q6 {        img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)
    7 s2 ^7 ?' P; }0 e0 ~* |/ Z$ ]        # diving by 255
    % \7 l4 O# D( L" m" A, U7 @; ]3 s        img_res /= 255.00 O  g8 a6 w4 i, x0 O3 }

    , C% ^3 |( d% w7 w

    + @! z# R7 v0 B0 B2 u* ?2 B        # annotation file: e- P7 g1 T; d" D4 S: a
            annot_filename = img_name[:-4] + '.xml'- }3 U& c$ X- W- Y" ?) l8 [
            annot_file_path = os.path.join(self.xml_dir, annot_filename)  ]% v( F- g5 P6 j8 ]
    ! M2 \) P+ G# v' h( [
    # A; j. i* J% \+ t' ?+ V& X
            boxes = []
    5 o0 P( `+ l) o" I        labels = []1 B, d3 m: \7 W1 B+ @7 X
            tree = et.parse(annot_file_path)
    7 k) P# `9 }3 ~, n) L        root = tree.getroot()1 t0 N& b8 r3 o
    . |" u& h. \% V. a9 P, G9 n
    " `5 w3 ?* o5 X) u$ j* O9 P5 b
            # cv2 image gives size as height x width/ k* g* j; q. O" f; x
            wt = img.shape[1]
    0 N2 \( h. p* u. j/ K        ht = img.shape[0]4 n* a3 `! A; z, A

    - |, a! s* Z/ h: ?5 e: t1 z
    ( p0 [& X  l7 p4 ]- c5 r; R
            # box coordinates for xml files are extracted and corrected for image size given( c3 A( _* |' p" `( L% V
            for member in root.findall('object'):( Q+ z$ `: I  h6 n1 K1 \* E
                labels.append(self.classes.index(member.find('name').text))  v, A6 w1 f( ]4 j2 L" U
    ) m, A" [9 U  _$ a
    : @/ i0 I% v' T1 \( ^( ~7 X( w
                # bounding box3 |, i4 b8 f+ y
                xmin = int(member.find('bndbox').find('xmin').text)4 X0 j% M, U" m! v" d
                xmax = int(member.find('bndbox').find('xmax').text)6 M8 p0 R# P- V1 x9 J- W
    , }+ v/ N* x6 K; U7 I2 y5 N7 \4 Z

    5 R5 ~# O. j- n            ymin = int(member.find('bndbox').find('ymin').text)6 y6 @9 L9 t  C) P
                ymax = int(member.find('bndbox').find('ymax').text)5 ?: L$ F4 g9 B+ d9 P" X
    5 Z$ G) l! ~- ~, [  g# `

    ; y" Y5 s3 H2 X% n* r6 q            xmin_corr = (xmin / wt) * self.width8 j% c1 L( t; P7 R1 v5 y
                xmax_corr = (xmax / wt) * self.width3 c5 j  v/ R1 ~' o7 j, i% F
                ymin_corr = (ymin / ht) * self.height
    3 o$ j- y0 T4 W# g; B            ymax_corr = (ymax / ht) * self.height
    ( [! u0 p( j5 f% U            boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])
    + t+ @3 ~; ]4 V5 ?+ K& I9 c% \+ `% y" x  x' F  j: `
    7 |3 o9 t/ g/ w4 l2 |9 `
            # convert boxes into a torch.Tensor* J# w- t' `& \& e1 t# Z
            boxes = torch.as_tensor(boxes, dtype=torch.float32)8 n' ?+ W$ C' s8 w, ^

    ; q6 l; X5 Z3 h) z* U
    4 r3 u# o, x4 ?, f1 y
            # getting the areas of the boxes
    1 c& B% K4 T  Q! }) C) O        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])& K/ e' }8 x- R

    ) E! d  f1 S" f8 P3 e/ j

    0 m% v: t: f+ @: m6 s' j( v# \& |        # suppose all instances are not crowd5 O- f7 s& Q  |. L9 k3 N2 W7 H
            iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64)
    % @% H6 c1 L2 @! \) J( G/ ]1 x
    4 x+ t- O3 J6 Q# H/ K
    . T! |, a6 J' O! K5 `) F$ v
            labels = torch.as_tensor(labels, dtype=torch.int64)& p! G  t! |' D1 b; X

    - U( }7 }7 J1 _9 }3 M

    . o' \3 ^8 U# {9 t2 b1 a        target = {}
    # L: y/ t+ S  K* D1 |# i" b  A        target["boxes"] = boxes: Z9 L  y% D# B: K0 q( [$ j2 _( n
            target["labels"] = labels& _* M) t0 z! Z% X3 |" b6 @
            target["area"] = area
    2 K2 l6 {, f+ e2 ^7 G        target["iscrowd"] = iscrowd* P$ f: V1 z( }) {4 n
            # image_id3 J& J8 G# r' b7 i' n9 ^9 Y9 F) ]3 y" C; G
            image_id = torch.tensor([idx])
    # B+ N! }, U$ F: ?* g: f        target["image_id"] = image_id+ S+ P( d. J7 @: Y( J: W4 j
    7 J% A+ f3 H; ~9 ]2 m% N

    7 T6 t  \& b) w        if self.transforms:% x# g% e: i( g0 F( D
                sample = self.transforms(image=img_res,9 x/ m4 M% }1 r) d
                                         bboxes=target['boxes'],
    / S; g* X) B: f. C8 l3 I                                     labels=labels)
    ' l# I5 f, e  ?& F/ o+ O* f* h3 D! B$ l$ U0 e
    $ l- k+ R. n/ P, T- @& E
                img_res = sample['image']
    6 H4 D. e9 M0 \            target['boxes'] = torch.Tensor(sample['bboxes'])1 F5 J# u% g1 k  H/ u+ N, [4 k3 f
    3 C+ @3 g# x, G- m/ R% C+ J

    2 l6 }: ^5 X: w# D        return img_res, target
    7 K! ?1 u! p1 W! v, A( U3 i$ H: G+ M/ D
    ( H5 s$ ~* R/ R! z! L9 Q" R
        def __len__(self):
    $ i: k3 Y1 e- N' P; N        return len(self.imgs)1 j, T( ~; ?/ |" [& w

    0 ?0 `% q# s8 u

    + h0 R) C5 L! v; s# function to convert a torchtensor back to PIL image
    9 W8 V5 A" r8 Z1 qdef torch_to_pil(img):6 |( F: c0 R) |! l$ [
        return torchtrans.ToPILImage()(img).convert('RGB')
    . C2 c4 M7 [3 }) @' f1 M; S+ ?' T/ {1 m
    0 r) ^. J* {0 `; X  O0 b
    8 q6 `$ t# _  W5 J( Z+ B2 k/ R
    # M& \; ~, S$ m' i
    def plot_img_bbox(img, target):& [6 Z* s7 G0 T- @
        # plot the image and bboxes9 |3 ~: v. s1 s- ]* l, E
        fig, a = plt.subplots(1, 1)
    ' ?0 i" d$ S' ~3 B- I  d# R    fig.set_size_inches(5, 5)- h4 [6 }: w& S9 Q0 x* s
        a.imshow(img)
    ' i" L: L  v4 w1 Y+ s    for box in (target['boxes']):. \2 _2 ?5 f% W
            x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]4 ?+ |" ~( h' ]
            rect = patches.Rectangle((x, y),: O% w; [9 L7 L
                                     width, height,' p/ k/ y! o7 O" R- E" ?0 X
                                     linewidth=2,
    * u0 I5 K( u; g7 L, l                                 edgecolor='r',. S- s# z5 o2 ^3 x+ J
                                     facecolor='none')
    3 ^0 O, A3 u7 `! Y6 z! t+ \3 m- |1 n' O3 ?* c$ L3 U3 C: n9 W
    / r) l* H' s2 j' S6 X
            # Draw the bounding box on top of the image( o- g6 r4 Z( n8 Q
            a.add_patch(rect)  i, K/ t  n/ O: f
        plt.show()
    + J+ B( C9 o: f) B! J5 e4 N0 Q+ }
    ) m4 H0 ^  s! U2 k. [( m1 v8 Y

    0 X3 v' y# B9 l: Y( `! q
    5 ]! n& [4 A. Q1 J, b7 I
    * i7 N5 O- X" }0 g0 r
    def get_transform(train):* h1 R) e$ k# a" Y/ `& B
        if train:& v- E: ~9 T, Q% i2 \
            return A.Compose([
    8 W% Z4 T' j. c: h( e            A.HorizontalFlip(0.5),' Z7 Z' Z( v& v* ~% D1 \
                # ToTensorV2 converts image to pytorch tensor without div by 2554 _& e! i' R% k" z7 b
                ToTensorV2(p=1.0)
    ( d: O0 _7 z7 r  `7 V& n        ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
    $ P) y' g# D' F/ g4 [' m    else:/ R. J3 D3 W  p; N5 x% |+ k
            return A.Compose([
    + L  N8 ~; ]1 ?6 V% y* r            ToTensorV2(p=1.0)- k! }+ j' A0 m" |2 b- A" h6 I
            ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
    " l& w  N$ [4 S% D: d, t% L% ~2 L* w1 q3 z) y, i0 D8 r

    . S$ `/ F# j0 M9 b% O0 q' B( m- F  Y4 X3 D1 T2 U) P3 J  W1 o, N

    , B% {4 ?9 g8 k( v; `! S6 X' I  ~# ^& z. N6 ^0 m. ?& n
    . V# s1 @- A# [8 W9 B) k
    dataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))3 r& E+ K* k0 C; R; T
    6 K$ c/ @" i6 N

    ! b/ L' {! K' Y; J9 K7 g* }print(len(dataset))9 [- y$ F- y2 L
    # getting the image and target for a test index.  Feel free to change the index.7 F" w( f  Q/ P' n5 i
    img, target = dataset[29]
    # H7 Y0 u  t, a! ~& N4 {print(img.shape, '\n', target)7 I6 V  U9 l3 P- @
    plot_img_bbox(torch_to_pil(img), target)
    + r4 q# q* ~4 S' W$ a0 L0 \1$ M. q( I# Z2 v+ }+ ]
    2
    # ~* b# e. @6 V1 |9 p) b3
    6 ]3 Q8 ?7 @$ y: P. a, @# _- c49 k' D; _1 ]5 s8 G& |: b7 N
    5
    1 U% f0 C0 l3 E6
    0 m, i' ^. _" x, e7 ~4 M  g7
      F3 |* ]6 C, c4 B; D8
    7 c" E3 }5 ]5 L/ D, j+ |9
    % V5 D# Q6 G4 |. k& s: B8 L! ^' R" X10
    6 K& U) \! ]2 U" ]! d( r11
    9 K! Y+ ?* e6 B6 ?12
    4 w! u6 i; [' a. B. T/ u) U13+ m% h* m6 z- H
    14, P9 L* h$ ^( N0 n- H! q* Y9 `
    15
    ) n4 Y& }. ^0 P  u16
    ; @& E9 k- i6 }  B( J17
    # e% s2 Q) k+ F' j, R0 N18+ K1 T# V/ B9 H2 D* S. X  l" v
    19- p/ _2 G) g! i' L( u$ c0 v
    20
    3 j. v6 C: X8 Y0 w1 e) r21
    8 I+ r0 v2 S4 g- V' Y- C; P22
    * P8 J9 U, x+ b& X- w4 w0 `23( l) b  {  l5 B3 z: L+ u3 a3 h
    241 O! I9 R7 f5 p( b, p2 M8 q
    25* F* o+ m1 t( m
    26. A% C" G2 j$ l* Q( A
    27/ j) t) C0 i; G7 C# [9 t/ n2 \
    28
    ' k, F! E- z  x9 E6 Y29% n9 _  c7 O0 E7 T
    30& _% r1 a9 w4 `: W$ z* X+ V2 B
    31
    # j; b  V" e) b2 F32
    / F# H' x+ C6 t8 B( g# c33
    : D8 B; ^8 l! d34
    " F- }. ^2 [9 H- X35
    6 k, [6 ~0 R/ U; p36- ]4 F* M/ H% p) j1 q8 T2 P
    371 }; K/ Q0 X) O
    38
    6 e7 E6 X7 J( \" V% V: S39+ j" e2 l$ `& a
    40; G( t, I6 c( Z9 k
    41
    ' f9 w8 f) A. U: a42
    , r% E: W0 V; S: d4 h+ w43
    4 k& a1 r+ Y* X4 I9 p440 @/ O2 D; V' x
    452 k; V% M5 U. ]" p
    46, ?- m+ l' n' {) s0 a; j6 j
    47: T* a# X' W  A% q0 a
    48( K3 T8 e9 j. A2 P6 [
    49
    ' z  B- G5 T( a' o5 p) l9 o$ W$ U50. c/ c( c2 }. F& [5 ~
    51
    ' v7 F+ N7 Z+ X. `$ }  n2 i; B0 o523 A7 f# C- G: v. s
    53
    % |3 |% [7 Y1 J% K/ j/ V0 g54
    , p% @& B7 F2 @1 v4 M558 u8 s& D7 X1 C0 v4 B
    56
    $ Q9 `4 {0 h! c) o( I7 D57
    8 F& z/ m$ v  n3 W58/ D# `' Q5 A7 A/ J3 F* _
    59
    4 g4 `" S6 `0 d4 s606 ~* r! q( G; r7 p
    61! g- K# |+ @: g
    62* g" i( e8 z# i' W. B4 p! Z* n
    63! j, D7 f) N0 W$ h
    64
    ! c9 ^/ ]- x0 n/ s+ ~7 }0 L65
    : p* ~, w( f7 x  K66
    " u3 _5 f4 T  l67
    0 d+ h5 J0 v" J: d" a& E3 E685 I6 R$ E3 K# ]9 \9 o% g- G+ f
    699 n  a7 t6 L5 @6 N8 W' M+ y1 J: t
    70
    0 q* J/ V( z5 O! ?8 B: Y- D6 U/ [# v71- J) n3 |% g8 Y% U' k
    72% _$ ~; f3 b. g, {% U! l
    73. r- A+ P, }! G* N8 v$ n/ f
    74; }" l' Y+ g3 R# S+ W
    75
    4 q+ k  k- j: D2 X) P$ r& b0 H7 H76
    % P# K& n0 S1 d* ^8 S$ L1 R$ h. [77
      ?+ f5 w2 X6 w* a- P% Y78+ H- r6 G6 D7 `8 F$ o+ o( ?; l
    79
    , X2 v0 F; T! V3 @5 c1 k80# A9 I4 U: v& r/ y" w
    81; P: P+ q5 U: q; b8 {: B
    826 ^; H$ t, a2 ~2 M; L6 q
    831 W- x4 i; [* M; m$ t( m! e
    84
    & Y2 g: Q3 I& T; R85
    * H( ~9 Z' e$ G0 W7 L! U86
    0 A3 I! P' c' \! O87, i! y+ j) f$ p' r. Z
    88$ b$ Z( V) G: D* D
    89
    , w: r/ W  q% w3 H4 L4 ~90' L6 k: `  R. }- t
    91
    ) L* _+ C5 z+ ?92
    / w' T8 H, p$ L& n8 q: _93: g( x1 j" c$ [
    94
    ' a0 D* i2 J7 s3 ]; C95
    % F  L9 K7 P, f1 |8 `; T96, o  o! ^# T# k# C
    97
    . Z/ c6 w: u2 ^/ |988 r& n* \, o) X  p: S
    994 j' `# i: Y; |& t) K
    100$ f- e* S. O( z% u. v* l
    1019 P* ?: G9 v0 f. W3 S
    102! w* o* n- s' w4 G0 a' E# P0 B; W0 q7 M
    103
    : k0 C; X. c9 o104
    6 Y- x/ E* \1 ^1050 G0 L+ i: {) H" `0 j! R" N
    106
    ! O! u3 U: P6 {) a1 y' T  O+ C& m107
    - P- o0 J1 E. @7 t- v& i$ m108+ ^& Y5 H) Y4 z
    109% |; L( U4 u' A& m! R7 j" S: t
    110
    ' G7 \/ }4 n7 M: j* ~111
    # k2 j5 m$ s* n; B9 l# l112
    $ ^% g  _0 K* Y  Y* L9 B+ K/ B: ~' a1137 U1 F7 N- f# _$ [1 M! q- {
    114. ~+ t0 Q- T+ w
    115) G& M# _2 g, I* E9 u+ |+ ~. q4 [
    116
    1 x5 _- s; h& M1177 {5 z6 L. }) H" ~# B7 N7 [
    118' D/ j9 U! G" P. {. t6 Y2 @
    119/ m% S! h8 o: [5 {. @2 C5 q
    120
    ' A+ \: r4 t; H- O0 `$ A* V3 x/ J121
    . w6 i. l7 F5 a. L; d& H& K6 {/ S122
      L2 P5 U  t4 j1235 Y- Z2 V: J/ h; `8 h. D4 A1 R
    124" O/ Q! N6 F# t% |" \3 H/ e
    1256 ?8 k! i% |! g: R, U
    126
    , }5 Z4 P/ b  N' K% G: l& d127
    3 w  Q* t- O( Y/ {# o* F2 N1 {( J128
    5 f" C) v# c' _! N/ S+ L* _( I9 K% u129# p( {& P! w9 R/ a5 }
    130
    & q- q+ P8 z. K0 q' V9 T( ~131
    9 }: G5 a; _3 u' W132
    ; g) ^/ e8 Z8 j( p1330 x  X, n. y, b$ J$ ]
    134
    * d/ l( A3 P+ x( p135+ w7 y. e6 z# Z+ S1 @3 l; m* F/ L- G
    136
    ) C* D" `& A: y$ w2 ]137- R: E  q1 i, L3 w5 X, O5 L' L( m
    1380 V6 K" D+ f7 t' m& M  g
    139- f3 ?- C' u0 d
    140
    9 }6 @1 r* z  D: j+ ~5 ~& s141" x) H, e+ r7 \& [' O# `; G7 A# x
    1420 |/ K; N% i5 u% v
    143
    . N9 [  n; p7 x9 p# o144
    $ `! v9 b/ z. B8 ]( y0 K145
    3 Y) X! r& C/ D5 m146
    1 J: l+ @" R* r" }7 T147
    & w( ?! |5 Q4 [0 k148
    & Q9 {- h: D0 X+ _7 {149
    0 G3 L& J$ ?) C3 |) P$ @150
    % `, [" f1 e9 o+ g( o151& u3 s9 j) c; Y
    152% y0 O& L! r" g, A! ?$ m3 Q1 a9 O
    153
    ) ]9 n+ B3 h4 u154
    ( {* g9 N) Y6 y! M3 A8 E1558 q3 ]5 j$ ^" F
    156: G9 c7 V9 y9 n- t2 h$ L
    输出如下:
    ; k7 E" @" A  @, G
      ?% w3 U+ B- y; Z% J9 m; E1 l! J! c+ l
      J; H% O& B& v5 Z
    torch.Size([3, 480, 480])
    : E* s) Y8 M  ~3 J8 ~, i {'boxes': tensor([[130.8000,  97.8000, 327.6000, 292.2000],$ P+ Y: q" s) s( t/ e+ I% O
            [159.0000, 268.8000, 349.8000, 427.8000],7 o+ ?1 E  s" N4 n- }
            [  0.0000, 282.0000, 118.2000, 429.6000],
    4 R" K3 W: h' O6 A* z        [ 43.8000, 107.4000, 199.2000, 280.2000],6 ^' T+ z4 w# }, P! k1 a* l
            [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])}
    / V2 O1 ~, c% K- {0 S$ B. [3 c1
      u7 h7 ^# c3 ~) [5 I2
    # L: n. j) P3 W7 @5 {1 H3: d! p. N4 W2 s$ z% _( X& z
    4
    : M! U) M# L$ h% B( A5
    - K7 L0 E4 b; c* q* A6" `# _/ L: O& o6 p% n4 p$ `
    3 ], N/ K, a; F. i+ B
    4 {/ _& ^# D% Z* s
    / O% G% n! K+ H5 W/ j

    2 ^! Q3 k" @, C( T下载地址
    # D. L( y  y, f0 T9 u& J链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw
    0 @/ y! P6 J; w! `3 Y. T# }提取码:srjn
    - G' M7 x* l1 n0 {" N————————————————$ p, Z( V* b( R! N. s
    版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ! g+ y$ z$ f  p+ c1 x% t( b$ \5 |原文链接:https://blog.csdn.net/weixin_44510615/article/details/118496273# I& ?1 `; H$ D4 G) q" b
    7 K0 t" E& q1 K5 C2 W) z
    , r4 x* x- e6 l% `* a# c
    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-11 05:04 , Processed in 0.350419 second(s), 51 queries .

    回顶部