From a18330c84691dfcc028b9b505df31cdefedce9d5 Mon Sep 17 00:00:00 2001 From: Zilian <13718722639leo@gmail.com> Date: Wed, 27 Oct 2021 14:56:58 +0200 Subject: [PATCH] Upload --- README.md | 14 + cfg/yolov3-vattenhallen-test.cfg | 785 ++++++++++++++++++ cfg/yolov3-vattenhallen.cfg | 785 ++++++++++++++++++ cfg/yolov3-veges-test.cfg | 785 ++++++++++++++++++ cfg/yolov3-veges.cfg | 785 ++++++++++++++++++ data/vattenhallen.data | 6 + data/veges.data | 6 + ..._20210929_16_08_31_Pro.jpg:Zone.Identifier | 3 + ..._20210929_16_14_16_Pro.jpg:Zone.Identifier | 3 + dataset/classes.txt | 7 + dataset/test.list | 80 ++ dataset/test.txt | 21 + dataset/train.list | 317 +++++++ dataset/train.txt | 212 +++++ src/cal_location.py | 110 +++ src/client.py | 137 +++ src/darknet.py | 340 ++++++++ src/darknet_images.py | 236 ++++++ src/detect.py | 116 +++ src/load_cam.py | 11 + src/move.py | 182 ++++ static/a.mat | Bin 0 -> 179 bytes static/camera.mat | Bin 0 -> 22584 bytes static/camera_no_distortion.mat | Bin 0 -> 11116 bytes static/distance.txt | 6 + test.md | 9 + weights/yolov3-vattenhallen_best.weights | 3 + weights/yolov3-veges_best.weights | 3 + 28 files changed, 4962 insertions(+) create mode 100644 README.md create mode 100644 cfg/yolov3-vattenhallen-test.cfg create mode 100644 cfg/yolov3-vattenhallen.cfg create mode 100644 cfg/yolov3-veges-test.cfg create mode 100644 cfg/yolov3-veges.cfg create mode 100644 data/vattenhallen.data create mode 100644 data/veges.data create mode 100644 dataset/WIN_20210929_16_08_31_Pro.jpg:Zone.Identifier create mode 100644 dataset/WIN_20210929_16_14_16_Pro.jpg:Zone.Identifier create mode 100644 dataset/classes.txt create mode 100644 dataset/test.list create mode 100644 dataset/test.txt create mode 100644 dataset/train.list create mode 100644 dataset/train.txt create mode 100644 src/cal_location.py create mode 100644 src/client.py create mode 100644 src/darknet.py create mode 100644 src/darknet_images.py create mode 100644 src/detect.py create mode 100644 src/load_cam.py create mode 100644 src/move.py create mode 100644 static/a.mat create mode 100644 static/camera.mat create mode 100644 static/camera_no_distortion.mat create mode 100644 static/distance.txt create mode 100644 test.md create mode 100644 weights/yolov3-vattenhallen_best.weights create mode 100644 weights/yolov3-veges_best.weights diff --git a/README.md b/README.md new file mode 100644 index 0000000..0b4e703 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# camera calbration的结果必须转换为struct才能存 + +# 必须通过合适的编译,得到/libdarknet.so 才能用python调用 + + +To test darknet_images.py +``` +python ./*darknet_images.py --input ~/farmbot/img --weights ~/farmbot/weights/yolov3-vattenhallen_best.weights --dont_show --ext_output --save_labels --config_file ~/farmbot/cfg/yolov3-vattenhallen-test.cfg --data_file ~/farmbot/data/vattenhallen.data +``` +Default values are used for the rest. + +save label去了哪里? 存到了和img同一个路径下 同名.txt文件,所以可以给一folder的图片同时检测 + +最好修改一下save label的地址,单独放一个folder \ No newline at end of file diff --git a/cfg/yolov3-vattenhallen-test.cfg b/cfg/yolov3-vattenhallen-test.cfg new file mode 100644 index 0000000..f8befdc --- /dev/null +++ b/cfg/yolov3-vattenhallen-test.cfg @@ -0,0 +1,785 @@ +[net] +# Testing +batch=1 +subdivisions=1 +# Training +# batch=64 +# subdivisions=32 +width=416 +height=416 +channels=3 +momentum=0.9 +decay=0.0005 +angle=0 +saturation = 1.5 +exposure = 1.5 +hue=.1 + +learning_rate=0.001 +burn_in=1000 +max_batches = 14000 +policy=steps +steps=11200,12600 +scales=.1,.1 + + + +[convolutional] +batch_normalize=1 +filters=32 +size=3 +stride=1 +pad=1 +activation=leaky + +# Downsample + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=32 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +###################### + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=36 +activation=linear + +[yolo] +mask = 6,7,8 +anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 +classes=7 +num=9 +jitter=.3 +ignore_thresh = .5 +truth_thresh = 1 +random=1 + +[route] +layers = -4 + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = -1, 61 + + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=36 +activation=linear + +[yolo] +mask = 3,4,5 +anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 +classes=7 +num=9 +jitter=.3 +ignore_thresh = .5 +truth_thresh = 1 +random=1 + +[route] +layers = -4 + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = -1, 36 + + + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=36 +activation=linear + +[yolo] +mask = 0,1,2 +anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 +classes=7 +num=9 +jitter=.3 +ignore_thresh = .5 +truth_thresh = 1 +random=1 + diff --git a/cfg/yolov3-vattenhallen.cfg b/cfg/yolov3-vattenhallen.cfg new file mode 100644 index 0000000..2847929 --- /dev/null +++ b/cfg/yolov3-vattenhallen.cfg @@ -0,0 +1,785 @@ +[net] +# Testing +# batch=1 +# subdivisions=1 +# Training +batch=64 +subdivisions=32 +width=416 +height=416 +channels=3 +momentum=0.9 +decay=0.0005 +angle=0 +saturation = 1.5 +exposure = 1.5 +hue=.1 + +learning_rate=0.001 +burn_in=1000 +max_batches = 14000 +policy=steps +steps=11200,12600 +scales=.1,.1 + + + +[convolutional] +batch_normalize=1 +filters=32 +size=3 +stride=1 +pad=1 +activation=leaky + +# Downsample + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=32 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +###################### + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=36 +activation=linear + +[yolo] +mask = 6,7,8 +anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 +classes=7 +num=9 +jitter=.3 +ignore_thresh = .5 +truth_thresh = 1 +random=1 + +[route] +layers = -4 + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = -1, 61 + + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=36 +activation=linear + +[yolo] +mask = 3,4,5 +anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 +classes=7 +num=9 +jitter=.3 +ignore_thresh = .5 +truth_thresh = 1 +random=1 + +[route] +layers = -4 + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = -1, 36 + + + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=36 +activation=linear + +[yolo] +mask = 0,1,2 +anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 +classes=7 +num=9 +jitter=.3 +ignore_thresh = .5 +truth_thresh = 1 +random=1 + diff --git a/cfg/yolov3-veges-test.cfg b/cfg/yolov3-veges-test.cfg new file mode 100644 index 0000000..241b960 --- /dev/null +++ b/cfg/yolov3-veges-test.cfg @@ -0,0 +1,785 @@ +[net] +# Testing + batch=1 + subdivisions=1 +# Training +# batch=64 +# subdivisions=32 +width=416 +height=416 +channels=3 +momentum=0.9 +decay=0.0005 +angle=0 +saturation = 1.5 +exposure = 1.5 +hue=.1 + +learning_rate=0.001 +burn_in=1000 +max_batches = 20000 +policy=steps +steps=16000,18000 +scales=.1,.1 + + + +[convolutional] +batch_normalize=1 +filters=32 +size=3 +stride=1 +pad=1 +activation=leaky + +# Downsample + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=32 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +###################### + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=45 +activation=linear + +[yolo] +mask = 6,7,8 +anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 +classes=10 +num=9 +jitter=.3 +ignore_thresh = .5 +truth_thresh = 1 +random=1 + +[route] +layers = -4 + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = -1, 61 + + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=45 +activation=linear + +[yolo] +mask = 3,4,5 +anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 +classes=10 +num=9 +jitter=.3 +ignore_thresh = .5 +truth_thresh = 1 +random=1 + +[route] +layers = -4 + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = -1, 36 + + + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=45 +activation=linear + +[yolo] +mask = 0,1,2 +anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 +classes=10 +num=9 +jitter=.3 +ignore_thresh = .5 +truth_thresh = 1 +random=1 + diff --git a/cfg/yolov3-veges.cfg b/cfg/yolov3-veges.cfg new file mode 100644 index 0000000..393efb6 --- /dev/null +++ b/cfg/yolov3-veges.cfg @@ -0,0 +1,785 @@ +[net] +# Testing +# batch=1 +# subdivisions=1 +# Training +batch=64 +subdivisions=32 +width=416 +height=416 +channels=3 +momentum=0.9 +decay=0.0005 +angle=0 +saturation = 1.5 +exposure = 1.5 +hue=.1 + +learning_rate=0.001 +burn_in=1000 +max_batches = 20000 +policy=steps +steps=16000,18000 +scales=.1,.1 + + + +[convolutional] +batch_normalize=1 +filters=32 +size=3 +stride=1 +pad=1 +activation=leaky + +# Downsample + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=32 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +###################### + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=45 +activation=linear + +[yolo] +mask = 6,7,8 +anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 +classes=10 +num=9 +jitter=.3 +ignore_thresh = .5 +truth_thresh = 1 +random=1 + +[route] +layers = -4 + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = -1, 61 + + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=45 +activation=linear + +[yolo] +mask = 3,4,5 +anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 +classes=10 +num=9 +jitter=.3 +ignore_thresh = .5 +truth_thresh = 1 +random=1 + +[route] +layers = -4 + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = -1, 36 + + + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=45 +activation=linear + +[yolo] +mask = 0,1,2 +anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 +classes=10 +num=9 +jitter=.3 +ignore_thresh = .5 +truth_thresh = 1 +random=1 + diff --git a/data/vattenhallen.data b/data/vattenhallen.data new file mode 100644 index 0000000..f6812d7 --- /dev/null +++ b/data/vattenhallen.data @@ -0,0 +1,6 @@ +classes= 7 +train = ../dataset/train.list +valid = ../dataset/test.list +names = /home/xzleo/farmbot/dataset/classes.txt +backup = backup + diff --git a/data/veges.data b/data/veges.data new file mode 100644 index 0000000..174c19a --- /dev/null +++ b/data/veges.data @@ -0,0 +1,6 @@ +classes= 10 +train = /home/xzleo/farmbot/dataset/train.txt +valid = /home/xzleo/farmbot/dataset/test.txt +names = /home/xzleo/farmbot/dataset/classes.txt +backup = backup + diff --git a/dataset/WIN_20210929_16_08_31_Pro.jpg:Zone.Identifier b/dataset/WIN_20210929_16_08_31_Pro.jpg:Zone.Identifier new file mode 100644 index 0000000..744d15f --- /dev/null +++ b/dataset/WIN_20210929_16_08_31_Pro.jpg:Zone.Identifier @@ -0,0 +1,3 @@ +[ZoneTransfer] +LastWriterPackageFamilyName=Microsoft.WindowsCamera_8wekyb3d8bbwe +ZoneId=3 diff --git a/dataset/WIN_20210929_16_14_16_Pro.jpg:Zone.Identifier b/dataset/WIN_20210929_16_14_16_Pro.jpg:Zone.Identifier new file mode 100644 index 0000000..744d15f --- /dev/null +++ b/dataset/WIN_20210929_16_14_16_Pro.jpg:Zone.Identifier @@ -0,0 +1,3 @@ +[ZoneTransfer] +LastWriterPackageFamilyName=Microsoft.WindowsCamera_8wekyb3d8bbwe +ZoneId=3 diff --git a/dataset/classes.txt b/dataset/classes.txt new file mode 100644 index 0000000..1a6be54 --- /dev/null +++ b/dataset/classes.txt @@ -0,0 +1,7 @@ +tomato +mushroom +potato +carrot +beetroot +zucchini +hand diff --git a/dataset/test.list b/dataset/test.list new file mode 100644 index 0000000..5dbdcbf --- /dev/null +++ b/dataset/test.list @@ -0,0 +1,80 @@ +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_15_22_15_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_39_45_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_41_35_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_40_45_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_15_44_41_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_27_25_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_18_05_45_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_18_02_43_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_18_08_27_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_22_25_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_17_58_31_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_17_55_27_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_17_54_31_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_15_22_25_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_06_35_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_20_15_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_15_41_55_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_18_04_25_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_15_23_10_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_41_27_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_05_55_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_18_00_55_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_09_43_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_19_43_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_22_43_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_28_43_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_06_31_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_05_41_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_30_31_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_07_25_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_29_45_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_20_43_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_05_35_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_40_54_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_39_25_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_15_21_10_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_40_27_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_40_41_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_29_10_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_18_07_37_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_17_59_55_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_15_42_45_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_15_16_35_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_24_15_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_15_24_37_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_15_43_45_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_18_05_41_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_15_41_27_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_15_41_15_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_18_08_35_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_08_43_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_18_07_27_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_40_37_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_18_04_35_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_07_15_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_17_58_43_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_08_27_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_17_54_54_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_15_17_10_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_29_55_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_39_55_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_42_25_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_15_43_15_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_30_15_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_39_31_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_23_35_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_23_10_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_15_19_37_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_18_04_31_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_41_10_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_15_24_10_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_39_35_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_18_05_37_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_18_06_45_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_20_55_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_16_06_27_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_15_22_37_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_17_54_45_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_18_01_55_Pro.jpg +/export/work/ziliang/vattenhallen/test/PNGimages/WIN_20210807_17_58_27_Pro.jpg diff --git a/dataset/test.txt b/dataset/test.txt new file mode 100644 index 0000000..c838331 --- /dev/null +++ b/dataset/test.txt @@ -0,0 +1,21 @@ +/export/work/ziliang/veges/test/PNGimages/100_d.png +/export/work/ziliang/veges/test/PNGimages/10_a.png +/export/work/ziliang/veges/test/PNGimages/120_e.png +/export/work/ziliang/veges/test/PNGimages/131_e.png +/export/work/ziliang/veges/test/PNGimages/140_f.png +/export/work/ziliang/veges/test/PNGimages/155_f.png +/export/work/ziliang/veges/test/PNGimages/160_g.png +/export/work/ziliang/veges/test/PNGimages/172_g.png +/export/work/ziliang/veges/test/PNGimages/185_h.png +/export/work/ziliang/veges/test/PNGimages/206_h.png +/export/work/ziliang/veges/test/PNGimages/222_i.png +/export/work/ziliang/veges/test/PNGimages/231_i.png +/export/work/ziliang/veges/test/PNGimages/242_j.png +/export/work/ziliang/veges/test/PNGimages/250_j.png +/export/work/ziliang/veges/test/PNGimages/25_b.png +/export/work/ziliang/veges/test/PNGimages/261_j.png +/export/work/ziliang/veges/test/PNGimages/42_b.png +/export/work/ziliang/veges/test/PNGimages/4_a.png +/export/work/ziliang/veges/test/PNGimages/53_c.png +/export/work/ziliang/veges/test/PNGimages/65_c.png +/export/work/ziliang/veges/test/PNGimages/79_d.png diff --git a/dataset/train.list b/dataset/train.list new file mode 100644 index 0000000..c80870a --- /dev/null +++ b/dataset/train.list @@ -0,0 +1,317 @@ +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_41_52_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_25_59_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_43_53_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_22_14_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_41_12_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_20_38_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_30_24_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_44_32_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_55_13_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_01_19_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_08_06_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_09_52_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_08_09_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_41_08_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_58_22_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_22_21_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_21_12_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_57_02_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_08_59_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_02_17_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_24_28_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_05_24_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_08_36_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_56_11_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_09_48_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_39_42_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_56_03_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_23_16_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_09_39_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_20_22_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_23_53_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_40_56_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_56_32_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_40_16_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_41_05_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_05_19_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_16_29_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_27_02_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_05_59_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_27_22_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_55_22_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_40_07_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_57_06_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_05_01_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_22_50_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_07_59_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_27_58_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_09_13_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_22_20_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_19_51_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_23_48_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_06_23_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_25_06_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_40_29_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_27_21_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_39_49_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_09_17_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_04_12_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_08_39_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_07_04_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_04_03_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_26_16_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_28_23_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_07_58_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_22_01_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_42_36_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_30_05_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_55_17_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_42_48_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_39_52_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_40_04_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_54_49_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_27_13_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_00_22_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_40_11_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_05_19_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_24_08_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_29_52_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_41_18_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_40_56_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_42_14_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_44_48_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_41_01_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_46_07_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_59_09_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_27_42_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_41_44_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_00_29_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_43_09_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_42_07_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_08_24_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_44_44_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_21_30_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_45_58_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_00_49_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_40_36_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_29_26_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_58_17_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_25_56_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_06_02_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_39_12_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_07_04_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_53_59_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_29_04_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_21_01_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_45_50_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_43_01_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_41_12_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_10_01_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_29_17_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_08_50_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_22_46_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_30_20_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_07_33_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_29_07_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_43_18_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_04_57_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_19_57_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_26_46_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_25_34_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_23_13_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_44_51_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_56_36_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_28_32_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_27_51_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_28_57_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_29_49_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_09_56_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_21_07_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_20_26_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_18_48_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_24_52_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_44_23_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_39_58_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_55_11_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_57_24_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_07_52_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_23_53_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_15_58_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_09_06_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_40_46_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_39_38_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_42_17_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_07_39_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_22_30_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_00_18_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_40_48_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_26_05_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_39_16_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_59_20_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_05_52_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_06_44_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_19_48_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_26_01_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_07_44_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_24_42_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_16_59_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_57_52_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_02_39_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_41_29_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_27_17_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_57_12_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_41_59_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_42_33_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_20_53_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_28_39_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_08_03_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_27_29_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_02_59_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_39_28_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_42_39_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_53_39_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_42_05_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_07_13_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_23_58_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_42_21_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_42_04_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_01_40_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_22_18_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_23_26_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_07_07_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_41_56_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_46_14_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_58_58_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_28_52_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_23_07_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_16_50_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_56_20_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_19_44_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_07_28_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_23_23_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_41_53_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_24_18_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_27_34_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_40_22_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_28_36_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_26_29_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_28_13_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_57_16_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_29_02_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_41_50_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_24_03_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_05_44_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_23_33_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_40_12_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_58_00_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_29_22_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_26_11_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_27_47_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_56_59_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_22_48_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_06_57_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_43_06_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_06_11_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_42_19_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_41_07_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_24_38_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_54_59_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_24_11_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_09_26_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_26_19_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_42_42_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_03_51_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_26_08_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_05_29_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_40_21_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_40_24_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_56_29_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_54_06_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_29_57_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_03_59_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_24_06_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_22_32_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_28_29_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_30_02_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_08_33_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_23_38_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_22_57_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_40_34_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_22_42_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_23_02_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_29_13_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_28_20_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_55_33_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_08_08_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_21_19_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_54_40_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_41_16_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_26_22_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_07_48_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_20_49_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_26_50_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_08_18_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_39_38_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_25_49_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_09_22_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_42_53_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_05_48_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_22_39_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_57_39_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_00_33_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_55_05_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_07_08_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_40_01_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_41_47_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_24_21_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_43_13_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_39_22_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_27_09_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_02_28_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_28_04_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_53_52_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_41_59_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_08_12_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_41_23_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_42_12_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_00_46_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_22_09_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_08_56_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_06_16_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_23_01_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_57_30_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_28_08_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_57_47_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_28_17_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_55_56_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_43_57_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_05_11_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_28_47_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_42_29_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_08_30_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_02_48_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_08_53_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_17_55_08_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_05_39_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_23_44_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_21_03_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_40_01_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_23_19_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_28_50_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_06_19_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_06_06_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_40_30_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_22_56_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_42_57_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_28_26_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_01_50_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_18_05_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_26_58_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_09_09_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_22_52_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_22_08_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_26_24_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_26_12_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_18_05_23_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_16_42_02_Pro.jpg +/export/work/ziliang/vattenhallen/train/PNGimages/WIN_20210807_15_45_47_Pro.jpg diff --git a/dataset/train.txt b/dataset/train.txt new file mode 100644 index 0000000..c7df570 --- /dev/null +++ b/dataset/train.txt @@ -0,0 +1,212 @@ +/export/work/ziliang/veges/train/PNGimages/0_a.png +/export/work/ziliang/veges/train/PNGimages/101_d.png +/export/work/ziliang/veges/train/PNGimages/102_d.png +/export/work/ziliang/veges/train/PNGimages/104_e.png +/export/work/ziliang/veges/train/PNGimages/105_e.png +/export/work/ziliang/veges/train/PNGimages/106_e.png +/export/work/ziliang/veges/train/PNGimages/107_e.png +/export/work/ziliang/veges/train/PNGimages/108_e.png +/export/work/ziliang/veges/train/PNGimages/109_e.png +/export/work/ziliang/veges/train/PNGimages/110_e.png +/export/work/ziliang/veges/train/PNGimages/111_e.png +/export/work/ziliang/veges/train/PNGimages/112_e.png +/export/work/ziliang/veges/train/PNGimages/113_e.png +/export/work/ziliang/veges/train/PNGimages/114_e.png +/export/work/ziliang/veges/train/PNGimages/115_e.png +/export/work/ziliang/veges/train/PNGimages/116_e.png +/export/work/ziliang/veges/train/PNGimages/117_e.png +/export/work/ziliang/veges/train/PNGimages/118_e.png +/export/work/ziliang/veges/train/PNGimages/119_e.png +/export/work/ziliang/veges/train/PNGimages/11_a.png +/export/work/ziliang/veges/train/PNGimages/121_e.png +/export/work/ziliang/veges/train/PNGimages/123_e.png +/export/work/ziliang/veges/train/PNGimages/124_e.png +/export/work/ziliang/veges/train/PNGimages/125_e.png +/export/work/ziliang/veges/train/PNGimages/127_e.png +/export/work/ziliang/veges/train/PNGimages/128_e.png +/export/work/ziliang/veges/train/PNGimages/129_e.png +/export/work/ziliang/veges/train/PNGimages/12_a.png +/export/work/ziliang/veges/train/PNGimages/133_f.png +/export/work/ziliang/veges/train/PNGimages/134_f.png +/export/work/ziliang/veges/train/PNGimages/135_f.png +/export/work/ziliang/veges/train/PNGimages/136_f.png +/export/work/ziliang/veges/train/PNGimages/137_f.png +/export/work/ziliang/veges/train/PNGimages/138_f.png +/export/work/ziliang/veges/train/PNGimages/139_f.png +/export/work/ziliang/veges/train/PNGimages/141_f.png +/export/work/ziliang/veges/train/PNGimages/143_f.png +/export/work/ziliang/veges/train/PNGimages/144_f.png +/export/work/ziliang/veges/train/PNGimages/145_f.png +/export/work/ziliang/veges/train/PNGimages/146_f.png +/export/work/ziliang/veges/train/PNGimages/147_f.png +/export/work/ziliang/veges/train/PNGimages/148_f.png +/export/work/ziliang/veges/train/PNGimages/149_f.png +/export/work/ziliang/veges/train/PNGimages/150_f.png +/export/work/ziliang/veges/train/PNGimages/151_f.png +/export/work/ziliang/veges/train/PNGimages/152_f.png +/export/work/ziliang/veges/train/PNGimages/153_f.png +/export/work/ziliang/veges/train/PNGimages/154_f.png +/export/work/ziliang/veges/train/PNGimages/156_f.png +/export/work/ziliang/veges/train/PNGimages/157_f.png +/export/work/ziliang/veges/train/PNGimages/158_g.png +/export/work/ziliang/veges/train/PNGimages/159_g.png +/export/work/ziliang/veges/train/PNGimages/15_a.png +/export/work/ziliang/veges/train/PNGimages/161_g.png +/export/work/ziliang/veges/train/PNGimages/162_g.png +/export/work/ziliang/veges/train/PNGimages/163_g.png +/export/work/ziliang/veges/train/PNGimages/164_g.png +/export/work/ziliang/veges/train/PNGimages/165_g.png +/export/work/ziliang/veges/train/PNGimages/166_g.png +/export/work/ziliang/veges/train/PNGimages/168_g.png +/export/work/ziliang/veges/train/PNGimages/169_g.png +/export/work/ziliang/veges/train/PNGimages/16_a.png +/export/work/ziliang/veges/train/PNGimages/170_g.png +/export/work/ziliang/veges/train/PNGimages/171_g.png +/export/work/ziliang/veges/train/PNGimages/173_g.png +/export/work/ziliang/veges/train/PNGimages/174_g.png +/export/work/ziliang/veges/train/PNGimages/175_g.png +/export/work/ziliang/veges/train/PNGimages/176_g.png +/export/work/ziliang/veges/train/PNGimages/177_g.png +/export/work/ziliang/veges/train/PNGimages/178_g.png +/export/work/ziliang/veges/train/PNGimages/179_g.png +/export/work/ziliang/veges/train/PNGimages/17_a.png +/export/work/ziliang/veges/train/PNGimages/180_g.png +/export/work/ziliang/veges/train/PNGimages/181_g.png +/export/work/ziliang/veges/train/PNGimages/182_h.png +/export/work/ziliang/veges/train/PNGimages/183_h.png +/export/work/ziliang/veges/train/PNGimages/184_h.png +/export/work/ziliang/veges/train/PNGimages/186_h.png +/export/work/ziliang/veges/train/PNGimages/187_h.png +/export/work/ziliang/veges/train/PNGimages/188_h.png +/export/work/ziliang/veges/train/PNGimages/189_h.png +/export/work/ziliang/veges/train/PNGimages/18_a.png +/export/work/ziliang/veges/train/PNGimages/191_h.png +/export/work/ziliang/veges/train/PNGimages/192_h.png +/export/work/ziliang/veges/train/PNGimages/193_h.png +/export/work/ziliang/veges/train/PNGimages/194_h.png +/export/work/ziliang/veges/train/PNGimages/195_h.png +/export/work/ziliang/veges/train/PNGimages/196_h.png +/export/work/ziliang/veges/train/PNGimages/197_h.png +/export/work/ziliang/veges/train/PNGimages/198_h.png +/export/work/ziliang/veges/train/PNGimages/19_a.png +/export/work/ziliang/veges/train/PNGimages/1_a.png +/export/work/ziliang/veges/train/PNGimages/200_h.png +/export/work/ziliang/veges/train/PNGimages/201_h.png +/export/work/ziliang/veges/train/PNGimages/202_h.png +/export/work/ziliang/veges/train/PNGimages/203_h.png +/export/work/ziliang/veges/train/PNGimages/204_h.png +/export/work/ziliang/veges/train/PNGimages/205_h.png +/export/work/ziliang/veges/train/PNGimages/207_h.png +/export/work/ziliang/veges/train/PNGimages/210_i.png +/export/work/ziliang/veges/train/PNGimages/211_i.png +/export/work/ziliang/veges/train/PNGimages/212_i.png +/export/work/ziliang/veges/train/PNGimages/213_i.png +/export/work/ziliang/veges/train/PNGimages/214_i.png +/export/work/ziliang/veges/train/PNGimages/215_i.png +/export/work/ziliang/veges/train/PNGimages/216_i.png +/export/work/ziliang/veges/train/PNGimages/217_i.png +/export/work/ziliang/veges/train/PNGimages/218_i.png +/export/work/ziliang/veges/train/PNGimages/219_i.png +/export/work/ziliang/veges/train/PNGimages/220_i.png +/export/work/ziliang/veges/train/PNGimages/221_i.png +/export/work/ziliang/veges/train/PNGimages/222_i.png +/export/work/ziliang/veges/train/PNGimages/223_i.png +/export/work/ziliang/veges/train/PNGimages/224_i.png +/export/work/ziliang/veges/train/PNGimages/225_i.png +/export/work/ziliang/veges/train/PNGimages/226_i.png +/export/work/ziliang/veges/train/PNGimages/227_i.png +/export/work/ziliang/veges/train/PNGimages/228_i.png +/export/work/ziliang/veges/train/PNGimages/229_i.png +/export/work/ziliang/veges/train/PNGimages/230_i.png +/export/work/ziliang/veges/train/PNGimages/231_i.png +/export/work/ziliang/veges/train/PNGimages/232_i.png +/export/work/ziliang/veges/train/PNGimages/233_i.png +/export/work/ziliang/veges/train/PNGimages/234_j.png +/export/work/ziliang/veges/train/PNGimages/235_j.png +/export/work/ziliang/veges/train/PNGimages/237_j.png +/export/work/ziliang/veges/train/PNGimages/238_j.png +/export/work/ziliang/veges/train/PNGimages/239_j.png +/export/work/ziliang/veges/train/PNGimages/23_b.png +/export/work/ziliang/veges/train/PNGimages/240_j.png +/export/work/ziliang/veges/train/PNGimages/241_j.png +/export/work/ziliang/veges/train/PNGimages/243_j.png +/export/work/ziliang/veges/train/PNGimages/245_j.png +/export/work/ziliang/veges/train/PNGimages/246_j.png +/export/work/ziliang/veges/train/PNGimages/247_j.png +/export/work/ziliang/veges/train/PNGimages/248_j.png +/export/work/ziliang/veges/train/PNGimages/249_j.png +/export/work/ziliang/veges/train/PNGimages/24_b.png +/export/work/ziliang/veges/train/PNGimages/251_j.png +/export/work/ziliang/veges/train/PNGimages/252_j.png +/export/work/ziliang/veges/train/PNGimages/254_j.png +/export/work/ziliang/veges/train/PNGimages/255_j.png +/export/work/ziliang/veges/train/PNGimages/256_j.png +/export/work/ziliang/veges/train/PNGimages/257_j.png +/export/work/ziliang/veges/train/PNGimages/258_j.png +/export/work/ziliang/veges/train/PNGimages/259_j.png +/export/work/ziliang/veges/train/PNGimages/260_j.png +/export/work/ziliang/veges/train/PNGimages/262_j.png +/export/work/ziliang/veges/train/PNGimages/26_b.png +/export/work/ziliang/veges/train/PNGimages/27_b.png +/export/work/ziliang/veges/train/PNGimages/2_a.png +/export/work/ziliang/veges/train/PNGimages/32_b.png +/export/work/ziliang/veges/train/PNGimages/33_b.png +/export/work/ziliang/veges/train/PNGimages/34_b.png +/export/work/ziliang/veges/train/PNGimages/35_b.png +/export/work/ziliang/veges/train/PNGimages/36_b.png +/export/work/ziliang/veges/train/PNGimages/3_a.png +/export/work/ziliang/veges/train/PNGimages/40_b.png +/export/work/ziliang/veges/train/PNGimages/41_b.png +/export/work/ziliang/veges/train/PNGimages/43_b.png +/export/work/ziliang/veges/train/PNGimages/44_b.png +/export/work/ziliang/veges/train/PNGimages/45_b.png +/export/work/ziliang/veges/train/PNGimages/46_b.png +/export/work/ziliang/veges/train/PNGimages/49_c.png +/export/work/ziliang/veges/train/PNGimages/50_c.png +/export/work/ziliang/veges/train/PNGimages/51_c.png +/export/work/ziliang/veges/train/PNGimages/52_c.png +/export/work/ziliang/veges/train/PNGimages/54_c.png +/export/work/ziliang/veges/train/PNGimages/55_c.png +/export/work/ziliang/veges/train/PNGimages/56_c.png +/export/work/ziliang/veges/train/PNGimages/57_c.png +/export/work/ziliang/veges/train/PNGimages/58_c.png +/export/work/ziliang/veges/train/PNGimages/59_c.png +/export/work/ziliang/veges/train/PNGimages/5_a.png +/export/work/ziliang/veges/train/PNGimages/60_c.png +/export/work/ziliang/veges/train/PNGimages/61_c.png +/export/work/ziliang/veges/train/PNGimages/62_c.png +/export/work/ziliang/veges/train/PNGimages/63_c.png +/export/work/ziliang/veges/train/PNGimages/64_c.png +/export/work/ziliang/veges/train/PNGimages/66_c.png +/export/work/ziliang/veges/train/PNGimages/67_c.png +/export/work/ziliang/veges/train/PNGimages/68_c.png +/export/work/ziliang/veges/train/PNGimages/69_c.png +/export/work/ziliang/veges/train/PNGimages/6_a.png +/export/work/ziliang/veges/train/PNGimages/70_c.png +/export/work/ziliang/veges/train/PNGimages/71_c.png +/export/work/ziliang/veges/train/PNGimages/72_c.png +/export/work/ziliang/veges/train/PNGimages/73_c.png +/export/work/ziliang/veges/train/PNGimages/74_c.png +/export/work/ziliang/veges/train/PNGimages/75_c.png +/export/work/ziliang/veges/train/PNGimages/76_d.png +/export/work/ziliang/veges/train/PNGimages/77_d.png +/export/work/ziliang/veges/train/PNGimages/78_d.png +/export/work/ziliang/veges/train/PNGimages/80_d.png +/export/work/ziliang/veges/train/PNGimages/81_d.png +/export/work/ziliang/veges/train/PNGimages/82_d.png +/export/work/ziliang/veges/train/PNGimages/83_d.png +/export/work/ziliang/veges/train/PNGimages/85_d.png +/export/work/ziliang/veges/train/PNGimages/86_d.png +/export/work/ziliang/veges/train/PNGimages/87_d.png +/export/work/ziliang/veges/train/PNGimages/89_d.png +/export/work/ziliang/veges/train/PNGimages/8_a.png +/export/work/ziliang/veges/train/PNGimages/90_d.png +/export/work/ziliang/veges/train/PNGimages/91_d.png +/export/work/ziliang/veges/train/PNGimages/92_d.png +/export/work/ziliang/veges/train/PNGimages/93_d.png +/export/work/ziliang/veges/train/PNGimages/95_d.png +/export/work/ziliang/veges/train/PNGimages/96_d.png +/export/work/ziliang/veges/train/PNGimages/97_d.png +/export/work/ziliang/veges/train/PNGimages/98_d.png +/export/work/ziliang/veges/train/PNGimages/99_d.png +/export/work/ziliang/veges/train/PNGimages/9_a.png diff --git a/src/cal_location.py b/src/cal_location.py new file mode 100644 index 0000000..ec7fcee --- /dev/null +++ b/src/cal_location.py @@ -0,0 +1,110 @@ +# load darknet weights to predict locations +# weights 可以hardcode +# 1. 研究清楚darknet的输出怎么读取! +# 2. 根据相机内餐外参,换算出相机坐标系中目标的位置 +# 3. 根据每张图对应encoder的量,计算全局位置 +from argparse import ArgumentParser, Namespace +from logging import basicConfig, DEBUG, INFO, error, getLogger +from pathlib import Path +from numpy import array, ndarray +from scipy.io import loadmat +from typing import Dict, List, Tuple, Iterable, Optional, Int + + +_CAM_EXTENSIONS = 'mat' + +"""Logger for log file""" +_LOG = getLogger(__name__) + +"""Data type for camera matrix""" +CAM_MATRIX = "" + +"""Constant sweeping height""" +SWEEP_Z = 0 + + +def load_camera(cam_path: Path) -> ndarray(shape=(3, 3)): # 这个type hint应该这么写吗? + ''' + load the mat file that contains camera calibration result, read the intrinsic matrix of the camera + :param cam_path: path of the mat file + :return intrinsic_matrix: K matrix of the camera + ''' + if not cam_path.suffix.lstrip('.') == _CAM_EXTENSIONS: + _LOG.error('{} has an illegal extension'.format(cam_path)) + return None + + try: + data = loadmat(cam_path) + except FileNotFoundError: + _LOG.error(' No such file') + return None + + intrinsic_matrix = data['camera_no_distortion'][0, 0][11] + _LOG.info('Load intrinsic_matrix of the camera {}'.format(intrinsic_matrix)) + return intrinsic_matrix + +# def download_imgs(): +# 由Alex提供的包解决 +# return + +def detect(): + +def read_detect(): + ''' + 也许需要读入一张图的所有目标的box + ''' + +def read_camera_locations()-> Tuple[float, float, float]: + ''' + Read the camera's global positions from a txt file, + every position has a corresponding image + ''' + return (x_camera, y_camera, z_camera) + +def project(pixel_x: Int, pixel_y: Int, cam_matrix: )->Tuple[float, float]: + ''' + Project image coordinate to floor coordinate in the camera coordinate system + ''' + + +def cal_obj_location(inner_matrix) -> Tuple[float, float]: + ''' + Input: camera location + box + Camera_matrix + Output: global location of a box + ''' + x_camera, y_camera, z_camera = read_camera_locations() + + + return + +def paser(): + return + + +if __name__ == 'main': + parser = ArgumentParser() + parser.add_argument( + '-cam', + '--camera_matrix', + type=Path, + default='../static/camera_no_distortion.mat', + help='Path to mat file that contains intrinsic camera matrix K' + ) + parser.add_argument( + '-l', + '--log', + type=Path, + default='../log/location.log', + help='Path to the log file' + ) + + parser.add_argument('-v', '--verbose', action='store_true', help='Verbose mode') + arguments = parser.parse_args() + if arguments.verbose: + basicConfig(filename=arguments.log, level=DEBUG) + else: + basicConfig(filename=arguments.log, level=INFO) + + \ No newline at end of file diff --git a/src/client.py b/src/client.py new file mode 100644 index 0000000..884e96e --- /dev/null +++ b/src/client.py @@ -0,0 +1,137 @@ +import paho.mqtt.client as mqtt +import json +import time +from uuid import uuid4 # 通用唯一标识符 ( Universally Unique Identifier ) +import logging #日志模块 + +# values over max (and under min) will be clipped +MAX_X = 2400 +MAX_Y = 1200 +MIN_Z = -460 # TODO test this one! + +def coord(x, y, z): + return {"kind": "coordinate", "args": {"x": x, "y": y, "z": z}} # 返回json 嵌套对象 + +def move_request(x, y, z): + return {"kind": "rpc_request", # 返回 json对象,对象内含数组 + "args": {"label": ""}, + "body": [{"kind": "move_absolute", + "args": {"location": coord(x, y, z), + "offset": coord(0, 0, 0), + "speed": 100}}]} + +def take_photo_request(): + return {"kind": "rpc_request", + "args": {"label": ""}, #label空着是为了在blocking_request中填上uuid,唯一识别码 + "body": [{"kind": "take_photo", "args": {}}]} + +def clip(v, min_v, max_v): + if v < min_v: return min_v + if v > max_v: return max_v + return v + +class FarmbotClient(object): + + def __init__(self, device_id, token): + + self.device_id = device_id + self.client = mqtt.Client() # 类元素继承了另一个对象 + self.client.username_pw_set(self.device_id, token) #传入 用户名和密码 + self.client.on_connect = self._on_connect #??? + self.client.on_message = self._on_message + + logging.basicConfig(level=logging.DEBUG, + format="%(asctime)s\t%(name)s\t%(levelname)s\t%(message)s", + filename='farmbot_client.log', + filemode='a') + console = logging.StreamHandler() + console.setLevel(logging.INFO) + console.setFormatter(logging.Formatter("%(asctime)s\t%(message)s")) + logging.getLogger('').addHandler(console) + + self.connected = False + self.client.connect("clever-octopus.rmq.cloudamqp.com", 1883, 60) #前面的url要运行按README.md中request_token.py 后面俩是TCP Port, Websocket Port + self.client.loop_start() + # 初始化函数里就会连接到服务器上,所以每次实例化一个新的client时,就已经连上了 + + + def shutdown(self): + self.client.disconnect() + self.client.loop_stop() + + def move(self, x, y, z): + x = clip(x, 0, MAX_X) + y = clip(y, 0, MAX_Y) + z = clip(z, MIN_Z, 0) + status_ok = self._blocking_request(move_request(x, y, z)) # 发请求 + logging.info("MOVE (%s,%s,%s) [%s]", x, y, z, status_ok) #存日志,包括执行了什么“move x y z +返回值 ” + + def take_photo(self): + # TODO: is this enough? it's issue a request for the photo, but is the actual capture async? + status_ok = self._blocking_request(take_photo_request()) + logging.info("TAKE_PHOTO [%s]", status_ok) + + def _blocking_request(self, request, retries_remaining=3): + if retries_remaining==0: + logging.error("< blocking request [%s] OUT OF RETRIES", request) #尝试3次,然后在日志中记录错误 + return False + + self._wait_for_connection() #在哪定义的? + + # assign a new uuid for this attempt + self.pending_uuid = str(uuid4()) + request['args']['label'] = self.pending_uuid #接收move_request函数的json对象 + logging.debug("> blocking request [%s] retries=%d", request, retries_remaining) + + # send request off 发送请求 + self.rpc_status = None + self.client.publish("bot/" + self.device_id + "/from_clients", json.dumps(request)) + + # wait for response + timeout_counter = 600 # ~1min 等待1s + while self.rpc_status is None: #这个self.rpc_status 是应答的flag + time.sleep(0.1) + timeout_counter -= 1 + if timeout_counter == 0: + logging.warn("< blocking request TIMEOUT [%s]", request) #时间到了,无应答 + return self._blocking_request(request, retries_remaining-1) + self.pending_uuid = None + + # if it's ok, we're done! + if self.rpc_status == 'rpc_ok': + logging.debug("< blocking request OK [%s]", request) + return True + + # if it's not ok, wait a bit and retry + if self.rpc_status == 'rpc_error': + logging.warn("< blocking request ERROR [%s]", request) + time.sleep(1) + return self._blocking_request(request, retries_remaining-1) + + # unexpected state (???) + msg = "unexpected rpc_status [%s]" % self.rpc_status + logging.error(msg) + raise Exception(msg) + + + def _wait_for_connection(self): + # TODO: better way to do all this async event driven rather than with polling :/ + timeout_counter = 600 # ~1min + while not self.connected: #用一个self.connected判断连上了没有,若没连上,等待 + time.sleep(0.1) + timeout_counter -= 1 + if timeout_counter == 0: + raise Exception("unable to connect") + + def _on_connect(self, client, userdata, flags, rc): + logging.debug("> _on_connect") + self.client.subscribe("bot/" + self.device_id + "/from_device") + self.connected = True + logging.debug("< _on_connect") + + def _on_message(self, client, userdata, msg): + resp = json.loads(msg.payload.decode()) + if resp['args']['label'] != 'ping': + logging.debug("> _on_message [%s] [%s]", msg.topic, resp) + if msg.topic.endswith("/from_device") and resp['args']['label'] == self.pending_uuid: + self.rpc_status = resp['kind'] diff --git a/src/darknet.py b/src/darknet.py new file mode 100644 index 0000000..7f9c416 --- /dev/null +++ b/src/darknet.py @@ -0,0 +1,340 @@ +#!/usr/bin/env python3 + +""" +Python 3 wrapper for identifying objects in images + +Running the script requires opencv-python to be installed (`pip install opencv-python`) +Directly viewing or returning bounding-boxed images requires scikit-image to be installed (`pip install scikit-image`) +Use pip3 instead of pip on some systems to be sure to install modules for python3 +""" + +from ctypes import * +import math +import random +import os + + +class BOX(Structure): + _fields_ = [("x", c_float), + ("y", c_float), + ("w", c_float), + ("h", c_float)] + + +class DETECTION(Structure): + _fields_ = [("bbox", BOX), + ("classes", c_int), + ("best_class_idx", c_int), + ("prob", POINTER(c_float)), + ("mask", POINTER(c_float)), + ("objectness", c_float), + ("sort_class", c_int), + ("uc", POINTER(c_float)), + ("points", c_int), + ("embeddings", POINTER(c_float)), + ("embedding_size", c_int), + ("sim", c_float), + ("track_id", c_int)] + +class DETNUMPAIR(Structure): + _fields_ = [("num", c_int), + ("dets", POINTER(DETECTION))] + + +class IMAGE(Structure): + _fields_ = [("w", c_int), + ("h", c_int), + ("c", c_int), + ("data", POINTER(c_float))] + + +class METADATA(Structure): + _fields_ = [("classes", c_int), + ("names", POINTER(c_char_p))] + + +def network_width(net): + return lib.network_width(net) + + +def network_height(net): + return lib.network_height(net) + + +def bbox2points(bbox): + """ + From bounding box yolo format + to corner points cv2 rectangle + """ + x, y, w, h = bbox + xmin = int(round(x - (w / 2))) + xmax = int(round(x + (w / 2))) + ymin = int(round(y - (h / 2))) + ymax = int(round(y + (h / 2))) + return xmin, ymin, xmax, ymax + + +def class_colors(names): + """ + Create a dict with one random BGR color for each + class name + """ + return {name: ( + random.randint(0, 255), + random.randint(0, 255), + random.randint(0, 255)) for name in names} + + +def load_network(config_file, data_file, weights, batch_size=1): + """ + load model description and weights from config files + args: + config_file (str): path to .cfg model file + data_file (str): path to .data model file + weights (str): path to weights + returns: + network: trained model + class_names + class_colors + """ + network = load_net_custom( + config_file.encode("ascii"), + weights.encode("ascii"), 0, batch_size) + metadata = load_meta(data_file.encode("ascii")) + class_names = [metadata.names[i].decode("ascii") for i in range(metadata.classes)] + colors = class_colors(class_names) + return network, class_names, colors + + +def print_detections(detections, coordinates=False): + print("\nObjects:") + for label, confidence, bbox in detections: + x, y, w, h = bbox + if coordinates: + print("{}: {}% (left_x: {:.0f} top_y: {:.0f} width: {:.0f} height: {:.0f})".format(label, confidence, x, y, w, h)) + else: + print("{}: {}%".format(label, confidence)) + + +def draw_boxes(detections, image, colors): + import cv2 + for label, confidence, bbox in detections: + left, top, right, bottom = bbox2points(bbox) + cv2.rectangle(image, (left, top), (right, bottom), colors[label], 1) + cv2.putText(image, "{} [{:.2f}]".format(label, float(confidence)), + (left, top - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, + colors[label], 2) + return image + + +def decode_detection(detections): + decoded = [] + for label, confidence, bbox in detections: + confidence = str(round(confidence * 100, 2)) + decoded.append((str(label), confidence, bbox)) + return decoded + +# https://www.pyimagesearch.com/2015/02/16/faster-non-maximum-suppression-python/ +# Malisiewicz et al. +def non_max_suppression_fast(detections, overlap_thresh): + boxes = [] + for detection in detections: + _, _, _, (x, y, w, h) = detection + x1 = x - w / 2 + y1 = y - h / 2 + x2 = x + w / 2 + y2 = y + h / 2 + boxes.append(np.array([x1, y1, x2, y2])) + boxes_array = np.array(boxes) + + # initialize the list of picked indexes + pick = [] + # grab the coordinates of the bounding boxes + x1 = boxes_array[:, 0] + y1 = boxes_array[:, 1] + x2 = boxes_array[:, 2] + y2 = boxes_array[:, 3] + # compute the area of the bounding boxes and sort the bounding + # boxes by the bottom-right y-coordinate of the bounding box + area = (x2 - x1 + 1) * (y2 - y1 + 1) + idxs = np.argsort(y2) + # keep looping while some indexes still remain in the indexes + # list + while len(idxs) > 0: + # grab the last index in the indexes list and add the + # index value to the list of picked indexes + last = len(idxs) - 1 + i = idxs[last] + pick.append(i) + # find the largest (x, y) coordinates for the start of + # the bounding box and the smallest (x, y) coordinates + # for the end of the bounding box + xx1 = np.maximum(x1[i], x1[idxs[:last]]) + yy1 = np.maximum(y1[i], y1[idxs[:last]]) + xx2 = np.minimum(x2[i], x2[idxs[:last]]) + yy2 = np.minimum(y2[i], y2[idxs[:last]]) + # compute the width and height of the bounding box + w = np.maximum(0, xx2 - xx1 + 1) + h = np.maximum(0, yy2 - yy1 + 1) + # compute the ratio of overlap + overlap = (w * h) / area[idxs[:last]] + # delete all indexes from the index list that have + idxs = np.delete(idxs, np.concatenate(([last], + np.where(overlap > overlap_thresh)[0]))) + # return only the bounding boxes that were picked using the + # integer data type + return [detections[i] for i in pick] + +def remove_negatives(detections, class_names, num): + """ + Remove all classes with 0% confidence within the detection + """ + predictions = [] + for j in range(num): + for idx, name in enumerate(class_names): + if detections[j].prob[idx] > 0: + bbox = detections[j].bbox + bbox = (bbox.x, bbox.y, bbox.w, bbox.h) + predictions.append((name, detections[j].prob[idx], (bbox))) + return predictions + + +def remove_negatives_faster(detections, class_names, num): + """ + Faster version of remove_negatives (very useful when using yolo9000) + """ + predictions = [] + for j in range(num): + if detections[j].best_class_idx == -1: + continue + name = class_names[detections[j].best_class_idx] + bbox = detections[j].bbox + bbox = (bbox.x, bbox.y, bbox.w, bbox.h) + predictions.append((name, detections[j].prob[detections[j].best_class_idx], bbox)) + return predictions + + +def detect_image(network, class_names, image, thresh=.5, hier_thresh=.5, nms=.45): # + """ + Returns a list with highest confidence class and their bbox + """ + pnum = pointer(c_int(0)) + predict_image(network, image) # image 需要什么类型 + detections = get_network_boxes(network, image.w, image.h, + thresh, hier_thresh, None, 0, pnum, 0) + #print_detections(detections, coordinates=True) + num = pnum[0] + if nms: + do_nms_sort(detections, num, len(class_names), nms) + predictions = remove_negatives(detections, class_names, num) + predictions = decode_detection(predictions) + free_detections(detections, num) + return sorted(predictions, key=lambda x: x[1]) + + +if os.name == "posix": + cwd = os.path.abspath(os.path.join(os.getcwd(), "..")) + lib = CDLL(cwd + "/darknet/libdarknet.so", RTLD_GLOBAL) +elif os.name == "nt": + cwd = os.path.dirname(__file__) + os.environ['PATH'] = cwd + ';' + os.environ['PATH'] + lib = CDLL("darknet.dll", RTLD_GLOBAL) +else: + print("Unsupported OS") + exit + +lib.network_width.argtypes = [c_void_p] +lib.network_width.restype = c_int +lib.network_height.argtypes = [c_void_p] +lib.network_height.restype = c_int + +copy_image_from_bytes = lib.copy_image_from_bytes +copy_image_from_bytes.argtypes = [IMAGE,c_char_p] + +predict = lib.network_predict_ptr +predict.argtypes = [c_void_p, POINTER(c_float)] +predict.restype = POINTER(c_float) + +set_gpu = lib.cuda_set_device +init_cpu = lib.init_cpu + +make_image = lib.make_image +make_image.argtypes = [c_int, c_int, c_int] +make_image.restype = IMAGE + +get_network_boxes = lib.get_network_boxes +get_network_boxes.argtypes = [c_void_p, c_int, c_int, c_float, c_float, POINTER(c_int), c_int, POINTER(c_int), c_int] +get_network_boxes.restype = POINTER(DETECTION) + +make_network_boxes = lib.make_network_boxes +make_network_boxes.argtypes = [c_void_p] +make_network_boxes.restype = POINTER(DETECTION) + +free_detections = lib.free_detections +free_detections.argtypes = [POINTER(DETECTION), c_int] + +free_batch_detections = lib.free_batch_detections +free_batch_detections.argtypes = [POINTER(DETNUMPAIR), c_int] + +free_ptrs = lib.free_ptrs +free_ptrs.argtypes = [POINTER(c_void_p), c_int] + +network_predict = lib.network_predict_ptr +network_predict.argtypes = [c_void_p, POINTER(c_float)] + +reset_rnn = lib.reset_rnn +reset_rnn.argtypes = [c_void_p] + +load_net = lib.load_network +load_net.argtypes = [c_char_p, c_char_p, c_int] +load_net.restype = c_void_p + +load_net_custom = lib.load_network_custom +load_net_custom.argtypes = [c_char_p, c_char_p, c_int, c_int] +load_net_custom.restype = c_void_p + +free_network_ptr = lib.free_network_ptr +free_network_ptr.argtypes = [c_void_p] +free_network_ptr.restype = c_void_p + +do_nms_obj = lib.do_nms_obj +do_nms_obj.argtypes = [POINTER(DETECTION), c_int, c_int, c_float] + +do_nms_sort = lib.do_nms_sort +do_nms_sort.argtypes = [POINTER(DETECTION), c_int, c_int, c_float] + +free_image = lib.free_image +free_image.argtypes = [IMAGE] + +letterbox_image = lib.letterbox_image +letterbox_image.argtypes = [IMAGE, c_int, c_int] +letterbox_image.restype = IMAGE + +load_meta = lib.get_metadata +lib.get_metadata.argtypes = [c_char_p] +lib.get_metadata.restype = METADATA + +load_image = lib.load_image_color +load_image.argtypes = [c_char_p, c_int, c_int] +load_image.restype = IMAGE + +rgbgr_image = lib.rgbgr_image +rgbgr_image.argtypes = [IMAGE] + +predict_image = lib.network_predict_image +predict_image.argtypes = [c_void_p, IMAGE] +predict_image.restype = POINTER(c_float) + +predict_image_letterbox = lib.network_predict_image_letterbox +predict_image_letterbox.argtypes = [c_void_p, IMAGE] +predict_image_letterbox.restype = POINTER(c_float) + +network_predict_batch = lib.network_predict_batch +network_predict_batch.argtypes = [c_void_p, IMAGE, c_int, c_int, c_int, + c_float, c_float, POINTER(c_int), c_int, c_int] +network_predict_batch.restype = POINTER(DETNUMPAIR) + +if __name__ == "__main__": + net = load_network("/home/xzleo/farmbot/darknet/cfg/yolov3-veges-test.cfg", "/home/xzleo/farmbot/darknet/data/veges.data", "/home/xzleo/farmbot/darknet/backup/yolov3-veges_best.weights") + img = load_image(b"/home/xzleo/farmbot/dataset/2_a.png", 0, 0) + predictions = detect_image(net, img, thresh=.5, hier_thresh=.5, nms=.45) \ No newline at end of file diff --git a/src/darknet_images.py b/src/darknet_images.py new file mode 100644 index 0000000..b670441 --- /dev/null +++ b/src/darknet_images.py @@ -0,0 +1,236 @@ +import argparse +import os +import glob +import random +import darknet # darknet.py +import time +import cv2 +import numpy as np + + +def parser(): + parser = argparse.ArgumentParser(description="YOLO Object Detection") + parser.add_argument("--input", type=str, default="", + help="image source. It can be a single image, a" + "txt with paths to them, or a folder. Image valid" + " formats are jpg, jpeg or png." + "If no input is given, ") + parser.add_argument("--batch_size", default=1, type=int, + help="number of images to be processed at the same time") + parser.add_argument("--weights", default="yolov4.weights", + help="yolo weights path") + parser.add_argument("--dont_show", action='store_true', + help="windown inference display. For headless systems") + parser.add_argument("--ext_output", action='store_true', + help="display bbox coordinates of detected objects") + parser.add_argument("--save_labels", action='store_true', + help="save detections bbox for each image in yolo format") + parser.add_argument("--config_file", default="./cfg/yolov4.cfg", + help="path to config file") + parser.add_argument("--data_file", default="./cfg/coco.data", + help="path to data file") + parser.add_argument("--thresh", type=float, default=.25, + help="remove detections with lower confidence") + return parser.parse_args() + + +def check_arguments_errors(args): + assert 0 < args.thresh < 1, "Threshold should be a float between zero and one (non-inclusive)" + if not os.path.exists(args.config_file): + raise(ValueError("Invalid config path {}".format(os.path.abspath(args.config_file)))) + if not os.path.exists(args.weights): + raise(ValueError("Invalid weight path {}".format(os.path.abspath(args.weights)))) + if not os.path.exists(args.data_file): + raise(ValueError("Invalid data file path {}".format(os.path.abspath(args.data_file)))) + if args.input and not os.path.exists(args.input): + raise(ValueError("Invalid image path {}".format(os.path.abspath(args.input)))) + + +# def check_batch_shape(images, batch_size): +# """ +# Image sizes should be the same width and height +# """ +# shapes = [image.shape for image in images] +# if len(set(shapes)) > 1: +# raise ValueError("Images don't have same shape") +# if len(shapes) > batch_size: +# raise ValueError("Batch size higher than number of images") +# return shapes[0] + + +def load_images(images_path): + """ + If image path is given, return it directly + For txt file, read it and return each line as image path + In other case, it's a folder, return a list with names of each + jpg, jpeg and png file + """ + input_path_extension = images_path.split('.')[-1] + if input_path_extension in ['jpg', 'jpeg', 'png']: + # single image + return [images_path] + elif input_path_extension == "txt": + with open(images_path, "r") as f: + return f.read().splitlines() + else: + # folders + return glob.glob( + os.path.join(images_path, "*.jpg")) + \ + glob.glob(os.path.join(images_path, "*.png")) + \ + glob.glob(os.path.join(images_path, "*.jpeg")) + + +# def prepare_batch(images, network, channels=3): +# width = darknet.network_width(network) +# height = darknet.network_height(network) + +# darknet_images = [] +# for image in images: +# image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) +# image_resized = cv2.resize(image_rgb, (width, height), +# interpolation=cv2.INTER_LINEAR) +# custom_image = image_resized.transpose(2, 0, 1) +# darknet_images.append(custom_image) + +# batch_array = np.concatenate(darknet_images, axis=0) +# batch_array = np.ascontiguousarray(batch_array.flat, dtype=np.float32)/255.0 +# darknet_images = batch_array.ctypes.data_as(darknet.POINTER(darknet.c_float)) +# return darknet.IMAGE(width, height, channels, darknet_images) + + +def image_detection(image_path, network, class_names, class_colors, thresh): + # Darknet doesn't accept numpy images. + # Create one with image we reuse for each detect + width = darknet.network_width(network) + height = darknet.network_height(network) + darknet_image = darknet.make_image(width, height, 3) + + image = cv2.imread(image_path) + image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) + image_resized = cv2.resize(image_rgb, (width, height), + interpolation=cv2.INTER_LINEAR) + + darknet.copy_image_from_bytes(darknet_image, image_resized.tobytes()) + detections = darknet.detect_image(network, class_names, darknet_image, thresh=thresh) + darknet.free_image(darknet_image) + image = darknet.draw_boxes(detections, image_resized, class_colors) + return cv2.cvtColor(image, cv2.COLOR_BGR2RGB), detections + + +# def batch_detection(network, images, class_names, class_colors, +# thresh=0.25, hier_thresh=.5, nms=.45, batch_size=4): +# image_height, image_width, _ = check_batch_shape(images, batch_size) +# darknet_images = prepare_batch(images, network) +# batch_detections = darknet.network_predict_batch(network, darknet_images, batch_size, image_width, +# image_height, thresh, hier_thresh, None, 0, 0) +# batch_predictions = [] +# for idx in range(batch_size): +# num = batch_detections[idx].num +# detections = batch_detections[idx].dets +# if nms: +# darknet.do_nms_obj(detections, num, len(class_names), nms) +# predictions = darknet.remove_negatives(detections, class_names, num) +# images[idx] = darknet.draw_boxes(predictions, images[idx], class_colors) +# batch_predictions.append(predictions) +# darknet.free_batch_detections(batch_detections, batch_size) +# return images, batch_predictions + + +# def image_classification(image, network, class_names): +# width = darknet.network_width(network) +# height = darknet.network_height(network) +# image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) +# image_resized = cv2.resize(image_rgb, (width, height), +# interpolation=cv2.INTER_LINEAR) +# darknet_image = darknet.make_image(width, height, 3) +# darknet.copy_image_from_bytes(darknet_image, image_resized.tobytes()) +# detections = darknet.predict_image(network, darknet_image) +# predictions = [(name, detections[idx]) for idx, name in enumerate(class_names)] +# darknet.free_image(darknet_image) +# return sorted(predictions, key=lambda x: -x[1]) + + +def convert2relative(image, bbox): + """ + YOLO format use relative coordinates for annotation + """ + x, y, w, h = bbox + height, width, _ = image.shape + return x/width, y/height, w/width, h/height + + +def save_annotations(name, image, detections, class_names): + """ + Files saved with image_name.txt and relative coordinates + """ + file_name = os.path.splitext(name)[0] + ".txt" + with open(file_name, "w") as f: + for label, confidence, bbox in detections: + x, y, w, h = convert2relative(image, bbox) + label = class_names.index(label) + f.write("{} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(label, x, y, w, h, float(confidence))) + + +""" def batch_detection_example(): + args = parser() + check_arguments_errors(args) + batch_size = 3 + random.seed(3) # deterministic bbox colors + network, class_names, class_colors = darknet.load_network( + args.config_file, + args.data_file, + args.weights, + batch_size=batch_size + ) + image_names = ['data/horses.jpg', 'data/horses.jpg', 'data/eagle.jpg'] + images = [cv2.imread(image) for image in image_names] + images, detections, = batch_detection(network, images, class_names, + class_colors, batch_size=batch_size) + for name, image in zip(image_names, images): + cv2.imwrite(name.replace("data/", ""), image) + print(detections) """ + + +def main(): + args = parser() + check_arguments_errors(args) + + random.seed(3) # deterministic bbox colors + network, class_names, class_colors = darknet.load_network( + args.config_file, + args.data_file, + args.weights, + batch_size=args.batch_size + ) + + images = load_images(args.input) + + index = 0 + while True: + # loop asking for new image paths if no list is given + if args.input: + if index >= len(images): + break + image_name = images[index] + else: + image_name = input("Enter Image Path: ") + prev_time = time.time() + image, detections = image_detection( + image_name, network, class_names, class_colors, args.thresh + ) + if args.save_labels: + save_annotations(image_name, image, detections, class_names) + darknet.print_detections(detections, args.ext_output) + fps = int(1/(time.time() - prev_time)) + print("FPS: {}".format(fps)) + if not args.dont_show: + cv2.imshow('Inference', image) + if cv2.waitKey() & 0xFF == ord('q'): + break + index += 1 + + +if __name__ == "__main__": + # unconmment next line for an example of batch processing + # batch_detection_example() + main() diff --git a/src/detect.py b/src/detect.py new file mode 100644 index 0000000..cf52bed --- /dev/null +++ b/src/detect.py @@ -0,0 +1,116 @@ +''' +load images taken by the camera, return bounding boxes +''' +import argparse +import os +import glob +from pathlib import Path +import random +import darknet #darknet.py +import time +import cv2 +import numpy as np +from logging import basicConfig, DEBUG, INFO, error, getLogger + +# IMG_EXTENSION = ['jpg', 'jpeg', 'png'] + +"""Logger for printing.""" +_LOG = getLogger(__name__) + + +def load_images(images_path): + """ + load all images in a folder for detection + + :param images_path: the path folder + :return list of image paths + """ + + return glob.glob( + os.path.join(images_path, "*.jpg")) + \ + glob.glob(os.path.join(images_path, "*.png")) + \ + glob.glob(os.path.join(images_path, "*.jpeg")) + + +def image_detection(image_path, network, class_names, class_colors, thresh): + ''' + Accept single image + ''' + # Darknet doesn't accept numpy images. + # Create one with image we reuse for each detect + width = darknet.network_width(network) + height = darknet.network_height(network) + darknet_image = darknet.make_image(width, height, 3) + + image = cv2.imread(image_path) + image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) + image_resized = cv2.resize(image_rgb, (width, height), + interpolation=cv2.INTER_LINEAR) + + darknet.copy_image_from_bytes(darknet_image, image_resized.tobytes()) + detections = darknet.detect_image(network, class_names, darknet_image, thresh=thresh) + darknet.free_image(darknet_image) + image = darknet.draw_boxes(detections, image_resized, class_colors) + return cv2.cvtColor(image, cv2.COLOR_BGR2RGB), detections + + +def convert2relative(image, bbox): + """ + YOLO format use relative coordinates for annotation + """ + x, y, w, h = bbox + height, width, _ = image.shape + return x/width, y/height, w/width, h/height + + +def save_annotations(name, image, detections, class_names) -> None: + """ + Files saved with image_name.txt and relative coordinates + """ + file_name = os.path.splitext(name)[0] + ".txt" + with open(file_name, "w") as f: + for label, confidence, bbox in detections: + x, y, w, h = convert2relative(image, bbox) + label = class_names.index(label) + f.write("{} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(label, x, y, w, h, float(confidence))) + return None + + +def detect(img_dir: Path, weight_path: Path, cfg_path: Path, data_path: Path, thresh: float =0.25, save_labels: bool =True) -> None: + """ + main function for this script + """ + random.seed(3) # deterministic bbox colors + network, class_names, class_colors = darknet.load_network( + cfg_path, + data_path, + weight_path + ) + + images = load_images(img_dir) + + num_img = len(images) + + if num_img == 0: + _LOG.error("No images with legal extensions in assigned dir") + raise ValueError("No images, please sweep the bed again.") + + index = 0 + while index < num_img: + image_name = images[index] # search the folder for single images + prev_time = time.time() + # run yolo on a single img + image, detections = image_detection( + image_name, network, class_names, class_colors, thresh + ) + if save_labels: + save_annotations(image_name, image, detections, class_names) # 应该换个路径存 + # darknet.print_detections(detections, true) + + fps = int(1/(time.time() - prev_time)) + _LOG.debug("FPS: {}".format(fps)) + + index += 1 + return None + + diff --git a/src/load_cam.py b/src/load_cam.py new file mode 100644 index 0000000..afba1c3 --- /dev/null +++ b/src/load_cam.py @@ -0,0 +1,11 @@ +''' +load camera intrinsic matrix as .mat file +''' +import scipy.io as io + +data = io.loadmat('../static/camera_no_distortion.mat') +print(data['camera_no_distortion'][0, 0][11]) # intrinsic matrix +print(type(data['camera_no_distortion'][0, 0][11])) +print(data['camera_no_distortion'][0, 0][11].shape) + +# 加上argparser diff --git a/src/move.py b/src/move.py new file mode 100644 index 0000000..2da316a --- /dev/null +++ b/src/move.py @@ -0,0 +1,182 @@ +''' +Author: Ziliang Xiong +This script is for al the functions that drive Farmbot to Move, including: +1. Taking Photos 2. Move to an assigned point (x, y, z) +3. Sweep the planting bed 4. Grip a target +''' + +from argparse import ArgumentParser +from logging import getLogger +from os import path, makedirs +from time import sleep, time +from serial import Serial, PARITY_NONE, STOPBITS_ONE, EIGHTBITS +# from requests.api import delete +from typing import List +from pathlib import Path +from logging import basicConfig, DEBUG, INFO, error, getLogger + +from datetime import timezone +from dateutil.parser import parse +from requests import get, delete + +import creds +from client import FarmbotClient + + +_SWEEEP_HEIGHT = -200 + +Logger = getLogger(__name__) + +class Opts: + def __init__(self, min_x, max_x, min_y, max_y, delta, offset, flag): + self.min_x = min_x + self.max_x = max_x + self.min_y = min_y + self.max_y = max_y + self.delta = delta + self.offset = offset + self.flag = flag + + +def sweep(min_x=0, max_x=1300, min_y=0, max_y=1000, delta=500, offset=0, flag=True) -> List: + ''' + Sweep the bed at a certain height, first move along x axis, then y, like a zig zag; + Taking pictures and record the location of the camera that corresponds to the picture + Input: min_x: left most point on x axis + max_x: right most point on x axis + min_y: front most point on y axis + max_y: back most point on y axis + delta: the interval for scaning + offset: + flag: for degging, if true, don't actually drive FarmBot + Output: none + ''' + opts = Opts(min_x, max_x, min_y, max_y, delta, offset, flag) + + pts = [] + sweep_y_negative = False + for x in range(opts.min_x, opts.max_x, opts.delta): + y_range = range(opts.min_y, opts.max_y, opts.delta) + if sweep_y_negative: + y_range = reversed(y_range) + sweep_y_negative = not sweep_y_negative + for y in y_range: + pts.append((x+opts.offset, y+opts.offset)) + + Logger.info('Moving pattern generated') + + if opts.flag: + Logger.info('Run without sweep') + exit() + + client = FarmbotClient(creds.device_id, creds.token) + client.move(0, 0, _SWEEEP_HEIGHT) # ensure moving from original + for x, y in pts: + client.move(x, y, _SWEEEP_HEIGHT) # move camera + #client #需要添加一个函数,读取当前位置,需要吗? + client.take_photo() + client.shutdown() + return pts + + +def download_images() -> Path: + REQUEST_HEADERS = {'Authorization': 'Bearer ' + creds.token, 'content-type': "application/json"} + + while True: + response = get('https://my.farmbot.io/api/images', headers=REQUEST_HEADERS) # http rquest + images = response.json() + Logger.info("Download {} Images".format(len(images))) + if len(images) == 0: # cannot receive images + break # leave the loop + + at_least_one_dup = False + for image_info in images: + + if 'placehold.it' in image_info['attachment_url']: + Logger.debug("IGNORE! placeholder", image_info['id']) + continue + + # convert date time of capture from UTC To AEDT and extract + # a simple string version for local image filename + dts = parse(image_info['attachment_processed_at']) + dts = dts.replace(tzinfo=timezone.utc).astimezone(tz=None) + local_img_dir = "imgs/%s" % dts.strftime("%Y%m%d") #the name of local pics 新建图片的位置 + if not path.exists(local_img_dir): + makedirs(local_img_dir) + local_img_name = "%s/%s.jpg" % (local_img_dir, dts.strftime("%H%M%S")) + Logger.debug(">", local_img_name) + + # download image from google storage and save locally + captured_img_name = image_info['meta']['name'] + if captured_img_name.startswith("/tmp/images"): + req = get(image_info['attachment_url'], allow_redirects=True) + open(local_img_name, 'wb').write(req.content) + + # post delete from cloud storage + delete("https://my.farmbot.io/api/images/%d" % image_info['id'], + headers=REQUEST_HEADERS) + + if at_least_one_dup: + Logger.debug("only at least one dup; give DELETEs a chance to work") + sleep(2) + return local_img_dir + + +def simple_move(x: int, y: int, z: int, photo: bool) -> None: + ''' + Move to a place, if flag is true, take a picture + Input: x, y,z: destination point + photo: take a pic or not + ''' + client = FarmbotClient(creds.device_id, creds.token) + client.move(x, y, z) + if photo: + # take a picture + client.take_photo() + client.shutdown() + return None + +def gripper(open: bool) -> None: + ''' + Use a serial port to drive the gripper to open or close + ''' + ser = Serial( + port = 'COM4', # 这里不应为hard code + baudrate = 9600, + parity = PARITY_NONE, + stopbits = STOPBITS_ONE, + bytesize = EIGHTBITS, + timeout = 1 + ) + if open: + ser.write(str.encode("o")) + else: + ser.write(str.encode("c")) + return None + + +if __name__ == '__main__': + parser = ArgumentParser() + parser.add_argument( + '-m', + '--mode', + type=int, + help='Mode for FarmBot, 1 for simple move with an assigned detination, 2 for Sweeping' + ) + + arguments = parser.parse_args() + + if arguments.mode == 1: + Logger.info('Input the destination:') + destination_x = int(input('X:')) + destination_y = int(input('Y:')) + destination_z = int(input('Z:')) + photo = True if input('Take a photo or not?[Y/N]:') == 'Y' else False + simple_move_start = time() + simple_move(destination_x, destination_y, destination_z, photo) + Logger.info(f'time cost {time.time()-simple_move_start}') + elif arguments.mode == 2: + sweep() + else: + Logger.error('Wrong mode number {arguments.mode}') + diff --git a/static/a.mat b/static/a.mat new file mode 100644 index 0000000000000000000000000000000000000000..46627a3ee6975b1500deb5043f0ffc19bee1b799 GIT binary patch literal 179 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQV4Jk_w+L}(NS<NN=+<DO;O0t zvr-67EK%@JE>SQtRxmWTGPSfaHdHV&Ffvpi5-`93qo*%F0|SFL0|P_FoX5!t2^$!a o%oLtATv9l|_0*Wr&{)8jDN$((f6(C*hmM@$Nnv1+|I6?e01^r;4gdfE literal 0 HcmV?d00001 diff --git a/static/camera.mat b/static/camera.mat new file mode 100644 index 0000000000000000000000000000000000000000..7a202766b610670b223324a7ec87d13ffbfe0513 GIT binary patch literal 22584 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQV4Jk_w+L}(NS<NN=+<DO;O0t zvr-68O;HF=El@DBR4_ERGB&d^G*K`zFfvpi64){_KmensFFykVLl^@CL&coO$q5NF z7?0#QoMAlD#3OKk<A{yJoH;XQM@^BK5HV#&G>>3<;)l|2{A?$=7o1u?ZHbuZXU3y8 z6V5ztopqe+>1M~XX)RsNKZFFH#j2@TO0Y4Us^WVCGCdrJ>3dL2&*2aw#dv9khgSUZ zAmcxWfgJxPygJ4=`uaT4lbtRaEo+6HJf`&Bj_OqQ(-bYTejB0{t15bEnaU)uMN@9M zn%~v;I2E--I<`zzU2~gvXOXSq_xF*0&mR|8+@Jsb_v7EsqxavxReXNyF`42shVwr5 zY<$9@=oQ!Ekv!$#-PwOizrLC0{UGo2pX?`kC*N64jL0}~_G!WE>bf}npS@q}@7LSD z|M+sQ%l4jy^CrH$Uv)yf>R0(`??2yfJf5s${=WNnc(wcNr+L%XtuxCL6TAC5vj6;R z`}g0k$NbW^wx~4id_RBpYwgOD@6v<rZnw*`zH@MgbV2v-`~Pbrt@72vrumuWO*=L% zPvUOw9kWTPKQ@*Zs@>nIvj5|o?EjuMk8f_*>&*Z2zpD31_~ZS%p6ru&n*JwZPvzZW zF?+RX*S<~b`~1dy*X|uV>ko^kO*^;E?A*KiQzKubWM(I4?LYd=x=gRUuy~7E*~ap+ z`#=7E_n!N9|L0j}?!U-;pYk#<`BlQ>pKHH&n_Je_ve=5xE`9xG?VH>kw*TY)?=7CO zV@Gt+|LHd)9=^2iH7MR(a__~DT0vpyaP#S3E0`O9=H>mb*ni>X-Lv;97w?_AQ1xHM zU+4ce3Kvh^J@(6d_Stp!KV912_+t5w%TJ2`EZsf7Ub5cvljXmdxRa0V?AILJvSD9O z*0im*dn-LPKhJ+vS$wbHZ}8-=J?~~;zr1em*G2z=ZRhJX%KyDS-`Qljdc>>WRa^Ei zY}fx9YyNk3w$0z<$361WtX1}AlU(i1E*-Ns<MOG`NtyolhDX@H2S2`lom#*D+wuF~ z{_p?uf99X-KkqKCemec9uD9Lur8VF0oV<7O;=bK)io}<@KjyaGtNMTC^ZIMmo&NuK zmRdcD|9pD->#B15_xoP_KfA9?=>GlbuN#-_yA{qZ{NJH={mK39!DYqVZ&=PAmz>|n zzcW)jNuv1tvNLy^7tMTp+D|=2?YYr(HI~^YEYplXJzDksnQmmyRykXD?MEuc`^@5Y z?Ek5wD!=#ht_PutSJiTF`<KP5ZEencAwN$y$;!lA|Hqo#q(0HN;V)lIKDp%ZmSt}% z&&)dQ6&l?Zm$HJ>yx46;T*A55uUR{n#-BJ-tRweOc-FBaZWWd#r7gk9@qTaTq)zhH z{bx}exaUpbse2VMsdvu5p84=#dyN#^oaA#S-rh)BH2utqtJ{uwbrj7|+g(_!{+xTp z7qhZ!Ex#<5EzfQ^`rwqrvZR`IYZm>qTNY}u>rG3bR<go6Ns|I^waF2`FFX}*)=^XN z4%-}IJu~xuQuLBv3Y}f@0qZvHJ|E}x-6i|lrXGoBjn{O=SNqln$fn*r+9bF0O#Q3( ztd3S+PAF<e)~$c^ro~+?$LVh3&u-h}8@IK7&o2A#cX4*|x<5r(>-2Ol+blWn;?*Yi zS<%b?@_`AxCadFBKW4FNcZJpNjrm+&R=y-P{AjiCwbF>3_0PqMUw-`4amS#$b<Opt zo7HP)U%kQjEb*M`=VzO>m(A$?)O9sAHJW#CM10rM>9@@6Z`e$aH7E%@J+~(L+l(&~ zt0mieZcf{wd@k{HZ{%Y2C7T^Hj+og+?spEa=lZ?sdFgAul?T@>SzODoKX_(upms%w z<*|;bpRKPJx#x=AuI#!#Y2Mb(efqYqZ!NN(ozYw^{w4I2*~QmI^IlxDuDay=Zt3i> z;CWw;KVBujLR@ak1HJqQ!tVUHI(z*l7=Bvt`SqHWd)~^K<VVeVzgbzXB-7RPy=UU= z%>NThg?^dJm84vHc&Bos-26{Yo_}xud*^I-{r0}Q=l6fvUBOg0X{x@ZjX>~`zZb3q zYM;`W6uBt&p1^T|!sM&&s{`6N_O@@nr><GF+5hNO)o{(EPs^`YCK|im_}r6NA>u4G zWn0SWsRk~Vq2)7jjh&53Pr09X`tawrD~6kHiadO~bEnOF8`pVJ`fn4oBp>biS>O;Z zcJKQI|9M~7ozKW;N$~7BB2c$~^D0Zt2>betspn7MnEtBpM}pFm7~XeQVTLW`t*0t` zp6_wzHG8SPz&$wo^#z|c72j8;M|Mq7Ol|7SU$nq|YxcPZiKaY)qPiFF)X!5~bICt! z@?=R7%a;c8%&z5rtT1}7^UU_ys+iuRC${giFXnSjx#c#mqGqC!*D0I(oDx^1%zb|? zZc<|UTll<&SwrYg-r)&5muoJ%zvQGx>;jLtS@~W0y7%UDd)tJ&3g&<RvGA>_h+=w} zp9yEnz2BaT)<vArzx8&{!`83AMd#|pEb91}@48a&g8rKLeeZrq?lBJ#tL0e4ky{to z#lL@Z+!fc!F>Bsm-k%k(_2<E)gbHox^V2PlwH-SD=IY{04-}QA$uCJ`v*$YYW$B@F z3G;MI4W){WRM&q0@%DmwTGZ8xDmL?1Y`r2;*4@`#*>ypAhxxI+7v+lzAG*iM9F2JV zD@p0i)A`jCf+X5MAF+@A%k=Nl{rrO^B9AK<Wu97Daia2F$-Xy7CoKPUX`cPYj@R>V z9`>8JsN<OA%ry!}LLY2e_9<7T;Gy(V>)#yCCVY~y8`|bK3BPBJJ!1J%;eW7o1M~3+ z|4s|BUx&I&xgLgZd$+`67sKK`Pq{wVbnW={W%cYv%b9A%)m_Z4d*aHs%$U#Q_iM(7 zrJp{;oj19)VTzKGcinkYrns92XC7nvanojL$!WJ2Pd^&%syUo+-sbJepbfz$S<9MN zOj3GuFzEK<^N0Al74}bazEK~zI!Ee_UiJPp4qF8l`)9Q9oIAYi%&9PUnaV8IQ`>_S z^Xnf^dBIfhqb_yw2P@|n_Uk-WiXUA6xmqKqdG6=D&TC(PwlE*A{k(9$cG8nq(i6^W z|6Mw@>CX?QX#M@x8?0|GP7{5z-21NCYsTp-|DI{Pw<g_VxnsxH2Wnqd@7u7u;o=z= z$E+gT4}y1=CN=C4mdtql_B?xDHuI|a@vSwhX6;h^qP6$U`khb2oVoI*9QP3lbotj) zc7B`A8|9E`5~t@TPye+{;D@ho?C-Z}Hx`Se&iujg^O;tumdRGWe-Q?zwyUImNq^n5 z<@Cn+ehZ?U4A0#aDcdXcuVigxb}?63oA}q+S$s9zwtVciT8?tFb=O-r{@t@EyJuS5 zqi=Id3oSm`1RH(7zWav%pChi<CH_6@mHTsQp+E(H#!Q1hM$eADH(T3SyT$S6(_GCN z`(<CB{y8@{JaW6xr<qaGf1WGN+w$?*?4L1l9hcXeEi14Hm^0y#i{RW-Dp&8Gc<r<M zo2hY^#-aSbp4B>UmiEUO1+dCr*c;3ov}4b^8G9EA|I6}--MFM)*!fAiDO<aeozvO* zH~A;1KV5HJ^DXi2l?hE}m>xXIdGqM*gZ?wh$9dQs?rCRv_u0J>Jrh3F(}vIT>y{YZ zBaQF1rEkphnP~PZXQJ+(1J{Ejbh%}?X3gW3E@!RdSW;`2;<Ug1*i2?=!&OHlwcoYQ zxtO-r>cK1@nU&TO|6WbFz0HfQQt^TBy&rl4g<f}VTZ<O|Gh5s$nAy>O$0zuIafkoQ zhCrn^&Nk`ax!mIBReWAzB>p_1KXrBH0lUKZopR?Te_Z_AnaJ_PvvZjvSA|QuN8m-h zHNw?)`*hj&h247oa1VdwhmxfR9~decp4(a)Xw7@v`fQ!shqf1gk8Hm<VSmcZhe>Re zg??$*)Ly7g-Jd?Qq5ewCBq_-c{Q2j1XnvFVU&B*!s?Bzd@%tsZk1k(JKi4Jl;`@Bd zn-~5oeJXjfXuJ73gCiUFy~^YKFe|+5d{#Z{kCeQ11(wIv-L8CTn9O777jKc1Z~4dW z;6AUwmglo$s`{AiuF9LX{OPh<q^7@8DZ0Dx|Jv7a5B~o>+8pvq;Qxo4?RA`M+4v>T z+sbx+m&%pgJ!ipuiOhUyj(x%+sy4w6_clGXi(P0De)Fxxbj<^+kNq*LHhy4Jv(EpO z&<n%5GjZJyUimcS^szlUrp0q6mPLl^laHCWSfS10#Y&9x)O;77UAbZMnevS~98Gh@ z)J4u6mS=kVH_haGUCD;8C*~fw-gx>=b4}lIxq0&^I8R*Sc-epb%H})o+)CL>r}WO8 zx3c$-y861V?*%(nEh%5`a_5KS?QlJoxVKh6|DEN%kS}JNBlAXZ+FjYV9adiP!QZS; z{H$)c<0k!K)9Z`#eU}_8j{B+iyxMX93d<9QLeC#<pW&sGrtto6TB*)6fAJ~rV)%B? zzo)TrrS{><t=F$-74EqFx44n3qN}H~_k;!G&Mz*PAD_tI=oH`XbfjNKceS)wQ^osi z$r}uH3p(#!?TkpjvvY|7%MZ~z8~Y8I|7BdaW}bY|{t0vPj`QN*@?uL~g+FjB`1G}} z>c`z3Mt9CnIGx_S`%vAA^hbQ}%cN?qCs?eSc{;gwH~0Ph%>Tahem<_lw63MG>#Dgx zy5pkL9|SEe+)rJcdrfkK@!!KY72@AaHn;uqBIrb{wCQWxaCPz1b{mgbIWGIXqeQR& zZP?6T@(uG#{=WVbaQ%mPym~KdKkNLf;yusb*v(n^fceg4yY^@04A;Np7&-kjc(cyZ zpw#@w;r;vfy%2x0dE@27TcVEmzX_YI#<cHgySwYUXMetC&2+Q*H1oUH!hG>J!msVR zZ?M_l?&NXFZ>awj`o~N0TIQSTjm~m^j_$s-{fpR-J{ei@m(MyU#?Gn`-f`u{%q>4n zpLjGHFMZHf8v9o6@6M|9Bf+n@cgF_LXnx=Sc+a}#^(||T&PaMGH<!;kF8;$;#`BYu zRi_0XD*U(d)bn*M$@34THcyvtnWwmVTm7lmjEPhK9#C##c$%d?XY$)s-C76dn18%> zZd&n$<uO)=g)1K0>wU=VJ#HBvBKqC8DenFAkIvH%_wP3HdaLxouJ6?A#(yVFuNNIR zdhk56+V9Q#7wb>>h^}4w;`fWvd8^e6ES6o>7JvBXh>2S0Cyg(q`#$e%w)iYnx0(0R zljbtN`(+%Z7hin4<h^1w)BDEnWpalj?kw3p<#hMgZOisEo<C%`{LQ2X>58*&$Z*NL z@;I%V{hzr?e~L%=0r{H$fo6>-wkK$6|C0Fd!{qmK)1@o!Kl)VV?Eb*;Wkmkse<z9; ze)$r)YR2Z!*yPUv>_0j0Sv}p*EVoO|kFg?jQt~VrMfYzdYtK8`ZTen2Sx)(W<Y(P( zr;GBcnO)D0Dy}!$?x!2oTKpmO(3)>%MK$@EJGs89_UrR_HpL$ND%QWvIX`-7TC3PA zvyX2}S5%6h+j`vDTaWSA?R)R_IuGpmw)VgF4dwaojT4!F^lrcU^!(BX{E0!wvc&uD zD{r23_2PL>xw&sOnC&{&&Pf;jwBLK~-i?byzn(txWv4Imxz|4)emwhn!{+N>pC4Rt z|4;kJzxSHgd;B>)KZWmc&1Ai*-u;Ym5}RC7ns)j6Fq>8{win~O_HEXzHk-$D*H>}b zU#>qUYQ?<2rQ(Q6^Y#<>Lb=zjdAPlB(iDlmW|cd1Ue6VMB)92u5%Uk12UUi<L@NaR zS6<g);Vbpi`TDkW+T(+wb8S9Y+&8LOE#p?S)hv<mm3`of$UFWA9!`F@QNB)e_4jor zyN~RXzR|yO=Z*ZFsM!_L->PR=Ok<1BE}8N^?CGzjI?k%<2j&lNcda>k@k4a%-VE96 z)6e9@DEc+r=i^qp%ifoHoAYSifw?_De}DbmxV!Sr&FR7q;(HVQuk*3}zqBjPs4C{( z*UUTF6Z>jq!_0OUeGFJ57rRsXo7ajtCmm$#Z^@LG@cs&1wDHF|4(T`IN|qO<zg9jL z`EO;{-yia8|4uPB*tW|;=ZK|?v#EQ;++#IPwNuUCB&;sKvDQ&uvtv!zU(tW!9?y52 zXX8I>+!y=4v98<q%*?1s9DCo-T;upczNPi*>iz@%HkykUwSO?at6mvm{V8Hb-Sd5q zP1l_NU+|CTmsg`tPpkPS)z24R-D{qx|EV^_uIR7!-cx%XvwiT7&bH-tsTEoJaqp9f z>W^+rR=&3AeAbSCj~Zn6ou1OPiTB<@{{{DZ>|Qb0P40iZdyb>5n)e?S{x@y5t<qEM z3rd%2X1q8S{h@i^&5MC|%KIx{y_mk@e^bHXCgvBXQ{Gj0yByS8^kU;fxgTCH%1h_T zytz1$cfytZZC0~(n}5^&)WO$r_p)%&Ol2mS6R|h`yTyA-SDv}=l;+u(f8*+!a=wCd zyG_!5l)kGjc+!4+wZiqVx0g(rerjy!H3@c+GqZT@^=sjJ)ia0g$rr?#eh;7g$Ut0% zBVhiqt1~}b-K+NYaK+<4uNHT#esJT7uKYxI6^p~Y+ZpdCZ+^aSN0IdJx7yQQw%fJ) z-6+zRf37(FYSZC>=N_N4(_%Fqnb~V!5V1HT{eR)N0`^xI&$efqyeqz+IhS*u?u+EC zH|~2~_Mh{Xh$xY+)UVj`*-P!)<C!bDHV4dqdOJ<Z&*lHco9Z6l<X)Zc+%CP^==9F_ zXa345ADH|lq1*a$lVZN%??(!Awr8K@S-H2P`Rl6d>u)Q%hxeZQ=u{V`5%SWPasP## z=el1Vyv_9AbibQ=vCW*Qt6lHas~-GR)E0=}rm=JupY#5`ug@-e8nah=*?q|~wZ~n1 z_gD%3Na~L`@q;yZ$?=2DeCZFLw}q9@eSBm4!=nqPPoB8^&>gFM_Br!K&F^<S{_rd3 z;N9sj>YpEZa-)Jl|5UlV$oZzYIE$x7b6&e2^45`4<Y!U-eKNG!-g?pbr&-PAMWK_q z?kzaKcE$CbE029;?#}(QYG+mbuBScP6^;}3|G2wa;6u`bhUU{B>}<?(-`O4swKvV( z#_(f`Wx?}Ld|&S8OuM1LR(YhmGBEATS8w&UFRL8qZY|D@E13OSzx}<;6c)?xb3PpB z`P5;vZ|CKU{1)G01Rr!2m+Ej@*|F99E;+CDoB4(D%h_)u^<L;_+;mjmVqxb!b&ZAe zp;~$U_mPKcw_kb3Rn4-en}7aHp9B6)UEA}01K!_I-_FW*!QDMCr?dU9i(Ogam6{i& zoA^Rq?X~87Z9kU!V7j<;-37^t#Kmm)x3}2*|B{j{-qW;~o2}RT@xI0DkBd9nYfsQV zckaoro*Rj~H|(zopYO@O<9+kIS?{m(CEoYG?at5cKjC!qy_LJ1{hvRXAs4gn`{lVS zSod>_rkCj*+R56>oI53AT^;*dU5DCdmA53#59#wB&uX(&I3F=}^X;aC?oUc~?Vo4< zBec-vnN?r7>gltSFQlI+pK>pkf$wJd^DovH<#(Iywtl<n=|28j?(rudy*elLb!}<P z+@h!tQWiz2vz>SXrk}WQ?Py~3L2bden&vy+|MpqjFH+%n{L7CoKTi~YtgUVhdk}uF z{t`3i5!al>mF4`8PF3xlnbi3C^SdV%*9vM^A84M}yhG~!mhZ_QY>)0wHTWR@fo*l| zVHd%F3l47&-?c#h$@%Lm&ocTQNzSj-c8*Vb^6Sg$J3sUOt=TH}ZxMf6&v%#qi|SVu z<xBo@`Mm8w)9s%!@_R46caT?`vHMG{Nx`aV&(*n}?u*Xli(2Ede^H5>mYRHNe~e|2 zF8lve_j7W-KYw*lN9(R(-|PIzO^Yw8cWqLV;QOBYw|=$-d)e+~+23l9eEoXaXA!GR zyvA%5)#6HtpLZOYYjoFJy!glV?zip7uv+^sx>B>RO-N1OVOR3x=kw(&{xdN!{Qv(Z zqS9h&^zC>lm#(`CLbsMW9@fl!GUwKACy^i_sqKcrZvp}@uJc)WL(_SpnPRYq=FD$y z%^PJ}l(s3lKfXEl%Ebly?pwXDJYM{3-|N5Y-p_x(>)!KS+n!d=+xo7QfB*0D`>z#q zZu9?>?bJE+Ic3>IW2a3kLl0h9G1GO&B;)E@uT~fDg(XRqX7|?btucSKYeL7XKl-%? z_a@%fcNVEjndoZ$eYx(wvr4t{V!DY>IXK_%`D6OmKul0lQ`T-~fA#cJ-O`g<jvW8J z`uNHyv57MuS}O-0QR?m9y(?C6{+-*aq-%OzSw2@B3Ya*-Agt~F-q!CjpIeLaiz1Gk zF<7MaZrg+}zb)UVU)|v0@#L(AALq5m<<aLq9NBZ?V%GG}kuF~s{Csy**J)Dzy&oB> zPd@2&Tv~Fvb;&xDKeMJZxSn{U&6mF@@`%>6uk4<(-4(`s=V$y9DAVPbWLqozDYohl z^Xt|n`KjeDN0Lwce7M~9>)8$U4{y)RwCD0XU-@^gEbol`7e7vF^tqat=lt08jPFlr z$jsd99JONEucx&o-QRA1fBHk`{MG55ir)?QpRu@P;^wjA{?dHY-L1cWrcFO8=(K2$ z>aKjld)n{kYTPYtcfDc1_Tz;e-23Zyot+<lO6g2<UD4W|I!bZt_iFRK-ZG8t{I{mR zZHsR<_x0*bD)vwPeWZHEa(iWsXpWsllGeA*JN1iXPkrNbV|8?mm#Ron=-k))_H)`B zme=!Y9^Ny1;oHg&=C><<JYe}Teaji!d9NBveeWo~YZuraecaw=pPI^}zl;-SnhS{Y z-aMdk;&Gw1*u5QHKPSIG;<vx!;-@P%*HRxiPB3|A(3_l-d^_OC%$B|JXYcoafBc^B z?}2vvU*ERZ?rJP7i@I8O#Cgu&x;*FR2?pZfaW}#k_Vc{_F)OUCR5o633ujBq+rQ4y zwHqfqF;SWKvAUshe}Ve1B)jW@?)&7bW~=@_7IRW;Qf5@UiN)3#^UFRab3Sq|`)1NU z@8G^SrWe^hM6dc0Hka>B?6$CF#*!b;-mjZ;vVGq6-^<p_{HZ)O+<LD-UEsdjE2{ke z#LmZ;pVwe5s{USiCG5~T(Pfk6n64`x-S$3t!@T?NMKADGHU*nzc^i0bQjXboNY5?r z(@&oVzlzJA#Hc+fh?0w*t9N{l|LP?@0{VTYPlleW{BVD<d6ejf=&Xftj$)6FcgNd2 z;QIfeG<a#eVt<sI&Yu6@80Rf#tCDSr3p=g7d9LF73!5usqaQSXzY()s;9sK1^|}uS zs{CgDx|8gB;NiXZ-_9JYi<-KPG3|Py|F7u$@F(o~UyHIC#XqaYUykicj6dmlbQ;f( z%yUnYogRe87@m7yA@%L;Pm4(2is>`nN6xDh-SNcNM{mu+Uyt|xc2l%_bUZKkws4Ef z`IWb`SRWbW{5xO0c2(<<Rc0EOUMfENT)6xQ!{^t0KC4B;9R9^{FYQxO+^Mm3OR^V# zcaMHzn(caqb-c&)<-1EieKT(tSN6Z@Z(Xupx!!_vvFWYE_FY?FZJO*Kc|<qJ&yyjh z`gB^T!8=aR4-Ou6XM+_5eLDRs7~}-P)A@5;?4-pq#4WEo|7SH9KgOWGr>1@0mt>t! zHl1ttdGP!U<vJ~Yj9LHPvNXdF-7{Zm1V+hySv$>o6Z^jpku%p7uIH<qYo4-C&n@l9 z!AZu`5BhsIKl{^A5#_mCN{3Cal6BqMxq(iXgz67#@0P8K*}MCh(woOT6RV7+Kkq&M zZQUJKxx^PHXD%Kn7Wx#i<CDOLRFzW`9M(_M-TdmTwxIsgm)!fBmfzXJHb1;vF~9Wv zo*i>|<~%VwZtkQ%F?Z=r+aK{Z2R&{veSBj*^}`~8LOsKcHg%uWkJvv8dYFBp+-k~) zJOLZmdve|83xBCj<+gKkxc92Ek@3M<yRDsfiq{@Ee3$((pQ7HM9oJ`vCeFWn<wm03 z0o!2bv{{mWqON}rei-(oS>x%`*{4cwyiS^akMEzM&9wR?wqsYKRv(G&=zqBLd8_fn zbj5><zHS$=zj&fKvFk*8LwM?<Z|*0y%Un&6ez2?l5dZp}Gv04GYIIiom!UKB=aNeT z?5m%@?q}#PO^)j`a+kaDTI}myHyKqyf6@6$e1ErU>8PEJ?<-iwQrawhUbELB?rN>= zVNZA471BQzZ4~_>SdwYnKc}^B?(C^OiQ8YeG-dNtIIJ;AedO~-`PJu(PY?Ior`&8U zo;d%J{-M&wofB?L)f{4~Q=29Fvj1(t`rof7td@CGoO0+}#GBxWg16IrDs`W~c(@=_ zC&(~vvA^gZoeWP&@s1zYTz_o|z5HF&HEI9l2gl7W-|kwG{pWLkdMxvMuWkEpeG#lY zcRNvHZ~wKE-;;M%PYA!G%eC_U!T&w3?Q`l|{-0C(CbP0xcGg_M+e+RIx9e038Gg8K zS<|7<9wYHS`0tgTs>_!|jW7Fi{H)tsdHEpo;dLD?6Cbo%-FMXu-{>EEXHwrk8?pS` z_lynI4zOD1{c|+?U?pH|RO6%cDrZ~i{2Iom&R2DsYaeXhUi5yG{N@u{f2}4)nRi=A z-rqK>uj-JmuhP1iPM_{9FT5G`AS(Onucf)38;U1>dz18mH~4&2j@%=wgO@L?WB=MK ze!AF@v#D-&sHk?-!uS`BAKf+tFNpfIiE)Q<U$;%EoW<jGldygMiGrD}8$K``DSda^ z>Fd!A-ODHLKFRlS;u*`8%5yp6!d?d2vd>f9`OWxqZDh)2@8^G*UL@YQR~f-x^vlQe z&+dojhvJPD6&S00CvTE{%=G_QUUadf&DnoOp8xEgbnRdFQi{1Q>$mCrueLutKloK1 zd#Uq<Iq|8Md%*Kzw>BB|1CpNcflu51xn22PwmFII(fwkp+$ymz*5Olk$b4SYHR*Vt zd(DldlT9{F;GYyf)mKb3VedWJP_tJm?V|5rbJ{$aF=O3tmYRY;WzSbTuJdrd_)G6q z?}0h*OIjYOWFCF_JLW{?+eHt0YuTEFzG)qvKdIrsl9|3vO2u!pjtYNZvi`bicC^Y9 zi`L&a;}4!#8+hCM^`^QD%>fU**UYfi6#r(R6SMm3`$PQq_Pe+*^h-a*Q~8#$w(@4) zYmo)&nUjp(^)|&Ra++VeP&H%6=4(>54Aur$?{n7ej4NDW!(8j#ce>>A$p?->hwn;M zO4Rvr@o72yD^9yvJyW^gMYTIkgE@XutG|pIWB$s%d&lNC`X{N!B+U0H3_Mx3<cFMn z&ZWpF2Y;|%e|u`hoo~{2_eQ8I>x3IK$ba4vw?5k~Zlk<LM!2J1<%c6z1!_I&tM>?U ze?Gaqqju|u?w+XPWSduV^H<j<h<u9tbm{aXtxutk%HMp}dN6OI+5R}5dr#hOk~Nj+ z*l4oyt>7Qy4Ta?)7Jm-SR@|$|Q7d}?^VV-Zx8!xJH{F_XZKv<l&r>e67adc5m)U5u zu0{XVJBEFt`@3@v*&LRgeUG1My-jbAm*fYg^A8W-2>1}@!CxP${UIyO`suC0Gta-P zM$QUX)SJG=ja#tZ(BAn!!z=aMZ`I;C_VI4)+xM#L*PZ0Y6;DHj-(*;MN$gPnEEJWr z_ki-L-@0;#_S^FN?R0mHFY`O_F7tq`^QPS|#Cn_K6VfGK86^A6tl|2VWn}PY@4ZSf zP7lwj?ZQ9QbE{LD|89KWrukhb*w9{W<Gw!<U(+}468obhwMy>s44yeQ_tSs2eyZ5- zv|jv?lbd{y-6Qt;CHk}e^6WWu<KZ0N!c)8VRDSR?`#SsX)mh#%{=2DeXZ#@`AE0q= zS*@dI<b#>bGsL&tN)vs`_~~kb@~2*l*2sHHl8=iC*Io&~xP&wP{DSw7U3C1VT;^-c zkQQ6lJu#&_OvUZ+xwP8;geUg-{*TUYZpd!@)}H+71b1I?>16A-+WK=&80~2NdwuIP z-DS_4dxQV1PR@|O^*AcI@#3KiN4Y*%tobIs@&IRLq?xn2%qQO|lS3!2e{`((UvY+g zs9Dktp)WU|)U~d$`m}d{_3f^lFNU?6>$go`#Q#v2XMZT4^^NE?`|}t6{qX#4`{I?c z*UIm4zF$0_Ghx~@W%<hV?~%I}$r<*Vhs<w?`L<-%<H8R0!oQk+Efo`|+*MzFK-%t~ z+EnHPoW*OmHMRWO`lsWM^@ASCBWpkB9NhKy<h!*8boX0rc+6Iy5H(9{J>MSAwp;V2 zvGM)h=3C=@-qUi~&Cl8s;@=o|KYe$3$A{^5_j~>|%{j-l)~f06s@uQQo7GwSs{EdP z`IGSM_XFlnd(ItxeU58ZKkr}OSds6N=S`n4h!>Fj_0ryTugBf`u(wh_x<9YGyKTQf zne3FUb{unz&ux3<y72w8-D?80UH&U{3F=uh?4Hr1dTZl@{Gc@=w_SeknWw&5CeZx# zqh_<JL;B3;(^s=B_}A4Ik$P3pZcj?(%uoyd4~wjpcL|1n`?&At^o04L+UDt8ub985 z+`KFEV8Yy=KK`7gvu4|z+Am#~u)@0LdZ5$Cl-)lk8Gk#OrL(8IX8y7V0tQ>SErPnO z68r5Y&AHz5aoKaL$Bh4P-Z<{L?#~Y43co9-&ek`6Ug1-)@7*rBFU$Mcj3i#jpKM&3 z{8?jv4%e@Y#$WF9SXNy<93RE!SiF8ge%H)O|Nlm|(`WjIeZ0lKf6dQ58oYHAe!jdo z>+Oqvi(tNtjg8!APp|)TePRE@mEtQl7uv14%%Aq^VpaOHEzJw|ai{6Mp6+J9Byv;T z8KVzV6{1u#RopfnTiwCj5&SAFe`fKC@NZKmRle)cwyg2nYb5c>Ph6+M`)!z*c)Y9Z zv%d!FR$TuCU*BlUWjJr}=JL$9U*^nBPmOQ0ni2IYXbOMzPxi7m=8XNH@A222bN|2K z=+#f}m;XIK<)s|w2leffr2|}l|84)%dD$S#Ps*-hedo8YWv$O2Hy*e0KbrADEYoM= zeXe^duG;=#%5o`>R_?vsDBbt`OXSVF7rrO2Sj=KEy@tzZW2>A`@9)jA8~O8}_8<PH zylzh0MA^g_-(Lk8N4-7RUfZa--Oc{c&NWt_7Te8R{z-0aSgXC~lK-1*K5$mgep#FR zK`=06mT(nU?E}8+zw;B)ecYBUXM8IiYHZ)K?9jTo-9PPKoVE<#<K9tcUC%Xd<66c2 z<<|AwuNIxyXuVmu@WG8;ti6u=q@!HtnzY9)xpu>`!zSh0Y}b1_3+{`DsaMQfeqVe_ zi?F_u{pEY}L=WWo{@%&fcS6|j<?_gL7VZ<CbR6J(uzJp!CF|n_^o8WFiu?ZF-<mqB z|G;A1OP=EDm#P+oJXpn0J43i$Gd)R8J#W=dsWp!!@7~X9-}9s``>U(MyOdoA`#u>w z*btOsD)f7an2(l~=kM!z)4316T%mmU_1gGL?-jpIcbcDA|1CkdT;hYzx0CDs+Od4i zb}w|XeD?d#jg>q1&G}ZUeCFj&n`Z|Tx657eza+0z*YxXv-HhE@Dsw-bF_m9y_CT$! z>{q~t>HU!&VO(FXovPbWq;byo=i?_`+nxA+2mc6>{PNXD^Yt{R5ApL$F1AQ~n0kJ) z^y`~j=12YYyUz1bC~{ZthGoycaR1x9IkEj=;?y_s8~XBVY`-i0uu$I~UCLI`6n@N{ z*Tv50nwsv;-siLO%KiG5KmUGto3(q8+zAcqdBQC=99Q$|8RSG-`e!9}S{>r_%sscL zw$SgzQ@0l<W&Z8`<Q%oXjhmG*;`p@Mx%*}u`&bYj%V+yM^_Jn&gzYyJUT)>6opf`z zOzGyV6Zw9{`aMVg+*aNd*EGLkm9Ki6vK-ILY<+Fb{$Kmnu6Ek@yh8T=mBv3R^Nizo z-0PLB7AbAz`*VDsyro{_wVO8ei@&OGod4m0E$3V2t$wGsGKatUs+SXdWbeDoXLm)U z)K6Yay!wFo+h!i?(k@~7M;q#x3nrB<S}bqlArU`KZm-Ah|Hr29E0Le9a7^t%<m-EV zd#Atn&hL6Yas7qqzpfnN=4-T9(c1r}|M<=Tg|#b+xJw&bbcL2TEx##sbei}De^0v` ze)(=OQ_ky7<!AcOYmyy0EpgtnTddO`Z}{JMK~t>wW8IpV{JR`iOp}+McD}5ce}wgT z%VGJ|GQ3f#QY&qLZkv8lUOJDjE{oaLw)EbScTDSz?yoHhUGn?xoLk}5jvjWW=T-`G z*?-+@6tSK&=1eX}or!qGv!6Ld-ivK6-<=xD@Zb9EX1;jdd4fHnJw9#wr%s!l+xeD- zZ?)U0c@A<$hxw<<GSxX{<sFr2`p@w`W&M{FvA}t=l$ZMMKRoxD&Dw*O&M`Nu56jz3 zDo)BO;d{F}_f=ZnlCL%f#j%X9avJ8gmT?s9w%zz}&q9fRXGCY39;{#VspP5N58s;G zg_g~A`7$fsZa=bTj`**}rC+QgC$9LX)H{E7T&MICP5F&4w=l)cP}V*>wIR7^`~4~W zdp_=YcP~1E_5Zca=WUn#-1({9uFCJt>sY1LeHDhe&-pjE)$h1GHC6k?&XCP@H@^D) z@Kk%VV3tJ1<4!m6=Jx5Tr+n-9>L)(rp8S5n{)aE@dS)^0F>sTu-p#v5EnwsNKV5$m zmN?{J*E^CvE%36^i<37m*<2Ifu`c7o8(sJNrwwLaz1q3YdC`k0=Ue72dYiNKdU(P5 zCD&@D>r!_AI%OQ7Uy<LtZM{p3im=E%JqNk&P5bZsZ}~UB*e9!lp-{-)g#W~npZ{t< zSo1!ZASfTTnW?n7X1n%%@#prs=Nn6$9~@hw@$;h8gT}q<3N9L4@pSZKj_0j8_~mZG zE@_K&t#8>~3G)*_OepMMS^uY6e%m7%M<HQ8$sdXLANtzsGp{dZ_F2Au(a*2z?iosy z_O1*uEw;W^Sm$%!?e)T&8@-F<BJxe$wFBA9#40z6v>onuQTuWu>&4v1iJ?_<pKU&B zI(JjVi?6EdJJ>7#eEfV>C`0~<;M^_U^N!bj4O#R<<f&C#<%K`1)@90hy{<Z}yFBm9 z-a8x5np&MGKfCi+zxDhB{JGg)TP~{4ihb|5a_RHZnM;<*9B~YqIO(tLlUY0eu6fJ8 zkL%@`q8E#wUsy9=UnjGDznFCW%vP(3@t1>_FxBtt+q`8)YYpd%G~J%2d(6pO*1d6- zy|iQUj>+@Zt6pDn!tln?Jti4dY=4X1?Yp{;@qEjYXWK#yw*JoPoB7<}*WTo6=f*PW zHyxd4gB|vNx7@$gRsQ+AH44hY>{0nw<JG>oAIiVWwAuQB`qSCUvh}X=cjUf0W(D}X z{@loX@_6I!6Nb{$F8%v@cd1kI74u1Y(HCE|TEz&h5O4o{>gSBZ-<5V3{G0S&;qb!y zuJiLvZQUL#S1)yy`uS?}(VX*%5BdbJ8L#B{8E#T}olEq^d$EeM%VyL)zx+~1Z|U=J zb=K+J2im_k-8DB;?)zDt&TF@%bgPz;q10c4$M>f8I9AE+lD5Cmvg^cFX-g;RJ;ruB z-J)NzzM8u5(`tzqCre8`fAalQ`qZ=Ko#3Ua%xy{RZzsnevCU&$XCJl4%&X>{()x97 z^Y(QAd%Nqz^p)*(OVcL(Zjty>7;{f^`RWhs*FS|He!f9D!}W&Bdb?>h3weAxOzMpG z_kWT4_xtaK`}INl?WZ3-FJOP~%9fk_@~#_`b&AAgHv6Wh8iiHnZnQl0uU5*F-||%K zP0^$Crd+l$x>Irg{=EO6Re$EzpPaD&y}tF6`QPK4?!TzNF@K-lLHU*cWB%{_cR#Kr z;7;~m^UCknU(0{)iz|_J{{H@T+n>``E9-y!efrbj(4W6?E%ws6Z|3IS`7&qk9$TBe zb8YYZH&r&jx#N9N!S{d9WES5w+bwfuF2BW}N+)4&et+|7WB&B={Pp?!w-=QEJC?oZ z{nNL5ZXdgS@Xpo5|MT~n-`)K?-Z$dy!v`;3<UD`l@cqy0U->sTUOare?ce^J2l@Q} zuQ;OSFI}#`J>UQ4ivwT36daWHx$ynVpTpJ4<@x^U<@)K?!qR^pe`fz##dj~_O~U?j z2dDo|kGu8e!OO4ei9c_<K0dE@{}^xYXMs=WcO*VoekCwqVS3=nS@(+S=6$&p_3(e# zx&Kq`_Q&o~_!j@q^7OKzAI|%A(@)Mn@sQ_l+vI=8v(0|rmoELkcjES6{EzDyAtT}0 z5x%+G=gEd>wFn%VBw(rHI`P?*xTPNKL6%$QSXt<;bXodziWApLm#r;Ryj+(G7f)NH z;i@=Q$4fn_bGt@+t^NCNvDeFMf8Vyh_x}99&AZn<HN0Lm?_<wl+joY?mT3Ip6gRxG zKU%YU|8}Em_4%T={_dT+`G2+c(=X=N>;L%v{cH37```bM`s-i(|Nr~{`EUFx+;&Aj zG#)7b{++V_{`sIE8h_(X&Oi13`P+B5x9!Zo|7PdS<nQtKg)OcAt1RFD<^L4rul_|# zKH9Im|D5OF%Q<)U@BBai{MY|~|Gu|>X20{h{I6Y}f8T%SJK+8-{+;Q8!`;TUt5)@i zXRP*EKJRIx_|47dc)xxAy7*?|U;V4)TU|HpuK%Ha<@Eg&-L<=Y7A;TPaB=nNPw%!Z z-CS=|wbr`1erm0Ham@OEA$EHorEK`}D{7k9@{*8$vkIEO?VP<{Eog00KY!Mz;QvAA zwf5ND6_lHLWSYym(EU#*A3Z0#ELCA^TQd9WG~KVWtJ?S8Gktt!{V|zs7YbheUVDl& zCvT#Cb$)`4ZuDZ2cbhf3%jV44bLO&HXPxjp{p;q>7545ryZg*$!`WLiw%n+__{6CC z`uT!qMuk?^YF@vlz0Xvv-o5+vuM=$*+t!8suADHp<L`>=DsT6`XR%&)&-F(7+(TBq zFH3x5CZB7Qz5efw&isS#>h~KO=M^hyFSgY+cowWw>%UJ+rRH(qtVx$Q-@d4o<lhrp zy7kMC;$JsjoqHd4(ER5AEBC*b#nh?VADw7@fOl^6t@OjK;W2NQOBu~O-Bm7^HFx)f zm%Q<}M7HG!PEIb~mT^R)^x5t=A6n+}O}n%8#PY~x_A(a#TK^WZKVSE>=vDRfBBO0{ z-jyxamb<v@%yk1ZrQ*qw*O!{Q2P;lJ{&dQB6}zmsGlg>{568ZAo#S}ur**Wfc#-X= z<SzHKMo-<Q-a40MnSEIEndQoT_p=VqY~#CHX?eA+x@4nkntPM!^o^>e-DgB?&uv+~ zd*`ED6?&PIo}F}!72Y||F56zZJbRsUbmso8>}P#@B)5G#lc}%fRF!yp3X}db?fT`F zX&c0oXB$;7{d&jt%-ibdX=}o69Nsg}c5QCJLUZH9pOgNG9GhLacKUS5g>TR1tlPI{ z@qzDYaciX#A~Zgvy*rov=E=1;saE@ZPa5xkarO+y&dSj8-QVLY7n;4j|2tZ8zGeN> zL-oJs{u1Bcz4fF2k$#=2*6TC0YWII!x2)RaX#cCM|7D#^k8BjmyHPpqQTx(kQEr!} zWaeyeS=F^H<lY+FZR_NIzqkA^A$mS&>n=s1(?Zj#Hh($#y;47N)fKhn%NI2)-620U zCsDxn<(1&%*rJTC$ijlqY)fy$g)2*^cIsT+^W#O=djE~_hmW3LJY(sqx@oQ1Pd81e ztb8%Cl|QmeDt75g`PSdF*O#hHdHCIEdv@V>h3)66rz=cbdP#oWrcI|3HQQ~w_OJSA zd;Y^mQ@P_oj@P$&^B=HX^o!lu)jZPc#h-_v-ZIx7SD&xzPSec(%pd$M&GFy2aN{24 z46l-skH?>6o2cFsyrQdh^s~XytM`tYJS_{-t4x*j{W$H2w0O*tm0AaP{L{CXW#p0Z z!M;qs%=g#Mx(~s#PTk4;Q^oN|>A}t1_$bfdkl^fN50ocd&zxm#F?m^w^;@G{#rgTE z74O)d1kYdg(M&wC_THSS^BjWb_@!TctX=W%-nO?V^VTdE+5dM3&)>9MfxhPYnYGTp zB-0PybAGy+NnX%;=5^-<?R~e+mma*(UG?pP0_R7eTem-#25<a-{AK<g;}5gv?=7#h z^XB|?w9xQExJ1OJA0IeR^v<>Vc*Su}wEFj${yEvx>I{@w@8>V&i#X^%C3|u8^Rih% z{kD|~t2oZjzrXJMzNXsu-|pM_{n7Y+^z%>O7k9IYN?&Ns>iX2d{jvH$(4>w>x1AUC z8`z)zdd>AnW`U`xiTv*vJ=r;BqS>jx&Q4ru^40X-1%LU%M~}GoMQ}g7e`rSg`uvMi zmR#7IZ}H^Sj-H&F$&8k1Y}fMFZ<^wtx6kjp?liBQ_}eMdTHjadZQZA8BKj>Y$%`-S z)Y&SRJ9S5%KigiccVObV)~{*C5B3`@eR}WNcE$gB0(S%ZemrS8{r`w<$fS#XMh|v< z+0(m{_0P-4QO3773+#9y7<S`P-BxA2`89IM_wP1^PG8WT@$1#1E!H|ymFJ3md1C3U zYkFaqwP3|(&iiJXyBn5G%k$SPTGjT)`hIwnm{WhVm$b5=epZ*><&eWc@w;wSKJ4w- zU+($nviFbJ&x>Mp|3nGISQJ@3F*WDx*B9D+<%*zjTu#;5pjWI)x0mjiUpZ^Ls@T6L zbN-y0#qfMpCAYoTs)f(DelD-nU(kQ+mE%VX@sxcgwi9n$Pu=b&_HSjEK>7Jy%)1w# z{T8Cmpnt3Rtnh?>pT0T&Uq($Us@AE_<NFdjdB?vny?35lUIlQo=1ESkE?(xym!I$P zi1ShXsnk7^+<%_zsQde~V_B2g&i$Gd9>MeMlY)L-SNI<-lD?;oVYe8M`HcDO^=DJg z&sO$()OVfPdE@-^c{016>-GLAySKjcPr{$Y^Q{lXFA7!8%Q$>~iob({Vu8ZPjQ9$c z-;%oXMYxOp%dc9`)tLWp&A-Ec6Zw~#e{&Q35Vcf1b`IO`nZKv!+B>fc$lP>SWs?8y z+t+*S`Reo67`^A;-@V;$*G>74k9ucsj{m@AV_==|X{!2x(4^13e3RJw&*@Z@$o<rO zQU2BP&!R<-HlE_BxvU^&7spp0)V=i_Te5xrmlHd`KG0nla_z731?L=llWVL$eB~>u zCK>%`EZ<mq-}XrLr7yJ$_b1FxahSO@P4CT%%$T^|Jqx0^p4zQz-^=Z%Ygxry_+?La zG^aghi+srb2YXJG?3lZ!W7(SN*0H^9GG4allY~DgcJ2CABz|!2U+&jCb<VMFxpUHQ z(MqQ8V(P9(dUx&l{5R*rq$S^a4lR#Sif_Ex`FGFM)AMI3&cA!+3cG02aZAbH(e+9D zw}y9ysC*DGEBrT|^M-oHHNOok`eC_Mdy;Gm@}K-_+1GD#>i3O*L7au6>eKRU+xI+t z{$$GWlmqv#b+6Kyc;BvQ)4BA6htE8-m%e&V@SfrIlGeDFxwp9w39i4ir|av-1EopM zMb8vItgo7I=ZVk*`#o>39P>S~`PNI`z`hm2SDcrw`};t6J7?;}+3%X)e~k{82z_v; z>KiNn*99K;wC7$w5oGQ5YuVf?o;~xc?T*QPEWB|&b|Qo2vv{`aqEnmflk~iG3i=(^ zt~{}ct4No{#`ek96XDO_x;;2k6EojIuu$`_Pw!98-B%txGs``)Ir`a(Pizl5q&L60 zpnOC5l*QjOVs&eRX7Bhf_vxTj#64B9f1+_V8fESAE{o@{i;Cp@Y4)0JA6NU|&yVeH zALd&)(<jvK;rx5rkGKs#Y~TOoTyV$w4UYd=q}_w<-e0!YI8b-$)U(-N1J_)B_w5|J zJQsg%nDPFezqWoGUvthE)w=(q(c*~@$GWdhaow@8OLYa+>u%XPr$3qep`qU`-DF<& zoboEB`&JXV<A2_1wf7a1@NbiSG|#Y6+*8gk|K&F3cZc=vSN@l<cz($&*R1iLR%rDf zeTBM5#l5?-yE*vgpNs4GQRLWne2IX4p+oWU=qIw*?^YCw{ZS0Lev;R^dymWy%^H?J zg4b4FUCq76sN7xp4C}fX%HeWzo$symmbI5>-?wPi<Tt+-$F*GbFpB2<ujzAgx95kQ z>K6BeS7(IGs4{!C>)^8|j8`|jZ<^kADeBR8y<gvauW(LnXcoVfu>VKT+tYVD)@S^w zoceD?w8-Zd9~yH{Jia$4uzkXMABW$%kv}4DEHQjhq4MFy+ADk5eoV{>Jo$m~-Hwlz zX>tcdw<~Y@WcG{AZC~I;nV(CH{zUxbKP3L$Xqv|2b02MQt;=`(E8fSe@zKR5JNWun z8|HJedFSV8Hdh#(zxykFiSoK*e7a>TPS=Qj%~We?|HMCU<+o(bvxgG0_`ZZ1Uk;b^ z{cv%mR<hHpp38abV~(u#+PBWW*DCm^%!f&?f76?8x##R|{B0r={of&8L28M8)HACm zC+orkUG56SNKL%m`6uzxTxRpuiy?)lS`Jt*v3my^kTUusurPH|&o9lwj^Y@GooDX+ z>gR4`zqsgQ@^z;C#C+4w>8Vb2uT;Bp4{#@29COo_{Ox8MV<XdMwY+YjUi*jB{*Kp* z?))zeTHz}CsXeM7sP|h-E%Wspv89gv4C}4c6SgO0Zn)-iCs-<}?6tucFL6_qWy<G| zu)Fb9G298Xs@>gsZpZ%CpT(RT*FO@I_5JfLc#9(2_f;D0EXNm|<JkX;tw80zIB(`A z#h({0F2BweC+ZiSoaFgS_S%I+jz=QT!Y{7quHEy~Px<;pI|svu33h*03xC@AI6(K? z%q@FgF|Rkwzx?U#!S+SlyWRSg|AgH4KP9^7;M&=fc1!*ETDWkt{p5dNF3itww^gXU zK5g^o1J|3<_Z}>B`R99_TXKp0Tyv*X@h<|^?_<kkK3&qis#nXl@2I8x*XqFZquRDQ zUh^6Fb>9|iZ*ZF{zsvNa>ZfFfqb!2Iv_H@MDXg_1{Km)M&Ci+ZwKlJC4w|4n=dagE z-Kk%U)BjvLpngSK{+{KBeWt&Q@808j@!i5GR``ebD{bC8J;hf9w`#jynEdFO<k5Kz z|9Ps<?>*CY@BQ+azfBf9cHZ4%x`FrC67`+zjr&=IjOVi4Ii0;sl;^-}p6uvp{Z&4a znP06r?ZoxvEHgz<9?yxbKWKMiWzl(ax7vk=(qHekXn1eVkyYzy8$SDUf@XzNkfHu( z)|cAzpPiO%m=|*G@ozV~4aN0kjana;27f;6JzIH?__`kovQ^@)+2>jHRpwp2RXG34 z)kj<9a!<t9?fm*&^u^^F<*)P4H2$v$u6!Iip}l7FX+fhE^FuH17pZsIf4+iET|?Pk zW2b8I>hgzw-0S~;Fj=E6Y?8)!|IpgrTQ?gwypMk4YWd~mOL^x<K?2jYRu}V1o$&vd zd^)-}W&W;6Uy(OKCqKxTvHiGnElW4IW2*V7t0_vqa=aEt-RJ!wBr<z_XzRU2CXaQ! zPMAMD+^GC+p4%M@$2%eqI?WfxX69QR^j!LS<K+#PH=WV2XInjS^`YOgOZ?4(49XeL z?VF;`?)csy**aeH!K6S*qsu(sId-$f3bHYqpZu$D*AO@5)hEAhhX*&82Yprl)NOg^ z!wwCu3R~+vTW8+*`yr&z>X*d6ye-+OMi1K=JD&$E-xqa4tJ3!HKaZ+S9Y3n~dHZlY z@jkUE{W!z&MelkW;~V7*Cufw|tjzu{ZIjhte(?nFN~a@}3+GlSF#Xj1RwK8(&+c+! z;qm$RJ^$ahz9fNRzsudz1_BHC3f<-^ZhGMSEUjdN@}HO2m&s(Sw8c4Jd%i1i{)5u5 zvc_|SPx{N`H(PwN7T>qq^;Jq%{1c`>|3YhDm>56stN2@Usxke**FExr(G$yk3Q}u~ zzO78nm$=pOZ{@10ycI^TSWJH&?_)gBs!&kLKL5d;iYK?0Zis$;xa(WogOKc9SAUj0 zalX-Z_U)<_>U_<wWS2Ym%g%nXYwMABeD;5vf6P7p`e&WMx1#XvA~Pmc?A7~iz*tsL zJg@%CSw$QBtcM0auGbt*lGbmk-|c)!R#WBN`tIKgmR~43Q(GQX?!7hT+N3|1PJWU1 zt8ghw+Wy4WyH@t@4e>8*-`dOGe9m>6cWb}lowoGX8>9H*N_Vth-tk?a^3e6Qfm7Y$ zmCii-f3Y*&F}6RIf9CdgE_#Lzc3W@G+-JyQ&vpOVUW?YBQ@Z3frR=l*_5Zxws^Ev$ zZ%uF8#e1Ot@KVPb_77VZy@-5PcO%;LfAnvcBhEh#mRC7QtgOC%TPy9sOnIwr)zXBx z4{d8_?5~}6g=6(W=|i#6^DLev-dCG1?bp8HR)0?j>pP#h^ImB$I@fyk((k2AHfGf) z`eyljShDl@<A01tUOIiaRC#^j`&E_N&($_gIeJkw`lk4b$Kh%^5v+Cm)(fA17pzO^ z`M&y_LcWCcc5%0gzN!@ghnfH9%u<LdlmF{Hp?d4-qz`p(<)SB7rp%LCu}ENgM{(9M zeZR$i#n!!hi~{{#+(a)ud{A4Q8CS^nq(<_F?uE8GA$Pyaa(^yf`=z&P&Y6Sm(U;cv z9s2LDJo~Yyyj{rQWb1D~LnDsxxBWYF;6lE<$G>&&rrqSVJMmMr;>beA&jHiVZV`Jj z^U2}OleW(&c44;?VmgqV=--rAG09TH`ubt<8qK1$@t-@d#OK-PvsSp~-2AeP{qKgp z&aW?p?&ufYtjc8ipdhmER*a_7pXoLKb$_YdYoGTxdf{>h+m*RGAN-f5Z^&F>edf@u zlW`Bq&y_B{%KsyHhmp%J$&U|I*3N(IIsd}b9GM!PKUZ!>2Y40eU#PL=|I77wQq=0H zE|08FdfgQN^-hm-K?D0bhso7^Kecwgo_<%M_V%QknM?EnHSJ>4%O?M_ao;Nc#%D`_ z!8M0^9i7xgtT)_KPki%fs@L2<^QP;}l(@ZDZ?XJar8V=5t<2xh+ZX?KZ@pkIt&zSh z!%p?Rw94_4gV#e}t3AtAsonSIOauFg`77p}*ZMlcx%GZk{vG!B(Z8$r{P*5xzqU@U zQnTb+)WW|lR~|0e=KeytvhrRn=Zwv+_WJX(m1<p|b?#y?O5ewS_DxIt(b~mZpLBWH z&rK=eD}1CkeTJU$`_QtlU*c5%2DPp!=6*G;;KKTF%@n`Lnwpbom)>vPdVOt++?}rc z#jj89*>dQj4sXp_^V$!IMt`2AnJzA5KUw~8LbBF!1M!%cyAxcW-THGvSMuqSyfW=f z?f`bJu2+4H<we_c3hy`6JURPz&wkdw+cI+EpEJyP&X;fWbq7Pu({JXTj`0a^zlWLd zSCszV@#R_EkKU*(OBL~ol&s^Sw-otz99tr8s$y>)x+#3JRps5-!ZWEq&aVEtf$81! zlxn-}N}r1=tFJJgsny!Q>iSRSeD%q!o5K#BuanyNDs>6}q+gRi?{s?hN&mgs<XzP< z?q}PcT)%u}iP#Ty_l1tdMg>#tJo6_qpM1~#SUF_vg82N2bIdB|8(5Y8D)ImEcY1r4 z@yqn-Q*C|JN?#toz45)m{RhVyUno7=e!%`NSK{&o=ND_O?fDYvE-v=_Qpk>_XD2Wm zIbZx`#`jGJQZvtPn2`A5H0vp5>tK)jv-TY@<h{TCrTOz!#uer<$)CO}e7VY&p0oGl zoO5&c7X3~)n<?)<JDhR-SxNQD*RNd;IXrcTmgIxORwZk8t3Ud&_u%q!wU@K|Tzs;c zWjvpn|1}f3?t40RQh>UOZBf={j{V}Z`8Ra5&sTq1=jS5lviD70PGhl%|JMy|_6O@v zJUkt@!rJI|`zLLW`CHz3u9x)HG~wr+!BxYVtaVs!vgN;@45FnUvR9rc$T0oz)Y!)Q zko=BIMYk%gn9l!c-4ew)bFuJs{Wy;OhASftQ}{$gr0Z_QIp4Fku(mk(zlr1Gv8oT; zPfN^N{GWZgkU1;(<C&Xts#eWlunhkqyI*-fYx>mFCvA?*H++7Bp{YFeY8>x}rVpWV z`C>1#r;7M<dBj~ywJ~zA_tVUeyFA^y!e4Rqybr$NKC@-c89HyD+OJemrCBoH`4?aC zNeQV+)tsm6cQySwIJM>0JcUmt`8q2Y;##x0uFXGYGvVEX2-V&lGd|zG$^C%&+1Uwe z=T$zj%{7=^F#FE;gq+>-U%pA-pVedOo_;jes%6jfpeZZZlI>M@s|T!YdGI8`=S||7 z|MT7N3o?mof7`Y;K;fVNxAoC3&#wBHF-|w^e<E{Zy$(~~kC{`I#J^<UX0zhC&uGIF zZ=3mC{R6jX$&wtlACayr4eqy|+1&N=bxh#&eSMajzN@~P>NH>UFT=k{XHNU=bGhff z?K;cP1Myb7t<UdQ`s!SFI86CNj^804@1O1`+TU$BT$b`q!cO@Q%MaBTKBsS59ch=W ztpDk9>HpsevkPpeEnBBKWvle{2|q0#s`JL>bCz_<aLRDR-cMi3px-3XxqZT(_XhS` zv$-Gr{}=K0QN)pW*ZQ!_DIcbO+V|_|-6yqO^Mb!<d||hIT2#u}(I0W~t`>joo|lUp z)$ScwS`czr@qY4#&4FL<sUG^@*KQZDSaV(SU!myA>dSS@GML+Mv!!0z^|hma`i*Za zpY|_{*qSQxYUYCvElsvd{$0sk+3mD{#hTx-cg0HQ|GZ-N+~n1|a}RrS)aPB_6CYV8 zV6(o|bN_wsJEx~l^qAyw;;_ofsf#a8uPLu7pLFJ{QsApkbsg8Q&y*AEpAbIjrrW3O z-JWxE{%Wz#ah+2muyxbSWj4&FYY$CizozY%A;V%nMWWt!#;<8hyWC~93|aM!`scf@ zv2qTss&xKm(Ngo^{oW1d1WNm7+g0C5`4kta9&(!dFW-4Z#f4g&b&F+XYa7Em|8kT{ ze`qT$Y}~2z=y5=e=^Ms39`)H}v)cA1CZC((mJ}Zl)i+1GVkXzQ?i0<nS0vTG8T|U~ zEB{AC>7jbz_0>P0d)D7uC{oG!`|Gr=Pg9lV&3Si`bNPXCC9{AWu6tq<x3z8B;+u+$ z{i{Nq&c9Q>K53$T*KN6~Rg3&5|LEiSx%!{(V$)T60{;p&2ir6KyjEVcyK(l4oo#Bn z1OBh8|7^c~1?%sayCp#vw|BmaE3j(%87MPhvtR!neu2ElyO&S+XKv}l`J;I9r}B<^ zJ{y_KCrTRjyY%}k?|irMKPv;n|Nn2pt4*%H++8266>G2}aPck0x2M+57WrA%&9$_{ zOEq`d@7A><CsSw7Qd0GrVNj+Q*iqzrW4DG<&PyfVTg^(IT3u|#cJJ3b`!nlY)bll) z&&8*&y<fieZS4K^&nxdg|5Ryr{<DzTwIzivtsO6J@9MFS)lp))T=D;R#K{%A`r=!Z zl3v`cJNj19`Q2Z!JJZ4sPw+U}tm@3=awIrA)mz}pE$;TtD=HIa?{Tbn+t(peTKn1k zb#dDUVcyA8iY1G-JbU?Wy1DC;C4Uc`Y5RTS`{u`YCsry2nSXWmtl8P2u`lRev2#zY z^pkUI+GVWO0@6k9{VW&$ecU<jLaa=klGry@A8q*^x=NC{&t;d1bb7q{`RhDexuny+ zZoh1s!vdkN=k&y?-l$KFeYBxQaAL^I-YRy>+T#xE<>t6MUGwAFeNy1{ZnoV=XDTVl zT{8Dqo2JO5`upC$c-NNVZ5J=S-P93Lea^Fr#Wu|TQbr-yxBeL=x!=PCFN%0wt=4`R z-oK|UPR6<7@2k3Qp%3%YM2c0|{^^GV2q@`A8XE5vKlpFb8QGI7Lnjpf(=+}n<$UC2 zZ=d`m$xEiUQ}c^@J2b9VeAQIQW1WAy?p_4n&fx5~K3yB{FZaD=_Q5;m*U2j^zYD7U zbJo^sDJ?eowK!kNj?vic_zH2Olt)`tET=~OSR8L?^3cxt)w6eZ7K9$+c*iq4X8$8r z=Sh3zdjIhL=Gt55XD6Vjq&3+~Pj|nX(w{X)&ED=eN_jl9eE#`=$0jfa9Y6KI&ti{2 z-rA<QdoIa1x@dj+vGcV0f5|7_MZWy;Ew;J)q>U2ihnOWkS|uPDxHV#J<zvN1Sv6ZX z9FzXGGv%Bmo3(S<v-MApDd(AQof=dmvFSi@{1xvX*|k3>O}&}g*0c9VnIFTSeW|BR z^=e!G#J%B8ny7y%=GL+ooIBsDTQ;V4)Zc#lYohpr`<AnN<?9dcI~wcz>gtK+N5{|F zJI+6mclxPXSI3vh`sW+wspn~w2B&sBo8!Q&e?!&a+TJ|2{Z~sqtF2q|{%rKN3a0Z~ z{cK)S<rLP<66Vgo<F+R@>8;t^=KG86_o~GvdOWwh-{o-Qu>AdNi>kX7Sp%;%nQ%I* zX!<=1?ATp-W5%So2Obs|EbK)-x!gT|R_vod-1|?Fh0MQu=NkMn`J}#5Zo_Yvr*X3L z|G%+%V#Olf>~|pV_uo`5!;;=la{K2hGJb0koUZNKvi#B-=YaBG?pOc*RlI-GaT@QT zI-#Ydp6r_v?|Z)WoqD1^uHgOB@Q&t3my<U?V_d$c*75H3#>1A=UQL_3!oO_V-AgP_ zx<5?n6L;zISd#LfSM=4C7VYmhtQGq`n{}Tg=6`0@E^e~eApPxqkN@%StlUh`l;5w} z_I7F2jf3k?#Xp<TXcHcD&-9(#zx<UK5_oL9XWnDB>fnB<`~CNe{vF#Y?-lVL|7|BZ zS492F+?wAhtPg@Nh^*bUtx3^YuR}LV(0*ang|uA5H*v-nqJukr{mxNX%woNT{|;vi z-yg5@oR4@Dw=Y}2JXmb1{vM-H!LR4irkhwC$S*wE(wy00zTDa{DOvK{{M+011UH2G z<)1(7^PqOAUwxu(!KZJZUoDb3Qs`V@!)?QTY}KEDP=?<&wQ4&1TmE*PiL+RIu6)Xp zooDkI>K;j@^(`;mvn?r3?9=JIe|d?XTF!4|^QYZy+k5R|-lKQb9nLAYdjB5SzNBbF zsO}S%G$+&42a|hmuGy<0`Ddbv-*1NBmCE^?&zZs%*|!&^yn4|7xc^>$qI}_oPye@w zKaUR2ZVRkCX?xeFvf;^@g6Ss@{lD!IVi{|>d;8khLjr$&cN+4%3O%#WtelBI^~>v3 zy^MZ0R&>mGVDRK|K*{aZ87JOfyj5;0v8N#C?>ws`(Fwn2o#s8V&(2%6?vQ1ZZt~4f zlQ%dYRynT3_fb4{n>PD8o~Lt`|6{C~q;}dvz9#*yx6hUX%}i<Er*@beF|1s9t5)z_ z`N?@kaUDCBTd2nE<@#x{*V;%h;;@q6jt23g>k|JuUO2CDeWLf?*6*tV7B{fW$&dKr z_Dw15<h78k$q}K)R5pd^=f0V<{CJ@LqaCf68}u8$eK6=Qc(L}mU7^Qv3*NsLyg!w1 z$MQP&JFTmom27ZNb?>Qjz8~V_x1Dq2h!ffUvb?S(_RU21o$i@&_IGYd^xJSTpVbO2 zUKk!;smlGW{mzVUHG&mxkABtO=X`K3YWuwkqfhFlr=Gu3@Ne2)t3K;Nc*jd#Ppem_ zZoPhSc^~_Q)fH++u78$H4__Ow*k;YeO(r5gRji#Z%}YtRx+%(1yiTf0<T$@>>)%fk zmwguu&s>z-r2EEFYQE^AuPon|ez==`u$ifO;jX#^3qPFNB<dWPFKMT{bo1uK=@0jq zJ9}Sv|K!iHxog|@&A;9Jej|UU+=Tb+>y~K8PPS?YKgV8|qx-A-;fsrGFITu1or!%l zm8I^F=MuwBGp@~kX^<<Gf9>Y}S<f6x{`GRcQct+OVA0|72lxNIsY(5DUNdFKy$|jd zDYqT64WC~9tbTm~zwp*=w}a}Bn0|G+z)+yex5|F=JF7=h%N|VT`yEobdMdks_`Pqd zq#ug3Po8nG@`SX$($fIj0_`<6Q>~e7mYz4d)BJ$_ui(9y`VS?aR$k_QuC#7V`}Qw! z62Iyu?O7wa^?K3X*pIol;y=sJy7<dt?b`x@e|+18({Gt8@>k9+wbsa&pCKsS{fGPP z?9`-&>nCn(VbK0C?Z?JLHxDi6xw$dN@BNqQ4=mLlblex7<9zGbHs<|Z*X!bo#6R-P zy#4W)@Q)+E9t6BIK4T~}?_A5|(i`9J?w!H)LHWFD>M`3hypw`jJ<c!R@;`U2uj8L+ zWp%$@O*PzEsb{viE6?kS<_it1-c)t@^~B>nbGR?=KkzS%*S}Qp>1xf$S%nYW3oUn^ zb)FMBUD`PP!oKfK>hkQ?Cl=lJJ<I&Des03k@Gbs1k7rz2Q2)_y-AB8=8bL|<wJb+g zFL&6xTkv_BPUSu=x!MWBpX00;YBy%|MhkpPe!Ro~Si||XzeDf6VdgWk%09Dm!{W=% zFG~f&j+S%1J}a=ir*hw`<F7WppSpLt`X#HXg#8Ar-zHA;_14YUKWA<Fa{<=>OX`=^ zvfmRg=imHLx$j!l;-KTUZT8=SjlLwXzkVq3iKRx{tUiBvt4-^c$QM@0dcuA?E}hLi zwx{^Q#a*25AGuw2%KssFNp|<??niGTzWs4{5V+yO-cqqw6Lpe;t~AC!{671weS`nc zl`r{%4fQt}PBS{WMZReIlRFD*U7oMGAA3V}pT*rmfoEH+Ccn&l-C%yM&2D+Y4c#9r z3s%amW#@nWX7bVv{+9$3TZ?b3+{*oJndAEW|3}#?rpIyoerQ>7^25xumHN*XJZZUB zYTTH7H1g~9m;nAa?)^J*AIPse?j5ZBMLg--#{i8FYotC`%wqag{+#XXfubv%ub(dd zAW`eGLwWZ%lOHqEr`6sQ-Qyru9r7%2_i3Ni?hD^f;^{wiRHx#CU)4k1H$v`KvO%kb z1gq2kHQIJ`?@Qb2D_+t5c*TvM>gT3kQ(GQrC%`i+G?dNm!QAI3{&!kEsoZ04Bv!2S z|M;&1FDrRI-g!J}YUjTUS>tza?kUZg{3Giihv2{Yma2!P_PBkSHs7jb>aD3V+q=)D zPp*p6*#B``ja2>gbI1Q(uhVh-vy}hzR_4tY@-OS1_`=|R);D-BPec0E348C?@94If zTDYA}@!p=lvTmj;oQ?jn&*nI?*R=G~E3q5#+jpugXZRbisK_tR@NIlG-_`cU{cZ0} z?pE}Dd;Y6xY3hplO@Ci3Wy}9@Rl!`b@zcdginrb7yX|`-`>ZW^Uue$8+@+;PMc1d; zd{}p-wBTgOtMH~L|7y=HU3I*A%bJGr$L~}!xnFH<x4#q1Z1G&@{e@jVAFHc_gUkyw z4Bp<*cKyq7M=bBA+jH~TZQt7!p6`n>4-x;UwYsuag@4D>6Ku~l6ykEeG~2pPc%E}! zx4!*X!dKyA#~0UoY`UVh_0int=fiE9|7hu%ay@g>Z(hT>=6L0y?AM=umgwnUvi8ZS zUsWe=8LOZ)m)W_5ulc*@u1`0Am)PBYHa%eq|L>4r=Te*WmwXhP8QUQp{qNNprFZh* zZVHC44(PW%es52*=K4GTH*aJ5`FuWCZ}8$D-Ua5j<QQzs!f%u-uWw^sSAWB{y?$5d z^Di%JU(Aepqj1AsCF#?8u`l<&Jj__}EqTrBqNk@DjTadlPZIo;XrrCd+HtP*dGAcF zGloLhzR$mw%sU$tr}j(sM@~%6rwP{*n_r1+uMjMhf3wAtxnfF4oq48NMS<?=le+Bl zmj2?u>l?Uyt#ai#?Ev#P-)26)`*6O&@5-stKfcPfXL23g>!=h~`>elWW3kx&Ovbzx zsk57%6ptI*Zkl*-cjbAZ@c1w6yN~;Q<n(>e|Mgv6)dAD}4!H}Mo_F<jiLZ6~$D)4E zcYD8MEnC|&GiCWt?IuObJU`a1a^EBOD^v3P>g|si-|D;WbWgCqUzXFN_Dyr5?;6R5 z+Lrs9)41LU?caXq5&M4Uv}~!{i{Dvh+Qrp>HBb6_S()#d-S)fp*R$N)Ie+=ul}z_P z{SlJee|)b)&K--H=a&C+E!*W9vGmTlWY!z)^FRANTPX75yU+IOw%-EQpDv#M{orX2 z@2U0KnfJ=(KC0NI=x--JJ2&9_q&wHo$*qunc<buH<QID{n<Q=1{I%-A){+wT5A(Oj z-;r(kQKZCFKF{I4!1OoLciR7X%$dA()y4HE=Wc&|FL~XAv$xBS%hiVL%FBFg_n>9^ z;wA6;eyi8#SN_qRlmGU2-8RD~*6BBX|6#1Rn73_p(Z>A|7vDblsBJR8ZK`zue^b}? z^OYwyt0YAJ6nx+!VW9Ugyz2fbEA@FSHXGAJr)gc-X&!MhiDzy6^1~k^H`xD73y3t@ zo31N!Ppz8sw@>+$shmfDX=c?ZeOUWrM`4Ri@9v<|m1jAt;&b;-?6X+im2c^L@Xz_3 zyNd7H{19Daar+=c<>^g7ubyZ8AsqL>a!1qmuja4aXI`#)_xt9(>#X0nF0q*@$1}by z+xb?gO24rGPFH2rhVqZc#4X%^EdH4jZ*_k6@$Gw-{@oIJei`fEDQkIWW(N8GbQIb; z?^^f9ZK-y9<3(EDty}i*{AE2$x92mKxyv)Z{QLCjq>axD>O8JLN|$}GpNHLbVU4nL zpILwZyQ4d0P8Y0x*|9#q)w3&RamN?cxi(AtOb<NV`%Uu0vpo+^28ykJ@P6<1ZATxd zm&IkiS3e`Dt-kYp?ME+{Z7a@Ro6%YAad)wvtlqPwtomWmyG$P3>3{j>?t%2*=dYLB z9gUHgTkzmS#TS3aUk7iMec3#(hxL4S<ML~fi`V-z$EU}Zo2+L1*IATNmAs~-qUzP$ zb1wJOB_D5Cu6d%HGrHuH_zV9Y%?f6@XxX1N;o`3@emL}S`QnGux26`Y(W&UpuYVtC z`735q{Pcd!r$?vFF|hxTKJVz>)ouq8tIyAxRd8p$a&$=Ao@0L#cNEUfQ+V^?k4hTL z1o^sGhij~l)E@V{zA&|eyZ)1rpVFVlYiE6kmV2lACvxSpunpm*v40mTzg=<s?A4w5 z2c(@R$8TM&bpOuQ^N-m##JerpmM!?B)qYj(ZLJ4iT;@Cee_+mIIOEspr3b{7HmT3* zF=3qF*?zajs^h0m;p96r4!;O*3jR93U17hZw*G08eQ8euPt5zldo=&Y^r?26;_tE7 z|K$DkDVEQ^_)ng{&#AXv{ORTA>~CA-D8!3g-uGle>SX)hu01&%@*#OM<<5nD%h$fQ z>fy)v_y7Ma`Bz%E{LKDy(<lFY{*&!T@4r_yzuqhTk^J)h`Tg_%Z?_9{Rsa3J?A^b* zee0}$1=t>5|HZ9#vHEA%^b6+qPlo?m8~?Ii`}^8|+n=ATQU1UE&i-$bpW?sR{%8N| zc>l%!zjN1RZ+~}t|K+Ps|BI||SpVh8zKe@LeS0$hPtyPEZen5euV??)e>?r}C%<s* S%c0xq-#gF$&mh3SC<*{8{Yef0 literal 0 HcmV?d00001 diff --git a/static/camera_no_distortion.mat b/static/camera_no_distortion.mat new file mode 100644 index 0000000000000000000000000000000000000000..a6dfb95acd43f2df93c7da74b44eaec7a467ecc9 GIT binary patch literal 11116 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 literal 0 HcmV?d00001 diff --git a/static/distance.txt b/static/distance.txt new file mode 100644 index 0000000..915b1e6 --- /dev/null +++ b/static/distance.txt @@ -0,0 +1,6 @@ +camera's distance to the encoder +delta_x1 +delta_y1 +gripper's distance to the encoder +delta_x2 +delta_y2 \ No newline at end of file diff --git a/test.md b/test.md new file mode 100644 index 0000000..08733bc --- /dev/null +++ b/test.md @@ -0,0 +1,9 @@ +To test darknet_images.py +``` +python ./*darknet_images.py --input ~/farmbot/img --weights ~/farmbot/darknet/backup/yolov3-vattenhallen_best.weights --dont_show --ext_output --save_labels --config_file ~/farmbot/darknet/cfg/yolov3-vattenhallen-test.cfg --data_file ~/farmbot/darknet/data/vattenhallen.data +``` +Default values are used for the rest. + +save label去了哪里? 存到了和img同一个路径下 同名.txt文件,所以可以给一folder的图片同时检测 + +最好修改一下save label的地址,单独放一个folder \ No newline at end of file diff --git a/weights/yolov3-vattenhallen_best.weights b/weights/yolov3-vattenhallen_best.weights new file mode 100644 index 0000000..2be2b03 --- /dev/null +++ b/weights/yolov3-vattenhallen_best.weights @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4c52e0a741d72314e911bc52f237c915b2fba237aebb32d1fd4c8927a9f3ff7 +size 246434628 diff --git a/weights/yolov3-veges_best.weights b/weights/yolov3-veges_best.weights new file mode 100644 index 0000000..ab34a25 --- /dev/null +++ b/weights/yolov3-veges_best.weights @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:37dab259468e45f107c0b1f0071c50c035e110346634b089aac8c584c71e36f1 +size 246499248 -- GitLab