Compare commits

...

511 Commits

Author SHA1 Message Date
Daniel Yang d7b2f716ee
Merge pull request #2102 from Evezerest/release2.0-rc1
Change the path of joinus.png to absolute path
2021-02-26 11:49:21 +08:00
Leif 7086e509a1 Change the path of joinus.png to absolute path 2021-02-24 19:29:54 +08:00
dyning 5693001294
Merge pull request #1525 from Evezerest/dy1
set default use_gpu to False
2020-12-20 09:54:43 +08:00
dyning 42fc648c87
Update reference.md 2020-12-20 08:29:12 +08:00
dyning e75c3c1033
Update algorithm_overview_en.md 2020-12-20 08:28:52 +08:00
dyning e26a060b99
Update algorithm_overview.md 2020-12-20 08:27:20 +08:00
dyning 65af573fb0
Update algorithm_overview.md 2020-12-20 08:26:44 +08:00
dyning fc84375dc6
Update algorithm_overview.md 2020-12-20 08:26:02 +08:00
dyning 623843881b
Update algorithm_overview_en.md 2020-12-20 08:25:58 +08:00
dyning 60f344eae1
Update README.md 2020-12-20 08:20:52 +08:00
dyning 75a281f4db
Update README.md 2020-12-20 08:20:45 +08:00
dyning 87eca8ff9c
Update README_ch.md 2020-12-20 08:20:31 +08:00
dyning 9d1bc3ebb0
Update README.md 2020-12-19 20:11:21 +08:00
dyning 0bc91f4947
Update README.md 2020-12-19 20:10:54 +08:00
dyning 20a7688d23
Update README_ch.md 2020-12-19 20:07:06 +08:00
dyning fa1d099055
Update README.md 2020-12-19 20:02:58 +08:00
dyning fd3ddebbbf
Update README_ch.md 2020-12-19 20:02:39 +08:00
Leif 50b5ed91f1 set default use_gpu to False 2020-12-19 11:42:08 +08:00
dyning 011104e09f
Merge pull request #1514 from Evezerest/dy3
Add single box re-recognition function and perfect shortcut keys
2020-12-19 11:33:28 +08:00
dyning 7bd93832a1
Merge pull request #1517 from WenmuZhou/tree_doc
update inference doc
2020-12-19 10:05:13 +08:00
WenmuZhou b615f6704d load model by pretrained_model 2020-12-18 23:00:16 +08:00
WenmuZhou 73d4b41ab0 update inference doc 2020-12-18 22:36:04 +08:00
zhoujun 99175c6106
Merge pull request #1513 from WenmuZhou/dygraph_rc
Save configuration files and logs only during training
2020-12-18 22:20:01 +08:00
Evezerest fad11f89a8
Merge branch 'dygraph' into dy3 2020-12-18 19:38:43 +08:00
Leif 0c6fc71b25 Update PPOCRLabel 2020-12-18 19:35:02 +08:00
Leif ffe71f5851 Update AutoDialog 2020-12-18 19:32:16 +08:00
Leif 03002bbc55 Add single box re-recognition function and perfect shortcut keys 2020-12-18 19:28:38 +08:00
WenmuZhou ae12459015 Save configuration files and logs only during training 2020-12-18 18:51:19 +08:00
WenmuZhou 7f76986c28 Remove duplicate definitions 2020-12-18 18:29:13 +08:00
zhoujun 6bffeb58af
Merge pull request #1506 from WenmuZhou/dygraph_rc
fix typo error
2020-12-18 17:49:10 +08:00
WenmuZhou e3a2f818fa fix typo error 2020-12-18 17:46:48 +08:00
zhoujun 0492ba4f86
Merge pull request #1503 from LDOUBLEV/dyg_db
add tensorrt args
2020-12-18 15:39:48 +08:00
LDOUBLEV 9039cca26d add tensorrt args 2020-12-18 15:27:44 +08:00
Double_V 49b0a92b2d
Merge pull request #1501 from LDOUBLEV/dyg_db
fix db process
2020-12-18 14:45:40 +08:00
LDOUBLEV ec37732512 fix db process 2020-12-18 14:45:06 +08:00
MissPenguin 263a9fc5d4
Merge pull request #1498 from MissPenguin/dygraph
fix sast inference bug
2020-12-18 14:12:11 +08:00
MissPenguin d489d3c27d fix sast inference bug 2020-12-18 03:40:22 +00:00
Double_V 2ba66200a9
Merge pull request #1496 from LDOUBLEV/dyg_db
adjust cls_batch_num to 6 for speed-up
2020-12-18 11:11:42 +08:00
LDOUBLEV a6fd8f8066 adjust cls_batch_num to 6 for speed-up 2020-12-18 11:11:02 +08:00
zhoujun 6bbd58aa14
Merge pull request #1494 from WenmuZhou/tree_doc
适配py3.5
2020-12-18 10:38:15 +08:00
WenmuZhou 30e2bd4f34 适配py3.5 2020-12-18 10:04:50 +08:00
Double_V d9f11deeec
Merge pull request #1491 from LDOUBLEV/dyg_db
adjust rec_batch_num as 1
2020-12-17 20:59:12 +08:00
LDOUBLEV 65b4cc0cf3 adjust rec_batch_num as 1 2020-12-17 20:58:23 +08:00
Double_V 0f9b88ed91
Merge pull request #1489 from LDOUBLEV/dyg_db
fludd 2 paddle
2020-12-17 20:28:17 +08:00
LDOUBLEV fd92294bfa fludd 2 paddle 2020-12-17 20:27:43 +08:00
Daniel Yang d407cf92d9
Merge pull request #1482 from Evezerest/dy3
Update joinus.png
2020-12-17 15:53:44 +08:00
littletomatodonkey fc85051d64
add support for cpu infer (#1480)
* add support for cpu infer

* fix readme
2020-12-17 15:28:19 +08:00
Leif 246a0bce7d Merge remote-tracking branch 'upstream/dygraph' into dy3 2020-12-17 15:18:20 +08:00
Leif 4779e00ac1 Update joinus.png 2020-12-17 15:14:24 +08:00
Wei Shengyu 84b4323abf
add notice in height of style images. (#1475)
* add examples in doc

* add files

* modify files

* dbg typo

* add notice in size of style images
2020-12-16 20:20:18 +08:00
MissPenguin fbf66516b4
Merge pull request #1474 from WenmuZhou/tree_doc
fix bugs
2020-12-16 19:43:36 +08:00
WenmuZhou 39955558b8 fix bugs 2020-12-16 19:41:44 +08:00
Double_V 8501e36ea2
Merge pull request #1471 from LDOUBLEV/dyg_db
update c inference
2020-12-16 18:29:53 +08:00
LDOUBLEV b70f9bf858 update c inference 2020-12-16 18:29:27 +08:00
LDOUBLEV 76580ea143 update c inference 2020-12-16 18:28:26 +08:00
Wei Shengyu 368eeb5f93
Add batch examples in StyleText doc (#1469)
* add examples in doc

* add files

* modify files

* dbg typo
2020-12-16 16:55:28 +08:00
Double_V f9f6263005
Merge pull request #1468 from LDOUBLEV/dyg_db
add 1, 11, 12.jpg
2020-12-16 16:38:06 +08:00
LDOUBLEV f12f4aba07 add 1, 11, 12.jpg 2020-12-16 16:36:58 +08:00
MissPenguin eebd4f1c29
Merge pull request #1467 from LDOUBLEV/dyg_db
delete doc imgs and fix inference doc
2020-12-16 16:30:55 +08:00
LDOUBLEV 02f37689c7 delete doc imgs and fix inference doc 2020-12-16 16:28:42 +08:00
MissPenguin a2af2c52e0
Merge pull request #1466 from LDOUBLEV/dyg_db
delete bad case
2020-12-16 16:02:51 +08:00
LDOUBLEV c5f3cde845 delete bad case 2020-12-16 16:00:43 +08:00
zhoujun d885b55820
Merge pull request #1465 from WenmuZhou/tree_doc
fix typo error
2020-12-16 15:21:19 +08:00
WenmuZhou f7de55d931 fix typo error 2020-12-16 15:16:46 +08:00
MissPenguin 2a15989f19
Merge pull request #1463 from MissPenguin/dygraph
update faq
2020-12-16 15:04:42 +08:00
MissPenguin 396e88b888 update faq 2020-12-16 07:02:51 +00:00
MissPenguin 75b9feb0a6
Merge pull request #1460 from Evezerest/dy3
Update FAQ
2020-12-16 14:34:50 +08:00
MissPenguin 631fe2ecca
Merge pull request #1459 from weisy11/dygraph
update style text doc, add corpus file descriptions
2020-12-16 14:34:01 +08:00
MissPenguin f38a22c0b3
Merge pull request #1449 from WenmuZhou/tree_doc
[Dygraph] change DBHead output to dict and update db config
2020-12-16 14:33:14 +08:00
Daniel Yang be8bc1fc9e
Update README_ch.md 2020-12-16 14:10:45 +08:00
dyning 120ec52ae7
Update README_ch.md 2020-12-16 14:07:20 +08:00
WenmuZhou a8d1f2db94 update 2020-12-16 13:06:48 +08:00
Leif d6fd98dfab Update readme 2020-12-16 12:52:26 +08:00
Leif 78d5197146 Merge remote-tracking branch 'upstream/dygraph' into dy3 2020-12-16 12:10:19 +08:00
Leif bd3140186a Update FAQ 2020-12-16 12:09:55 +08:00
Wei Shengyu f41851025b
Update README.md 2020-12-16 11:42:14 +08:00
Wei Shengyu 0b44875369
Update README_ch.md 2020-12-16 11:41:34 +08:00
Wei Shengyu ce37bd1d80
Update README.md 2020-12-16 11:36:59 +08:00
Wei Shengyu bff7c8aa9f
Update README.md 2020-12-16 11:36:35 +08:00
Wei Shengyu b1a613a851
Update README.md 2020-12-16 11:28:52 +08:00
Wei Shengyu 221d49f662
Update README_ch.md 2020-12-16 11:28:20 +08:00
MissPenguin c683a181d4
Update readme_en.md 2020-12-16 11:15:25 +08:00
MissPenguin f456cc16af
Update readme.md 2020-12-16 11:15:06 +08:00
MissPenguin 2b43c77c03
Update models_list.md 2020-12-16 11:03:59 +08:00
MissPenguin dbdb6881f3
Update README_ch.md 2020-12-16 11:02:50 +08:00
MissPenguin 02527479d4
Update models_list_en.md 2020-12-16 11:02:01 +08:00
MissPenguin a1c8eabbe1
Update README.md 2020-12-16 11:01:21 +08:00
MissPenguin 51d80bd696
Update README.md 2020-12-16 10:59:49 +08:00
dyning 297491460e
Merge pull request #1457 from WenmuZhou/update_whl_doc
update whl version
2020-12-16 10:59:31 +08:00
MissPenguin 06fac86f76
Update models_list_en.md 2020-12-16 10:59:05 +08:00
WenmuZhou aa556e6020 update whl recommend version 2020-12-16 10:58:30 +08:00
MissPenguin d5de108d8f
Update README_ch.md 2020-12-16 10:55:47 +08:00
MissPenguin 6471683972
Update README_ch.md 2020-12-16 10:55:17 +08:00
WenmuZhou 8a51374837 update whl version 2020-12-16 10:51:39 +08:00
MissPenguin f75687711d
Update README.md 2020-12-16 10:51:06 +08:00
MissPenguin d5b17e808a
Update README.md 2020-12-16 10:50:38 +08:00
dyning 0576e4a294
Merge pull request #1455 from WenmuZhou/update_whl_doc
[Dygraph] update whl doc
2020-12-16 10:46:48 +08:00
WenmuZhou dbea8e743c update whl doc 2020-12-16 10:36:22 +08:00
MissPenguin ba7cedd450
Update README_ch.md 2020-12-16 10:09:06 +08:00
MissPenguin cce0b57a6b
Update README_ch.md 2020-12-16 10:08:44 +08:00
MissPenguin 56e2330484
Update README.md 2020-12-16 10:07:22 +08:00
MissPenguin 2bc4d9a1f7
Update README.md 2020-12-16 10:06:31 +08:00
littletomatodonkey 00a84c605b
fix table (#1454) 2020-12-16 00:59:32 +08:00
Wei Shengyu 217b991f05
update images (#1453) 2020-12-16 00:58:41 +08:00
dyning d9038e1d12
Merge pull request #1452 from grasswolfs/update_notice_1215
Update readme
2020-12-16 00:56:35 +08:00
grasswolfs 0166051935 test=develop, test=documents_fix 2020-12-16 00:55:11 +08:00
dyning a035e65048
Update README.md 2020-12-16 00:54:56 +08:00
grasswolfs 214e86164d test=develop, test=documents_fix 2020-12-16 00:53:26 +08:00
dyning aa5b04cff5
Merge pull request #1448 from littletomatodonkey/dyg/fix_en_st
fix style text readme
2020-12-16 00:53:12 +08:00
dyning 22f4679b72
Update README_ch.md 2020-12-16 00:51:26 +08:00
grasswolfs 95daf7eee1 test=develop, test=documents_fix 2020-12-16 00:48:55 +08:00
littletomatodonkey 79a2a321ef fix conflict 2020-12-15 16:47:21 +00:00
dyning b2a1b3c0c5
Update models_list.md 2020-12-16 00:45:51 +08:00
grasswolfs f1aa210097 Merge branch 'dygraph' of https://github.com/PaddlePaddle/PaddleOCR into update_notice_1215 2020-12-16 00:45:42 +08:00
grasswolfs 139e2af2e0 test=develop, test=documents_fix 2020-12-16 00:44:40 +08:00
littletomatodonkey 25becc0117 fix doc 2020-12-15 16:44:38 +00:00
dyning 4b19d37282
Merge pull request #1451 from weisy11/dygraph
add file descriptions in Style text tree
2020-12-16 00:43:45 +08:00
weishengyu 099dcab479 dbg 2020-12-16 00:43:06 +08:00
dyning 2b3d3b1a1b
Update README_ch.md 2020-12-16 00:41:56 +08:00
dyning a7b13a0ec0
Update README_ch.md 2020-12-16 00:41:10 +08:00
dyning 7f383a4368
Update README.md 2020-12-16 00:40:38 +08:00
dyning abc93b3af2
Update README.md 2020-12-16 00:39:28 +08:00
littletomatodonkey 074a620ead Merge branch 'dygraph' of https://github.com/PaddlePaddle/PaddleOCR into dyg/fix_en_st 2020-12-15 16:36:08 +00:00
littletomatodonkey d72d4165b4 fix doc 2020-12-15 16:35:38 +00:00
weishengyu 81488b1330 add file descriptions 2020-12-16 00:32:11 +08:00
dyning 980014c1d5
Update models_list_en.md 2020-12-16 00:31:06 +08:00
dyning fde71656be
Update models_list_en.md 2020-12-16 00:29:41 +08:00
dyning bcdf701fae
Merge pull request #1450 from weisy11/dygraph
add example images for English
2020-12-16 00:21:13 +08:00
weishengyu 5fb8564bb2 add example images for English 2020-12-16 00:20:01 +08:00
weishengyu cccfc98dc7 change images 2020-12-16 00:05:36 +08:00
WenmuZhou 41c2af4924 update predict_det 2020-12-16 00:03:50 +08:00
littletomatodonkey 89305e1c8e Merge branch 'dygraph' of https://github.com/PaddlePaddle/PaddleOCR into dyg/fix_en_st 2020-12-15 16:01:08 +00:00
WenmuZhou 2ad0ca44cd update db config 2020-12-16 00:00:03 +08:00
littletomatodonkey 6cec111e6b fix typo 2020-12-15 16:00:00 +00:00
dyning 161a47a6e2
Update README_ch.md 2020-12-15 23:57:56 +08:00
WenmuZhou d3b609ee09 change DBHead output to dict 2020-12-15 23:49:50 +08:00
dyning a3573c4a13
Update README_ch.md 2020-12-15 23:49:07 +08:00
dyning 87f9fcec66
Update README_ch.md 2020-12-15 23:46:59 +08:00
dyning c97359c671
Update README_ch.md 2020-12-15 23:38:16 +08:00
dyning fa60cafe74
Update README_ch.md 2020-12-15 23:37:39 +08:00
MissPenguin fde92a1a5a
Update README_ch.md 2020-12-15 23:37:13 +08:00
dyning d7f222a6e1
Update README_ch.md 2020-12-15 23:37:10 +08:00
MissPenguin 280a2dbdba
Update README.md 2020-12-15 23:36:47 +08:00
dyning 7b11ddd43e
Update README_ch.md 2020-12-15 23:36:13 +08:00
dyning cdfa38c9c0
Update README_ch.md 2020-12-15 23:35:10 +08:00
littletomatodonkey 084bc5a926 fix style exit readme 2020-12-15 15:34:07 +00:00
MissPenguin cf0d24e53e
Merge pull request #1434 from Evezerest/dy3
Update autoDialog
2020-12-15 23:33:56 +08:00
dyning 66b8c8c354
Update README_ch.md 2020-12-15 23:33:09 +08:00
dyning d48fa3fd62
Update README_ch.md 2020-12-15 23:32:33 +08:00
dyning e65c9f10ce
Merge pull request #1447 from weisy11/dygraph
update doc
2020-12-15 23:31:21 +08:00
weishengyu 9802b9340d update doc 2020-12-15 23:30:03 +08:00
MissPenguin abf2a4fbff
Merge pull request #1446 from MissPenguin/dygraph
fix sast configs
2020-12-15 23:30:01 +08:00
MissPenguin a56d8244d0 fix sast configs 2020-12-15 15:24:53 +00:00
dyning 7408ddad36
Merge pull request #1444 from weisy11/dygraph
update style text doc
2020-12-15 23:21:29 +08:00
dyning bb31dc4be1
Merge pull request #1445 from grasswolfs/update_readme_1215
Update readme and related docs
2020-12-15 23:21:03 +08:00
weishengyu 92d507b0c9 add description 2020-12-15 23:20:35 +08:00
MissPenguin 5632dec4e4
Update models_list_en.md 2020-12-15 23:19:19 +08:00
MissPenguin eb7ec38f9d
Update models_list.md 2020-12-15 23:16:10 +08:00
grasswolfs f5b362952d test=develop, test=documents_fix 2020-12-15 23:14:11 +08:00
MissPenguin fc49d94db0
Update algorithm_overview.md 2020-12-15 23:13:42 +08:00
MissPenguin e9ce6dcc83
Update algorithm_overview_en.md 2020-12-15 23:12:25 +08:00
weishengyu 5b9a8b9c23 update doc 2020-12-15 23:12:17 +08:00
grasswolfs 53b993454a test=develop, test=documents_fix 2020-12-15 23:11:41 +08:00
MissPenguin 16a2fcda49
Update algorithm_overview_en.md 2020-12-15 23:11:38 +08:00
MissPenguin ecc81c35a5
Update algorithm_overview_en.md 2020-12-15 23:11:05 +08:00
MissPenguin 5d7e7016af
Update algorithm_overview_en.md 2020-12-15 23:09:33 +08:00
Double_V 3df2f8f142
Merge pull request #1443 from LDOUBLEV/dyg_db
update images link
2020-12-15 23:05:57 +08:00
LDOUBLEV 84684ab8d6 update images link 2020-12-15 23:03:48 +08:00
dyning 99d83c0551
Update README_ch.md 2020-12-15 23:03:24 +08:00
dyning 57e6edd97c
Update README_ch.md 2020-12-15 23:02:41 +08:00
dyning b1bff7aefb
Update README_ch.md 2020-12-15 22:57:50 +08:00
MissPenguin 80fc4f59dc
Merge pull request #1438 from MissPenguin/dygraph
update inference for east & sast
2020-12-15 22:56:13 +08:00
dyning c2188d11a9
Update README_ch.md 2020-12-15 22:54:15 +08:00
dyning 37227a4ad3
Update README_ch.md 2020-12-15 22:53:28 +08:00
dyning 7e55149343
Update README_ch.md 2020-12-15 22:53:07 +08:00
dyning 3eee0eb453
Update README_ch.md 2020-12-15 22:52:44 +08:00
grasswolfs 7950062dd8 test=develop, test=documents_fix 2020-12-15 22:50:57 +08:00
dyning 2c4e3ecdb9
Update README_ch.md 2020-12-15 22:50:48 +08:00
dyning c249275915
Merge pull request #1441 from weisy11/dygraph
rename style_text_rec -> style_text
2020-12-15 22:50:05 +08:00
MissPenguin afa1b992bc nothing important 2020-12-15 14:49:13 +00:00
weishengyu b91055eefa rename style_text_rec -> style_text 2020-12-15 22:46:58 +08:00
grasswolfs 802caeccbf Merge branch 'dygraph' of https://github.com/PaddlePaddle/PaddleOCR into update_readme_1215 2020-12-15 22:38:48 +08:00
grasswolfs ca1d962890 test=develop, test=documents_fix 2020-12-15 22:37:52 +08:00
MissPenguin fe46b77edf fix conflicts 2020-12-15 14:29:44 +00:00
Double_V 703bb1a97c
Merge pull request #1426 from LDOUBLEV/dyg_db
update visualized results
2020-12-15 22:26:57 +08:00
LDOUBLEV 3882cefe71 update french_0.jpg 2020-12-15 22:23:23 +08:00
LDOUBLEV 936b515177 mobile to server 2020-12-15 22:19:07 +08:00
dyning 9ad5c6b2bd
Update README_ch.md 2020-12-15 22:17:34 +08:00
LDOUBLEV 8fedee3637 update visualized images 2020-12-15 22:16:17 +08:00
LDOUBLEV 0c33ea634e update visualized images 2020-12-15 22:14:29 +08:00
dyning cdb07d350a
Update README_ch.md 2020-12-15 22:13:20 +08:00
MissPenguin c9a8cd83b1 fix db eval 2020-12-15 14:13:04 +00:00
Double_V 24f0f3b68d
Merge pull request #1439 from LDOUBLEV/fix_dyg_doc
opt db inference doc
2020-12-15 22:12:37 +08:00
dyning 72f29adaa7
Update README_ch.md 2020-12-15 22:11:59 +08:00
dyning ee6a4de2a4
Update README_ch.md 2020-12-15 22:11:18 +08:00
MissPenguin b596e70f14 fix db eval 2020-12-15 14:11:02 +00:00
dyning 18f8bfc13a
Update README_ch.md 2020-12-15 22:10:21 +08:00
dyning a5583fac45
Update README_ch.md 2020-12-15 22:09:50 +08:00
dyning 39a4f68e75
Update README_ch.md 2020-12-15 22:07:43 +08:00
LDOUBLEV 2aa5a1affd update visualized images 2020-12-15 22:07:10 +08:00
dyning b48f5da1f2
Update README_ch.md 2020-12-15 22:06:38 +08:00
dyning 0888a4ae2b
Merge pull request #1440 from weisy11/dygraph
Update Styletext doc
2020-12-15 22:04:37 +08:00
weishengyu e27c136a49 add images and charts 2020-12-15 22:02:22 +08:00
weishengyu 22ac6bc529 rename files 2020-12-15 21:53:06 +08:00
dyning a26968a4c0
Merge pull request #1428 from weisy11/dygraph
Add Style Text Rec
2020-12-15 21:48:10 +08:00
weishengyu 27830164b1 modify doc 2020-12-15 21:46:56 +08:00
MissPenguin 7936a998cb update models link and eval metrics 2020-12-15 13:42:26 +00:00
weishengyu 09b940f3b3 dbg 2020-12-15 21:17:38 +08:00
weishengyu d219ad4059 dbg 2020-12-15 21:17:03 +08:00
weishengyu f03dcd603f dbg 2020-12-15 21:14:48 +08:00
LDOUBLEV 2714ef6209 opt db inference doc 2020-12-15 21:06:18 +08:00
LDOUBLEV 0b2a6a1a4c opt db inference doc 2020-12-15 20:58:32 +08:00
LDOUBLEV 293884a5e3 opt db inference doc 2020-12-15 20:56:10 +08:00
MissPenguin 3f64d27b71 update inference for east & sast 2020-12-15 12:54:02 +00:00
Double_V 3c15b9a0c2
Merge pull request #1436 from tink2123/dygraph_doc
update recognition doc
2020-12-15 20:38:06 +08:00
tink2123 3602b066ba fix ic15.yml and del img_words_en 2020-12-15 20:32:18 +08:00
weishengyu 8bce9baab3 change doc and move style_text to root folder 2020-12-15 20:21:04 +08:00
xiaoting 2874ff8750
Merge pull request #1435 from LDOUBLEV/fix_dyg_doc
fix detection doc
2020-12-15 20:01:31 +08:00
tink2123 ca3ea1b53c update recognition doc 2020-12-15 19:56:42 +08:00
LDOUBLEV 39aa077010 fix detection doc 2020-12-15 19:56:32 +08:00
LDOUBLEV 6749a349c0 Merge branch 'dygraph' of https://github.com/PaddlePaddle/PaddleOCR into dyg_db 2020-12-15 19:41:21 +08:00
Leif a633d37d3d Update autoDialog 2020-12-15 19:37:54 +08:00
LDOUBLEV 887219cf08 modify visualized results 2020-12-15 19:29:16 +08:00
xiaoting 3a8dbe9ee0
Merge pull request #1433 from tink2123/dygraph_doc
mv rare and starnet in rec doc
2020-12-15 19:09:29 +08:00
zhoujun 4e87349bc6
Merge pull request #1431 from WenmuZhou/tree_doc
[Dygraph] add  Algorithm overview
2020-12-15 19:08:24 +08:00
tink2123 0820562963 mv rare and starnet in rec doc 2020-12-15 19:08:18 +08:00
MissPenguin 1f926f5f01
Merge pull request #1430 from LDOUBLEV/fix_dyg_doc
update install paddle to 2.0rc1
2020-12-15 19:05:39 +08:00
WenmuZhou 74c70afa8b update 2020-12-15 19:02:29 +08:00
LDOUBLEV 62eab69d9a update doc 2020-12-15 18:59:40 +08:00
WenmuZhou 18446d3139 remove star-net 2020-12-15 18:04:21 +08:00
WenmuZhou 97b0103b8f delete attention 2020-12-15 17:59:03 +08:00
WenmuZhou 34c1ddfecb Add paddle version notes 2020-12-15 17:54:16 +08:00
WenmuZhou 9b370bb26a Delete unused code 2020-12-15 17:51:09 +08:00
WenmuZhou e92ed072ee Merge branch 'dygraph' of https://github.com/PaddlePaddle/PaddleOCR into tree_doc 2020-12-15 17:50:17 +08:00
LDOUBLEV 4d504da629 update doc 2020-12-15 17:38:00 +08:00
WenmuZhou dbb2cfed3a update to rc1 2020-12-15 17:36:46 +08:00
WenmuZhou fc14267bad update link 2020-12-15 17:34:26 +08:00
WenmuZhou d5c85e4035 update Algorithm overview 2020-12-15 17:31:36 +08:00
LDOUBLEV 7de103c513 update doc 2020-12-15 17:19:31 +08:00
LDOUBLEV b3807c2faf update install paddle 2020-12-15 16:53:27 +08:00
LDOUBLEV 65c5dbd46f Merge branch 'dygraph' of https://github.com/PaddlePaddle/PaddleOCR into dyg_db 2020-12-15 16:36:22 +08:00
weishengyu da1c7fe0b9 add download link 2020-12-15 16:35:46 +08:00
LDOUBLEV c238eb0fe7 update imgs 2020-12-15 16:20:57 +08:00
LDOUBLEV c43302498d update imgs 2020-12-15 16:19:38 +08:00
LDOUBLEV d515bc87a1 update imgs 2020-12-15 16:18:01 +08:00
LDOUBLEV 55f8f4dc81 update imgs 2020-12-15 16:14:38 +08:00
weishengyu 966fdaab01 python2 not supported 2020-12-15 15:55:02 +08:00
weishengyu 596947758f add headers and remove useless import 2020-12-15 15:52:23 +08:00
weishengyu 181b2933c1 change config; add doc 2020-12-15 15:38:01 +08:00
MissPenguin f26772ac84
Merge pull request #1425 from Evezerest/dy3
Add PPOCRLabel and FAQ_dy
2020-12-15 15:19:31 +08:00
LDOUBLEV 59f50a6ada fix conflicts 2020-12-15 15:13:15 +08:00
Leif 14df1b95af Update Wechat group QR code and delete redundancy codes in PPOCRLabel 2020-12-15 15:12:06 +08:00
LDOUBLEV e99565c7f3 README_en.md to README.md 2020-12-15 15:09:24 +08:00
LDOUBLEV 0ca35c3f5b modify visual res of 2.0 2020-12-15 15:08:23 +08:00
weishengyu d3dcaed41c change config 2020-12-15 14:35:52 +08:00
Leif a49382e530 Update steps_en gif 2020-12-15 14:32:19 +08:00
MissPenguin 762c57879a
Merge pull request #1415 from WenmuZhou/dygraph_rc
[Dygraph] trans numpy to paddle in tps
2020-12-15 14:12:03 +08:00
MissPenguin a598b3ef17
Merge pull request #1423 from PaddlePaddle/dygraph_doc
update Readme.md
2020-12-15 14:11:00 +08:00
tink2123 6d36aad2ef update date 2020-12-15 13:35:24 +08:00
tink2123 c55f017110 update date 2020-12-15 13:30:03 +08:00
tink2123 53551bcbb0 del Readme_en.md and update version 2020-12-15 13:24:54 +08:00
MissPenguin 4717df2f9d
Merge pull request #1422 from TingquanGao/dygraph
Fix the link error
2020-12-15 13:20:20 +08:00
tink2123 c650bd119c update Readme.md 2020-12-15 13:04:19 +08:00
weishengyu f2d98c5e76 add style_text_rec 2020-12-15 11:26:54 +08:00
TingquanGao a79345e543 Fix the link error 2020-12-15 11:26:24 +08:00
WenmuZhou fe1372420e Merge branch 'dygraph' of https://github.com/PaddlePaddle/PaddleOCR into tree_doc 2020-12-15 10:02:06 +08:00
MissPenguin b1623d69a5
Merge pull request #1417 from MissPenguin/dygraph
update hubserving
2020-12-14 21:23:01 +08:00
Leif 91685c0693 Update shortcuts 2020-12-14 20:55:32 +08:00
Leif 40673f996a Delete redundancy codes and add save label in menu 2020-12-14 20:50:12 +08:00
MissPenguin af0f81dfe1 remove pdserving 2020-12-14 11:45:26 +00:00
MissPenguin 0ba5e95cc0 update hubserving 2020-12-14 11:42:00 +00:00
WenmuZhou e6878b2113 trans numpy to paddle 2020-12-14 18:23:47 +08:00
WenmuZhou 7b53596ce6 Merge branch 'dygraph' of https://github.com/PaddlePaddle/PaddleOCR into dygraph_rc 2020-12-14 17:34:17 +08:00
LDOUBLEV 91170e7a0b Merge branch 'dygraph' of https://github.com/PaddlePaddle/PaddleOCR into dyg_db 2020-12-14 15:03:51 +08:00
LDOUBLEV 1055fee36d add note 2020-12-14 15:03:42 +08:00
Leif b909893585 Merge remote-tracking branch 'upstream/dygraph' into dy3 2020-12-14 13:51:48 +08:00
Leif 47752ddf08 Update join us 2020-12-14 13:51:37 +08:00
zhoujun 0e32093fdc
add grad clip (#1411) 2020-12-14 12:19:33 +08:00
WenmuZhou 53d4eab6cd Merge remote-tracking branch 'origin/tree_doc' into tree_doc
# Conflicts:
#	doc/doc_ch/config.md
#	doc/doc_en/config_en.md
2020-12-14 12:10:41 +08:00
WenmuZhou ccd7c40be6 add grad clip 2020-12-14 12:09:25 +08:00
Double_V 53b514e39d
delete lite,slim, iosdemo and android demo of dyrgaph branch for now (#1403)
delete lite,slim, iosdemo and android demo of dyrgaph branch for now
2020-12-13 17:21:26 +08:00
littletomatodonkey e84ea2667f
fix prob (#1404) 2020-12-13 17:19:52 +08:00
LDOUBLEV b0ae672873 delete lite,slim, iosdemo and android demo of dyrgaph branch for now 2020-12-13 15:19:49 +08:00
LDOUBLEV 2735e9e3c9 Merge branch 'dygraph' of https://github.com/PaddlePaddle/PaddleOCR into dyg_db 2020-12-13 15:14:27 +08:00
MissPenguin 52671b7db2
Merge pull request #1402 from MissPenguin/dygraph
fix predict_det
2020-12-13 14:50:51 +08:00
MissPenguin edc0fd0ccd fix predict_det 2020-12-13 06:18:26 +00:00
MissPenguin d7f5365190
Merge pull request #1401 from WenmuZhou/tree_doc
[Dygraph] Fix printing problem when multi-image prediction
2020-12-13 12:13:15 +08:00
WenmuZhou c12259091e Fix printing problem when multi-image prediction 2020-12-12 20:10:19 +08:00
MissPenguin bf145a2173
Merge pull request #1398 from WenmuZhou/tree_doc
update config
2020-12-12 19:49:09 +08:00
MissPenguin 71b8416493
Merge pull request #1392 from tink2123/dygraph_doc
[Dygraph] update readme and polish some docs
2020-12-12 19:48:30 +08:00
tink2123 09ebcb43b9 Merge branch 'dygraph_doc' of https://github.com/tink2123/PaddleOCR into dygraph 2020-12-12 14:16:36 +08:00
tink2123 3ebb4a1660 update doc 2020-12-12 14:13:27 +08:00
WenmuZhou 4b87314a46 update config 2020-12-12 14:12:18 +08:00
MissPenguin 6acf8a1d1f
Merge pull request #1397 from WenmuZhou/tree_doc
[Dygraph] add model list doc, update model link in paddeocr.py and update model size in quick start doc
2020-12-12 14:02:42 +08:00
WenmuZhou d3ca2e426e update inference result 2020-12-12 13:28:33 +08:00
WenmuZhou 8ddeec8428 update inference doc 2020-12-12 12:57:05 +08:00
WenmuZhou 25ec8caced update inference 2020-12-12 11:30:49 +08:00
WenmuZhou dd649a1c6c delete path in config 2020-12-12 11:25:05 +08:00
WenmuZhou 1759c1a812 remove 2.0 load 1.1 model 2020-12-12 11:03:50 +08:00
WenmuZhou c3231f1b0e remove 2.0 load 1.1 model 2020-12-12 11:03:11 +08:00
WenmuZhou 0e80bade3c update inference.md to inference_en.md 2020-12-12 10:55:42 +08:00
WenmuZhou cee24caf51 update model size 2020-12-12 10:54:40 +08:00
WenmuZhou 03d5853240 update model_list doc 2020-12-12 10:53:49 +08:00
Leif 43ccde7d88 Merge remote-tracking branch 'upstream/dygraph' into dy3 2020-12-12 09:52:20 +08:00
Leif ff5e11cb43 Update FAQ 2020-12-12 09:45:07 +08:00
WenmuZhou f4dd2ee65c update pre-train model of rec 2020-12-11 23:06:31 +08:00
WenmuZhou 49c32f44f9 change v1.1 to v2.0 2020-12-11 22:20:26 +08:00
WenmuZhou 8d113f7d9d update link 2020-12-11 22:06:42 +08:00
Leif a14fce5bdf Add save label in menu 2020-12-11 21:53:01 +08:00
Double_V e55e224131
set use_shared_momery as False when eval (#1394) 2020-12-11 21:07:43 +08:00
LDOUBLEV 493a71711c set use_shared_momery as False when eval 2020-12-11 21:02:49 +08:00
MissPenguin 16a20e0dda
Merge pull request #1393 from WenmuZhou/tree_doc
[Dygraph] update link in doc
2020-12-11 19:43:59 +08:00
Leif 4c4cad8bd5 Add PPOCRLabel 2020-12-11 19:23:27 +08:00
WenmuZhou 913e11cbb8 update model size 2020-12-11 18:54:30 +08:00
WenmuZhou b5f9a7ec5b update link in doc 2020-12-11 18:48:23 +08:00
xiaoting 3feb56f167
Merge branch 'dygraph' into dygraph_doc 2020-12-11 17:53:30 +08:00
tink2123 61b94e47cb polish doc 2020-12-11 17:50:01 +08:00
zhoujun 569deedc41
Merge pull request #1388 from WenmuZhou/tree_doc
[Dygraph] change output path
2020-12-11 13:29:44 +08:00
WenmuZhou 3ea94c94d2 change save_model_dir 2020-12-11 13:27:27 +08:00
zhoujun 058c0e5302
fix typo error (#1387) 2020-12-11 13:21:58 +08:00
WenmuZhou 49895d097a fix typo error 2020-12-11 13:19:37 +08:00
MissPenguin 1007e5309c
Merge pull request #1385 from TingquanGao/dygraph
Fix the errors about description of dict
2020-12-11 12:47:40 +08:00
gaotingquan-dev 1de89825f6 Fix the errors about description of dict 2020-12-11 03:30:16 +00:00
MissPenguin 8b2feecb3a
Merge pull request #1367 from WenmuZhou/update_angle_class_doc
[Dygraph] update quickstart doc, model link uses link as a placeholder
2020-12-11 09:42:37 +08:00
MissPenguin 31b8aa54f7
Merge pull request #1372 from tink2123/dygraph_doc
update reademe for dygraph
2020-12-11 09:25:10 +08:00
MissPenguin ba956b485e
Merge pull request #1380 from LDOUBLEV/dyg_db
update doc of db and installtion
2020-12-11 09:23:23 +08:00
xiaoting 631fd9fdec
Merge branch 'dygraph' into dygraph_doc 2020-12-10 19:38:55 +08:00
xiaoting 90b968d596
Merge pull request #1317 from xmy0916/dygraph
fix doc algorithm_overview ch&en
2020-12-10 18:58:45 +08:00
xmy0916 7737685935 fix doc recognition ch&en 2020-12-10 18:56:21 +08:00
xmy0916 a2f95be771 fix doc recognition ch&en 2020-12-10 18:43:27 +08:00
LDOUBLEV da84f0b15f update 2020-12-10 17:36:49 +08:00
zhoujun e83bd2d81d
Merge pull request #1382 from WenmuZhou/py_inference_doc
change gpus to selected_gpus
2020-12-10 17:29:32 +08:00
WenmuZhou ef9490ed75 change gpus to selected_gpus 2020-12-10 17:28:30 +08:00
MissPenguin 94cce9093f
Merge pull request #1339 from WenmuZhou/py_inference_doc
[Dygraph] add py inference doc
2020-12-10 17:23:02 +08:00
WenmuZhou 2ed027a91c change selected_gpus to gpus 2020-12-10 17:20:10 +08:00
WenmuZhou 4561ec9798 update doc 2020-12-10 17:15:05 +08:00
WenmuZhou 042034b61d The parameters of export are consistent with the static image 2020-12-10 17:14:58 +08:00
LDOUBLEV cad5ea1144 update doc of db and installtion 2020-12-10 16:34:56 +08:00
tink2123 8520dd1e8c update readme 2020-12-10 14:21:23 +08:00
zhoujun 0458f0cc05
Merge pull request #13 from PaddlePaddle/dygraph
Dygraph
2020-12-10 12:26:52 +08:00
MissPenguin 836839bbf6
Merge pull request #1364 from LDOUBLEV/dyg_db
add ppocr_v2 ch_db
2020-12-10 11:02:26 +08:00
LDOUBLEV d97d98fe01 opt random sample 2020-12-10 11:00:05 +08:00
LDOUBLEV b8ba703548 delete data_num_per_epoch 2020-12-10 10:19:39 +08:00
LDOUBLEV e23c4de5d8 1.1 to 2.0 2020-12-10 10:12:50 +08:00
MissPenguin e65339eca7
Merge pull request #1374 from WenmuZhou/docker
[Dygraph] add docker depoly
2020-12-10 09:56:42 +08:00
WenmuZhou 81a1087ece Fix spelling errors 2020-12-10 00:58:24 +08:00
WenmuZhou 7e0324a4de reomve load_static_weights 2020-12-10 00:28:57 +08:00
WenmuZhou 0a28221d76 Update model conversion instructions 2020-12-10 00:26:19 +08:00
WenmuZhou 0ff2aef299 rename inference model save path 2020-12-09 23:59:29 +08:00
WenmuZhou 4fd696ccdf update inference model name 2020-12-09 23:55:38 +08:00
littletomatodonkey 2f67f2c839
fix config (#1373) 2020-12-09 23:47:06 +08:00
WenmuZhou c1ca9e3769 add docker depoly 2020-12-09 23:32:12 +08:00
zhoujun 19d66e6209 Merge branch 'dygraph' of https://github.com/PaddlePaddle/PaddleOCR into py_inference_doc 2020-12-09 22:45:35 +08:00
LDOUBLEV a5b219127f fix conflicts 2020-12-09 22:07:20 +08:00
xmy0916 ce518e552c fix doc algorithm&recognition en&ch 2020-12-09 20:45:56 +08:00
LDOUBLEV 7cce85cc5c fix conflicts 2020-12-09 20:44:43 +08:00
MissPenguin 055f207fcf
Merge pull request #1371 from tink2123/update_multi
update multi dic and export
2020-12-09 20:37:35 +08:00
LDOUBLEV e7ad27c399 fix conflicts 2020-12-09 20:30:50 +08:00
LDOUBLEV c0b4cefdcb fix comments and transform to transforms 2020-12-09 20:26:40 +08:00
tink2123 a31626759c update reademe for dygraph 2020-12-09 20:18:10 +08:00
MissPenguin 91f5ab5c30
Merge pull request #1365 from WenmuZhou/tree_doc
[Dygraph] add tree doc
2020-12-09 20:11:38 +08:00
tink2123 7eeef5933c update multi dic and export 2020-12-09 11:56:37 +00:00
WenmuZhou 204ab814f1 delete rename 2020-12-09 18:42:47 +08:00
WenmuZhou fa0ad0f4fd rename inference model name 2020-12-09 18:40:44 +08:00
WenmuZhou 13cc1f3c41 delete rename 2020-12-09 18:38:27 +08:00
WenmuZhou 72cbcc23e1 delete srn 2020-12-09 17:42:14 +08:00
WenmuZhou 25b8b35c9b add rare 2020-12-09 17:37:40 +08:00
MissPenguin 5b2f6b7524
Merge pull request #1368 from WenmuZhou/dygraph_rc
[Dygraph] add config file of DB, CRNN,Rosetta, StarNet
2020-12-09 17:36:37 +08:00
WenmuZhou 04b0318b56 Delete unused files 2020-12-09 17:27:50 +08:00
WenmuZhou af3ce2cd92 remove blank line 2020-12-09 17:27:30 +08:00
WenmuZhou 02da7ec53e add pretrain_models 2020-12-09 17:27:06 +08:00
WenmuZhou 8ac3423a17 add east and sast 2020-12-09 17:23:21 +08:00
MissPenguin bd7f8f72cc
Merge pull request #1363 from MissPenguin/dygraph
add east & sast
2020-12-09 17:04:34 +08:00
MissPenguin 3c9d3f6bf5
Merge pull request #1357 from WenmuZhou/add_new_algorithm
[Dygraph] add doc of how to add new algorithm
2020-12-09 16:55:46 +08:00
MissPenguin d42bf7a0b7 fix db postprocess 2020-12-09 08:51:43 +00:00
WenmuZhou f103634f75 Correction expression 2020-12-09 16:49:42 +08:00
MissPenguin 661e459e3e fix character_type 2020-12-09 08:48:27 +00:00
WenmuZhou 2af8f2a011 update quickstart doc, model link uses link as a placeholder 2020-12-09 16:35:55 +08:00
WenmuZhou 8524c2c60a update tree doc 2020-12-09 15:58:28 +08:00
MissPenguin 45f90e9431
Merge pull request #1338 from WenmuZhou/dygraph_rc
[Dygraph] add hub serving
2020-12-09 15:46:53 +08:00
MissPenguin 26eb83fbad
Merge pull request #1313 from WenmuZhou/config_doc
[Dygraph] add config file doc
2020-12-09 15:38:15 +08:00
LDOUBLEV 5f2f08a09c add ppocr_v2 ch_db 2020-12-09 14:59:04 +08:00
MissPenguin 021c1132a9 add east & sast 2020-12-09 06:45:25 +00:00
zhoujun a948584ca5
Merge pull request #1344 from WenmuZhou/update_angle_class_doc
paddleocr whl adaptation dygraph
2020-12-08 06:24:40 -06:00
WenmuZhou 3aae17e0d5 add doc of how to add new algorithm 2020-12-08 20:23:05 +08:00
xiaoting 0ecc335d9d
Merge pull request #1353 from tink2123/update_multi
update for multi-languages
2020-12-08 19:12:40 +08:00
tink2123 bccf9edf61 update for multi-language 2020-12-08 19:10:57 +08:00
tink2123 311569b2bc update for multi-language 2020-12-08 19:09:03 +08:00
tink2123 dd0f8c1d89 update for multi-language 2020-12-08 19:07:39 +08:00
xiaoting 8a5566c974
add multi lang yml and dict (#1312)
* add multi lang yml and dict

* update yml
2020-12-08 13:32:17 +08:00
WenmuZhou 28b2d43e57 paddleocr whl adaptation dygraph 2020-12-07 19:10:19 +08:00
WenmuZhou bccb261228 rename 地址 to link 2020-12-07 16:32:57 +08:00
WenmuZhou c654dbf709 add rec config on english dataset 2020-12-07 16:25:12 +08:00
WenmuZhou 98e5d59e9d add det ic15 config 2020-12-07 16:17:36 +08:00
WenmuZhou d986c22085 update inference doc 2020-12-07 15:48:46 +08:00
zhoujun eade2ce87a
Merge pull request #1308 from WenmuZhou/update_angle_class_doc
Update angle class doc
2020-12-07 01:46:04 -06:00
WenmuZhou 5d9c03890b merge upstream 2020-12-07 13:10:12 +08:00
WenmuZhou 2c8ba6a961 merge upstream 2020-12-07 12:51:40 +08:00
WenmuZhou 38f27a5339 merge upstream 2020-12-07 12:38:44 +08:00
zhoujun 99ee41d8db
Merge pull request #1299 from WenmuZhou/fix_predict_system
add predict_cls to predict_system
2020-12-06 20:28:37 -06:00
WenmuZhou cb371c1ecc first update inference.md 2020-12-04 17:09:28 +08:00
xmy0916 1e15b1d1c2 fix doc recognition ch&en 2020-12-03 19:58:35 +08:00
xmy0916 8ecaf41e82 fix doc algorithm_overview ch&en 2020-12-03 17:29:29 +08:00
WenmuZhou 8e914a869f update config file doc 2020-12-03 15:44:52 +08:00
WenmuZhou c6ab13203c update angle_class doc 2020-12-02 18:43:15 +08:00
WenmuZhou 34cd39194d use logger.info replace print 2020-12-02 15:55:28 +08:00
WenmuZhou a804a97c92 add drop_score to args 2020-12-02 15:55:15 +08:00
WenmuZhou e696c7906d delete debug code 2020-12-02 15:53:55 +08:00
zhoujun 2985e7b897
use cls_batch_num replace rec_batch_num (#1298) 2020-12-02 12:22:41 +08:00
WenmuZhou cb7afb8588 add hubserving 2020-12-01 17:46:50 +08:00
WenmuZhou 9fd163038f Merge branch 'dygraph_rc' of https://github.com/WenmuZhou/PaddleOCR into dygraph_rc 2020-12-01 16:46:31 +08:00
WenmuZhou a621bef893 add predict_cls to predict_system 2020-12-01 16:45:45 +08:00
WenmuZhou 902606499b add predict_cls to predict_system 2020-12-01 16:42:10 +08:00
WenmuZhou 7eede6b44b use cls_batch_num replace rec_batch_num 2020-12-01 15:44:04 +08:00
zhoujun 9b2c0e4838
Merge pull request #1235 from WenmuZhou/dygraph_rc
修复ips计算过少的问题
2020-11-30 22:48:28 -06:00
WenmuZhou 1c43e8bbb4 Adapt to windows 2020-11-30 16:54:18 +08:00
WenmuZhou a44c2a699f Adapt to windows 2020-11-30 16:48:51 +08:00
WenmuZhou bbc52fc993 Merge branch 'dygraph_rc' of https://github.com/WenmuZhou/PaddleOCR into dygraph_rc 2020-11-30 12:22:57 +08:00
WenmuZhou ef0880b9ae delete save_inference_mode fun, because the dev paddle has support export crnn model 2020-11-28 22:56:10 +08:00
WenmuZhou 5983e1af14 Remove redundant functions 2020-11-27 15:30:31 +08:00
WenmuZhou 835bfa456c Remove the channel conversion of the image and keep it consistent with the training phase 2020-11-27 15:29:14 +08:00
WenmuZhou 05dcfdec68 Fix the bug that the predict time is calculated incorrectly 2020-11-27 15:28:31 +08:00
littletomatodonkey c4fcd14354
refine dynamic sampling (#1256) 2020-11-26 21:32:33 +08:00
WenmuZhou 606a387354 删掉多余的判断 2020-11-24 16:01:00 +08:00
WenmuZhou 0da2cdb40c Merge branch 'dygraph' of https://github.com/PaddlePaddle/PaddleOCR into dygraph_rc 2020-11-24 15:51:44 +08:00
WenmuZhou 40023f76a6 修复ips和batch_cost输出错误的bug 2020-11-24 15:47:12 +08:00
littletomatodonkey 169b629b0f
fix error (#1177) 2020-11-21 23:02:18 +08:00
zhoujun bc563c642c
添加方向分类器 (#1184)
add cls module
2020-11-21 22:10:45 +08:00
Double_V c852b91647
Merge pull request #1212 from littletomatodonkey/2.0rc/add_server_cfg
add common ch config
2020-11-20 11:28:31 +08:00
littletomatodonkey 023aef4878 add common ch config 2020-11-20 02:38:08 +00:00
WenmuZhou 0c287c41ea python端预测完成 2020-11-17 17:28:28 +08:00
WenmuZhou 903b102f5f 分数取均值 2020-11-17 17:27:59 +08:00
WenmuZhou 31d48243b8 添加方向分类器 2020-11-17 14:07:39 +08:00
WenmuZhou c8f7a68314 merge upstream 2020-11-17 13:03:07 +08:00
zhoujun fc7b5d225b
Merge pull request #1181 from WenmuZhou/dygraph_rc
日志符合benckmark规范
2020-11-16 22:54:44 -06:00
WenmuZhou 4950c8458d 添加方向分类器 2020-11-17 12:54:24 +08:00
WenmuZhou 931d138bb3 更新日志格式 2020-11-16 19:11:42 +08:00
WenmuZhou 21fca149b2 添加空格 2020-11-16 19:02:00 +08:00
WenmuZhou e822901522 日志符合benchmark规范 2020-11-16 19:00:27 +08:00
Double_V 10b54d6696
Merge pull request #1168 from WenmuZhou/dygraph_rc
delete fluid
2020-11-15 15:01:22 +08:00
WenmuZhou d4facfe4e5 delete fluid 2020-11-13 17:01:41 +08:00
Double_V a40731aaac
Merge pull request #1164 from littletomatodonkey/2.0rc/add_rec_mobile
add ch lite yaml file
2020-11-13 11:36:19 +08:00
littletomatodonkey a0e72cf317 add try-catch to catch beautiful bugs 2020-11-12 15:55:52 +00:00
littletomatodonkey 1dc7e8942f fix some cute typos 2020-11-12 12:47:28 +00:00
littletomatodonkey 7a7059456a add ch lite yaml file 2020-11-12 12:44:56 +00:00
zhoujun c708041e13
CRNN导出 (#1159)
* 识别模型导出

* 识别模型inference
2020-11-12 19:42:32 +08:00
WenmuZhou d1affce65a delete fluid 2020-11-12 17:14:33 +08:00
WenmuZhou 453c6f68bd 识别模型inference 2020-11-12 12:07:41 +08:00
WenmuZhou 4d44b23043 识别模型导出 2020-11-12 12:06:46 +08:00
zhoujun 882ad39580
Merge pull request #1146 from WenmuZhou/dygraph_rc
add tps mdule
2020-11-11 13:15:51 +08:00
WenmuZhou 367c49dffd 删除 db torch后处理 2020-11-10 18:16:07 +08:00
WenmuZhou 33d9688014 更新NumpyArrayInitializer为Assign 2020-11-10 17:25:44 +08:00
WenmuZhou 65d3dfc729 rnn支持导出 2020-11-10 17:18:50 +08:00
WenmuZhou 2f9f258ff4 添加tps网络 2020-11-10 17:18:32 +08:00
WenmuZhou ff0f23d495 训练集shuffle改为false 2020-11-10 12:45:25 +08:00
dyning dc6e724efb
Merge pull request #1139 from WenmuZhou/dygraph_rc
新增功能
2020-11-09 19:19:57 +08:00
WenmuZhou b2004fe586 添加resnet backbone 2020-11-09 18:29:33 +08:00
WenmuZhou 4d775dc98f rc版本适配 2020-11-09 18:20:03 +08:00
WenmuZhou 44840726ff 后处理添加类型判断 2020-11-09 18:19:42 +08:00
WenmuZhou 4402e62959 修正export_model里的bug,添加predict_det 2020-11-09 18:19:30 +08:00
WenmuZhou 89e031f0e7 添加infer_det和infer_rec 2020-11-09 16:40:24 +08:00
MissPenguin b863528dcd
Merge pull request #1133 from WenmuZhou/dygraph_rc
fix bug and update save_load to rc version
2020-11-09 14:33:12 +08:00
WenmuZhou b28ea0a929 添加opencv依赖 2020-11-09 13:29:09 +08:00
WenmuZhou 672318256c 删除eval多余的参数 2020-11-09 13:28:46 +08:00
WenmuZhou 4eba6c0dce 修复一些导致不可用的bug 2020-11-09 13:28:15 +08:00
WenmuZhou 49958dca61 适配rc版本 2020-11-09 13:27:31 +08:00
dyning c93b4a171d
Merge pull request #1123 from WenmuZhou/dygraph_rc
fix some error and make some change
2020-11-06 19:34:23 +08:00
WenmuZhou a414dd8649 fix write error 2020-11-06 19:15:21 +08:00
WenmuZhou d2435e35bc change config path 2020-11-06 19:13:33 +08:00
WenmuZhou 6e4249eaf2 change python to python3 2020-11-06 19:12:34 +08:00
WenmuZhou 0c183d25d8 change config to baseline 2020-11-06 19:12:07 +08:00
WenmuZhou cafb2df8a6 change log name to root 2020-11-06 19:11:42 +08:00
WenmuZhou 91dee973da change log name to root 2020-11-06 19:11:35 +08:00
WenmuZhou 60f8f1e181 del unuse import 2020-11-06 19:09:52 +08:00
WenmuZhou 33c66f8ed3 add shuffle param 2020-11-06 19:02:04 +08:00
WenmuZhou 2aa92e6a64 fix bug 2020-11-06 18:56:53 +08:00
WenmuZhou 9467b75436 delete shuffle param 2020-11-06 18:56:05 +08:00
WenmuZhou 592bd60fe2 switch learning_rate and lr 2020-11-06 18:22:31 +08:00
WenmuZhou d9e921c743 change align_mode to 1 2020-11-06 18:15:44 +08:00
WenmuZhou 8f81956fc4 rename metric 2020-11-06 15:43:04 +08:00
WenmuZhou 695c4db7ea switch learning_rate and lr 2020-11-05 20:49:44 +08:00
WenmuZhou d092a5a22f switch learning_rate and lr 2020-11-05 20:47:16 +08:00
WenmuZhou 41b33c9e9c change KaimingNormal to KaimingUniform 2020-11-05 20:45:19 +08:00
dyning 96c9190710
Merge pull request #1105 from dyning/dygraph
updata structure of dygraph
2020-11-05 20:25:29 +08:00
dyning 1ae379198e trans to paddle-rc 2020-11-05 15:13:36 +08:00
dyning fa675f8954 updata structure of dygraph 2020-11-04 20:43:27 +08:00
dyning 7d09cd1928
Merge pull request #989 from WenmuZhou/dygraph
yml文件删掉一些个人路径
2020-10-27 13:38:43 +08:00
WenmuZhou e1b39945b8 注释更改为英文 2020-10-27 11:30:23 +08:00
WenmuZhou bbe375352e 删除check_static函数 2020-10-27 11:23:26 +08:00
WenmuZhou 122c82e93f 测试模式时将输出softmax后返回 2020-10-23 12:07:44 +08:00
WenmuZhou 6241b8f9ca 添加静态图的create_predictor 2020-10-22 19:03:24 +08:00
WenmuZhou 60711bafe2 添加静态图的create_predictor 2020-10-22 18:24:42 +08:00
WenmuZhou 08b3f98c4f 去掉注释 2020-10-22 18:22:56 +08:00
WenmuZhou 7c96520de7 yml文件去除个人路径 2020-10-22 18:20:20 +08:00
dyning f1048e296e
Merge pull request #970 from WenmuZhou/dygraph
解决crnn训练时对labels进行合并的bug
2020-10-20 19:21:25 +08:00
WenmuZhou 388d8dae33 删除个人目录 2020-10-20 17:47:38 +08:00
WenmuZhou 0968363a89 修复一处注释错误 2020-10-20 17:39:07 +08:00
WenmuZhou 8edc6f245b 删除配置文件里的个人路径 2020-10-20 17:38:24 +08:00
WenmuZhou a88ce7a5b6 修正对label decode时重复字符会消失的bug 2020-10-20 16:08:03 +08:00
WenmuZhou ca9ea622a9 添加im2seq实现 2020-10-20 16:07:19 +08:00
zhoujun 52b40f36e5
Merge pull request #952 from WenmuZhou/dygraph
使用PaddleClass的resnet_vd
2020-10-16 20:21:45 +08:00
WenmuZhou bdad0cefe6 检测和识别的resnet使用paddleclass里的 2020-10-16 20:19:17 +08:00
WenmuZhou 8f1b9c8b0d 对齐静态图时使用random数据 2020-10-16 20:18:45 +08:00
WenmuZhou 8626855142 配置文件默认renset layers修改为34 2020-10-16 20:17:44 +08:00
WenmuZhou 2463355632 hidden_size添加默认参数 2020-10-16 16:39:37 +08:00
WenmuZhou f5613aa9be num_workers改为8 2020-10-16 16:38:56 +08:00
WenmuZhou a75a614a43 修复test_loader函数不可用的问题 2020-10-16 16:37:44 +08:00
zhoujun 7d3ba1f13d
Merge pull request #926 from WenmuZhou/dygraph
update doc
2020-10-13 17:50:42 +08:00
WenmuZhou 8c000977dd update doc 2020-10-13 17:49:16 +08:00
zhoujun 4ffb5b621f
Merge pull request #924 from WenmuZhou/dygraph
Dygraph
2020-10-13 17:28:50 +08:00
WenmuZhou aad3093a91 dygraph first commit 2020-10-13 17:13:33 +08:00
619 changed files with 45140 additions and 59223 deletions

View File

@ -1,8 +1,7 @@
include LICENSE.txt
include README.md
recursive-include ppocr/utils *.txt utility.py character.py check.py
recursive-include ppocr/data/det *.py
recursive-include ppocr/utils *.txt utility.py logging.py
recursive-include ppocr/data/ *.py
recursive-include ppocr/postprocess *.py
recursive-include ppocr/postprocess/lanms *.*
recursive-include tools/infer *.py
recursive-include tools/infer *.py

35
PPOCRLabel/Makefile Normal file
View File

@ -0,0 +1,35 @@
# ex: set ts=8 noet:
all: qt5 test
test: testpy3
testpy2:
python -m unittest discover tests
testpy3:
python3 -m unittest discover tests
qt4: qt4py2
qt5: qt5py3
qt4py2:
pyrcc4 -py2 -o libs/resources.py resources.qrc
qt4py3:
pyrcc4 -py3 -o libs/resources.py resources.qrc
qt5py3:
pyrcc5 -o libs/resources.py resources.qrc
clean:
rm -rf ~/.labelImgSettings.pkl *.pyc dist labelImg.egg-info __pycache__ build
pip_upload:
python3 setup.py upload
long_description:
restview --long-description
.PHONY: all

2014
PPOCRLabel/PPOCRLabel.py Normal file

File diff suppressed because it is too large Load Diff

153
PPOCRLabel/README.md Normal file
View File

@ -0,0 +1,153 @@
English | [简体中文](README_ch.md)
# PPOCRLabel
PPOCRLabel is a semi-automatic graphic annotation tool suitable for OCR field. It is written in python3 and pyqt5, supporting rectangular box annotation and four-point annotation modes. Annotations can be directly used for the training of PPOCR detection and recognition models.
<img src="./data/gif/steps_en.gif" width="100%"/>
### Recent Update
- 2020.12.18: Support re-recognition of a single label box (by [ninetailskim](https://github.com/ninetailskim) ), perfect shortcut keys.
## Installation
### 1. Install PaddleOCR
Refer to [PaddleOCR installation document](https://github.com/PaddlePaddle/PaddleOCR/blob/develop/doc/doc_ch/installation.md) to prepare PaddleOCR
### 2. Install PPOCRLabel
#### Windows + Anaconda
Download and install [Anaconda](https://www.anaconda.com/download/#download) (Python 3+)
```
pip install pyqt5
cd ./PPOCRLabel # Change the directory to the PPOCRLabel folder
python PPOCRLabel.py
```
#### Ubuntu Linux
```
pip3 install pyqt5
pip3 install trash-cli
cd ./PPOCRLabel # Change the directory to the PPOCRLabel folder
python3 PPOCRLabel.py
```
#### macOS
```
pip3 install pyqt5
pip3 uninstall opencv-python # Uninstall opencv manually as it conflicts with pyqt
pip3 install opencv-contrib-python-headless # Install the headless version of opencv
cd ./PPOCRLabel # Change the directory to the PPOCRLabel folder
python3 PPOCRLabel.py
```
## Usage
### Steps
1. Build and launch using the instructions above.
2. Click 'Open Dir' in Menu/File to select the folder of the picture.<sup>[1]</sup>
3. Click 'Auto recognition', use PPOCR model to automatically annotate images which marked with 'X' <sup>[2]</sup>before the file name.
4. Create Box:
4.1 Click 'Create RectBox' or press 'W' in English keyboard mode to draw a new rectangle detection box. Click and release left mouse to select a region to annotate the text area.
4.2 Press 'P' to enter four-point labeling mode which enables you to create any four-point shape by clicking four points with the left mouse button in succession and DOUBLE CLICK the left mouse as the signal of labeling completion.
5. After the marking frame is drawn, the user clicks "OK", and the detection frame will be pre-assigned a "TEMPORARY" label.
6. Click 're-Recognition', model will rewrite ALL recognition results in ALL detection box<sup>[3]</sup>.
7. Double click the result in 'recognition result' list to manually change inaccurate recognition results.
8. Click "Check", the image status will switch to "√",then the program automatically jump to the next(The results will not be written directly to the file at this time).
9. Click "Delete Image" and the image will be deleted to the recycle bin.
10. Labeling result: the user can save manually through the menu "File - Save Label", while the program will also save automatically after every 10 images confirmed by the user.the manually checked label will be stored in *Label.txt* under the opened picture folder.
Click "PaddleOCR"-"Save Recognition Results" in the menu bar, the recognition training data of such pictures will be saved in the *crop_img* folder, and the recognition label will be saved in *rec_gt.txt*<sup>[4]</sup>.
### Note
[1] PPOCRLabel uses the opened folder as the project. After opening the image folder, the picture will not be displayed in the dialog. Instead, the pictures under the folder will be directly imported into the program after clicking "Open Dir".
[2] The image status indicates whether the user has saved the image manually. If it has not been saved manually it is "X", otherwise it is "√", PPOCRLabel will not relabel pictures with a status of "√".
[3] After clicking "Re-recognize", the model will overwrite ALL recognition results in the picture.
Therefore, if the recognition result has been manually changed before, it may change after re-recognition.
[4] The files produced by PPOCRLabel can be found under the opened picture folder including the following, please do not manually change the contents, otherwise it will cause the program to be abnormal.
| File name | Description |
| :-----------: | :----------------------------------------------------------: |
| Label.txt | The detection label file can be directly used for PPOCR detection model training. After the user saves 10 label results, the file will be automatically saved. It will also be written when the user closes the application or changes the file folder. |
| fileState.txt | The picture status file save the image in the current folder that has been manually confirmed by the user. |
| Cache.cach | Cache files to save the results of model recognition. |
| rec_gt.txt | The recognition label file, which can be directly used for PPOCR identification model training, is generated after the user clicks on the menu bar "File"-"Save recognition result". |
| crop_img | The recognition data, generated at the same time with *rec_gt.txt* |
## Explanation
### Shortcut keys
| Shortcut keys | Description |
| ---------------- | ------------------------------------------------ |
| Ctrl + shift + A | Automatically label all unchecked images |
| Ctrl + shift + R | Re-recognize all the labels of the current image |
| W | Create a rect box |
| Q | Create a four-points box |
| Ctrl + E | Edit label of the selected box |
| Ctrl + R | Re-recognize the selected box |
| Backspace | Delete the selected box |
| Ctrl + V | Check image |
| Ctrl + Shift + d | Delete image |
| D | Next image |
| A | Previous image |
| Ctrl++ | Zoom in |
| Ctrl-- | Zoom out |
| ↑→↓← | Move selected box |
### Built-in Model
- Default model: PPOCRLabel uses the Chinese and English ultra-lightweight OCR model in PaddleOCR by default, supports Chinese, English and number recognition, and multiple language detection.
- Model language switching: Changing the built-in model language is supportable by clicking "PaddleOCR"-"Choose OCR Model" in the menu bar. Currently supported languagesinclude French, German, Korean, and Japanese.
For specific model download links, please refer to [PaddleOCR Model List](https://github.com/PaddlePaddle/PaddleOCR/blob/develop/doc/doc_en/models_list_en.md#multilingual-recognition-modelupdating)
- Custom model: The model trained by users can be replaced by modifying PPOCRLabel.py in [PaddleOCR class instantiation](https://github.com/PaddlePaddle/PaddleOCR/blob/develop/PPOCRLabel/PPOCRLabel.py#L110) referring [Custom Model Code](https://github.com/PaddlePaddle/PaddleOCR/blob/develop/doc/doc_en/whl_en.md#use-custom-model)
### Export partial recognition results
For some data that are difficult to recognize, the recognition results will not be exported by **unchecking** the corresponding tags in the recognition results checkbox.
*Note: The status of the checkboxes in the recognition results still needs to be saved manually by clicking Save Button.*
### Error message
- If paddleocr is installed with whl, it has a higher priority than calling PaddleOCR class with paddleocr.py, which may cause an exception if whl package is not updated.
- For Linux users, if you get an error starting with **objc[XXXXX]** when opening the software, it proves that your opencv version is too high. It is recommended to install version 4.2:
```
pip install opencv-python==4.2.0.32
```
- If you get an error starting with **Missing string id **,you need to recompile resources:
```
pyrcc5 -o libs/resources.py resources.qrc
```
- If you get an error ``` module 'cv2' has no attribute 'INTER_NEAREST'```, you need to delete all opencv related packages first, and then reinstall the headless version of opencv
```
pip install opencv-contrib-python-headless
```
### Related
1.[Tzutalin. LabelImg. Git code (2015)](https://github.com/tzutalin/labelImg)

134
PPOCRLabel/README_ch.md Normal file
View File

@ -0,0 +1,134 @@
[English](README.md) | 简体中文
# PPOCRLabel
PPOCRLabel是一款适用于OCR领域的半自动化图形标注工具使用python3和pyqt5编写支持矩形框标注和四点标注模式导出格式可直接用于PPOCR检测和识别模型的训练。
<img src="./data/gif/steps.gif" width="100%"/>
#### 近期更新
- 2020.12.18: 支持对单个标记框进行重新识别by [ninetailskim](https://github.com/ninetailskim) ),完善快捷键。
## 安装
### 1. 安装PaddleOCR
参考[PaddleOCR安装文档](https://github.com/PaddlePaddle/PaddleOCR/blob/develop/doc/doc_ch/installation.md)准备好PaddleOCR
### 2. 安装PPOCRLabel
#### Windows + Anaconda
```
pip install pyqt5
cd ./PPOCRLabel # 将目录切换到PPOCRLabel文件夹下
python PPOCRLabel.py --lang ch
```
#### Ubuntu Linux
```
pip3 install pyqt5
pip3 install trash-cli
cd ./PPOCRLabel # 将目录切换到PPOCRLabel文件夹下
python3 PPOCRLabel.py --lang ch
```
#### macOS
```
pip3 install pyqt5
pip3 uninstall opencv-python # 由于mac版本的opencv与pyqt有冲突需先手动卸载opencv
pip3 install opencv-contrib-python-headless # 安装headless版本的open-cv
cd ./PPOCRLabel # 将目录切换到PPOCRLabel文件夹下
python3 PPOCRLabel.py --lang ch
```
## 使用
### 操作步骤
1. 安装与运行:使用上述命令安装与运行程序。
2. 打开文件夹:在菜单栏点击 “文件” - "打开目录" 选择待标记图片的文件夹<sup>[1]</sup>.
3. 自动标注:点击 ”自动标注“使用PPOCR超轻量模型对图片文件名前图片状态<sup>[2]</sup>为 “X” 的图片进行自动标注。
4. 手动标注:点击 “矩形标注”(推荐直接在英文模式下点击键盘中的 “W”)用户可对当前图片中模型未检出的部分进行手动绘制标记框。点击键盘P则使用四点标注模式或点击“编辑” - “四点标注”用户依次点击4个点后双击左键表示标注完成。
5. 标记框绘制完成后,用户点击 “确认”,检测框会先被预分配一个 “待识别” 标签。
6. 重新识别:将图片中的所有检测画绘制/调整完成后,点击 “重新识别”PPOCR模型会对当前图片中的**所有检测框**重新识别<sup>[3]</sup>
7. 内容更改:双击识别结果,对不准确的识别结果进行手动更改。
8. 确认标记:点击 “确认”,图片状态切换为 “√”,跳转至下一张(此时不会直接将结果写入文件)。
9. 删除:点击 “删除图像”,图片将会被删除至回收站。
10. 保存结果:用户可以通过菜单中“文件-保存标记结果”手动保存同时程序也会在用户每确认10张图片后自动保存一次。手动确认过的标记将会被存放在所打开图片文件夹下的*Label.txt*中。在菜单栏点击 “文件” - "保存识别结果"后,会将此类图片的识别训练数据保存在*crop_img*文件夹下,识别标签保存在*rec_gt.txt*中<sup>[4]</sup>
### 注意
[1] PPOCRLabel以文件夹为基本标记单位打开待标记的图片文件夹后不会在窗口栏中显示图片而是在点击 "选择文件夹" 之后直接将文件夹下的图片导入到程序中。
[2] 图片状态表示本张图片用户是否手动保存过,未手动保存过即为 “X”手动保存过为 “√”。点击 “自动标注”按钮后PPOCRLabel不会对状态为 “√” 的图片重新标注。
[3] 点击“重新识别”后,模型会对图片中的识别结果进行覆盖。因此如果在此之前手动更改过识别结果,有可能在重新识别后产生变动。
[4] PPOCRLabel产生的文件放置于标记图片文件夹下包括一下几种请勿手动更改其中内容否则会引起程序出现异常。
| 文件名 | 说明 |
| :-----------: | :----------------------------------------------------------: |
| Label.txt | 检测标签可直接用于PPOCR检测模型训练。用户每保存10张检测结果后程序会进行自动写入。当用户关闭应用程序或切换文件路径后同样会进行写入。 |
| fileState.txt | 图片状态标记文件,保存当前文件夹下已经被用户手动确认过的图片名称。 |
| Cache.cach | 缓存文件,保存模型自动识别的结果。 |
| rec_gt.txt | 识别标签。可直接用于PPOCR识别模型训练。需用户手动点击菜单栏“文件” - "保存识别结果"后产生。 |
| crop_img | 识别数据。按照检测框切割后的图片。与rec_gt.txt同时产生。 |
## 说明
### 快捷键
| 快捷键 | 说明 |
| ---------------- | ---------------------------- |
| Ctrl + shift + A | 自动标注所有未确认过的图片 |
| Ctrl + shift + R | 对当前图片的所有标记重新识别 |
| W | 新建矩形框 |
| Q | 新建四点框 |
| Ctrl + E | 编辑所选框标签 |
| Ctrl + R | 重新识别所选标记 |
| Backspace | 删除所选框 |
| Ctrl + V | 确认本张图片标记 |
| Ctrl + Shift + d | 删除本张图片 |
| D | 下一张图片 |
| A | 上一张图片 |
| Ctrl++ | 缩小 |
| Ctrl-- | 放大 |
| ↑→↓← | 移动标记框 |
### 内置模型
- 默认模型PPOCRLabel默认使用PaddleOCR中的中英文超轻量OCR模型支持中英文与数字识别多种语言检测。
- 模型语言切换:用户可通过菜单栏中 "PaddleOCR" - "选择模型" 切换内置模型语言,目前支持的语言包括法文、德文、韩文、日文。具体模型下载链接可参考[PaddleOCR模型列表](https://github.com/PaddlePaddle/PaddleOCR/blob/develop/doc/doc_ch/models_list.md).
- 自定义模型:用户可根据[自定义模型代码使用](https://github.com/PaddlePaddle/PaddleOCR/blob/develop/doc/doc_ch/whl.md#%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A8%A1%E5%9E%8B)通过修改PPOCRLabel.py中针对[PaddleOCR类的实例化](https://github.com/PaddlePaddle/PaddleOCR/blob/develop/PPOCRLabel/PPOCRLabel.py#L110)替换成自己训练的模型。
### 导出部分识别结果
针对部分难以识别的数据,通过在识别结果的复选框中**取消勾选**相应的标记,其识别结果不会被导出。
*注意:识别结果中的复选框状态仍需用户手动点击保存后才能保留*
### 错误提示
- 如果同时使用whl包安装了paddleocr其优先级大于通过paddleocr.py调用PaddleOCR类whl包未更新时会导致程序异常。
- PPOCRLabel**不支持对中文文件名**的图片进行自动标注。
- 针对Linux用户如果您在打开软件过程中出现**objc[XXXXX]**开头的错误证明您的opencv版本太高建议安装4.2版本:
```
pip install opencv-python==4.2.0.32
```
- 如果出现 ```Missing string id``` 开头的错误,需要重新编译资源:
```
pyrcc5 -o libs/resources.py resources.qrc
```
- 如果出现``` module 'cv2' has no attribute 'INTER_NEAREST'```错误需要首先删除所有opencv相关包然后重新安装headless版本的opencv
```
pip install opencv-contrib-python-headless
```
### 参考资料
1.[Tzutalin. LabelImg. Git code (2015)](https://github.com/tzutalin/labelImg)

46
PPOCRLabel/combobox.py Normal file
View File

@ -0,0 +1,46 @@
# Copyright (c) <2015-Present> Tzutalin
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import sys
try:
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QComboBox
except ImportError:
# needed for py3+qt4
# Ref:
# http://pyqt.sourceforge.net/Docs/PyQt4/incompatible_apis.html
# http://stackoverflow.com/questions/21217399/pyqt4-qtcore-qvariant-object-instead-of-a-string
if sys.version_info.major >= 3:
import sip
sip.setapi('QVariant', 2)
from PyQt4.QtGui import QWidget, QHBoxLayout, QComboBox
class ComboBox(QWidget):
def __init__(self, parent=None, items=[]):
super(ComboBox, self).__init__(parent)
layout = QHBoxLayout()
self.cb = QComboBox()
self.items = items
self.cb.addItems(self.items)
self.cb.currentIndexChanged.connect(parent.comboSelectionChanged)
layout.addWidget(self.cb)
self.setLayout(layout)
def update_items(self, items):
self.items = items
self.cb.clear()
self.cb.addItems(self.items)

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 MiB

BIN
PPOCRLabel/data/paddle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

View File

@ -0,0 +1,2 @@
__version_info__ = ('1', '0', '0')
__version__ = '.'.join(__version_info__)

View File

@ -0,0 +1,155 @@
try:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
except ImportError:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import json
from libs.utils import newIcon
BB = QDialogButtonBox
class Worker(QThread):
progressBarValue = pyqtSignal(int)
listValue = pyqtSignal(str)
endsignal = pyqtSignal(int, str)
handle = 0
def __init__(self, ocr, mImgList, mainThread, model):
super(Worker, self).__init__()
self.ocr = ocr
self.mImgList = mImgList
self.mainThread = mainThread
self.model = model
self.setStackSize(1024*1024)
def run(self):
try:
findex = 0
for Imgpath in self.mImgList:
if self.handle == 0:
self.listValue.emit(Imgpath)
if self.model == 'paddle':
self.result_dic = self.ocr.ocr(Imgpath, cls=True, det=True)
# 结果保存
if self.result_dic is None or len(self.result_dic) == 0:
print('Can not recognise file is : ', Imgpath)
pass
else:
strs = ''
for res in self.result_dic:
chars = res[1][0]
cond = res[1][1]
posi = res[0]
strs += "Transcription: " + chars + " Probability: " + str(cond) + \
" Location: " + json.dumps(posi) +'\n'
# Sending large amounts of data repeatedly through pyqtSignal may affect the program efficiency
self.listValue.emit(strs)
self.mainThread.result_dic = self.result_dic
self.mainThread.filePath = Imgpath
# 保存
self.mainThread.saveFile(mode='Auto')
findex += 1
self.progressBarValue.emit(findex)
else:
break
self.endsignal.emit(0, "readAll")
self.exec()
except Exception as e:
print(e)
raise
class AutoDialog(QDialog):
def __init__(self, text="Enter object label", parent=None, ocr=None, mImgList=None, lenbar=0):
super(AutoDialog, self).__init__(parent)
self.setFixedWidth(1000)
self.parent = parent
self.ocr = ocr
self.mImgList = mImgList
self.pb = QProgressBar()
self.pb.setRange(0, lenbar)
self.pb.setValue(0)
layout = QVBoxLayout()
layout.addWidget(self.pb)
self.model = 'paddle'
self.listWidget = QListWidget(self)
layout.addWidget(self.listWidget)
self.buttonBox = bb = BB(BB.Ok | BB.Cancel, Qt.Horizontal, self)
bb.button(BB.Ok).setIcon(newIcon('done'))
bb.button(BB.Cancel).setIcon(newIcon('undo'))
bb.accepted.connect(self.validate)
bb.rejected.connect(self.reject)
layout.addWidget(bb)
bb.button(BB.Ok).setEnabled(False)
self.setLayout(layout)
# self.setWindowTitle("自动标注中")
self.setWindowModality(Qt.ApplicationModal)
# self.setWindowFlags(Qt.WindowCloseButtonHint)
self.thread_1 = Worker(self.ocr, self.mImgList, self.parent, 'paddle')
self.thread_1.progressBarValue.connect(self.handleProgressBarSingal)
self.thread_1.listValue.connect(self.handleListWidgetSingal)
self.thread_1.endsignal.connect(self.handleEndsignalSignal)
def handleProgressBarSingal(self, i):
self.pb.setValue(i)
def handleListWidgetSingal(self, i):
self.listWidget.addItem(i)
titem = self.listWidget.item(self.listWidget.count() - 1)
self.listWidget.scrollToItem(titem)
def handleEndsignalSignal(self, i, str):
if i == 0 and str == "readAll":
self.buttonBox.button(BB.Ok).setEnabled(True)
self.buttonBox.button(BB.Cancel).setEnabled(False)
def reject(self):
print("reject")
self.thread_1.handle = -1
self.thread_1.quit()
# del self.thread_1
# if self.thread_1.isRunning():
# self.thread_1.terminate()
# self.thread_1.quit()
# super(AutoDialog,self).reject()
while not self.thread_1.isFinished():
pass
self.accept()
def validate(self):
self.accept()
def postProcess(self):
try:
self.edit.setText(self.edit.text().trimmed())
# print(self.edit.text())
except AttributeError:
# PyQt5: AttributeError: 'str' object has no attribute 'trimmed'
self.edit.setText(self.edit.text())
print(self.edit.text())
def popUp(self):
self.thread_1.start()
return 1 if self.exec_() else None
def closeEvent(self, event):
print("???")
# if self.thread_1.isRunning():
# self.thread_1.quit()
#
# # self._thread.terminate()
# # del self.thread_1
# super(AutoDialog, self).closeEvent(event)
self.reject()

798
PPOCRLabel/libs/canvas.py Normal file
View File

@ -0,0 +1,798 @@
# Copyright (c) <2015-Present> Tzutalin
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
try:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
except ImportError:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
#from PyQt4.QtOpenGL import *
from libs.shape import Shape
from libs.utils import distance
CURSOR_DEFAULT = Qt.ArrowCursor
CURSOR_POINT = Qt.PointingHandCursor
CURSOR_DRAW = Qt.CrossCursor
CURSOR_MOVE = Qt.ClosedHandCursor
CURSOR_GRAB = Qt.OpenHandCursor
# class Canvas(QGLWidget):
class Canvas(QWidget):
zoomRequest = pyqtSignal(int)
scrollRequest = pyqtSignal(int, int)
newShape = pyqtSignal()
selectionChanged = pyqtSignal(bool)
shapeMoved = pyqtSignal()
drawingPolygon = pyqtSignal(bool)
CREATE, EDIT = list(range(2))
_fill_drawing = False # draw shadows
epsilon = 11.0
def __init__(self, *args, **kwargs):
super(Canvas, self).__init__(*args, **kwargs)
# Initialise local state.
self.mode = self.EDIT
self.shapes = []
self.current = None
self.selectedShape = None # save the selected shape here
self.selectedShapeCopy = None
self.drawingLineColor = QColor(0, 0, 255)
self.drawingRectColor = QColor(0, 0, 255)
self.line = Shape(line_color=self.drawingLineColor)
self.prevPoint = QPointF()
self.offsets = QPointF(), QPointF()
self.scale = 1.0
self.pixmap = QPixmap()
self.visible = {}
self._hideBackround = False
self.hideBackround = False
self.hShape = None
self.hVertex = None
self._painter = QPainter()
self._cursor = CURSOR_DEFAULT
# Menus:
self.menus = (QMenu(), QMenu())
# Set widget options.
self.setMouseTracking(True)
self.setFocusPolicy(Qt.WheelFocus)
self.verified = False
self.drawSquare = False
self.fourpoint = True # ADD
self.pointnum = 0
#initialisation for panning
self.pan_initial_pos = QPoint()
def setDrawingColor(self, qColor):
self.drawingLineColor = qColor
self.drawingRectColor = qColor
def enterEvent(self, ev):
self.overrideCursor(self._cursor)
def leaveEvent(self, ev):
self.restoreCursor()
def focusOutEvent(self, ev):
self.restoreCursor()
def isVisible(self, shape):
return self.visible.get(shape, True)
def drawing(self):
return self.mode == self.CREATE
def editing(self):
return self.mode == self.EDIT
def setEditing(self, value=True):
self.mode = self.EDIT if value else self.CREATE
if not value: # Create
self.unHighlight()
self.deSelectShape()
self.prevPoint = QPointF()
self.repaint()
def unHighlight(self):
if self.hShape:
self.hShape.highlightClear()
self.hVertex = self.hShape = None
def selectedVertex(self):
return self.hVertex is not None
def mouseMoveEvent(self, ev):
"""Update line with last point and current coordinates."""
pos = self.transformPos(ev.pos())
# Update coordinates in status bar if image is opened
window = self.parent().window()
if window.filePath is not None:
self.parent().window().labelCoordinates.setText(
'X: %d; Y: %d' % (pos.x(), pos.y()))
# Polygon drawing.
if self.drawing():
self.overrideCursor(CURSOR_DRAW) # ?
if self.current:
# Display annotation width and height while drawing
currentWidth = abs(self.current[0].x() - pos.x())
currentHeight = abs(self.current[0].y() - pos.y())
self.parent().window().labelCoordinates.setText(
'Width: %d, Height: %d / X: %d; Y: %d' % (currentWidth, currentHeight, pos.x(), pos.y()))
color = self.drawingLineColor
if self.outOfPixmap(pos):
# Don't allow the user to draw outside the pixmap.
# Clip the coordinates to 0 or max,
# if they are outside the range [0, max]
size = self.pixmap.size()
clipped_x = min(max(0, pos.x()), size.width())
clipped_y = min(max(0, pos.y()), size.height())
pos = QPointF(clipped_x, clipped_y)
elif len(self.current) > 1 and self.closeEnough(pos, self.current[0]) and not self.fourpoint:
# Attract line to starting point and colorise to alert the
# user:
pos = self.current[0]
color = self.current.line_color
self.overrideCursor(CURSOR_POINT)
self.current.highlightVertex(0, Shape.NEAR_VERTEX)
elif ( # ADD
len(self.current) > 1
and self.fourpoint
and self.closeEnough(pos, self.current[0])
):
# Attract line to starting point and
# colorise to alert the user.
pos = self.current[0]
self.overrideCursor(CURSOR_POINT)
self.current.highlightVertex(0, Shape.NEAR_VERTEX)
if self.drawSquare:
initPos = self.current[0]
minX = initPos.x()
minY = initPos.y()
min_size = min(abs(pos.x() - minX), abs(pos.y() - minY))
directionX = -1 if pos.x() - minX < 0 else 1
directionY = -1 if pos.y() - minY < 0 else 1
self.line[1] = QPointF(minX + directionX * min_size, minY + directionY * min_size)
elif self.fourpoint:
# self.line[self.pointnum] = pos # OLD
self.line[0] = self.current[-1]
self.line[1] = pos
else:
self.line[1] = pos # pos is the mouse's current position
self.line.line_color = color
self.prevPoint = QPointF() #
self.current.highlightClear()
else:
self.prevPoint = pos
self.repaint()
return
# Polygon copy moving.
if Qt.RightButton & ev.buttons():
if self.selectedShapeCopy and self.prevPoint:
self.overrideCursor(CURSOR_MOVE)
self.boundedMoveShape(self.selectedShapeCopy, pos)
self.repaint()
elif self.selectedShape:
self.selectedShapeCopy = self.selectedShape.copy()
self.repaint()
return
# Polygon/Vertex moving.
if Qt.LeftButton & ev.buttons():
if self.selectedVertex():
self.boundedMoveVertex(pos)
self.shapeMoved.emit()
self.repaint()
elif self.selectedShape and self.prevPoint:
self.overrideCursor(CURSOR_MOVE)
self.boundedMoveShape(self.selectedShape, pos)
self.shapeMoved.emit()
self.repaint()
else:
#pan
delta_x = pos.x() - self.pan_initial_pos.x()
delta_y = pos.y() - self.pan_initial_pos.y()
self.scrollRequest.emit(delta_x, Qt.Horizontal)
self.scrollRequest.emit(delta_y, Qt.Vertical)
self.update()
return
# Just hovering over the canvas, 2 posibilities:
# - Highlight shapes
# - Highlight vertex
# Update shape/vertex fill and tooltip value accordingly.
self.setToolTip("Image")
for shape in reversed([s for s in self.shapes if self.isVisible(s)]):
# Look for a nearby vertex to highlight. If that fails,
# check if we happen to be inside a shape.
index = shape.nearestVertex(pos, self.epsilon)
if index is not None:
if self.selectedVertex():
self.hShape.highlightClear()
self.hVertex, self.hShape = index, shape
shape.highlightVertex(index, shape.MOVE_VERTEX)
self.overrideCursor(CURSOR_POINT)
self.setToolTip("Click & drag to move point")
self.setStatusTip(self.toolTip())
self.update()
break
elif shape.containsPoint(pos):
if self.selectedVertex():
self.hShape.highlightClear()
self.hVertex, self.hShape = None, shape
self.setToolTip(
"Click & drag to move shape '%s'" % shape.label)
self.setStatusTip(self.toolTip())
self.overrideCursor(CURSOR_GRAB)
self.update()
break
else: # Nothing found, clear highlights, reset state.
if self.hShape:
self.hShape.highlightClear()
self.update()
self.hVertex, self.hShape = None, None
self.overrideCursor(CURSOR_DEFAULT)
def mousePressEvent(self, ev):
pos = self.transformPos(ev.pos())
if ev.button() == Qt.LeftButton:
if self.drawing():
# self.handleDrawing(pos) # OLD
if self.current and self.fourpoint: # ADD IF
# Add point to existing shape.
print('Adding points in mousePressEvent is ', self.line[1])
self.current.addPoint(self.line[1])
self.line[0] = self.current[-1]
if self.current.isClosed():
# print('1111')
self.finalise()
elif not self.outOfPixmap(pos):
# Create new shape.
self.current = Shape()# self.current = Shape(shape_type=self.createMode)
self.current.addPoint(pos)
# if self.createMode == "point":
# self.finalise()
# else:
# if self.createMode == "circle":
# self.current.shape_type = "circle"
self.line.points = [pos, pos]
self.setHiding()
self.drawingPolygon.emit(True)
self.update()
else:
selection = self.selectShapePoint(pos)
self.prevPoint = pos
if selection is None:
#pan
QApplication.setOverrideCursor(QCursor(Qt.OpenHandCursor))
self.pan_initial_pos = pos
elif ev.button() == Qt.RightButton and self.editing():
self.selectShapePoint(pos)
self.prevPoint = pos
self.update()
def mouseReleaseEvent(self, ev):
if ev.button() == Qt.RightButton:
menu = self.menus[bool(self.selectedShapeCopy)]
self.restoreCursor()
if not menu.exec_(self.mapToGlobal(ev.pos()))\
and self.selectedShapeCopy:
# Cancel the move by deleting the shadow copy.
self.selectedShapeCopy = None
self.repaint()
elif ev.button() == Qt.LeftButton and self.selectedShape: # OLD
if self.selectedVertex():
self.overrideCursor(CURSOR_POINT)
else:
self.overrideCursor(CURSOR_GRAB)
elif ev.button() == Qt.LeftButton and not self.fourpoint:
pos = self.transformPos(ev.pos())
if self.drawing():
self.handleDrawing(pos)
else:
#pan
QApplication.restoreOverrideCursor() # ?
def endMove(self, copy=False):
assert self.selectedShape and self.selectedShapeCopy
shape = self.selectedShapeCopy
#del shape.fill_color
#del shape.line_color
if copy:
self.shapes.append(shape)
self.selectedShape.selected = False
self.selectedShape = shape
self.repaint()
else:
self.selectedShape.points = [p for p in shape.points]
self.selectedShapeCopy = None
def hideBackroundShapes(self, value):
self.hideBackround = value
if self.selectedShape:
# Only hide other shapes if there is a current selection.
# Otherwise the user will not be able to select a shape.
self.setHiding(True)
self.repaint()
def handleDrawing(self, pos):
if self.current and self.current.reachMaxPoints() is False:
if self.fourpoint:
targetPos = self.line[self.pointnum]
self.current.addPoint(targetPos)
print('current points in handleDrawing is ', self.line[self.pointnum])
self.update()
if self.pointnum == 3:
self.finalise()
else: # 按住送掉后跳到这里
initPos = self.current[0]
print('initPos', self.current[0])
minX = initPos.x()
minY = initPos.y()
targetPos = self.line[1]
maxX = targetPos.x()
maxY = targetPos.y()
self.current.addPoint(QPointF(maxX, minY))
self.current.addPoint(targetPos)
self.current.addPoint(QPointF(minX, maxY))
self.finalise()
elif not self.outOfPixmap(pos):
print('release')
self.current = Shape()
self.current.addPoint(pos)
self.line.points = [pos, pos]
self.setHiding()
self.drawingPolygon.emit(True)
self.update()
def setHiding(self, enable=True):
self._hideBackround = self.hideBackround if enable else False
def canCloseShape(self):
return self.drawing() and self.current and len(self.current) > 2
def mouseDoubleClickEvent(self, ev):
# We need at least 4 points here, since the mousePress handler
# adds an extra one before this handler is called.
if self.canCloseShape() and len(self.current) > 3:
if not self.fourpoint:
self.current.popPoint()
self.finalise()
def selectShape(self, shape):
self.deSelectShape()
shape.selected = True
self.selectedShape = shape
self.setHiding()
self.selectionChanged.emit(True)
self.update()
def selectShapePoint(self, point):
"""Select the first shape created which contains this point."""
self.deSelectShape()
if self.selectedVertex(): # A vertex is marked for selection.
index, shape = self.hVertex, self.hShape
shape.highlightVertex(index, shape.MOVE_VERTEX)
self.selectShape(shape)
return self.hVertex
for shape in reversed(self.shapes):
if self.isVisible(shape) and shape.containsPoint(point):
self.selectShape(shape)
self.calculateOffsets(shape, point)
return self.selectedShape
return None
def calculateOffsets(self, shape, point):
rect = shape.boundingRect()
x1 = rect.x() - point.x()
y1 = rect.y() - point.y()
x2 = (rect.x() + rect.width()) - point.x()
y2 = (rect.y() + rect.height()) - point.y()
self.offsets = QPointF(x1, y1), QPointF(x2, y2)
def snapPointToCanvas(self, x, y):
"""
Moves a point x,y to within the boundaries of the canvas.
:return: (x,y,snapped) where snapped is True if x or y were changed, False if not.
"""
if x < 0 or x > self.pixmap.width() or y < 0 or y > self.pixmap.height():
x = max(x, 0)
y = max(y, 0)
x = min(x, self.pixmap.width())
y = min(y, self.pixmap.height())
return x, y, True
return x, y, False
def boundedMoveVertex(self, pos):
index, shape = self.hVertex, self.hShape
point = shape[index]
if self.outOfPixmap(pos):
size = self.pixmap.size()
clipped_x = min(max(0, pos.x()), size.width())
clipped_y = min(max(0, pos.y()), size.height())
pos = QPointF(clipped_x, clipped_y)
if self.drawSquare:
opposite_point_index = (index + 2) % 4
opposite_point = shape[opposite_point_index]
min_size = min(abs(pos.x() - opposite_point.x()), abs(pos.y() - opposite_point.y()))
directionX = -1 if pos.x() - opposite_point.x() < 0 else 1
directionY = -1 if pos.y() - opposite_point.y() < 0 else 1
shiftPos = QPointF(opposite_point.x() + directionX * min_size - point.x(),
opposite_point.y() + directionY * min_size - point.y())
else:
shiftPos = pos - point
shape.moveVertexBy(index, shiftPos)
lindex = (index + 1) % 4
rindex = (index + 3) % 4
lshift = None
rshift = None
if index % 2 == 0:
rshift = QPointF(shiftPos.x(), 0)
lshift = QPointF(0, shiftPos.y())
else:
lshift = QPointF(shiftPos.x(), 0)
rshift = QPointF(0, shiftPos.y())
shape.moveVertexBy(rindex, rshift)
shape.moveVertexBy(lindex, lshift)
def boundedMoveShape(self, shape, pos):
if self.outOfPixmap(pos):
return False # No need to move
o1 = pos + self.offsets[0]
if self.outOfPixmap(o1):
pos -= QPointF(min(0, o1.x()), min(0, o1.y()))
o2 = pos + self.offsets[1]
if self.outOfPixmap(o2):
pos += QPointF(min(0, self.pixmap.width() - o2.x()),
min(0, self.pixmap.height() - o2.y()))
# The next line tracks the new position of the cursor
# relative to the shape, but also results in making it
# a bit "shaky" when nearing the border and allows it to
# go outside of the shape's area for some reason. XXX
#self.calculateOffsets(self.selectedShape, pos)
dp = pos - self.prevPoint
if dp:
shape.moveBy(dp)
self.prevPoint = pos
return True
return False
def deSelectShape(self):
if self.selectedShape:
self.selectedShape.selected = False
self.selectedShape = None
self.setHiding(False)
self.selectionChanged.emit(False)
self.update()
def deleteSelected(self):
if self.selectedShape:
shape = self.selectedShape
self.shapes.remove(self.selectedShape)
self.selectedShape = None
self.update()
return shape
def copySelectedShape(self):
if self.selectedShape:
shape = self.selectedShape.copy()
self.deSelectShape()
self.shapes.append(shape)
shape.selected = True
self.selectedShape = shape
self.boundedShiftShape(shape)
return shape
def boundedShiftShape(self, shape):
# Try to move in one direction, and if it fails in another.
# Give up if both fail.
point = shape[0]
offset = QPointF(2.0, 2.0)
self.calculateOffsets(shape, point)
self.prevPoint = point
if not self.boundedMoveShape(shape, point - offset):
self.boundedMoveShape(shape, point + offset)
def paintEvent(self, event):
if not self.pixmap:
return super(Canvas, self).paintEvent(event)
p = self._painter
p.begin(self)
p.setRenderHint(QPainter.Antialiasing)
p.setRenderHint(QPainter.HighQualityAntialiasing)
p.setRenderHint(QPainter.SmoothPixmapTransform)
p.scale(self.scale, self.scale)
p.translate(self.offsetToCenter())
p.drawPixmap(0, 0, self.pixmap)
Shape.scale = self.scale
for shape in self.shapes:
if (shape.selected or not self._hideBackround) and self.isVisible(shape):
shape.fill = shape.selected or shape == self.hShape
shape.paint(p)
if self.current:
self.current.paint(p)
self.line.paint(p)
if self.selectedShapeCopy:
self.selectedShapeCopy.paint(p)
# Paint rect
if self.current is not None and len(self.line) == 2 and not self.fourpoint:
# print('Drawing rect')
leftTop = self.line[0]
rightBottom = self.line[1]
rectWidth = rightBottom.x() - leftTop.x()
rectHeight = rightBottom.y() - leftTop.y()
p.setPen(self.drawingRectColor)
brush = QBrush(Qt.BDiagPattern)
p.setBrush(brush)
p.drawRect(leftTop.x(), leftTop.y(), rectWidth, rectHeight)
# ADD
if (
self.fillDrawing()
and self.fourpoint
and self.current is not None
and len(self.current.points) >= 2
):
print('paint event')
drawing_shape = self.current.copy()
drawing_shape.addPoint(self.line[1])
drawing_shape.fill = True
drawing_shape.paint(p)
if self.drawing() and not self.prevPoint.isNull() and not self.outOfPixmap(self.prevPoint):
p.setPen(QColor(0, 0, 0))
p.drawLine(self.prevPoint.x(), 0, self.prevPoint.x(), self.pixmap.height())
p.drawLine(0, self.prevPoint.y(), self.pixmap.width(), self.prevPoint.y())
self.setAutoFillBackground(True)
if self.verified:
pal = self.palette()
pal.setColor(self.backgroundRole(), QColor(184, 239, 38, 128))
self.setPalette(pal)
else:
pal = self.palette()
pal.setColor(self.backgroundRole(), QColor(232, 232, 232, 255))
self.setPalette(pal)
p.end()
def fillDrawing(self):
return self._fill_drawing
def transformPos(self, point):
"""Convert from widget-logical coordinates to painter-logical coordinates."""
return point / self.scale - self.offsetToCenter()
def offsetToCenter(self):
s = self.scale
area = super(Canvas, self).size()
w, h = self.pixmap.width() * s, self.pixmap.height() * s
aw, ah = area.width(), area.height()
x = (aw - w) / (2 * s) if aw > w else 0
y = (ah - h) / (2 * s) if ah > h else 0
return QPointF(x, y)
def outOfPixmap(self, p):
w, h = self.pixmap.width(), self.pixmap.height()
return not (0 <= p.x() <= w and 0 <= p.y() <= h)
def finalise(self):
assert self.current
if self.current.points[0] == self.current.points[-1]:
# print('finalse')
self.current = None
self.drawingPolygon.emit(False)
self.update()
return
self.current.close()
self.shapes.append(self.current)
self.current = None
self.setHiding(False)
self.newShape.emit()
self.update()
def closeEnough(self, p1, p2):
#d = distance(p1 - p2)
#m = (p1-p2).manhattanLength()
# print "d %.2f, m %d, %.2f" % (d, m, d - m)
return distance(p1 - p2) < self.epsilon
# These two, along with a call to adjustSize are required for the
# scroll area.
def sizeHint(self):
return self.minimumSizeHint()
def minimumSizeHint(self):
if self.pixmap:
return self.scale * self.pixmap.size()
return super(Canvas, self).minimumSizeHint()
def wheelEvent(self, ev):
qt_version = 4 if hasattr(ev, "delta") else 5
if qt_version == 4:
if ev.orientation() == Qt.Vertical:
v_delta = ev.delta()
h_delta = 0
else:
h_delta = ev.delta()
v_delta = 0
else:
delta = ev.angleDelta()
h_delta = delta.x()
v_delta = delta.y()
mods = ev.modifiers()
if Qt.ControlModifier == int(mods) and v_delta:
self.zoomRequest.emit(v_delta)
else:
v_delta and self.scrollRequest.emit(v_delta, Qt.Vertical)
h_delta and self.scrollRequest.emit(h_delta, Qt.Horizontal)
ev.accept()
def keyPressEvent(self, ev):
key = ev.key()
if key == Qt.Key_Escape and self.current:
print('ESC press')
self.current = None
self.drawingPolygon.emit(False)
self.update()
elif key == Qt.Key_Return and self.canCloseShape():
self.finalise()
elif key == Qt.Key_Left and self.selectedShape:
self.moveOnePixel('Left')
elif key == Qt.Key_Right and self.selectedShape:
self.moveOnePixel('Right')
elif key == Qt.Key_Up and self.selectedShape:
self.moveOnePixel('Up')
elif key == Qt.Key_Down and self.selectedShape:
self.moveOnePixel('Down')
def moveOnePixel(self, direction):
# print(self.selectedShape.points)
if direction == 'Left' and not self.moveOutOfBound(QPointF(-1.0, 0)):
# print("move Left one pixel")
self.selectedShape.points[0] += QPointF(-1.0, 0)
self.selectedShape.points[1] += QPointF(-1.0, 0)
self.selectedShape.points[2] += QPointF(-1.0, 0)
self.selectedShape.points[3] += QPointF(-1.0, 0)
elif direction == 'Right' and not self.moveOutOfBound(QPointF(1.0, 0)):
# print("move Right one pixel")
self.selectedShape.points[0] += QPointF(1.0, 0)
self.selectedShape.points[1] += QPointF(1.0, 0)
self.selectedShape.points[2] += QPointF(1.0, 0)
self.selectedShape.points[3] += QPointF(1.0, 0)
elif direction == 'Up' and not self.moveOutOfBound(QPointF(0, -1.0)):
# print("move Up one pixel")
self.selectedShape.points[0] += QPointF(0, -1.0)
self.selectedShape.points[1] += QPointF(0, -1.0)
self.selectedShape.points[2] += QPointF(0, -1.0)
self.selectedShape.points[3] += QPointF(0, -1.0)
elif direction == 'Down' and not self.moveOutOfBound(QPointF(0, 1.0)):
# print("move Down one pixel")
self.selectedShape.points[0] += QPointF(0, 1.0)
self.selectedShape.points[1] += QPointF(0, 1.0)
self.selectedShape.points[2] += QPointF(0, 1.0)
self.selectedShape.points[3] += QPointF(0, 1.0)
self.shapeMoved.emit()
self.repaint()
def moveOutOfBound(self, step):
points = [p1+p2 for p1, p2 in zip(self.selectedShape.points, [step]*4)]
return True in map(self.outOfPixmap, points)
def setLastLabel(self, text, line_color = None, fill_color = None):
assert text
self.shapes[-1].label = text
if line_color:
self.shapes[-1].line_color = line_color
if fill_color:
self.shapes[-1].fill_color = fill_color
return self.shapes[-1]
def undoLastLine(self):
assert self.shapes
self.current = self.shapes.pop()
self.current.setOpen()
self.line.points = [self.current[-1], self.current[0]]
self.drawingPolygon.emit(True)
def resetAllLines(self):
assert self.shapes
self.current = self.shapes.pop()
self.current.setOpen()
self.line.points = [self.current[-1], self.current[0]]
self.drawingPolygon.emit(True)
self.current = None
self.drawingPolygon.emit(False)
self.update()
def loadPixmap(self, pixmap):
self.pixmap = pixmap
self.shapes = []
self.repaint() # 这函数在哪
def loadShapes(self, shapes):
self.shapes = list(shapes)
self.current = None
self.repaint()
def setShapeVisible(self, shape, value):
self.visible[shape] = value
self.repaint()
def currentCursor(self):
cursor = QApplication.overrideCursor()
if cursor is not None:
cursor = cursor.shape()
return cursor
def overrideCursor(self, cursor):
self._cursor = cursor
if self.currentCursor() is None:
QApplication.setOverrideCursor(cursor)
else:
QApplication.changeOverrideCursor(cursor)
def restoreCursor(self):
QApplication.restoreOverrideCursor()
def resetState(self):
self.restoreCursor()
self.pixmap = None
self.update()
def setDrawingShapeToSquare(self, status):
self.drawSquare = status

View File

@ -0,0 +1,49 @@
# Copyright (c) <2015-Present> Tzutalin
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
try:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import QColorDialog, QDialogButtonBox
except ImportError:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
BB = QDialogButtonBox
class ColorDialog(QColorDialog):
def __init__(self, parent=None):
super(ColorDialog, self).__init__(parent)
self.setOption(QColorDialog.ShowAlphaChannel)
# The Mac native dialog does not support our restore button.
self.setOption(QColorDialog.DontUseNativeDialog)
# Add a restore defaults button.
# The default is set at invocation time, so that it
# works across dialogs for different elements.
self.default = None
self.bb = self.layout().itemAt(1).widget()
self.bb.addButton(BB.RestoreDefaults)
self.bb.clicked.connect(self.checkRestore)
def getColor(self, value=None, title=None, default=None):
self.default = default
if title:
self.setWindowTitle(title)
if value:
self.setCurrentColor(value)
return self.currentColor() if self.exec_() else None
def checkRestore(self, button):
if self.bb.buttonRole(button) & BB.ResetRole and self.default:
self.setCurrentColor(self.default)

View File

@ -0,0 +1,31 @@
# Copyright (c) <2015-Present> Tzutalin
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
SETTING_FILENAME = 'filename'
SETTING_RECENT_FILES = 'recentFiles'
SETTING_WIN_SIZE = 'window/size'
SETTING_WIN_POSE = 'window/position'
SETTING_WIN_GEOMETRY = 'window/geometry'
SETTING_LINE_COLOR = 'line/color'
SETTING_FILL_COLOR = 'fill/color'
SETTING_ADVANCE_MODE = 'advanced'
SETTING_WIN_STATE = 'window/state'
SETTING_SAVE_DIR = 'savedir'
SETTING_PAINT_LABEL = 'paintlabel'
SETTING_LAST_OPEN_DIR = 'lastOpenDir'
SETTING_AUTO_SAVE = 'autosave'
SETTING_SINGLE_CLASS = 'singleclass'
FORMAT_PASCALVOC='PascalVOC'
FORMAT_YOLO='YOLO'
SETTING_DRAW_SQUARE = 'draw/square'
SETTING_LABEL_FILE_FORMAT= 'labelFileFormat'
DEFAULT_ENCODING = 'utf-8'

View File

@ -0,0 +1,143 @@
# Copyright (c) <2015-Present> Tzutalin
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#!/usr/bin/env python
# -*- coding: utf8 -*-
import json
from pathlib import Path
from libs.constants import DEFAULT_ENCODING
import os
JSON_EXT = '.json'
ENCODE_METHOD = DEFAULT_ENCODING
class CreateMLWriter:
def __init__(self, foldername, filename, imgsize, shapes, outputfile, databasesrc='Unknown', localimgpath=None):
self.foldername = foldername
self.filename = filename
self.databasesrc = databasesrc
self.imgsize = imgsize
self.boxlist = []
self.localimgpath = localimgpath
self.verified = False
self.shapes = shapes
self.outputfile = outputfile
def write(self):
if os.path.isfile(self.outputfile):
with open(self.outputfile, "r") as file:
input_data = file.read()
outputdict = json.loads(input_data)
else:
outputdict = []
outputimagedict = {
"image": self.filename,
"annotations": []
}
for shape in self.shapes:
points = shape["points"]
x1 = points[0][0]
y1 = points[0][1]
x2 = points[1][0]
y2 = points[2][1]
height, width, x, y = self.calculate_coordinates(x1, x2, y1, y2)
shapedict = {
"label": shape["label"],
"coordinates": {
"x": x,
"y": y,
"width": width,
"height": height
}
}
outputimagedict["annotations"].append(shapedict)
# check if image already in output
exists = False
for i in range(0, len(outputdict)):
if outputdict[i]["image"] == outputimagedict["image"]:
exists = True
outputdict[i] = outputimagedict
break
if not exists:
outputdict.append(outputimagedict)
Path(self.outputfile).write_text(json.dumps(outputdict), ENCODE_METHOD)
def calculate_coordinates(self, x1, x2, y1, y2):
if x1 < x2:
xmin = x1
xmax = x2
else:
xmin = x2
xmax = x1
if y1 < y2:
ymin = y1
ymax = y2
else:
ymin = y2
ymax = y1
width = xmax - xmin
if width < 0:
width = width * -1
height = ymax - ymin
# x and y from center of rect
x = xmin + width / 2
y = ymin + height / 2
return height, width, x, y
class CreateMLReader:
def __init__(self, jsonpath, filepath):
self.jsonpath = jsonpath
self.shapes = []
self.verified = False
self.filename = filepath.split("/")[-1:][0]
try:
self.parse_json()
except ValueError:
print("JSON decoding failed")
def parse_json(self):
with open(self.jsonpath, "r") as file:
inputdata = file.read()
outputdict = json.loads(inputdata)
self.verified = True
if len(self.shapes) > 0:
self.shapes = []
for image in outputdict:
if image["image"] == self.filename:
for shape in image["annotations"]:
self.add_shape(shape["label"], shape["coordinates"])
def add_shape(self, label, bndbox):
xmin = bndbox["x"] - (bndbox["width"] / 2)
ymin = bndbox["y"] - (bndbox["height"] / 2)
xmax = bndbox["x"] + (bndbox["width"] / 2)
ymax = bndbox["y"] + (bndbox["height"] / 2)
points = [(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax)]
self.shapes.append((label, points, None, None, True))
def get_shapes(self):
return self.shapes

View File

@ -0,0 +1,40 @@
# Copyright (c) <2015-Present> Tzutalin
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
try:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
except ImportError:
# needed for py3+qt4
# Ref:
# http://pyqt.sourceforge.net/Docs/PyQt4/incompatible_apis.html
# http://stackoverflow.com/questions/21217399/pyqt4-qtcore-qvariant-object-instead-of-a-string
if sys.version_info.major >= 3:
import sip
sip.setapi('QVariant', 2)
from PyQt4.QtGui import *
from PyQt4.QtCore import *
# PyQt5: TypeError: unhashable type: 'QListWidgetItem'
class HashableQListWidgetItem(QListWidgetItem):
def __init__(self, *args):
super(HashableQListWidgetItem, self).__init__(*args)
def __hash__(self):
return hash(id(self))

View File

@ -0,0 +1,107 @@
# Copyright (c) <2015-Present> Tzutalin
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
try:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
except ImportError:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from libs.utils import newIcon, labelValidator
BB = QDialogButtonBox
class LabelDialog(QDialog):
def __init__(self, text="Enter object label", parent=None, listItem=None):
super(LabelDialog, self).__init__(parent)
self.edit = QLineEdit() # OLD
# self.edit = QTextEdit()
self.edit.setText(text)
# self.edit.setValidator(labelValidator()) # 验证有效性
self.edit.editingFinished.connect(self.postProcess)
model = QStringListModel()
model.setStringList(listItem)
completer = QCompleter()
completer.setModel(model)
self.edit.setCompleter(completer)
layout = QVBoxLayout()
layout.addWidget(self.edit)
self.buttonBox = bb = BB(BB.Ok | BB.Cancel, Qt.Horizontal, self)
bb.button(BB.Ok).setIcon(newIcon('done'))
bb.button(BB.Cancel).setIcon(newIcon('undo'))
bb.accepted.connect(self.validate)
bb.rejected.connect(self.reject)
layout.addWidget(bb)
# if listItem is not None and len(listItem) > 0:
# self.listWidget = QListWidget(self)
# for item in listItem:
# self.listWidget.addItem(item)
# self.listWidget.itemClicked.connect(self.listItemClick)
# self.listWidget.itemDoubleClicked.connect(self.listItemDoubleClick)
# layout.addWidget(self.listWidget)
self.setLayout(layout)
def validate(self):
try:
if self.edit.text().trimmed():
self.accept()
except AttributeError:
# PyQt5: AttributeError: 'str' object has no attribute 'trimmed'
if self.edit.text().strip():
self.accept()
def postProcess(self):
try:
self.edit.setText(self.edit.text().trimmed())
# print(self.edit.text())
except AttributeError:
# PyQt5: AttributeError: 'str' object has no attribute 'trimmed'
self.edit.setText(self.edit.text())
print(self.edit.text())
def popUp(self, text='', move=True):
self.edit.setText(text)
self.edit.setSelection(0, len(text))
self.edit.setFocus(Qt.PopupFocusReason)
if move:
cursor_pos = QCursor.pos()
parent_bottomRight = self.parentWidget().geometry()
max_x = parent_bottomRight.x() + parent_bottomRight.width() - self.sizeHint().width()
max_y = parent_bottomRight.y() + parent_bottomRight.height() - self.sizeHint().height()
max_global = self.parentWidget().mapToGlobal(QPoint(max_x, max_y))
if cursor_pos.x() > max_global.x():
cursor_pos.setX(max_global.x())
if cursor_pos.y() > max_global.y():
cursor_pos.setY(max_global.y())
self.move(cursor_pos)
return self.edit.text() if self.exec_() else None
def listItemClick(self, tQListWidgetItem):
try:
text = tQListWidgetItem.text().trimmed()
except AttributeError:
# PyQt5: AttributeError: 'str' object has no attribute 'trimmed'
text = tQListWidgetItem.text().strip()
self.edit.setText(text)
def listItemDoubleClick(self, tQListWidgetItem):
self.listItemClick(tQListWidgetItem)
self.validate()

11109
PPOCRLabel/libs/resources.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,60 @@
# Copyright (c) <2015-Present> Tzutalin
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import pickle
import os
import sys
class Settings(object):
def __init__(self):
# Be default, the home will be in the same folder as labelImg
home = os.path.expanduser("~")
self.data = {}
# self.path = os.path.join(home, '.labelImgSettings.pkl')
self.path = os.path.join(home, '.autoOCRSettings.pkl')
def __setitem__(self, key, value):
self.data[key] = value
def __getitem__(self, key):
return self.data[key]
def get(self, key, default=None):
if key in self.data:
return self.data[key]
return default
def save(self):
if self.path:
with open(self.path, 'wb') as f:
pickle.dump(self.data, f, pickle.HIGHEST_PROTOCOL)
return True
return False
def load(self):
try:
if os.path.exists(self.path):
with open(self.path, 'rb') as f:
self.data = pickle.load(f)
return True
except:
print('Loading setting failed')
return False
def reset(self):
if os.path.exists(self.path):
os.remove(self.path)
print('Remove setting pkl file ${0}'.format(self.path))
self.data = {}
self.path = None

217
PPOCRLabel/libs/shape.py Normal file
View File

@ -0,0 +1,217 @@
# Copyright (c) <2015-Present> Tzutalin
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#!/usr/bin/python
# -*- coding: utf-8 -*-
try:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
except ImportError:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from libs.utils import distance
import sys
DEFAULT_LINE_COLOR = QColor(0, 255, 0, 128)
DEFAULT_FILL_COLOR = QColor(255, 0, 0, 128)
DEFAULT_SELECT_LINE_COLOR = QColor(255, 255, 255)
DEFAULT_SELECT_FILL_COLOR = QColor(0, 128, 255, 155)
DEFAULT_VERTEX_FILL_COLOR = QColor(0, 255, 0, 255)
DEFAULT_HVERTEX_FILL_COLOR = QColor(255, 0, 0)
MIN_Y_LABEL = 10
class Shape(object):
P_SQUARE, P_ROUND = range(2)
MOVE_VERTEX, NEAR_VERTEX = range(2)
# The following class variables influence the drawing
# of _all_ shape objects.
line_color = DEFAULT_LINE_COLOR
fill_color = DEFAULT_FILL_COLOR
select_line_color = DEFAULT_SELECT_LINE_COLOR
select_fill_color = DEFAULT_SELECT_FILL_COLOR
vertex_fill_color = DEFAULT_VERTEX_FILL_COLOR
hvertex_fill_color = DEFAULT_HVERTEX_FILL_COLOR
point_type = P_ROUND
point_size = 8
scale = 1.0
def __init__(self, label=None, line_color=None, difficult=False, paintLabel=False):
self.label = label
self.points = []
self.fill = False
self.selected = False
self.difficult = difficult
self.paintLabel = paintLabel
self._highlightIndex = None
self._highlightMode = self.NEAR_VERTEX
self._highlightSettings = {
self.NEAR_VERTEX: (4, self.P_ROUND),
self.MOVE_VERTEX: (1.5, self.P_SQUARE),
}
self._closed = False
if line_color is not None:
# Override the class line_color attribute
# with an object attribute. Currently this
# is used for drawing the pending line a different color.
self.line_color = line_color
def close(self):
self._closed = True
def reachMaxPoints(self):
if len(self.points) >= 4:
return True
return False
def addPoint(self, point):
if not self.reachMaxPoints():
self.points.append(point)
def popPoint(self):
if self.points:
return self.points.pop()
return None
def isClosed(self):
return self._closed
def setOpen(self):
self._closed = False
def paint(self, painter):
if self.points:
color = self.select_line_color if self.selected else self.line_color
pen = QPen(color)
# Try using integer sizes for smoother drawing(?)
pen.setWidth(max(1, int(round(2.0 / self.scale))))
painter.setPen(pen)
line_path = QPainterPath()
vrtx_path = QPainterPath()
line_path.moveTo(self.points[0])
# Uncommenting the following line will draw 2 paths
# for the 1st vertex, and make it non-filled, which
# may be desirable.
#self.drawVertex(vrtx_path, 0)
for i, p in enumerate(self.points):
line_path.lineTo(p)
self.drawVertex(vrtx_path, i)
if self.isClosed():
line_path.lineTo(self.points[0])
painter.drawPath(line_path)
painter.drawPath(vrtx_path)
painter.fillPath(vrtx_path, self.vertex_fill_color)
# Draw text at the top-left
if self.paintLabel:
min_x = sys.maxsize
min_y = sys.maxsize
for point in self.points:
min_x = min(min_x, point.x())
min_y = min(min_y, point.y())
if min_x != sys.maxsize and min_y != sys.maxsize:
font = QFont()
font.setPointSize(8)
font.setBold(True)
painter.setFont(font)
if(self.label == None):
self.label = ""
if(min_y < MIN_Y_LABEL):
min_y += MIN_Y_LABEL
painter.drawText(min_x, min_y, self.label)
if self.fill:
color = self.select_fill_color if self.selected else self.fill_color
painter.fillPath(line_path, color)
def drawVertex(self, path, i):
d = self.point_size / self.scale
shape = self.point_type
point = self.points[i]
if i == self._highlightIndex:
size, shape = self._highlightSettings[self._highlightMode]
d *= size
if self._highlightIndex is not None:
self.vertex_fill_color = self.hvertex_fill_color
else:
self.vertex_fill_color = Shape.vertex_fill_color
if shape == self.P_SQUARE:
path.addRect(point.x() - d / 2, point.y() - d / 2, d, d)
elif shape == self.P_ROUND:
path.addEllipse(point, d / 2.0, d / 2.0)
else:
assert False, "unsupported vertex shape"
def nearestVertex(self, point, epsilon):
for i, p in enumerate(self.points):
if distance(p - point) <= epsilon:
return i
return None
def containsPoint(self, point):
return self.makePath().contains(point)
def makePath(self):
path = QPainterPath(self.points[0])
for p in self.points[1:]:
path.lineTo(p)
return path
def boundingRect(self):
return self.makePath().boundingRect()
def moveBy(self, offset):
self.points = [p + offset for p in self.points]
def moveVertexBy(self, i, offset):
self.points[i] = self.points[i] + offset
def highlightVertex(self, i, action):
self._highlightIndex = i
self._highlightMode = action
def highlightClear(self):
self._highlightIndex = None
def copy(self):
shape = Shape("%s" % self.label)
shape.points = [p for p in self.points]
shape.fill = self.fill
shape.selected = self.selected
shape._closed = self._closed
if self.line_color != Shape.line_color:
shape.line_color = self.line_color
if self.fill_color != Shape.fill_color:
shape.fill_color = self.fill_color
shape.difficult = self.difficult
return shape
def __len__(self):
return len(self.points)
def __getitem__(self, key):
return self.points[key]
def __setitem__(self, key, value):
self.points[key] = value

View File

@ -0,0 +1,86 @@
# Copyright (c) <2015-Present> Tzutalin
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
import os
import sys
import locale
from libs.ustr import ustr
try:
from PyQt5.QtCore import *
except ImportError:
if sys.version_info.major >= 3:
import sip
sip.setapi('QVariant', 2)
from PyQt4.QtCore import *
class StringBundle:
__create_key = object()
def __init__(self, create_key, localeStr):
assert(create_key == StringBundle.__create_key), "StringBundle must be created using StringBundle.getBundle"
self.idToMessage = {}
paths = self.__createLookupFallbackList(localeStr)
for path in paths:
self.__loadBundle(path)
@classmethod
def getBundle(cls, localeStr=None):
if localeStr is None:
try:
localeStr = locale.getlocale()[0] if locale.getlocale() and len(
locale.getlocale()) > 0 else os.getenv('LANG')
except:
print('Invalid locale')
localeStr = 'en'
return StringBundle(cls.__create_key, localeStr)
def getString(self, stringId):
assert(stringId in self.idToMessage), "Missing string id : " + stringId
return self.idToMessage[stringId]
def __createLookupFallbackList(self, localeStr):
resultPaths = []
basePath = ":/strings"
resultPaths.append(basePath)
if localeStr is not None:
# Don't follow standard BCP47. Simple fallback
tags = re.split('[^a-zA-Z]', localeStr)
for tag in tags:
lastPath = resultPaths[-1]
resultPaths.append(lastPath + '-' + tag)
return resultPaths
def __loadBundle(self, path):
PROP_SEPERATOR = '='
f = QFile(path)
if f.exists():
if f.open(QIODevice.ReadOnly | QFile.Text):
text = QTextStream(f)
text.setCodec("UTF-8")
while not text.atEnd():
line = ustr(text.readLine())
key_value = line.split(PROP_SEPERATOR)
key = key_value[0].strip()
value = PROP_SEPERATOR.join(key_value[1:]).strip().strip('"')
self.idToMessage[key] = value
f.close()

View File

@ -0,0 +1,51 @@
# Copyright (c) <2015-Present> Tzutalin
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
try:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
except ImportError:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class ToolBar(QToolBar):
def __init__(self, title):
super(ToolBar, self).__init__(title)
layout = self.layout()
m = (0, 0, 0, 0)
layout.setSpacing(0)
layout.setContentsMargins(*m)
self.setContentsMargins(*m)
self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint)
def addAction(self, action):
if isinstance(action, QWidgetAction):
return super(ToolBar, self).addAction(action)
btn = ToolButton()
btn.setDefaultAction(action)
btn.setToolButtonStyle(self.toolButtonStyle())
self.addWidget(btn)
class ToolButton(QToolButton):
"""ToolBar companion class which ensures all buttons have the same size."""
minSize = (60, 60)
def minimumSizeHint(self):
ms = super(ToolButton, self).minimumSizeHint()
w1, h1 = ms.width(), ms.height()
w2, h2 = self.minSize
ToolButton.minSize = max(w1, w2), max(h1, h2)
return QSize(*ToolButton.minSize)

29
PPOCRLabel/libs/ustr.py Normal file
View File

@ -0,0 +1,29 @@
# Copyright (c) <2015-Present> Tzutalin
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import sys
from libs.constants import DEFAULT_ENCODING
def ustr(x):
'''py2/py3 unicode helper'''
if sys.version_info < (3, 0, 0):
from PyQt4.QtCore import QString
if type(x) == str:
return x.decode(DEFAULT_ENCODING)
if type(x) == QString:
#https://blog.csdn.net/friendan/article/details/51088476
#https://blog.csdn.net/xxm524/article/details/74937308
return unicode(x.toUtf8(), DEFAULT_ENCODING, 'ignore')
return x
else:
return x

182
PPOCRLabel/libs/utils.py Normal file
View File

@ -0,0 +1,182 @@
# Copyright (c) <2015-Present> Tzutalin
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from math import sqrt
from libs.ustr import ustr
import hashlib
import re
import sys
import cv2
import numpy as np
try:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
except ImportError:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
def newIcon(icon, iconSize=None):
if iconSize is not None:
return QIcon(QIcon(':/' + icon).pixmap(iconSize,iconSize))
else:
return QIcon(':/' + icon)
def newButton(text, icon=None, slot=None):
b = QPushButton(text)
if icon is not None:
b.setIcon(newIcon(icon))
if slot is not None:
b.clicked.connect(slot)
return b
def newAction(parent, text, slot=None, shortcut=None, icon=None,
tip=None, checkable=False, enabled=True, iconSize=None):
"""Create a new action and assign callbacks, shortcuts, etc."""
a = QAction(text, parent)
if icon is not None:
if iconSize is not None:
a.setIcon(newIcon(icon, iconSize))
else:
a.setIcon(newIcon(icon))
if shortcut is not None:
if isinstance(shortcut, (list, tuple)):
a.setShortcuts(shortcut)
else:
a.setShortcut(shortcut)
if tip is not None:
a.setToolTip(tip)
a.setStatusTip(tip)
if slot is not None:
a.triggered.connect(slot)
if checkable:
a.setCheckable(True)
a.setEnabled(enabled)
return a
def addActions(widget, actions):
for action in actions:
if action is None:
widget.addSeparator()
elif isinstance(action, QMenu):
widget.addMenu(action)
else:
widget.addAction(action)
def labelValidator():
return QRegExpValidator(QRegExp(r'^[^ \t].+'), None)
class struct(object):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def distance(p):
return sqrt(p.x() * p.x() + p.y() * p.y())
def fmtShortcut(text):
mod, key = text.split('+', 1)
return '<b>%s</b>+<b>%s</b>' % (mod, key)
def generateColorByText(text):
s = ustr(text)
hashCode = int(hashlib.sha256(s.encode('utf-8')).hexdigest(), 16)
r = int((hashCode / 255) % 255)
g = int((hashCode / 65025) % 255)
b = int((hashCode / 16581375) % 255)
return QColor(r, g, b, 100)
def have_qstring():
'''p3/qt5 get rid of QString wrapper as py3 has native unicode str type'''
return not (sys.version_info.major >= 3 or QT_VERSION_STR.startswith('5.'))
def util_qt_strlistclass():
return QStringList if have_qstring() else list
def natural_sort(list, key=lambda s:s):
"""
Sort the list into natural alphanumeric order.
"""
def get_alphanum_key_func(key):
convert = lambda text: int(text) if text.isdigit() else text
return lambda s: [convert(c) for c in re.split('([0-9]+)', key(s))]
sort_key = get_alphanum_key_func(key)
list.sort(key=sort_key)
def get_rotate_crop_image(img, points):
try:
img_crop_width = int(
max(
np.linalg.norm(points[0] - points[1]),
np.linalg.norm(points[2] - points[3])))
img_crop_height = int(
max(
np.linalg.norm(points[0] - points[3]),
np.linalg.norm(points[1] - points[2])))
pts_std = np.float32([[0, 0], [img_crop_width, 0],
[img_crop_width, img_crop_height],
[0, img_crop_height]])
M = cv2.getPerspectiveTransform(points, pts_std)
dst_img = cv2.warpPerspective(
img,
M, (img_crop_width, img_crop_height),
borderMode=cv2.BORDER_REPLICATE,
flags=cv2.INTER_CUBIC)
dst_img_height, dst_img_width = dst_img.shape[0:2]
if dst_img_height * 1.0 / dst_img_width >= 1.5:
dst_img = np.rot90(dst_img)
return dst_img
except Exception as e:
print(e)
def stepsInfo(lang='en'):
if lang == 'ch':
msg = "1. 安装与运行:使用上述命令安装与运行程序。\n" \
"2. 打开文件夹:在菜单栏点击 “文件” - 打开目录 选择待标记图片的文件夹.\n"\
"3. 自动标注:点击 ”自动标注“使用PPOCR超轻量模型对图片文件名前图片状态为 “X” 的图片进行自动标注。\n" \
"4. 手动标注:点击 “矩形标注”(推荐直接在英文模式下点击键盘中的 “W”),用户可对当前图片中模型未检出的部分进行手动" \
"绘制标记框。点击键盘P则使用四点标注模式或点击“编辑” - “四点标注”用户依次点击4个点后双击左键表示标注完成。\n" \
"5. 标记框绘制完成后,用户点击 “确认”,检测框会先被预分配一个 “待识别” 标签。\n" \
"6. 重新识别:将图片中的所有检测画绘制/调整完成后,点击 “重新识别”PPOCR模型会对当前图片中的**所有检测框**重新识别。\n" \
"7. 内容更改:双击识别结果,对不准确的识别结果进行手动更改。\n" \
"8. 保存:点击 “保存”,图片状态切换为 “√”,跳转至下一张。\n" \
"9. 删除:点击 “删除图像”,图片将会被删除至回收站。\n" \
"10. 标注结果:关闭应用程序或切换文件路径后,手动保存过的标签将会被存放在所打开图片文件夹下的" \
"*Label.txt*中。在菜单栏点击 “PaddleOCR” - 保存识别结果后,会将此类图片的识别训练数据保存在*crop_img*文件夹下," \
"识别标签保存在*rec_gt.txt*中。\n"
else:
msg = "1. Build and launch using the instructions above.\n" \
"2. Click 'Open Dir' in Menu/File to select the folder of the picture.\n"\
"3. Click 'Auto recognition', use PPOCR model to automatically annotate images which marked with 'X' before the file name."\
"4. Create Box:\n"\
"4.1 Click 'Create RectBox' or press 'W' in English keyboard mode to draw a new rectangle detection box. Click and release left mouse to select a region to annotate the text area.\n"\
"4.2 Press 'P' to enter four-point labeling mode which enables you to create any four-point shape by clicking four points with the left mouse button in succession and DOUBLE CLICK the left mouse as the signal of labeling completion.\n"\
"5. After the marking frame is drawn, the user clicks 'OK', and the detection frame will be pre-assigned a TEMPORARY label.\n"\
"6. Click re-Recognition, model will rewrite ALL recognition results in ALL detection box.\n"\
"7. Double click the result in 'recognition result' list to manually change inaccurate recognition results.\n"\
"8. Click 'Save', the image status will switch to '',then the program automatically jump to the next.\n"\
"9. Click 'Delete Image' and the image will be deleted to the recycle bin.\n"\
"10. Labeling result: After closing the application or switching the file path, the manually saved label will be stored in *Label.txt* under the opened picture folder.\n"\
" Click PaddleOCR-Save Recognition Results in the menu bar, the recognition training data of such pictures will be saved in the *crop_img* folder, and the recognition label will be saved in *rec_gt.txt*.\n"
return msg

View File

@ -0,0 +1,38 @@
# Copyright (c) <2015-Present> Tzutalin
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
try:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
except ImportError:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class ZoomWidget(QSpinBox):
def __init__(self, value=100):
super(ZoomWidget, self).__init__()
self.setButtonSymbols(QAbstractSpinBox.NoButtons)
self.setRange(1, 500)
self.setSuffix(' %')
self.setValue(value)
self.setToolTip(u'Zoom Level')
self.setStatusTip(self.toolTip())
self.setAlignment(Qt.AlignCenter)
def minimumSizeHint(self):
height = super(ZoomWidget, self).minimumSizeHint().height()
fm = QFontMetrics(self.font())
width = fm.width(str(self.maximum()))
return QSize(width, height)

View File

@ -0,0 +1,2 @@
pyqt5==5.10.1
lxml==4.2.4

39
PPOCRLabel/resources.qrc Normal file
View File

@ -0,0 +1,39 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file alias="help">resources/icons/help.png</file>
<file alias="app">resources/icons/app.png</file>
<file alias="Auto">resources/icons/Auto.png</file>
<file alias="reRec">resources/icons/reRec.png</file>
<file alias="expert">resources/icons/expert2.png</file>
<file alias="done">resources/icons/done.png</file>
<file alias="file">resources/icons/file.png</file>
<file alias="labels">resources/icons/labels.png</file>
<file alias="new">resources/icons/objects.png</file>
<file alias="close">resources/icons/close.png</file>
<file alias="fit-width">resources/icons/fit-width.png</file>
<file alias="fit-window">resources/icons/fit-window.png</file>
<file alias="undo">resources/icons/undo.png</file>
<file alias="hide">resources/icons/eye.png</file>
<file alias="quit">resources/icons/quit.png</file>
<file alias="copy">resources/icons/copy.png</file>
<file alias="edit">resources/icons/edit.png</file>
<file alias="open">resources/icons/open.png</file>
<file alias="save">resources/icons/save.png</file>
<file alias="format_voc">resources/icons/format_voc.png</file>
<file alias="format_yolo">resources/icons/format_yolo.png</file>
<file alias="save-as">resources/icons/save-as.png</file>
<file alias="color">resources/icons/color.png</file>
<file alias="color_line">resources/icons/color_line.png</file>
<file alias="zoom">resources/icons/zoom.png</file>
<file alias="zoom-in">resources/icons/zoom-in.png</file>
<file alias="zoom-out">resources/icons/zoom-out.png</file>
<file alias="delete">resources/icons/cancel.png</file>
<file alias="next">resources/icons/next.png</file>
<file alias="prev">resources/icons/prev.png</file>
<file alias="resetall">resources/icons/resetall.png</file>
<file alias="verify">resources/icons/verify.png</file>
<file alias="strings">resources/strings/strings.properties</file>
<file alias="strings-zh-CN">resources/strings/strings-zh-CN.properties</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 B

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="200px" height="200px" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>APPicon备份 3@2x</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#A5ACFF" offset="0%"></stop>
<stop stop-color="#545DFF" offset="100%"></stop>
</linearGradient>
</defs>
<g id="APPicon备份-3" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组-3备份-2" fill="url(#linearGradient-1)">
<rect id="矩形" x="0" y="0" width="200" height="200" rx="4"></rect>
</g>
<g id="编组-4备份" transform="translate(11.000000, 11.000000)">
<polyline id="路径" stroke="#FFFFFF" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" points="104 167 11 167 11 11 167 11 167 96.7728865"></polyline>
<circle id="椭圆形" fill="#FFFFFF" cx="167" cy="11" r="11"></circle>
<circle id="椭圆形备份-8" fill="#FFFFFF" cx="11" cy="11" r="11"></circle>
<circle id="椭圆形备份-9" fill="#FFFFFF" cx="11" cy="167" r="11"></circle>
</g>
<path d="M85.9991492,141 L69,141 L69,60 L97.061099,60.0005168 C106.622339,60.0180588 113.008403,60.4807625 115.775763,61.1684309 C120.478388,62.336394 124.240393,64.9067781 127.297375,69.1122872 C130.353887,73.08404 132,78.4580969 132,84.7663606 C132,89.6731387 131.059499,93.8786478 129.413268,97.1497163 C127.767626,100.420785 125.416373,103.224458 122.594751,105.09369 C119.773129,106.962805 116.951625,108.364641 114.130121,108.83192 C110.367998,109.766594 104.724872,110 97.4355156,110 L97.4355156,110 L85.999,110 L85.9991492,141 Z M86,74.2965717 L85.9299926,74.2965717 L85.929,96.849 L95.7229134,96.8497738 C101.895297,96.8497738 106.289281,96.4080944 108.473591,95.739226 L108.655396,95.681343 C110.771288,94.9806587 112.417401,93.5787054 113.828271,91.7095902 C115.239023,89.840475 115.709274,87.7373697 115.709274,85.4009757 C115.709274,82.3637805 114.768772,80.0273866 113.122542,78.1581545 C111.476782,76.2890393 109.125646,75.1206084 106.538915,74.6533297 C104.879206,74.2409217 101.572085,74.1924031 96.7786667,74.186695 L95.8002135,74.1860291 C95.4674884,74.1859339 95.1282054,74.1859339 94.7824121,74.1859339 L86,74.185 L86,74.2965717 Z" id="形状结合" fill="#FFFFFF"></path>
<g id="编组" transform="translate(158.000000, 153.000000) rotate(65.000000) translate(-158.000000, -153.000000) translate(126.000000, 113.000000)">
<path d="M32,8 C14.326888,8 0,22.326888 0,40 C0,49.0801087 3.78188139,57.2769117 9.85641113,63.1011759 M32,72 C49.673112,72 64,57.673112 64,40 C64,30.9865538 60.2734449,22.8434911 54.2770078,17.0274853" id="形状备份-2" stroke="#FFFFFF" stroke-width="5" stroke-linecap="round"></path>
<polygon id="三角形备份-3" fill="#FFFFFF" transform="translate(38.000000, 8.000000) scale(-1, 1) rotate(-90.000000) translate(-38.000000, -8.000000) " points="38 2 46 14 30 14"></polygon>
<polygon id="三角形备份-4" fill="#FFFFFF" transform="translate(26.000000, 72.000000) rotate(-90.000000) translate(-26.000000, -72.000000) " points="26 66 34 78 18 78"></polygon>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,400 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
<svg
width="48pt"
height="48pt"
viewBox="0 0 256 256"
style="overflow:visible;enable-background:new 0 0 256 256"
xml:space="preserve"
xmlns="http://www.w3.org/2000/svg"
xmlns:xap="http://ns.adobe.com/xap/1.0/"
xmlns:xapGImg="http://ns.adobe.com/xap/1.0/g/img/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/"
xmlns:pdf="http://ns.adobe.com/pdf/1.3/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
xmlns:x="adobe:ns:meta/"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
id="svg548"
sodipodi:version="0.32"
sodipodi:docname="/home/david/Desktop/action/button_ok.svg"
sodipodi:docbase="/home/david/Desktop/action/">
<defs
id="defs584">
<linearGradient
id="XMLID_5_"
gradientUnits="userSpaceOnUse"
x1="127.9536"
y1="47.3267"
x2="127.9536"
y2="212.9885">
<stop
offset="0"
style="stop-color:#009900"
id="stop556" />
<stop
offset="1"
style="stop-color:#334966"
id="stop557" />
<a:midPointStop
offset="0"
style="stop-color:#009900"
id="midPointStop558" />
<a:midPointStop
offset="0.5"
style="stop-color:#009900"
id="midPointStop559" />
<a:midPointStop
offset="1"
style="stop-color:#334966"
id="midPointStop560" />
</linearGradient>
<linearGradient
id="XMLID_6_"
gradientUnits="userSpaceOnUse"
x1="127.9536"
y1="77.2075"
x2="127.9536"
y2="307.6057">
<stop
offset="0"
style="stop-color:#33CC33"
id="stop563" />
<stop
offset="1"
style="stop-color:#336666"
id="stop564" />
<a:midPointStop
offset="0"
style="stop-color:#33CC33"
id="midPointStop565" />
<a:midPointStop
offset="0.5"
style="stop-color:#33CC33"
id="midPointStop566" />
<a:midPointStop
offset="1"
style="stop-color:#336666"
id="midPointStop567" />
</linearGradient>
<linearGradient
id="XMLID_7_"
gradientUnits="userSpaceOnUse"
x1="127.9536"
y1="77.3672"
x2="127.9536"
y2="307.3626">
<stop
offset="0.0056"
style="stop-color:#CCFF66"
id="stop570" />
<stop
offset="1"
style="stop-color:#009900"
id="stop571" />
<a:midPointStop
offset="0.0056"
style="stop-color:#CCFF66"
id="midPointStop572" />
<a:midPointStop
offset="0.5"
style="stop-color:#CCFF66"
id="midPointStop573" />
<a:midPointStop
offset="1"
style="stop-color:#009900"
id="midPointStop574" />
</linearGradient>
<radialGradient
id="XMLID_8_"
cx="54.2729"
cy="89.3477"
r="120.8132"
fx="54.2729"
fy="89.3477"
gradientUnits="userSpaceOnUse">
<stop
offset="0.000000"
style="stop-color:#ffffff;stop-opacity:1;"
id="stop577" />
<stop
offset="1.000000"
style="stop-color:#92ff00;stop-opacity:1;"
id="stop578" />
<a:midPointStop
offset="0"
style="stop-color:#FFFFFF"
id="midPointStop579" />
<a:midPointStop
offset="0.5"
style="stop-color:#FFFFFF"
id="midPointStop580" />
<a:midPointStop
offset="1"
style="stop-color:#000000"
id="midPointStop581" />
</radialGradient>
</defs>
<sodipodi:namedview
id="base" />
<metadata
id="metadata549">
<xpacket>begin='' id='W5M0MpCehiHzreSzNTczkc9d' </xpacket>
<x:xmpmeta
x:xmptk="XMP toolkit 3.0-29, framework 1.6">
<rdf:RDF>
<rdf:Description
rdf:about="uuid:609bc623-b01c-476b-9349-300763160df1">
<pdf:Producer>
Adobe PDF library 5.00</pdf:Producer>
</rdf:Description>
<rdf:Description
rdf:about="uuid:609bc623-b01c-476b-9349-300763160df1" />
<rdf:Description
rdf:about="uuid:609bc623-b01c-476b-9349-300763160df1" />
<rdf:Description
rdf:about="uuid:609bc623-b01c-476b-9349-300763160df1">
<xap:CreateDate>
2003-12-22T22:34:35+02:00</xap:CreateDate>
<xap:ModifyDate>
2004-04-17T21:25:50Z</xap:ModifyDate>
<xap:CreatorTool>
Adobe Illustrator 10.0</xap:CreatorTool>
<xap:MetadataDate>
2004-01-19T17:51:02+01:00</xap:MetadataDate>
<xap:Thumbnails>
<rdf:Alt>
<rdf:li
rdf:parseType="Resource">
<xapGImg:format>
JPEG</xapGImg:format>
<xapGImg:width>
256</xapGImg:width>
<xapGImg:height>
256</xapGImg:height>
<xapGImg:image>
/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER
AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy
obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp
0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo
+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7
FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7F
XYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX
Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXY
q7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq
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</xapGImg:image>
</rdf:li>
</rdf:Alt>
</xap:Thumbnails>
</rdf:Description>
<rdf:Description
rdf:about="uuid:609bc623-b01c-476b-9349-300763160df1">
<xapMM:DocumentID>
uuid:4b4d592f-95b8-4bcd-a892-74a536c5e52f</xapMM:DocumentID>
</rdf:Description>
<rdf:Description
rdf:about="uuid:609bc623-b01c-476b-9349-300763160df1">
<dc:format>
image/svg+xml</dc:format>
<dc:title>
<rdf:Alt>
<rdf:li
xml:lang="x-default">
test.ai</rdf:li>
</rdf:Alt>
</dc:title>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
<xpacket>end='w' </xpacket>
</metadata>
<rect
id="_x3C_Slice_x3E_"
style="font-size:12;fill:none;"
width="256"
height="256" />
<path
style="font-size:12;opacity:0.2;"
d="M221.848,47.811c0,0-130.558,89.471-132.578,90.855c-1.689-1.683-41.779-41.595-41.779-41.595 c-2.978-2.968-6.891-4.068-10.467-2.943c-3.89,1.232-6.403,4.005-7.08,7.809l-0.42,2.363c-0.135,0.765-0.122,1.532,0.037,2.285 l0.589,2.802l0.408,1.247l46.254,101.694c1.449,3.183,4.375,5.427,7.83,6.001c3.441,0.579,6.936-0.598,9.349-3.144 L235.225,65.893c2.066-2.169,3.252-5.263,3.252-8.481l-0.129-1.236l-0.572-2.723c-0.697-3.33-2.852-5.804-6.227-7.157 C229.395,45.431,225.963,44.991,221.848,47.811z"
id="path552" />
<path
style="font-size:12;opacity:0.2;"
d="M218.848,47.811c0,0-130.558,89.471-132.578,90.855c-1.689-1.683-41.779-41.595-41.779-41.595 c-2.978-2.968-6.891-4.068-10.467-2.943c-3.89,1.232-6.403,4.005-7.08,7.809l-0.42,2.363c-0.135,0.765-0.122,1.532,0.037,2.285 l0.589,2.802l0.408,1.247l46.254,101.694c1.449,3.183,4.375,5.427,7.83,6.001c3.441,0.579,6.936-0.598,9.349-3.144 L232.225,65.893c2.066-2.169,3.252-5.263,3.252-8.481l-0.129-1.236l-0.572-2.723c-0.697-3.33-2.852-5.804-6.227-7.157 C226.395,45.431,222.963,44.991,218.848,47.811z"
id="path553" />
<path
style="font-size:12;opacity:0.2;"
d="M217.848,45.811c0,0-130.558,89.471-132.578,90.855c-1.689-1.683-41.779-41.595-41.779-41.595 c-2.978-2.968-6.891-4.068-10.467-2.943c-3.89,1.232-6.403,4.005-7.08,7.809l-0.42,2.363c-0.135,0.765-0.122,1.532,0.037,2.285 l0.589,2.802l0.408,1.247l46.254,101.694c1.449,3.183,4.375,5.427,7.83,6.001c3.441,0.579,6.936-0.598,9.349-3.144 L231.225,63.893c2.066-2.169,3.252-5.263,3.252-8.481l-0.129-1.236l-0.572-2.723c-0.697-3.33-2.852-5.804-6.227-7.157 C225.395,43.431,221.963,42.991,217.848,45.811z"
id="path554" />
<path
style="font-size:12;fill:url(#XMLID_5_);"
d="M215.848,43.811c0,0-130.558,89.471-132.578,90.855 c-1.689-1.683-41.779-41.595-41.779-41.595c-2.978-2.968-6.891-4.068-10.467-2.943c-3.89,1.232-6.403,4.005-7.08,7.809 l-0.42,2.363c-0.135,0.765-0.122,1.532,0.037,2.285l0.589,2.802l0.408,1.247l46.254,101.694c1.449,3.183,4.375,5.427,7.83,6.001 c3.441,0.579,6.936-0.598,9.349-3.144L229.225,61.893c2.066-2.169,3.252-5.263,3.252-8.481l-0.129-1.236l-0.572-2.723 c-0.697-3.33-2.852-5.804-6.227-7.157C223.395,41.431,219.963,40.991,215.848,43.811z"
id="path561" />
<path
style="font-size:12;fill:url(#XMLID_6_);"
d="M219.239,48.761c0,0-135.454,92.824-136.679,93.665 c-5.106-5.083-45.302-45.103-45.302-45.103c-1.187-1.182-2.833-1.976-4.431-1.472c-1.597,0.505-2.684,1.485-2.977,3.135 l-0.42,2.364l0.589,2.802c0.007,0.016,46.252,101.691,46.252,101.691c0.621,1.363,1.876,2.321,3.354,2.567 c1.477,0.247,2.978-0.265,4.008-1.353L224.865,57.77c1.021-1.072,1.611-2.665,1.611-4.358l-0.572-2.728 c-0.309-1.471-1.192-2.26-2.588-2.82C221.922,47.305,220.477,47.913,219.239,48.761z"
id="path568" />
<path
style="font-size:12;fill:url(#XMLID_7_);"
d="M84.485,146.561c-1.425,0.977-3.344,0.803-4.567-0.416c0,0-44.921-44.724-45.833-45.632 c-0.091,0.252-0.154,0.533-0.154,0.838c0,0.328,0.06,0.662,0.192,0.955c0,0,46.096,101.347,46.241,101.664 c0.877-0.93,141.232-149.292,141.232-149.292c0.232-0.243,0.381-0.741,0.381-1.266c0-0.322-0.074-0.645-0.2-0.935 C220.751,53.177,84.485,146.561,84.485,146.561z"
id="path575" />
<path
style="font-size:12;fill:url(#XMLID_8_);"
d="M86.517,149.525c-0.001,0-0.001,0.004-0.001,0.004 c-2.848,1.947-6.69,1.596-9.133-0.838c0,0-20.052-19.966-33.287-33.141c10.589,23.282,30.678,67.45,37.327,82.069 c6.078-6.424,93.826-99.178,119.981-126.826C170.026,92.297,86.517,149.525,86.517,149.525z"
id="path582" />
</svg>

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 765 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 786 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,819 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
<svg
xmlns:pdf="http://ns.adobe.com/pdf/1.3/"
xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/"
xmlns:xapGImg="http://ns.adobe.com/xap/1.0/g/img/"
xmlns:xap="http://ns.adobe.com/xap/1.0/"
xmlns:ns0="http://ns.adobe.com/SaveForWeb/1.0/"
xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
xmlns:x="adobe:ns:meta/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48pt"
height="48pt"
viewBox="0 0 256 256"
overflow="visible"
enable-background="new 0 0 256 256"
xml:space="preserve"
id="svg710"
sodipodi:version="0.32"
sodipodi:docname="application-text.svg"
version="1.1"
inkscape:version="0.48.1 r9760">
<defs
id="defs796">
<linearGradient
y2="245.0005"
x2="128.9995"
y1="11"
x1="128.9995"
gradientUnits="userSpaceOnUse"
id="XMLID_9_">
<stop
id="stop717"
style="stop-color:#494949"
offset="0" />
<stop
id="stop718"
style="stop-color:#000000"
offset="1" />
<a:midPointStop
id="midPointStop719"
style="stop-color:#494949"
offset="0" />
<a:midPointStop
id="midPointStop720"
style="stop-color:#494949"
offset="0.5" />
<a:midPointStop
id="midPointStop721"
style="stop-color:#000000"
offset="1" />
</linearGradient>
<linearGradient
y2="226.9471"
x2="226.9471"
y1="29.0532"
x1="29.0532"
gradientUnits="userSpaceOnUse"
id="XMLID_10_">
<stop
id="stop725"
style="stop-color:#FFFFFF"
offset="0" />
<stop
id="stop726"
style="stop-color:#DADADA"
offset="1" />
<a:midPointStop
id="midPointStop727"
style="stop-color:#FFFFFF"
offset="0" />
<a:midPointStop
id="midPointStop728"
style="stop-color:#FFFFFF"
offset="0.5" />
<a:midPointStop
id="midPointStop729"
style="stop-color:#DADADA"
offset="1" />
</linearGradient>
<linearGradient
gradientTransform="matrix(0.1991,0.98,-0.98,0.1991,91.6944,573.5653)"
y2="-164.2214"
x2="-360.2456"
y1="-94.4194"
x1="-481.7007"
gradientUnits="userSpaceOnUse"
id="XMLID_11_">
<stop
id="stop736"
style="stop-color:#990000"
offset="0" />
<stop
id="stop737"
style="stop-color:#7C0000"
offset="1" />
<a:midPointStop
id="midPointStop738"
style="stop-color:#990000"
offset="0" />
<a:midPointStop
id="midPointStop739"
style="stop-color:#990000"
offset="0.5" />
<a:midPointStop
id="midPointStop740"
style="stop-color:#7C0000"
offset="1" />
</linearGradient>
<linearGradient
gradientTransform="matrix(-0.999,0.0435,0.0435,0.999,-1277.0056,-496.5172)"
y2="706.3217"
x2="-1355.0455"
y1="685.3809"
x1="-1375.9844"
gradientUnits="userSpaceOnUse"
id="XMLID_12_">
<stop
id="stop743"
style="stop-color:#F8F1DC"
offset="0" />
<stop
id="stop744"
style="stop-color:#D6A84A"
offset="1" />
<a:midPointStop
id="midPointStop745"
style="stop-color:#F8F1DC"
offset="0" />
<a:midPointStop
id="midPointStop746"
style="stop-color:#F8F1DC"
offset="0.5" />
<a:midPointStop
id="midPointStop747"
style="stop-color:#D6A84A"
offset="1" />
</linearGradient>
<linearGradient
y2="160.1823"
x2="137.6021"
y1="-0.7954"
x1="65.0947"
gradientUnits="userSpaceOnUse"
id="XMLID_13_">
<stop
id="stop750"
style="stop-color:#FFA700"
offset="0" />
<stop
id="stop751"
style="stop-color:#FFD700"
offset="0.7753" />
<stop
id="stop752"
style="stop-color:#FF794B"
offset="1" />
<a:midPointStop
id="midPointStop753"
style="stop-color:#FFA700"
offset="0" />
<a:midPointStop
id="midPointStop754"
style="stop-color:#FFA700"
offset="0.5" />
<a:midPointStop
id="midPointStop755"
style="stop-color:#FFD700"
offset="0.7753" />
<a:midPointStop
id="midPointStop756"
style="stop-color:#FFD700"
offset="0.5" />
<a:midPointStop
id="midPointStop757"
style="stop-color:#FF794B"
offset="1" />
</linearGradient>
<linearGradient
gradientTransform="matrix(-0.999,0.0435,0.0435,0.999,-1277.0056,-496.5172)"
y2="622.5333"
x2="-1325.3219"
y1="635.7949"
x1="-1336.4497"
gradientUnits="userSpaceOnUse"
id="XMLID_14_">
<stop
id="stop763"
style="stop-color:#FFC957"
offset="0" />
<stop
id="stop764"
style="stop-color:#FF6D00"
offset="1" />
<a:midPointStop
id="midPointStop765"
style="stop-color:#FFC957"
offset="0" />
<a:midPointStop
id="midPointStop766"
style="stop-color:#FFC957"
offset="0.5" />
<a:midPointStop
id="midPointStop767"
style="stop-color:#FF6D00"
offset="1" />
</linearGradient>
<linearGradient
gradientTransform="matrix(-0.999,0.0435,0.0435,0.999,-1277.0056,-496.5172)"
y2="699.4763"
x2="-1354.6851"
y1="595.6309"
x1="-1401.459"
gradientUnits="userSpaceOnUse"
id="XMLID_15_">
<stop
id="stop770"
style="stop-color:#FFA700"
offset="0" />
<stop
id="stop771"
style="stop-color:#FFD700"
offset="0.7753" />
<stop
id="stop772"
style="stop-color:#FF9200"
offset="1" />
<a:midPointStop
id="midPointStop773"
style="stop-color:#FFA700"
offset="0" />
<a:midPointStop
id="midPointStop774"
style="stop-color:#FFA700"
offset="0.5" />
<a:midPointStop
id="midPointStop775"
style="stop-color:#FFD700"
offset="0.7753" />
<a:midPointStop
id="midPointStop776"
style="stop-color:#FFD700"
offset="0.5" />
<a:midPointStop
id="midPointStop777"
style="stop-color:#FF9200"
offset="1" />
</linearGradient>
<linearGradient
y2="115.5361"
x2="144.5898"
y1="115.5361"
x1="67.8452"
gradientUnits="userSpaceOnUse"
id="XMLID_16_">
<stop
id="stop780"
style="stop-color:#7D7D99"
offset="0" />
<stop
id="stop781"
style="stop-color:#B1B1C5"
offset="0.1798" />
<stop
id="stop782"
style="stop-color:#BCBCC8"
offset="0.3727" />
<stop
id="stop783"
style="stop-color:#C8C8CB"
offset="0.6825" />
<stop
id="stop784"
style="stop-color:#CCCCCC"
offset="1" />
<a:midPointStop
id="midPointStop785"
style="stop-color:#7D7D99"
offset="0" />
<a:midPointStop
id="midPointStop786"
style="stop-color:#7D7D99"
offset="0.5" />
<a:midPointStop
id="midPointStop787"
style="stop-color:#B1B1C5"
offset="0.1798" />
<a:midPointStop
id="midPointStop788"
style="stop-color:#B1B1C5"
offset="0.2881" />
<a:midPointStop
id="midPointStop789"
style="stop-color:#CCCCCC"
offset="1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#XMLID_16_"
id="linearGradient80060"
gradientUnits="userSpaceOnUse"
x1="67.8452"
y1="115.5361"
x2="144.5898"
y2="115.5361"
gradientTransform="translate(0,-25.600002)" /><linearGradient
inkscape:collect="always"
xlink:href="#XMLID_15_"
id="linearGradient80063"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-0.999,0.0435,0.0435,0.999,-1277.0056,-522.11722)"
x1="-1401.459"
y1="595.6309"
x2="-1354.6851"
y2="699.4763" /><linearGradient
inkscape:collect="always"
xlink:href="#XMLID_14_"
id="linearGradient80066"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-0.999,0.0435,0.0435,0.999,-1277.0056,-522.11722)"
x1="-1336.4497"
y1="635.7949"
x2="-1325.3219"
y2="622.5333" /><linearGradient
inkscape:collect="always"
xlink:href="#XMLID_13_"
id="linearGradient80072"
gradientUnits="userSpaceOnUse"
x1="65.0947"
y1="-0.7954"
x2="137.6021"
y2="160.1823"
gradientTransform="translate(0,-25.600002)" /><linearGradient
inkscape:collect="always"
xlink:href="#XMLID_12_"
id="linearGradient80075"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-0.999,0.0435,0.0435,0.999,-1277.0056,-522.11722)"
x1="-1375.9844"
y1="685.3809"
x2="-1355.0455"
y2="706.3217" /><linearGradient
inkscape:collect="always"
xlink:href="#XMLID_11_"
id="linearGradient80078"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.1991,0.98,-0.98,0.1991,91.6944,547.96528)"
x1="-481.7007"
y1="-94.4194"
x2="-360.2456"
y2="-164.2214" /><linearGradient
inkscape:collect="always"
xlink:href="#XMLID_10_"
id="linearGradient80085"
gradientUnits="userSpaceOnUse"
x1="29.0532"
y1="29.0532"
x2="226.9471"
y2="226.9471" /><linearGradient
inkscape:collect="always"
xlink:href="#XMLID_9_"
id="linearGradient80089"
gradientUnits="userSpaceOnUse"
x1="128.9995"
y1="11"
x2="128.9995"
y2="245.0005" /></defs>
<sodipodi:namedview
id="base"
showgrid="false"
inkscape:zoom="3.6203867"
inkscape:cx="24.932695"
inkscape:cy="18.484388"
inkscape:window-width="1280"
inkscape:window-height="766"
inkscape:window-x="0"
inkscape:window-y="20"
inkscape:window-maximized="0"
inkscape:current-layer="svg710" />
<metadata
id="metadata711">
<ns0:sfw>
<ns0:slices>
<ns0:slice
x="0"
y="0"
width="256"
height="256"
sliceID="124333141" />
</ns0:slices>
<ns0:sliceSourceBounds
x="0"
y="0"
width="256"
height="256"
bottomLeftOrigin="true" />
<ns0:optimizationSettings>
<ns0:targetSettings
fileFormat="PNG24Format"
targetSettingsID="0">
<ns0:PNG24Format
transparency="true"
includeCaption="false"
interlaced="false"
noMatteColor="false"
matteColor="#FFFFFF"
filtered="false" />
</ns0:targetSettings>
</ns0:optimizationSettings>
</ns0:sfw>
<xpacket
id="xpacket79197">begin='' id='W5M0MpCehiHzreSzNTczkc9d' </xpacket>
<x:xmpmeta
x:xmptk="XMP toolkit 3.0-29, framework 1.6">
<metadata
id="metadata79254"><rdf:RDF>
<rdf:Description
rdf:about="uuid:cbee75c6-82d1-45ba-8274-b89c6084675c">
<pdf:Producer>
Adobe PDF library 5.00</pdf:Producer>
</rdf:Description>
<rdf:Description
rdf:about="uuid:cbee75c6-82d1-45ba-8274-b89c6084675c" />
<rdf:Description
rdf:about="uuid:cbee75c6-82d1-45ba-8274-b89c6084675c" />
<rdf:Description
rdf:about="uuid:cbee75c6-82d1-45ba-8274-b89c6084675c">
<xap:CreateDate>
2004-01-26T11:58:28+02:00</xap:CreateDate>
<xap:ModifyDate>
2004-03-28T20:41:40Z</xap:ModifyDate>
<xap:CreatorTool>
Adobe Illustrator 10.0</xap:CreatorTool>
<xap:MetadataDate>
2004-02-16T23:58:32+01:00</xap:MetadataDate>
<xap:Thumbnails>
<rdf:Alt>
<rdf:li
rdf:parseType="Resource">
<xapGImg:format>
JPEG</xapGImg:format>
<xapGImg:width>
256</xapGImg:width>
<xapGImg:height>
256</xapGImg:height>
<xapGImg:image>
/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER
AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy
obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp
0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo
+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7
FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYqlvmDzFo
3l7TJdT1e5W1tItuTbszHoiKN2Y+AxV4j5g/5ydvTcMnl/SYlgU0Se/LOzDxMcTIF/4M4qk//QzP
nv8A5YNL/wCRVx/2UYq7/oZnz3/ywaX/AMirj/soxV3/AEMz57/5YNL/AORVx/2UYq7/AKGZ89/8
sGl/8irj/soxV3/QzPnv/lg0v/kVcf8AZRirv+hmfPf/ACwaX/yKuP8AsoxV3/QzPnv/AJYNL/5F
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
f//Z</xapGImg:image>
</rdf:li>
</rdf:Alt>
</xap:Thumbnails>
</rdf:Description>
<rdf:Description
rdf:about="uuid:cbee75c6-82d1-45ba-8274-b89c6084675c">
<xapMM:DocumentID>
uuid:4ee3f24b-6ed2-4a2e-8f7a-50b762c8da8b</xapMM:DocumentID>
</rdf:Description>
<rdf:Description
rdf:about="uuid:cbee75c6-82d1-45ba-8274-b89c6084675c">
<dc:format>
image/svg+xml</dc:format>
<dc:title>
<rdf:Alt>
<rdf:li
xml:lang="x-default">
mime.ai</rdf:li>
</rdf:Alt>
</dc:title>
</rdf:Description>
<cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata></x:xmpmeta>
<xpacket
id="xpacket79199">end='w' </xpacket>
</metadata>
<path
style="opacity:0.2"
inkscape:connector-curvature="0"
id="path713"
d="m 44,15.5 c -9.374,0 -17,7.626 -17,17 v 200 c 0,9.374 7.626,17 17,17 h 176 c 9.375,0 17,-7.626 17,-17 v -200 c 0,-9.374 -7.625,-17 -17,-17 H 44 z" /><path
style="opacity:0.2"
inkscape:connector-curvature="0"
id="path714"
d="m 42,13.5 c -9.374,0 -17,7.626 -17,17 v 200 c 0,9.374 7.626,17 17,17 h 176 c 9.375,0 17,-7.626 17,-17 v -200 c 0,-9.374 -7.625,-17 -17,-17 H 42 z" /><path
style="opacity:0.2"
inkscape:connector-curvature="0"
id="path715"
d="m 40,12.5 c -9.374,0 -17,7.626 -17,17 v 200 c 0,9.374 7.626,17 17,17 h 176 c 9.375,0 17,-7.626 17,-17 v -200 c 0,-9.374 -7.625,-17 -17,-17 H 40 z" /><path
inkscape:connector-curvature="0"
style="fill:url(#linearGradient80089)"
id="path722"
d="m 41,11 c -9.374,0 -17,7.626 -17,17 v 200 c 0,9.374 7.626,17 17,17 h 176 c 9.375,0 17,-7.626 17,-17 V 28 c 0,-9.374 -7.625,-17 -17,-17 H 41 z" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path723"
d="m 28,228 c 0,6.627 5.373,12 12,12 h 176 c 6.627,0 12,-5.373 12,-12 V 28 c 0,-6.627 -5.373,-12 -12,-12 H 40 c -6.627,0 -12,5.373 -12,12 v 200 z" /><path
inkscape:connector-curvature="0"
style="fill:url(#linearGradient80085)"
id="path730"
d="m 40,21 c -3.86,0 -7,3.14 -7,7 v 200 c 0,3.859 3.14,7 7,7 h 176 c 3.859,0 7,-3.141 7,-7 V 28 c 0,-3.86 -3.141,-7 -7,-7 H 40 z" /><path
style="opacity:0.2"
inkscape:connector-curvature="0"
id="path731"
d="m 191.924,170.38398 c -11.613,-36.12699 -13.717,-42.66999 -14.859,-44.06399 0.119,0.076 0.289,0.178 0.289,0.178 L 98.804,39.042999 c -4.195,-4.65 -14.005,0.356 -21.355,6.976 -7.283,6.542 -13.32,15.772999 -9.37,20.563999 l 78.944,87.542982 0.533,0.094 37.768,17.602 7.688,2.365 -1.088,-3.803 z" /><path
style="opacity:0.2"
inkscape:connector-curvature="0"
id="path732"
d="m 193.557,167.91598 c -11.611,-36.12499 -13.713,-42.66999 -14.855,-44.06399 0.117,0.072 0.287,0.178 0.287,0.178 L 100.444,36.574999 c -4.199,-4.651 -14.015,0.355 -21.361,6.975 -7.281,6.545 -13.32,15.772999 -9.368,20.565999 l 78.945,87.538982 0.533,0.1 37.77,17.598 7.682,2.367 -1.088,-3.804 z" /><path
style="opacity:0.2"
inkscape:connector-curvature="0"
id="path733"
d="M 186.773,165.44898 C 175.16,129.32199 173.06,122.77699 171.91,121.38099 c 0.121,0.074 0.295,0.18 0.295,0.18 L 93.653,34.103999 c -4.192,-4.65 -14.009,0.359 -21.354,6.978 -7.283,6.542 -13.321,15.770999 -9.369,20.564999 l 78.942,87.540982 0.535,0.096 37.768,17.598 7.686,2.367 -1.088,-3.8 z" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path734"
d="m 186.43,163.75498 c -11.613,-36.12499 -13.713,-42.66599 -14.863,-44.06099 0.123,0.072 0.293,0.18 0.293,0.18 L 93.314,32.415999 c -4.199,-4.651 -14.015,0.357 -21.359,6.977 -7.283,6.543 -13.322,15.773999 -9.37,20.565999 l 78.941,87.540982 0.535,0.098 37.771,17.598 7.686,2.363 -1.088,-3.804 z" /><path
inkscape:connector-curvature="0"
style="fill:url(#linearGradient80078)"
id="path741"
d="m 186.43,163.75498 c -11.613,-36.12499 -13.713,-42.66599 -14.863,-44.06099 0.123,0.072 0.293,0.18 0.293,0.18 L 93.314,32.415999 c -4.199,-4.651 -14.015,0.357 -21.359,6.977 -7.283,6.543 -13.322,15.773999 -9.37,20.565999 l 78.941,87.540982 0.535,0.098 37.771,17.598 7.686,2.363 -1.088,-3.804 z" /><path
inkscape:connector-curvature="0"
style="fill:url(#linearGradient80075)"
id="path748"
d="m 166.969,122.16199 13.723,38.12899 -36.371,-17.90199 0.168,-0.152 c -0.25,-0.08 -0.496,-0.178 -0.701,-0.316 l -0.125,0.121 -75.303,-83.569992 0.123,-0.104 c -2.246,-2.49 1.032,-9.093999 7.308,-14.751999 6.28,-5.652 13.18,-8.219 15.425,-5.733 l 75.292,83.564991 0.461,0.714 z" /><path
inkscape:connector-curvature="0"
style="fill:url(#linearGradient80072)"
id="path758"
d="m 148.652,144.52098 c 2.076,-0.369 4.635,-1.479 7.252,-3.13899 1.617,-1.018 3.279,-2.283 4.898,-3.744 1.455,-1.303 2.736,-2.666 3.84,-4.01 2.076,-2.531 3.322,-5.213 3.781,-7.424 l -1.455,-4.043 -0.463,-0.715 -74.798,-83.017991 c 0.608,2.24 -0.962,5.938 -4.063,9.74 -1.134,1.389 -2.441,2.789 -3.945,4.141 -1.574,1.418999 -3.195,2.651999 -4.767,3.653999 -4.493,2.871 -8.628,3.928 -10.548,2.486 l -0.025,0.021 75.303,83.569992 0.125,-0.121 c 0.205,0.139 0.451,0.236 0.701,0.316 l -0.168,0.152 4.332,2.13399 z" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path759"
d="m 68.083,57.809998 c 1.732,1.772 5.994,0.776 10.643,-2.194 1.541,-0.982 3.132,-2.193 4.677,-3.585999 1.476,-1.325 2.759,-2.701 3.872,-4.063 3.578,-4.388 5.091,-8.642 3.477,-10.584 l 0.023,-0.024 75.817,84.118991 c 0.635,2.262 -0.588,6.498 -3.754,10.357 -1.082,1.318 -2.34,2.656 -3.77,3.934 -1.588,1.434 -3.219,2.676 -4.807,3.676 -4.74,3.006 -9.303,4.19899 -11.016,2.301 -0.393,-0.439 -2.098,-2.336 -2.145,-2.406 l -73.255,-81.313992 0.238,-0.216 z" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path760"
d="m 75.79,43.614999 c 6.28,-5.652 13.18,-8.219 15.425,-5.733 l 16.961,18.827999 1.152,26.49 -17.973,0.784 -22.996,-25.513 0.123,-0.104 c -2.246,-2.49 1.032,-9.092999 7.308,-14.751999 z" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path761"
d="m 68.083,57.809998 c 1.732,1.772 5.994,0.776 10.643,-2.194 1.541,-0.982 3.132,-2.193 4.677,-3.585999 1.476,-1.325 2.759,-2.701 3.872,-4.063 3.578,-4.388 5.091,-8.642 3.477,-10.584 l 0.023,-0.024 75.817,84.118991 c 0.635,2.262 -0.588,6.498 -3.754,10.357 -1.082,1.318 -2.34,2.656 -3.77,3.934 -1.588,1.434 -3.219,2.676 -4.807,3.676 -4.74,3.006 -9.303,4.19899 -11.016,2.301 -0.393,-0.439 -2.098,-2.336 -2.145,-2.406 l -73.255,-81.313992 0.238,-0.216 z" /><path
inkscape:connector-curvature="0"
style="fill:url(#linearGradient80066)"
id="path768"
d="m 75.79,43.614999 c 6.28,-5.652 13.18,-8.219 15.425,-5.733 l 16.961,18.827999 1.152,26.49 -17.973,0.784 -22.996,-25.513 0.123,-0.104 c -2.246,-2.49 1.032,-9.092999 7.308,-14.751999 z" /><path
inkscape:connector-curvature="0"
style="fill:url(#linearGradient80063)"
id="path778"
d="m 68.083,57.809998 c 1.732,1.772 5.994,0.776 10.643,-2.194 1.541,-0.982 3.132,-2.193 4.677,-3.585999 1.476,-1.325 2.759,-2.701 3.872,-4.063 3.578,-4.388 5.091,-8.642 3.477,-10.584 l 0.023,-0.024 75.817,84.118991 c 0.635,2.262 -0.588,6.498 -3.754,10.357 -1.082,1.318 -2.34,2.656 -3.77,3.934 -1.588,1.434 -3.219,2.676 -4.807,3.676 -4.74,3.006 -9.303,4.19899 -11.016,2.301 -0.393,-0.439 -2.098,-2.336 -2.145,-2.406 l -73.255,-81.313992 0.238,-0.216 z" /><path
inkscape:connector-curvature="0"
style="fill:url(#linearGradient80060)"
id="path790"
d="m 74.357,65.112998 c 0,0 6.036,-0.212 10.685,-3.182 1.542,-0.983 3.132,-2.193 4.677,-3.586 1.477,-1.326 2.76,-2.701 3.873,-4.064 2.928,-3.588999 4.469,-7.087999 4.049,-9.306999 l -6.865,-7.617 -0.023,0.024 c 1.614,1.942 0.102,6.196 -3.477,10.584 -1.113,1.362 -2.396,2.738 -3.872,4.063 -1.545,1.392999 -3.136,2.603999 -4.677,3.585999 -4.648,2.971 -8.91,3.967 -10.643,2.194 l -0.238,0.217 73.256,81.310992 c 0.047,0.07 1.752,1.967 2.145,2.406 0.342,0.377 0.799,0.627 1.344,0.771 L 74.357,65.112998 z" /><path
style="fill:#003333"
inkscape:connector-curvature="0"
id="path791"
d="m 172.035,149.75398 c -1.635,1.477 -3.307,2.764 -4.949,3.84 l 13.605,6.697 -5.096,-14.156 c -1.058,1.218 -2.243,2.441 -3.56,3.619 z" /><path
style="opacity:0.5;fill:#ffffff"
inkscape:connector-curvature="0"
id="path792"
d="M 163.121,131.45299 86.968,48.329999 c 0.1,-0.12 0.213,-0.242 0.307,-0.364 1.428,-1.752 2.52,-3.49 3.225,-5.058 l 75.768,82.706991 c -0.553,1.824 -1.6,3.867 -3.147,5.838 z" /><path
style="opacity:0.5;fill:#ffffff"
inkscape:connector-curvature="0"
id="path793"
d="m 87.275,47.965999 c 0.634,-0.774 1.189,-1.548 1.694,-2.3 l 76.015,82.973991 c -0.578,1.063 -1.283,2.146 -2.146,3.193 -0.744,0.896 -1.566,1.805 -2.465,2.697 L 84.152,51.331999 c 1.164,-1.108 2.209,-2.24 3.123,-3.366 z" /><rect
style="fill:none"
y="0"
x="0"
height="256"
width="256"
id="_x3C_Slice_x3E_" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:4.26666689;stroke-opacity:1"
id="rect79256"
width="150.77966"
height="48.813557"
x="9.313406"
y="170.86343"
ry="0" /><text
xml:space="preserve"
style="font-size:42.66666794px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:justify;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Linux Libertine O C;-inkscape-font-specification:Linux Libertine O C"
x="24.554667"
y="207.10201"
id="text80094"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan80096"
x="24.554667"
y="207.10201"
style="font-style:italic;font-weight:bold;-inkscape-font-specification:Linux Libertine O C Bold Italic">Labels</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 977 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,577 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
xmlns:i="http://ns.adobe.com/AdobeIllustrator/10.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.0"
width="48pt"
height="48pt"
viewBox="0 0 256 256"
id="svg2"
xml:space="preserve"
sodipodi:version="0.32"
inkscape:version="0.42+devel"
sodipodi:docname="gtk-open2.svg"
sodipodi:docbase="/home/cschalle/gnome/gnome-themes-extras/Nuvola/icons/scalable/stock"><metadata
id="metadata85"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><sodipodi:namedview
inkscape:cy="417.84947"
inkscape:cx="305.25953"
inkscape:zoom="0.43415836"
inkscape:window-height="563"
inkscape:window-width="822"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#ffffff"
id="base"
inkscape:window-x="0"
inkscape:window-y="30"
inkscape:current-layer="svg2" /><defs
id="defs151" />
<g
id="switch6">
<foreignObject
id="foreignObject8"
height="1"
width="1"
y="0"
x="0"
requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/">
<i:pgfRef
xlink:href="#adobe_illustrator_pgf">
</i:pgfRef>
</foreignObject>
<g
id="g10">
<g
id="Layer_1">
<rect
width="256"
height="256"
x="0"
y="0"
style="fill:none"
id="rect13" />
</g>
<g
id="Layer_2">
<linearGradient
x1="98.551804"
y1="41.2593"
x2="98.551804"
y2="214.72549"
id="XMLID_14_"
gradientUnits="userSpaceOnUse">
<stop
style="stop-color:#c9e6ff;stop-opacity:1"
offset="0"
id="stop17" />
<stop
style="stop-color:#006dff;stop-opacity:1"
offset="0.55620003"
id="stop19" />
<stop
style="stop-color:#0035ed;stop-opacity:1"
offset="1"
id="stop21" />
<a:midPointStop
style="stop-color:#C9E6FF"
offset="0" />
<a:midPointStop
style="stop-color:#C9E6FF"
offset="0.5" />
<a:midPointStop
style="stop-color:#006DFF"
offset="0.5562" />
<a:midPointStop
style="stop-color:#006DFF"
offset="0.5" />
<a:midPointStop
style="stop-color:#0035ED"
offset="1" />
</linearGradient>
<path
d="M 17.219,51.266 C 16.115,51.266 15.219,52.163 15.219,53.266 L 15.219,202.735 C 15.219,203.838 16.115,204.735 17.219,204.735 L 179.885,204.735 C 180.989,204.735 181.885,203.838 181.885,202.735 L 181.885,75.933 C 181.885,74.83 180.989,73.933 179.885,73.933 L 100.552,73.933 L 100.552,53.266 C 100.552,52.163 99.656,51.266 98.552,51.266 L 17.219,51.266 z "
style="fill:url(#XMLID_14_)"
id="path23" />
<linearGradient
x1="98.551804"
y1="41.258801"
x2="98.551804"
y2="214.7274"
id="XMLID_15_"
gradientUnits="userSpaceOnUse">
<stop
style="stop-color:#dcf0ff;stop-opacity:1"
offset="0"
id="stop26" />
<stop
style="stop-color:#428aff;stop-opacity:1"
offset="0.58990002"
id="stop28" />
<stop
style="stop-color:#006dff;stop-opacity:1"
offset="0.85949999"
id="stop30" />
<stop
style="stop-color:#0035ed;stop-opacity:1"
offset="1"
id="stop32" />
<a:midPointStop
style="stop-color:#DCF0FF"
offset="0" />
<a:midPointStop
style="stop-color:#DCF0FF"
offset="0.5" />
<a:midPointStop
style="stop-color:#428AFF"
offset="0.5899" />
<a:midPointStop
style="stop-color:#428AFF"
offset="0.5" />
<a:midPointStop
style="stop-color:#006DFF"
offset="0.8595" />
<a:midPointStop
style="stop-color:#006DFF"
offset="0.5" />
<a:midPointStop
style="stop-color:#0035ED"
offset="1" />
</linearGradient>
<path
d="M 20.219,56.266 C 20.219,61.91 20.219,194.091 20.219,199.735 C 25.891,199.735 171.213,199.735 176.885,199.735 C 176.885,194.154 176.885,84.514 176.885,78.933 C 171.33,78.933 95.552,78.933 95.552,78.933 C 95.552,78.933 95.552,60.651 95.552,56.266 C 90.2,56.266 25.572,56.266 20.219,56.266 z "
style="fill:url(#XMLID_15_)"
id="path34" />
<linearGradient
x1="98.551804"
y1="41.2593"
x2="98.551804"
y2="214.72549"
id="XMLID_16_"
gradientUnits="userSpaceOnUse">
<stop
style="stop-color:#ffffff;stop-opacity:1"
offset="0"
id="stop37" />
<stop
style="stop-color:#e9f2ff;stop-opacity:1"
offset="0.1147"
id="stop39" />
<stop
style="stop-color:#b0d2ff;stop-opacity:1"
offset="0.35389999"
id="stop41" />
<stop
style="stop-color:#579fff;stop-opacity:1"
offset="0.6936"
id="stop43" />
<stop
style="stop-color:#006dff;stop-opacity:1"
offset="1"
id="stop45" />
<a:midPointStop
style="stop-color:#FFFFFF"
offset="0" />
<a:midPointStop
style="stop-color:#FFFFFF"
offset="0.5424" />
<a:midPointStop
style="stop-color:#006DFF"
offset="1" />
</linearGradient>
<path
d="M 179.885,73.933 L 100.552,73.933 L 100.552,53.266 C 100.552,52.163 99.656,51.266 98.552,51.266 L 17.219,51.266 C 16.115,51.266 15.219,52.163 15.219,53.266 L 15.219,57.266 L 91.552,57.266 C 92.656,57.266 93.552,58.163 93.552,59.266 L 93.552,79.933 L 172.885,79.933 C 173.989,79.933 174.885,80.83 174.885,81.933 L 174.885,204.735 L 179.885,204.735 C 180.989,204.735 181.885,203.838 181.885,202.735 L 181.885,75.933 C 181.885,74.83 180.988,73.933 179.885,73.933 z "
style="fill:url(#XMLID_16_)"
id="path47" />
<linearGradient
x1="106.9839"
y1="98.599098"
x2="106.9839"
y2="206.73489"
id="XMLID_17_"
gradientUnits="userSpaceOnUse">
<stop
style="stop-color:#0099ff;stop-opacity:1"
offset="0"
id="stop50" />
<stop
style="stop-color:#0089e5;stop-opacity:1"
offset="0.0937"
id="stop52" />
<stop
style="stop-color:#00406b;stop-opacity:1"
offset="0.54689997"
id="stop54" />
<stop
style="stop-color:#00121e;stop-opacity:1"
offset="0.85769999"
id="stop56" />
<stop
style="stop-color:#000000;stop-opacity:1"
offset="1"
id="stop58" />
<a:midPointStop
style="stop-color:#0099FF"
offset="0" />
<a:midPointStop
style="stop-color:#0099FF"
offset="0.4689" />
<a:midPointStop
style="stop-color:#000000"
offset="1" />
</linearGradient>
<path
d="M 32.083,106.599 L 32.083,206.734 L 42.083,206.734 C 42.083,180.445 42.083,111.718 42.083,108.599 C 45.222,108.599 143.57,108.599 181.884,108.599 L 181.884,98.599 L 40.083,98.599 C 35.665,98.599 32.083,102.181 32.083,106.599 z "
style="opacity:0.3;fill:url(#XMLID_17_)"
id="path60" />
<linearGradient
x1="6.3671999"
y1="47.148399"
x2="179.4046"
y2="220.1859"
id="XMLID_18_"
gradientUnits="userSpaceOnUse">
<stop
style="stop-color:#0053bd;stop-opacity:1"
offset="0"
id="stop63" />
<stop
style="stop-color:#00008d;stop-opacity:1"
offset="1"
id="stop65" />
<a:midPointStop
style="stop-color:#0053BD"
offset="0" />
<a:midPointStop
style="stop-color:#0053BD"
offset="0.5" />
<a:midPointStop
style="stop-color:#00008D"
offset="1" />
</linearGradient>
<path
d="M 179.885,63.933 L 110.552,63.933 L 110.552,53.266 C 110.552,46.639 105.18,41.266 98.552,41.266 L 17.219,41.266 C 10.591,41.266 5.219,46.639 5.219,53.266 L 5.219,75.933 L 5.219,202.735 C 5.219,209.362 10.591,214.735 17.219,214.735 L 98.552,214.735 L 179.885,214.735 C 186.512,214.735 191.885,209.362 191.885,202.735 L 191.885,75.933 C 191.885,69.305 186.512,63.933 179.885,63.933 z M 181.885,202.734 C 181.885,203.837 180.989,204.734 179.885,204.734 L 17.219,204.734 C 16.115,204.734 15.219,203.837 15.219,202.734 L 15.219,53.266 C 15.219,52.163 16.115,51.266 17.219,51.266 L 98.552,51.266 C 99.656,51.266 100.552,52.163 100.552,53.266 L 100.552,73.933 L 179.885,73.933 C 180.989,73.933 181.885,74.83 181.885,75.933 L 181.885,202.734 z "
style="fill:url(#XMLID_18_)"
id="path67" />
<linearGradient
x1="128.48441"
y1="86.066902"
x2="128.48441"
y2="228.0708"
id="XMLID_19_"
gradientUnits="userSpaceOnUse">
<stop
style="stop-color:#c9e6ff;stop-opacity:1"
offset="0"
id="stop70" />
<stop
style="stop-color:#006dff;stop-opacity:1"
offset="0.55620003"
id="stop72" />
<stop
style="stop-color:#0035ed;stop-opacity:1"
offset="1"
id="stop74" />
<a:midPointStop
style="stop-color:#C9E6FF"
offset="0" />
<a:midPointStop
style="stop-color:#C9E6FF"
offset="0.5" />
<a:midPointStop
style="stop-color:#006DFF"
offset="0.5562" />
<a:midPointStop
style="stop-color:#006DFF"
offset="0.5" />
<a:midPointStop
style="stop-color:#0035ED"
offset="1" />
</linearGradient>
<path
d="M 51.083,96.599 C 51.083,100.388 51.083,200.946 51.083,204.734 C 54.933,204.734 202.035,204.734 205.884,204.734 C 205.884,200.946 205.884,100.387 205.884,96.599 C 202.035,96.599 54.933,96.599 51.083,96.599 z "
style="fill:url(#XMLID_19_)"
id="path76" />
<linearGradient
x1="128.48441"
y1="86.064499"
x2="128.48441"
y2="228.06689"
id="XMLID_20_"
gradientUnits="userSpaceOnUse">
<stop
style="stop-color:#dcf0ff;stop-opacity:1"
offset="0"
id="stop79" />
<stop
style="stop-color:#428aff;stop-opacity:1"
offset="0.6742"
id="stop81" />
<stop
style="stop-color:#006dff;stop-opacity:1"
offset="1"
id="stop83" />
<a:midPointStop
style="stop-color:#DCF0FF"
offset="0" />
<a:midPointStop
style="stop-color:#DCF0FF"
offset="0.5" />
<a:midPointStop
style="stop-color:#428AFF"
offset="0.6742" />
<a:midPointStop
style="stop-color:#428AFF"
offset="0.5" />
<a:midPointStop
style="stop-color:#006DFF"
offset="1" />
</linearGradient>
<path
d="M 56.083,101.599 C 56.083,110.255 56.083,191.079 56.083,199.734 C 65.135,199.734 191.833,199.734 200.884,199.734 C 200.884,191.079 200.884,110.255 200.884,101.599 C 191.834,101.599 65.135,101.599 56.083,101.599 z "
style="fill:url(#XMLID_20_)"
id="path85" />
<linearGradient
x1="54.491199"
y1="76.673798"
x2="217.155"
y2="239.3376"
id="XMLID_21_"
gradientUnits="userSpaceOnUse">
<stop
style="stop-color:#0053bd;stop-opacity:1"
offset="0"
id="stop88" />
<stop
style="stop-color:#00008d;stop-opacity:1"
offset="1"
id="stop90" />
<a:midPointStop
style="stop-color:#0053BD"
offset="0" />
<a:midPointStop
style="stop-color:#0053BD"
offset="0.5" />
<a:midPointStop
style="stop-color:#00008D"
offset="1" />
</linearGradient>
<path
d="M 207.885,86.599 L 49.083,86.599 C 44.664,86.599 41.083,90.181 41.083,94.599 L 41.083,206.734 C 41.083,211.152 44.664,214.734 49.083,214.734 L 207.884,214.734 C 212.302,214.734 215.884,211.152 215.884,206.734 L 215.884,94.599 C 215.885,90.181 212.303,86.599 207.885,86.599 z M 205.885,204.734 C 202.035,204.734 54.933,204.734 51.084,204.734 C 51.084,200.946 51.084,100.387 51.084,96.599 C 54.934,96.599 202.036,96.599 205.885,96.599 C 205.885,100.388 205.885,200.946 205.885,204.734 z "
style="fill:url(#XMLID_21_)"
id="path92" />
<linearGradient
x1="128.48441"
y1="86.066902"
x2="128.48441"
y2="228.0708"
id="XMLID_22_"
gradientUnits="userSpaceOnUse">
<stop
style="stop-color:#ffffff;stop-opacity:1"
offset="0"
id="stop95" />
<stop
style="stop-color:#f7fbff;stop-opacity:1"
offset="0.0862"
id="stop97" />
<stop
style="stop-color:#e2eeff;stop-opacity:1"
offset="0.2177"
id="stop99" />
<stop
style="stop-color:#c0dbff;stop-opacity:1"
offset="0.3779"
id="stop101" />
<stop
style="stop-color:#8fbfff;stop-opacity:1"
offset="0.56089997"
id="stop103" />
<stop
style="stop-color:#529cff;stop-opacity:1"
offset="0.76310003"
id="stop105" />
<stop
style="stop-color:#0871ff;stop-opacity:1"
offset="0.97839999"
id="stop107" />
<stop
style="stop-color:#006dff;stop-opacity:1"
offset="1"
id="stop109" />
<a:midPointStop
style="stop-color:#FFFFFF"
offset="0" />
<a:midPointStop
style="stop-color:#FFFFFF"
offset="0.6158" />
<a:midPointStop
style="stop-color:#006DFF"
offset="1" />
</linearGradient>
<path
d="M 51.083,96.599 C 51.083,97.141 51.083,99.667 51.083,103.599 C 82.419,103.599 194.529,103.599 197.884,103.599 C 197.884,106.846 197.884,181.163 197.884,204.734 C 202.511,204.734 205.39,204.734 205.884,204.734 C 205.884,200.946 205.884,100.387 205.884,96.599 C 202.035,96.599 54.933,96.599 51.083,96.599 z "
style="fill:url(#XMLID_22_)"
id="path111" />
<path
d="M 132.455,30.044 C 126.885,30.044 122.355,34.574 122.355,40.143 L 122.355,158.953 C 122.355,164.521 126.885,169.053 132.455,169.053 L 237.008,169.053 C 242.576,169.053 247.108,164.522 247.108,158.953 L 247.108,40.143 C 247.108,34.574 242.577,30.044 237.008,30.044 L 132.455,30.044 z "
style="fill:#003366"
id="path113" />
<linearGradient
x1="158.8916"
y1="73.708504"
x2="299.68201"
y2="214.4994"
id="XMLID_23_"
gradientUnits="userSpaceOnUse">
<stop
style="stop-color:#ffffff;stop-opacity:1"
offset="0"
id="stop116" />
<stop
style="stop-color:#99ccff;stop-opacity:1"
offset="1"
id="stop118" />
<a:midPointStop
style="stop-color:#FFFFFF"
offset="0" />
<a:midPointStop
style="stop-color:#FFFFFF"
offset="0.5" />
<a:midPointStop
style="stop-color:#99CCFF"
offset="1" />
</linearGradient>
<path
d="M 132.455,35.984 C 130.162,35.984 128.295,37.85 128.295,40.143 L 128.295,158.953 C 128.295,161.246 130.162,163.111 132.455,163.111 L 237.008,163.111 C 239.301,163.111 241.166,161.246 241.166,158.953 L 241.166,40.143 C 241.166,37.85 239.301,35.984 237.008,35.984 L 132.455,35.984 z "
style="fill:url(#XMLID_23_)"
id="path120" />
<path
d="M 205.523,86.479 C 216.566,76.124 229.841,71.031 244.136,68.5 L 244.136,40.143 C 244.136,36.206 240.943,33.014 237.007,33.014 L 132.455,33.014 C 128.517,33.014 125.326,36.206 125.326,40.143 L 125.326,125.251 C 154.779,127.473 182.639,106.979 205.523,86.479 z "
style="opacity:0.4;fill:#ffffff"
id="path122" />
<linearGradient
x1="141.7061"
y1="66.528297"
x2="239.2188"
y2="164.041"
id="XMLID_24_"
gradientUnits="userSpaceOnUse">
<stop
style="stop-color:#0053bd;stop-opacity:1"
offset="0"
id="stop125" />
<stop
style="stop-color:#00008d;stop-opacity:1"
offset="1"
id="stop127" />
<a:midPointStop
style="stop-color:#0053BD"
offset="0" />
<a:midPointStop
style="stop-color:#0053BD"
offset="0.5" />
<a:midPointStop
style="stop-color:#00008D"
offset="1" />
</linearGradient>
<path
d="M 207.885,86.599 L 122.355,86.599 L 122.355,96.599 C 162.027,96.599 203.855,96.599 205.885,96.599 C 205.885,98.946 205.885,138.441 205.885,169.053 L 215.885,169.053 L 215.885,94.599 C 215.885,90.181 212.303,86.599 207.885,86.599 z "
style="opacity:0.2;fill:url(#XMLID_24_)"
id="path129" />
<linearGradient
x1="164.1201"
y1="89.542"
x2="164.1201"
y2="184.68871"
id="XMLID_25_"
gradientUnits="userSpaceOnUse">
<stop
style="stop-color:#c9e6ff;stop-opacity:1"
offset="0"
id="stop132" />
<stop
style="stop-color:#006dff;stop-opacity:1"
offset="0.55620003"
id="stop134" />
<stop
style="stop-color:#0035ed;stop-opacity:1"
offset="1"
id="stop136" />
<a:midPointStop
style="stop-color:#C9E6FF"
offset="0" />
<a:midPointStop
style="stop-color:#C9E6FF"
offset="0.5" />
<a:midPointStop
style="stop-color:#006DFF"
offset="0.5562" />
<a:midPointStop
style="stop-color:#006DFF"
offset="0.5" />
<a:midPointStop
style="stop-color:#0035ED"
offset="1" />
</linearGradient>
<path
d="M 122.355,158.953 C 122.355,164.521 126.885,169.053 132.455,169.053 L 205.885,169.053 C 205.885,138.442 205.885,98.947 205.885,96.599 C 203.856,96.599 162.028,96.599 122.355,96.599 L 122.355,158.953 L 122.355,158.953 z "
style="opacity:0.2;fill:url(#XMLID_25_)"
id="path138" />
<linearGradient
x1="185.8848"
y1="86.066902"
x2="185.8848"
y2="228.0708"
id="XMLID_26_"
gradientUnits="userSpaceOnUse">
<stop
style="stop-color:#0053bd;stop-opacity:1"
offset="0"
id="stop141" />
<stop
style="stop-color:#00008d;stop-opacity:1"
offset="1"
id="stop143" />
<a:midPointStop
style="stop-color:#0053BD"
offset="0" />
<a:midPointStop
style="stop-color:#0053BD"
offset="0.5" />
<a:midPointStop
style="stop-color:#00008D"
offset="1" />
</linearGradient>
<path
d="M 181.885,96.599 L 181.885,202.734 C 181.885,203.837 180.989,204.734 179.885,204.734 C 184.268,204.734 188.244,204.734 191.705,204.734 C 191.814,204.083 191.885,203.417 191.885,202.734 L 191.885,96.599 C 188.916,96.599 185.557,96.599 181.885,96.599 z "
style="opacity:0.3;fill:url(#XMLID_26_)"
id="path145" />
<path
d="M 122.355,96.599 L 122.355,103.599 C 159.458,103.599 195.991,103.599 197.885,103.599 C 197.885,105.771 197.885,139.741 197.885,169.053 L 205.885,169.053 C 205.885,138.442 205.885,98.947 205.885,96.599 C 203.855,96.599 162.027,96.599 122.355,96.599 z "
style="opacity:0.2;fill:#ffffff"
id="path147" />
<rect
width="256"
height="256"
x="0"
y="0"
style="fill:none"
id="_x3C_Slice_x3E_" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,679 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
<svg
width="48pt"
height="48pt"
viewBox="0 0 48 48"
style="overflow:visible;enable-background:new 0 0 48 48"
xml:space="preserve"
xmlns="http://www.w3.org/2000/svg"
xmlns:xap="http://ns.adobe.com/xap/1.0/"
xmlns:xapGImg="http://ns.adobe.com/xap/1.0/g/img/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/"
xmlns:pdf="http://ns.adobe.com/pdf/1.3/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
xmlns:x="adobe:ns:meta/"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
id="svg589"
sodipodi:version="0.32"
sodipodi:docname="/home/david/Desktop/temp/devices/gnome-dev-floppy.svg"
sodipodi:docbase="/home/david/Desktop/temp/devices/">
<defs
id="defs677" />
<sodipodi:namedview
id="base" />
<metadata
id="metadata590">
<xpacket>begin='' id='W5M0MpCehiHzreSzNTczkc9d' </xpacket>
<x:xmpmeta
x:xmptk="XMP toolkit 3.0-29, framework 1.6">
<rdf:RDF>
<rdf:Description
rdf:about="uuid:9dfcc10e-f4e2-4cbf-91b0-8deea2f1a998">
<pdf:Producer>
Adobe PDF library 5.00</pdf:Producer>
</rdf:Description>
<rdf:Description
rdf:about="uuid:9dfcc10e-f4e2-4cbf-91b0-8deea2f1a998" />
<rdf:Description
rdf:about="uuid:9dfcc10e-f4e2-4cbf-91b0-8deea2f1a998" />
<rdf:Description
rdf:about="uuid:9dfcc10e-f4e2-4cbf-91b0-8deea2f1a998">
<xap:CreateDate>
2004-02-04T02:08:51+02:00</xap:CreateDate>
<xap:ModifyDate>
2004-03-29T09:20:16Z</xap:ModifyDate>
<xap:CreatorTool>
Adobe Illustrator 10.0</xap:CreatorTool>
<xap:MetadataDate>
2004-02-29T14:54:28+01:00</xap:MetadataDate>
<xap:Thumbnails>
<rdf:Alt>
<rdf:li
rdf:parseType="Resource">
<xapGImg:format>
JPEG</xapGImg:format>
<xapGImg:width>
256</xapGImg:width>
<xapGImg:height>
256</xapGImg:height>
<xapGImg:image>
/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER
AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy
obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp
0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo
+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7
FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7F
XYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX
Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXY
q7FXzd+b/wDzlWum3k+h+QxFc3EJMdzrkoEkKuNiLZPsyU/nb4fAEb50vZ/YXEBPLsP5v62meXue
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</xapGImg:image>
</rdf:li>
</rdf:Alt>
</xap:Thumbnails>
</rdf:Description>
<rdf:Description
rdf:about="uuid:9dfcc10e-f4e2-4cbf-91b0-8deea2f1a998">
<xapMM:DocumentID>
uuid:f3c53255-be8a-4b04-817b-695bf2c54c8b</xapMM:DocumentID>
</rdf:Description>
<rdf:Description
rdf:about="uuid:9dfcc10e-f4e2-4cbf-91b0-8deea2f1a998">
<dc:format>
image/svg+xml</dc:format>
<dc:title>
<rdf:Alt>
<rdf:li
xml:lang="x-default">
filesave.ai</rdf:li>
</rdf:Alt>
</dc:title>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
<xpacket>end='w' </xpacket>
</metadata>
<g
id="Layer_1">
<path
style="opacity:0.2;"
d="M9.416,5.208c-2.047,0-3.712,1.693-3.712,3.775V39.15c0,2.082,1.666,3.775,3.712,3.775h29.401 c2.047,0,3.712-1.693,3.712-3.775V8.983c0-2.082-1.665-3.775-3.712-3.775H9.416z"
id="path592" />
<path
style="opacity:0.2;"
d="M9.041,4.833c-2.047,0-3.712,1.693-3.712,3.775v30.167c0,2.082,1.666,3.775,3.712,3.775h29.401 c2.047,0,3.712-1.693,3.712-3.775V8.608c0-2.082-1.665-3.775-3.712-3.775H9.041z"
id="path593" />
<path
style="fill:#00008D;"
d="M8.854,4.646c-2.047,0-3.712,1.693-3.712,3.775v30.167c0,2.082,1.666,3.775,3.712,3.775h29.401 c2.047,0,3.712-1.693,3.712-3.775V8.42c0-2.082-1.665-3.775-3.712-3.775H8.854z"
id="path594" />
<path
style="fill:#00008D;"
d="M8.854,5.021c-1.84,0-3.337,1.525-3.337,3.4v30.167c0,1.875,1.497,3.4,3.337,3.4h29.401 c1.84,0,3.337-1.525,3.337-3.4V8.42c0-1.875-1.497-3.4-3.337-3.4H8.854z"
id="path595" />
<path
id="path166_1_"
style="fill:#FFFFFF;"
d="M40.654,38.588c0,1.36-1.074,2.463-2.399,2.463H8.854c-1.326,0-2.4-1.103-2.4-2.463V8.42 c0-1.36,1.074-2.462,2.4-2.462h29.401c1.325,0,2.399,1.103,2.399,2.462V38.588z" />
<linearGradient
id="path166_2_"
gradientUnits="userSpaceOnUse"
x1="-149.0464"
y1="251.1436"
x2="-149.0464"
y2="436.303"
gradientTransform="matrix(0.1875 0 0 -0.1875 51.5 83.75)">
<stop
offset="0"
style="stop-color:#B4E2FF"
id="stop598" />
<stop
offset="1"
style="stop-color:#006DFF"
id="stop599" />
<a:midPointStop
offset="0"
style="stop-color:#B4E2FF"
id="midPointStop600" />
<a:midPointStop
offset="0.5"
style="stop-color:#B4E2FF"
id="midPointStop601" />
<a:midPointStop
offset="1"
style="stop-color:#006DFF"
id="midPointStop602" />
</linearGradient>
<path
id="path166"
style="fill:url(#path166_2_);"
d="M40.654,38.588c0,1.36-1.074,2.463-2.399,2.463H8.854c-1.326,0-2.4-1.103-2.4-2.463V8.42 c0-1.36,1.074-2.462,2.4-2.462h29.401c1.325,0,2.399,1.103,2.399,2.462V38.588z" />
<path
style="fill:#FFFFFF;"
d="M8.854,6.521c-1.013,0-1.837,0.852-1.837,1.9v30.167c0,1.048,0.824,1.9,1.837,1.9h29.401 c1.013,0,1.837-0.853,1.837-1.9V8.42c0-1.048-0.824-1.9-1.837-1.9H8.854z"
id="path604" />
<linearGradient
id="XMLID_1_"
gradientUnits="userSpaceOnUse"
x1="7.3057"
y1="7.2559"
x2="50.7728"
y2="50.7231">
<stop
offset="0"
style="stop-color:#94CAFF"
id="stop606" />
<stop
offset="1"
style="stop-color:#006DFF"
id="stop607" />
<a:midPointStop
offset="0"
style="stop-color:#94CAFF"
id="midPointStop608" />
<a:midPointStop
offset="0.5"
style="stop-color:#94CAFF"
id="midPointStop609" />
<a:midPointStop
offset="1"
style="stop-color:#006DFF"
id="midPointStop610" />
</linearGradient>
<path
style="fill:url(#XMLID_1_);"
d="M8.854,6.521c-1.013,0-1.837,0.852-1.837,1.9v30.167c0,1.048,0.824,1.9,1.837,1.9h29.401 c1.013,0,1.837-0.853,1.837-1.9V8.42c0-1.048-0.824-1.9-1.837-1.9H8.854z"
id="path611" />
<linearGradient
id="XMLID_2_"
gradientUnits="userSpaceOnUse"
x1="23.5039"
y1="2.187"
x2="23.5039"
y2="34.4368">
<stop
offset="0"
style="stop-color:#428AFF"
id="stop613" />
<stop
offset="1"
style="stop-color:#C9E6FF"
id="stop614" />
<a:midPointStop
offset="0"
style="stop-color:#428AFF"
id="midPointStop615" />
<a:midPointStop
offset="0.5"
style="stop-color:#428AFF"
id="midPointStop616" />
<a:midPointStop
offset="1"
style="stop-color:#C9E6FF"
id="midPointStop617" />
</linearGradient>
<path
style="fill:url(#XMLID_2_);"
d="M36.626,6.861c0,0-26.184,0-26.914,0c0,0.704,0,16.59,0,17.294c0.721,0,26.864,0,27.583,0 c0-0.704,0-16.59,0-17.294C36.988,6.861,36.626,6.861,36.626,6.861z"
id="path618" />
<polygon
id="path186_1_"
style="fill:#FFFFFF;"
points="35.809,6.486 10.221,6.486 10.221,23.405 36.788,23.405 36.788,6.486 " />
<linearGradient
id="path186_2_"
gradientUnits="userSpaceOnUse"
x1="-104.5933"
y1="411.6699"
x2="-206.815"
y2="309.4482"
gradientTransform="matrix(0.1875 0 0 -0.1875 51.5 83.75)">
<stop
offset="0"
style="stop-color:#CCCCCC"
id="stop621" />
<stop
offset="1"
style="stop-color:#F0F0F0"
id="stop622" />
<a:midPointStop
offset="0"
style="stop-color:#CCCCCC"
id="midPointStop623" />
<a:midPointStop
offset="0.5"
style="stop-color:#CCCCCC"
id="midPointStop624" />
<a:midPointStop
offset="1"
style="stop-color:#F0F0F0"
id="midPointStop625" />
</linearGradient>
<polygon
id="path186"
style="fill:url(#path186_2_);"
points="35.809,6.486 10.221,6.486 10.221,23.405 36.788,23.405 36.788,6.486 " />
<path
style="fill:#FFFFFF;stroke:#FFFFFF;stroke-width:0.1875;"
d="M11.488,7.019c0,0.698,0,14.542,0,15.239c0.716,0,23.417,0,24.133,0c0-0.698,0-14.541,0-15.239 C34.904,7.019,12.204,7.019,11.488,7.019z"
id="path627" />
<linearGradient
id="XMLID_3_"
gradientUnits="userSpaceOnUse"
x1="34.5967"
y1="3.5967"
x2="18.4087"
y2="19.7847">
<stop
offset="0"
style="stop-color:#FFFFFF"
id="stop629" />
<stop
offset="0.5506"
style="stop-color:#E6EDFF"
id="stop630" />
<stop
offset="1"
style="stop-color:#FFFFFF"
id="stop631" />
<a:midPointStop
offset="0"
style="stop-color:#FFFFFF"
id="midPointStop632" />
<a:midPointStop
offset="0.5"
style="stop-color:#FFFFFF"
id="midPointStop633" />
<a:midPointStop
offset="0.5506"
style="stop-color:#E6EDFF"
id="midPointStop634" />
<a:midPointStop
offset="0.5"
style="stop-color:#E6EDFF"
id="midPointStop635" />
<a:midPointStop
offset="1"
style="stop-color:#FFFFFF"
id="midPointStop636" />
</linearGradient>
<path
style="fill:url(#XMLID_3_);stroke:#FFFFFF;stroke-width:0.1875;"
d="M11.488,7.019c0,0.698,0,14.542,0,15.239c0.716,0,23.417,0,24.133,0c0-0.698,0-14.541,0-15.239 C34.904,7.019,12.204,7.019,11.488,7.019z"
id="path637" />
<linearGradient
id="path205_1_"
gradientUnits="userSpaceOnUse"
x1="-174.4409"
y1="300.0908"
x2="-108.8787"
y2="210.2074"
gradientTransform="matrix(0.1875 0 0 -0.1875 51.5 83.75)">
<stop
offset="0"
style="stop-color:#003399"
id="stop639" />
<stop
offset="0.2697"
style="stop-color:#0035ED"
id="stop640" />
<stop
offset="1"
style="stop-color:#57ADFF"
id="stop641" />
<a:midPointStop
offset="0"
style="stop-color:#003399"
id="midPointStop642" />
<a:midPointStop
offset="0.5"
style="stop-color:#003399"
id="midPointStop643" />
<a:midPointStop
offset="0.2697"
style="stop-color:#0035ED"
id="midPointStop644" />
<a:midPointStop
offset="0.5"
style="stop-color:#0035ED"
id="midPointStop645" />
<a:midPointStop
offset="1"
style="stop-color:#57ADFF"
id="midPointStop646" />
</linearGradient>
<rect
id="path205"
x="12.154"
y="26.479"
style="fill:url(#path205_1_);"
width="22.007"
height="13.978" />
<linearGradient
id="XMLID_4_"
gradientUnits="userSpaceOnUse"
x1="21.8687"
y1="25.1875"
x2="21.8687"
y2="44.6251">
<stop
offset="0"
style="stop-color:#DFDFDF"
id="stop649" />
<stop
offset="1"
style="stop-color:#7D7D99"
id="stop650" />
<a:midPointStop
offset="0"
style="stop-color:#DFDFDF"
id="midPointStop651" />
<a:midPointStop
offset="0.5"
style="stop-color:#DFDFDF"
id="midPointStop652" />
<a:midPointStop
offset="1"
style="stop-color:#7D7D99"
id="midPointStop653" />
</linearGradient>
<path
style="fill:url(#XMLID_4_);"
d="M13.244,27.021c-0.311,0-0.563,0.252-0.563,0.563v13.104c0,0.312,0.252,0.563,0.563,0.563h17.249 c0.311,0,0.563-0.251,0.563-0.563V27.583c0-0.311-0.252-0.563-0.563-0.563H13.244z M18.85,30.697c0,0.871,0,5.078,0,5.949 c-0.683,0-2.075,0-2.759,0c0-0.871,0-5.078,0-5.949C16.775,30.697,18.167,30.697,18.85,30.697z"
id="path654" />
<linearGradient
id="XMLID_5_"
gradientUnits="userSpaceOnUse"
x1="-158.0337"
y1="288.0684"
x2="-158.0337"
y2="231.3219"
gradientTransform="matrix(0.1875 0 0 -0.1875 51.5 83.75)">
<stop
offset="0"
style="stop-color:#F0F0F0"
id="stop656" />
<stop
offset="0.6348"
style="stop-color:#CECEDB"
id="stop657" />
<stop
offset="0.8595"
style="stop-color:#B1B1C5"
id="stop658" />
<stop
offset="1"
style="stop-color:#FFFFFF"
id="stop659" />
<a:midPointStop
offset="0"
style="stop-color:#F0F0F0"
id="midPointStop660" />
<a:midPointStop
offset="0.5"
style="stop-color:#F0F0F0"
id="midPointStop661" />
<a:midPointStop
offset="0.6348"
style="stop-color:#CECEDB"
id="midPointStop662" />
<a:midPointStop
offset="0.5"
style="stop-color:#CECEDB"
id="midPointStop663" />
<a:midPointStop
offset="0.8595"
style="stop-color:#B1B1C5"
id="midPointStop664" />
<a:midPointStop
offset="0.5"
style="stop-color:#B1B1C5"
id="midPointStop665" />
<a:midPointStop
offset="1"
style="stop-color:#FFFFFF"
id="midPointStop666" />
</linearGradient>
<path
style="fill:url(#XMLID_5_);"
d="M13.244,27.583v13.104h17.249V27.583H13.244z M19.413,37.209h-3.884v-7.074h3.884V37.209z"
id="path667" />
<linearGradient
id="path228_1_"
gradientUnits="userSpaceOnUse"
x1="-68.1494"
y1="388.4561"
x2="-68.1494"
y2="404.6693"
gradientTransform="matrix(0.1875 0 0 -0.1875 51.5 83.75)">
<stop
offset="0"
style="stop-color:#3399FF"
id="stop669" />
<stop
offset="1"
style="stop-color:#000000"
id="stop670" />
<a:midPointStop
offset="0"
style="stop-color:#3399FF"
id="midPointStop671" />
<a:midPointStop
offset="0.5"
style="stop-color:#3399FF"
id="midPointStop672" />
<a:midPointStop
offset="1"
style="stop-color:#000000"
id="midPointStop673" />
</linearGradient>
<rect
id="path228"
x="37.83"
y="9.031"
style="fill:url(#path228_1_);"
width="1.784"
height="1.785" />
<polyline
id="_x3C_Slice_x3E_"
style="fill:none;"
points="0,48 0,0 48,0 48,48 " />
</g>
</svg>

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,98 @@
saveAsDetail=將标签保存到其他文件
changeSaveDir=改变存放目录
openFile=打开文件
shapeLineColorDetail=更改线条颜色
resetAll=重置界面与保存地址
crtBox=矩形标注
crtBoxDetail=创建一个新的区块
dupBoxDetail=复制区块
verifyImg=验证图像
zoominDetail=放大
verifyImgDetail=验证图像
saveDetail=保存标签文件
openFileDetail=打开图像文件
fitWidthDetail=调整宽度适应到窗口宽度
tutorial=PaddleOCR地址
editLabel=编辑标签
openAnnotationDetail=打开标签文件
quit=退出
shapeFillColorDetail=更改填充颜色
closeCurDetail=关闭当前文件
closeCur=关闭文件
deleteImg=删除图像
deleteImgDetail=删除当前图像
fitWin=调整到窗口大小
delBox=删除选择的区块
boxLineColorDetail=选择线框颜色
originalsize=原始大小
resetAllDetail=重置所有设定
zoomoutDetail=放大画面
save=确认
saveAs=另存为
fitWinDetail=缩放到当前窗口大小
openDir=打开目录
copyPrevBounding=复制当前图像中的上一个边界框
showHide=显示/隐藏标签
changeSaveFormat=更改存储格式
shapeFillColor=填充颜色
quitApp=退出程序
dupBox=复制区块
delBoxDetail=删除区块
zoomin=放大画面
info=信息
openAnnotation=开启标签
prevImgDetail=上一个图像
fitWidth=缩放到跟当前画面一样宽
zoomout=缩小画面
changeSavedAnnotationDir=更改保存标签文件的预设目录
nextImgDetail=下一个图像
originalsizeDetail=放大到原始大小
prevImg=上一张
tutorialDetail=显示示范内容
shapeLineColor=形状线条颜色
boxLineColor=区块线条颜色
editLabelDetail=修改当前所选的区块颜色
nextImg=下一张
useDefaultLabel=使用预设标签
useDifficult=有难度的
boxLabelText=区块的标签
labels=标签
autoSaveMode=自动保存模式
singleClsMode=单一类别模式
displayLabel=显示类别
fileList=文件列表
files=文件
advancedMode=专家模式
advancedModeDetail=切换到专家模式
showAllBoxDetail=显示所有区块
hideAllBoxDetail=隐藏所有区块
annoPanel=标注面板
anno=标注
addNewBbox=新框
reLabel=重标注
choosemodel=选择模型
tipchoosemodel=选择OCR模型
ImageResize=图片缩放
IR=图片缩放
autoRecognition=自动标注
reRecognition=重新识别
mfile=文件
medit=编辑
mview=视图
mhelp=帮助
iconList=缩略图
detectionBoxposition=检测框位置
recognitionResult=识别结果
creatPolygon=四点标注
drawSquares=正方形标注
saveRec=保存识别结果
tempLabel=待识别
steps=操作步骤
choseModelLg=选择模型语言
cancel=取消
ok=确认
autolabeling=自动标注中
hideBox=隐藏所有标注
showBox=显示所有标注
saveLabel=保存标记结果
singleRe=重识别此区块

View File

@ -0,0 +1,98 @@
openFile=Open
openFileDetail=Open image or label file
quit=Quit
quitApp=Quit application
openDir=Open Dir
copyPrevBounding=Copy previous Bounding Boxes in the current image
changeSavedAnnotationDir=Change default saved Annotation dir
openAnnotation=Open Annotation
openAnnotationDetail=Open an annotation file
changeSaveDir=Change Save Dir
nextImg=Next Image
nextImgDetail=Open the next Image
prevImg=Prev Image
prevImgDetail=Open the previous Image
verifyImg=Verify Image
verifyImgDetail=Verify Image
save=Check
saveDetail=Save the labels to a file
changeSaveFormat=Change save format
saveAs=Save As
saveAsDetail=Save the labels to a different file
closeCur=Close
closeCurDetail=Close the current file
deleteImg=Delete current image
deleteImgDetail=Delete the current image
resetAll=Reset Interface and Save Dir
resetAllDetail=Reset All
boxLineColor=Box Line Color
boxLineColorDetail=Choose Box line color
crtBox=Create RectBox
crtBoxDetail=Draw a new box
delBox=Delete RectBox
delBoxDetail=Remove the box
dupBox=Duplicate RectBox
dupBoxDetail=Create a duplicate of the selected box
tutorial=PaddleOCR url
tutorialDetail=Show demo
info=Information
zoomin=Zoom In
zoominDetail=Increase zoom level
zoomout=Zoom Out
zoomoutDetail=Decrease zoom level
originalsize=Original size
originalsizeDetail=Zoom to original size
fitWin=Fit Window
fitWinDetail=Zoom follows window size
fitWidth=Fit Width
fitWidthDetail=Zoom follows window width
editLabel=Edit Label
editLabelDetail=Modify the label of the selected Box
shapeLineColor=Shape Line Color
shapeLineColorDetail=Change the line color for this specific shape
shapeFillColor=Shape Fill Color
shapeFillColorDetail=Change the fill color for this specific shape
showHide=Show/Hide Label Panel
useDefaultLabel=Use default label
useDifficult=Difficult
boxLabelText=Box Labels
labels=Labels
autoSaveMode=Auto Save mode
singleClsMode=Single Class Mode
displayLabel=Display Labels
fileList=File List
files=Files
advancedMode=Advanced Mode
advancedModeDetail=Swtich to advanced mode
showAllBoxDetail=Show all bounding boxes
hideAllBoxDetail=Hide all bounding boxes
annoPanel=anno Panel
anno=anno
addNewBbox=new bbox
reLabel=reLabel
choosemodel=Choose OCR model
tipchoosemodel=Choose OCR model from dir
ImageResize=Image Resize
IR=Image Resize
autoRecognition=Auto Recognition
reRecognition=Re-recognition
mfile=File
medit=Eidt
mview=View
mhelp=Help
iconList=Icon List
detectionBoxposition=Detection box position
recognitionResult=Recognition result
creatPolygon=Create Quadrilateral
drawSquares=Draw Squares
saveRec=Save Recognition Result
tempLabel=TEMPORARY
steps=Steps
choseModelLg=Choose Model Language
cancel=Cancel
ok=OK
autolabeling=Automatic Labeling
hideBox=Hide All Box
showBox=Show All Box
saveLabel=Save Label
singleRe=Re-recognition RectBox

8
PPOCRLabel/setup.cfg Normal file
View File

@ -0,0 +1,8 @@
[bumpversion]
commit = True
tag = True
[bumpversion:file:setup.py]
[bdist_wheel]
universal = 1

139
PPOCRLabel/setup.py Normal file
View File

@ -0,0 +1,139 @@
# Copyright (c) <2015-Present> Tzutalin
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from setuptools import setup, find_packages, Command
from sys import platform as _platform
from shutil import rmtree
import sys
import os
here = os.path.abspath(os.path.dirname(__file__))
NAME = 'labelImg'
REQUIRES_PYTHON = '>=3.0.0'
REQUIRED_DEP = ['pyqt5', 'lxml']
about = {}
with open(os.path.join(here, 'libs', '__init__.py')) as f:
exec(f.read(), about)
with open('README.rst') as readme_file:
readme = readme_file.read()
with open('HISTORY.rst') as history_file:
history = history_file.read()
# OS specific settings
SET_REQUIRES = []
if _platform == "linux" or _platform == "linux2":
# linux
print('linux')
elif _platform == "darwin":
# MAC OS X
SET_REQUIRES.append('py2app')
required_packages = find_packages()
required_packages.append('labelImg')
APP = [NAME + '.py']
OPTIONS = {
'argv_emulation': True,
'iconfile': 'resources/icons/app.icns'
}
class UploadCommand(Command):
"""Support setup.py upload."""
description=readme + '\n\n' + history,
user_options = []
@staticmethod
def status(s):
"""Prints things in bold."""
print('\033[1m{0}\033[0m'.format(s))
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
try:
self.status('Removing previous builds…')
rmtree(os.path.join(here, 'dist'))
except OSError:
self.status('Fail to remove previous builds..')
pass
self.status('Building Source and Wheel (universal) distribution…')
os.system(
'{0} setup.py sdist bdist_wheel --universal'.format(sys.executable))
self.status('Uploading the package to PyPI via Twine…')
os.system('twine upload dist/*')
self.status('Pushing git tags…')
os.system('git tag -d v{0}'.format(about['__version__']))
os.system('git tag v{0}'.format(about['__version__']))
# os.system('git push --tags')
sys.exit()
setup(
app=APP,
name=NAME,
version=about['__version__'],
description="LabelImg is a graphical image annotation tool and label object bounding boxes in images",
long_description=readme + '\n\n' + history,
author="TzuTa Lin",
author_email='tzu.ta.lin@gmail.com',
url='https://github.com/tzutalin/labelImg',
python_requires=REQUIRES_PYTHON,
package_dir={'labelImg': '.'},
packages=required_packages,
entry_points={
'console_scripts': [
'labelImg=labelImg.labelImg:main'
]
},
include_package_data=True,
install_requires=REQUIRED_DEP,
license="MIT license",
zip_safe=False,
keywords='labelImg labelTool development annotation deeplearning',
classifiers=[
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Natural Language :: English',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
],
package_data={'data/predefined_classes.txt': ['data/predefined_classes.txt']},
options={'py2app': OPTIONS},
setup_requires=SET_REQUIRES,
# $ setup.py publish support.
cmdclass={
'upload': UploadCommand,
}
)

306
README.md
View File

@ -1,209 +1,185 @@
[English](README_en.md) | 简体中文
English | [简体中文](README_ch.md)
## 简介
PaddleOCR旨在打造一套丰富、领先、且实用的OCR工具库助力使用者训练出更好的模型并应用落地。
## Introduction
PaddleOCR aims to create multilingual, awesome, leading, and practical OCR tools that help users train better models and apply them into practice.
**近期更新**
- 2020.8.26 更新OCR相关的84个常见问题及解答具体参考[FAQ](./doc/doc_ch/FAQ.md)
- 2020.8.24 支持通过whl包安装使用PaddleOCR具体参考[Paddleocr Package使用说明](./doc/doc_ch/whl.md)
- 2020.8.21 更新8月18日B站直播课回放和PPT课节2易学易用的OCR工具大礼包[获取地址](https://aistudio.baidu.com/aistudio/education/group/info/1519)
- 2020.8.16 开源文本检测算法[SAST](https://arxiv.org/abs/1908.05498)和文本识别算法[SRN](https://arxiv.org/abs/2003.12294)
- 2020.7.23 发布7月21日B站直播课回放和PPT课节1PaddleOCR开源大礼包全面解读[获取地址](https://aistudio.baidu.com/aistudio/course/introduce/1519)
- 2020.7.15 添加基于EasyEdge和Paddle-Lite的移动端DEMO支持iOS和Android系统
- [more](./doc/doc_ch/update.md)
## Notice
PaddleOCR supports both dynamic graph and static graph programming paradigm
- Dynamic graph: dygraph branch (default), **supported by paddle 2.0rc1+ ([installation](./doc/doc_en/installation_en.md))**
- Static graph: develop branch
**Recent updates**
- 2020.12.15 update Data synthesis tool, i.e., [Style-Text](./StyleText/README.md)easy to synthesize a large number of images which are similar to the target scene image.
- 2020.11.25 Update a new data annotation tool, i.e., [PPOCRLabel](./PPOCRLabel/README.md), which is helpful to improve the labeling efficiency. Moreover, the labeling results can be used in training of the PP-OCR system directly.
- 2020.9.22 Update the PP-OCR technical article, https://arxiv.org/abs/2009.09941
- [more](./doc/doc_en/update_en.md)
## 特性
- 超轻量级中文OCR模型总模型仅8.6M
- 单模型支持中英文数字组合识别、竖排文本识别、长文本识别
- 检测模型DB4.1M+识别模型CRNN4.5M
- 实用通用中文OCR模型
- 多种预测推理部署方案,包括服务部署和端侧部署
- 多种文本检测训练算法EAST、DB、SAST
- 多种文本识别训练算法Rosetta、CRNN、STAR-Net、RARE、SRN
- 可运行于Linux、Windows、MacOS等多种系统
## Features
- PPOCR series of high-quality pre-trained models, comparable to commercial effects
- Ultra lightweight ppocr_mobile series models: detection (3.0M) + direction classifier (1.4M) + recognition (5.0M) = 9.4M
- General ppocr_server series models: detection (47.1M) + direction classifier (1.4M) + recognition (94.9M) = 143.4M
- Support Chinese, English, and digit recognition, vertical text recognition, and long text recognition
- Support multi-language recognition: Korean, Japanese, German, French
- Rich toolkits related to the OCR areas
- Semi-automatic data annotation tool, i.e., PPOCRLabel: support fast and efficient data annotation
- Data synthesis tool, i.e., Style-Text: easy to synthesize a large number of images which are similar to the target scene image
- Support user-defined training, provides rich predictive inference deployment solutions
- Support PIP installation, easy to use
- Support Linux, Windows, MacOS and other systems
## 快速体验
## Visualization
<div align="center">
<img src="doc/imgs_results/11.jpg" width="800">
<img src="doc/imgs_results/ch_ppocr_mobile_v2.0/test_add_91.jpg" width="800">
<img src="doc/imgs_results/ch_ppocr_mobile_v2.0/00018069.jpg" width="800">
</div>
上图是超轻量级中文OCR模型效果展示更多效果图请见[效果展示页面](./doc/doc_ch/visualization.md)。
The above pictures are the visualizations of the general ppocr_server model. For more effect pictures, please see [More visualizations](./doc/doc_en/visualization_en.md).
- 超轻量级中文OCR在线体验地址https://www.paddlepaddle.org.cn/hub/scene/ocr
- 移动端DEMO体验(基于EasyEdge和Paddle-Lite, 支持iOS和Android系统)[安装包二维码获取地址](https://ai.baidu.com/easyedge/app/openSource?from=paddlelite)
<a name="Community"></a>
## Community
- Scan the QR code below with your Wechat, you can access to official technical exchange group. Look forward to your participation.
Android手机也可以扫描下面二维码安装体验。
<div align="center">
<img src="https://raw.githubusercontent.com/PaddlePaddle/PaddleOCR/release/2.0/doc/joinus.PNG" width = "200" height = "200" />
</div>
## Quick Experience
You can also quickly experience the ultra-lightweight OCR : [Online Experience](https://www.paddlepaddle.org.cn/hub/scene/ocr)
Mobile DEMO experience (based on EasyEdge and Paddle-Lite, supports iOS and Android systems): [Sign in to the website to obtain the QR code for installing the App](https://ai.baidu.com/easyedge/app/openSource?from=paddlelite)
Also, you can scan the QR code below to install the App (**Android support only**)
<div align="center">
<img src="./doc/ocr-android-easyedge.png" width = "200" height = "200" />
</div>
- [**OCR Quick Start**](./doc/doc_en/quickstart_en.md)
## 中文OCR模型列表
|模型名称|模型简介|检测模型地址|识别模型地址|支持空格的识别模型地址|
|-|-|-|-|-|
|chinese_db_crnn_mobile|超轻量级中文OCR模型|[inference模型](https://paddleocr.bj.bcebos.com/ch_models/ch_det_mv3_db_infer.tar) / [预训练模型](https://paddleocr.bj.bcebos.com/ch_models/ch_det_mv3_db.tar)|[inference模型](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_mv3_crnn_infer.tar) / [预训练模型](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_mv3_crnn.tar)|[inference模型](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_mv3_crnn_enhance_infer.tar) / [预训练模型](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_mv3_crnn_enhance.tar)
|chinese_db_crnn_server|通用中文OCR模型|[inference模型](https://paddleocr.bj.bcebos.com/ch_models/ch_det_r50_vd_db_infer.tar) / [预训练模型](https://paddleocr.bj.bcebos.com/ch_models/ch_det_r50_vd_db.tar)|[inference模型](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_r34_vd_crnn_infer.tar) / [预训练模型](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_r34_vd_crnn.tar)|[inference模型](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_r34_vd_crnn_enhance_infer.tar) / [预训练模型](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_r34_vd_crnn_enhance.tar)
## 文档教程
- [快速安装](./doc/doc_ch/installation.md)
- [中文OCR模型快速使用](./doc/doc_ch/quickstart.md)
- 算法介绍
- [文本检测](#文本检测算法)
- [文本识别](#文本识别算法)
- 模型训练/评估
- [文本检测](./doc/doc_ch/detection.md)
- [文本识别](./doc/doc_ch/recognition.md)
- [yml参数配置文件介绍](./doc/doc_ch/config.md)
- [中文OCR训练预测技巧](./doc/doc_ch/tricks.md)
- 预测部署
- [基于Python预测引擎推理](./doc/doc_ch/inference.md)
- [基于C++预测引擎推理](./deploy/cpp_infer/readme.md)
- [服务化部署](./doc/doc_ch/serving.md)
- [端侧部署](./deploy/lite/readme.md)
- 模型量化压缩coming soon
- [Benchmark](./doc/doc_ch/benchmark.md)
- 数据集
- [通用中英文OCR数据集](./doc/doc_ch/datasets.md)
- [手写中文OCR数据集](./doc/doc_ch/handwritten_datasets.md)
- [垂类多语言OCR数据集](./doc/doc_ch/vertical_and_multilingual_datasets.md)
- [常用数据标注工具](./doc/doc_ch/data_annotation.md)
- [常用数据合成工具](./doc/doc_ch/data_synthesis.md)
- 效果展示
- [超轻量级中文OCR效果展示](#超轻量级中文OCR效果展示)
- [通用中文OCR效果展示](#通用中文OCR效果展示)
- [支持空格的中文OCR效果展示](#支持空格的中文OCR效果展示)
- FAQ
- [【精选】OCR精选10个问题](./doc/doc_ch/FAQ.md)
- [【理论篇】OCR通用21个问题](./doc/doc_ch/FAQ.md)
- [【实战篇】PaddleOCR实战53个问题](./doc/doc_ch/FAQ.md)
- [技术交流群](#欢迎加入PaddleOCR技术交流群)
- [参考文献](./doc/doc_ch/reference.md)
- [许可证书](#许可证书)
- [贡献代码](#贡献代码)
<a name="算法介绍"></a>
## 算法介绍
<a name="文本检测算法"></a>
### 1.文本检测算法
PaddleOCR开源的文本检测算法列表
- [x] EAST([paper](https://arxiv.org/abs/1704.03155))
- [x] DB([paper](https://arxiv.org/abs/1911.08947))
- [x] SAST([paper](https://arxiv.org/abs/1908.05498))(百度自研)
在ICDAR2015文本检测公开数据集上算法效果如下
|模型|骨干网络|precision|recall|Hmean|下载链接|
|-|-|-|-|-|-|
|EAST|ResNet50_vd|88.18%|85.51%|86.82%|[下载链接](https://paddleocr.bj.bcebos.com/det_r50_vd_east.tar)|
|EAST|MobileNetV3|81.67%|79.83%|80.74%|[下载链接](https://paddleocr.bj.bcebos.com/det_mv3_east.tar)|
|DB|ResNet50_vd|83.79%|80.65%|82.19%|[下载链接](https://paddleocr.bj.bcebos.com/det_r50_vd_db.tar)|
|DB|MobileNetV3|75.92%|73.18%|74.53%|[下载链接](https://paddleocr.bj.bcebos.com/det_mv3_db.tar)|
|SAST|ResNet50_vd|92.18%|82.96%|87.33%|[下载链接](https://paddleocr.bj.bcebos.com/SAST/sast_r50_vd_icdar2015.tar)|
在Total-text文本检测公开数据集上算法效果如下
|模型|骨干网络|precision|recall|Hmean|下载链接|
|-|-|-|-|-|-|
|SAST|ResNet50_vd|88.74%|79.80%|84.03%|[下载链接](https://paddleocr.bj.bcebos.com/SAST/sast_r50_vd_total_text.tar)|
**说明:** SAST模型训练额外加入了icdar2013、icdar2017、COCO-Text、ArT等公开数据集进行调优。PaddleOCR用到的经过整理格式的英文公开数据集下载[百度云地址](https://pan.baidu.com/s/12cPnZcVuV1zn5DOd4mqjVw) (提取码: 2bpi)
<a name="Supported-Chinese-model-list"></a>
使用[LSVT](https://github.com/PaddlePaddle/PaddleOCR/blob/develop/doc/doc_ch/datasets.md#1icdar2019-lsvt)街景数据集共3w张数据训练中文检测模型的相关配置和预训练文件如下
## PP-OCR 2.0 series model listUpdate on Dec 15
**Note** : Compared with [models 1.1](https://github.com/PaddlePaddle/PaddleOCR/blob/develop/doc/doc_en/models_list_en.md), which are trained with static graph programming paradigm, models 2.0 are the dynamic graph trained version and achieve close performance.
|模型|骨干网络|配置文件|预训练模型|
|-|-|-|-|
|超轻量中文模型|MobileNetV3|det_mv3_db.yml|[下载链接](https://paddleocr.bj.bcebos.com/ch_models/ch_det_mv3_db.tar)|
|通用中文OCR模型|ResNet50_vd|det_r50_vd_db.yml|[下载链接](https://paddleocr.bj.bcebos.com/ch_models/ch_det_r50_vd_db.tar)|
| Model introduction | Model name | Recommended scene | Detection model | Direction classifier | Recognition model |
| ------------------------------------------------------------ | ---------------------------- | ----------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| Chinese and English ultra-lightweight OCR model (9.4M) | ch_ppocr_mobile_v2.0_xx | Mobile & server |[inference model](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_det_infer.tar) / [pre-trained model](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_det_train.tar)|[inference model](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_infer.tar) / [pre-trained model](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_train.tar) |[inference model](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_rec_infer.tar) / [pre-trained model](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_rec_pre.tar) |
| Chinese and English general OCR model (143.4M) | ch_ppocr_server_v2.0_xx | Server |[inference model](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_server_v2.0_det_infer.tar) / [pre-trained model](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_server_v2.0_det_train.tar) |[inference model](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_infer.tar) / [pre-trained model](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_traingit.tar) |[inference model](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_server_v2.0_rec_infer.tar) / [pre-trained model](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_server_v2.0_rec_pre.tar) |
* 注: 上述DB模型的训练和评估需设置后处理参数box_thresh=0.6unclip_ratio=1.5,使用不同数据集、不同模型训练,可调整这两个参数进行优化
PaddleOCR文本检测算法的训练和使用请参考文档教程中[模型训练/评估中的文本检测部分](./doc/doc_ch/detection.md)。
For more model downloads (including multiple languages), please refer to [PP-OCR v2.0 series model downloads](./doc/doc_en/models_list_en.md).
<a name="文本识别算法"></a>
### 2.文本识别算法
For a new language request, please refer to [Guideline for new language_requests](#language_requests).
PaddleOCR开源的文本识别算法列表
- [x] CRNN([paper](https://arxiv.org/abs/1507.05717))
- [x] Rosetta([paper](https://arxiv.org/abs/1910.05085))
- [x] STAR-Net([paper](http://www.bmva.org/bmvc/2016/papers/paper043/index.html))
- [x] RARE([paper](https://arxiv.org/abs/1603.03915v1))
- [x] SRN([paper](https://arxiv.org/abs/2003.12294))(百度自研)
## Tutorials
- [Installation](./doc/doc_en/installation_en.md)
- [Quick Start](./doc/doc_en/quickstart_en.md)
- [Code Structure](./doc/doc_en/tree_en.md)
- Algorithm Introduction
- [Text Detection Algorithm](./doc/doc_en/algorithm_overview_en.md)
- [Text Recognition Algorithm](./doc/doc_en/algorithm_overview_en.md)
- [PP-OCR Pipeline](#PP-OCR-Pipeline)
- Model Training/Evaluation
- [Text Detection](./doc/doc_en/detection_en.md)
- [Text Recognition](./doc/doc_en/recognition_en.md)
- [Direction Classification](./doc/doc_en/angle_class_en.md)
- [Yml Configuration](./doc/doc_en/config_en.md)
- Inference and Deployment
- [Quick Inference Based on PIP](./doc/doc_en/whl_en.md)
- [Python Inference](./doc/doc_en/inference_en.md)
- [C++ Inference](./deploy/cpp_infer/readme_en.md)
- [Serving](./deploy/hubserving/readme_en.md)
- [Mobile](https://github.com/PaddlePaddle/PaddleOCR/blob/develop/deploy/lite/readme_en.md)
- [Benchmark](./doc/doc_en/benchmark_en.md)
- Data Annotation and Synthesis
- [Semi-automatic Annotation Tool: PPOCRLabel](./PPOCRLabel/README.md)
- [Data Synthesis Tool: Style-Text](./StyleText/README.md)
- [Other Data Annotation Tools](./doc/doc_en/data_annotation_en.md)
- [Other Data Synthesis Tools](./doc/doc_en/data_synthesis_en.md)
- Datasets
- [General OCR Datasets(Chinese/English)](./doc/doc_en/datasets_en.md)
- [HandWritten_OCR_Datasets(Chinese)](./doc/doc_en/handwritten_datasets_en.md)
- [Various OCR Datasets(multilingual)](./doc/doc_en/vertical_and_multilingual_datasets_en.md)
- [Visualization](#Visualization)
- [New language requests](#language_requests)
- [FAQ](./doc/doc_en/FAQ_en.md)
- [Community](#Community)
- [References](./doc/doc_en/reference_en.md)
- [License](#LICENSE)
- [Contribution](#CONTRIBUTION)
参考[DTRB](https://arxiv.org/abs/1904.01906)文字识别训练和评估流程使用MJSynth和SynthText两个文字识别数据集训练在IIIT, SVT, IC03, IC13, IC15, SVTP, CUTE数据集上进行评估算法效果如下
|模型|骨干网络|Avg Accuracy|模型存储命名|下载链接|
|-|-|-|-|-|
|Rosetta|Resnet34_vd|80.24%|rec_r34_vd_none_none_ctc|[下载链接](https://paddleocr.bj.bcebos.com/rec_r34_vd_none_none_ctc.tar)|
|Rosetta|MobileNetV3|78.16%|rec_mv3_none_none_ctc|[下载链接](https://paddleocr.bj.bcebos.com/rec_mv3_none_none_ctc.tar)|
|CRNN|Resnet34_vd|82.20%|rec_r34_vd_none_bilstm_ctc|[下载链接](https://paddleocr.bj.bcebos.com/rec_r34_vd_none_bilstm_ctc.tar)|
|CRNN|MobileNetV3|79.37%|rec_mv3_none_bilstm_ctc|[下载链接](https://paddleocr.bj.bcebos.com/rec_mv3_none_bilstm_ctc.tar)|
|STAR-Net|Resnet34_vd|83.93%|rec_r34_vd_tps_bilstm_ctc|[下载链接](https://paddleocr.bj.bcebos.com/rec_r34_vd_tps_bilstm_ctc.tar)|
|STAR-Net|MobileNetV3|81.56%|rec_mv3_tps_bilstm_ctc|[下载链接](https://paddleocr.bj.bcebos.com/rec_mv3_tps_bilstm_ctc.tar)|
|RARE|Resnet34_vd|84.90%|rec_r34_vd_tps_bilstm_attn|[下载链接](https://paddleocr.bj.bcebos.com/rec_r34_vd_tps_bilstm_attn.tar)|
|RARE|MobileNetV3|83.32%|rec_mv3_tps_bilstm_attn|[下载链接](https://paddleocr.bj.bcebos.com/rec_mv3_tps_bilstm_attn.tar)|
|SRN|Resnet50_vd_fpn|88.33%|rec_r50fpn_vd_none_srn|[下载链接](https://paddleocr.bj.bcebos.com/SRN/rec_r50fpn_vd_none_srn.tar)|
**说明:** SRN模型使用了数据扰动方法对上述提到对两个训练集进行增广增广后的数据可以在[百度网盘](https://pan.baidu.com/s/1-HSZ-ZVdqBF2HaBZ5pRAKA)上下载,提取码: y3ry。
原始论文使用两阶段训练平均精度为89.74%PaddleOCR中使用one-stage训练平均精度为88.33%。两种预训练权重均在[下载链接](https://paddleocr.bj.bcebos.com/SRN/rec_r50fpn_vd_none_srn.tar)中。
<a name="PP-OCR-Pipeline"></a>
使用[LSVT](https://github.com/PaddlePaddle/PaddleOCR/blob/develop/doc/doc_ch/datasets.md#1icdar2019-lsvt)街景数据集根据真值将图crop出来30w数据进行位置校准。此外基于LSVT语料生成500w合成数据训练中文模型相关配置和预训练文件如下
|模型|骨干网络|配置文件|预训练模型|
|-|-|-|-|
|超轻量中文模型|MobileNetV3|rec_chinese_lite_train.yml|[下载链接](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_mv3_crnn.tar)|
|通用中文OCR模型|Resnet34_vd|rec_chinese_common_train.yml|[下载链接](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_r34_vd_crnn.tar)|
PaddleOCR文本识别算法的训练和使用请参考文档教程中[模型训练/评估中的文本识别部分](./doc/doc_ch/recognition.md)。
## 效果展示
<a name="超轻量级中文OCR效果展示"></a>
### 1.超轻量级中文OCR效果展示 [more](./doc/doc_ch/visualization.md)
## PP-OCR Pipeline
<div align="center">
<img src="doc/imgs_results/1.jpg" width="800">
<img src="./doc/ppocr_framework.png" width="800">
</div>
<a name="通用中文OCR效果展示"></a>
### 2.通用中文OCR效果展示 [more](./doc/doc_ch/visualization.md)
PP-OCR is a practical ultra-lightweight OCR system. It is mainly composed of three parts: DB text detection[2], detection frame correction and CRNN text recognition[7]. The system adopts 19 effective strategies from 8 aspects including backbone network selection and adjustment, prediction head design, data augmentation, learning rate transformation strategy, regularization parameter selection, pre-training model use, and automatic model tailoring and quantization to optimize and slim down the models of each module. The final results are an ultra-lightweight Chinese and English OCR model with an overall size of 3.5M and a 2.8M English digital OCR model. For more details, please refer to the PP-OCR technical article (https://arxiv.org/abs/2009.09941). Besides, The implementation of the FPGM Pruner [8] and PACT quantization [9] is based on [PaddleSlim](https://github.com/PaddlePaddle/PaddleSlim).
## Visualization [more](./doc/doc_en/visualization_en.md)
- Chinese OCR model
<div align="center">
<img src="doc/imgs_results/chinese_db_crnn_server/11.jpg" width="800">
<img src="./doc/imgs_results/ch_ppocr_mobile_v2.0/test_add_91.jpg" width="800">
<img src="./doc/imgs_results/ch_ppocr_mobile_v2.0/00015504.jpg" width="800">
<img src="./doc/imgs_results/ch_ppocr_mobile_v2.0/00056221.jpg" width="800">
<img src="./doc/imgs_results/ch_ppocr_mobile_v2.0/rotate_00052204.jpg" width="800">
</div>
<a name="支持空格的中文OCR效果展示"></a>
### 3.支持空格的中文OCR效果展示 [more](./doc/doc_ch/visualization.md)
- English OCR model
<div align="center">
<img src="doc/imgs_results/chinese_db_crnn_server/en_paper.jpg" width="800">
<img src="./doc/imgs_results/ch_ppocr_mobile_v2.0/img_12.jpg" width="800">
</div>
<a name="欢迎加入PaddleOCR技术交流群"></a>
## 欢迎加入PaddleOCR技术交流群
请扫描下面二维码完成问卷填写获取加群二维码和OCR方向的炼丹秘籍
- Multilingual OCR model
<div align="center">
<img src="./doc/joinus.jpg" width = "200" height = "200" />
<img src="./doc/imgs_results/french_0.jpg" width="800">
<img src="./doc/imgs_results/korean.jpg" width="800">
</div>
<a name="许可证书"></a>
## 许可证书
本项目的发布受<a href="https://github.com/PaddlePaddle/PaddleOCR/blob/master/LICENSE">Apache 2.0 license</a>许可认证。
<a name="贡献代码"></a>
## 贡献代码
我们非常欢迎你为PaddleOCR贡献代码也十分感谢你的反馈。
<a name="language_requests"></a>
## Guideline for new language requests
- 非常感谢 [Khanh Tran](https://github.com/xxxpsyduck) 和 [Karl Horky](https://github.com/karlhorky) 贡献修改英文文档
- 非常感谢 [zhangxin](https://github.com/ZhangXinNan)([Blog](https://blog.csdn.net/sdlypyzq)) 贡献新的可视化方式、添加.gitgnore、处理手动设置PYTHONPATH环境变量的问题
- 非常感谢 [lyl120117](https://github.com/lyl120117) 贡献打印网络结构的代码
- 非常感谢 [xiangyubo](https://github.com/xiangyubo) 贡献手写中文OCR数据集
- 非常感谢 [authorfu](https://github.com/authorfu) 贡献Android和[xiadeye](https://github.com/xiadeye) 贡献IOS的demo代码
- 非常感谢 [BeyondYourself](https://github.com/BeyondYourself) 给PaddleOCR提了很多非常棒的建议并简化了PaddleOCR的部分代码风格。
- 非常感谢 [tangmq](https://gitee.com/tangmq) 给PaddleOCR增加Docker化部署服务支持快速发布可调用的Restful API服务。
If you want to request a new language support, a PR with 2 following files are needed
1. In folder [ppocr/utils/dict](./ppocr/utils/dict),
it is necessary to submit the dict text to this path and name it with `{language}_dict.txt` that contains a list of all characters. Please see the format example from other files in that folder.
2. In folder [ppocr/utils/corpus](./ppocr/utils/corpus),
it is necessary to submit the corpus to this path and name it with `{language}_corpus.txt` that contains a list of words in your language.
Maybe, 50000 words per language is necessary at least.
Of course, the more, the better.
If your language has unique elements, please tell me in advance within any way, such as useful links, wikipedia and so on.
More details, please refer to [Multilingual OCR Development Plan](https://github.com/PaddlePaddle/PaddleOCR/issues/1048).
<a name="LICENSE"></a>
## License
This project is released under <a href="https://github.com/PaddlePaddle/PaddleOCR/blob/master/LICENSE">Apache 2.0 license</a>
<a name="CONTRIBUTION"></a>
## Contribution
We welcome all the contributions to PaddleOCR and appreciate for your feedback very much.
- Many thanks to [Khanh Tran](https://github.com/xxxpsyduck) and [Karl Horky](https://github.com/karlhorky) for contributing and revising the English documentation.
- Many thanks to [zhangxin](https://github.com/ZhangXinNan) for contributing the new visualize function、add .gitgnore and discard set PYTHONPATH manually.
- Many thanks to [lyl120117](https://github.com/lyl120117) for contributing the code for printing the network structure.
- Thanks [xiangyubo](https://github.com/xiangyubo) for contributing the handwritten Chinese OCR datasets.
- Thanks [authorfu](https://github.com/authorfu) for contributing Android demo and [xiadeye](https://github.com/xiadeye) contributing iOS demo, respectively.
- Thanks [BeyondYourself](https://github.com/BeyondYourself) for contributing many great suggestions and simplifying part of the code style.
- Thanks [tangmq](https://gitee.com/tangmq) for contributing Dockerized deployment services to PaddleOCR and supporting the rapid release of callable Restful API services.
- Thanks [lijinhan](https://github.com/lijinhan) for contributing a new way, i.e., java SpringBoot, to achieve the request for the Hubserving deployment.
- Thanks [Mejans](https://github.com/Mejans) for contributing the Occitan corpus and character set.
- Thanks [LKKlein](https://github.com/LKKlein) for contributing a new deploying package with the Golang program language.
- Thanks [Evezerest](https://github.com/Evezerest), [ninetailskim](https://github.com/ninetailskim), [edencfc](https://github.com/edencfc), [BeyondYourself](https://github.com/BeyondYourself) and [1084667371](https://github.com/1084667371) for contributing a new data annotation tool, i.e., PPOCRLabel。

160
README_ch.md Executable file
View File

@ -0,0 +1,160 @@
[English](README.md) | 简体中文
## 简介
PaddleOCR旨在打造一套丰富、领先、且实用的OCR工具库助力使用者训练出更好的模型并应用落地。
## 注意
PaddleOCR同时支持动态图与静态图两种编程范式
- 动态图版本dygraph分支默认需将paddle版本升级至2.0rc1+[快速安装](./doc/doc_ch/installation.md)
- 静态图版本develop分支
**近期更新**
- 2020.12.15 更新数据合成工具[Style-Text](./StyleText/README_ch.md),可以批量合成大量与目标场景类似的图像,在多个场景验证,效果明显提升。
- 2020.12.14 [FAQ](./doc/doc_ch/FAQ.md)新增5个高频问题总数127个每周一都会更新欢迎大家持续关注。
- 2020.11.25 更新半自动标注工具[PPOCRLabel](./PPOCRLabel/README_ch.md)辅助开发者高效完成标注任务输出格式与PP-OCR训练任务完美衔接。
- 2020.9.22 更新PP-OCR技术文章https://arxiv.org/abs/2009.09941
- [More](./doc/doc_ch/update.md)
## 特性
- PPOCR系列高质量预训练模型准确的识别效果
- 超轻量ppocr_mobile移动端系列检测3.0M+方向分类器1.4M+ 识别5.0M= 9.4M
- 通用ppocr_server系列检测47.1M+方向分类器1.4M+ 识别94.9M= 143.4M
- 支持中英文数字组合识别、竖排文本识别、长文本识别
- 支持多语言识别:韩语、日语、德语、法语
- 丰富易用的OCR相关工具组件
- 半自动数据标注工具PPOCRLabel支持快速高效的数据标注
- 数据合成工具Style-Text批量合成大量与目标场景类似的图像
- 支持用户自定义训练,提供丰富的预测推理部署方案
- 支持PIP快速安装使用
- 可运行于Linux、Windows、MacOS等多种系统
## 效果展示
<div align="center">
<img src="doc/imgs_results/ch_ppocr_mobile_v2.0/test_add_91.jpg" width="800">
<img src="doc/imgs_results/ch_ppocr_mobile_v2.0/00018069.jpg" width="800">
</div>
上图是通用ppocr_server模型效果展示更多效果图请见[效果展示页面](./doc/doc_ch/visualization.md)。
<a name="欢迎加入PaddleOCR技术交流群"></a>
## 欢迎加入PaddleOCR技术交流群
- 微信扫描二维码加入官方交流群,获得更高效的问题答疑,与各行各业开发者充分交流,期待您的加入。
<div align="center">
<img src="https://raw.githubusercontent.com/PaddlePaddle/PaddleOCR/release/2.0/doc/joinus.PNG" width = "200" height = "200" />
</div>
## 快速体验
- PC端超轻量级中文OCR在线体验地址https://www.paddlepaddle.org.cn/hub/scene/ocr
- 移动端:[安装包DEMO下载地址](https://ai.baidu.com/easyedge/app/openSource?from=paddlelite)(基于EasyEdge和Paddle-Lite, 支持iOS和Android系统)Android手机也可以直接扫描下面二维码安装体验。
<div align="center">
<img src="./doc/ocr-android-easyedge.png" width = "200" height = "200" />
</div>
- 代码体验:从[快速安装](./doc/doc_ch/quickstart.md) 开始
<a name="模型下载"></a>
## PP-OCR 2.0系列模型列表(更新中)
**说明** 2.0版模型和[1.1版模型](https://github.com/PaddlePaddle/PaddleOCR/blob/develop/doc/doc_ch/models_list.md)的主要区别在于动态图训练vs.静态图训练,模型性能上无明显差距。
| 模型简介 | 模型名称 |推荐场景 | 检测模型 | 方向分类器 | 识别模型 |
| ------------ | --------------- | ----------------|---- | ---------- | -------- |
| 中英文超轻量OCR模型9.4M | ch_ppocr_mobile_v2.0_xx |移动端&服务器端|[推理模型](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_det_infer.tar) / [预训练模型](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_det_train.tar)|[推理模型](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_infer.tar) / [预训练模型](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_train.tar) |[推理模型](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_rec_infer.tar) / [预训练模型](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_rec_pre.tar) |
| 中英文通用OCR模型143.4M |ch_ppocr_server_v2.0_xx|服务器端 |[推理模型](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_server_v2.0_det_infer.tar) / [预训练模型](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_server_v2.0_det_train.tar) |[推理模型](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_infer.tar) / [预训练模型](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_train.tar) |[推理模型](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_server_v2.0_rec_infer.tar) / [预训练模型](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_server_v2.0_rec_pre.tar) |
更多模型下载(包括多语言),可以参考[PP-OCR v2.0 系列模型下载](./doc/doc_ch/models_list.md)
## 文档教程
- [快速安装](./doc/doc_ch/installation.md)
- [中文OCR模型快速使用](./doc/doc_ch/quickstart.md)
- [代码组织结构](./doc/doc_ch/tree.md)
- 算法介绍
- [文本检测](./doc/doc_ch/algorithm_overview.md)
- [文本识别](./doc/doc_ch/algorithm_overview.md)
- [PP-OCR Pipline](#PP-OCR)
- 模型训练/评估
- [文本检测](./doc/doc_ch/detection.md)
- [文本识别](./doc/doc_ch/recognition.md)
- [方向分类器](./doc/doc_ch/angle_class.md)
- [yml参数配置文件介绍](./doc/doc_ch/config.md)
- 预测部署
- [基于pip安装whl包快速推理](./doc/doc_ch/whl.md)
- [基于Python脚本预测引擎推理](./doc/doc_ch/inference.md)
- [基于C++预测引擎推理](./deploy/cpp_infer/readme.md)
- [服务化部署](./deploy/hubserving/readme.md)
- [端侧部署](https://github.com/PaddlePaddle/PaddleOCR/blob/develop/deploy/lite/readme.md)
- [Benchmark](./doc/doc_ch/benchmark.md)
- 数据集
- [通用中英文OCR数据集](./doc/doc_ch/datasets.md)
- [手写中文OCR数据集](./doc/doc_ch/handwritten_datasets.md)
- [垂类多语言OCR数据集](./doc/doc_ch/vertical_and_multilingual_datasets.md)
- 数据标注与合成
- [半自动标注工具PPOCRLabel](./PPOCRLabel/README_ch.md)
- [数据合成工具Style-Text](./StyleText/README_ch.md)
- [其它数据标注工具](./doc/doc_ch/data_annotation.md)
- [其它数据合成工具](./doc/doc_ch/data_synthesis.md)
- [效果展示](#效果展示)
- FAQ
- [【精选】OCR精选10个问题](./doc/doc_ch/FAQ.md)
- [【理论篇】OCR通用30个问题](./doc/doc_ch/FAQ.md)
- [【实战篇】PaddleOCR实战84个问题](./doc/doc_ch/FAQ.md)
- [技术交流群](#欢迎加入PaddleOCR技术交流群)
- [参考文献](./doc/doc_ch/reference.md)
- [许可证书](#许可证书)
- [贡献代码](#贡献代码)
<a name="PP-OCR"></a>
## PP-OCR Pipline
<div align="center">
<img src="./doc/ppocr_framework.png" width="800">
</div>
PP-OCR是一个实用的超轻量OCR系统。主要由DB文本检测[2]、检测框矫正和CRNN文本识别三部分组成[7]。该系统从骨干网络选择和调整、预测头部的设计、数据增强、学习率变换策略、正则化参数选择、预训练模型使用以及模型自动裁剪量化8个方面采用19个有效策略对各个模块的模型进行效果调优和瘦身最终得到整体大小为3.5M的超轻量中英文OCR和2.8M的英文数字OCR。更多细节请参考PP-OCR技术方案 https://arxiv.org/abs/2009.09941 。其中FPGM裁剪器[8]和PACT量化[9]的实现可以参考[PaddleSlim](https://github.com/PaddlePaddle/PaddleSlim)。
<a name="效果展示"></a>
## 效果展示 [more](./doc/doc_ch/visualization.md)
- 中文模型
<div align="center">
<img src="./doc/imgs_results/ch_ppocr_mobile_v2.0/test_add_91.jpg" width="800">
<img src="./doc/imgs_results/ch_ppocr_mobile_v2.0/00015504.jpg" width="800">
<img src="./doc/imgs_results/ch_ppocr_mobile_v2.0/00056221.jpg" width="800">
<img src="./doc/imgs_results/ch_ppocr_mobile_v2.0/rotate_00052204.jpg" width="800">
</div>
- 英文模型
<div align="center">
<img src="./doc/imgs_results/ch_ppocr_mobile_v2.0/img_12.jpg" width="800">
</div>
- 其他语言模型
<div align="center">
<img src="./doc/imgs_results/french_0.jpg" width="800">
<img src="./doc/imgs_results/korean.jpg" width="800">
</div>
<a name="许可证书"></a>
## 许可证书
本项目的发布受<a href="https://github.com/PaddlePaddle/PaddleOCR/blob/master/LICENSE">Apache 2.0 license</a>许可认证。
<a name="贡献代码"></a>
## 贡献代码
我们非常欢迎你为PaddleOCR贡献代码也十分感谢你的反馈。
- 非常感谢 [Khanh Tran](https://github.com/xxxpsyduck) 和 [Karl Horky](https://github.com/karlhorky) 贡献修改英文文档
- 非常感谢 [zhangxin](https://github.com/ZhangXinNan)([Blog](https://blog.csdn.net/sdlypyzq)) 贡献新的可视化方式、添加.gitgnore、处理手动设置PYTHONPATH环境变量的问题
- 非常感谢 [lyl120117](https://github.com/lyl120117) 贡献打印网络结构的代码
- 非常感谢 [xiangyubo](https://github.com/xiangyubo) 贡献手写中文OCR数据集
- 非常感谢 [authorfu](https://github.com/authorfu) 贡献Android和[xiadeye](https://github.com/xiadeye) 贡献IOS的demo代码
- 非常感谢 [BeyondYourself](https://github.com/BeyondYourself) 给PaddleOCR提了很多非常棒的建议并简化了PaddleOCR的部分代码风格。
- 非常感谢 [tangmq](https://gitee.com/tangmq) 给PaddleOCR增加Docker化部署服务支持快速发布可调用的Restful API服务。
- 非常感谢 [lijinhan](https://github.com/lijinhan) 给PaddleOCR增加java SpringBoot 调用OCR Hubserving接口完成对OCR服务化部署的使用。
- 非常感谢 [Mejans](https://github.com/Mejans) 给PaddleOCR增加新语言奥克西坦语Occitan的字典和语料。
- 非常感谢 [Evezerest](https://github.com/Evezerest) [ninetailskim](https://github.com/ninetailskim) [edencfc](https://github.com/edencfc) [BeyondYourself](https://github.com/BeyondYourself) [1084667371](https://github.com/1084667371) 贡献了PPOCRLabel的完整代码。

View File

@ -1,231 +0,0 @@
English | [简体中文](README.md)
## Introduction
PaddleOCR aims to create rich, leading, and practical OCR tools that help users train better models and apply them into practice.
**Recent updates**
- 2020.8.24 Support the use of PaddleOCR through whl package installationpelease refer [PaddleOCR Package](https://github.com/PaddlePaddle/PaddleOCR/blob/develop/doc/doc_en/whl_en.md)
- 2020.8.16, Release text detection algorithm [SAST](https://arxiv.org/abs/1908.05498) and text recognition algorithm [SRN](https://arxiv.org/abs/2003.12294)
- 2020.7.23, Release the playback and PPT of live class on BiliBili station, PaddleOCR Introduction, [address](https://aistudio.baidu.com/aistudio/course/introduce/1519)
- 2020.7.15, Add mobile App demo , support both iOS and Android ( based on easyedge and Paddle Lite)
- 2020.7.15, Improve the deployment ability, add the C + + inference , serving deployment. In addition, the benchmarks of the ultra-lightweight OCR model are provided.
- 2020.7.15, Add several related datasets, data annotation and synthesis tools.
- [more](./doc/doc_en/update_en.md)
## Features
- Ultra-lightweight OCR model, total model size is only 8.6M
- Single model supports Chinese/English numbers combination recognition, vertical text recognition, long text recognition
- Detection model DB (4.1M) + recognition model CRNN (4.5M)
- Various text detection algorithms: EAST, DB
- Various text recognition algorithms: Rosetta, CRNN, STAR-Net, RARE
- Support Linux, Windows, macOS and other systems.
## Visualization
![](doc/imgs_results/11.jpg)
![](doc/imgs_results/img_10.jpg)
[More visualization](./doc/doc_en/visualization_en.md)
You can also quickly experience the ultra-lightweight OCR : [Online Experience](https://www.paddlepaddle.org.cn/hub/scene/ocr)
Mobile DEMO experience (based on EasyEdge and Paddle-Lite, supports iOS and Android systems): [Sign in to the website to obtain the QR code for installing the App](https://ai.baidu.com/easyedge/app/openSource?from=paddlelite)
Also, you can scan the QR code below to install the App (**Android support only**)
<div align="center">
<img src="./doc/ocr-android-easyedge.png" width = "200" height = "200" />
</div>
- [**OCR Quick Start**](./doc/doc_en/quickstart_en.md)
<a name="Supported-Chinese-model-list"></a>
### Supported Models:
|Model Name|Description |Detection Model link|Recognition Model link| Support for space Recognition Model link|
|-|-|-|-|-|
|db_crnn_mobile|ultra-lightweight OCR model|[inference model](https://paddleocr.bj.bcebos.com/ch_models/ch_det_mv3_db_infer.tar) / [pre-trained model](https://paddleocr.bj.bcebos.com/ch_models/ch_det_mv3_db.tar)|[inference model](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_mv3_crnn_infer.tar) / [pre-trained model](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_mv3_crnn.tar)|[inference model](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_mv3_crnn_enhance_infer.tar) / [pre-train model](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_mv3_crnn_enhance.tar)
|db_crnn_server|General OCR model|[inference model](https://paddleocr.bj.bcebos.com/ch_models/ch_det_r50_vd_db_infer.tar) / [pre-trained model](https://paddleocr.bj.bcebos.com/ch_models/ch_det_r50_vd_db.tar)|[inference model](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_r34_vd_crnn_infer.tar) / [pre-trained model](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_r34_vd_crnn.tar)|[inference model](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_r34_vd_crnn_enhance_infer.tar) / [pre-train model](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_r34_vd_crnn_enhance.tar)
## Tutorials
- [Installation](./doc/doc_en/installation_en.md)
- [Quick Start](./doc/doc_en/quickstart_en.md)
- Algorithm introduction
- [Text Detection Algorithm](#TEXTDETECTIONALGORITHM)
- [Text Recognition Algorithm](#TEXTRECOGNITIONALGORITHM)
- [END-TO-END OCR Algorithm](#ENDENDOCRALGORITHM)
- Model training/evaluation
- [Text Detection](./doc/doc_en/detection_en.md)
- [Text Recognition](./doc/doc_en/recognition_en.md)
- [Yml Configuration](./doc/doc_en/config_en.md)
- [Tricks](./doc/doc_en/tricks_en.md)
- Deployment
- [Python Inference](./doc/doc_en/inference_en.md)
- [C++ Inference](./deploy/cpp_infer/readme_en.md)
- [Serving](./doc/doc_en/serving_en.md)
- [Mobile](./deploy/lite/readme_en.md)
- Model Quantization and Compression (coming soon)
- [Benchmark](./doc/doc_en/benchmark_en.md)
- Datasets
- [General OCR Datasets(Chinese/English)](./doc/doc_en/datasets_en.md)
- [HandWritten_OCR_Datasets(Chinese)](./doc/doc_en/handwritten_datasets_en.md)
- [Various OCR Datasets(multilingual)](./doc/doc_en/vertical_and_multilingual_datasets_en.md)
- [Data Annotation Tools](./doc/doc_en/data_annotation_en.md)
- [Data Synthesis Tools](./doc/doc_en/data_synthesis_en.md)
- [FAQ](#FAQ)
- Visualization
- [Ultra-lightweight Chinese/English OCR Visualization](#UCOCRVIS)
- [General Chinese/English OCR Visualization](#GeOCRVIS)
- [Chinese/English OCR Visualization (Support Space Recognition )](#SpaceOCRVIS)
- [Community](#Community)
- [References](./doc/doc_en/reference_en.md)
- [License](#LICENSE)
- [Contribution](#CONTRIBUTION)
<a name="TEXTDETECTIONALGORITHM"></a>
## Text Detection Algorithm
PaddleOCR open source text detection algorithms list:
- [x] EAST([paper](https://arxiv.org/abs/1704.03155))
- [x] DB([paper](https://arxiv.org/abs/1911.08947))
- [x] SAST([paper](https://arxiv.org/abs/1908.05498))(Baidu Self-Research)
On the ICDAR2015 dataset, the text detection result is as follows:
|Model|Backbone|precision|recall|Hmean|Download link|
|-|-|-|-|-|-|
|EAST|ResNet50_vd|88.18%|85.51%|86.82%|[Download link](https://paddleocr.bj.bcebos.com/det_r50_vd_east.tar)|
|EAST|MobileNetV3|81.67%|79.83%|80.74%|[Download link](https://paddleocr.bj.bcebos.com/det_mv3_east.tar)|
|DB|ResNet50_vd|83.79%|80.65%|82.19%|[Download link](https://paddleocr.bj.bcebos.com/det_r50_vd_db.tar)|
|DB|MobileNetV3|75.92%|73.18%|74.53%|[Download link](https://paddleocr.bj.bcebos.com/det_mv3_db.tar)|
|SAST|ResNet50_vd|92.18%|82.96%|87.33%|[Download link](https://paddleocr.bj.bcebos.com/SAST/sast_r50_vd_icdar2015.tar)|
On Total-Text dataset, the text detection result is as follows:
|Model|Backbone|precision|recall|Hmean|Download link|
|-|-|-|-|-|-|
|SAST|ResNet50_vd|88.74%|79.80%|84.03%|[Download link](https://paddleocr.bj.bcebos.com/SAST/sast_r50_vd_total_text.tar)|
**Note** Additional data, like icdar2013, icdar2017, COCO-Text, ArT, was added to the model training of SAST. Download English public dataset in organized format used by PaddleOCR from [Baidu Drive](https://pan.baidu.com/s/12cPnZcVuV1zn5DOd4mqjVw) (download code: 2bpi).
For use of [LSVT](https://github.com/PaddlePaddle/PaddleOCR/blob/develop/doc/doc_en/datasets_en.md#1-icdar2019-lsvt) street view dataset with a total of 3w training datathe related configuration and pre-trained models for text detection task are as follows:
|Model|Backbone|Configuration file|Pre-trained model|
|-|-|-|-|
|ultra-lightweight OCR model|MobileNetV3|det_mv3_db.yml|[Download link](https://paddleocr.bj.bcebos.com/ch_models/ch_det_mv3_db.tar)|
|General OCR model|ResNet50_vd|det_r50_vd_db.yml|[Download link](https://paddleocr.bj.bcebos.com/ch_models/ch_det_r50_vd_db.tar)|
* Note: For the training and evaluation of the above DB model, post-processing parameters box_thresh=0.6 and unclip_ratio=1.5 need to be set. If using different datasets and different models for training, these two parameters can be adjusted for better result.
For the training guide and use of PaddleOCR text detection algorithms, please refer to the document [Text detection model training/evaluation/prediction](./doc/doc_en/detection_en.md)
<a name="TEXTRECOGNITIONALGORITHM"></a>
## Text Recognition Algorithm
PaddleOCR open-source text recognition algorithms list:
- [x] CRNN([paper](https://arxiv.org/abs/1507.05717))
- [x] Rosetta([paper](https://arxiv.org/abs/1910.05085))
- [x] STAR-Net([paper](http://www.bmva.org/bmvc/2016/papers/paper043/index.html))
- [x] RARE([paper](https://arxiv.org/abs/1603.03915v1))
- [x] SRN([paper](https://arxiv.org/abs/2003.12294))(Baidu Self-Research)
Refer to [DTRB](https://arxiv.org/abs/1904.01906), the training and evaluation result of these above text recognition (using MJSynth and SynthText for training, evaluate on IIIT, SVT, IC03, IC13, IC15, SVTP, CUTE) is as follow:
|Model|Backbone|Avg Accuracy|Module combination|Download link|
|-|-|-|-|-|
|Rosetta|Resnet34_vd|80.24%|rec_r34_vd_none_none_ctc|[Download link](https://paddleocr.bj.bcebos.com/rec_r34_vd_none_none_ctc.tar)|
|Rosetta|MobileNetV3|78.16%|rec_mv3_none_none_ctc|[Download link](https://paddleocr.bj.bcebos.com/rec_mv3_none_none_ctc.tar)|
|CRNN|Resnet34_vd|82.20%|rec_r34_vd_none_bilstm_ctc|[Download link](https://paddleocr.bj.bcebos.com/rec_r34_vd_none_bilstm_ctc.tar)|
|CRNN|MobileNetV3|79.37%|rec_mv3_none_bilstm_ctc|[Download link](https://paddleocr.bj.bcebos.com/rec_mv3_none_bilstm_ctc.tar)|
|STAR-Net|Resnet34_vd|83.93%|rec_r34_vd_tps_bilstm_ctc|[Download link](https://paddleocr.bj.bcebos.com/rec_r34_vd_tps_bilstm_ctc.tar)|
|STAR-Net|MobileNetV3|81.56%|rec_mv3_tps_bilstm_ctc|[Download link](https://paddleocr.bj.bcebos.com/rec_mv3_tps_bilstm_ctc.tar)|
|RARE|Resnet34_vd|84.90%|rec_r34_vd_tps_bilstm_attn|[Download link](https://paddleocr.bj.bcebos.com/rec_r34_vd_tps_bilstm_attn.tar)|
|RARE|MobileNetV3|83.32%|rec_mv3_tps_bilstm_attn|[Download link](https://paddleocr.bj.bcebos.com/rec_mv3_tps_bilstm_attn.tar)|
|SRN|Resnet50_vd_fpn|88.33%|rec_r50fpn_vd_none_srn|[Download link](https://paddleocr.bj.bcebos.com/SRN/rec_r50fpn_vd_none_srn.tar)|
**Note** SRN model uses data expansion method to expand the two training sets mentioned above, and the expanded data can be downloaded from [Baidu Drive](https://pan.baidu.com/s/1-HSZ-ZVdqBF2HaBZ5pRAKA) (download code: y3ry).
The average accuracy of the two-stage training in the original paper is 89.74%, and that of one stage training in paddleocr is 88.33%. Both pre-trained weights can be downloaded [here](https://paddleocr.bj.bcebos.com/SRN/rec_r50fpn_vd_none_srn.tar).
We use [LSVT](https://github.com/PaddlePaddle/PaddleOCR/blob/develop/doc/doc_en/datasets_en.md#1-icdar2019-lsvt) dataset and cropout 30w training data from original photos by using position groundtruth and make some calibration needed. In addition, based on the LSVT corpus, 500w synthetic data is generated to train the model. The related configuration and pre-trained models are as follows:
|Model|Backbone|Configuration file|Pre-trained model|
|-|-|-|-|
|ultra-lightweight OCR model|MobileNetV3|rec_chinese_lite_train.yml|[Download link](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_mv3_crnn.tar)|[inference model](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_mv3_crnn_enhance_infer.tar) & [pre-trained model](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_mv3_crnn_enhance.tar)|
|General OCR model|Resnet34_vd|rec_chinese_common_train.yml|[Download link](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_r34_vd_crnn.tar)|[inference model](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_r34_vd_crnn_enhance_infer.tar) & [pre-trained model](https://paddleocr.bj.bcebos.com/ch_models/ch_rec_r34_vd_crnn_enhance.tar)|
Please refer to the document for training guide and use of PaddleOCR text recognition algorithms [Text recognition model training/evaluation/prediction](./doc/doc_en/recognition_en.md)
<a name="ENDENDOCRALGORITHM"></a>
## END-TO-END OCR Algorithm
- [ ] [End2End-PSL](https://arxiv.org/abs/1909.07808)(Baidu Self-Research, coming soon)
## Visualization
<a name="UCOCRVIS"></a>
### 1.Ultra-lightweight Chinese/English OCR Visualization [more](./doc/doc_en/visualization_en.md)
<div align="center">
<img src="doc/imgs_results/1.jpg" width="800">
</div>
<a name="GeOCRVIS"></a>
### 2. General Chinese/English OCR Visualization [more](./doc/doc_en/visualization_en.md)
<div align="center">
<img src="doc/imgs_results/chinese_db_crnn_server/11.jpg" width="800">
</div>
<a name="SpaceOCRVIS"></a>
### 3.Chinese/English OCR Visualization (Space_support) [more](./doc/doc_en/visualization_en.md)
<div align="center">
<img src="doc/imgs_results/chinese_db_crnn_server/en_paper.jpg" width="800">
</div>
<a name="FAQ"></a>
## FAQ
1. Error when using attention-based recognition model: KeyError: 'predict'
The inference of recognition model based on attention loss is still being debugged. For Chinese text recognition, it is recommended to choose the recognition model based on CTC loss first. In practice, it is also found that the recognition model based on attention loss is not as effective as the one based on CTC loss.
2. About inference speed
When there are a lot of texts in the picture, the prediction time will increase. You can use `--rec_batch_num` to set a smaller prediction batch size. The default value is 30, which can be changed to 10 or other values.
3. Service deployment and mobile deployment
It is expected that the service deployment based on Serving and the mobile deployment based on Paddle Lite will be released successively in mid-to-late June. Stay tuned for more updates.
4. Release time of self-developed algorithm
Baidu Self-developed algorithms such as SAST, SRN and end2end PSL will be released in June or July. Please be patient.
[more](./doc/doc_en/FAQ_en.md)
<a name="Community"></a>
## Community
Scan the QR code below with your wechat and completing the questionnaire, you can access to offical technical exchange group.
<div align="center">
<img src="./doc/joinus.jpg" width = "200" height = "200" />
</div>
<a name="LICENSE"></a>
## License
This project is released under <a href="https://github.com/PaddlePaddle/PaddleOCR/blob/master/LICENSE">Apache 2.0 license</a>
<a name="CONTRIBUTION"></a>
## Contribution
We welcome all the contributions to PaddleOCR and appreciate for your feedback very much.
- Many thanks to [Khanh Tran](https://github.com/xxxpsyduck) and [Karl Horky](https://github.com/karlhorky) for contributing and revising the English documentation.
- Many thanks to [zhangxin](https://github.com/ZhangXinNan) for contributing the new visualize function、add .gitgnore and discard set PYTHONPATH manually.
- Many thanks to [lyl120117](https://github.com/lyl120117) for contributing the code for printing the network structure.
- Thanks [xiangyubo](https://github.com/xiangyubo) for contributing the handwritten Chinese OCR datasets.
- Thanks [authorfu](https://github.com/authorfu) for contributing Android demo and [xiadeye](https://github.com/xiadeye) contributing iOS demo, respectively.
- Thanks [BeyondYourself](https://github.com/BeyondYourself) for contributing many great suggestions and simplifying part of the code style.
- Thanks [tangmq](https://gitee.com/tangmq) for contributing Dockerized deployment services to PaddleOCR and supporting the rapid release of callable Restful API services.

220
StyleText/README.md Normal file
View File

@ -0,0 +1,220 @@
English | [简体中文](README_ch.md)
## Style Text
### Contents
- [1. Introduction](#Introduction)
- [2. Preparation](#Preparation)
- [3. Quick Start](#Quick_Start)
- [4. Applications](#Applications)
- [5. Code Structure](#Code_structure)
<a name="Introduction"></a>
### Introduction
<div align="center">
<img src="doc/images/3.png" width="800">
</div>
<div align="center">
<img src="doc/images/9.png" width="600">
</div>
The Style-Text data synthesis tool is a tool based on Baidu and HUST cooperation research work, "Editing Text in the Wild" [https://arxiv.org/abs/1908.03047](https://arxiv.org/abs/1908.03047).
Different from the commonly used GAN-based data synthesis tools, the main framework of Style-Text includes:
* (1) Text foreground style transfer module.
* (2) Background extraction module.
* (3) Fusion module.
After these three steps, you can quickly realize the image text style transfer. The following figure is some results of the data synthesis tool.
<div align="center">
<img src="doc/images/10.png" width="1000">
</div>
<a name="Preparation"></a>
#### Preparation
1. Please refer the [QUICK INSTALLATION](../doc/doc_en/installation_en.md) to install PaddlePaddle. Python3 environment is strongly recommended.
2. Download the pretrained models and unzip:
```bash
cd StyleText
wget https://paddleocr.bj.bcebos.com/dygraph_v2.0/style_text/style_text_models.zip
unzip style_text_models.zip
```
If you save the model in another location, please modify the address of the model file in `configs/config.yml`, and you need to modify these three configurations at the same time:
```
bg_generator:
pretrain: style_text_rec/bg_generator
...
text_generator:
pretrain: style_text_models/text_generator
...
fusion_generator:
pretrain: style_text_models/fusion_generator
```
<a name="Quick_Start"></a>
### Quick Start
#### Synthesis single image
1. You can run `tools/synth_image` and generate the demo image, which is saved in the current folder.
```python
python3 tools/synth_image.py -c configs/config.yml --style_image examples/style_images/2.jpg --text_corpus PaddleOCR --language en
```
* Note 1: The language options is correspond to the corpus. Currently, the tool only supports English, Simplified Chinese and Korean.
* Note 2: Synth-Text is mainly used to generate images for OCR recognition models.
So the height of style images should be around 32 pixels. Images in other sizes may behave poorly.
* Note 3: You can modify `use_gpu` in `configs/config.yml` to determine whether to use GPU for prediction.
For example, enter the following image and corpus `PaddleOCR`.
<div align="center">
<img src="examples/style_images/2.jpg" width="300">
</div>
The result `fake_fusion.jpg` will be generated.
<div align="center">
<img src="doc/images/4.jpg" width="300">
</div>
What's more, the medium result `fake_bg.jpg` will also be saved, which is the background output.
<div align="center">
<img src="doc/images/7.jpg" width="300">
</div>
`fake_text.jpg` * `fake_text.jpg` is the generated image with the same font style as `Style Input`.
<div align="center">
<img src="doc/images/8.jpg" width="300">
</div>
#### Batch synthesis
In actual application scenarios, it is often necessary to synthesize pictures in batches and add them to the training set. StyleText can use a batch of style pictures and corpus to synthesize data in batches. The synthesis process is as follows:
1. The referenced dataset can be specifed in `configs/dataset_config.yml`:
* `Global`
* `output_dir:`Output synthesis data path.
* `StyleSampler`
* `image_home`style images' folder.
* `label_file`Style images' file list. If label is provided, then it is the label file path.
* `with_label`Whether the `label_file` is label file list.
* `CorpusGenerator`
* `method`Method of CorpusGeneratorsupports `FileCorpus` and `EnNumCorpus`. If `EnNumCorpus` is usedNo other configuration is neededotherwise you need to set `corpus_file` and `language`.
* `language`Language of the corpus.
* `corpus_file`: Filepath of the corpus. Corpus file should be a text file which will be split by line-endings'\n'. Corpus generator samples one line each time.
Example of corpus file:
```
PaddleOCR
飞桨文字识别
StyleText
风格文本图像数据合成
```
We provide a general dataset containing Chinese, English and Korean (50,000 images in all) for your trial ([download link](https://paddleocr.bj.bcebos.com/dygraph_v2.0/style_text/chkoen_5w.tar)), some examples are given below :
<div align="center">
<img src="doc/images/5.png" width="800">
</div>
2. You can run the following command to start synthesis task:
``` bash
python3 tools/synth_dataset.py -c configs/dataset_config.yml
```
We also provide example corpus and images in `examples` folder.
<div align="center">
<img src="examples/style_images/1.jpg" width="300">
<img src="examples/style_images/2.jpg" width="300">
</div>
If you run the code above directly, you will get example output data in `output_data` folder.
You will get synthesis images and labels as below:
<div align="center">
<img src="doc/images/12.png" width="800">
</div>
There will be some cache under the `label` folder. If the program exit unexpectedly, you can find cached labels there.
When the program finish normally, you will find all the labels in `label.txt` which give the final results.
<a name="Applications"></a>
### Applications
We take two scenes as examples, which are metal surface English number recognition and general Korean recognition, to illustrate practical cases of using StyleText to synthesize data to improve text recognition. The following figure shows some examples of real scene images and composite images:
<div align="center">
<img src="doc/images/11.png" width="800">
</div>
After adding the above synthetic data for training, the accuracy of the recognition model is improved, which is shown in the following table:
| Scenario | Characters | Raw Data | Test Data | Only Use Raw Data</br>Recognition Accuracy | New Synthetic Data | Simultaneous Use of Synthetic Data</br>Recognition Accuracy | Index Improvement |
| -------- | ---------- | -------- | -------- | -------------------------- | ------------ | ---------------------- | -------- |
| Metal surface | English and numbers | 2203 | 650 | 0.5938 | 20000 | 0.7546 | 16% |
| Random background | Korean | 5631 | 1230 | 0.3012 | 100000 | 0.5057 | 20% |
<a name="Code_structure"></a>
### Code Structure
```
StyleText
|-- arch // Network module files.
| |-- base_module.py
| |-- decoder.py
| |-- encoder.py
| |-- spectral_norm.py
| `-- style_text_rec.py
|-- configs // Config files.
| |-- config.yml
| `-- dataset_config.yml
|-- engine // Synthesis engines.
| |-- corpus_generators.py // Sample corpus from file or generate random corpus.
| |-- predictors.py // Predict using network.
| |-- style_samplers.py // Sample style images.
| |-- synthesisers.py // Manage other engines to synthesis images.
| |-- text_drawers.py // Generate standard input text images.
| `-- writers.py // Write synthesis images and labels into files.
|-- examples // Example files.
| |-- corpus
| | `-- example.txt
| |-- image_list.txt
| `-- style_images
| |-- 1.jpg
| `-- 2.jpg
|-- fonts // Font files.
| |-- ch_standard.ttf
| |-- en_standard.ttf
| `-- ko_standard.ttf
|-- tools // Program entrance.
| |-- __init__.py
| |-- synth_dataset.py // Synthesis dataset.
| `-- synth_image.py // Synthesis image.
`-- utils // Module of basic functions.
|-- config.py
|-- load_params.py
|-- logging.py
|-- math_functions.py
`-- sys_funcs.py
```

205
StyleText/README_ch.md Normal file
View File

@ -0,0 +1,205 @@
简体中文 | [English](README.md)
## Style Text
### 目录
- [一、工具简介](#工具简介)
- [二、环境配置](#环境配置)
- [三、快速上手](#快速上手)
- [四、应用案例](#应用案例)
- [五、代码结构](#代码结构)
<a name="工具简介"></a>
### 一、工具简介
<div align="center">
<img src="doc/images/3.png" width="800">
</div>
<div align="center">
<img src="doc/images/1.png" width="600">
</div>
Style-Text数据合成工具是基于百度和华科合作研发的文本编辑算法《Editing Text in the Wild》https://arxiv.org/abs/1908.03047
不同于常用的基于GAN的数据合成工具Style-Text主要框架包括1.文本前景风格迁移模块 2.背景抽取模块 3.融合模块。经过这样三步,就可以迅速实现图像文本风格迁移。下图是一些该数据合成工具效果图。
<div align="center">
<img src="doc/images/2.png" width="1000">
</div>
<a name="环境配置"></a>
### 二、环境配置
1. 参考[快速安装](../doc/doc_ch/installation.md)安装PaddleOCR。
2. 进入`StyleText`目录,下载模型,并解压:
```bash
cd StyleText
wget https://paddleocr.bj.bcebos.com/dygraph_v2.0/style_text/style_text_models.zip
unzip style_text_models.zip
```
如果您将模型保存再其他位置,请在`configs/config.yml`中修改模型文件的地址,修改时需要同时修改这三个配置:
```
bg_generator:
pretrain: style_text_models/bg_generator
...
text_generator:
pretrain: style_text_models/text_generator
...
fusion_generator:
pretrain: style_text_models/fusion_generator
```
<a name="快速上手"></a>
### 三、快速上手
#### 合成单张图
输入一张风格图和一段文字语料运行tools/synth_image合成单张图片结果图像保存在当前目录下
```python
python3 tools/synth_image.py -c configs/config.yml --style_image examples/style_images/2.jpg --text_corpus PaddleOCR --language en
```
* 注1语言选项和语料相对应目前该工具只支持英文、简体中文和韩语。
* 注2Style-Text生成的数据主要应用于OCR识别场景。基于当前PaddleOCR识别模型的设计我们主要支持高度在32左右的风格图像。
如果输入图像尺寸相差过多,效果可能不佳。
* 注3可以通过修改配置文件中的`use_gpu`(true或者false)参数来决定是否使用GPU进行预测。
例如,输入如下图片和语料"PaddleOCR":
<div align="center">
<img src="examples/style_images/2.jpg" width="300">
</div>
生成合成数据`fake_fusion.jpg`
<div align="center">
<img src="doc/images/4.jpg" width="300">
</div>
除此之外,程序还会生成并保存中间结果`fake_bg.jpg`:为风格参考图去掉文字后的背景;
<div align="center">
<img src="doc/images/7.jpg" width="300">
</div>
`fake_text.jpg`:是用提供的字符串,仿照风格参考图中文字的风格,生成在灰色背景上的文字图片。
<div align="center">
<img src="doc/images/8.jpg" width="300">
</div>
#### 批量合成
在实际应用场景中经常需要批量合成图片补充到训练集中。Style-Text可以使用一批风格图片和语料批量合成数据。合成过程如下
1. 在`configs/dataset_config.yml`中配置目标场景风格图像和语料的路径,具体如下:
* `Global`
* `output_dir:`:保存合成数据的目录。
* `StyleSampler`
* `image_home`:风格图片目录;
* `label_file`风格图片路径列表文件如果所用数据集有label则label_file为label文件路径
* `with_label`:标志`label_file`是否为label文件。
* `CorpusGenerator`
* `method`:语料生成方法,目前有`FileCorpus`和`EnNumCorpus`可选。如果使用`EnNumCorpus`,则不需要填写其他配置,否则需要修改`corpus_file`和`language`
* `language`:语料的语种;
* `corpus_file`: 语料文件路径。语料文件应使用文本文件。语料生成器首先会将语料按行切分,之后每次随机选取一行。
语料文件格式示例:
```
PaddleOCR
飞桨文字识别
StyleText
风格文本图像数据合成
...
```
Style-Text也提供了一批中英韩5万张通用场景数据用作文本风格图像便于合成场景丰富的文本图像下图给出了一些示例。
中英韩5万张通用场景数据: [下载地址](https://paddleocr.bj.bcebos.com/dygraph_v2.0/style_text/chkoen_5w.tar)
<div align="center">
<img src="doc/images/5.png" width="800">
</div>
2. 运行`tools/synth_dataset`合成数据:
``` bash
python tools/synth_dataset.py -c configs/dataset_config.yml
```
我们在examples目录下提供了样例图片和语料。
<div align="center">
<img src="examples/style_images/1.jpg" width="300">
<img src="examples/style_images/2.jpg" width="300">
</div>
直接运行上述命令可以在output_data中产生样例输出包括图片和用于训练识别模型的标注文件
<div align="center">
<img src="doc/images/12.png" width="800">
</div>
其中label目录下的标注文件为程序运行过程中产生的缓存如果程序在中途异常终止可以使用缓存的标注文件。
如果程序正常运行完毕则会在output_data下生成label.txt为最终的标注结果。
<a name="应用案例"></a>
### 四、应用案例
下面以金属表面英文数字识别和通用韩语识别两个场景为例说明使用Style-Text合成数据来提升文本识别效果的实际案例。下图给出了一些真实场景图像和合成图像的示例
<div align="center">
<img src="doc/images/6.png" width="800">
</div>
在添加上述合成数据进行训练后,识别模型的效果提升,如下表所示:
| 场景 | 字符 | 原始数据 | 测试数据 | 只使用原始数据</br>识别准确率 | 新增合成数据 | 同时使用合成数据</br>识别准确率 | 指标提升 |
| -------- | ---------- | -------- | -------- | -------------------------- | ------------ | ---------------------- | -------- |
| 金属表面 | 英文和数字 | 2203 | 650 | 0.5938 | 20000 | 0.7546 | 16% |
| 随机背景 | 韩语 | 5631 | 1230 | 0.3012 | 100000 | 0.5057 | 20% |
<a name="代码结构"></a>
### 五、代码结构
```
StyleText
|-- arch // 网络结构定义文件
| |-- base_module.py
| |-- decoder.py
| |-- encoder.py
| |-- spectral_norm.py
| `-- style_text_rec.py
|-- configs // 配置文件
| |-- config.yml
| `-- dataset_config.yml
|-- engine // 数据合成引擎
| |-- corpus_generators.py // 从文本采样或随机生成语料
| |-- predictors.py // 调用网络生成数据
| |-- style_samplers.py // 采样风格图片
| |-- synthesisers.py // 调度各个模块,合成数据
| |-- text_drawers.py // 生成标准文字图片,用作输入
| `-- writers.py // 将合成的图片和标签写入本地目录
|-- examples // 示例文件
| |-- corpus
| | `-- example.txt
| |-- image_list.txt
| `-- style_images
| |-- 1.jpg
| `-- 2.jpg
|-- fonts // 字体文件
| |-- ch_standard.ttf
| |-- en_standard.ttf
| `-- ko_standard.ttf
|-- tools // 程序入口
| |-- __init__.py
| |-- synth_dataset.py // 批量合成数据
| `-- synth_image.py // 合成单张图片
`-- utils // 其他基础功能模块
|-- config.py
|-- load_params.py
|-- logging.py
|-- math_functions.py
`-- sys_funcs.py
```

0
StyleText/__init__.py Normal file
View File

View File

View File

@ -0,0 +1,255 @@
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import paddle
import paddle.nn as nn
from arch.spectral_norm import spectral_norm
class CBN(nn.Layer):
def __init__(self,
name,
in_channels,
out_channels,
kernel_size,
stride=1,
padding=0,
dilation=1,
groups=1,
use_bias=False,
norm_layer=None,
act=None,
act_attr=None):
super(CBN, self).__init__()
if use_bias:
bias_attr = paddle.ParamAttr(name=name + "_bias")
else:
bias_attr = None
self._conv = paddle.nn.Conv2D(
in_channels=in_channels,
out_channels=out_channels,
kernel_size=kernel_size,
stride=stride,
padding=padding,
dilation=dilation,
groups=groups,
weight_attr=paddle.ParamAttr(name=name + "_weights"),
bias_attr=bias_attr)
if norm_layer:
self._norm_layer = getattr(paddle.nn, norm_layer)(
num_features=out_channels, name=name + "_bn")
else:
self._norm_layer = None
if act:
if act_attr:
self._act = getattr(paddle.nn, act)(**act_attr,
name=name + "_" + act)
else:
self._act = getattr(paddle.nn, act)(name=name + "_" + act)
else:
self._act = None
def forward(self, x):
out = self._conv(x)
if self._norm_layer:
out = self._norm_layer(out)
if self._act:
out = self._act(out)
return out
class SNConv(nn.Layer):
def __init__(self,
name,
in_channels,
out_channels,
kernel_size,
stride=1,
padding=0,
dilation=1,
groups=1,
use_bias=False,
norm_layer=None,
act=None,
act_attr=None):
super(SNConv, self).__init__()
if use_bias:
bias_attr = paddle.ParamAttr(name=name + "_bias")
else:
bias_attr = None
self._sn_conv = spectral_norm(
paddle.nn.Conv2D(
in_channels=in_channels,
out_channels=out_channels,
kernel_size=kernel_size,
stride=stride,
padding=padding,
dilation=dilation,
groups=groups,
weight_attr=paddle.ParamAttr(name=name + "_weights"),
bias_attr=bias_attr))
if norm_layer:
self._norm_layer = getattr(paddle.nn, norm_layer)(
num_features=out_channels, name=name + "_bn")
else:
self._norm_layer = None
if act:
if act_attr:
self._act = getattr(paddle.nn, act)(**act_attr,
name=name + "_" + act)
else:
self._act = getattr(paddle.nn, act)(name=name + "_" + act)
else:
self._act = None
def forward(self, x):
out = self._sn_conv(x)
if self._norm_layer:
out = self._norm_layer(out)
if self._act:
out = self._act(out)
return out
class SNConvTranspose(nn.Layer):
def __init__(self,
name,
in_channels,
out_channels,
kernel_size,
stride=1,
padding=0,
output_padding=0,
dilation=1,
groups=1,
use_bias=False,
norm_layer=None,
act=None,
act_attr=None):
super(SNConvTranspose, self).__init__()
if use_bias:
bias_attr = paddle.ParamAttr(name=name + "_bias")
else:
bias_attr = None
self._sn_conv_transpose = spectral_norm(
paddle.nn.Conv2DTranspose(
in_channels=in_channels,
out_channels=out_channels,
kernel_size=kernel_size,
stride=stride,
padding=padding,
output_padding=output_padding,
dilation=dilation,
groups=groups,
weight_attr=paddle.ParamAttr(name=name + "_weights"),
bias_attr=bias_attr))
if norm_layer:
self._norm_layer = getattr(paddle.nn, norm_layer)(
num_features=out_channels, name=name + "_bn")
else:
self._norm_layer = None
if act:
if act_attr:
self._act = getattr(paddle.nn, act)(**act_attr,
name=name + "_" + act)
else:
self._act = getattr(paddle.nn, act)(name=name + "_" + act)
else:
self._act = None
def forward(self, x):
out = self._sn_conv_transpose(x)
if self._norm_layer:
out = self._norm_layer(out)
if self._act:
out = self._act(out)
return out
class MiddleNet(nn.Layer):
def __init__(self, name, in_channels, mid_channels, out_channels,
use_bias):
super(MiddleNet, self).__init__()
self._sn_conv1 = SNConv(
name=name + "_sn_conv1",
in_channels=in_channels,
out_channels=mid_channels,
kernel_size=1,
use_bias=use_bias,
norm_layer=None,
act=None)
self._pad2d = nn.Pad2D(padding=[1, 1, 1, 1], mode="replicate")
self._sn_conv2 = SNConv(
name=name + "_sn_conv2",
in_channels=mid_channels,
out_channels=mid_channels,
kernel_size=3,
use_bias=use_bias)
self._sn_conv3 = SNConv(
name=name + "_sn_conv3",
in_channels=mid_channels,
out_channels=out_channels,
kernel_size=1,
use_bias=use_bias)
def forward(self, x):
sn_conv1 = self._sn_conv1.forward(x)
pad_2d = self._pad2d.forward(sn_conv1)
sn_conv2 = self._sn_conv2.forward(pad_2d)
sn_conv3 = self._sn_conv3.forward(sn_conv2)
return sn_conv3
class ResBlock(nn.Layer):
def __init__(self, name, channels, norm_layer, use_dropout, use_dilation,
use_bias):
super(ResBlock, self).__init__()
if use_dilation:
padding_mat = [1, 1, 1, 1]
else:
padding_mat = [0, 0, 0, 0]
self._pad1 = nn.Pad2D(padding_mat, mode="replicate")
self._sn_conv1 = SNConv(
name=name + "_sn_conv1",
in_channels=channels,
out_channels=channels,
kernel_size=3,
padding=0,
norm_layer=norm_layer,
use_bias=use_bias,
act="ReLU",
act_attr=None)
if use_dropout:
self._dropout = nn.Dropout(0.5)
else:
self._dropout = None
self._pad2 = nn.Pad2D([1, 1, 1, 1], mode="replicate")
self._sn_conv2 = SNConv(
name=name + "_sn_conv2",
in_channels=channels,
out_channels=channels,
kernel_size=3,
norm_layer=norm_layer,
use_bias=use_bias,
act="ReLU",
act_attr=None)
def forward(self, x):
pad1 = self._pad1.forward(x)
sn_conv1 = self._sn_conv1.forward(pad1)
pad2 = self._pad2.forward(sn_conv1)
sn_conv2 = self._sn_conv2.forward(pad2)
return sn_conv2 + x

251
StyleText/arch/decoder.py Normal file
View File

@ -0,0 +1,251 @@
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import paddle
import paddle.nn as nn
from arch.base_module import SNConv, SNConvTranspose, ResBlock
class Decoder(nn.Layer):
def __init__(self, name, encode_dim, out_channels, use_bias, norm_layer,
act, act_attr, conv_block_dropout, conv_block_num,
conv_block_dilation, out_conv_act, out_conv_act_attr):
super(Decoder, self).__init__()
conv_blocks = []
for i in range(conv_block_num):
conv_blocks.append(
ResBlock(
name="{}_conv_block_{}".format(name, i),
channels=encode_dim * 8,
norm_layer=norm_layer,
use_dropout=conv_block_dropout,
use_dilation=conv_block_dilation,
use_bias=use_bias))
self.conv_blocks = nn.Sequential(*conv_blocks)
self._up1 = SNConvTranspose(
name=name + "_up1",
in_channels=encode_dim * 8,
out_channels=encode_dim * 4,
kernel_size=3,
stride=2,
padding=1,
output_padding=1,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
self._up2 = SNConvTranspose(
name=name + "_up2",
in_channels=encode_dim * 4,
out_channels=encode_dim * 2,
kernel_size=3,
stride=2,
padding=1,
output_padding=1,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
self._up3 = SNConvTranspose(
name=name + "_up3",
in_channels=encode_dim * 2,
out_channels=encode_dim,
kernel_size=3,
stride=2,
padding=1,
output_padding=1,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
self._pad2d = paddle.nn.Pad2D([1, 1, 1, 1], mode="replicate")
self._out_conv = SNConv(
name=name + "_out_conv",
in_channels=encode_dim,
out_channels=out_channels,
kernel_size=3,
use_bias=use_bias,
norm_layer=None,
act=out_conv_act,
act_attr=out_conv_act_attr)
def forward(self, x):
if isinstance(x, (list, tuple)):
x = paddle.concat(x, axis=1)
output_dict = dict()
output_dict["conv_blocks"] = self.conv_blocks.forward(x)
output_dict["up1"] = self._up1.forward(output_dict["conv_blocks"])
output_dict["up2"] = self._up2.forward(output_dict["up1"])
output_dict["up3"] = self._up3.forward(output_dict["up2"])
output_dict["pad2d"] = self._pad2d.forward(output_dict["up3"])
output_dict["out_conv"] = self._out_conv.forward(output_dict["pad2d"])
return output_dict
class DecoderUnet(nn.Layer):
def __init__(self, name, encode_dim, out_channels, use_bias, norm_layer,
act, act_attr, conv_block_dropout, conv_block_num,
conv_block_dilation, out_conv_act, out_conv_act_attr):
super(DecoderUnet, self).__init__()
conv_blocks = []
for i in range(conv_block_num):
conv_blocks.append(
ResBlock(
name="{}_conv_block_{}".format(name, i),
channels=encode_dim * 8,
norm_layer=norm_layer,
use_dropout=conv_block_dropout,
use_dilation=conv_block_dilation,
use_bias=use_bias))
self._conv_blocks = nn.Sequential(*conv_blocks)
self._up1 = SNConvTranspose(
name=name + "_up1",
in_channels=encode_dim * 8,
out_channels=encode_dim * 4,
kernel_size=3,
stride=2,
padding=1,
output_padding=1,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
self._up2 = SNConvTranspose(
name=name + "_up2",
in_channels=encode_dim * 8,
out_channels=encode_dim * 2,
kernel_size=3,
stride=2,
padding=1,
output_padding=1,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
self._up3 = SNConvTranspose(
name=name + "_up3",
in_channels=encode_dim * 4,
out_channels=encode_dim,
kernel_size=3,
stride=2,
padding=1,
output_padding=1,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
self._pad2d = paddle.nn.Pad2D([1, 1, 1, 1], mode="replicate")
self._out_conv = SNConv(
name=name + "_out_conv",
in_channels=encode_dim,
out_channels=out_channels,
kernel_size=3,
use_bias=use_bias,
norm_layer=None,
act=out_conv_act,
act_attr=out_conv_act_attr)
def forward(self, x, y, feature2, feature1):
output_dict = dict()
output_dict["conv_blocks"] = self._conv_blocks(
paddle.concat(
(x, y), axis=1))
output_dict["up1"] = self._up1.forward(output_dict["conv_blocks"])
output_dict["up2"] = self._up2.forward(
paddle.concat(
(output_dict["up1"], feature2), axis=1))
output_dict["up3"] = self._up3.forward(
paddle.concat(
(output_dict["up2"], feature1), axis=1))
output_dict["pad2d"] = self._pad2d.forward(output_dict["up3"])
output_dict["out_conv"] = self._out_conv.forward(output_dict["pad2d"])
return output_dict
class SingleDecoder(nn.Layer):
def __init__(self, name, encode_dim, out_channels, use_bias, norm_layer,
act, act_attr, conv_block_dropout, conv_block_num,
conv_block_dilation, out_conv_act, out_conv_act_attr):
super(SingleDecoder, self).__init__()
conv_blocks = []
for i in range(conv_block_num):
conv_blocks.append(
ResBlock(
name="{}_conv_block_{}".format(name, i),
channels=encode_dim * 4,
norm_layer=norm_layer,
use_dropout=conv_block_dropout,
use_dilation=conv_block_dilation,
use_bias=use_bias))
self._conv_blocks = nn.Sequential(*conv_blocks)
self._up1 = SNConvTranspose(
name=name + "_up1",
in_channels=encode_dim * 4,
out_channels=encode_dim * 4,
kernel_size=3,
stride=2,
padding=1,
output_padding=1,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
self._up2 = SNConvTranspose(
name=name + "_up2",
in_channels=encode_dim * 8,
out_channels=encode_dim * 2,
kernel_size=3,
stride=2,
padding=1,
output_padding=1,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
self._up3 = SNConvTranspose(
name=name + "_up3",
in_channels=encode_dim * 4,
out_channels=encode_dim,
kernel_size=3,
stride=2,
padding=1,
output_padding=1,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
self._pad2d = paddle.nn.Pad2D([1, 1, 1, 1], mode="replicate")
self._out_conv = SNConv(
name=name + "_out_conv",
in_channels=encode_dim,
out_channels=out_channels,
kernel_size=3,
use_bias=use_bias,
norm_layer=None,
act=out_conv_act,
act_attr=out_conv_act_attr)
def forward(self, x, feature2, feature1):
output_dict = dict()
output_dict["conv_blocks"] = self._conv_blocks.forward(x)
output_dict["up1"] = self._up1.forward(output_dict["conv_blocks"])
output_dict["up2"] = self._up2.forward(
paddle.concat(
(output_dict["up1"], feature2), axis=1))
output_dict["up3"] = self._up3.forward(
paddle.concat(
(output_dict["up2"], feature1), axis=1))
output_dict["pad2d"] = self._pad2d.forward(output_dict["up3"])
output_dict["out_conv"] = self._out_conv.forward(output_dict["pad2d"])
return output_dict

186
StyleText/arch/encoder.py Normal file
View File

@ -0,0 +1,186 @@
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import paddle
import paddle.nn as nn
from arch.base_module import SNConv, SNConvTranspose, ResBlock
class Encoder(nn.Layer):
def __init__(self, name, in_channels, encode_dim, use_bias, norm_layer,
act, act_attr, conv_block_dropout, conv_block_num,
conv_block_dilation):
super(Encoder, self).__init__()
self._pad2d = paddle.nn.Pad2D([3, 3, 3, 3], mode="replicate")
self._in_conv = SNConv(
name=name + "_in_conv",
in_channels=in_channels,
out_channels=encode_dim,
kernel_size=7,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
self._down1 = SNConv(
name=name + "_down1",
in_channels=encode_dim,
out_channels=encode_dim * 2,
kernel_size=3,
stride=2,
padding=1,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
self._down2 = SNConv(
name=name + "_down2",
in_channels=encode_dim * 2,
out_channels=encode_dim * 4,
kernel_size=3,
stride=2,
padding=1,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
self._down3 = SNConv(
name=name + "_down3",
in_channels=encode_dim * 4,
out_channels=encode_dim * 4,
kernel_size=3,
stride=2,
padding=1,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
conv_blocks = []
for i in range(conv_block_num):
conv_blocks.append(
ResBlock(
name="{}_conv_block_{}".format(name, i),
channels=encode_dim * 4,
norm_layer=norm_layer,
use_dropout=conv_block_dropout,
use_dilation=conv_block_dilation,
use_bias=use_bias))
self._conv_blocks = nn.Sequential(*conv_blocks)
def forward(self, x):
out_dict = dict()
x = self._pad2d(x)
out_dict["in_conv"] = self._in_conv.forward(x)
out_dict["down1"] = self._down1.forward(out_dict["in_conv"])
out_dict["down2"] = self._down2.forward(out_dict["down1"])
out_dict["down3"] = self._down3.forward(out_dict["down2"])
out_dict["res_blocks"] = self._conv_blocks.forward(out_dict["down3"])
return out_dict
class EncoderUnet(nn.Layer):
def __init__(self, name, in_channels, encode_dim, use_bias, norm_layer,
act, act_attr):
super(EncoderUnet, self).__init__()
self._pad2d = paddle.nn.Pad2D([3, 3, 3, 3], mode="replicate")
self._in_conv = SNConv(
name=name + "_in_conv",
in_channels=in_channels,
out_channels=encode_dim,
kernel_size=7,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
self._down1 = SNConv(
name=name + "_down1",
in_channels=encode_dim,
out_channels=encode_dim * 2,
kernel_size=3,
stride=2,
padding=1,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
self._down2 = SNConv(
name=name + "_down2",
in_channels=encode_dim * 2,
out_channels=encode_dim * 2,
kernel_size=3,
stride=2,
padding=1,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
self._down3 = SNConv(
name=name + "_down3",
in_channels=encode_dim * 2,
out_channels=encode_dim * 2,
kernel_size=3,
stride=2,
padding=1,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
self._down4 = SNConv(
name=name + "_down4",
in_channels=encode_dim * 2,
out_channels=encode_dim * 2,
kernel_size=3,
stride=2,
padding=1,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
self._up1 = SNConvTranspose(
name=name + "_up1",
in_channels=encode_dim * 2,
out_channels=encode_dim * 2,
kernel_size=3,
stride=2,
padding=1,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
self._up2 = SNConvTranspose(
name=name + "_up2",
in_channels=encode_dim * 4,
out_channels=encode_dim * 4,
kernel_size=3,
stride=2,
padding=1,
use_bias=use_bias,
norm_layer=norm_layer,
act=act,
act_attr=act_attr)
def forward(self, x):
output_dict = dict()
x = self._pad2d(x)
output_dict['in_conv'] = self._in_conv.forward(x)
output_dict['down1'] = self._down1.forward(output_dict['in_conv'])
output_dict['down2'] = self._down2.forward(output_dict['down1'])
output_dict['down3'] = self._down3.forward(output_dict['down2'])
output_dict['down4'] = self._down4.forward(output_dict['down3'])
output_dict['up1'] = self._up1.forward(output_dict['down4'])
output_dict['up2'] = self._up2.forward(
paddle.concat(
(output_dict['down3'], output_dict['up1']), axis=1))
output_dict['concat'] = paddle.concat(
(output_dict['down2'], output_dict['up2']), axis=1)
return output_dict

View File

@ -0,0 +1,150 @@
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import paddle
import paddle.nn as nn
import paddle.nn.functional as F
def normal_(x, mean=0., std=1.):
temp_value = paddle.normal(mean, std, shape=x.shape)
x.set_value(temp_value)
return x
class SpectralNorm(object):
def __init__(self, name='weight', n_power_iterations=1, dim=0, eps=1e-12):
self.name = name
self.dim = dim
if n_power_iterations <= 0:
raise ValueError('Expected n_power_iterations to be positive, but '
'got n_power_iterations={}'.format(
n_power_iterations))
self.n_power_iterations = n_power_iterations
self.eps = eps
def reshape_weight_to_matrix(self, weight):
weight_mat = weight
if self.dim != 0:
# transpose dim to front
weight_mat = weight_mat.transpose([
self.dim,
* [d for d in range(weight_mat.dim()) if d != self.dim]
])
height = weight_mat.shape[0]
return weight_mat.reshape([height, -1])
def compute_weight(self, module, do_power_iteration):
weight = getattr(module, self.name + '_orig')
u = getattr(module, self.name + '_u')
v = getattr(module, self.name + '_v')
weight_mat = self.reshape_weight_to_matrix(weight)
if do_power_iteration:
with paddle.no_grad():
for _ in range(self.n_power_iterations):
v.set_value(
F.normalize(
paddle.matmul(
weight_mat,
u,
transpose_x=True,
transpose_y=False),
axis=0,
epsilon=self.eps, ))
u.set_value(
F.normalize(
paddle.matmul(weight_mat, v),
axis=0,
epsilon=self.eps, ))
if self.n_power_iterations > 0:
u = u.clone()
v = v.clone()
sigma = paddle.dot(u, paddle.mv(weight_mat, v))
weight = weight / sigma
return weight
def remove(self, module):
with paddle.no_grad():
weight = self.compute_weight(module, do_power_iteration=False)
delattr(module, self.name)
delattr(module, self.name + '_u')
delattr(module, self.name + '_v')
delattr(module, self.name + '_orig')
module.add_parameter(self.name, weight.detach())
def __call__(self, module, inputs):
setattr(
module,
self.name,
self.compute_weight(
module, do_power_iteration=module.training))
@staticmethod
def apply(module, name, n_power_iterations, dim, eps):
for k, hook in module._forward_pre_hooks.items():
if isinstance(hook, SpectralNorm) and hook.name == name:
raise RuntimeError(
"Cannot register two spectral_norm hooks on "
"the same parameter {}".format(name))
fn = SpectralNorm(name, n_power_iterations, dim, eps)
weight = module._parameters[name]
with paddle.no_grad():
weight_mat = fn.reshape_weight_to_matrix(weight)
h, w = weight_mat.shape
# randomly initialize u and v
u = module.create_parameter([h])
u = normal_(u, 0., 1.)
v = module.create_parameter([w])
v = normal_(v, 0., 1.)
u = F.normalize(u, axis=0, epsilon=fn.eps)
v = F.normalize(v, axis=0, epsilon=fn.eps)
# delete fn.name form parameters, otherwise you can not set attribute
del module._parameters[fn.name]
module.add_parameter(fn.name + "_orig", weight)
# still need to assign weight back as fn.name because all sorts of
# things may assume that it exists, e.g., when initializing weights.
# However, we can't directly assign as it could be an Parameter and
# gets added as a parameter. Instead, we register weight * 1.0 as a plain
# attribute.
setattr(module, fn.name, weight * 1.0)
module.register_buffer(fn.name + "_u", u)
module.register_buffer(fn.name + "_v", v)
module.register_forward_pre_hook(fn)
return fn
def spectral_norm(module,
name='weight',
n_power_iterations=1,
eps=1e-12,
dim=None):
if dim is None:
if isinstance(module, (nn.Conv1DTranspose, nn.Conv2DTranspose,
nn.Conv3DTranspose, nn.Linear)):
dim = 1
else:
dim = 0
SpectralNorm.apply(module, name, n_power_iterations, dim, eps)
return module

View File

@ -0,0 +1,285 @@
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import paddle
import paddle.nn as nn
from arch.base_module import MiddleNet, ResBlock
from arch.encoder import Encoder
from arch.decoder import Decoder, DecoderUnet, SingleDecoder
from utils.load_params import load_dygraph_pretrain
from utils.logging import get_logger
class StyleTextRec(nn.Layer):
def __init__(self, config):
super(StyleTextRec, self).__init__()
self.logger = get_logger()
self.text_generator = TextGenerator(config["Predictor"][
"text_generator"])
self.bg_generator = BgGeneratorWithMask(config["Predictor"][
"bg_generator"])
self.fusion_generator = FusionGeneratorSimple(config["Predictor"][
"fusion_generator"])
bg_generator_pretrain = config["Predictor"]["bg_generator"]["pretrain"]
text_generator_pretrain = config["Predictor"]["text_generator"][
"pretrain"]
fusion_generator_pretrain = config["Predictor"]["fusion_generator"][
"pretrain"]
load_dygraph_pretrain(
self.bg_generator,
self.logger,
path=bg_generator_pretrain,
load_static_weights=False)
load_dygraph_pretrain(
self.text_generator,
self.logger,
path=text_generator_pretrain,
load_static_weights=False)
load_dygraph_pretrain(
self.fusion_generator,
self.logger,
path=fusion_generator_pretrain,
load_static_weights=False)
def forward(self, style_input, text_input):
text_gen_output = self.text_generator.forward(style_input, text_input)
fake_text = text_gen_output["fake_text"]
fake_sk = text_gen_output["fake_sk"]
bg_gen_output = self.bg_generator.forward(style_input)
bg_encode_feature = bg_gen_output["bg_encode_feature"]
bg_decode_feature1 = bg_gen_output["bg_decode_feature1"]
bg_decode_feature2 = bg_gen_output["bg_decode_feature2"]
fake_bg = bg_gen_output["fake_bg"]
fusion_gen_output = self.fusion_generator.forward(fake_text, fake_bg)
fake_fusion = fusion_gen_output["fake_fusion"]
return {
"fake_fusion": fake_fusion,
"fake_text": fake_text,
"fake_sk": fake_sk,
"fake_bg": fake_bg,
}
class TextGenerator(nn.Layer):
def __init__(self, config):
super(TextGenerator, self).__init__()
name = config["module_name"]
encode_dim = config["encode_dim"]
norm_layer = config["norm_layer"]
conv_block_dropout = config["conv_block_dropout"]
conv_block_num = config["conv_block_num"]
conv_block_dilation = config["conv_block_dilation"]
if norm_layer == "InstanceNorm2D":
use_bias = True
else:
use_bias = False
self.encoder_text = Encoder(
name=name + "_encoder_text",
in_channels=3,
encode_dim=encode_dim,
use_bias=use_bias,
norm_layer=norm_layer,
act="ReLU",
act_attr=None,
conv_block_dropout=conv_block_dropout,
conv_block_num=conv_block_num,
conv_block_dilation=conv_block_dilation)
self.encoder_style = Encoder(
name=name + "_encoder_style",
in_channels=3,
encode_dim=encode_dim,
use_bias=use_bias,
norm_layer=norm_layer,
act="ReLU",
act_attr=None,
conv_block_dropout=conv_block_dropout,
conv_block_num=conv_block_num,
conv_block_dilation=conv_block_dilation)
self.decoder_text = Decoder(
name=name + "_decoder_text",
encode_dim=encode_dim,
out_channels=int(encode_dim / 2),
use_bias=use_bias,
norm_layer=norm_layer,
act="ReLU",
act_attr=None,
conv_block_dropout=conv_block_dropout,
conv_block_num=conv_block_num,
conv_block_dilation=conv_block_dilation,
out_conv_act="Tanh",
out_conv_act_attr=None)
self.decoder_sk = Decoder(
name=name + "_decoder_sk",
encode_dim=encode_dim,
out_channels=1,
use_bias=use_bias,
norm_layer=norm_layer,
act="ReLU",
act_attr=None,
conv_block_dropout=conv_block_dropout,
conv_block_num=conv_block_num,
conv_block_dilation=conv_block_dilation,
out_conv_act="Sigmoid",
out_conv_act_attr=None)
self.middle = MiddleNet(
name=name + "_middle_net",
in_channels=int(encode_dim / 2) + 1,
mid_channels=encode_dim,
out_channels=3,
use_bias=use_bias)
def forward(self, style_input, text_input):
style_feature = self.encoder_style.forward(style_input)["res_blocks"]
text_feature = self.encoder_text.forward(text_input)["res_blocks"]
fake_c_temp = self.decoder_text.forward([text_feature,
style_feature])["out_conv"]
fake_sk = self.decoder_sk.forward([text_feature,
style_feature])["out_conv"]
fake_text = self.middle(paddle.concat((fake_c_temp, fake_sk), axis=1))
return {"fake_sk": fake_sk, "fake_text": fake_text}
class BgGeneratorWithMask(nn.Layer):
def __init__(self, config):
super(BgGeneratorWithMask, self).__init__()
name = config["module_name"]
encode_dim = config["encode_dim"]
norm_layer = config["norm_layer"]
conv_block_dropout = config["conv_block_dropout"]
conv_block_num = config["conv_block_num"]
conv_block_dilation = config["conv_block_dilation"]
self.output_factor = config.get("output_factor", 1.0)
if norm_layer == "InstanceNorm2D":
use_bias = True
else:
use_bias = False
self.encoder_bg = Encoder(
name=name + "_encoder_bg",
in_channels=3,
encode_dim=encode_dim,
use_bias=use_bias,
norm_layer=norm_layer,
act="ReLU",
act_attr=None,
conv_block_dropout=conv_block_dropout,
conv_block_num=conv_block_num,
conv_block_dilation=conv_block_dilation)
self.decoder_bg = SingleDecoder(
name=name + "_decoder_bg",
encode_dim=encode_dim,
out_channels=3,
use_bias=use_bias,
norm_layer=norm_layer,
act="ReLU",
act_attr=None,
conv_block_dropout=conv_block_dropout,
conv_block_num=conv_block_num,
conv_block_dilation=conv_block_dilation,
out_conv_act="Tanh",
out_conv_act_attr=None)
self.decoder_mask = Decoder(
name=name + "_decoder_mask",
encode_dim=encode_dim // 2,
out_channels=1,
use_bias=use_bias,
norm_layer=norm_layer,
act="ReLU",
act_attr=None,
conv_block_dropout=conv_block_dropout,
conv_block_num=conv_block_num,
conv_block_dilation=conv_block_dilation,
out_conv_act="Sigmoid",
out_conv_act_attr=None)
self.middle = MiddleNet(
name=name + "_middle_net",
in_channels=3 + 1,
mid_channels=encode_dim,
out_channels=3,
use_bias=use_bias)
def forward(self, style_input):
encode_bg_output = self.encoder_bg(style_input)
decode_bg_output = self.decoder_bg(encode_bg_output["res_blocks"],
encode_bg_output["down2"],
encode_bg_output["down1"])
fake_c_temp = decode_bg_output["out_conv"]
fake_bg_mask = self.decoder_mask.forward(encode_bg_output[
"res_blocks"])["out_conv"]
fake_bg = self.middle(
paddle.concat(
(fake_c_temp, fake_bg_mask), axis=1))
return {
"bg_encode_feature": encode_bg_output["res_blocks"],
"bg_decode_feature1": decode_bg_output["up1"],
"bg_decode_feature2": decode_bg_output["up2"],
"fake_bg": fake_bg,
"fake_bg_mask": fake_bg_mask,
}
class FusionGeneratorSimple(nn.Layer):
def __init__(self, config):
super(FusionGeneratorSimple, self).__init__()
name = config["module_name"]
encode_dim = config["encode_dim"]
norm_layer = config["norm_layer"]
conv_block_dropout = config["conv_block_dropout"]
conv_block_dilation = config["conv_block_dilation"]
if norm_layer == "InstanceNorm2D":
use_bias = True
else:
use_bias = False
self._conv = nn.Conv2D(
in_channels=6,
out_channels=encode_dim,
kernel_size=3,
stride=1,
padding=1,
groups=1,
weight_attr=paddle.ParamAttr(name=name + "_conv_weights"),
bias_attr=False)
self._res_block = ResBlock(
name="{}_conv_block".format(name),
channels=encode_dim,
norm_layer=norm_layer,
use_dropout=conv_block_dropout,
use_dilation=conv_block_dilation,
use_bias=use_bias)
self._reduce_conv = nn.Conv2D(
in_channels=encode_dim,
out_channels=3,
kernel_size=3,
stride=1,
padding=1,
groups=1,
weight_attr=paddle.ParamAttr(name=name + "_reduce_conv_weights"),
bias_attr=False)
def forward(self, fake_text, fake_bg):
fake_concat = paddle.concat((fake_text, fake_bg), axis=1)
fake_concat_tmp = self._conv(fake_concat)
output_res = self._res_block(fake_concat_tmp)
fake_fusion = self._reduce_conv(output_res)
return {"fake_fusion": fake_fusion}

View File

@ -0,0 +1,54 @@
Global:
output_num: 10
output_dir: output_data
use_gpu: false
image_height: 32
image_width: 320
TextDrawer:
fonts:
en: fonts/en_standard.ttf
ch: fonts/ch_standard.ttf
ko: fonts/ko_standard.ttf
Predictor:
method: StyleTextRecPredictor
algorithm: StyleTextRec
scale: 0.00392156862745098
mean:
- 0.5
- 0.5
- 0.5
std:
- 0.5
- 0.5
- 0.5
expand_result: false
bg_generator:
pretrain: style_text_models/bg_generator
module_name: bg_generator
generator_type: BgGeneratorWithMask
encode_dim: 64
norm_layer: null
conv_block_num: 4
conv_block_dropout: false
conv_block_dilation: true
output_factor: 1.05
text_generator:
pretrain: style_text_models/text_generator
module_name: text_generator
generator_type: TextGenerator
encode_dim: 64
norm_layer: InstanceNorm2D
conv_block_num: 4
conv_block_dropout: false
conv_block_dilation: true
fusion_generator:
pretrain: style_text_models/fusion_generator
module_name: fusion_generator
generator_type: FusionGeneratorSimple
encode_dim: 64
norm_layer: null
conv_block_num: 4
conv_block_dropout: false
conv_block_dilation: true
Writer:
method: SimpleWriter

View File

@ -0,0 +1,64 @@
Global:
output_num: 10
output_dir: output_data
use_gpu: false
image_height: 32
image_width: 320
standard_font: fonts/en_standard.ttf
TextDrawer:
fonts:
en: fonts/en_standard.ttf
ch: fonts/ch_standard.ttf
ko: fonts/ko_standard.ttf
StyleSampler:
method: DatasetSampler
image_home: examples
label_file: examples/image_list.txt
with_label: true
CorpusGenerator:
method: FileCorpus
language: ch
corpus_file: examples/corpus/example.txt
Predictor:
method: StyleTextRecPredictor
algorithm: StyleTextRec
scale: 0.00392156862745098
mean:
- 0.5
- 0.5
- 0.5
std:
- 0.5
- 0.5
- 0.5
expand_result: false
bg_generator:
pretrain: style_text_models/bg_generator
module_name: bg_generator
generator_type: BgGeneratorWithMask
encode_dim: 64
norm_layer: null
conv_block_num: 4
conv_block_dropout: false
conv_block_dilation: true
output_factor: 1.05
text_generator:
pretrain: style_text_models/text_generator
module_name: text_generator
generator_type: TextGenerator
encode_dim: 64
norm_layer: InstanceNorm2D
conv_block_num: 4
conv_block_dropout: false
conv_block_dilation: true
fusion_generator:
pretrain: style_text_models/fusion_generator
module_name: fusion_generator
generator_type: FusionGeneratorSimple
encode_dim: 64
norm_layer: null
conv_block_num: 4
conv_block_dropout: false
conv_block_dilation: true
Writer:
method: SimpleWriter

BIN
StyleText/doc/images/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

BIN
StyleText/doc/images/10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

BIN
StyleText/doc/images/11.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

BIN
StyleText/doc/images/12.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

BIN
StyleText/doc/images/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

BIN
StyleText/doc/images/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
StyleText/doc/images/4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Some files were not shown because too many files have changed in this diff Show More