; s, z ^8 f% T+ c; I" v 6 D3 `' ]+ l$ {7 L' J<annotation> 8 u# B$ M& J: K7 z/ I* b <folder>train</folder>8 _8 c( |' P. W3 _9 V: t
<filename>apple_30.jpg</filename> + L3 H* v" Y" ?: |& E <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>3 {2 `1 |6 L4 W$ n
<source>+ ?$ _3 E9 n9 k: Q
<database>Unknown</database> & p7 T4 S) @. K8 i2 g </source> / L/ g3 V- X. R' v6 d& | <size>" ]8 A) \/ e# \ A8 @/ p2 O
<width>800</width>, R, x& t" ~. o! C. Q4 g7 F
<height>800</height> ( E$ K$ F9 [6 t, c4 a* c ^ <depth>3</depth> : k2 f+ D0 g: E5 c: `7 N </size> : ?% o8 Q7 p- H <segmented>0</segmented>% X! U0 s: v) H: I/ [9 t N7 [( ^+ n
<object>3 B) h7 h9 v6 }3 [3 }" r: G
<name>apple</name> ' Z: L' ?3 ]/ K" r* A <pose>Unspecified</pose>$ ?/ s* \" ~. k
<truncated>0</truncated>* K" F! S' e1 D. e! S W
<difficult>0</difficult>9 k( q6 y; k, j+ d8 `& @
<bndbox>/ L0 ?: X- U' q& x1 u
<xmin>254</xmin>& n6 v" V( ]! k0 H0 m+ m, s
<ymin>163</ymin>: Q( J3 t- U& j9 e" g, u
<xmax>582</xmax>& [+ H5 G! l7 z# ?
<ymax>487</ymax> # N& {8 p! V; M5 f; n% y </bndbox> + s! U! ^. e* d! W f$ D) R; {9 J </object> 3 Y* |6 w+ c, c) t% f! \, w <object>5 q$ k) r; D! H1 R& J' ~
<name>apple</name>) `$ n( c7 ?+ T- J
<pose>Unspecified</pose>) F9 o+ e, l/ x6 b
<truncated>0</truncated> # s. R* i" A6 i1 q7 B <difficult>0</difficult>- d: M+ t) L4 ^* h9 o
<bndbox>8 S# E9 v+ i0 K. ]/ _& y |9 q
<xmin>217</xmin>0 B# U& W- w3 d$ a4 Z& x
<ymin>448</ymin>) N' x3 H9 A% @6 G* b
<xmax>535</xmax> " t1 h4 v- O% m* P" y <ymax>713</ymax># Y! t% Y2 Y% H5 A+ B: ~- p
</bndbox>) K( b3 ~, r- d# o" b, E0 ~- K
</object>" ^1 d6 p7 a- K; o6 j' R+ U7 L4 d
<object>$ s Q1 x. G5 A/ l1 X& a
<name>apple</name> 2 k1 y( l2 e* S T6 \ k: z0 f <pose>Unspecified</pose> % {, Q; Z: g) L2 ?: W! t5 s <truncated>1</truncated> & A6 B+ p% U8 b$ W' g* o <difficult>0</difficult>* A, l( ^: U3 g9 f2 c5 ~% L# j
<bndbox> 7 v" Y9 s7 ~9 S* j0 m) o <xmin>603</xmin> ! {0 p8 R U4 m, U' V <ymin>470</ymin> ' o8 c3 a2 Y7 c. E0 S; k/ v2 k* t <xmax>800</xmax> " Q- D. V" J+ V6 {6 N- U' j( l <ymax>716</ymax> + @) {3 X# u( x$ ^4 v! K </bndbox>5 R6 L* ?0 Z4 f4 u
</object>; M% ?5 M% s" m2 }' U
<object> * g, c6 {- |6 x <name>apple</name>6 @" `1 `% z5 G, j/ F7 x' I
<pose>Unspecified</pose> 9 {1 t9 T/ p( o. u! G2 D9 j <truncated>0</truncated> ; ?4 ^: b) d, K: Y3 A <difficult>0</difficult> ' D+ I. j( f, h9 p <bndbox> : ?( S/ T6 o, b! h* `$ B" u <xmin>468</xmin> / W; K1 D; a# j: ]; l, v7 a2 ?8 n <ymin>179</ymin>' l# ~5 k. w( M
<xmax>727</xmax> 1 O. e7 j5 q& f' I <ymax>467</ymax> ( ?( ~' G2 q3 W& W* y0 Q6 F$ m </bndbox>* _# ^. |; q4 X, S( q: V& S# `
</object>) U8 {% n/ U4 O
<object> 8 _, ~# W% w+ a, P <name>apple</name> 5 ^% Y' W6 G1 C+ _; l <pose>Unspecified</pose> 5 C( Q% _4 e" y3 U7 K <truncated>1</truncated>7 F: L& D3 n% C6 m1 a
<difficult>0</difficult> ; _5 f& i; C7 c* M: a! l <bndbox>' X& I5 { a( [
<xmin>1</xmin> 0 S5 y- b) R5 j: d+ d <ymin>63</ymin>- L& `! P4 E6 L: A( r
<xmax>308</xmax> . m Q0 O/ e% Y7 z( G. z8 S5 n <ymax>414</ymax>: g7 E5 D1 w& {7 h( u* |( [. f
</bndbox>* D O$ N" Y# V# a5 V
</object> ) J8 y. @& F: Y- D+ b7 W</annotation>- Y6 T/ t0 `( M( n
1 5 o0 c5 ~( p, `% T' A2; X( Y% ]& E) \$ N0 d
3' j: f G1 k& t5 b# v1 Z" J8 r9 J
44 B' Z* n5 F3 Y+ C, `; S
5; n7 ?/ F9 l0 V
6$ U. [0 _- S2 q/ y
7 , ?9 h/ d2 R0 v. `- p8 ' E, {1 R0 [* h7 F L3 h: G' O9 " ]5 \' z4 P0 U. h: V* Q6 v10 , i5 ?( E0 ]' C% U8 L# \& Z/ N11 8 x7 A7 B A) ]127 J5 |* ]! s* {
138 A d' w* K) o2 F/ Q6 J9 j# G
14 , A- B* M: p U15 ! Y) i0 S! _7 v; {$ l% H160 A+ \( U) H Q) ~$ p3 s
17 ; J1 }6 l: W1 \+ _18 6 s) W/ Y9 K' S! X! c# \19: @8 U% ^. I$ P/ E8 d* H
20 ' F& ~9 P, m7 i/ g$ j+ Z21 9 ~6 v N. u) d. O T9 v, F1 z22% a% R; q8 t( L2 o
23 C( ^4 l3 Q' h$ g24 8 {1 {1 E4 F' h3 E- t8 Z: H25 / F" |7 O; g% z- q; x' T26 / w) c, w. _$ [, ^3 F. W$ b* i27 6 {0 F! q1 k; ^" @& S28 [$ O; C2 g) l/ A% H
29 - }, u+ {7 k$ j% t* M" p2 N30 3 H; |1 w5 }; ?: a31 ' E) Q% e: T. W# @( u& S* B323 {" k: p: V. Z+ c5 ~$ L8 t# t
33 + J4 Q& @7 ]7 x* f' W34 ; O2 V4 E( g/ t& n2 q. ]9 \( z9 ^6 Z35 # S# A* E4 H, M36 6 @2 d7 A9 f! d+ \37; O! K. G6 `& n
38& i7 {7 u+ k4 k
39' Z+ o: \1 }) h7 _0 a9 M7 t- e
403 F3 o! r/ l/ z( u7 q+ R8 o) {
410 j0 T' h. P0 x y
42 / K( k0 [$ V9 g' U# f6 M43 3 Q9 l, `* s0 q" S1 O44 `7 l; e9 b' D0 w9 T8 t
45 # B3 P, M o( d* \9 V! v% y4 t46$ Y+ a: v5 O5 H A2 c7 g
47( g( { g+ H- d- N/ T3 {- c
48 / r' W' o8 c3 a+ i% F$ p8 X+ q492 m5 v0 v* y( p% D; {
50 8 \% G8 O. `5 M" T; D51 6 T8 s2 a! e3 e+ V525 ~- d. I- o1 s" m, h! X$ Y
53 9 U8 w: W+ c# U6 s) @6 k54+ y9 p5 W: v; Y* P% b
55 " | A- q& f6 h567 V8 b2 Z( |. y
57 4 \% E1 K: `, o( b8 l58 ) e: E% f& i( f* `" p: O59 / t2 H3 ^' B- ?5 s( l( {5 C. K60( S, |1 H" E* B. f0 D# {
61 : ~' |! T( t; T% t7 F! r62 / ]& ~* `8 X& \0 ? R, X! x: k( Z63 0 |9 r" g1 l- c S64( Z+ k2 k& h1 Y2 }: d: o) [
65# R9 {! i# \# p. `. X! w6 f$ s
66% t! e0 J: Q0 Z+ S0 g
67 q/ j; B* j F& L5 w2 V68 5 q% D/ Z& }. F, l9 m. J: G8 A69 # R$ S- u6 \, q6 G8 a/ m: Y70 # i+ h; f3 }7 V5 z) h712 E) y1 i& U1 x1 J' E
723 w& x$ P7 c9 `/ W+ T
735 a9 l6 x4 ~3 m8 }6 R2 p# R6 b
74 ! V" c/ p. T. W将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。 2 o# o" s7 {% ]% z% w' M/ Y % |1 X X& B9 O$ O' P) ?6 o% g. h/ x0 ^+ ?
import os, U' w, Z9 n$ `! k$ ^& ?9 B" U
import numpy as np, T9 H% b# G/ V; M
import cv2 7 k7 z2 H: {% @! I' O8 E& j% vimport torch' ]# I n4 m- S4 B7 I$ k
import matplotlib.patches as patches: O7 T E- _3 D5 \7 }: \
import albumentations as A + c" O+ J# y8 F- {$ jfrom albumentations.pytorch.transforms import ToTensorV2 ' R& M; y! K( c1 bfrom matplotlib import pyplot as plt * g4 g9 P( {, j/ S! _from torch.utils.data import Dataset 9 L6 I' Z) ]6 d. O9 Ffrom xml.etree import ElementTree as et0 u6 W6 \$ D4 p+ D
from torchvision import transforms as torchtrans # M+ d. L- j- a' j/ a0 M1 B4 V1 \ H8 v; a
4 D/ R9 w/ Q5 U) X4 o6 A& _8 \% [# defining the files directory and testing directory2 F5 `# `. A- I- i2 C
train_image_dir = 'train/train/image'. S/ s D5 q6 q* c% M) q6 m9 d+ m
train_xml_dir = 'train/train/xml', Q2 m" p2 ]) R& L6 ]1 x2 u, x
# test_image_dir = 'test/test/image'# j% E: R' }! U8 J( Q
# test_xml_dir = 'test/test/xml'% l+ s+ ?8 |. u$ T
4 V9 E! l7 f( X" ~% ^
5 n# ?, `# s# j7 N. B# r# l
class FruitImagesDataset(Dataset):; h4 O" D" B6 t6 s
8 N2 j6 v5 L0 x 4 K* ?+ m! t( A# K/ J def __init__(self, image_dir, xml_dir, width, height, transforms=None): 5 ?; \" H1 M* o/ _6 c- T self.transforms = transforms# a' R2 q, s* J4 s
self.image_dir = image_dir 3 M% O! F/ ~ O ] self.xml_dir = xml_dir % u% ~; D$ g2 I' b8 q self.height = height- R! V9 o$ E q$ ^8 \- F7 T
self.width = width $ v% i Y7 o& i5 N! \7 N6 F, X7 g0 ~6 `- A% G: G# M$ ^% X
8 o9 `! z3 T( ~! {0 c' w
# sorting the images for consistency, V6 \" D$ k/ a2 ~. s
# To get images, the extension of the filename is checked to be jpg . I w# o4 P" | self.imgs = [image for image in os.listdir(self.image_dir)1 F8 Q( w N9 R ~" a- l! F* ]
if image[-4:] == '.jpg']) U; A! F' S$ f9 y( I: b* K' s
self.xmls = [xml for xml in os.listdir(self.xml_dir) + Y5 O$ r! \3 ?! v7 r7 P if xml[-4:] == '.xml'] * m% m! x2 L9 C) v' H3 y9 @* {9 i6 n7 l* g) z
1 h' Q c; U& U, v
# classes: 0 index is reserved for background0 Q( W) s3 j5 u& _3 P7 N1 w0 B
self.classes = ['apple', 'banana', 'orange']8 x7 e2 I0 w: e, y$ t
l" @/ e, o; `; P2 n- Y$ A4 V, W4 O+ k. {9 G
def __getitem__(self, idx): ( E3 W2 x' T7 j+ i, c V # N+ y) h7 V/ ^: ]& M$ J9 z" }. m
img_name = self.imgs[idx]7 m' H* o! [0 c
image_path = os.path.join(self.image_dir, img_name)% D6 [2 i! }# L5 E$ I: j
7 s. B! o4 F* [8 W3 u 1 n/ C% ?1 Z& ~+ l! D # reading the images and converting them to correct size and color, @, P$ J- K; r6 B. v
img = cv2.imread(image_path)+ v9 t6 T9 y% T* A/ Z- c
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)4 W8 _( p3 S9 y. s; f" N/ P# f3 L7 X
img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA). E- L3 ~2 [& M* W( Q
# diving by 255 ; E& @% }+ c6 d* n img_res /= 255.0 1 G- T' I* T. T* s7 v I. U) v' C3 ?# ~% s% s9 Q1 p6 ^
1 x- j1 \- u: z' ~ y' @3 g # annotation file1 s7 o) q2 b' h2 F
annot_filename = img_name[:-4] + '.xml'9 U: S: X# G5 ?& r) Q* ^* i
annot_file_path = os.path.join(self.xml_dir, annot_filename); k0 G3 e. r0 ^" h( q3 L
. i( h5 F, ^! N8 d, T; M
/ E! P3 S. h( F0 H/ [ L
boxes = []# i- S# q2 ` G* l3 P% x' @1 _2 M
labels = [] $ C! V5 d$ d# d tree = et.parse(annot_file_path)+ A' t/ ~1 n- {* `" `$ h
root = tree.getroot() ]- E7 X1 X9 M9 i9 w+ ^' e4 @. |2 y' e" ^1 V# R
6 ~. N, x6 \7 A7 |: Z6 |; g
# cv2 image gives size as height x width ( f6 M: E+ J- h$ y/ L wt = img.shape[1] , ?- } t8 B3 m* P5 @7 g% r, k ht = img.shape[0] 1 d4 q1 J; p3 Z* l 2 p& c, P' ?1 P4 k0 c7 } 5 g- @# w# F8 r; V # box coordinates for xml files are extracted and corrected for image size given8 }6 k; f# g$ v% J+ J* |) E* s! w
for member in root.findall('object'): ! l6 ~! J( G" i8 m labels.append(self.classes.index(member.find('name').text)) . W! }8 a+ ?% w9 V( ^# Z# G2 m/ B; y8 y& r5 r3 I/ k g& S
* u2 b y( f# }
# bounding box - U# x3 }3 {$ T) F% G/ y xmin = int(member.find('bndbox').find('xmin').text)2 G$ D8 t9 {& @& P$ F% `* l6 B
xmax = int(member.find('bndbox').find('xmax').text) . V% f( U M9 ~/ j, M 4 f9 z4 O: F G2 s- ]1 H5 M( y6 G$ h; E4 T8 w
ymin = int(member.find('bndbox').find('ymin').text) ! m0 ~7 p' d$ T- y2 \; G9 P; B ymax = int(member.find('bndbox').find('ymax').text) $ X# E4 t7 i& x$ e( ^2 B- S6 ~0 I X6 ?8 z; H8 P7 |. k
* ^1 T e) O4 a: F. w H
xmin_corr = (xmin / wt) * self.width ' S4 N8 i% B* }& k C# }4 f- X$ [ xmax_corr = (xmax / wt) * self.width9 U( y7 `6 K) l$ E9 M: y
ymin_corr = (ymin / ht) * self.height. w! |$ a5 H- N( r( t
ymax_corr = (ymax / ht) * self.height , G+ i/ Y% B2 v7 { B boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])# C5 V2 A8 y7 u9 f) b; k0 Q
; ]- J4 m& ]. `1 v* Q: ~/ Y
$ A: [8 X& M) @* G
# convert boxes into a torch.Tensor3 u7 o. V: L) W/ O
boxes = torch.as_tensor(boxes, dtype=torch.float32)2 b. [$ n, }( a$ A' d6 b* Q. C# }
v* @& o. x) {+ w( w+ [
% T- X/ X& Q. K7 h" D3 W/ } # getting the areas of the boxes : j/ I! K' v4 s2 }; Q area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0]) ; W' G6 \4 W6 m0 q& `7 k9 t, {) }) w4 O- v! v" \: n
4 V8 p: ^9 f) O% I; M4 T/ n # suppose all instances are not crowd 6 | b' p$ K3 c( _ iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64) 5 K- a9 }: E5 @5 ^ 1 _" F' x/ H0 h5 b! }9 M% H2 B* Y' S$ k0 ^' \, ^8 k
labels = torch.as_tensor(labels, dtype=torch.int64) ( {6 [7 Y7 b C! N) M6 P9 D. m/ X( \0 a0 V8 W+ W
# u4 G& a0 P" O7 |* D' z target = {}" Y" m2 D8 F/ \: e7 ~. v1 M
target["boxes"] = boxes- N" N* Q* z" q5 ^! T4 N& {
target["labels"] = labels / O7 C4 g2 [1 j- i' d2 I target["area"] = area k* k5 `( ]+ [# @& G
target["iscrowd"] = iscrowd [. ?0 {5 H4 i' w! u! x # image_id% D) ]" y! z! G, n' \
image_id = torch.tensor([idx]) . L( d- h% I: [5 g target["image_id"] = image_id 9 Z7 D% t( c, f) D$ U 4 F$ @9 \) i& f# A% D9 L2 ^ i! F& ]" K$ p
if self.transforms:( _: w1 Q$ b$ R6 M
sample = self.transforms(image=img_res, ], P5 h* ]7 L2 @5 z* k! \( M
bboxes=target['boxes'],: R0 p8 ]2 x; E- h
labels=labels) ' l/ a" b& g( E, ~% r + \% ]6 ?9 R7 W# w, B! m, {0 R# f3 v
img_res = sample['image'] 5 F0 d: k5 ?7 V/ ~ target['boxes'] = torch.Tensor(sample['bboxes']) ' C- x# _' W1 t! I2 g4 j; k+ \0 ] 2 `- w; ~- ~$ _) Y$ O5 W& h) y% P
return img_res, target/ J5 n- }% t6 h
+ B! B7 N: D' G' I6 q$ g
( K. h/ g# c: a% D" [" e$ T' ]9 a
def __len__(self): , ]* V/ e( t3 V$ Y return len(self.imgs); V$ n" O; M7 V
" H8 \% K6 |% ~+ j5 E. x$ l5 M2 u
# function to convert a torchtensor back to PIL image# ^$ j/ W3 a( y. d
def torch_to_pil(img): # X) |5 j1 d; y: O) c* ^, m, @ return torchtrans.ToPILImage()(img).convert('RGB') , p: {9 e6 C( N- s) L , y i9 ~7 F5 t! g. C6 M. J4 c ) `3 E! M% n3 M5 {0 _, b/ W2 ?+ g* s' K* U) k3 H: D
) ?& n- Z/ o) |/ p7 }def plot_img_bbox(img, target):7 g( X% V2 I1 v! r D
# plot the image and bboxes 6 `" E9 N4 g% t8 l$ M2 s+ h% c" t fig, a = plt.subplots(1, 1) % b! g6 t* c( o- A, a9 J fig.set_size_inches(5, 5) 0 o0 r& R( X' d a.imshow(img)6 }% q! Z9 B2 n) \% u
for box in (target['boxes']):, s# i* V% Y$ U+ E* X) ^* p
x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]3 Q) h) T/ n3 b7 B3 n* X& a
rect = patches.Rectangle((x, y), L5 T# \8 i5 w9 ~* n* c
width, height,7 y; u/ u1 p+ G0 O5 N1 d% L; v# k
linewidth=2,8 D/ {2 u0 n& A5 P! j/ w# @
edgecolor='r', 0 |2 c2 g+ P% j- k6 o q1 ` facecolor='none') `: J2 T: {6 A. C' K# `5 F # u4 b$ s7 S% w2 W {( ]+ j 3 L6 `6 O7 a" S$ g5 E- y( A3 e # Draw the bounding box on top of the image 1 J% M8 j8 s' A a.add_patch(rect) - ?+ B" d5 N0 x" u9 x- W, y) g! e plt.show() 4 K( N k% U; ^" _ 7 p) U% H2 M, I / j2 i& ]2 P1 { k0 L6 I; a" o" ^( K+ |: q/ u
( N& h9 {4 g( t* I5 l% B( x$ [ U
def get_transform(train): ' y y$ u( K+ ^ if train:6 f+ h9 Q0 w _& A6 s- s
return A.Compose([ - Q8 Q! V' D( K$ B P A.HorizontalFlip(0.5), ) A- o3 t( v9 T9 m. Q+ S # ToTensorV2 converts image to pytorch tensor without div by 255. l+ R. k; j7 T6 n8 [. v2 t
ToTensorV2(p=1.0) C! @+ r5 {2 M5 Q9 {% q; {5 E ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']}) . C9 B" f4 [- p else:' B6 g ?6 s2 r6 f3 n
return A.Compose([ / O) B7 N4 _6 u/ ?3 f! Y. K* c3 P8 K ToTensorV2(p=1.0)" G' _$ h2 C- y
], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']}) - I6 Z; F+ B9 ~" l, v5 @8 x. `9 P) d+ I
0 k! F2 k) W; y' B! s. i ; H7 @ x# e$ g7 U1 G0 K9 U5 `: j0 O4 o- [; O
, t2 `: }6 u. R* |- a q+ p3 k) G, ]% p8 x. E; a
dataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True)) ( {1 M/ V$ Y3 l# F0 m% ^& X- j0 z" f4 e% W3 c
% F- h1 H9 [2 ~( A- T* N4 B
print(len(dataset)) - @. ?. E, z! `, ?1 j6 N# j# getting the image and target for a test index. Feel free to change the index. 3 R+ N; C8 n6 g9 N3 D" b5 ]- wimg, target = dataset[29]0 D8 q8 ?8 W3 l; W
print(img.shape, '\n', target) 3 F% ^ B* K: t5 Oplot_img_bbox(torch_to_pil(img), target) D! p9 U- a, {; ~4 K$ l1 ; r) A- N$ J4 w7 w( ~% a) m7 J2 " w1 G! k. d- J/ J1 [3: r R- d. @8 i5 W5 E& V
4 & t8 Q. A) R! G1 R! C5 ( C. c- d O# t2 q" B6 , F! f8 Z8 f5 s8 E9 a0 Q9 v7 3 h1 }; `1 n" l5 |8* r( j6 a5 K' U' v0 |% z% Q
91 S! V9 o: o, |
10/ e0 a5 {. e2 b; t! k5 s4 X
11' \/ N8 D- ], ^( C7 }
125 m& ~7 ^9 g8 I& j* W
136 x6 p7 u9 e, w) ~" H! x
14 C6 \7 P7 w' b, v' l _# p) P5 A7 p15$ O8 x1 w: Q5 E; m3 R* U# d8 k
16' R' ~4 }1 b$ Y9 N$ q7 J, n1 h
17 $ k, E/ Z- [) D9 f8 m6 N& a18 4 g7 t% F2 o: p19+ K3 F6 v7 i! ^6 s" C, c
20( \0 Y1 c2 c5 E$ J( q
21- g. B2 ^! ]; d6 N! S4 e6 k7 {
229 l3 F3 X; \# A2 ?/ ]# N. C- U$ c
23# R. @( y5 P9 [! }% G. Q
24 ! G" w" k' r9 z1 e5 Y2 ]25 ( o% @$ E/ G2 G8 |" _/ Q- O' J" C266 l& |0 I4 O. o4 b
27 6 s9 y0 J/ ^$ h, [7 I! s% S28 9 [' n' S; g# R& e+ j29# q" G+ }$ l( g! m4 K, {* k
307 ^# t' t& f* ^- G% J2 d9 r9 I$ t1 E
31 k8 T, x) P" I0 y+ S' L" B5 i0 Q, ?322 a$ j9 ]3 |' G4 n4 t
33, \( K1 ^. V& P* }0 U
34 # q' G, @- h) G35 9 t. f% |+ F% e" U) P) E36, o. _+ s* Q, U* Q0 z! N$ l
37 + X* Q4 p. Z) C38 ' z, G6 _. B. t L# R39 2 n5 S3 B9 F' e. J9 Y, G/ [7 @40 5 {3 p7 ]( w9 p2 k! F410 _2 B# Y2 M) Q# r0 x/ z3 O
42 9 `$ c* ]' R6 q43; }7 {$ a0 `5 U9 h
44 8 G: T* R7 s4 H9 O" G7 ]; I45" \8 M. p! n# J* V
46 2 N4 [4 P: R+ `. v' }* A9 S47# [9 p0 x: C( e
480 H V6 i/ T# s6 }, `( Y: g
49! e2 G8 N) a5 W( \, r
50 ; u. X# r! p; ], V516 T- I3 ?+ h: S: A+ P! C
52 & O& i! Q1 M, ?; b% P1 t53 8 B& {( l2 {6 L54 & m# R" k: l0 x% w7 P8 A55 % p: L: \8 f9 k5 {56; _" D# J# }, s7 n: R5 W+ ^, A A
57 , ^9 [$ ]$ x. C" B+ o: ? e58 7 V) p0 P: i- R+ m59 : P. }( T' G4 T4 S! f- |60; x, k1 l8 A( @; }
61; u# _4 o6 V7 y) {- P
62 ! z% `" N0 m3 ^7 Q63$ m2 D& x- H& X4 T4 s
643 c( V' R( R) J; y& I
65 3 f' b0 u; [2 \# Z- x9 M8 [66( N7 ?% v: K4 c O( s
677 R% j) Y" F! s9 a, K
68* P2 ?2 J+ m/ J
69) w$ a3 ^3 j% q$ Z
70% n+ ]% i0 o# d1 I! H; R& D8 o5 j
71 / E8 B6 g1 [6 P6 u72# |# J. b5 j) P' |/ b; [/ d: d
73: t. i) ^- W/ k | }
74 ) D! S' K4 f7 ]0 i. O* T2 U' M75 9 d& N. p& B9 G, C9 d762 E! H' ]$ a' h3 H
77 % @4 |% c2 @3 r78& S9 g, _5 A* Q- x3 h6 D4 A$ e
79" j* z0 W) d* T: T. }
80 0 t+ m% D- X% E) e& u4 D81 : Q& `4 d6 O4 C82 & T4 }) D0 n1 E: L8 a83 4 i& _( n$ n. V/ E1 ]84 * f$ b; x0 q( ~" [$ F859 G! B' w4 r2 u5 p& ^$ N
86 X# w4 ^$ C' ~1 q9 x! W
87; Y7 X/ R, i# Q) R# P
88" Z- z; P0 R& y5 K2 R
89 % t; o# R1 C* Q/ e901 j) s# x- W7 p
91 n0 e9 u4 Q" Z4 P% ~. r) v& X
92 6 v9 U( B: q* z& P N5 s$ l& W7 m93+ v7 i! F7 I( v) m
94 ( N" g* s, V5 o# H- W95+ o8 L: ?8 I, L( ?& f' ~
96 ) V6 V% ]8 ~! g2 [% _97 1 k2 o8 s8 N9 x9 P6 |& e2 K98 * \0 q9 G* b$ `* X999 _& }# ^! D8 M% z3 H, x
100 " c$ @7 E: ~' l( I101 + J Y! n; E9 H9 ?% y1023 o! l# |6 p! L5 {. g% R
103' A, K6 }3 r$ i( T
104 . N) b6 S a/ H; m9 f- {1 q105 ! p+ g! b$ A5 {+ j106 . B2 F. H; D! }4 Z107( Z! G% ^; C, q. ?5 F6 C9 S6 @
108 5 ?& g: @5 s6 K8 K3 Z3 H109 / Q3 ]' |$ [- U8 P# t0 i110) k3 ]7 I: i: D0 Q
111 " S v; p; M/ D* A+ y112 ( E7 j6 _- |3 l# ]+ d9 {1 V! ~6 ~113 2 L+ y/ T: ?$ f1 m114. O. K8 {4 p6 m; l( P1 p% R
115 . ~! x/ }2 f G+ S0 ? {1165 c( a0 W* [4 x+ }
117 9 x! n# J9 j( s, A" m1 T( P118 7 G3 O8 s t3 u9 V4 ]119 B0 v6 m' H5 A+ E
120! i- O+ `& R. r% ^
1219 x" T+ I _# g
122 ) D6 j" G1 g7 Z5 P. ^123+ ^3 w n f# |' I& _, ~
1241 v* t; ~6 F- s5 e& {" \
1254 X$ o* r+ k4 H3 H8 M) C S- a+ g
126 / R4 B4 V( t5 e( M* r127$ ?4 B j2 S _4 Z
128 . J6 X5 w4 q9 I1291 b5 l$ k; A4 f# d7 o" m8 Z
130( R' K! c- ~* l w; i' A0 A
131 1 f# i3 ?& l. J1 u% X+ M& ^132 + a% U7 ?! j$ d' k3 R: R133 / U8 H2 M$ A/ f6 b( q1 q! y X134 1 W) G) Z0 Z3 c* K$ |# o& Y' h* O135 ! Y9 r) i. D' r" G0 ?136; h: q! D! r# g% j4 J
137 . k1 A+ h4 L/ _: L138+ b7 Z, ]# h7 K6 W7 x A
139 1 v; U9 X6 |$ z140, f6 l, B2 M$ V% @- X! y8 F2 Q
141* ?9 d, T6 ]9 S
142 ( |1 ?6 ~2 b* A- ~1435 O ?. t5 y1 r8 b( o0 V4 w/ j+ p
144* o1 s7 o. i5 J6 N" A
145: B2 o& N, x0 m) k( O6 a1 p
146 ; ?( M) p' A+ t z+ E; [147 0 g% \6 B# J& q% K: i. p% w) H148 1 t+ i% O& i4 s7 C$ c/ G7 d149 ' z/ w$ q- S4 a5 |# K0 U- a8 U150' c3 Q, e* Q8 e8 P" o8 @7 e' p
151: Q" Y8 s& O1 t; B9 N$ \
152 Z( [3 r* m; _# y. c
153 ; s; r, T* o1 \# O$ ~154 " K, r2 e/ Z% X3 G# l155 8 U i' n) Q3 Y156 6 v$ b2 t5 `# H _& p! }) T2 x输出如下:: t+ i; i4 [; Z, f