From 03b965f0e22462c11245e16bc6464b7f865e4496 Mon Sep 17 00:00:00 2001 From: huaiyukeji Date: Sun, 17 Dec 2023 22:15:21 +0800 Subject: [PATCH 1/3] init --- .gitignore | 4 + IMG_1766.JPG | Bin 0 -> 219722 bytes LICENSE | 21 + README.md | 96 + .../jiyan_gt_challenge_demo-checkpoint.ipynb | 708 ++ ...\346\250\241\345\236\213-checkpoint.ipynb" | 225 + ...knet yolo-v3|cuda|cudnn|opencv|anaconda.md | 350 + doc/classifier_train_handbook.md | 108 + doc/detector_train_handbook.md | 177 + doc/jiyan_gt_challenge.md | 45 + doc/jiyan_gt_challenge_demo.ipynb | 711 ++ ...01\350\256\255\347\273\203\351\233\206.md" | 98 + ...347\224\250\346\250\241\345\236\213.ipynb" | 225 + hanzi_detection/.gitignore | 27 + hanzi_detection/LICENSE | 12 + hanzi_detection/LICENSE.fuck | 13 + hanzi_detection/LICENSE.gen | 91 + hanzi_detection/LICENSE.gpl | 674 ++ hanzi_detection/LICENSE.meta | 8 + hanzi_detection/LICENSE.mit | 22 + hanzi_detection/LICENSE.v1 | 13 + hanzi_detection/Makefile | 105 + hanzi_detection/README.md | 75 + hanzi_detection/examples/art.c | 59 + hanzi_detection/examples/attention.c | 459 + hanzi_detection/examples/captcha.c | 353 + hanzi_detection/examples/cifar.c | 251 + hanzi_detection/examples/classifier.c | 1098 +++ hanzi_detection/examples/coco.c | 357 + hanzi_detection/examples/darknet.c | 503 ++ .../examples/detector-scipy-opencv.py | 56 + hanzi_detection/examples/detector.c | 850 ++ hanzi_detection/examples/detector.py | 27 + hanzi_detection/examples/dice.c | 116 + hanzi_detection/examples/go.c | 1370 +++ hanzi_detection/examples/instance-segmenter.c | 267 + hanzi_detection/examples/lsd.c | 1378 +++ hanzi_detection/examples/nightmare.c | 414 + hanzi_detection/examples/regressor.c | 240 + hanzi_detection/examples/rnn.c | 542 ++ hanzi_detection/examples/rnn_vid.c | 208 + hanzi_detection/examples/segmenter.c | 255 + hanzi_detection/examples/super.c | 120 + hanzi_detection/examples/swag.c | 83 + hanzi_detection/examples/tag.c | 140 + hanzi_detection/examples/voxel.c | 161 + hanzi_detection/examples/writing.c | 144 + hanzi_detection/examples/yolo.c | 327 + .../0015673f726b2a1ddd43c1758553093b.txt | 4 + .../0030fbc156e567a2c34afe4495318e16.txt | 4 + .../0042d7d2797b26fcfc090e27678beedd.txt | 5 + .../0048a76678a29202cf03731f46af9c64.txt | 4 + .../00ce931e1afbaf47c62f6078e72014ce.txt | 4 + .../00de8e4044705679726aa5d933d67552.txt | 4 + .../00e8f9ff61bf4198ea528683f78be58c.txt | 5 + .../01349f81609688ead3f4922171a990f5.txt | 5 + .../018dd492b73e5858609dbf0f5488eb83.txt | 4 + .../01d165ec1170956fe61d09c4e6f622ed.txt | 4 + .../01ea835c546ad4d92f0f6b5c96433857.txt | 3 + .../024a5273d7b06566748bc3af0fd0a5e2.txt | 4 + .../024a9fcf3c6839003a16f6697b23eb41.txt | 5 + .../024d91a69f693c9f9e3261a11c7ddec3.txt | 4 + .../03135f6a3cec7f4e3399da4f3680aa67.txt | 4 + .../0375e570bedd2c1971f3209966f8a016.txt | 5 + .../03fb416e2ce8e109b230a1a5eef7f4e4.txt | 4 + .../0421f63e65b44b56c6cd6530680e5548.txt | 4 + .../04bc8a6657ead2cb0040495ee2449073.txt | 5 + .../04f36d827bf62ba22575845abd2cd686.txt | 3 + .../0535f8e873fb35d9908080cfca034c2a.txt | 5 + .../05baf0f3e50f888066fa7a5089fd9430.txt | 4 + .../05c0562027595fdbe6ea4865b2857d88.txt | 4 + .../0616cfeaf489be156925e7f72933ad16.txt | 5 + .../063a4a8ad72b7e35028c538ad6ca0054.txt | 4 + .../068991d2c91c4557fd3b62caa14ac42b.txt | 4 + .../06bb5442887985888d34813121e4e60f.txt | 4 + .../06c01c623ce3df90cfbcad78608b7e0b.txt | 4 + .../06f78cfea588d3ab81e31307cedb40f3.txt | 4 + .../07198db7bebe69fdf9123a8878e15fe0.txt | 4 + .../07e0a4d3d6d5d46bc18fc3f86fd8eccd.txt | 5 + .../0838e809552b0e7687dff54b7d86bf8d.txt | 4 + .../083996edc86518a47d0c162ad619dcca.txt | 4 + .../08565520e94a144d9e7724ed9faf6397.txt | 5 + .../08890d707663fddf9b508bf9974438d0.txt | 5 + .../088b1c0b5fa93a460c680481278f5247.txt | 5 + .../08a89aa6731e641e7412d3822060b42c.txt | 5 + .../092d2caa24368f56233612b6019b2cfe.txt | 5 + .../09aaae767c369d3dcb56095e80518ea9.txt | 4 + .../09ff8eeb96236d7d7c944c55cb65bf8e.txt | 4 + .../0a15af430229d19ba86493002a728d6b.txt | 5 + .../0a3fb252edf036d0befc7197abd7afc2.txt | 3 + .../0ac2879f54b40e477f004c5b575e3ae2.txt | 4 + .../0ac54a37fbb19e4d38a949b9d213db6f.txt | 4 + .../0ba19a1362f1827134c58420316639ce.txt | 4 + .../0bc9fc26ea8517f1ca84aaa20778d2be.txt | 4 + .../0bccf4ff604195e928da0f96ce17cb3d.txt | 4 + .../0bddb0e71ae5e10ac50af3998c82aa24.txt | 3 + .../0c9cecb6017cd048c027c5c00a3e005a.txt | 4 + .../0cbd494511dc9d3f08462aebb3f08a0e.txt | 5 + .../0d420d53d31ad18f63030453ee07df30.txt | 5 + .../0d50a0f54aec320e588a56d5e608ea3c.txt | 5 + .../0d7bff55519270e35592453080503caf.txt | 4 + .../0d93825688787383bdfc3928313e6317.txt | 4 + .../0dd2286d9b48b256cce0dc7f5e787a53.txt | 3 + .../0e4c55874ee43a24a1417bff7d4e3243.txt | 3 + .../0e7be3751e71b7d2e3a08e7d403339de.txt | 4 + .../0eb4748c9cddfef8e2b3b8d24a527213.txt | 5 + .../0f018811743efcc8abaa0291a55e9489.txt | 4 + .../0f2b0cff03a943ad3e77017a5f652d7e.txt | 5 + .../0f6f3b9381ed7c5e3300950b1de87d0a.txt | 4 + .../0f92c06c08a03be7d3cd7beaf2595a4a.txt | 5 + .../0fba588204945afbe73b4dda96f17c67.txt | 4 + .../0fbca2e637530cfe656a5afd6f93df1e.txt | 4 + .../0fd53c38ff13f0b5c21460a7e81da046.txt | 4 + .../10267c0ea85d17f4345f04a5f94a25c3.txt | 4 + .../102b99628f017bb3836cc370ac140a1c.txt | 4 + .../1057a07b83ba65107342a7356ee335ee.txt | 4 + .../1058037bf1fdf0ce15e141ca4a8c5130.txt | 4 + .../1089399d6818798ead8e206af6b93c64.txt | 4 + .../11708c6d46c68a498ed251b2a4b31661.txt | 4 + .../12a2dafccccdebfca7f9b6014a998908.txt | 4 + .../12c267146d5575e3daf0387b24d34757.txt | 4 + .../12e571e75e6807539e853f96362448bc.txt | 4 + .../131295e0302cbc98854b360ff1b440b4.txt | 4 + .../13367be1abe079551709c1d78d307b2c.txt | 4 + .../1338212e36abce3bec13a5f94f947041.txt | 4 + .../1339fab26e29b773cf6fad0a80be8af7.txt | 4 + .../139cdc6c1010890a7bd7e2fe33d653ac.txt | 3 + .../13af453e5931bc27b2c6d857db4734d1.txt | 3 + .../13ef50a6498949c46390239e9f389c6e.txt | 4 + .../1462ae1ff9710380029bb8085f0a09f5.txt | 4 + .../14a6f9165625b7ff823e06f3d337c3ce.txt | 4 + .../14c38cbce9c8f0dec58a4c2e80d6a64b.txt | 4 + .../155034b20152b8ee2b713117a6dc3fff.txt | 4 + .../1557d239ebbe9fc78408b86057ff31d3.txt | 4 + .../156cd8f615704a54fcbca2c78f455581.txt | 4 + .../15a3d1098204e3698244b0b1fe28ba4b.txt | 4 + .../15f562ab07b6729287fc291de5985c5d.txt | 4 + .../161a0941bfb4f401d4bd2ef02bfb1cc1.txt | 4 + .../161e73bf0edc5b668560c363ea9291e1.txt | 2 + .../1636430a6cd50dcdd4912dc80117450b.txt | 4 + .../164f00b8a34453467cbdf39d6f5ae05a.txt | 4 + .../1655730eaba36f88e24eef1f62ca06ba.txt | 5 + .../1656ec17e43048f7adf1a0bf14d2eb04.txt | 4 + .../16b9855ea43e138c1ea9f757b9541298.txt | 4 + .../16d63c91dad3b2fb7f587c0fbb10c4b9.txt | 4 + .../17e119c9c56a343e6bf1db39479eeaac.txt | 5 + .../17eb067409590d1d36eb775aecfde424.txt | 4 + .../17f183afbe5f16297c833295cb2d3385.txt | 5 + .../1816fd114e0a72c42d8646593985424e.txt | 5 + .../182e9412144c9c76e4db5d551f00c8ee.txt | 5 + .../185bf6065ea7e52a8790fb6fdb00a3fe.txt | 4 + .../18a19da15a777de664434709365248b9.txt | 4 + .../18d1c97cd1a9fa1151aef69e7a84650c.txt | 2 + .../18e2487614c8d4e42bb661894dc2710a.txt | 3 + .../192848b00b4aa9abae37328e3e3461b3.txt | 4 + .../19629e0ac4e90db1530ed27f7d3ea572.txt | 5 + .../198643733bbecb9983b9a9b6ba09d104.txt | 4 + .../1998e89be33f97aa321d40657779f1b8.txt | 5 + .../19a3ab4f6dd50bfa59bc273b9756e28c.txt | 5 + .../19b320409f359a5076ebf86b6db93f49.txt | 4 + .../1a334a887020bedfdf686212d6ee8fc9.txt | 5 + .../1a7c00fb964dcce4013ca613a4ecffb1.txt | 4 + .../1aa7a73ae4066c73c0171c2c0171120f.txt | 3 + .../1abbeb512eb0ee31e594286f7378483a.txt | 4 + .../1b328e79270431411a4105cc04766f81.txt | 5 + .../1b64dd87c266e3a1a3b8bc47ca7f8f9c.txt | 4 + .../1b96328cfd5161240b956c50db9da611.txt | 5 + .../1bac247e288ffc2f39b69afb5edd85d0.txt | 4 + .../1bc89cbb8478e47ea5f21dbe1b5aef2e.txt | 3 + .../1bcc2e765f3ec9325eb3e7f26a80efb9.txt | 4 + .../1c54362cc06c10affe0ad5dc391fc097.txt | 5 + .../1cecbc5941bb3f2fc7d77eb856c8174b.txt | 3 + .../1d1316acd36600691c3a3a469732ed3b.txt | 4 + .../1d30c3c97478102ffa4695269f1872bb.txt | 3 + .../1db380775a448eca6f6ca1b7e9cac997.txt | 3 + .../1db907ebd4ef8927e6129edd4bd51a79.txt | 5 + .../1de1a2db534fa54404d252a930d67791.txt | 4 + .../1e337714085bc8f81959ee583b2bac59.txt | 5 + .../1e43173fe41b7bedd6b0443c9f8f52c1.txt | 5 + .../1e54d43e51d4a8c7c681413cd8a010e9.txt | 5 + .../1ebeaad92c47ae8659221affb32c0c24.txt | 5 + .../1ec56554bd6d6a61921ffe4b3adf68a0.txt | 4 + .../1eee3dbb935848d69fa712136f58a52f.txt | 3 + .../1ef9d8c97f05081cde0d8817b337d2f0.txt | 5 + .../1f0e7c0ddd27073e1c3cd1ba51943e8b.txt | 5 + .../1f375507c30e04a415fe1430a2e348d3.txt | 4 + .../1f729d61063c58610385bc4736bbe328.txt | 2 + .../1f9e28171dc32f9f6b6b38864ab91544.txt | 5 + .../1fd9c3c35a0a8319c1840cefd43ebf59.txt | 4 + .../1fefe4293d23b1997764d240aa199bab.txt | 4 + .../203473aef6cb33fc75f1ec547a91a860.txt | 4 + .../2056f79ca3d5a6130d0cf4f0d8d5116d.txt | 4 + .../20688e29e9e30e36c1feaba958758cca.txt | 3 + .../20c6853fe3e50a43ebe1ac3b78d6bcb2.txt | 5 + .../20cb791f2fcca081fa86c3b05ae0d279.txt | 4 + .../2124e1eb90cd78a04d3e9de5c6a0ca56.txt | 4 + .../212b0e07e39b78f98abfdb543aa23233.txt | 4 + .../214a7fa290fb1d4e781d1a74d8304e1d.txt | 5 + .../22ca2fb7130874d362fa27f1fcd42a97.txt | 4 + .../230d9b2ba814cb55ea2ddfd262ac3f05.txt | 5 + .../23ad24f4ba9c49dcc0556d223244cfca.txt | 4 + .../23b763675fdcbcc8231a7331a5ee2054.txt | 4 + .../23b7bb244e75296aa9d3c9ce8909776f.txt | 4 + .../2405b94d92350980466907ad21b177fd.txt | 4 + .../243b73642e664939459c368e8b961eed.txt | 5 + .../2482b9ea7ec49ff82dfbdd25a165ac11.txt | 4 + .../24b31e4dc0ef9a1b7fb4982fa6fa1d67.txt | 2 + .../24c4675db1fc6ce5fef94865f8e8657f.txt | 5 + .../24c4e43259813c107e1880cef1259ae2.txt | 4 + .../24e532b00dbb22fbf8d3eb69d9c43fe2.txt | 3 + .../2528763dfb1415935b12345e46536883.txt | 5 + .../252c16abff5c2aa55d5f5649653cff6d.txt | 5 + .../252dc1039d55faf8f96f0d0522a87f68.txt | 4 + .../253c1cf9c37f194ff42dfd8d699f542b.txt | 4 + .../25442cd7d6867aa14a8b4f3e84fcd312.txt | 4 + .../2572489e8fbda978b69ad5701ac183ca.txt | 3 + .../25a8971dbaf318a9fafa771398d2bb27.txt | 4 + .../266ebc793a3a4f768f51843d30d928b4.txt | 3 + .../2692ad9b21167e92aeb5f680d04b2943.txt | 3 + .../26ab9ad844e0fb566acecc33a59d8f0c.txt | 4 + .../26c9b08fe3a222681c30e122d7100cfb.txt | 4 + .../26ff5049791fd2ca3b340179e8bd2f6e.txt | 4 + .../275824c44f2764e3dabc1aa394a63f5d.txt | 4 + .../27614a499cd42da30086c5fc04357495.txt | 3 + .../2785b56988566f9b40632aa4dd2639c0.txt | 4 + .../27cedc437426bbc65ea5eaf99a103f93.txt | 3 + .../27e4f1d606aa041331f837fc36d80303.txt | 3 + .../2802b54b9ce502a3d0223373ef29f9e5.txt | 5 + .../29217bf09348fc6672f31a2b0b75dddf.txt | 4 + .../29531f6ee4db068fef479ffe078d3407.txt | 4 + .../297e8f9878261738824b46a843101fad.txt | 4 + .../29e4037dfe177961578e61016abc238b.txt | 5 + .../2a11e5c25520dfbf4f7acfe8eeb17ac8.txt | 3 + .../2a12d8bad11354d42223677b019756f4.txt | 4 + .../2a51f4389143ab687afff1d2c48e11de.txt | 5 + .../2bc569ff922b5e5721ec56382c202a08.txt | 5 + .../2bf7d3943ea7c1c1f769454a0532b5cc.txt | 4 + .../2cd539a53507a68be0b187b78220b5ae.txt | 5 + .../2cf988cb3cbf0a33905d0eb8f22a4d10.txt | 3 + .../2cffbb67e88753b5ce9e76ad3ca8a02c.txt | 4 + .../2d6644ac20fc154f3f87991a7a72ff0b.txt | 4 + .../2d81f892b114e8411d2ccefdce810344.txt | 5 + .../2dd7ac714f6f2d23274b25426ba48c28.txt | 5 + .../2de05aac0bfe7d09d439bd446a987cba.txt | 5 + .../2e62bb50610ea90401f3f22af756bb90.txt | 4 + .../2e9c77df2fe9918c86b7dba5d8d4eb90.txt | 4 + .../2ed9136952126655cd5aed1eabe4b643.txt | 4 + .../2ef14dde986e023e3b29a9418ac383aa.txt | 5 + .../2f14336db03cb04a3a13672ec39d554e.txt | 4 + .../2f661a1ccc172fc4d93b34125e501b7c.txt | 5 + .../301bf216d9158e5e00cf733564fe8deb.txt | 4 + .../304884b9fb08dfed4f6d0ad3302dd481.txt | 4 + .../30734a8d96f16fc032fdae23abb125fd.txt | 4 + .../30c454de1091e2c8353031014f357d8a.txt | 4 + .../30ea0a988ada37d49ae0a3b625001a2b.txt | 5 + .../317fef1a77ccd76f488fd3d989d7277f.txt | 4 + .../31aff6c22410f62e6f81edda3c76bf37.txt | 3 + .../324cceb0ede63ea0451864b7374851ee.txt | 4 + .../32931cea51d456eb118d48ba251fd96c.txt | 3 + .../32bcb16a2ac96d8d06a951f68454547e.txt | 4 + .../3358ec54f4f2d54e20a1afea0444603b.txt | 5 + .../33aafbf05b7a45ae5fd4305bd6b71bfd.txt | 4 + .../33cc6dd020e9e87b38d6714ad48173b3.txt | 4 + .../33cc9a0a271a8969ce825a322d871eb0.txt | 4 + .../33f6fe0cc7349bc429d851070034b9c7.txt | 4 + .../34265621dc29035f2a6374aa4c0928cd.txt | 4 + .../344697d5ea9d8f7a88988a4c3c137e05.txt | 4 + .../34859f8d0b5daf546cd23ca7f8980bec.txt | 5 + .../34cfa27bda86ba353341d82e6e2d3e3a.txt | 4 + .../352087fdb9d79e15044d8cb56361b7f6.txt | 3 + .../354270d1b5c84e02c6d8f45bd34c9f93.txt | 5 + .../35433a835cefecc321f4bc6a9bc71adb.txt | 4 + .../358ab3e8a509856a29aaff4ff98a2da0.txt | 4 + .../35bb5dc037981ac228b323279a392f05.txt | 4 + .../3709202f37839ddfcac127e14830c031.txt | 4 + .../373ffa4e024d68f6718fef76d254c10a.txt | 4 + .../37af211faff08dd7fcee38778b23c3c0.txt | 4 + .../37e115a70165f9fb469417d674ed1159.txt | 4 + .../380171932c2c5d30c6a872fcc7cf4f70.txt | 3 + .../38141676ba07b3162e0880b7095690a7.txt | 5 + .../383c368d567ead936df453b31aafdf03.txt | 4 + .../38765786334f6ae590c67b304a89846e.txt | 4 + .../38e8a13e37e89e9f155709eeacc0e130.txt | 3 + .../3947f53dbe2dfa9f425ee519fbbb9627.txt | 4 + .../39572c8f0ee635b9582ebfc68867a583.txt | 5 + .../39998cd68c76b506594c31c94de6a4e2.txt | 4 + .../39a1abca7498e67aeefdf5ba470e5baf.txt | 5 + .../3a05ebbefa111e8abc5bfca916b29f0c.txt | 4 + .../3a4ddda1468ddf3bc421107a1151ec12.txt | 3 + .../3ac3c7892c28af27bdfa389f63348e40.txt | 4 + .../3ad248eb9a4b550fb9eeb6178eed85b7.txt | 5 + .../3b04e9d066ef9b9ab2e9513397872508.txt | 5 + .../3b0b2785db0720c42f788afeda444bf0.txt | 3 + .../3b28f8967114d50e7c790ae4e58bc138.txt | 3 + .../3b5b69512930da8394e1c516a89f7679.txt | 4 + .../3bb814bb367bf8b22e903e9a783255a8.txt | 4 + .../3c09cd0d477c5c818cbf337a4dce155f.txt | 3 + .../3c1535c54b706927a6b9c600ec82ac09.txt | 4 + .../3c559399b79d0d44f349620a953f400d.txt | 4 + .../3c89b85cf2566f5a97110e4f8ad1f9eb.txt | 4 + .../3d0bd114bd539dca3c37c802d2d2bb82.txt | 3 + .../3d21cf9a8ccbc2009bc9310467df503d.txt | 3 + .../3d2c231825835a7f33c3a8b9999b85da.txt | 2 + .../3d495703dfc8712ca625622618c39adb.txt | 4 + .../3d9c7eb149e5ef0c470fc5eeb3293e64.txt | 4 + .../3da2cb4374aeef3779f181b50c67deef.txt | 4 + .../3e5f116148bfbe30079ea83289b85d39.txt | 4 + .../3e6c5b9a345590ac8ed792f4a8f1f420.txt | 4 + .../3e9755e6718b502b3379a86938fef3f1.txt | 4 + .../3f0dfde55daeae85903abe53ec3829b9.txt | 4 + .../3f6d0954e7509c8b907de00979423cc6.txt | 4 + .../3f97dcb9dc399235558efc7b7e2a5e47.txt | 4 + .../3f9c37a1d0b4e008de2a527054730cab.txt | 5 + .../404fe4af760d2e7a22db64188004d17f.txt | 5 + .../40cf6cc0f27841b8e1b1126c05e94031.txt | 4 + .../41099fa89d0976dc14094190f9d81eae.txt | 4 + .../4127977ad3f5e5cbfabd7e1dd44c8b33.txt | 3 + .../4131f80c8c09c8d7010b0224adc9985b.txt | 5 + .../413f7048cfedefd240d754103f4c5795.txt | 4 + .../424894fb7373acd4163a2d8974573b1c.txt | 4 + .../4255a578c0c4adea9e877ea07a42651e.txt | 3 + .../42c85c6092ae84555be25554924f8ac0.txt | 4 + .../42e35b4e0a15c96f7603a71be92a0cf3.txt | 5 + .../43c1d9494197ea8b750b25dc79e5df92.txt | 3 + .../44250c2677e5f92e144996e809fbcd41.txt | 4 + .../449bcec9a6c92331dc76e27325c5e57a.txt | 4 + .../44ac74930cd0bdb395579fe7dbb11684.txt | 5 + .../453e3c641ffd8d9e18e8c97e35726e54.txt | 3 + .../45522e099c48a5b043cb2dfa33439f63.txt | 3 + .../45789d6753f3f127ea5dbca642664b2c.txt | 3 + .../4580f3f6bcb6ed28b79982c92ea5d7bf.txt | 3 + .../45e8630d55a70d218c92f37ad351c3af.txt | 5 + .../45e8ddd22bb30566d424faa33d6e38f2.txt | 4 + .../47011c9a66be34f7f7c1ce5dd056fa3f.txt | 4 + .../4785b7a059fa0e0e21eef81afa2136d9.txt | 3 + .../47f1d5fffa38b7f18e6c9fe93ab5582a.txt | 4 + .../4814204b196308a1b07525a125ca774d.txt | 3 + .../487d269d8cb04ac063193a340dd128f8.txt | 4 + .../487f2e24aa3452205edf6459aaabbbb2.txt | 5 + .../48837cb6ce0fb59876adb982b5052edd.txt | 4 + .../48c254260b982877992b4eeb61a81abf.txt | 4 + .../48e9362e6e4be312d32b38fcbd540fc9.txt | 4 + .../49c4a01e2945484086efdae0008935d8.txt | 5 + .../49c83cc7b12efaa4caa9bffbaef78e3b.txt | 4 + .../4be2851e1ea3829c81f55c701a2f0187.txt | 5 + .../4c010902a0a21d508521f55704315883.txt | 5 + .../4c83b69d15bd0519b0b71185f0bcc56d.txt | 4 + .../4c8e3b21d4e2473369fab4ded85c14bd.txt | 3 + .../4c93c736f37e12c9d376fd42dfdcc60b.txt | 4 + .../4ca2f7e6a71b78e101d3ddae7d362e85.txt | 5 + .../4d070ac638da477048122564e402a359.txt | 3 + .../4d6ac172e896a7dcb24729b528cd3765.txt | 3 + .../4dde8b597fa0a9989b91887e207e0411.txt | 5 + .../4de515d5e780a7859edabd14df82af32.txt | 4 + .../4e017520fd4be6a4c1dfb9f70f8c7511.txt | 4 + .../4e138cb90a8fec9e04c056c9363412d7.txt | 3 + .../4e15d77b96f5f26585cb164e11ced558.txt | 5 + .../4e1f4012fb8e1cea6e187486c880aa63.txt | 3 + .../4f00d944819bd9bd092ed77d596173b9.txt | 4 + .../4f667f12274be131d029491dad8a966e.txt | 3 + .../4f958ed2f5d448829002ac08bf9c17b3.txt | 5 + .../4ffc782b89c5dc232782abef5165c719.txt | 4 + .../504589663fb6dd5062daa143fcba1ff6.txt | 5 + .../50dcad12bd25596f0be4c14fbfa19cd9.txt | 4 + .../510e7af64cd053bb699ee49375095145.txt | 5 + .../514062c3edb164ab3948e4b1a0034dd1.txt | 5 + .../514b4e534abd39a0249f91a6e6582b1e.txt | 2 + .../51f7ecde3dbd025454e5e4790f1063a9.txt | 4 + .../52ce8d5066eecf62f2effa92b5d6e5c8.txt | 4 + .../52d2e885bcd02b78f5e1f354571a3165.txt | 5 + .../52f499a872019fb8e145504313059613.txt | 4 + .../53392c800ef29685aacc26d7f10c94c1.txt | 4 + .../53793eba05cf925b90660330b35f5815.txt | 3 + .../53b9f88af3390499559fcb880606f947.txt | 4 + .../53c27964917ae271a0b1fda1ae64609f.txt | 5 + .../53fe2e14274d4ac3fc8493d0682f5e71.txt | 4 + .../543f709458e1fc55d05426ade00a46ef.txt | 5 + .../548a1a221108ab5a7ff05518caab7781.txt | 3 + .../554f45f4c1990b8e7b165a751a29fc28.txt | 4 + .../5572755e5c6b811bf439f2fa3a3ec237.txt | 3 + .../55daede03319fc87bbb77803b3b2a285.txt | 4 + .../564066b109017931039158168f5bba4b.txt | 4 + .../5679c2443905cec1f43c9b2b69fd9efd.txt | 4 + .../5679d5cfa0558639c73d26e11a785f89.txt | 4 + .../56abd6bf3a77580e1f7434b396332b9c.txt | 5 + .../5727e0644de09dd82e0f9ff84ae29d00.txt | 5 + .../57929e766af28dad62c3b6577689af07.txt | 3 + .../579a94ce642e496008d77b2685059844.txt | 3 + .../57c18f8afa90c070e2c13cae889a068f.txt | 5 + .../581b98d8edfac3f24fc5208bc57b18fe.txt | 3 + .../582afbda17bac0514ac6d9f0aeee9145.txt | 4 + .../58ff00a62d7c69f0b5baeaf873efcc45.txt | 3 + .../5a304f6bcd90886702924b600c498fda.txt | 3 + .../5a925a430b7771ae04739a101e5db4c6.txt | 3 + .../5abef28ccb79b61c39e44bdaec2e8a9c.txt | 4 + .../5afcf9f6329d796897538eab444b65ee.txt | 4 + .../5bd50732b523fe3c8fd746a621056e05.txt | 2 + .../5c403659a8d135fc7c77649459bec86a.txt | 4 + .../5c79a45619326ae910ca749cba788f1e.txt | 4 + .../5c8113761dce030345c6ff1cf0c2fc65.txt | 4 + .../5cd4e48a1d7e81309ad024d7734d85a9.txt | 3 + .../5cd686f9fa9595f01516468e55b15495.txt | 4 + .../5cd74787a1abeb18be2616712a9a64f9.txt | 4 + .../5dc9d9c62c331354eb297145ccdcb11c.txt | 4 + .../5dde6a3854a3b65d2281ece59b1e97f4.txt | 4 + .../5decce76eab508af166d5cc42f40e701.txt | 5 + .../5f3a9aced738b75096c2c6fe31e3ab0a.txt | 3 + .../5ffe6679b079f25980b01de470757dbf.txt | 4 + .../60506a3bbfbf61973a9561404d9696a7.txt | 4 + .../606c176fcc677a75f5e9926e191f3cf2.txt | 4 + .../609db062cfb76cfe8d37d7a9fdde4526.txt | 5 + .../60bd548ee4b8d76d50822ab8abc37e2f.txt | 4 + .../612de7dddb72056d5295d3f5daa9a331.txt | 4 + .../614858730a1db249067581a0000d3eba.txt | 4 + .../614ebd6252861be15e74420e75bb87d9.txt | 4 + .../615c95ac02a3050083dd03213844c953.txt | 4 + .../6160431243ccd47e3c99710890816fe2.txt | 4 + .../61863761596832d6a3a5a572221c1c0a.txt | 4 + .../61ca751747d09316c5a5da4df72d9f75.txt | 4 + .../61d0ff7b49020dd380cf1946ecbd6460.txt | 4 + .../62098e3c2fdfa614e90b97793475c05a.txt | 5 + .../627d9e84c2050f1e63ad8b21dfe0aad4.txt | 4 + .../62c9a42a4ffc7ebc2e2da3f7da351ac5.txt | 4 + .../62cf881287600117953c63b739a2249f.txt | 4 + .../6316e194764d0919061f95ee95c24d52.txt | 3 + .../63350fd5fe8aa1bb577fce9f577bfd53.txt | 4 + .../63bb13a2d95eedb57d2c566f2df33173.txt | 3 + .../641cbee1c55bb852d9a76acbfaff0996.txt | 4 + .../6469e4239304a13274b0af6a2e6cb8be.txt | 4 + .../647f279d088b08e79ee57029ceddf366.txt | 3 + .../64f121f89408216490af015f122f5626.txt | 5 + .../6531967f2e93a316e85968ad011ab298.txt | 4 + .../654da3f9d5a6f3f8ebd4657cfb60e0fa.txt | 5 + .../65a205310ec88ecdc9b0e143987f8323.txt | 3 + .../65e1d36f8ade84826fe1a011a13db813.txt | 5 + .../66686038b549eb8ff43b82bd40232971.txt | 4 + .../669f3f863917812a5aad9467713035eb.txt | 4 + .../66f5727e00ab69c6ef495fa5762bd3ac.txt | 5 + .../671dcfa5790bce42ff42e7361adef981.txt | 4 + .../674cdcfc5e75d72e67a57b268cb2d7c8.txt | 5 + .../675960daaf242fc304acc42997f5f5e8.txt | 4 + .../6761d9a3692394a926b110231cc9faa1.txt | 2 + .../67cc2082f51c3493d37927b395d7857f.txt | 5 + .../67cc43fadd103cabd453ce0e781c613a.txt | 4 + .../67d8f80d5128e94afcd8e05c9d63b318.txt | 4 + .../68021589884976b211fea7a1b536746b.txt | 4 + .../6811c132f0c1fdb54289db99fb7f8466.txt | 4 + .../6814fd1f5a973d88ad8e18db290763fa.txt | 5 + .../685a00671ecc6674b52dab309f709a39.txt | 3 + .../685fbde97e162e8e898316a0ca5eb1ea.txt | 5 + .../6874e45cafb16e88a3f184673284ea5e.txt | 3 + .../689e03d98c9ada4ea288165a9ccae310.txt | 4 + .../68c20ca22679dd2e57a12461c69872aa.txt | 4 + .../6a256b4463c2bfc2d41be1ffc23630c1.txt | 4 + .../6ae427c6254f66fc62732edc6ddc1ace.txt | 4 + .../6b5c01d5529e03f00b956735300e43b6.txt | 5 + .../6b8156e47350f0706fe6e62cd6bffcff.txt | 5 + .../6bad8bc610e01619ee550b2955ba8ad7.txt | 5 + .../6bfae2cb6f4bd0a25c84cd1b4873b90d.txt | 5 + .../6ccc2daae37222aaf0735232c9ccf397.txt | 5 + .../6d0bbede8f34a0d2964de8f6103276b5.txt | 5 + .../6d52ce280a29a63de6c9075a433b35b9.txt | 4 + .../6d8fa2539a2ef1645a8c701182dedd0a.txt | 5 + .../6f1725e81669f9305a3439151ef72f8c.txt | 2 + .../6f223bc6b316b0b23092440555a896fa.txt | 4 + .../6f6c2db4d2ce36081ac59018fbd038f3.txt | 4 + .../6f9ddbf3c152d3883f97d49209103a28.txt | 3 + .../6faed00d4e3c1920e974a95a269c6849.txt | 4 + .../6fb30e63335e1f7bac4ffdf25b3e1755.txt | 4 + .../6ff25b93f67c0e1ad048553fe613cb90.txt | 3 + .../706210c7ac57c921f111e72f880eba05.txt | 4 + .../70802160fb371dabcbb4bb1337a5f961.txt | 4 + .../71174b75dec785c7788664f7e55489b3.txt | 5 + .../7134f47548c2b955351652ff5645afa0.txt | 4 + .../71d08cef5ef7e0f411e76c72374323f2.txt | 4 + .../72026cff158522b81511ec70dcdf4aa0.txt | 5 + .../72836c22972e722dac846a1335740981.txt | 5 + .../72cc72e4557a4e81cf22abc1c528736b.txt | 4 + .../732aff09bd2c2cd1d0819518db9d0350.txt | 5 + .../73441b2ac1f58597e7ab1b53e17f13b6.txt | 3 + .../73aa55f4cd9bcfb421deb1af301ffc21.txt | 5 + .../73cba4855d73187819c25cf87099a594.txt | 3 + .../7415d41effa5df58627bd735635d4218.txt | 4 + .../741f932ae86107ee315fbdb88bfa6a0d.txt | 5 + .../7507925f7256682ed6aaea4c2d2aca10.txt | 4 + .../7512c7cd273ab4222c4271c553c9abc7.txt | 3 + .../7558d6ecd55b8cfa8c735d006368acbf.txt | 3 + .../757b85c3f6201ca3cd2fe354f27b3c3d.txt | 4 + .../759531a2d64ac993772dab9c346f9b43.txt | 4 + .../75f79b51486951278990668460cef32b.txt | 5 + .../76235edd4142671e43e1eb29f69d3554.txt | 5 + .../7653741a4131b7ef6209fc437ae56964.txt | 4 + .../767b2849dd02b721e2025bd9665cd08e.txt | 4 + .../768e06591d853849afafee9dd970df4e.txt | 4 + .../768fcfee15a5acbc6deabcb1741d283a.txt | 4 + .../76aa4f48dfc92400900361b27ce458a2.txt | 5 + .../775446ae1ae0487f41edf9102969aede.txt | 4 + .../7758166810159b5fc089bb8763925d4e.txt | 4 + .../77eba7306c042aa7b2693e432834a6f6.txt | 4 + .../78365d652a587dcef8698b8b4f6aab68.txt | 4 + .../789f90be8c819a3e1f7cc73ff4ee54d0.txt | 4 + .../78c4e10d7042750e25a0df8dab2a4f77.txt | 4 + .../792bceff46c5343c4927e09c984c9a07.txt | 4 + .../79ef570dd5d7ed7eb257f489c333ee2a.txt | 4 + .../7a6076274dc0ffa021d5ceed99d2705b.txt | 4 + .../7a8141295a15a0d2c16117a359d7ea87.txt | 4 + .../7b3eec52b87c51b8587ce68e77c65428.txt | 5 + .../7b484005392e1185cd9942f0f1ee32d4.txt | 5 + .../7b816e5ef036f986eb27e74e88588e67.txt | 4 + .../7baeafd04b96b5bb5f8c4905a0276f28.txt | 4 + .../7beb94930af6c2c3d922b6886f1785b2.txt | 5 + .../7bf9c0312e56614367ed476ab26fdfe0.txt | 4 + .../7c15d51dd9459b70b6986576e00a35ba.txt | 5 + .../7c2f257420c98a77608f3546e2d4e42b.txt | 4 + .../7c4bfea85556d58cafe707b639044c21.txt | 4 + .../7c726d2505d5d202db8107a3e7d214f7.txt | 5 + .../7c7c9a078033ab1200e8f5538da60604.txt | 4 + .../7cbc1e10898652b59115dddc9beec11d.txt | 5 + .../7cfde6ebf9eec8a96243199d81d90978.txt | 4 + .../7d0702e464105b4cec37e157eb019f72.txt | 4 + .../7d2b68cafe16cdd220b703eaa11c045a.txt | 4 + .../7d7ee2f85103ef65dfc74ecec42135f7.txt | 4 + .../7d85c83c09fa5d41f0e75e53fbb034fe.txt | 4 + .../7d9097329ae92c57796325322a926af8.txt | 4 + .../7e119a08bbd67f2a15cd2b58d30cb9f1.txt | 3 + .../7e60fd470b78624fc0575ba9754e3c45.txt | 3 + .../7e893ae3a6c6e47235b86f85d8e56bc3.txt | 4 + .../7e8e2b60ce201607bb7016d56d1fb4f8.txt | 5 + .../7e9a0961535e3804022f1ee6d5e2a436.txt | 4 + .../7ea6b24a19e30ea712147ea82ca375f9.txt | 4 + .../7eab038fb6a9b2a516fa43d19c3e114f.txt | 4 + .../7ee89ab02954a8b62efb3b8ab560a603.txt | 5 + .../7f0d0c08702801cb4c2c36d71e494ee2.txt | 4 + .../7f950692da36b446ee8e3bfb9b7bf34c.txt | 4 + .../7fc6c0a4d7fc53ecda70eb3ff5d655a8.txt | 4 + .../807a237f14859821ced70c98a08ba231.txt | 4 + .../80d888e66f661473ce0a4583cb0c3e97.txt | 5 + .../814613e0ac5d67cd9f9fdce55c8ec0d4.txt | 5 + .../816ab02d5092e43d35754dd87997967b.txt | 4 + .../816ba6108358498c381c6a697b15fe99.txt | 5 + .../819b61a21f99e6ddb7b249e1468e2c7c.txt | 4 + .../819fb3068bf1dbbc6c9b62d9a6802700.txt | 4 + .../82531ad88eac23be3c89801a6be66fdc.txt | 4 + .../829540032c7152c607fd4a1d16ae497a.txt | 3 + .../83626424d2bc3065e66eb4fb0298b60a.txt | 5 + .../841b6aedaab5148e1fa1f00a3ef6d760.txt | 4 + .../8431ae708a8ea4a39780a61a3d1920f3.txt | 5 + .../844360515e72f5309e4646d0c2fd1af3.txt | 3 + .../84563c5fe1937ff4e3c443c387be2519.txt | 3 + .../8461e90ae88f7ffd7221df75ff3632e1.txt | 3 + .../8525ea80a0ddcfabc3d5d2a2d1f7f4fe.txt | 4 + .../8546938654dcc948343c8887bdae97f6.txt | 4 + .../855b46a37a8e7a2981b0214bbcbb26d6.txt | 3 + .../85a622ab119518199a9fbcad4b85849a.txt | 3 + .../85a87be26b73191ae881543d8f5bd12c.txt | 4 + .../85dfaadf855933693738def81442c090.txt | 5 + .../8666d150ab4b46ade2ed09fd5948f624.txt | 5 + .../8676e9276e7ad1e688eb7fcc2bfc48b7.txt | 4 + .../86973ee052966ffce0ccf1a0a324585a.txt | 5 + .../86a9f4a069ab2fd1fc70a67556d28e50.txt | 4 + .../86cabdc3564921a02ea6c430ffcb3e61.txt | 5 + .../86cbadafab7cc34a9b23181507d720eb.txt | 5 + .../870780cca5d71b362695166e90e0fa29.txt | 5 + .../87230572cabd7f7cc731ddbd5f05cc19.txt | 5 + .../8736405022503e64c12ebd5e5c8f1b03.txt | 3 + .../874c14f81060497417ac949eaf19794f.txt | 4 + .../875c4a110234095486828834b0203b33.txt | 3 + .../875f2eb24f01a380e58f4a3f89115468.txt | 4 + .../878ce89141988cae8a469ef16c04aa0f.txt | 5 + .../880d7342370f7a03b57e9b3b52b3f74f.txt | 5 + .../885a0329f7b7e835c42f60476d4d8f10.txt | 4 + .../886ccb8a6bbcda450f889ab0f690c1c2.txt | 4 + .../8888f6cdc1120161964a6200de3c6809.txt | 4 + .../88ce36b0ccc7e1820c4c17c580d352ff.txt | 4 + .../89033239c7d547e5aa8410e09011134c.txt | 4 + .../890902ded3e227cf4a3f724aedd7aad5.txt | 2 + .../891d42e635294e5cad8dc8d008337db3.txt | 4 + .../891dbbbed3c2d0c197f71b0656f186c7.txt | 4 + .../89276d62d6f90ddfe13e8245115c7faa.txt | 4 + .../89a952ae9456c577b25ab8ce86f9b127.txt | 4 + .../89d595f80f108db3dd567a0467c3d88c.txt | 4 + .../89f5de3b9ca0a34a978ca34ec7d87984.txt | 3 + .../8a4f82bedea3fbb3acc230df7db97a45.txt | 4 + .../8a9a7b77de49a07e58174c8c323840fe.txt | 4 + .../8ad2c75e04c0a31b6efc9c4c73cce91e.txt | 3 + .../8ad723cb07f038c69451b25205c9cc81.txt | 5 + .../8b0ebee39a1bab46c59e9d64f9070352.txt | 3 + .../8bdcd29e44362431dcc99d3408686f24.txt | 4 + .../8c46a9c71bfe05333f8722f1daffd655.txt | 4 + .../8c5f4578d3c3aba5d3ff56bc85d5fd7d.txt | 5 + .../8ce0eaa8ced7a0fedc8ba3f7c617afd9.txt | 5 + .../8cece25086fce7e18417b586928cd678.txt | 4 + .../8d121244a22346cbf3f1f66c9e39b3e9.txt | 4 + .../8d2b1d6a62ac697a438255bd8f592278.txt | 4 + .../8e36bc2c5a0f8f265b48477b305b6a65.txt | 4 + .../8e598176aed7b7d1ef9ee2ee97c6313c.txt | 4 + .../8e8f50e29b22be7a9e57492dcf64b08a.txt | 3 + .../8f119bfbf2f0180405939f6b15fc9101.txt | 4 + .../8f1c87fc30fde6c850e14942621797e7.txt | 4 + .../8f4536d37e41ef35d57d386b6ec21f00.txt | 3 + .../8f6119695d73c3dd763b856ea399cac1.txt | 5 + .../8f6bb4abc2e8d4f5743e3475b095f866.txt | 4 + .../8f8f44e8967a0361c0e9a331e308bf9c.txt | 3 + .../8f9a20148094ef5b65e07936803831d7.txt | 3 + .../8fa5aa8ea22070d7cb1d55e23aae9184.txt | 5 + .../90397cf9d5a60d158d139c458162e4ee.txt | 4 + .../90e1b3f232acb9332b2c7f10ce3c87af.txt | 4 + .../91b9f129de7a430de4125136fa577b7b.txt | 4 + .../9285f113bb1c93841f0aa339b2a97497.txt | 3 + .../92d2733e159d0c348452b92d5edc50c6.txt | 3 + .../932e8588ca7b1c8bbd649abc3a374119.txt | 4 + .../935d66a51028b14e51839dfe133d4d36.txt | 4 + .../9361a0552be8ca021465b5d0fefef83a.txt | 3 + .../93c99695327cac738efbc1711ba8546f.txt | 3 + .../9468038a7d7e411f416cc27b84bf1598.txt | 3 + .../949f402eae7c2e3efd72a2d78a773849.txt | 4 + .../94a7b31d3a962fa9e2037659aba91eb1.txt | 3 + .../94b50768c69af3f3236d8d60e493e88c.txt | 4 + .../950f2041abd8569848e5229eaa92f42a.txt | 5 + .../953a44f985bc9ea38ddca4cdc71b76ed.txt | 4 + .../95a05e377d4a97bfd20aed87d987871e.txt | 4 + .../96919433ed7bcc4951847a9e2599d005.txt | 4 + .../9717485c255ec2689f5774c5434fe07b.txt | 4 + .../978f6bf7b09be180c9fcf9a14e4286ac.txt | 4 + .../97b91816db30b87582cc0fa687b0a249.txt | 4 + .../97ba02a27c83f4d4e746a7ae547c30da.txt | 4 + .../97c1d5b2c30f10b94179c9798881d634.txt | 4 + .../97e0730901729fa04d92bf38badbb678.txt | 5 + .../98524e97400db3d5cec8d815615e8ecc.txt | 4 + .../98b219b75cb72c27367677fd23b38f05.txt | 4 + .../98ca5251916504dec58abde2e3c502e6.txt | 4 + .../99bfea652214a6a41b74106f9dedd3a5.txt | 4 + .../99e45f9544b53f4e31f711518c2841e7.txt | 5 + .../99ec5f725326327ed8034925522d941e.txt | 4 + .../99eff4f19cfd6f1a75aaa834aa8ead8a.txt | 3 + .../99f53490264348c56c275acca0fc2adf.txt | 4 + .../9a79b11711d54dcd262eb0c777e8b7dd.txt | 4 + .../9a93361aaf6a7612454502e9b7b071a7.txt | 4 + .../9ad5a22c7c6ed587c9bec18e32075604.txt | 3 + .../9aefe57a6886c4c63b2dcfb25bc628b6.txt | 5 + .../9b0526a52d458eb2d80a7a58f6a9da8b.txt | 5 + .../9b193fb82af1fef76d2705e993ccce18.txt | 4 + .../9b2fb0d294f38aa22e8a94567195fed2.txt | 3 + .../9b7bf2e1ee9b6c6f8520c5841617d491.txt | 5 + .../9b7d9f137c885f5a0c697c7b81138347.txt | 5 + .../9bbc7d2d06425082472330d97296985c.txt | 5 + .../9c08c7848349823dffbf16ac1dd7fde2.txt | 5 + .../9c4a9ffd665f6d4eaf7a6a8ed0a55914.txt | 3 + .../9c60cb4cbab7836c200707f43bb44051.txt | 4 + .../9c784afe281faed6446cead9999468fe.txt | 5 + .../9c7e324db2f6923088e1428a5bfc1853.txt | 4 + .../9c8ae58463757708733c1377972765d1.txt | 4 + .../9c8d0ab038cf5908de0adad379438871.txt | 5 + .../9cd94333961738671eb031f231f82682.txt | 4 + .../9cfadf14d721875a86a0a3b96663be99.txt | 4 + .../9d4a73d1872dd017871d75c634ef735a.txt | 5 + .../9d5e6b6c7741e8f00d87ee67c643b04b.txt | 4 + .../9dbda62a725307cab594a22c41318024.txt | 4 + .../9e5e1d609b4b142a2fb588936ad39f05.txt | 4 + .../9e819206363a80c61175f1e39b39d603.txt | 4 + .../9efbc80a2ba6c3a256ae5bdd2677e147.txt | 3 + .../9f191a293528f170b2fddc35889a3460.txt | 3 + .../9f74e1e54c89d47ad93084ce1951258d.txt | 5 + .../9f987287209598d5c53893415d99912e.txt | 5 + .../a074eccd420a1d404b7220f4dd0c0628.txt | 4 + .../a150b5e884cbc0fca16af4dad96c26a3.txt | 3 + .../a1e783dc063fd3d116ee9b15d7b79b97.txt | 4 + .../a1e91b083a1f5ee6b7c743cfebacd750.txt | 3 + .../a1f7779bf16bf476c5c66672c33c7704.txt | 4 + .../a23af315d9cef507348c491f99cc3fb0.txt | 5 + .../a23c75b1b09039db0be1664aeee60ad0.txt | 4 + .../a257fe1660b3c2e7e225ceb7ea9df189.txt | 4 + .../a25e24900003730789465e978092520d.txt | 2 + .../a25e346167348694e3c2417d3b40f424.txt | 5 + .../a26dd757bda550ce54818a97af8f2b59.txt | 5 + .../a28e4a9541313bc27eb2c9058482d5e2.txt | 5 + .../a29560b4f90a3245e0ec054145809d47.txt | 5 + .../a2ac554fd0db3a5255a2ba1b97d801d7.txt | 4 + .../a2d39626b8795dc30e45b137fad78c02.txt | 4 + .../a31b10db33637e83d61d6c3bd4d2402e.txt | 5 + .../a3929123e598daa1f7e5f3900bdd31b3.txt | 5 + .../a3a8358e74acd7bf24b72a7e235c6ded.txt | 5 + .../a3ccab85e1d389eb6d635159f3adf06a.txt | 4 + .../a441b1b8061d039a90072ef9af820d14.txt | 2 + .../a44d6d0bd3d836d56e9c1eb8fe83ca83.txt | 5 + .../a484f6ee5d37eaa55aad1b1be8051d44.txt | 4 + .../a48bcefc7c3b54bc773fa9f7ab6abb7e.txt | 5 + .../a4f8c3b10d92497b501c1e9afa388421.txt | 4 + .../a582a728879d60893bcd31db885fce59.txt | 3 + .../a5c14915cf7fadd6bc4fd1a818d02a01.txt | 4 + .../a5fa2a57512b0e221d1b8f998a48454f.txt | 4 + .../a5fb894586afc629fcf3e8e806465daa.txt | 4 + .../a645e9b584f91c1b25bfdd44b1a1207c.txt | 3 + .../a73988c400f0f2ad4e51db239375ef30.txt | 5 + .../a7dbdfce74f20e69174bc2c77ff68b32.txt | 4 + .../a7f87cb1e96db0e16470b46b880b1c43.txt | 4 + .../a81c5093b057649726ec484351986fb7.txt | 5 + .../a8a38c2fa56faba0a9d526b857592aed.txt | 4 + .../a8b96cff8494ff3fad291751bd814c63.txt | 4 + .../a953f0291889f76911f8d7af7e8f00c0.txt | 4 + .../a98a8a3c4c6888719543ebdb14ad6763.txt | 4 + .../a9be83d24ee39185a8be2e44b62bd1b8.txt | 4 + .../aa0adc592954ac28e1394a341641c57b.txt | 4 + .../aa24b73a63d917835adfa87f802aef47.txt | 3 + .../aa53c93fa15412f2dd49652d49f2cb0f.txt | 4 + .../aa611d42127919301e3a4b81254e9d02.txt | 4 + .../aa792f1df61b084cbfbc612220b45c3b.txt | 4 + .../aadc37aef54962f2a7bb83ce41fc6a63.txt | 4 + .../ab20a003ffc7654bb720fbc672a39320.txt | 3 + .../ab20f82cf3fb2075507ceeeaac2d5cb6.txt | 4 + .../ab3c57d484ab0c8bca208a0d655c2e5b.txt | 5 + .../ab622579e4dc104cd8f90dc0027b6835.txt | 4 + .../ab780283f6bee797dabab0c67e596281.txt | 4 + .../ab89b794693e3535e0b58539ec1669d7.txt | 3 + .../ab9a8dcdda85f1d8789909803374fbea.txt | 4 + .../aba5bec4daa6c11fdd684594778e7737.txt | 4 + .../ac0dbaf22bdb140be1a11c068f9698de.txt | 4 + .../ac87279344b5d0d4e22f91b8c2ff41a8.txt | 4 + .../ad0138de5d88eb8dd7a7aab27947e539.txt | 4 + .../ad40d44fea1e8518be56c72565cbcd59.txt | 3 + .../add9a062cdb133e09ee686522d92f3c2.txt | 4 + .../ae13d3d287f61c40edb3ea2655d18ae4.txt | 5 + .../af22ae4d9de1488b00816e6693c6394e.txt | 4 + .../af3cdb723d7e28f0fb254165ba71d8b3.txt | 4 + .../af5f90b0517ff108a2c089b6e8c183e9.txt | 4 + .../af6d91402bf5bd9d18fbb5f080497ff8.txt | 4 + .../af7e05ca9dc6e26118059bbc83f15ee2.txt | 4 + .../afa66ae9a5d448ec2a2e1239026068a3.txt | 5 + .../b021c58e2f70a81cadaae120a4ac0b09.txt | 4 + .../b02782fbd52d87eab17fe5c24b326e92.txt | 4 + .../b07b099229ce0784c0a985b8a1d9c7e9.txt | 4 + .../b0c550e74255ed71c185b5c9c38f905f.txt | 5 + .../b0cb4774fb649ad7cf42a61b1c88a9a3.txt | 4 + .../b0db77aded4316b21d7f9d750b7d23fe.txt | 5 + .../b0ebc621829225814b6e2e16457842dc.txt | 3 + .../b1155e20b40430932a78807d5d6f28ed.txt | 4 + .../b17c3f2aec5ee198f8eb82e36606795a.txt | 3 + .../b21d921a6fe1ed762f066af97b77e37e.txt | 4 + .../b22ce1f95bb82dc2bf0b7de7d26eef1e.txt | 3 + .../b285a431eee55f896eece1af7fae362b.txt | 4 + .../b2c76e9c0889c683ba9800aa6431e17e.txt | 4 + .../b2e333e8efafafffc1056cd478f6a93b.txt | 4 + .../b2f36402178696779cbd5ae767761aca.txt | 4 + .../b313d4445189b53f759366aa8cc290c1.txt | 5 + .../b33ba39bf871947275cc51c40e312f39.txt | 4 + .../b3ed2f6e000821a26cefe6b480784c9b.txt | 5 + .../b46e47020634c7480bd802fa7c65080b.txt | 3 + .../b4c7cdb390fcf56407db19fec22bca8d.txt | 3 + .../b4cae86b47a05979be465c64300ac09e.txt | 4 + .../b518851c1217f7d4a074df1a43fdb82f.txt | 4 + .../b59366c05f0725f5eaaa0e87abc9b329.txt | 5 + .../b5c1a37feeb665781b937a84bb0389a1.txt | 5 + .../b5dcc36c30f6e4c6070a805973bb9770.txt | 5 + .../b61e121949adb85ef4f86bd3f050eb5a.txt | 4 + .../b66c6447d452f9b13cc50cb0f8c03636.txt | 5 + .../b694866d63fb09d8a512c9179126e28e.txt | 4 + .../b699a9ce2c12fcd1a06b80a34ce477e5.txt | 4 + .../b6b7c45763ffaff491fd4137f940602b.txt | 5 + .../b6b9625dcb895b6dedcaa1a65d5589a1.txt | 3 + .../b6bd0b66e0d14e44e3cd0fd48cdf37fb.txt | 4 + .../b6c214cc24e8f014c0074b2460cf8c4d.txt | 4 + .../b70ba7a811a4a34a04aca8acc9ab6e04.txt | 5 + .../b715a54323e31072a4f61fe0a7c590b5.txt | 4 + .../b725b0f15c9e35827b939d571f3cc4cf.txt | 4 + .../b755aacaa2cc98b607fa1324e9bfe7a8.txt | 2 + .../b844017030d28071aac4d16e94dac7b7.txt | 4 + .../b8512bcde0bd03f388666d453199912d.txt | 4 + .../b8806f0c9e5c5ca93fc549edf2493f63.txt | 5 + .../b899d82377c5a9648da29177d541e451.txt | 4 + .../b8bfe236cb667466794b7ba4e7c5ff26.txt | 4 + .../b8d38ca35d7b4556fa28dc08ace88a52.txt | 3 + .../b91179459dce704eacd8e56d47d4cd35.txt | 4 + .../b93a9f8a93cb56dd057eca621f377e39.txt | 4 + .../b97ff6246886a6d310f6547b054871a6.txt | 5 + .../b998e5ec5c52dc0a189d0c13e39735d5.txt | 4 + .../b9a45fa17c93ae5367db8f88a3b4b78e.txt | 5 + .../b9b19de7ac9e3f0aff0fb1b0c4879140.txt | 4 + .../ba61cdbe4e7a38a43a5d2256d18d9870.txt | 4 + .../ba8d0b375448ea588b520eccb6dd0d74.txt | 3 + .../baba6733f7ae96945cee14f6842b230c.txt | 4 + .../bacf33b57426360043832fc29d64e186.txt | 4 + .../bb07b0ab437edef64a9d7f69e7b063f9.txt | 5 + .../bb1a3899de55a61ad453b19ed3649ca1.txt | 3 + .../bbb47f9068532c006e71213011bd9f17.txt | 4 + .../bc16f9c82b95c22ca419a9f55f7a4b15.txt | 3 + .../bc531fca43eba674a8760b3042138cd5.txt | 4 + .../bc61071b0b4d28a95323d661da61b21d.txt | 5 + .../bc8a2e588cfc24e47f152bad38a47ee8.txt | 4 + .../bcbff27987e033a77bdff4adde10d377.txt | 4 + .../bd1fec8e38800e69e7ee0f036bc63c70.txt | 4 + .../bd738a5603e87873df7ffd3dbe6ac8da.txt | 4 + .../bd79800b60920e5af161c9d59d1b6b1d.txt | 4 + .../bdd6eafea84a93540a5071822b121202.txt | 5 + .../be55a1c87bf1113731f813cf4d9ee505.txt | 4 + .../be60746abb5738d62705f2d83ef94c28.txt | 3 + .../bf1bd13cadb47854d58011eb951f09a8.txt | 4 + .../bf3d15455b55b06f73e30fa8e7e74eb8.txt | 5 + .../bfb2b5cfa25f54dad21b1e622667b82f.txt | 2 + .../bfb848fe4c0383bb780a3d463cf7a55c.txt | 4 + .../c01d1b790183f1317221ed5ac419b22b.txt | 5 + .../c01fb35b68ee14941f5fef510fd245b4.txt | 5 + .../c01fd6ee1f631cd746a981cc5a56631c.txt | 5 + .../c122f206d967b08f4bb4a7aefb7d566e.txt | 3 + .../c1f4a45ee5e1f363d12e03f66c2c2ef3.txt | 4 + .../c218dc86cb609e450e5e0b3e2735bc37.txt | 5 + .../c27180332a1e1390501a20a336afd0d7.txt | 5 + .../c298f9d8f0b021fe164c27607aa690df.txt | 4 + .../c2af5b57f6e8e503dc2d7925fefa51ee.txt | 5 + .../c2e7b880f0f6a45836efa3445d86834a.txt | 4 + .../c367b4ff98810bd8ebb03aed1eb7fdf0.txt | 5 + .../c3ea24701ce2c070a187332432d69924.txt | 4 + .../c3f218074a5fa24554f35d41c7a8ed7a.txt | 4 + .../c41d724b4da6f27acf2f82dd6e01d7cf.txt | 4 + .../c5c10a2a03b99951c9bb7dd165699ae1.txt | 3 + .../c5fc663fc131d710865184d950a8e6ae.txt | 3 + .../c5fdbd5a41ac9b5ff6759b7fce6a032a.txt | 5 + .../c5ff5214ef37bcf7db239b02a94a34da.txt | 2 + .../c6a0cfc5364652cfbc5380750d34ba8e.txt | 3 + .../c728d6c7ebb6777f4b24f771407ceae1.txt | 5 + .../c7323b3e0c6b01cbc672235442b1224f.txt | 5 + .../c746e81377efc248393941ec62d016df.txt | 4 + .../c86afc2f78633eba946086bba9f6e7b7.txt | 4 + .../c8c60165f252de8814e19f73e4c1ce81.txt | 5 + .../c98a6a28cd3829b98d21d188a4601db1.txt | 4 + .../c9afbcc0e44b41122e696e28136c88aa.txt | 4 + .../c9bb1999c72d2aaa0fcb999b8fdf7f0f.txt | 5 + .../c9e2becfbabaeac5b24c84939775b1cb.txt | 4 + .../c9ea970d64c81dba3decc00ddddf6c43.txt | 5 + .../c9fe6aceba49d3b539c0de2a457008e8.txt | 5 + .../ca1d6a3c144fcc2a8eca6e20130c6fd9.txt | 3 + .../ca4467719d761828aea66d132d7de9e2.txt | 5 + .../cacac33e2e186579bd6f2717f432972a.txt | 4 + .../cb1da9b6dc01bb86c1706839671602a6.txt | 4 + .../cb50b723f788f9cf7d2183650f235287.txt | 5 + .../cbdfb8e619f468e2abd1df334f238989.txt | 3 + .../cbee1d284945cab0dcfde91514f64d5c.txt | 3 + .../cc0ef671b8168f7050e5d0f33bf22555.txt | 4 + .../ccaf3cbbd9490f2f0f30f6871848ebd2.txt | 5 + .../ccc6782058f6d04fe81dee47275ba6c8.txt | 2 + .../cd371c72dac20e77788ab8f025d27522.txt | 3 + .../cd5638d0f0b089a8b72d21131052f744.txt | 4 + .../cdb538530ed854a4421ae30f226ba5e6.txt | 4 + .../cdf0391f10105d6ed10a6df8e1d99a94.txt | 3 + .../ce0c4554be8d8f03c5129e47e199eebe.txt | 5 + .../ce4dea56cdf0a320ab3db6e53f912b08.txt | 5 + .../ceef3d514141c2e7d31f57f06748f0f4.txt | 4 + .../cf133e9c5a15a1164a3d6d1319cf58fe.txt | 4 + .../cf765ba6bb36fde7d35b2ed3f47b1dee.txt | 5 + .../d088c915a03c77bc89a9e466074f10a8.txt | 4 + .../d0a1616529f654f8e85f409a8ff71970.txt | 4 + .../d12d9d53a57a563793906271a40d9007.txt | 4 + .../d12df139d9d845b6612b28d63c6b7acb.txt | 4 + .../d167decdf90bd31cf8895d3836378c79.txt | 4 + .../d16c68d0ab3a80081c7ec312ca323db4.txt | 5 + .../d1a2bd7a51d77da0c53880d99cdf8e4f.txt | 4 + .../d1b016c1e260b06c9f4e1fb15f88745c.txt | 4 + .../d1c315d9478470375d2f1bb8e226694f.txt | 4 + .../d1ddf3e95dc619553298fa38c325e3d7.txt | 5 + .../d213aa519d82c13695f294fe2b9f0082.txt | 4 + .../d262c20cc228ad2f8742cc27973f5171.txt | 4 + .../d26c4932e2a6d260a6b748d6747e4207.txt | 4 + .../d2c0d0a6ba3766469b6088673fccfa52.txt | 3 + .../d2cbaa87bb20f4c60fa52c7b01e7bc47.txt | 4 + .../d310f40678f868b83d762347c73174c6.txt | 4 + .../d32016716f5bb487c7c22adedb06b350.txt | 4 + .../d342bbcaf71dd9fb28eaac993f523da8.txt | 5 + .../d3feb187cabf2b68f42d72c5f2c6d115.txt | 3 + .../d450e6a850bc1b9f570a6c9c4f53abb4.txt | 5 + .../d4c9419289b37089cc02c6c70b417826.txt | 2 + .../d4e1c74859109413588d5aaba4b8ec2c.txt | 4 + .../d503fd304a9f46d49d7819c6fe3008ea.txt | 4 + .../d5aed27f888ed08e77264f255f94aa3c.txt | 4 + .../d5beb716adf58c151412f2b2661666c7.txt | 3 + .../d5ef18ce299f1cde496ed3478cf618a3.txt | 3 + .../d605923185af2e57c934f27c976dd055.txt | 4 + .../d61f7561a0b075df7474e7907054bb64.txt | 4 + .../d62482850bc9d4e89e34be5058672bc6.txt | 3 + .../d6518fd1a9d59445aea5d45d2937dbbb.txt | 4 + .../d6cf1842d8e87e7313d52264f716959e.txt | 3 + .../d6d23263a8f514d9f710435ec907bc20.txt | 4 + .../d6e10b9e51fc1d72a5c22dad51121486.txt | 5 + .../d6e9bddb772c7cb92fb82327a1310b02.txt | 4 + .../d6ed22a87864a99d17610cc5bba9aa18.txt | 5 + .../d7298ddae4c93f1f02c93ff5eaa5eaf1.txt | 4 + .../d7540ca437085c9e4b7a982cebab8154.txt | 4 + .../d808680e3aa6391896e7f4182eb3a399.txt | 5 + .../d873341182a854350d35ac685378f543.txt | 4 + .../d8cde834eec73f92117454119b428fbe.txt | 4 + .../d8d5c3132ea0ded0bb15b46e8f4efdf0.txt | 2 + .../d91f785fee9465ba52ca2037ea94afa1.txt | 4 + .../d9a69c46e6103a1bc7629a04b2ecee27.txt | 4 + .../d9a8788c21d83541c6d00a5a947b73c2.txt | 4 + .../d9dd6f9830ee77c859f620b6f4767e6e.txt | 5 + .../da02dd84d5912c2572c57a6f43d59632.txt | 4 + .../da614350e7797b671b181dd7dbe4e86c.txt | 3 + .../da978a8a0eb70e9f3a0874c94bce2de2.txt | 5 + .../dadd516887f1ce445859a3a001fe22b4.txt | 5 + .../dae1862c2e81e3436854c7167a3d2c38.txt | 4 + .../db2f1ea74c09c97c21eabd75275b22ee.txt | 4 + .../dbb669ea4fb993396d91a84e3c4e03ff.txt | 3 + .../dbc87208c07b01ebada307292dac6ce0.txt | 4 + .../dbe533b180700cc5058b4cb38f2854fb.txt | 4 + .../dc7bd4dd36e1ac9d9dee9ae991776a1b.txt | 5 + .../dc7bdadd9163bff45cb3e6b0d37f04f6.txt | 4 + .../dc9c97f593f5b328bc992b7d6cf3ae8d.txt | 5 + .../dcb9ead591c60cc73bea72b0027b0e20.txt | 4 + .../dd4e01c3a404b697e120de5a08b1cd18.txt | 3 + .../dd974a4b8094fe5b01a2a8ea91fa323b.txt | 4 + .../ddbf97a99c4b4cf4ee49ab0ee30f0a84.txt | 5 + .../de97abcba845314e16d5ff2ca9287c05.txt | 5 + .../ded32dc618e3429d7b284a1407bbf310.txt | 4 + .../dfce23f9859ef192ce441ff977676699.txt | 3 + .../dfd5439e43fe87452411f4ebd3013fda.txt | 3 + .../e01630daba9d7c685e21b66d0235da30.txt | 3 + .../e0768bec49c06b70064475f1d04620b8.txt | 5 + .../e0a0fb2c926b62aa0e9f3b7dd29ad2df.txt | 4 + .../e0ee6b7033dbe46169b4518370bda33c.txt | 5 + .../e11bdd5667ec33b8bf5e4970cb61b590.txt | 4 + .../e133e335b9e34caa8297e7aa4e7baacc.txt | 4 + .../e13491f7e4ce140ba7a97caf32e6bdf8.txt | 4 + .../e14918f484b450b31449c9cfeadb4d74.txt | 4 + .../e1c8926c3d01980eafdc2c3180826b54.txt | 4 + .../e1dfb25a222de9e02093cd2320a01279.txt | 4 + .../e22ac344d1d92d0a45d857319a31ab70.txt | 4 + .../e2a502f0402b637c3b5db1ccdb25fb61.txt | 4 + .../e2b67e42c1f88376694b6a4c4332f8ea.txt | 4 + .../e349c3a317b4692f88fbe1c2f9550650.txt | 4 + .../e381598da10b8a7bd22119e0d2fddd11.txt | 3 + .../e3bf512165d0cffeed9d91930b48a552.txt | 3 + .../e3e2d910ace52fa2d6b81ca1ada0484c.txt | 4 + .../e3e9ab66c181c1968c8cdb3bda22e3d8.txt | 4 + .../e3ecb138c60227b3d36960b80e6b9969.txt | 5 + .../e3f2abeac581b5b6d531d5d6c1fe2972.txt | 4 + .../e4ae4d0417907bc046df141816330761.txt | 4 + .../e5d29009315cdd9199c28f9b4b7fedc0.txt | 5 + .../e60a704fe016af2c1203fcc215932b89.txt | 5 + .../e63d0af49aab5f943fb4c74216ae7969.txt | 4 + .../e64efc5cf5db058ed929e7d8a34bfeaf.txt | 4 + .../e6511fe6ea5d4b1f4f0652534dcb98ec.txt | 4 + .../e6748fe9f71e2d4cc2e56584ff7af39f.txt | 5 + .../e67be5e6f883bdb1796d879ec9863175.txt | 3 + .../e6950aeb6e43981bcd6c37503062b363.txt | 5 + .../e6c42b9ef60841473295b5ac704f3066.txt | 4 + .../e6cfe8a895e3920fe6530d125607a661.txt | 4 + .../e6dc56edf4211cf70bb21a9079e8fad4.txt | 4 + .../e6ed675168ed70283aa2cbca2ff8b375.txt | 4 + .../e6f46bf7797969bf38623ddd570a9408.txt | 5 + .../e71b0de681ce977be56b1fd764779892.txt | 3 + .../e76267df26cb369b5ed1dbb7eb0a3304.txt | 4 + .../e7a50aecb95568cde974a3155ba578b6.txt | 5 + .../e7f387540578c6de71bca05335eb5db4.txt | 4 + .../e81e2808fe55b860af30840346f58759.txt | 4 + .../e81f93a95008f3fd2ec191aaca86fe85.txt | 5 + .../e83668047e25d5f73d50252507f9f2d4.txt | 5 + .../e845556a1b726d19eed64166a235e3cc.txt | 3 + .../e88189acf062d3c6017180b7e1c5daed.txt | 4 + .../e884072b86f47778acef2f9a4378ab0d.txt | 1 + .../e88fd65b1f4b16872f90a11efcd6101b.txt | 5 + .../e89be41c77735c9123dca34218d6142d.txt | 5 + .../e8bf5c849e8c6c07236b8cdfa743602b.txt | 4 + .../e8cc2b2ff44787f04455e66006dd8e7d.txt | 4 + .../e8e45b323583b50ee94c81ab4dfd9447.txt | 4 + .../e90cfb0d261392f86af98fe66bc3d7a1.txt | 4 + .../e93b7ed193aff748bab5506f0ecb17b0.txt | 3 + .../e966b5ddd5883b9d902757a63f811e97.txt | 3 + .../e99913b8e2feec0714f9db3c4815e94e.txt | 5 + .../e9a90694356db46c54e253119acea3a3.txt | 4 + .../ea3674e09b8de8e989bde545aa574bff.txt | 4 + .../eb009f3942389ab23b87c64e7db10dda.txt | 5 + .../eb0afb42fb2569620832f9fad5703b5e.txt | 4 + .../ec41cd654443d0332389db08ded1eb33.txt | 5 + .../ecaff9787a434308f5e7b5e26728b80b.txt | 3 + .../ed2e95ed8716218b6caed4d6b6140050.txt | 4 + .../ed7756c3f3c50164d26f8dbd623060a8.txt | 4 + .../eda5c3c7718f3070479dc8264b818972.txt | 2 + .../edad635a8ef302e06dc4cbecec03f056.txt | 4 + .../edcde9aaa4d7b55b8034212857aca0e1.txt | 4 + .../edd8f46d6e4ff0f193cc2d82ccb24f63.txt | 4 + .../ee6083c50b40ff0c8a2828a17324ba6c.txt | 4 + .../ef0e92bbbee4dcaa25363dd1ff9708c6.txt | 5 + .../ef142b889873ac51ff9b784d8db5e9a0.txt | 5 + .../ef2633e9d1e96b147eeaa2c12c896070.txt | 5 + .../ef6f902af6acf7d065bfd20d91cb9ae5.txt | 4 + .../ef8337cf15c42924b10ae3a502cf0424.txt | 4 + .../ef98d3f6f1dc4fefad9f4a81c0560853.txt | 4 + .../efad6135fc1469652c4e4a49b8e875e7.txt | 4 + .../efb8e140b425665084ff3e98266b531a.txt | 3 + .../f00bb17d85d51e29e4ec1d51a2226f17.txt | 4 + .../f05d20abb2b9936d9a522fab738108d4.txt | 4 + .../f0db95fcb74fbc15d56e0ade5c34a96f.txt | 4 + .../f104dc3ca2a0360bf8b854f76b5072ce.txt | 4 + .../f13fec218b99e2dc108126d2334a9ebf.txt | 2 + .../f16c02e82910f941af67378563d3b415.txt | 4 + .../f195752519f8dd4fd2a9bdbc1b141397.txt | 5 + .../f1ea9f845f208c1bd0d5c86730759e1a.txt | 4 + .../f272b5c0201d78e19128800eafbbea76.txt | 4 + .../f28c3cfc1c94c00febc3717f177e1e28.txt | 4 + .../f3870d18faf4bd7b6fac66f7119397cf.txt | 4 + .../f409dfebaaae86cef4dcdf5306617649.txt | 4 + .../f419831f490ee7a0a50306b1f409d0a0.txt | 4 + .../f47073b5a23aa6a01ae67530540b0c09.txt | 4 + .../f4bf4f9315e86ffd5e351553ed86aa4e.txt | 4 + .../f4e820989083bf0d3f6a6fa58d23cf53.txt | 4 + .../f52b92c0cccb98f292f60d035dd2ab94.txt | 5 + .../f5779c0b22016b22ca856f30c661d448.txt | 3 + .../f5d23fc3190f08cbef79623ebe31a3b4.txt | 4 + .../f5e120f536fcc39cf654f4c94db1da9a.txt | 4 + .../f5e86297f0173b3e74dccbbb7056dd08.txt | 5 + .../f618add20c90062744d516dd45a4bf51.txt | 4 + .../f67f614434da278ba12617e415f79d26.txt | 4 + .../f693718414860f5d84e6bc44bbca149e.txt | 4 + .../f6a6397e01be24efb536c36ce04ddef3.txt | 4 + .../f6a72b786e9f7e3c1d77c7b4fc31861c.txt | 4 + .../f6d95b0399ab777293f40515cab97d51.txt | 4 + .../f6fd3d9a2d77bc871d1576b63eba9af0.txt | 4 + .../f7301422174591a9d05be1d17e656578.txt | 4 + .../f7828e14ab620601c975a14748681fa6.txt | 4 + .../f81476f1b68856abb2403f4120c4928d.txt | 4 + .../f874a3d818f17de0b3139cf12056551b.txt | 4 + .../f8c4636a0c26c3cc041a83cf078aad9c.txt | 4 + .../f96787979e2d56bb246ee62a31b5d865.txt | 4 + .../f9c65d47c8441b284f3e92a262f291da.txt | 4 + .../f9f5ea2a009bb50623136c1c6591a903.txt | 4 + .../f9f89c309709d34f6bb32f1bf2f02be2.txt | 3 + .../fa1ea8c4f4ddd462c17bb8c81aad432c.txt | 3 + .../fa7fe8108802c83205c66fe7caade124.txt | 5 + .../face9dcebae4da2f8a8159bfe59ee8ac.txt | 2 + .../fb4b7eeaa98f0f6b6a1bdd053d5beea8.txt | 5 + .../fbacaa34a04c3c6221d1ffeed14089b4.txt | 5 + .../fbba3c9273686ea5984366d2c4e0da6d.txt | 2 + .../fc7a198e1e6c9f93147c2195b7f1594f.txt | 4 + .../fc9aba974677d91558a3f7a8165a6f97.txt | 3 + .../fce59c14afae0c28214e78dc047f81c1.txt | 4 + .../fceef5e956eff358ec3b956dd9e2749e.txt | 4 + .../fd007672b1bfdeb6ec15ec3f9c0da5ea.txt | 4 + .../fd83e0bab3cc6706a8dbd1902185167b.txt | 4 + .../fdd51b44cf3ddf8dc6a77b9bfc19ca1c.txt | 5 + .../fddadb61964144436fd9980dcf8144a1.txt | 3 + .../fde51bc25cd84efd04b7e429fdb817b6.txt | 4 + .../fe0db3048d5452a58d50970966be8fc6.txt | 4 + .../fe1d90af8cc5f60d6905a005e026b5cd.txt | 4 + .../fe4697abfff8dd17fe11ca475577c38a.txt | 5 + .../fe642b4b7ccf1bb853a35278c80e90a8.txt | 5 + .../fe64c41bfccc5883f85639a8a9009f7e.txt | 3 + .../feb192a0864b3d014f01adf5445cb6ae.txt | 5 + .../ff7d2f8ab6790a3c3fa66b4eb6efa152.txt | 5 + .../ffb7b85dfd0c732e3055ea335bbaf870.txt | 5 + .../ffeb17610b24a45fbb9c9b687caa4d56.txt | 4 + .../009a7e97021d97dae6673b80f5562419.txt | 4 + .../00d85d76fffde2afbb5662ec32d4e6e3.txt | 4 + .../0109defc816d4d3f9ebec520758101ed.txt | 2 + .../013b4c04b2643efda758e27a68b47e8b.txt | 2 + .../0140db605724c01ba5142cbc218cfe25.txt | 3 + .../01c7ed9c137d1361d3cbc3425457119d.txt | 4 + .../01e020b4086fd8ecb300e61150e66444.txt | 3 + .../02f204657e32d9898613c0cb56cb5f19.txt | 4 + .../0304f393f7eb69101ddab817824ce675.txt | 4 + .../03256b23586b52f75fd89c48169c2580.txt | 4 + .../03e26365704345822c52eb7d4853e97f.txt | 3 + .../04f36d827bf62ba22575845abd2cd686.txt | 3 + .../04f8a5805d9b266c0d91dd062014dfaa.txt | 3 + .../0583ad55ecedb4ae888801613d288d0a.txt | 4 + .../0593d6a8f09c1960815f4c3d68355d91.txt | 4 + .../05b4f87fc4740cb39374870227371ad2.txt | 5 + .../0757d81f2a087c727869681b09734a65.txt | 5 + .../07e1e3b1060912328e34746e13ee19ae.txt | 4 + .../080ba59085ef88048ec8415d3eaf742a.txt | 4 + .../08220ca8d594cf17da36c9d4b9c57195.txt | 4 + .../08b29d17e97ff3a1adb8787b7f969578.txt | 4 + .../094846640c380b7e9c6ad297e4c2672a.txt | 4 + .../0a80281bab3eb2e167666b34d9167b4a.txt | 2 + .../0a9ae1aa5c8309bc02f169f6c7652822.txt | 4 + .../0a9bff5ea913ac5e5d9206bc34dbf4a9.txt | 4 + .../0af1caa776bdf673e904082cc2f76edf.txt | 5 + .../0b3240f52d3ec0f6246e64049a3c5444.txt | 3 + .../0be40c85ed6abac7dc600b8164aef739.txt | 4 + .../0c0198c6bff66812263b06f14ef07b57.txt | 4 + .../0c95c0d94a267ee41e471a9c73baff54.txt | 2 + .../0cffb0162877dd7032367bfa0592c83e.txt | 4 + .../0dcbc4d598c387ca212731a3d17d4130.txt | 4 + .../0de73b31c3c38c538bbc0d055991d1f3.txt | 4 + .../0e1ceb1fd5e14e57733032d9070e5ce1.txt | 4 + .../0eeafcecb06a43e3f8f9b5b38973992e.txt | 4 + .../0ef2825d91407a5a7ce4904c3f626804.txt | 3 + .../0f0438743b8c051059471f36ee9ceae6.txt | 5 + .../1043e72a8a78acad7fcd3464fd6c0edc.txt | 4 + .../1057a07b83ba65107342a7356ee335ee.txt | 4 + .../106c76e80c18785eb6b754a42cc3676f.txt | 4 + .../10ffa78896d3ab41de3dd9989818aa8f.txt | 4 + .../110ec995a4af1159da4ec4699016a91d.txt | 4 + .../11170c3c4b77a5b0ecccc3584722e9b3.txt | 3 + .../1129caac17eabf0f916b52f2b14b53c7.txt | 5 + .../116b3097928f2d0b478adcaa88f52631.txt | 4 + .../11ccd14f27f1fcae1803e6a1a787e7c7.txt | 5 + .../11e1ca8c81c5e711df3b8ae8a5fc6bc3.txt | 5 + .../13652dcb732f6b94b12e2c54ce09046a.txt | 2 + .../13b97793eec1064db7bf89855d732bab.txt | 5 + .../1485fe3b91a98e108dac134fefc3ce1e.txt | 4 + .../155034b20152b8ee2b713117a6dc3fff.txt | 4 + .../15701bebf45106e5aa9c44510d2690a0.txt | 5 + .../16be8ffe5ef1fc75e49f0b4c0dc7b333.txt | 4 + .../17af4c22377adbd21b47956d4dc6868a.txt | 4 + .../17f1fa3d015121a35a61284d754b908e.txt | 5 + .../192491b35377b986c5c8650b16eedf43.txt | 4 + .../19726a130475df782a8f306ecfb53baa.txt | 4 + .../19caba426117594cc403fb8ff86547b6.txt | 2 + .../1a62cf7a7b99e7cf533835e6d1188983.txt | 4 + .../1b4194d1d60be754fde2ac79965eed27.txt | 4 + .../1b42a7028ce6b0a4f197366472285b92.txt | 4 + .../1b88bcdc113af9db3b348edd481787bf.txt | 4 + .../1bab06733afd529dc3df158780fa2f9c.txt | 4 + .../1c33794f2acbbb2bae3dc99af1493819.txt | 2 + .../1c91cc97ad65688cf3ff8dbd3efa13b6.txt | 4 + .../1d30e913f0d6c62c32a8f38c9c131399.txt | 5 + .../1d7ecb23dd0021c6d0afbddbf3d5c877.txt | 4 + .../1dee58bfcfe52bca44b0520df4f94f3f.txt | 5 + .../1ea40a218bfff8bcc4e41a87fde1bba7.txt | 4 + .../1f2f9f7d868a3703647f73a5ea8e57c8.txt | 4 + .../1f375507c30e04a415fe1430a2e348d3.txt | 4 + .../1f8518a3b4eb317c3a094594994c918e.txt | 4 + .../204262c758c2e399c7a7f668cb035c32.txt | 5 + .../20bd48cc59aee5f57a37c3e19ccc5b81.txt | 5 + .../2132427f941a8eaf80e639731b26f8cd.txt | 4 + .../22107b73864219371dddf73da066786c.txt | 4 + .../222b581b22a76b737eb4070d7bd7cfca.txt | 4 + .../23532d65439430cbd36a4951c0c7af05.txt | 4 + .../25863f08d537a978fca92941aa8542a3.txt | 4 + .../26e77bc14f38e95bd86bee67a44da43e.txt | 1 + .../2761ffab840875beea0673738df78bf6.txt | 4 + .../27b663a9111e3ab540465370e6ec1e6f.txt | 3 + .../27edc29c28067e0c199215b30c046517.txt | 4 + .../29a82a5f398c44c717e5963b8aa18ce0.txt | 3 + .../2a27d33108c135b78005316e25b7344b.txt | 3 + .../2a37dff08e425c14579ca4ecb232122b.txt | 5 + .../2bc4c2dc4a0f69a21ff2381dd4e4dee3.txt | 5 + .../2cbf8c9e27871c5350b480fdc251e005.txt | 3 + .../2cd54245fbc81730d1697b2224ba4795.txt | 5 + .../2da14cd8670dac91bb5671c7bf40b327.txt | 4 + .../2e32a0ee0daab5ee5194a2f8b5e0f586.txt | 3 + .../2e677532d5e6379d7bb9227c73c10208.txt | 4 + .../2ee752feb40dded57dfb417a49803f5e.txt | 4 + .../2f63ed89bae4f75af1bf58e85899a462.txt | 4 + .../2fc6afecda457b5e083b8395cf7e37a4.txt | 4 + .../3036daac7bf852527515fd961c83485a.txt | 4 + .../30550bcc40a53e823571bf5843f595f7.txt | 4 + .../3159c888bb0b70dd182433f7b1d04909.txt | 4 + .../3186f4ce35b012e3b3fe8b8db2671c83.txt | 3 + .../318d149ff875c24ba2d4066346d1e9d6.txt | 2 + .../31b28e3fd6a231d6382367606843f088.txt | 4 + .../31ccc43eebe23e65879dea87292277ff.txt | 4 + .../320727f387d0c70e30d0ef6650212794.txt | 4 + .../326dc5fc5b0a058a96c3690141849192.txt | 3 + .../3332c0fc81c718ed96a430da7b4dae82.txt | 3 + .../33c311c9a9458c5791bc58d1462bdc93.txt | 4 + .../33e44da886008ccf1812715a8b3ae157.txt | 5 + .../346710c046ca0d5e1dee497c8b08997d.txt | 4 + .../34df9e42fb083ffc5411e73eba66d43a.txt | 3 + .../362fcc1a70d9c315b94c6a3317111b25.txt | 3 + .../36bf6e670468410177de50c83fac4b0c.txt | 5 + .../36bfb1e4d19d7a1325a7d1cd647175a1.txt | 4 + .../36eb0c3c00ce21d912db08b872ecfe85.txt | 4 + .../37431dd17168d3278269a68997c1e2a9.txt | 2 + .../37481c1fd1e3f459ff50847dbbeb5a93.txt | 4 + .../3795bbc85df7841dc04e3e14edfd21f4.txt | 4 + .../37ed57c07862e4dc18c7ef83e5a3ec3d.txt | 4 + .../38aa35b99729041734924db15ae6523b.txt | 4 + .../398550e0c7483b15fc97f5e17b33fe94.txt | 5 + .../39ef765bae2d2f3118f369de7317fb76.txt | 4 + .../3ac0f390b8a881b74e55f2af3f29250a.txt | 5 + .../3b134cad77abf272edd7323c9be89787.txt | 4 + .../3be2b5d228ad9dcba2ad0a01d24ea9af.txt | 4 + .../3c34b3c035744a0f64d8d979ca867511.txt | 4 + .../3c6aaefa8a430d08eb1de57e64b1e32d.txt | 4 + .../3c7d7f3fd805b7c10784a2252f0e62f5.txt | 4 + .../3d22bd6dcce2054b85e54e23df329bea.txt | 3 + .../3f23c2473ab75911807d6e2a69933e0d.txt | 4 + .../3f433eb056df56a8d69c6a1ea563e74c.txt | 4 + .../3f78208475b9dc4d9a8fc8d011888f02.txt | 4 + .../400195dc9a918704861ca9b3533fdb48.txt | 4 + .../401a6529b756023fafddc0ecc08f3a34.txt | 5 + .../410035421e5bbf571c52cf42f0bc283e.txt | 3 + .../4195841bf1ecb3b7f09a4b97b6225f80.txt | 4 + .../42770b7520259afe70390e59e0af99a0.txt | 4 + .../42bd385aa6a3f544f17bfa3a2efbd533.txt | 4 + .../43519d83899d5c69878f9c444f8120a2.txt | 4 + .../43605a2b412d6ac6f4449a0ed60ae30d.txt | 2 + .../44dbfd2e1b8d827e74a8c26c0dba82b0.txt | 4 + .../4510f763fc87557edeff52dc63c4362b.txt | 4 + .../452b4d9454ab5efa7e588537759b8b65.txt | 4 + .../45d878d88d345bdf47b96c54fb19020d.txt | 4 + .../46bf4c6370fd7a5038a576775cf047a7.txt | 3 + .../48588868e9e505c3ad9ed0fc1f38e7fc.txt | 4 + .../4999032b48901dc30550c8b43a0528a0.txt | 4 + .../4a4bc20da64e111c69659c49efb6a99b.txt | 4 + .../4a7ecc87a26e0406d0261d9d0c51af1b.txt | 5 + .../4c3b7d90e3c48ccbdc3dd899920427ab.txt | 4 + .../4c91928e0d18fb9f935323e21a7a377f.txt | 5 + .../4dc3e2b518cff881958a0d8023d04323.txt | 4 + .../4e4e945cf266b758ca86165a7d8d2b9c.txt | 5 + .../4e92d0b632411dfd1f034e6841285b63.txt | 4 + .../4ee71c6c6465bcd633e17a88bb66e6b6.txt | 3 + .../4f2e3ae76b23aa8f37e5c1f6a6764cbb.txt | 4 + .../5019576f93e20855db14485bbef2c955.txt | 4 + .../51334487bb9b1a0c74d8fa63e934cb13.txt | 4 + .../519ca1605ca2e29195f432ca7c6b9cee.txt | 4 + .../51b36552854c5e2fdcb505e67309fbf8.txt | 3 + .../520d7c9f42181d562be5fa94b7af12db.txt | 3 + .../529628f3551401356c3071efc858c265.txt | 3 + .../52a3837bf459d37710dd704419e496de.txt | 3 + .../5349d602f9deb7dd510eea3bb4695bce.txt | 5 + .../541444acfa5eaf5382767dced1c34dba.txt | 4 + .../54582ae38ee9947c1926d8193c1ae8b7.txt | 3 + .../54a2e506d9f0dc65308355b141269ef6.txt | 4 + .../54b7c5bf429eb9e20ed7db62ac737bb2.txt | 4 + .../5580c1dd0df32648b5ce98510507abd5.txt | 5 + .../558b1b333ddd1542bc561f02706c1fc4.txt | 4 + .../561e31e4b8f46b9687a8378710ac3b02.txt | 3 + .../582729139f879d1590ca60422deb8841.txt | 5 + .../58b6749ecb2db5b30fe90aafdd7e2598.txt | 3 + .../58fb78f5d92833e1570d0fb23857fd6d.txt | 5 + .../59e7550ded1e0f6bd251635be74f1dfe.txt | 3 + .../5b3153f226bd5c74cd48f228b8f7bd8c.txt | 3 + .../5bd31a05874d191357a938ab4f43099a.txt | 5 + .../5d4c6046a844ac9ba956624e854d274e.txt | 3 + .../5d85a738255bca6f79ff36cef8c21c8e.txt | 3 + .../5d9e5e18e9c5f3acfcd85709d30e3300.txt | 4 + .../5de94b7c29c8ca911b9f04f08cbbe52a.txt | 5 + .../5e0950103792f0632853c84a6ebb1387.txt | 4 + .../600a72d948d2e5c49beb1ba99f757bd9.txt | 4 + .../60462687400894cd6b98dc383092eb1e.txt | 3 + .../61533beb53948314aa6f92a4750a509f.txt | 4 + .../62619e202ab8cf792019f56950399e2d.txt | 4 + .../626f38915c39a337b0ba32d7979026af.txt | 5 + .../639bd3499a527300d3963cee02c78d4c.txt | 4 + .../63a9362a0fcce0e2c7aeb26f0ba700bd.txt | 4 + .../6472a94afc8804218f79747af43089d0.txt | 3 + .../647cb7c0cd83579bde57dc4ad34c9cd9.txt | 3 + .../648480a86f42c3d28e66eafcb09710b9.txt | 4 + .../65a965e01e4533ef2c33088a096a1dc7.txt | 4 + .../6618fc3a903127e48b2c4fa624b0dd65.txt | 5 + .../66608aa57990aa2b8bd49ae3994569da.txt | 4 + .../66fa72d54f8e560209ad9464de945c18.txt | 4 + .../678696f9eb5b903bbadad15d696328a2.txt | 5 + .../67d8686a17ab038abad3201430c57d22.txt | 4 + .../6a229e209beb7637e4ce5292d568798d.txt | 4 + .../6ae61d876c63fa6cf47263c7a2ae7691.txt | 4 + .../6b1be0537a54d118a8763eafe746e904.txt | 4 + .../6b2d3f4f96511774eb3bae27e3af06ad.txt | 5 + .../6cb874c40ca65ceea675a7373018cfc4.txt | 4 + .../6d13c490f207acee9e98881e13adb0f1.txt | 4 + .../6d5befea960e46a5c3274d0afc41ed1c.txt | 4 + .../6e0f25e1a76ff1cbc9d0180969d3b54d.txt | 3 + .../6ea4be782fe8a5e54d5bb9070c47f71a.txt | 4 + .../6ee961549759ead4213dbaf056bf62ae.txt | 4 + .../6f7612493d34d1f1b8ec804747165c32.txt | 3 + .../6fa30962d8f9c30116e466965179387f.txt | 4 + .../6fc67db2d6f8d0c0f40fe81faa04faa4.txt | 5 + .../7009b0450486cf01ddb3deae2baded34.txt | 5 + .../70bffc035ae5d0fd2bd314782cf69620.txt | 3 + .../710087f718f927c0d21c5f43b25bc85f.txt | 5 + .../71c8e9c164e8bfccecc6b0d0c711a8ac.txt | 4 + .../720436e9c276a5dd5159849e1d09e8ea.txt | 4 + .../726f8f3511fe3b8356332c19aa3ac299.txt | 5 + .../72cee0ff27d1c35768c2afdcfdc1183c.txt | 4 + .../741bd5c4d3a2342122b3bcbab4f733ea.txt | 4 + .../745ed065275224ee96b082e6423970e7.txt | 5 + .../7471731c4266eead2be85bc3b3bf45dc.txt | 4 + .../7534b599139ea12d7b44e2495fe05157.txt | 4 + .../75670a9f70f9d0bfd32204a4eab7d470.txt | 4 + .../76788b4474b560ecc99133113185a49b.txt | 4 + .../7726cef279d193502f5cb83b9a88e83e.txt | 4 + .../77312c07675c04d4b9267f93043a40ca.txt | 4 + .../775446ae1ae0487f41edf9102969aede.txt | 4 + .../77a7f5beb4fc4841f8a801f8cae29808.txt | 5 + .../77c4275bce0c9cd186cd53ccb9a706b2.txt | 4 + .../77eb813a40cdecdadc882c57f6b2cc4c.txt | 4 + .../785da55d2c7de97aeb6ad1bd19119d6f.txt | 5 + .../786d49911281c71f99e0d553c06ce3df.txt | 4 + .../7894d90a7e9e64d27d0d85c4c49555f3.txt | 4 + .../78ad4d9929b9f076963d726d53a6e940.txt | 2 + .../794ccd0649ea0e8be29589734058a57d.txt | 3 + .../79aa3d276582994734323d24cdb5ed01.txt | 4 + .../7a395e5c9d1fe6c75d862b922d77187c.txt | 5 + .../7baff76c5fb6c08564fa34fd83939453.txt | 5 + .../7c41d612128cd5e3b6e408883c934c95.txt | 4 + .../7cbff942d1478e98084353d0f7f62e31.txt | 4 + .../7d5348dd3b542499bbf02aed8bd36785.txt | 5 + .../7d93ad334d08b8c98c4284c1f8d2c4ec.txt | 5 + .../7d9c7bd57e89e7740ec07ecf8a048151.txt | 3 + .../7db7aae1e2bca2ca5235b8057009b0ac.txt | 5 + .../7e1f67b67402c4df5e1e2a44d25f51fa.txt | 4 + .../7f11e6e09918113dcddf6d681e13ea71.txt | 4 + .../7f5f376b86a286024c83c26ffb49cb8c.txt | 4 + .../7fbf8b0bbec82e061a8d3eea8f0a71d1.txt | 4 + .../8213f4a18007036d5f4065f5376ff774.txt | 4 + .../824a6558348b36207e550fec790c5722.txt | 4 + .../825a7b148796df2377293f52d740e817.txt | 4 + .../82a1fd80d6a43cf0496ed6110c2f8e02.txt | 4 + .../841f372e79296ea98dd109364f81c59d.txt | 4 + .../851459f4199292ed1a7577162d013e9d.txt | 5 + .../8559d83fb3386d14f3f864903dfec0c8.txt | 4 + .../857d3626683a302ff9b570090741ca51.txt | 3 + .../85f5c5779d8989d9d671ea60e397690b.txt | 4 + .../873baa02e1555c2c849ea326132b03c1.txt | 4 + .../87955b65b77f2f86b3c9331d4a14bbb6.txt | 5 + .../8825bb1799574d04b9d15cdd52cf748d.txt | 4 + .../89d87730899049f97ef3fb1c709cadd7.txt | 4 + .../8a15e934825b7cb2d3e5b613144cd910.txt | 3 + .../8b0d95e91c085a2685ffb3d8269d7077.txt | 5 + .../8d9a1d62882c4212fff968c6ce25430e.txt | 2 + .../8ec09b3461d580500e27199617e3bd9c.txt | 3 + .../8ec1c1e12dac2fa8d13e32f4e140be33.txt | 4 + .../8edd016df31d5637ec523779cac20961.txt | 2 + .../8eeb9ee66982325b11dd44ce2e765cee.txt | 4 + .../8f714f97e08d772374b551cc9f3e3580.txt | 4 + .../8fb7ce565187d7ce5e53bdd4e8be8565.txt | 4 + .../9097f94db10c3a77e4dcce0f9d873e28.txt | 4 + .../910ea301c783d2a6b264eae9672f23e6.txt | 2 + .../9142fa8d89b3e0b6f5eb1de4c092098a.txt | 4 + .../916ddce272ccfb0276d8af323e28e455.txt | 4 + .../91c65204b18c6fb96943baf908ea12c9.txt | 4 + .../9275e527c729636774d24889914a0008.txt | 4 + .../92de2815fa1300896a5caa248ddd3b27.txt | 3 + .../9331d444eb4022d9156c2981285761cb.txt | 5 + .../933a534cef0c2e5093597e01e1a48729.txt | 3 + .../935db938e9eda7ba1ee4a3b5991b9c57.txt | 3 + .../93d0fc7d138988945a0099da59269745.txt | 2 + .../941a7cd0eb00bba884869e751d00ae2c.txt | 3 + .../943a90030ea11eefa19af682ce7cc28e.txt | 4 + .../9449bc93017476ec283925e21bd8f1c9.txt | 4 + .../94f3d16d1488a8b7690542b6aaccb056.txt | 4 + .../952bdbcd285b419a773b8be327bf2edd.txt | 4 + .../95540a87f0439f94844fa8a078efa55e.txt | 5 + .../95c690c6734de26d8308b061d74081ae.txt | 4 + .../95e4b8a979c82909d89ef9b0fa3c1fda.txt | 4 + .../960e1a7f4b929bf85f024050639201c9.txt | 5 + .../961c2a792a5e1966cc7360da94d557c9.txt | 4 + .../96be01144f9c5cf1cbfea9e1bc15c27c.txt | 3 + .../96c0be811cbc2ba0144c31a967854e6a.txt | 4 + .../97e1ec9b22357b23ea61236d43b6c4a5.txt | 5 + .../99098dc4e3250e6b858211bf756805bd.txt | 5 + .../9937c9a1cd35f0a189489e1ba3e1ee6e.txt | 5 + .../996ea9758e9184460656293299f4fc5f.txt | 3 + .../99b3a193d98cedc339cf03ed0c89ed4e.txt | 4 + .../9a17dca9a159b52f6058c4b8b3758263.txt | 3 + .../9ade086496ac44efdbdbdf3345995b0d.txt | 3 + .../9af82de23dc4be3c15423a1f3c3a4468.txt | 4 + .../9b09d046433f03f50defda54e17a33ec.txt | 4 + .../9b5ace4527677b30a2ee7fe026991945.txt | 4 + .../9b716ca22bf76c39ca2102792f0614e9.txt | 3 + .../9b9428a20c87ccf17df3d1751b820344.txt | 4 + .../9b9e6a1b9082f4f9a7d5c745f84f497d.txt | 3 + .../9ba634bd945795ed8a76acdecfde49a4.txt | 4 + .../9c0f0a0ce42d8287c9f48a6cc7c71c1e.txt | 4 + .../9c5fbc59328f51d035932d0d1f542487.txt | 4 + .../9c9e4e374863bf04076ae1b6eaa5eac2.txt | 4 + .../9d11ef7100b8416d96188e22f5171adf.txt | 3 + .../9debdbee212d6c3067cf2cdaf270e3b3.txt | 4 + .../9e1e456a238764f55631e71db54e9e9e.txt | 4 + .../9eec1c737984af1556c71586c071121d.txt | 4 + .../9f6629f1db673de2d304b3fcc2c48ea2.txt | 4 + .../9fcc16f1a59fc5dc8061be9211d1406f.txt | 3 + .../a11fd151b48136b97839d38f924a2341.txt | 4 + .../a1f23934299c5079c5733105072d1f93.txt | 3 + .../a2b7e80c538e0511d89273aeed25a92f.txt | 5 + .../a2cc250a546ae544fb4695e2b8077ad1.txt | 3 + .../a2f87d16679f59a1686cd8eeeb1ca63f.txt | 4 + .../a3b3fcd204c9ef0ce797fe25747b85d3.txt | 4 + .../a3f1af91c9902e7bf1ff0648f38652be.txt | 4 + .../a42c96155f0b834b4d6e1a3eee789390.txt | 3 + .../a45c95d0bade2be240feeae148f17274.txt | 5 + .../a49f45d1fd6b6586eb46970b989c4dc7.txt | 3 + .../a4c1525c8db3dddd50e0092dc36862ac.txt | 4 + .../a4cbaa33dc42283d5371c48b6eb17cf5.txt | 4 + .../a4f4330957dfac60def39e08d8c69ca9.txt | 5 + .../a52f23dc0c83fd6f1b9e7ed7279bb9e3.txt | 4 + .../a584494c3ac50081b2f9574b18ba42fb.txt | 4 + .../a59cf66b62ea8d403f095bae377a1e82.txt | 5 + .../a5cfeb3eaa805540f31726104d5037c9.txt | 4 + .../a8a56b91eea0f9a8c480f81e0960a9f0.txt | 4 + .../a917d45a781de755ce4c7f727ecb663a.txt | 4 + .../a925e5a0d4a2ad37c36a0cdeae5f4a05.txt | 4 + .../a93bc75d3f60badf7765a69654aea189.txt | 3 + .../a955a755f40b0cda7492c7aa4fff2b52.txt | 4 + .../aaaf334aeff84ea148a1469d42c6fc82.txt | 3 + .../ab3afd0a8254672d351f549a76f83c98.txt | 4 + .../acecd72ff9410fb27b05718d047d24dc.txt | 4 + .../ad54ac1ce876f93cf5c813ec262845e2.txt | 4 + .../ad67a4d7d31da7c7e823b4c05d64270f.txt | 3 + .../add3c7e8571233b17df92912514e36ad.txt | 4 + .../ae5b492f03929fd6b81ebee9b2733e2a.txt | 4 + .../ae99c7c82d9ac7a6355323ae7a0a95c0.txt | 3 + .../aeb0dab30ccf763d9999214f196e1bed.txt | 5 + .../aef6711358ed63fb79fccd99e71fb50e.txt | 5 + .../af0b4beba3b6b475e18f735799b52cb3.txt | 5 + .../af214b3b06b5463cc90434a96bbafd51.txt | 4 + .../af38ad387f7dc992568a3fcb44a072e3.txt | 4 + .../af52415030cfdb1e111f787bb8cb99e2.txt | 3 + .../af85198787c82b979daf1a9fdf9596cf.txt | 4 + .../b019882b412128a36502c22a00be37b6.txt | 4 + .../b02782fbd52d87eab17fe5c24b326e92.txt | 4 + .../b0414baa9b45f1df4a49b0ba95ad0678.txt | 5 + .../b0d353a2cd82f830c13b5258a584fda2.txt | 5 + .../b1b1c0fb595245aca359befbc1f13d65.txt | 4 + .../b438e477a38a97ceb0d5901bf567c5cb.txt | 4 + .../b46052dfeffd46059f763fc055048757.txt | 5 + .../b4a91875a7d91bb5712fdc7ab460356e.txt | 5 + .../b4b7a065dc0d46c8524f44134b43df90.txt | 5 + .../b61570abaf72fc4e5b81089f5b08ccdf.txt | 3 + .../b6fa0e82f5ddf3937f7741872d5aab29.txt | 5 + .../b74470dc7d33f0c5ded118dcd72408dd.txt | 2 + .../b8116e2cc4e7e2a740cc06ed5b3eb64b.txt | 4 + .../b84dc59a29d1cb0bd465bc7ac9c21963.txt | 4 + .../b8d4fc353441b833014d5dfb7360acaa.txt | 4 + .../b932ad094993c20c7907ca8ce19afa68.txt | 4 + .../b9ab386866cdc3fe74d767f3aecdab33.txt | 4 + .../baf7fffc1651230f1ba31a474abac0e8.txt | 4 + .../bb86c627bbe6120f82a39eeac0a210c7.txt | 4 + .../bbca5c142aacd33545651d72c90e4d16.txt | 4 + .../bc42a65657fbbcab9abf3bbf7c253fb1.txt | 3 + .../bcb4a9a964f638055196c65f6da6f103.txt | 2 + .../bcc20ed95de63717b59927435fbb91b9.txt | 3 + .../bcde2471baeecec6694f8208c3d97279.txt | 3 + .../bce80bfebb680584076dcae61a8265af.txt | 5 + .../bd006d9d9227499468866ba030554c13.txt | 4 + .../bd621187dafd6846d11d7f2fb2459fa2.txt | 4 + .../be204f58ecb1f7aa29209167d8da5d70.txt | 5 + .../be3a11101c7b3e19e67219d5ffdba17b.txt | 4 + .../bfb153ecb1e3b7552b673f2f7be1ccf6.txt | 5 + .../c0448396a66b6a9a343c8d4f6c6c3eb0.txt | 5 + .../c1a0a37f454b2d5aaca369f6412bd0d3.txt | 4 + .../c2095599aaf0586f25f6c9a117d4fc0c.txt | 4 + .../c2602bfcc5527d69fbf66e5ba431c133.txt | 4 + .../c2983bce2fb62663ef1c1bb3dfa5a353.txt | 5 + .../c2bec2fae37fe4502cb53ecff9be1b6b.txt | 4 + .../c2d9f3757c2dad99ec8f45240d125369.txt | 5 + .../c3960b5c98ffe2f6f5b9f3f30bbd679e.txt | 3 + .../c3ae2001bc948489f52dea7ca6e95fc9.txt | 4 + .../c3fba3e40a39a345fc1a32d2c0e586c4.txt | 2 + .../c47e0ee821c908eb775487c485a1f011.txt | 3 + .../c4dee3d62365554783e3696baa67fe81.txt | 4 + .../c52724e65a186042b9991d546ca8353e.txt | 4 + .../c528c8c781aabb8841188b6c6870ef60.txt | 2 + .../c5383a5b4f6737d8a8aab45b34d75c85.txt | 4 + .../c6d8f37a44040738b00b6329975739f1.txt | 4 + .../c741348f69f3d93bca532c04d013d2ff.txt | 3 + .../c799e2d03ce8c169db17c2764eb15649.txt | 4 + .../c7c7760b123788dfc300c00f550c0c8b.txt | 5 + .../c81c448c1a4c106d2c0c65af9d171e84.txt | 4 + .../ca310ecb2347058231a4f39abe2a4b37.txt | 3 + .../cb3d6d429e9939b00f70b6b93f75e13c.txt | 4 + .../cbb3af2be8d11a04174cb3108ab47fd6.txt | 3 + .../cc6d83459819b0a75b6adc146f1bb21c.txt | 4 + .../ccd349028db6c236ae4dc2f72467013d.txt | 5 + .../cd5d962cad7da958ea255fb19a3dd930.txt | 4 + .../cda3322118354a1e2b32b97b8529e414.txt | 4 + .../ce0847f5942db97d0f8685af8167e89f.txt | 3 + .../cf4cb3db4ccc0a7ab9e9a2c4da9329a3.txt | 4 + .../cf5bffdcae03e2026d162acd7dbb567f.txt | 4 + .../cf8ebd04bf14d8ab3c4567c7e5fbb2af.txt | 5 + .../cfa7a42afb19842fef8d76b41f20758f.txt | 5 + .../d0208bea6e7dbf8ac017d394d06a6d97.txt | 5 + .../d0f201925be9f4efbaafe8620119875d.txt | 4 + .../d12354801e2a2689afabfaf237796d6f.txt | 3 + .../d123dc82eefece187055aba6869b95cd.txt | 5 + .../d1b7b384daafd2472881aed64e1468a7.txt | 4 + .../d22deb4dece26c8ed02e8a3f05dd0395.txt | 4 + .../d275671cecfe7df4e5219cd774826825.txt | 4 + .../d27a33ed1a6bf7de764fdb8b12440665.txt | 4 + .../d2bc4f474885b48501283f19d2a2dd80.txt | 2 + .../d3feb187cabf2b68f42d72c5f2c6d115.txt | 3 + .../d430ed3650c4c82c2a452f3ffc7690a9.txt | 3 + .../d48510fe6ec84c879f68b9f9385f5e14.txt | 5 + .../d49f32b48a997565aed8380dd447ef91.txt | 3 + .../d4ed6e5c29a19cace6f9c3a81ac3c961.txt | 4 + .../d59bd1237fe3ec57bec775cefe34fc59.txt | 4 + .../d6880efc983939a8bc39133bee849242.txt | 4 + .../d6efc173b527acd06565cce8947c68ed.txt | 5 + .../d712db479ec92c0b37b0801161820366.txt | 5 + .../d83e9ba661aaa1233102de0409b6832b.txt | 4 + .../d8526b86e748354547ff3c210e2c177b.txt | 4 + .../d8a4b88ac006bf17f9d46ff487f4e481.txt | 4 + .../d9e1da1b60affbc48272520117bf47d9.txt | 4 + .../da612470ecad5530274e30a0c519c26c.txt | 4 + .../dab87e721f5a1e8410af38bc09db6112.txt | 4 + .../db0b23b7c4b284e1901ac146f62345c8.txt | 3 + .../dbbe55447ad34d282c50beefa138cdfb.txt | 5 + .../dbc7066a0923685debf5925f6e9cb980.txt | 4 + .../dcfedaf9eddb9ce0a3c98d5fb29e9072.txt | 4 + .../dd730346a8a66e841d06223364ab66df.txt | 4 + .../ddd7b5b5ac9bba4014a6decf60e4bb66.txt | 4 + .../de23b7a87cd2a4fe477bebf589ebf278.txt | 4 + .../deffd3c1c8784398a62c8d1ebfb3e436.txt | 4 + .../df6c4c7dc3c069d53125e9b5014d1396.txt | 5 + .../dfc1aea91a1471e2a59c7e7d113ba6e1.txt | 5 + .../e05a5fbc31da900cdb2586cc9fcecd67.txt | 4 + .../e09bc7551899dbca3d98b3fa38790fea.txt | 4 + .../e10ab369a27acb2093e56d5ea4e9029a.txt | 4 + .../e133e335b9e34caa8297e7aa4e7baacc.txt | 4 + .../e20f844b4406d5935f605a65f589635d.txt | 5 + .../e26188d532509f649c96e984c95cf7aa.txt | 3 + .../e39a86e6070757a12ffe8b4970e94eb9.txt | 4 + .../e49863c40c18b9049601ae9dcd6511f7.txt | 5 + .../e4df16396ed7363d7f748680fb379f4c.txt | 5 + .../e55ec704a3a5c728d28ddbca60f7392e.txt | 4 + .../e65cf91b00d1eabe632cb6065fc58f1f.txt | 3 + .../e6cef5e7cdcd2ba2370e8ff7b2df9351.txt | 4 + .../e725d377ec830c8b0daa5e02261ceae0.txt | 5 + .../e74893a8e18678fb991bf242688ee2d5.txt | 4 + .../e83de5862e651226e954f206a8bfe2a1.txt | 5 + .../e887607248f7391b080c7a50af22d464.txt | 3 + .../e8a154d6c301c9ff032879f86d2f9b89.txt | 4 + .../ea1cb7d34fe49bbbb6e9251b16657918.txt | 3 + .../eabc94c7e737d3fdcb4b737f73f23db8.txt | 5 + .../eb14edc170ff105fde8cdcd83dd942c6.txt | 4 + .../eb4ea9d5d92a8c02c079ce4518e0e608.txt | 4 + .../ecf9efb8308a694a32d3fa64933e1752.txt | 5 + .../edfa08514ee31d005331d683ac0cbe5e.txt | 4 + .../ef0bab363420f2105bef4a4c30d823b4.txt | 4 + .../f005ad99e1ae30a0a5d4fd0b3dad7770.txt | 5 + .../f0749b18aa0747b73ac74d36c9ac5317.txt | 4 + .../f0b35ba8adfa960168421e0d7e2291d1.txt | 5 + .../f0d088d42bc11b780b4307eead291fd4.txt | 5 + .../f101f8745b2fc2a1dfd62faf74a5c53a.txt | 4 + .../f128bc5093ce92f6948a3846c2cdaa23.txt | 4 + .../f1370c1c58c5249c336abda28de9c58b.txt | 4 + .../f1df5ec7fc32fd167fe5e2bba70b5e90.txt | 4 + .../f2e0a2a2ba5b631b50364e9424d8a399.txt | 4 + .../f44189b1241a054fd74f1416e50ef578.txt | 5 + .../f4e820989083bf0d3f6a6fa58d23cf53.txt | 4 + .../f5552b84d08a383e183a2d4380cf3904.txt | 5 + .../f5d23fc3190f08cbef79623ebe31a3b4.txt | 4 + .../f6c0a1a8e44fbce047d5ee1ce4b7d563.txt | 4 + .../f6ec1b24e1a5cb0b3b5db121d901498d.txt | 3 + .../f7617b0afb68d73f7e004ee314352d91.txt | 4 + .../f7903039de6b51cd3953fbdfc8bae34c.txt | 4 + .../f7b3ea98396a0dd9549f4b4196cdb067.txt | 5 + .../f7da67a66d65dbe721d9359a064ab5cc.txt | 4 + .../f9f64c7eedcd4ade9c06ee23b326cb96.txt | 4 + .../fa4ff538d0763758fdcdf91ee0cc5ec1.txt | 4 + .../fa6c79a0fff4fdb246aa7dcdebaa7173.txt | 4 + .../fb162b8848d3b4d814ebeeef4e055cb7.txt | 4 + .../fb9c3337c7bb67f82c60e95e883e49fa.txt | 5 + .../fc687339c6964908a927657374dc0f0d.txt | 4 + .../fd2e892a2768cf93c57af72355073882.txt | 5 + .../fd5d72dcfdee2a36615a11ad69077808.txt | 4 + .../ff0817df5eb677c91d4dda6c1d4074dc.txt | 4 + .../ff9f936e5f3dd45ab09465d39d379763.txt | 4 + hanzi_detection/include/darknet.h | 805 ++ hanzi_detection/libdarknet.so | Bin 0 -> 538900 bytes hanzi_detection/model/jiyan_classify.cfg | 83 + hanzi_detection/model/jiyan_yolov3.cfg | 789 ++ hanzi_detection/python/darknet.py | 156 + hanzi_detection/python/proverbot.py | 37 + hanzi_detection/readme_classify.md | 20 + hanzi_detection/scripts/dice_label.sh | 20 + hanzi_detection/scripts/gen_tactic.sh | 5 + hanzi_detection/scripts/get_coco_dataset.sh | 31 + hanzi_detection/scripts/imagenet_label.sh | 15 + hanzi_detection/scripts/voc_label.py | 59 + hanzi_detection/src/activation_kernels.cu | 206 + hanzi_detection/src/activation_layer.c | 63 + hanzi_detection/src/activation_layer.h | 19 + hanzi_detection/src/activations.c | 150 + hanzi_detection/src/activations.h | 87 + hanzi_detection/src/avgpool_layer.c | 71 + hanzi_detection/src/avgpool_layer.h | 23 + hanzi_detection/src/avgpool_layer_kernels.cu | 61 + hanzi_detection/src/batchnorm_layer.c | 279 + hanzi_detection/src/batchnorm_layer.h | 19 + hanzi_detection/src/blas.c | 351 + hanzi_detection/src/blas.h | 105 + hanzi_detection/src/blas_kernels.cu | 1035 +++ hanzi_detection/src/box.c | 357 + hanzi_detection/src/box.h | 14 + hanzi_detection/src/classifier.h | 1 + hanzi_detection/src/col2im.c | 39 + hanzi_detection/src/col2im.h | 13 + hanzi_detection/src/col2im_kernels.cu | 58 + hanzi_detection/src/compare.c | 352 + hanzi_detection/src/connected_layer.c | 336 + hanzi_detection/src/connected_layer.h | 23 + hanzi_detection/src/convolutional_kernels.cu | 330 + hanzi_detection/src/convolutional_layer.c | 622 ++ hanzi_detection/src/convolutional_layer.h | 50 + hanzi_detection/src/cost_layer.c | 176 + hanzi_detection/src/cost_layer.h | 20 + hanzi_detection/src/crnn_layer.c | 283 + hanzi_detection/src/crnn_layer.h | 24 + hanzi_detection/src/crop_layer.c | 103 + hanzi_detection/src/crop_layer.h | 20 + hanzi_detection/src/crop_layer_kernels.cu | 225 + hanzi_detection/src/cuda.c | 178 + hanzi_detection/src/cuda.h | 20 + hanzi_detection/src/data.c | 1685 ++++ hanzi_detection/src/data.h | 50 + .../src/deconvolutional_kernels.cu | 139 + hanzi_detection/src/deconvolutional_layer.c | 312 + hanzi_detection/src/deconvolutional_layer.h | 25 + hanzi_detection/src/demo.c | 349 + hanzi_detection/src/demo.h | 6 + hanzi_detection/src/detection_layer.c | 275 + hanzi_detection/src/detection_layer.h | 18 + hanzi_detection/src/dropout_layer.c | 60 + hanzi_detection/src/dropout_layer.h | 20 + hanzi_detection/src/dropout_layer_kernels.cu | 41 + hanzi_detection/src/gemm.c | 324 + hanzi_detection/src/gemm.h | 34 + hanzi_detection/src/gru_layer.c | 406 + hanzi_detection/src/gru_layer.h | 24 + hanzi_detection/src/im2col.c | 40 + hanzi_detection/src/im2col.h | 15 + hanzi_detection/src/im2col_kernels.cu | 61 + hanzi_detection/src/image.c | 1466 ++++ hanzi_detection/src/image.h | 69 + hanzi_detection/src/image_opencv.cpp | 121 + hanzi_detection/src/iseg_layer.c | 225 + hanzi_detection/src/iseg_layer.h | 19 + hanzi_detection/src/l2norm_layer.c | 63 + hanzi_detection/src/l2norm_layer.h | 15 + hanzi_detection/src/layer.c | 97 + hanzi_detection/src/layer.h | 1 + hanzi_detection/src/list.c | 92 + hanzi_detection/src/list.h | 13 + hanzi_detection/src/local_layer.c | 293 + hanzi_detection/src/local_layer.h | 31 + hanzi_detection/src/logistic_layer.c | 71 + hanzi_detection/src/logistic_layer.h | 15 + hanzi_detection/src/lstm_layer.c | 626 ++ hanzi_detection/src/lstm_layer.h | 20 + hanzi_detection/src/matrix.c | 196 + hanzi_detection/src/matrix.h | 13 + hanzi_detection/src/maxpool_layer.c | 127 + hanzi_detection/src/maxpool_layer.h | 23 + hanzi_detection/src/maxpool_layer_kernels.cu | 106 + hanzi_detection/src/network.c | 1129 +++ hanzi_detection/src/network.h | 29 + hanzi_detection/src/normalization_layer.c | 151 + hanzi_detection/src/normalization_layer.h | 19 + hanzi_detection/src/option_list.c | 140 + hanzi_detection/src/option_list.h | 19 + hanzi_detection/src/parser.c | 1312 +++ hanzi_detection/src/parser.h | 9 + hanzi_detection/src/region_layer.c | 507 ++ hanzi_detection/src/region_layer.h | 18 + hanzi_detection/src/reorg_layer.c | 173 + hanzi_detection/src/reorg_layer.h | 20 + hanzi_detection/src/rnn_layer.c | 292 + hanzi_detection/src/rnn_layer.h | 25 + hanzi_detection/src/route_layer.c | 134 + hanzi_detection/src/route_layer.h | 18 + hanzi_detection/src/shortcut_layer.c | 90 + hanzi_detection/src/shortcut_layer.h | 17 + hanzi_detection/src/softmax_layer.c | 107 + hanzi_detection/src/softmax_layer.h | 19 + hanzi_detection/src/stb_image.h | 7462 +++++++++++++++++ hanzi_detection/src/stb_image_write.h | 1568 ++++ hanzi_detection/src/tree.c | 139 + hanzi_detection/src/tree.h | 8 + hanzi_detection/src/upsample_layer.c | 106 + hanzi_detection/src/upsample_layer.h | 15 + hanzi_detection/src/utils.c | 726 ++ hanzi_detection/src/utils.h | 53 + hanzi_detection/src/yolo_layer.c | 374 + hanzi_detection/src/yolo_layer.h | 19 + ...f7f9123704ef354a52d\346\227\205_u65c5.jpg" | Bin 0 -> 3966 bytes media/1590951689.png | Bin 0 -> 24312 bytes media/ab9a8dcdda85f1d8789909803374fbea.jpg | Bin 0 -> 174536 bytes media/e697bc6aa912eeb2610998833f209242.jpg | Bin 0 -> 156005 bytes media/geet_demo.jpg | Bin 0 -> 136834 bytes media/jiyan_test_api.png | Bin 0 -> 42887 bytes media/yidun_demo.jpg | Bin 0 -> 41793 bytes ...\277_1cde28c6abce11eab97c0242ac110002.jpg" | Bin 0 -> 1843 bytes nine | 1 + 1674 files changed, 49628 insertions(+) create mode 100644 .gitignore create mode 100644 IMG_1766.JPG create mode 100644 LICENSE create mode 100644 README.md create mode 100644 doc/.ipynb_checkpoints/jiyan_gt_challenge_demo-checkpoint.ipynb create mode 100644 "doc/.ipynb_checkpoints/\345\234\250Python\344\270\255\344\275\277\347\224\250\346\250\241\345\236\213-checkpoint.ipynb" create mode 100755 doc/Ubuntu18.04 install darknet yolo-v3|cuda|cudnn|opencv|anaconda.md create mode 100644 doc/classifier_train_handbook.md create mode 100644 doc/detector_train_handbook.md create mode 100644 doc/jiyan_gt_challenge.md create mode 100644 doc/jiyan_gt_challenge_demo.ipynb create mode 100644 "doc/\344\271\235\345\256\253\346\240\274\345\233\276\347\211\207\351\252\214\350\257\201\347\240\201\350\256\255\347\273\203\351\233\206.md" create mode 100644 "doc/\345\234\250Python\344\270\255\344\275\277\347\224\250\346\250\241\345\236\213.ipynb" create mode 100755 hanzi_detection/.gitignore create mode 100755 hanzi_detection/LICENSE create mode 100755 hanzi_detection/LICENSE.fuck create mode 100755 hanzi_detection/LICENSE.gen create mode 100755 hanzi_detection/LICENSE.gpl create mode 100755 hanzi_detection/LICENSE.meta create mode 100755 hanzi_detection/LICENSE.mit create mode 100755 hanzi_detection/LICENSE.v1 create mode 100755 hanzi_detection/Makefile create mode 100755 hanzi_detection/README.md create mode 100755 hanzi_detection/examples/art.c create mode 100755 hanzi_detection/examples/attention.c create mode 100755 hanzi_detection/examples/captcha.c create mode 100755 hanzi_detection/examples/cifar.c create mode 100755 hanzi_detection/examples/classifier.c create mode 100755 hanzi_detection/examples/coco.c create mode 100755 hanzi_detection/examples/darknet.c create mode 100755 hanzi_detection/examples/detector-scipy-opencv.py create mode 100755 hanzi_detection/examples/detector.c create mode 100755 hanzi_detection/examples/detector.py create mode 100755 hanzi_detection/examples/dice.c create mode 100755 hanzi_detection/examples/go.c create mode 100755 hanzi_detection/examples/instance-segmenter.c create mode 100755 hanzi_detection/examples/lsd.c create mode 100755 hanzi_detection/examples/nightmare.c create mode 100755 hanzi_detection/examples/regressor.c create mode 100755 hanzi_detection/examples/rnn.c create mode 100755 hanzi_detection/examples/rnn_vid.c create mode 100755 hanzi_detection/examples/segmenter.c create mode 100755 hanzi_detection/examples/super.c create mode 100755 hanzi_detection/examples/swag.c create mode 100755 hanzi_detection/examples/tag.c create mode 100755 hanzi_detection/examples/voxel.c create mode 100755 hanzi_detection/examples/writing.c create mode 100755 hanzi_detection/examples/yolo.c create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0015673f726b2a1ddd43c1758553093b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0030fbc156e567a2c34afe4495318e16.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0042d7d2797b26fcfc090e27678beedd.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0048a76678a29202cf03731f46af9c64.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/00ce931e1afbaf47c62f6078e72014ce.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/00de8e4044705679726aa5d933d67552.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/00e8f9ff61bf4198ea528683f78be58c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/01349f81609688ead3f4922171a990f5.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/018dd492b73e5858609dbf0f5488eb83.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/01d165ec1170956fe61d09c4e6f622ed.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/01ea835c546ad4d92f0f6b5c96433857.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/024a5273d7b06566748bc3af0fd0a5e2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/024a9fcf3c6839003a16f6697b23eb41.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/024d91a69f693c9f9e3261a11c7ddec3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/03135f6a3cec7f4e3399da4f3680aa67.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0375e570bedd2c1971f3209966f8a016.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/03fb416e2ce8e109b230a1a5eef7f4e4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0421f63e65b44b56c6cd6530680e5548.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/04bc8a6657ead2cb0040495ee2449073.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/04f36d827bf62ba22575845abd2cd686.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0535f8e873fb35d9908080cfca034c2a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/05baf0f3e50f888066fa7a5089fd9430.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/05c0562027595fdbe6ea4865b2857d88.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0616cfeaf489be156925e7f72933ad16.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/063a4a8ad72b7e35028c538ad6ca0054.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/068991d2c91c4557fd3b62caa14ac42b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/06bb5442887985888d34813121e4e60f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/06c01c623ce3df90cfbcad78608b7e0b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/06f78cfea588d3ab81e31307cedb40f3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/07198db7bebe69fdf9123a8878e15fe0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/07e0a4d3d6d5d46bc18fc3f86fd8eccd.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0838e809552b0e7687dff54b7d86bf8d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/083996edc86518a47d0c162ad619dcca.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/08565520e94a144d9e7724ed9faf6397.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/08890d707663fddf9b508bf9974438d0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/088b1c0b5fa93a460c680481278f5247.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/08a89aa6731e641e7412d3822060b42c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/092d2caa24368f56233612b6019b2cfe.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/09aaae767c369d3dcb56095e80518ea9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/09ff8eeb96236d7d7c944c55cb65bf8e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0a15af430229d19ba86493002a728d6b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0a3fb252edf036d0befc7197abd7afc2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0ac2879f54b40e477f004c5b575e3ae2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0ac54a37fbb19e4d38a949b9d213db6f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0ba19a1362f1827134c58420316639ce.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0bc9fc26ea8517f1ca84aaa20778d2be.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0bccf4ff604195e928da0f96ce17cb3d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0bddb0e71ae5e10ac50af3998c82aa24.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0c9cecb6017cd048c027c5c00a3e005a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0cbd494511dc9d3f08462aebb3f08a0e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0d420d53d31ad18f63030453ee07df30.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0d50a0f54aec320e588a56d5e608ea3c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0d7bff55519270e35592453080503caf.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0d93825688787383bdfc3928313e6317.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0dd2286d9b48b256cce0dc7f5e787a53.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0e4c55874ee43a24a1417bff7d4e3243.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0e7be3751e71b7d2e3a08e7d403339de.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0eb4748c9cddfef8e2b3b8d24a527213.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0f018811743efcc8abaa0291a55e9489.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0f2b0cff03a943ad3e77017a5f652d7e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0f6f3b9381ed7c5e3300950b1de87d0a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0f92c06c08a03be7d3cd7beaf2595a4a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0fba588204945afbe73b4dda96f17c67.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0fbca2e637530cfe656a5afd6f93df1e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0fd53c38ff13f0b5c21460a7e81da046.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/10267c0ea85d17f4345f04a5f94a25c3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/102b99628f017bb3836cc370ac140a1c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1057a07b83ba65107342a7356ee335ee.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1058037bf1fdf0ce15e141ca4a8c5130.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1089399d6818798ead8e206af6b93c64.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/11708c6d46c68a498ed251b2a4b31661.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/12a2dafccccdebfca7f9b6014a998908.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/12c267146d5575e3daf0387b24d34757.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/12e571e75e6807539e853f96362448bc.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/131295e0302cbc98854b360ff1b440b4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/13367be1abe079551709c1d78d307b2c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1338212e36abce3bec13a5f94f947041.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1339fab26e29b773cf6fad0a80be8af7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/139cdc6c1010890a7bd7e2fe33d653ac.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/13af453e5931bc27b2c6d857db4734d1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/13ef50a6498949c46390239e9f389c6e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1462ae1ff9710380029bb8085f0a09f5.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/14a6f9165625b7ff823e06f3d337c3ce.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/14c38cbce9c8f0dec58a4c2e80d6a64b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/155034b20152b8ee2b713117a6dc3fff.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1557d239ebbe9fc78408b86057ff31d3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/156cd8f615704a54fcbca2c78f455581.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/15a3d1098204e3698244b0b1fe28ba4b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/15f562ab07b6729287fc291de5985c5d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/161a0941bfb4f401d4bd2ef02bfb1cc1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/161e73bf0edc5b668560c363ea9291e1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1636430a6cd50dcdd4912dc80117450b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/164f00b8a34453467cbdf39d6f5ae05a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1655730eaba36f88e24eef1f62ca06ba.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1656ec17e43048f7adf1a0bf14d2eb04.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/16b9855ea43e138c1ea9f757b9541298.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/16d63c91dad3b2fb7f587c0fbb10c4b9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/17e119c9c56a343e6bf1db39479eeaac.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/17eb067409590d1d36eb775aecfde424.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/17f183afbe5f16297c833295cb2d3385.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1816fd114e0a72c42d8646593985424e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/182e9412144c9c76e4db5d551f00c8ee.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/185bf6065ea7e52a8790fb6fdb00a3fe.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/18a19da15a777de664434709365248b9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/18d1c97cd1a9fa1151aef69e7a84650c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/18e2487614c8d4e42bb661894dc2710a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/192848b00b4aa9abae37328e3e3461b3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/19629e0ac4e90db1530ed27f7d3ea572.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/198643733bbecb9983b9a9b6ba09d104.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1998e89be33f97aa321d40657779f1b8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/19a3ab4f6dd50bfa59bc273b9756e28c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/19b320409f359a5076ebf86b6db93f49.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1a334a887020bedfdf686212d6ee8fc9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1a7c00fb964dcce4013ca613a4ecffb1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1aa7a73ae4066c73c0171c2c0171120f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1abbeb512eb0ee31e594286f7378483a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1b328e79270431411a4105cc04766f81.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1b64dd87c266e3a1a3b8bc47ca7f8f9c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1b96328cfd5161240b956c50db9da611.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1bac247e288ffc2f39b69afb5edd85d0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1bc89cbb8478e47ea5f21dbe1b5aef2e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1bcc2e765f3ec9325eb3e7f26a80efb9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1c54362cc06c10affe0ad5dc391fc097.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1cecbc5941bb3f2fc7d77eb856c8174b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1d1316acd36600691c3a3a469732ed3b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1d30c3c97478102ffa4695269f1872bb.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1db380775a448eca6f6ca1b7e9cac997.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1db907ebd4ef8927e6129edd4bd51a79.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1de1a2db534fa54404d252a930d67791.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1e337714085bc8f81959ee583b2bac59.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1e43173fe41b7bedd6b0443c9f8f52c1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1e54d43e51d4a8c7c681413cd8a010e9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1ebeaad92c47ae8659221affb32c0c24.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1ec56554bd6d6a61921ffe4b3adf68a0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1eee3dbb935848d69fa712136f58a52f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1ef9d8c97f05081cde0d8817b337d2f0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1f0e7c0ddd27073e1c3cd1ba51943e8b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1f375507c30e04a415fe1430a2e348d3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1f729d61063c58610385bc4736bbe328.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1f9e28171dc32f9f6b6b38864ab91544.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1fd9c3c35a0a8319c1840cefd43ebf59.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1fefe4293d23b1997764d240aa199bab.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/203473aef6cb33fc75f1ec547a91a860.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2056f79ca3d5a6130d0cf4f0d8d5116d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/20688e29e9e30e36c1feaba958758cca.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/20c6853fe3e50a43ebe1ac3b78d6bcb2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/20cb791f2fcca081fa86c3b05ae0d279.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2124e1eb90cd78a04d3e9de5c6a0ca56.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/212b0e07e39b78f98abfdb543aa23233.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/214a7fa290fb1d4e781d1a74d8304e1d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/22ca2fb7130874d362fa27f1fcd42a97.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/230d9b2ba814cb55ea2ddfd262ac3f05.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/23ad24f4ba9c49dcc0556d223244cfca.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/23b763675fdcbcc8231a7331a5ee2054.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/23b7bb244e75296aa9d3c9ce8909776f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2405b94d92350980466907ad21b177fd.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/243b73642e664939459c368e8b961eed.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2482b9ea7ec49ff82dfbdd25a165ac11.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/24b31e4dc0ef9a1b7fb4982fa6fa1d67.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/24c4675db1fc6ce5fef94865f8e8657f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/24c4e43259813c107e1880cef1259ae2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/24e532b00dbb22fbf8d3eb69d9c43fe2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2528763dfb1415935b12345e46536883.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/252c16abff5c2aa55d5f5649653cff6d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/252dc1039d55faf8f96f0d0522a87f68.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/253c1cf9c37f194ff42dfd8d699f542b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/25442cd7d6867aa14a8b4f3e84fcd312.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2572489e8fbda978b69ad5701ac183ca.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/25a8971dbaf318a9fafa771398d2bb27.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/266ebc793a3a4f768f51843d30d928b4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2692ad9b21167e92aeb5f680d04b2943.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/26ab9ad844e0fb566acecc33a59d8f0c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/26c9b08fe3a222681c30e122d7100cfb.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/26ff5049791fd2ca3b340179e8bd2f6e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/275824c44f2764e3dabc1aa394a63f5d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/27614a499cd42da30086c5fc04357495.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2785b56988566f9b40632aa4dd2639c0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/27cedc437426bbc65ea5eaf99a103f93.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/27e4f1d606aa041331f837fc36d80303.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2802b54b9ce502a3d0223373ef29f9e5.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/29217bf09348fc6672f31a2b0b75dddf.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/29531f6ee4db068fef479ffe078d3407.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/297e8f9878261738824b46a843101fad.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/29e4037dfe177961578e61016abc238b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2a11e5c25520dfbf4f7acfe8eeb17ac8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2a12d8bad11354d42223677b019756f4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2a51f4389143ab687afff1d2c48e11de.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2bc569ff922b5e5721ec56382c202a08.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2bf7d3943ea7c1c1f769454a0532b5cc.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2cd539a53507a68be0b187b78220b5ae.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2cf988cb3cbf0a33905d0eb8f22a4d10.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2cffbb67e88753b5ce9e76ad3ca8a02c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2d6644ac20fc154f3f87991a7a72ff0b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2d81f892b114e8411d2ccefdce810344.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2dd7ac714f6f2d23274b25426ba48c28.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2de05aac0bfe7d09d439bd446a987cba.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2e62bb50610ea90401f3f22af756bb90.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2e9c77df2fe9918c86b7dba5d8d4eb90.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2ed9136952126655cd5aed1eabe4b643.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2ef14dde986e023e3b29a9418ac383aa.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2f14336db03cb04a3a13672ec39d554e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2f661a1ccc172fc4d93b34125e501b7c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/301bf216d9158e5e00cf733564fe8deb.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/304884b9fb08dfed4f6d0ad3302dd481.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/30734a8d96f16fc032fdae23abb125fd.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/30c454de1091e2c8353031014f357d8a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/30ea0a988ada37d49ae0a3b625001a2b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/317fef1a77ccd76f488fd3d989d7277f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/31aff6c22410f62e6f81edda3c76bf37.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/324cceb0ede63ea0451864b7374851ee.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/32931cea51d456eb118d48ba251fd96c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/32bcb16a2ac96d8d06a951f68454547e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3358ec54f4f2d54e20a1afea0444603b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/33aafbf05b7a45ae5fd4305bd6b71bfd.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/33cc6dd020e9e87b38d6714ad48173b3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/33cc9a0a271a8969ce825a322d871eb0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/33f6fe0cc7349bc429d851070034b9c7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/34265621dc29035f2a6374aa4c0928cd.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/344697d5ea9d8f7a88988a4c3c137e05.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/34859f8d0b5daf546cd23ca7f8980bec.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/34cfa27bda86ba353341d82e6e2d3e3a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/352087fdb9d79e15044d8cb56361b7f6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/354270d1b5c84e02c6d8f45bd34c9f93.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/35433a835cefecc321f4bc6a9bc71adb.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/358ab3e8a509856a29aaff4ff98a2da0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/35bb5dc037981ac228b323279a392f05.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3709202f37839ddfcac127e14830c031.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/373ffa4e024d68f6718fef76d254c10a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/37af211faff08dd7fcee38778b23c3c0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/37e115a70165f9fb469417d674ed1159.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/380171932c2c5d30c6a872fcc7cf4f70.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/38141676ba07b3162e0880b7095690a7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/383c368d567ead936df453b31aafdf03.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/38765786334f6ae590c67b304a89846e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/38e8a13e37e89e9f155709eeacc0e130.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3947f53dbe2dfa9f425ee519fbbb9627.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/39572c8f0ee635b9582ebfc68867a583.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/39998cd68c76b506594c31c94de6a4e2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/39a1abca7498e67aeefdf5ba470e5baf.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3a05ebbefa111e8abc5bfca916b29f0c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3a4ddda1468ddf3bc421107a1151ec12.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3ac3c7892c28af27bdfa389f63348e40.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3ad248eb9a4b550fb9eeb6178eed85b7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3b04e9d066ef9b9ab2e9513397872508.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3b0b2785db0720c42f788afeda444bf0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3b28f8967114d50e7c790ae4e58bc138.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3b5b69512930da8394e1c516a89f7679.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3bb814bb367bf8b22e903e9a783255a8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3c09cd0d477c5c818cbf337a4dce155f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3c1535c54b706927a6b9c600ec82ac09.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3c559399b79d0d44f349620a953f400d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3c89b85cf2566f5a97110e4f8ad1f9eb.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d0bd114bd539dca3c37c802d2d2bb82.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d21cf9a8ccbc2009bc9310467df503d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d2c231825835a7f33c3a8b9999b85da.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d495703dfc8712ca625622618c39adb.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d9c7eb149e5ef0c470fc5eeb3293e64.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3da2cb4374aeef3779f181b50c67deef.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3e5f116148bfbe30079ea83289b85d39.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3e6c5b9a345590ac8ed792f4a8f1f420.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3e9755e6718b502b3379a86938fef3f1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3f0dfde55daeae85903abe53ec3829b9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3f6d0954e7509c8b907de00979423cc6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3f97dcb9dc399235558efc7b7e2a5e47.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3f9c37a1d0b4e008de2a527054730cab.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/404fe4af760d2e7a22db64188004d17f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/40cf6cc0f27841b8e1b1126c05e94031.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/41099fa89d0976dc14094190f9d81eae.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4127977ad3f5e5cbfabd7e1dd44c8b33.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4131f80c8c09c8d7010b0224adc9985b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/413f7048cfedefd240d754103f4c5795.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/424894fb7373acd4163a2d8974573b1c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4255a578c0c4adea9e877ea07a42651e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/42c85c6092ae84555be25554924f8ac0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/42e35b4e0a15c96f7603a71be92a0cf3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/43c1d9494197ea8b750b25dc79e5df92.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/44250c2677e5f92e144996e809fbcd41.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/449bcec9a6c92331dc76e27325c5e57a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/44ac74930cd0bdb395579fe7dbb11684.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/453e3c641ffd8d9e18e8c97e35726e54.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/45522e099c48a5b043cb2dfa33439f63.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/45789d6753f3f127ea5dbca642664b2c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4580f3f6bcb6ed28b79982c92ea5d7bf.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/45e8630d55a70d218c92f37ad351c3af.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/45e8ddd22bb30566d424faa33d6e38f2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/47011c9a66be34f7f7c1ce5dd056fa3f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4785b7a059fa0e0e21eef81afa2136d9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/47f1d5fffa38b7f18e6c9fe93ab5582a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4814204b196308a1b07525a125ca774d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/487d269d8cb04ac063193a340dd128f8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/487f2e24aa3452205edf6459aaabbbb2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/48837cb6ce0fb59876adb982b5052edd.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/48c254260b982877992b4eeb61a81abf.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/48e9362e6e4be312d32b38fcbd540fc9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/49c4a01e2945484086efdae0008935d8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/49c83cc7b12efaa4caa9bffbaef78e3b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4be2851e1ea3829c81f55c701a2f0187.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4c010902a0a21d508521f55704315883.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4c83b69d15bd0519b0b71185f0bcc56d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4c8e3b21d4e2473369fab4ded85c14bd.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4c93c736f37e12c9d376fd42dfdcc60b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4ca2f7e6a71b78e101d3ddae7d362e85.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4d070ac638da477048122564e402a359.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4d6ac172e896a7dcb24729b528cd3765.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4dde8b597fa0a9989b91887e207e0411.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4de515d5e780a7859edabd14df82af32.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4e017520fd4be6a4c1dfb9f70f8c7511.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4e138cb90a8fec9e04c056c9363412d7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4e15d77b96f5f26585cb164e11ced558.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4e1f4012fb8e1cea6e187486c880aa63.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4f00d944819bd9bd092ed77d596173b9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4f667f12274be131d029491dad8a966e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4f958ed2f5d448829002ac08bf9c17b3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4ffc782b89c5dc232782abef5165c719.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/504589663fb6dd5062daa143fcba1ff6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/50dcad12bd25596f0be4c14fbfa19cd9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/510e7af64cd053bb699ee49375095145.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/514062c3edb164ab3948e4b1a0034dd1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/514b4e534abd39a0249f91a6e6582b1e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/51f7ecde3dbd025454e5e4790f1063a9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/52ce8d5066eecf62f2effa92b5d6e5c8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/52d2e885bcd02b78f5e1f354571a3165.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/52f499a872019fb8e145504313059613.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53392c800ef29685aacc26d7f10c94c1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53793eba05cf925b90660330b35f5815.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53b9f88af3390499559fcb880606f947.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53c27964917ae271a0b1fda1ae64609f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53fe2e14274d4ac3fc8493d0682f5e71.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/543f709458e1fc55d05426ade00a46ef.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/548a1a221108ab5a7ff05518caab7781.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/554f45f4c1990b8e7b165a751a29fc28.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5572755e5c6b811bf439f2fa3a3ec237.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/55daede03319fc87bbb77803b3b2a285.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/564066b109017931039158168f5bba4b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5679c2443905cec1f43c9b2b69fd9efd.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5679d5cfa0558639c73d26e11a785f89.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/56abd6bf3a77580e1f7434b396332b9c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5727e0644de09dd82e0f9ff84ae29d00.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/57929e766af28dad62c3b6577689af07.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/579a94ce642e496008d77b2685059844.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/57c18f8afa90c070e2c13cae889a068f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/581b98d8edfac3f24fc5208bc57b18fe.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/582afbda17bac0514ac6d9f0aeee9145.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/58ff00a62d7c69f0b5baeaf873efcc45.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5a304f6bcd90886702924b600c498fda.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5a925a430b7771ae04739a101e5db4c6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5abef28ccb79b61c39e44bdaec2e8a9c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5afcf9f6329d796897538eab444b65ee.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5bd50732b523fe3c8fd746a621056e05.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5c403659a8d135fc7c77649459bec86a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5c79a45619326ae910ca749cba788f1e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5c8113761dce030345c6ff1cf0c2fc65.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5cd4e48a1d7e81309ad024d7734d85a9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5cd686f9fa9595f01516468e55b15495.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5cd74787a1abeb18be2616712a9a64f9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5dc9d9c62c331354eb297145ccdcb11c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5dde6a3854a3b65d2281ece59b1e97f4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5decce76eab508af166d5cc42f40e701.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5f3a9aced738b75096c2c6fe31e3ab0a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5ffe6679b079f25980b01de470757dbf.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/60506a3bbfbf61973a9561404d9696a7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/606c176fcc677a75f5e9926e191f3cf2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/609db062cfb76cfe8d37d7a9fdde4526.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/60bd548ee4b8d76d50822ab8abc37e2f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/612de7dddb72056d5295d3f5daa9a331.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/614858730a1db249067581a0000d3eba.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/614ebd6252861be15e74420e75bb87d9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/615c95ac02a3050083dd03213844c953.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6160431243ccd47e3c99710890816fe2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/61863761596832d6a3a5a572221c1c0a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/61ca751747d09316c5a5da4df72d9f75.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/61d0ff7b49020dd380cf1946ecbd6460.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/62098e3c2fdfa614e90b97793475c05a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/627d9e84c2050f1e63ad8b21dfe0aad4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/62c9a42a4ffc7ebc2e2da3f7da351ac5.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/62cf881287600117953c63b739a2249f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6316e194764d0919061f95ee95c24d52.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/63350fd5fe8aa1bb577fce9f577bfd53.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/63bb13a2d95eedb57d2c566f2df33173.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/641cbee1c55bb852d9a76acbfaff0996.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6469e4239304a13274b0af6a2e6cb8be.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/647f279d088b08e79ee57029ceddf366.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/64f121f89408216490af015f122f5626.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6531967f2e93a316e85968ad011ab298.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/654da3f9d5a6f3f8ebd4657cfb60e0fa.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/65a205310ec88ecdc9b0e143987f8323.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/65e1d36f8ade84826fe1a011a13db813.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/66686038b549eb8ff43b82bd40232971.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/669f3f863917812a5aad9467713035eb.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/66f5727e00ab69c6ef495fa5762bd3ac.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/671dcfa5790bce42ff42e7361adef981.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/674cdcfc5e75d72e67a57b268cb2d7c8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/675960daaf242fc304acc42997f5f5e8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6761d9a3692394a926b110231cc9faa1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/67cc2082f51c3493d37927b395d7857f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/67cc43fadd103cabd453ce0e781c613a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/67d8f80d5128e94afcd8e05c9d63b318.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/68021589884976b211fea7a1b536746b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6811c132f0c1fdb54289db99fb7f8466.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6814fd1f5a973d88ad8e18db290763fa.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/685a00671ecc6674b52dab309f709a39.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/685fbde97e162e8e898316a0ca5eb1ea.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6874e45cafb16e88a3f184673284ea5e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/689e03d98c9ada4ea288165a9ccae310.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/68c20ca22679dd2e57a12461c69872aa.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6a256b4463c2bfc2d41be1ffc23630c1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6ae427c6254f66fc62732edc6ddc1ace.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6b5c01d5529e03f00b956735300e43b6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6b8156e47350f0706fe6e62cd6bffcff.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6bad8bc610e01619ee550b2955ba8ad7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6bfae2cb6f4bd0a25c84cd1b4873b90d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6ccc2daae37222aaf0735232c9ccf397.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6d0bbede8f34a0d2964de8f6103276b5.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6d52ce280a29a63de6c9075a433b35b9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6d8fa2539a2ef1645a8c701182dedd0a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6f1725e81669f9305a3439151ef72f8c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6f223bc6b316b0b23092440555a896fa.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6f6c2db4d2ce36081ac59018fbd038f3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6f9ddbf3c152d3883f97d49209103a28.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6faed00d4e3c1920e974a95a269c6849.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6fb30e63335e1f7bac4ffdf25b3e1755.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6ff25b93f67c0e1ad048553fe613cb90.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/706210c7ac57c921f111e72f880eba05.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/70802160fb371dabcbb4bb1337a5f961.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/71174b75dec785c7788664f7e55489b3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7134f47548c2b955351652ff5645afa0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/71d08cef5ef7e0f411e76c72374323f2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/72026cff158522b81511ec70dcdf4aa0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/72836c22972e722dac846a1335740981.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/72cc72e4557a4e81cf22abc1c528736b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/732aff09bd2c2cd1d0819518db9d0350.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/73441b2ac1f58597e7ab1b53e17f13b6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/73aa55f4cd9bcfb421deb1af301ffc21.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/73cba4855d73187819c25cf87099a594.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7415d41effa5df58627bd735635d4218.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/741f932ae86107ee315fbdb88bfa6a0d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7507925f7256682ed6aaea4c2d2aca10.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7512c7cd273ab4222c4271c553c9abc7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7558d6ecd55b8cfa8c735d006368acbf.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/757b85c3f6201ca3cd2fe354f27b3c3d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/759531a2d64ac993772dab9c346f9b43.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/75f79b51486951278990668460cef32b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/76235edd4142671e43e1eb29f69d3554.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7653741a4131b7ef6209fc437ae56964.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/767b2849dd02b721e2025bd9665cd08e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/768e06591d853849afafee9dd970df4e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/768fcfee15a5acbc6deabcb1741d283a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/76aa4f48dfc92400900361b27ce458a2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/775446ae1ae0487f41edf9102969aede.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7758166810159b5fc089bb8763925d4e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/77eba7306c042aa7b2693e432834a6f6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/78365d652a587dcef8698b8b4f6aab68.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/789f90be8c819a3e1f7cc73ff4ee54d0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/78c4e10d7042750e25a0df8dab2a4f77.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/792bceff46c5343c4927e09c984c9a07.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/79ef570dd5d7ed7eb257f489c333ee2a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7a6076274dc0ffa021d5ceed99d2705b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7a8141295a15a0d2c16117a359d7ea87.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7b3eec52b87c51b8587ce68e77c65428.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7b484005392e1185cd9942f0f1ee32d4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7b816e5ef036f986eb27e74e88588e67.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7baeafd04b96b5bb5f8c4905a0276f28.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7beb94930af6c2c3d922b6886f1785b2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7bf9c0312e56614367ed476ab26fdfe0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c15d51dd9459b70b6986576e00a35ba.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c2f257420c98a77608f3546e2d4e42b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c4bfea85556d58cafe707b639044c21.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c726d2505d5d202db8107a3e7d214f7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c7c9a078033ab1200e8f5538da60604.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7cbc1e10898652b59115dddc9beec11d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7cfde6ebf9eec8a96243199d81d90978.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d0702e464105b4cec37e157eb019f72.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d2b68cafe16cdd220b703eaa11c045a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d7ee2f85103ef65dfc74ecec42135f7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d85c83c09fa5d41f0e75e53fbb034fe.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d9097329ae92c57796325322a926af8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e119a08bbd67f2a15cd2b58d30cb9f1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e60fd470b78624fc0575ba9754e3c45.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e893ae3a6c6e47235b86f85d8e56bc3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e8e2b60ce201607bb7016d56d1fb4f8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e9a0961535e3804022f1ee6d5e2a436.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7ea6b24a19e30ea712147ea82ca375f9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7eab038fb6a9b2a516fa43d19c3e114f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7ee89ab02954a8b62efb3b8ab560a603.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7f0d0c08702801cb4c2c36d71e494ee2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7f950692da36b446ee8e3bfb9b7bf34c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7fc6c0a4d7fc53ecda70eb3ff5d655a8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/807a237f14859821ced70c98a08ba231.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/80d888e66f661473ce0a4583cb0c3e97.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/814613e0ac5d67cd9f9fdce55c8ec0d4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/816ab02d5092e43d35754dd87997967b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/816ba6108358498c381c6a697b15fe99.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/819b61a21f99e6ddb7b249e1468e2c7c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/819fb3068bf1dbbc6c9b62d9a6802700.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/82531ad88eac23be3c89801a6be66fdc.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/829540032c7152c607fd4a1d16ae497a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/83626424d2bc3065e66eb4fb0298b60a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/841b6aedaab5148e1fa1f00a3ef6d760.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8431ae708a8ea4a39780a61a3d1920f3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/844360515e72f5309e4646d0c2fd1af3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/84563c5fe1937ff4e3c443c387be2519.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8461e90ae88f7ffd7221df75ff3632e1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8525ea80a0ddcfabc3d5d2a2d1f7f4fe.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8546938654dcc948343c8887bdae97f6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/855b46a37a8e7a2981b0214bbcbb26d6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/85a622ab119518199a9fbcad4b85849a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/85a87be26b73191ae881543d8f5bd12c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/85dfaadf855933693738def81442c090.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8666d150ab4b46ade2ed09fd5948f624.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8676e9276e7ad1e688eb7fcc2bfc48b7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/86973ee052966ffce0ccf1a0a324585a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/86a9f4a069ab2fd1fc70a67556d28e50.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/86cabdc3564921a02ea6c430ffcb3e61.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/86cbadafab7cc34a9b23181507d720eb.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/870780cca5d71b362695166e90e0fa29.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/87230572cabd7f7cc731ddbd5f05cc19.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8736405022503e64c12ebd5e5c8f1b03.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/874c14f81060497417ac949eaf19794f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/875c4a110234095486828834b0203b33.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/875f2eb24f01a380e58f4a3f89115468.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/878ce89141988cae8a469ef16c04aa0f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/880d7342370f7a03b57e9b3b52b3f74f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/885a0329f7b7e835c42f60476d4d8f10.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/886ccb8a6bbcda450f889ab0f690c1c2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8888f6cdc1120161964a6200de3c6809.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/88ce36b0ccc7e1820c4c17c580d352ff.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89033239c7d547e5aa8410e09011134c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/890902ded3e227cf4a3f724aedd7aad5.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/891d42e635294e5cad8dc8d008337db3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/891dbbbed3c2d0c197f71b0656f186c7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89276d62d6f90ddfe13e8245115c7faa.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89a952ae9456c577b25ab8ce86f9b127.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89d595f80f108db3dd567a0467c3d88c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89f5de3b9ca0a34a978ca34ec7d87984.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8a4f82bedea3fbb3acc230df7db97a45.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8a9a7b77de49a07e58174c8c323840fe.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8ad2c75e04c0a31b6efc9c4c73cce91e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8ad723cb07f038c69451b25205c9cc81.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8b0ebee39a1bab46c59e9d64f9070352.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8bdcd29e44362431dcc99d3408686f24.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8c46a9c71bfe05333f8722f1daffd655.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8c5f4578d3c3aba5d3ff56bc85d5fd7d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8ce0eaa8ced7a0fedc8ba3f7c617afd9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8cece25086fce7e18417b586928cd678.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8d121244a22346cbf3f1f66c9e39b3e9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8d2b1d6a62ac697a438255bd8f592278.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8e36bc2c5a0f8f265b48477b305b6a65.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8e598176aed7b7d1ef9ee2ee97c6313c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8e8f50e29b22be7a9e57492dcf64b08a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f119bfbf2f0180405939f6b15fc9101.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f1c87fc30fde6c850e14942621797e7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f4536d37e41ef35d57d386b6ec21f00.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f6119695d73c3dd763b856ea399cac1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f6bb4abc2e8d4f5743e3475b095f866.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f8f44e8967a0361c0e9a331e308bf9c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f9a20148094ef5b65e07936803831d7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8fa5aa8ea22070d7cb1d55e23aae9184.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/90397cf9d5a60d158d139c458162e4ee.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/90e1b3f232acb9332b2c7f10ce3c87af.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/91b9f129de7a430de4125136fa577b7b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9285f113bb1c93841f0aa339b2a97497.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/92d2733e159d0c348452b92d5edc50c6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/932e8588ca7b1c8bbd649abc3a374119.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/935d66a51028b14e51839dfe133d4d36.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9361a0552be8ca021465b5d0fefef83a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/93c99695327cac738efbc1711ba8546f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9468038a7d7e411f416cc27b84bf1598.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/949f402eae7c2e3efd72a2d78a773849.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/94a7b31d3a962fa9e2037659aba91eb1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/94b50768c69af3f3236d8d60e493e88c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/950f2041abd8569848e5229eaa92f42a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/953a44f985bc9ea38ddca4cdc71b76ed.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/95a05e377d4a97bfd20aed87d987871e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/96919433ed7bcc4951847a9e2599d005.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9717485c255ec2689f5774c5434fe07b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/978f6bf7b09be180c9fcf9a14e4286ac.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/97b91816db30b87582cc0fa687b0a249.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/97ba02a27c83f4d4e746a7ae547c30da.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/97c1d5b2c30f10b94179c9798881d634.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/97e0730901729fa04d92bf38badbb678.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/98524e97400db3d5cec8d815615e8ecc.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/98b219b75cb72c27367677fd23b38f05.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/98ca5251916504dec58abde2e3c502e6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99bfea652214a6a41b74106f9dedd3a5.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99e45f9544b53f4e31f711518c2841e7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99ec5f725326327ed8034925522d941e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99eff4f19cfd6f1a75aaa834aa8ead8a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99f53490264348c56c275acca0fc2adf.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9a79b11711d54dcd262eb0c777e8b7dd.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9a93361aaf6a7612454502e9b7b071a7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9ad5a22c7c6ed587c9bec18e32075604.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9aefe57a6886c4c63b2dcfb25bc628b6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b0526a52d458eb2d80a7a58f6a9da8b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b193fb82af1fef76d2705e993ccce18.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b2fb0d294f38aa22e8a94567195fed2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b7bf2e1ee9b6c6f8520c5841617d491.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b7d9f137c885f5a0c697c7b81138347.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9bbc7d2d06425082472330d97296985c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c08c7848349823dffbf16ac1dd7fde2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c4a9ffd665f6d4eaf7a6a8ed0a55914.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c60cb4cbab7836c200707f43bb44051.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c784afe281faed6446cead9999468fe.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c7e324db2f6923088e1428a5bfc1853.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c8ae58463757708733c1377972765d1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c8d0ab038cf5908de0adad379438871.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9cd94333961738671eb031f231f82682.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9cfadf14d721875a86a0a3b96663be99.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9d4a73d1872dd017871d75c634ef735a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9d5e6b6c7741e8f00d87ee67c643b04b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9dbda62a725307cab594a22c41318024.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9e5e1d609b4b142a2fb588936ad39f05.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9e819206363a80c61175f1e39b39d603.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9efbc80a2ba6c3a256ae5bdd2677e147.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9f191a293528f170b2fddc35889a3460.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9f74e1e54c89d47ad93084ce1951258d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9f987287209598d5c53893415d99912e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a074eccd420a1d404b7220f4dd0c0628.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a150b5e884cbc0fca16af4dad96c26a3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a1e783dc063fd3d116ee9b15d7b79b97.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a1e91b083a1f5ee6b7c743cfebacd750.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a1f7779bf16bf476c5c66672c33c7704.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a23af315d9cef507348c491f99cc3fb0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a23c75b1b09039db0be1664aeee60ad0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a257fe1660b3c2e7e225ceb7ea9df189.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a25e24900003730789465e978092520d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a25e346167348694e3c2417d3b40f424.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a26dd757bda550ce54818a97af8f2b59.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a28e4a9541313bc27eb2c9058482d5e2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a29560b4f90a3245e0ec054145809d47.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a2ac554fd0db3a5255a2ba1b97d801d7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a2d39626b8795dc30e45b137fad78c02.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a31b10db33637e83d61d6c3bd4d2402e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a3929123e598daa1f7e5f3900bdd31b3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a3a8358e74acd7bf24b72a7e235c6ded.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a3ccab85e1d389eb6d635159f3adf06a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a441b1b8061d039a90072ef9af820d14.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a44d6d0bd3d836d56e9c1eb8fe83ca83.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a484f6ee5d37eaa55aad1b1be8051d44.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a48bcefc7c3b54bc773fa9f7ab6abb7e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a4f8c3b10d92497b501c1e9afa388421.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a582a728879d60893bcd31db885fce59.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a5c14915cf7fadd6bc4fd1a818d02a01.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a5fa2a57512b0e221d1b8f998a48454f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a5fb894586afc629fcf3e8e806465daa.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a645e9b584f91c1b25bfdd44b1a1207c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a73988c400f0f2ad4e51db239375ef30.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a7dbdfce74f20e69174bc2c77ff68b32.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a7f87cb1e96db0e16470b46b880b1c43.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a81c5093b057649726ec484351986fb7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a8a38c2fa56faba0a9d526b857592aed.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a8b96cff8494ff3fad291751bd814c63.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a953f0291889f76911f8d7af7e8f00c0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a98a8a3c4c6888719543ebdb14ad6763.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a9be83d24ee39185a8be2e44b62bd1b8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa0adc592954ac28e1394a341641c57b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa24b73a63d917835adfa87f802aef47.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa53c93fa15412f2dd49652d49f2cb0f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa611d42127919301e3a4b81254e9d02.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa792f1df61b084cbfbc612220b45c3b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aadc37aef54962f2a7bb83ce41fc6a63.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab20a003ffc7654bb720fbc672a39320.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab20f82cf3fb2075507ceeeaac2d5cb6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab3c57d484ab0c8bca208a0d655c2e5b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab622579e4dc104cd8f90dc0027b6835.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab780283f6bee797dabab0c67e596281.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab89b794693e3535e0b58539ec1669d7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab9a8dcdda85f1d8789909803374fbea.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aba5bec4daa6c11fdd684594778e7737.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ac0dbaf22bdb140be1a11c068f9698de.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ac87279344b5d0d4e22f91b8c2ff41a8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ad0138de5d88eb8dd7a7aab27947e539.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ad40d44fea1e8518be56c72565cbcd59.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/add9a062cdb133e09ee686522d92f3c2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ae13d3d287f61c40edb3ea2655d18ae4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af22ae4d9de1488b00816e6693c6394e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af3cdb723d7e28f0fb254165ba71d8b3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af5f90b0517ff108a2c089b6e8c183e9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af6d91402bf5bd9d18fbb5f080497ff8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af7e05ca9dc6e26118059bbc83f15ee2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/afa66ae9a5d448ec2a2e1239026068a3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b021c58e2f70a81cadaae120a4ac0b09.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b02782fbd52d87eab17fe5c24b326e92.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b07b099229ce0784c0a985b8a1d9c7e9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b0c550e74255ed71c185b5c9c38f905f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b0cb4774fb649ad7cf42a61b1c88a9a3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b0db77aded4316b21d7f9d750b7d23fe.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b0ebc621829225814b6e2e16457842dc.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b1155e20b40430932a78807d5d6f28ed.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b17c3f2aec5ee198f8eb82e36606795a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b21d921a6fe1ed762f066af97b77e37e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b22ce1f95bb82dc2bf0b7de7d26eef1e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b285a431eee55f896eece1af7fae362b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b2c76e9c0889c683ba9800aa6431e17e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b2e333e8efafafffc1056cd478f6a93b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b2f36402178696779cbd5ae767761aca.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b313d4445189b53f759366aa8cc290c1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b33ba39bf871947275cc51c40e312f39.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b3ed2f6e000821a26cefe6b480784c9b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b46e47020634c7480bd802fa7c65080b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b4c7cdb390fcf56407db19fec22bca8d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b4cae86b47a05979be465c64300ac09e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b518851c1217f7d4a074df1a43fdb82f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b59366c05f0725f5eaaa0e87abc9b329.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b5c1a37feeb665781b937a84bb0389a1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b5dcc36c30f6e4c6070a805973bb9770.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b61e121949adb85ef4f86bd3f050eb5a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b66c6447d452f9b13cc50cb0f8c03636.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b694866d63fb09d8a512c9179126e28e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b699a9ce2c12fcd1a06b80a34ce477e5.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b6b7c45763ffaff491fd4137f940602b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b6b9625dcb895b6dedcaa1a65d5589a1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b6bd0b66e0d14e44e3cd0fd48cdf37fb.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b6c214cc24e8f014c0074b2460cf8c4d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b70ba7a811a4a34a04aca8acc9ab6e04.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b715a54323e31072a4f61fe0a7c590b5.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b725b0f15c9e35827b939d571f3cc4cf.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b755aacaa2cc98b607fa1324e9bfe7a8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b844017030d28071aac4d16e94dac7b7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b8512bcde0bd03f388666d453199912d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b8806f0c9e5c5ca93fc549edf2493f63.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b899d82377c5a9648da29177d541e451.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b8bfe236cb667466794b7ba4e7c5ff26.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b8d38ca35d7b4556fa28dc08ace88a52.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b91179459dce704eacd8e56d47d4cd35.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b93a9f8a93cb56dd057eca621f377e39.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b97ff6246886a6d310f6547b054871a6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b998e5ec5c52dc0a189d0c13e39735d5.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b9a45fa17c93ae5367db8f88a3b4b78e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b9b19de7ac9e3f0aff0fb1b0c4879140.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ba61cdbe4e7a38a43a5d2256d18d9870.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ba8d0b375448ea588b520eccb6dd0d74.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/baba6733f7ae96945cee14f6842b230c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bacf33b57426360043832fc29d64e186.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bb07b0ab437edef64a9d7f69e7b063f9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bb1a3899de55a61ad453b19ed3649ca1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bbb47f9068532c006e71213011bd9f17.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bc16f9c82b95c22ca419a9f55f7a4b15.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bc531fca43eba674a8760b3042138cd5.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bc61071b0b4d28a95323d661da61b21d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bc8a2e588cfc24e47f152bad38a47ee8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bcbff27987e033a77bdff4adde10d377.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bd1fec8e38800e69e7ee0f036bc63c70.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bd738a5603e87873df7ffd3dbe6ac8da.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bd79800b60920e5af161c9d59d1b6b1d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bdd6eafea84a93540a5071822b121202.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/be55a1c87bf1113731f813cf4d9ee505.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/be60746abb5738d62705f2d83ef94c28.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bf1bd13cadb47854d58011eb951f09a8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bf3d15455b55b06f73e30fa8e7e74eb8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bfb2b5cfa25f54dad21b1e622667b82f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bfb848fe4c0383bb780a3d463cf7a55c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c01d1b790183f1317221ed5ac419b22b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c01fb35b68ee14941f5fef510fd245b4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c01fd6ee1f631cd746a981cc5a56631c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c122f206d967b08f4bb4a7aefb7d566e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c1f4a45ee5e1f363d12e03f66c2c2ef3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c218dc86cb609e450e5e0b3e2735bc37.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c27180332a1e1390501a20a336afd0d7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c298f9d8f0b021fe164c27607aa690df.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c2af5b57f6e8e503dc2d7925fefa51ee.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c2e7b880f0f6a45836efa3445d86834a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c367b4ff98810bd8ebb03aed1eb7fdf0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c3ea24701ce2c070a187332432d69924.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c3f218074a5fa24554f35d41c7a8ed7a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c41d724b4da6f27acf2f82dd6e01d7cf.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c5c10a2a03b99951c9bb7dd165699ae1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c5fc663fc131d710865184d950a8e6ae.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c5fdbd5a41ac9b5ff6759b7fce6a032a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c5ff5214ef37bcf7db239b02a94a34da.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c6a0cfc5364652cfbc5380750d34ba8e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c728d6c7ebb6777f4b24f771407ceae1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c7323b3e0c6b01cbc672235442b1224f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c746e81377efc248393941ec62d016df.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c86afc2f78633eba946086bba9f6e7b7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c8c60165f252de8814e19f73e4c1ce81.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c98a6a28cd3829b98d21d188a4601db1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9afbcc0e44b41122e696e28136c88aa.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9bb1999c72d2aaa0fcb999b8fdf7f0f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9e2becfbabaeac5b24c84939775b1cb.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9ea970d64c81dba3decc00ddddf6c43.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9fe6aceba49d3b539c0de2a457008e8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ca1d6a3c144fcc2a8eca6e20130c6fd9.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ca4467719d761828aea66d132d7de9e2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cacac33e2e186579bd6f2717f432972a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cb1da9b6dc01bb86c1706839671602a6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cb50b723f788f9cf7d2183650f235287.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cbdfb8e619f468e2abd1df334f238989.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cbee1d284945cab0dcfde91514f64d5c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cc0ef671b8168f7050e5d0f33bf22555.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ccaf3cbbd9490f2f0f30f6871848ebd2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ccc6782058f6d04fe81dee47275ba6c8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cd371c72dac20e77788ab8f025d27522.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cd5638d0f0b089a8b72d21131052f744.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cdb538530ed854a4421ae30f226ba5e6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cdf0391f10105d6ed10a6df8e1d99a94.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ce0c4554be8d8f03c5129e47e199eebe.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ce4dea56cdf0a320ab3db6e53f912b08.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ceef3d514141c2e7d31f57f06748f0f4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cf133e9c5a15a1164a3d6d1319cf58fe.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cf765ba6bb36fde7d35b2ed3f47b1dee.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d088c915a03c77bc89a9e466074f10a8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d0a1616529f654f8e85f409a8ff71970.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d12d9d53a57a563793906271a40d9007.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d12df139d9d845b6612b28d63c6b7acb.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d167decdf90bd31cf8895d3836378c79.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d16c68d0ab3a80081c7ec312ca323db4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d1a2bd7a51d77da0c53880d99cdf8e4f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d1b016c1e260b06c9f4e1fb15f88745c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d1c315d9478470375d2f1bb8e226694f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d1ddf3e95dc619553298fa38c325e3d7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d213aa519d82c13695f294fe2b9f0082.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d262c20cc228ad2f8742cc27973f5171.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d26c4932e2a6d260a6b748d6747e4207.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d2c0d0a6ba3766469b6088673fccfa52.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d2cbaa87bb20f4c60fa52c7b01e7bc47.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d310f40678f868b83d762347c73174c6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d32016716f5bb487c7c22adedb06b350.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d342bbcaf71dd9fb28eaac993f523da8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d3feb187cabf2b68f42d72c5f2c6d115.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d450e6a850bc1b9f570a6c9c4f53abb4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d4c9419289b37089cc02c6c70b417826.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d4e1c74859109413588d5aaba4b8ec2c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d503fd304a9f46d49d7819c6fe3008ea.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d5aed27f888ed08e77264f255f94aa3c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d5beb716adf58c151412f2b2661666c7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d5ef18ce299f1cde496ed3478cf618a3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d605923185af2e57c934f27c976dd055.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d61f7561a0b075df7474e7907054bb64.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d62482850bc9d4e89e34be5058672bc6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6518fd1a9d59445aea5d45d2937dbbb.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6cf1842d8e87e7313d52264f716959e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6d23263a8f514d9f710435ec907bc20.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6e10b9e51fc1d72a5c22dad51121486.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6e9bddb772c7cb92fb82327a1310b02.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6ed22a87864a99d17610cc5bba9aa18.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d7298ddae4c93f1f02c93ff5eaa5eaf1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d7540ca437085c9e4b7a982cebab8154.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d808680e3aa6391896e7f4182eb3a399.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d873341182a854350d35ac685378f543.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d8cde834eec73f92117454119b428fbe.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d8d5c3132ea0ded0bb15b46e8f4efdf0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d91f785fee9465ba52ca2037ea94afa1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d9a69c46e6103a1bc7629a04b2ecee27.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d9a8788c21d83541c6d00a5a947b73c2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d9dd6f9830ee77c859f620b6f4767e6e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/da02dd84d5912c2572c57a6f43d59632.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/da614350e7797b671b181dd7dbe4e86c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/da978a8a0eb70e9f3a0874c94bce2de2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dadd516887f1ce445859a3a001fe22b4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dae1862c2e81e3436854c7167a3d2c38.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/db2f1ea74c09c97c21eabd75275b22ee.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dbb669ea4fb993396d91a84e3c4e03ff.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dbc87208c07b01ebada307292dac6ce0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dbe533b180700cc5058b4cb38f2854fb.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dc7bd4dd36e1ac9d9dee9ae991776a1b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dc7bdadd9163bff45cb3e6b0d37f04f6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dc9c97f593f5b328bc992b7d6cf3ae8d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dcb9ead591c60cc73bea72b0027b0e20.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dd4e01c3a404b697e120de5a08b1cd18.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dd974a4b8094fe5b01a2a8ea91fa323b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ddbf97a99c4b4cf4ee49ab0ee30f0a84.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/de97abcba845314e16d5ff2ca9287c05.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ded32dc618e3429d7b284a1407bbf310.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dfce23f9859ef192ce441ff977676699.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dfd5439e43fe87452411f4ebd3013fda.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e01630daba9d7c685e21b66d0235da30.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e0768bec49c06b70064475f1d04620b8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e0a0fb2c926b62aa0e9f3b7dd29ad2df.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e0ee6b7033dbe46169b4518370bda33c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e11bdd5667ec33b8bf5e4970cb61b590.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e133e335b9e34caa8297e7aa4e7baacc.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e13491f7e4ce140ba7a97caf32e6bdf8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e14918f484b450b31449c9cfeadb4d74.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e1c8926c3d01980eafdc2c3180826b54.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e1dfb25a222de9e02093cd2320a01279.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e22ac344d1d92d0a45d857319a31ab70.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e2a502f0402b637c3b5db1ccdb25fb61.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e2b67e42c1f88376694b6a4c4332f8ea.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e349c3a317b4692f88fbe1c2f9550650.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e381598da10b8a7bd22119e0d2fddd11.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3bf512165d0cffeed9d91930b48a552.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3e2d910ace52fa2d6b81ca1ada0484c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3e9ab66c181c1968c8cdb3bda22e3d8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3ecb138c60227b3d36960b80e6b9969.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3f2abeac581b5b6d531d5d6c1fe2972.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e4ae4d0417907bc046df141816330761.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e5d29009315cdd9199c28f9b4b7fedc0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e60a704fe016af2c1203fcc215932b89.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e63d0af49aab5f943fb4c74216ae7969.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e64efc5cf5db058ed929e7d8a34bfeaf.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6511fe6ea5d4b1f4f0652534dcb98ec.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6748fe9f71e2d4cc2e56584ff7af39f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e67be5e6f883bdb1796d879ec9863175.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6950aeb6e43981bcd6c37503062b363.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6c42b9ef60841473295b5ac704f3066.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6cfe8a895e3920fe6530d125607a661.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6dc56edf4211cf70bb21a9079e8fad4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6ed675168ed70283aa2cbca2ff8b375.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6f46bf7797969bf38623ddd570a9408.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e71b0de681ce977be56b1fd764779892.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e76267df26cb369b5ed1dbb7eb0a3304.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e7a50aecb95568cde974a3155ba578b6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e7f387540578c6de71bca05335eb5db4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e81e2808fe55b860af30840346f58759.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e81f93a95008f3fd2ec191aaca86fe85.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e83668047e25d5f73d50252507f9f2d4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e845556a1b726d19eed64166a235e3cc.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e88189acf062d3c6017180b7e1c5daed.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e884072b86f47778acef2f9a4378ab0d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e88fd65b1f4b16872f90a11efcd6101b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e89be41c77735c9123dca34218d6142d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e8bf5c849e8c6c07236b8cdfa743602b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e8cc2b2ff44787f04455e66006dd8e7d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e8e45b323583b50ee94c81ab4dfd9447.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e90cfb0d261392f86af98fe66bc3d7a1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e93b7ed193aff748bab5506f0ecb17b0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e966b5ddd5883b9d902757a63f811e97.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e99913b8e2feec0714f9db3c4815e94e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e9a90694356db46c54e253119acea3a3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ea3674e09b8de8e989bde545aa574bff.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/eb009f3942389ab23b87c64e7db10dda.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/eb0afb42fb2569620832f9fad5703b5e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ec41cd654443d0332389db08ded1eb33.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ecaff9787a434308f5e7b5e26728b80b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ed2e95ed8716218b6caed4d6b6140050.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ed7756c3f3c50164d26f8dbd623060a8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/eda5c3c7718f3070479dc8264b818972.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/edad635a8ef302e06dc4cbecec03f056.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/edcde9aaa4d7b55b8034212857aca0e1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/edd8f46d6e4ff0f193cc2d82ccb24f63.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ee6083c50b40ff0c8a2828a17324ba6c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef0e92bbbee4dcaa25363dd1ff9708c6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef142b889873ac51ff9b784d8db5e9a0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef2633e9d1e96b147eeaa2c12c896070.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef6f902af6acf7d065bfd20d91cb9ae5.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef8337cf15c42924b10ae3a502cf0424.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef98d3f6f1dc4fefad9f4a81c0560853.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/efad6135fc1469652c4e4a49b8e875e7.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/efb8e140b425665084ff3e98266b531a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f00bb17d85d51e29e4ec1d51a2226f17.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f05d20abb2b9936d9a522fab738108d4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f0db95fcb74fbc15d56e0ade5c34a96f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f104dc3ca2a0360bf8b854f76b5072ce.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f13fec218b99e2dc108126d2334a9ebf.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f16c02e82910f941af67378563d3b415.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f195752519f8dd4fd2a9bdbc1b141397.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f1ea9f845f208c1bd0d5c86730759e1a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f272b5c0201d78e19128800eafbbea76.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f28c3cfc1c94c00febc3717f177e1e28.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f3870d18faf4bd7b6fac66f7119397cf.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f409dfebaaae86cef4dcdf5306617649.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f419831f490ee7a0a50306b1f409d0a0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f47073b5a23aa6a01ae67530540b0c09.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f4bf4f9315e86ffd5e351553ed86aa4e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f4e820989083bf0d3f6a6fa58d23cf53.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f52b92c0cccb98f292f60d035dd2ab94.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f5779c0b22016b22ca856f30c661d448.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f5d23fc3190f08cbef79623ebe31a3b4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f5e120f536fcc39cf654f4c94db1da9a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f5e86297f0173b3e74dccbbb7056dd08.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f618add20c90062744d516dd45a4bf51.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f67f614434da278ba12617e415f79d26.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f693718414860f5d84e6bc44bbca149e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f6a6397e01be24efb536c36ce04ddef3.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f6a72b786e9f7e3c1d77c7b4fc31861c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f6d95b0399ab777293f40515cab97d51.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f6fd3d9a2d77bc871d1576b63eba9af0.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f7301422174591a9d05be1d17e656578.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f7828e14ab620601c975a14748681fa6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f81476f1b68856abb2403f4120c4928d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f874a3d818f17de0b3139cf12056551b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f8c4636a0c26c3cc041a83cf078aad9c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f96787979e2d56bb246ee62a31b5d865.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f9c65d47c8441b284f3e92a262f291da.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f9f5ea2a009bb50623136c1c6591a903.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f9f89c309709d34f6bb32f1bf2f02be2.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fa1ea8c4f4ddd462c17bb8c81aad432c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fa7fe8108802c83205c66fe7caade124.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/face9dcebae4da2f8a8159bfe59ee8ac.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fb4b7eeaa98f0f6b6a1bdd053d5beea8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fbacaa34a04c3c6221d1ffeed14089b4.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fbba3c9273686ea5984366d2c4e0da6d.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fc7a198e1e6c9f93147c2195b7f1594f.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fc9aba974677d91558a3f7a8165a6f97.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fce59c14afae0c28214e78dc047f81c1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fceef5e956eff358ec3b956dd9e2749e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fd007672b1bfdeb6ec15ec3f9c0da5ea.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fd83e0bab3cc6706a8dbd1902185167b.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fdd51b44cf3ddf8dc6a77b9bfc19ca1c.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fddadb61964144436fd9980dcf8144a1.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fde51bc25cd84efd04b7e429fdb817b6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe0db3048d5452a58d50970966be8fc6.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe1d90af8cc5f60d6905a005e026b5cd.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe4697abfff8dd17fe11ca475577c38a.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe642b4b7ccf1bb853a35278c80e90a8.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe64c41bfccc5883f85639a8a9009f7e.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/feb192a0864b3d014f01adf5445cb6ae.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ff7d2f8ab6790a3c3fa66b4eb6efa152.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ffb7b85dfd0c732e3055ea335bbaf870.txt create mode 100644 hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ffeb17610b24a45fbb9c9b687caa4d56.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/009a7e97021d97dae6673b80f5562419.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/00d85d76fffde2afbb5662ec32d4e6e3.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0109defc816d4d3f9ebec520758101ed.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/013b4c04b2643efda758e27a68b47e8b.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0140db605724c01ba5142cbc218cfe25.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/01c7ed9c137d1361d3cbc3425457119d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/01e020b4086fd8ecb300e61150e66444.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/02f204657e32d9898613c0cb56cb5f19.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0304f393f7eb69101ddab817824ce675.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/03256b23586b52f75fd89c48169c2580.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/03e26365704345822c52eb7d4853e97f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/04f36d827bf62ba22575845abd2cd686.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/04f8a5805d9b266c0d91dd062014dfaa.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0583ad55ecedb4ae888801613d288d0a.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0593d6a8f09c1960815f4c3d68355d91.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/05b4f87fc4740cb39374870227371ad2.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0757d81f2a087c727869681b09734a65.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/07e1e3b1060912328e34746e13ee19ae.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/080ba59085ef88048ec8415d3eaf742a.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/08220ca8d594cf17da36c9d4b9c57195.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/08b29d17e97ff3a1adb8787b7f969578.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/094846640c380b7e9c6ad297e4c2672a.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0a80281bab3eb2e167666b34d9167b4a.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0a9ae1aa5c8309bc02f169f6c7652822.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0a9bff5ea913ac5e5d9206bc34dbf4a9.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0af1caa776bdf673e904082cc2f76edf.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0b3240f52d3ec0f6246e64049a3c5444.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0be40c85ed6abac7dc600b8164aef739.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0c0198c6bff66812263b06f14ef07b57.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0c95c0d94a267ee41e471a9c73baff54.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0cffb0162877dd7032367bfa0592c83e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0dcbc4d598c387ca212731a3d17d4130.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0de73b31c3c38c538bbc0d055991d1f3.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0e1ceb1fd5e14e57733032d9070e5ce1.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0eeafcecb06a43e3f8f9b5b38973992e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0ef2825d91407a5a7ce4904c3f626804.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0f0438743b8c051059471f36ee9ceae6.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1043e72a8a78acad7fcd3464fd6c0edc.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1057a07b83ba65107342a7356ee335ee.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/106c76e80c18785eb6b754a42cc3676f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/10ffa78896d3ab41de3dd9989818aa8f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/110ec995a4af1159da4ec4699016a91d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/11170c3c4b77a5b0ecccc3584722e9b3.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1129caac17eabf0f916b52f2b14b53c7.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/116b3097928f2d0b478adcaa88f52631.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/11ccd14f27f1fcae1803e6a1a787e7c7.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/11e1ca8c81c5e711df3b8ae8a5fc6bc3.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/13652dcb732f6b94b12e2c54ce09046a.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/13b97793eec1064db7bf89855d732bab.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1485fe3b91a98e108dac134fefc3ce1e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/155034b20152b8ee2b713117a6dc3fff.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/15701bebf45106e5aa9c44510d2690a0.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/16be8ffe5ef1fc75e49f0b4c0dc7b333.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/17af4c22377adbd21b47956d4dc6868a.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/17f1fa3d015121a35a61284d754b908e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/192491b35377b986c5c8650b16eedf43.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/19726a130475df782a8f306ecfb53baa.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/19caba426117594cc403fb8ff86547b6.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1a62cf7a7b99e7cf533835e6d1188983.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1b4194d1d60be754fde2ac79965eed27.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1b42a7028ce6b0a4f197366472285b92.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1b88bcdc113af9db3b348edd481787bf.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1bab06733afd529dc3df158780fa2f9c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1c33794f2acbbb2bae3dc99af1493819.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1c91cc97ad65688cf3ff8dbd3efa13b6.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1d30e913f0d6c62c32a8f38c9c131399.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1d7ecb23dd0021c6d0afbddbf3d5c877.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1dee58bfcfe52bca44b0520df4f94f3f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1ea40a218bfff8bcc4e41a87fde1bba7.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1f2f9f7d868a3703647f73a5ea8e57c8.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1f375507c30e04a415fe1430a2e348d3.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1f8518a3b4eb317c3a094594994c918e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/204262c758c2e399c7a7f668cb035c32.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/20bd48cc59aee5f57a37c3e19ccc5b81.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2132427f941a8eaf80e639731b26f8cd.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/22107b73864219371dddf73da066786c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/222b581b22a76b737eb4070d7bd7cfca.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/23532d65439430cbd36a4951c0c7af05.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/25863f08d537a978fca92941aa8542a3.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/26e77bc14f38e95bd86bee67a44da43e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2761ffab840875beea0673738df78bf6.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/27b663a9111e3ab540465370e6ec1e6f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/27edc29c28067e0c199215b30c046517.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/29a82a5f398c44c717e5963b8aa18ce0.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2a27d33108c135b78005316e25b7344b.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2a37dff08e425c14579ca4ecb232122b.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2bc4c2dc4a0f69a21ff2381dd4e4dee3.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2cbf8c9e27871c5350b480fdc251e005.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2cd54245fbc81730d1697b2224ba4795.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2da14cd8670dac91bb5671c7bf40b327.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2e32a0ee0daab5ee5194a2f8b5e0f586.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2e677532d5e6379d7bb9227c73c10208.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2ee752feb40dded57dfb417a49803f5e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2f63ed89bae4f75af1bf58e85899a462.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2fc6afecda457b5e083b8395cf7e37a4.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3036daac7bf852527515fd961c83485a.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/30550bcc40a53e823571bf5843f595f7.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3159c888bb0b70dd182433f7b1d04909.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3186f4ce35b012e3b3fe8b8db2671c83.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/318d149ff875c24ba2d4066346d1e9d6.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/31b28e3fd6a231d6382367606843f088.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/31ccc43eebe23e65879dea87292277ff.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/320727f387d0c70e30d0ef6650212794.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/326dc5fc5b0a058a96c3690141849192.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3332c0fc81c718ed96a430da7b4dae82.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/33c311c9a9458c5791bc58d1462bdc93.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/33e44da886008ccf1812715a8b3ae157.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/346710c046ca0d5e1dee497c8b08997d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/34df9e42fb083ffc5411e73eba66d43a.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/362fcc1a70d9c315b94c6a3317111b25.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/36bf6e670468410177de50c83fac4b0c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/36bfb1e4d19d7a1325a7d1cd647175a1.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/36eb0c3c00ce21d912db08b872ecfe85.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/37431dd17168d3278269a68997c1e2a9.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/37481c1fd1e3f459ff50847dbbeb5a93.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3795bbc85df7841dc04e3e14edfd21f4.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/37ed57c07862e4dc18c7ef83e5a3ec3d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/38aa35b99729041734924db15ae6523b.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/398550e0c7483b15fc97f5e17b33fe94.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/39ef765bae2d2f3118f369de7317fb76.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3ac0f390b8a881b74e55f2af3f29250a.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3b134cad77abf272edd7323c9be89787.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3be2b5d228ad9dcba2ad0a01d24ea9af.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3c34b3c035744a0f64d8d979ca867511.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3c6aaefa8a430d08eb1de57e64b1e32d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3c7d7f3fd805b7c10784a2252f0e62f5.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3d22bd6dcce2054b85e54e23df329bea.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3f23c2473ab75911807d6e2a69933e0d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3f433eb056df56a8d69c6a1ea563e74c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3f78208475b9dc4d9a8fc8d011888f02.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/400195dc9a918704861ca9b3533fdb48.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/401a6529b756023fafddc0ecc08f3a34.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/410035421e5bbf571c52cf42f0bc283e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4195841bf1ecb3b7f09a4b97b6225f80.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/42770b7520259afe70390e59e0af99a0.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/42bd385aa6a3f544f17bfa3a2efbd533.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/43519d83899d5c69878f9c444f8120a2.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/43605a2b412d6ac6f4449a0ed60ae30d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/44dbfd2e1b8d827e74a8c26c0dba82b0.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4510f763fc87557edeff52dc63c4362b.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/452b4d9454ab5efa7e588537759b8b65.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/45d878d88d345bdf47b96c54fb19020d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/46bf4c6370fd7a5038a576775cf047a7.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/48588868e9e505c3ad9ed0fc1f38e7fc.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4999032b48901dc30550c8b43a0528a0.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4a4bc20da64e111c69659c49efb6a99b.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4a7ecc87a26e0406d0261d9d0c51af1b.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4c3b7d90e3c48ccbdc3dd899920427ab.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4c91928e0d18fb9f935323e21a7a377f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4dc3e2b518cff881958a0d8023d04323.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4e4e945cf266b758ca86165a7d8d2b9c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4e92d0b632411dfd1f034e6841285b63.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4ee71c6c6465bcd633e17a88bb66e6b6.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4f2e3ae76b23aa8f37e5c1f6a6764cbb.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5019576f93e20855db14485bbef2c955.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/51334487bb9b1a0c74d8fa63e934cb13.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/519ca1605ca2e29195f432ca7c6b9cee.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/51b36552854c5e2fdcb505e67309fbf8.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/520d7c9f42181d562be5fa94b7af12db.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/529628f3551401356c3071efc858c265.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/52a3837bf459d37710dd704419e496de.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5349d602f9deb7dd510eea3bb4695bce.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/541444acfa5eaf5382767dced1c34dba.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/54582ae38ee9947c1926d8193c1ae8b7.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/54a2e506d9f0dc65308355b141269ef6.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/54b7c5bf429eb9e20ed7db62ac737bb2.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5580c1dd0df32648b5ce98510507abd5.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/558b1b333ddd1542bc561f02706c1fc4.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/561e31e4b8f46b9687a8378710ac3b02.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/582729139f879d1590ca60422deb8841.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/58b6749ecb2db5b30fe90aafdd7e2598.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/58fb78f5d92833e1570d0fb23857fd6d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/59e7550ded1e0f6bd251635be74f1dfe.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5b3153f226bd5c74cd48f228b8f7bd8c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5bd31a05874d191357a938ab4f43099a.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5d4c6046a844ac9ba956624e854d274e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5d85a738255bca6f79ff36cef8c21c8e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5d9e5e18e9c5f3acfcd85709d30e3300.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5de94b7c29c8ca911b9f04f08cbbe52a.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5e0950103792f0632853c84a6ebb1387.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/600a72d948d2e5c49beb1ba99f757bd9.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/60462687400894cd6b98dc383092eb1e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/61533beb53948314aa6f92a4750a509f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/62619e202ab8cf792019f56950399e2d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/626f38915c39a337b0ba32d7979026af.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/639bd3499a527300d3963cee02c78d4c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/63a9362a0fcce0e2c7aeb26f0ba700bd.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6472a94afc8804218f79747af43089d0.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/647cb7c0cd83579bde57dc4ad34c9cd9.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/648480a86f42c3d28e66eafcb09710b9.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/65a965e01e4533ef2c33088a096a1dc7.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6618fc3a903127e48b2c4fa624b0dd65.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/66608aa57990aa2b8bd49ae3994569da.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/66fa72d54f8e560209ad9464de945c18.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/678696f9eb5b903bbadad15d696328a2.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/67d8686a17ab038abad3201430c57d22.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6a229e209beb7637e4ce5292d568798d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6ae61d876c63fa6cf47263c7a2ae7691.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6b1be0537a54d118a8763eafe746e904.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6b2d3f4f96511774eb3bae27e3af06ad.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6cb874c40ca65ceea675a7373018cfc4.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6d13c490f207acee9e98881e13adb0f1.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6d5befea960e46a5c3274d0afc41ed1c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6e0f25e1a76ff1cbc9d0180969d3b54d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6ea4be782fe8a5e54d5bb9070c47f71a.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6ee961549759ead4213dbaf056bf62ae.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6f7612493d34d1f1b8ec804747165c32.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6fa30962d8f9c30116e466965179387f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6fc67db2d6f8d0c0f40fe81faa04faa4.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7009b0450486cf01ddb3deae2baded34.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/70bffc035ae5d0fd2bd314782cf69620.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/710087f718f927c0d21c5f43b25bc85f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/71c8e9c164e8bfccecc6b0d0c711a8ac.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/720436e9c276a5dd5159849e1d09e8ea.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/726f8f3511fe3b8356332c19aa3ac299.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/72cee0ff27d1c35768c2afdcfdc1183c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/741bd5c4d3a2342122b3bcbab4f733ea.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/745ed065275224ee96b082e6423970e7.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7471731c4266eead2be85bc3b3bf45dc.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7534b599139ea12d7b44e2495fe05157.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/75670a9f70f9d0bfd32204a4eab7d470.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/76788b4474b560ecc99133113185a49b.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7726cef279d193502f5cb83b9a88e83e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/77312c07675c04d4b9267f93043a40ca.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/775446ae1ae0487f41edf9102969aede.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/77a7f5beb4fc4841f8a801f8cae29808.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/77c4275bce0c9cd186cd53ccb9a706b2.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/77eb813a40cdecdadc882c57f6b2cc4c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/785da55d2c7de97aeb6ad1bd19119d6f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/786d49911281c71f99e0d553c06ce3df.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7894d90a7e9e64d27d0d85c4c49555f3.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/78ad4d9929b9f076963d726d53a6e940.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/794ccd0649ea0e8be29589734058a57d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/79aa3d276582994734323d24cdb5ed01.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7a395e5c9d1fe6c75d862b922d77187c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7baff76c5fb6c08564fa34fd83939453.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7c41d612128cd5e3b6e408883c934c95.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7cbff942d1478e98084353d0f7f62e31.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7d5348dd3b542499bbf02aed8bd36785.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7d93ad334d08b8c98c4284c1f8d2c4ec.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7d9c7bd57e89e7740ec07ecf8a048151.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7db7aae1e2bca2ca5235b8057009b0ac.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7e1f67b67402c4df5e1e2a44d25f51fa.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7f11e6e09918113dcddf6d681e13ea71.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7f5f376b86a286024c83c26ffb49cb8c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7fbf8b0bbec82e061a8d3eea8f0a71d1.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8213f4a18007036d5f4065f5376ff774.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/824a6558348b36207e550fec790c5722.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/825a7b148796df2377293f52d740e817.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/82a1fd80d6a43cf0496ed6110c2f8e02.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/841f372e79296ea98dd109364f81c59d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/851459f4199292ed1a7577162d013e9d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8559d83fb3386d14f3f864903dfec0c8.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/857d3626683a302ff9b570090741ca51.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/85f5c5779d8989d9d671ea60e397690b.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/873baa02e1555c2c849ea326132b03c1.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/87955b65b77f2f86b3c9331d4a14bbb6.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8825bb1799574d04b9d15cdd52cf748d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/89d87730899049f97ef3fb1c709cadd7.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8a15e934825b7cb2d3e5b613144cd910.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8b0d95e91c085a2685ffb3d8269d7077.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8d9a1d62882c4212fff968c6ce25430e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8ec09b3461d580500e27199617e3bd9c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8ec1c1e12dac2fa8d13e32f4e140be33.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8edd016df31d5637ec523779cac20961.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8eeb9ee66982325b11dd44ce2e765cee.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8f714f97e08d772374b551cc9f3e3580.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8fb7ce565187d7ce5e53bdd4e8be8565.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9097f94db10c3a77e4dcce0f9d873e28.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/910ea301c783d2a6b264eae9672f23e6.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9142fa8d89b3e0b6f5eb1de4c092098a.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/916ddce272ccfb0276d8af323e28e455.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/91c65204b18c6fb96943baf908ea12c9.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9275e527c729636774d24889914a0008.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/92de2815fa1300896a5caa248ddd3b27.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9331d444eb4022d9156c2981285761cb.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/933a534cef0c2e5093597e01e1a48729.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/935db938e9eda7ba1ee4a3b5991b9c57.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/93d0fc7d138988945a0099da59269745.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/941a7cd0eb00bba884869e751d00ae2c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/943a90030ea11eefa19af682ce7cc28e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9449bc93017476ec283925e21bd8f1c9.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/94f3d16d1488a8b7690542b6aaccb056.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/952bdbcd285b419a773b8be327bf2edd.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/95540a87f0439f94844fa8a078efa55e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/95c690c6734de26d8308b061d74081ae.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/95e4b8a979c82909d89ef9b0fa3c1fda.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/960e1a7f4b929bf85f024050639201c9.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/961c2a792a5e1966cc7360da94d557c9.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/96be01144f9c5cf1cbfea9e1bc15c27c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/96c0be811cbc2ba0144c31a967854e6a.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/97e1ec9b22357b23ea61236d43b6c4a5.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/99098dc4e3250e6b858211bf756805bd.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9937c9a1cd35f0a189489e1ba3e1ee6e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/996ea9758e9184460656293299f4fc5f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/99b3a193d98cedc339cf03ed0c89ed4e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9a17dca9a159b52f6058c4b8b3758263.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9ade086496ac44efdbdbdf3345995b0d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9af82de23dc4be3c15423a1f3c3a4468.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b09d046433f03f50defda54e17a33ec.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b5ace4527677b30a2ee7fe026991945.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b716ca22bf76c39ca2102792f0614e9.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b9428a20c87ccf17df3d1751b820344.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b9e6a1b9082f4f9a7d5c745f84f497d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9ba634bd945795ed8a76acdecfde49a4.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9c0f0a0ce42d8287c9f48a6cc7c71c1e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9c5fbc59328f51d035932d0d1f542487.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9c9e4e374863bf04076ae1b6eaa5eac2.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9d11ef7100b8416d96188e22f5171adf.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9debdbee212d6c3067cf2cdaf270e3b3.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9e1e456a238764f55631e71db54e9e9e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9eec1c737984af1556c71586c071121d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9f6629f1db673de2d304b3fcc2c48ea2.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9fcc16f1a59fc5dc8061be9211d1406f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a11fd151b48136b97839d38f924a2341.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a1f23934299c5079c5733105072d1f93.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a2b7e80c538e0511d89273aeed25a92f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a2cc250a546ae544fb4695e2b8077ad1.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a2f87d16679f59a1686cd8eeeb1ca63f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a3b3fcd204c9ef0ce797fe25747b85d3.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a3f1af91c9902e7bf1ff0648f38652be.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a42c96155f0b834b4d6e1a3eee789390.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a45c95d0bade2be240feeae148f17274.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a49f45d1fd6b6586eb46970b989c4dc7.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a4c1525c8db3dddd50e0092dc36862ac.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a4cbaa33dc42283d5371c48b6eb17cf5.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a4f4330957dfac60def39e08d8c69ca9.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a52f23dc0c83fd6f1b9e7ed7279bb9e3.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a584494c3ac50081b2f9574b18ba42fb.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a59cf66b62ea8d403f095bae377a1e82.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a5cfeb3eaa805540f31726104d5037c9.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a8a56b91eea0f9a8c480f81e0960a9f0.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a917d45a781de755ce4c7f727ecb663a.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a925e5a0d4a2ad37c36a0cdeae5f4a05.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a93bc75d3f60badf7765a69654aea189.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a955a755f40b0cda7492c7aa4fff2b52.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/aaaf334aeff84ea148a1469d42c6fc82.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ab3afd0a8254672d351f549a76f83c98.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/acecd72ff9410fb27b05718d047d24dc.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ad54ac1ce876f93cf5c813ec262845e2.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ad67a4d7d31da7c7e823b4c05d64270f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/add3c7e8571233b17df92912514e36ad.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ae5b492f03929fd6b81ebee9b2733e2a.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ae99c7c82d9ac7a6355323ae7a0a95c0.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/aeb0dab30ccf763d9999214f196e1bed.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/aef6711358ed63fb79fccd99e71fb50e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af0b4beba3b6b475e18f735799b52cb3.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af214b3b06b5463cc90434a96bbafd51.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af38ad387f7dc992568a3fcb44a072e3.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af52415030cfdb1e111f787bb8cb99e2.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af85198787c82b979daf1a9fdf9596cf.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b019882b412128a36502c22a00be37b6.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b02782fbd52d87eab17fe5c24b326e92.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b0414baa9b45f1df4a49b0ba95ad0678.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b0d353a2cd82f830c13b5258a584fda2.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b1b1c0fb595245aca359befbc1f13d65.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b438e477a38a97ceb0d5901bf567c5cb.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b46052dfeffd46059f763fc055048757.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b4a91875a7d91bb5712fdc7ab460356e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b4b7a065dc0d46c8524f44134b43df90.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b61570abaf72fc4e5b81089f5b08ccdf.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b6fa0e82f5ddf3937f7741872d5aab29.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b74470dc7d33f0c5ded118dcd72408dd.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b8116e2cc4e7e2a740cc06ed5b3eb64b.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b84dc59a29d1cb0bd465bc7ac9c21963.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b8d4fc353441b833014d5dfb7360acaa.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b932ad094993c20c7907ca8ce19afa68.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b9ab386866cdc3fe74d767f3aecdab33.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/baf7fffc1651230f1ba31a474abac0e8.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bb86c627bbe6120f82a39eeac0a210c7.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bbca5c142aacd33545651d72c90e4d16.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bc42a65657fbbcab9abf3bbf7c253fb1.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bcb4a9a964f638055196c65f6da6f103.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bcc20ed95de63717b59927435fbb91b9.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bcde2471baeecec6694f8208c3d97279.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bce80bfebb680584076dcae61a8265af.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bd006d9d9227499468866ba030554c13.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bd621187dafd6846d11d7f2fb2459fa2.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/be204f58ecb1f7aa29209167d8da5d70.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/be3a11101c7b3e19e67219d5ffdba17b.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bfb153ecb1e3b7552b673f2f7be1ccf6.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c0448396a66b6a9a343c8d4f6c6c3eb0.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c1a0a37f454b2d5aaca369f6412bd0d3.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2095599aaf0586f25f6c9a117d4fc0c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2602bfcc5527d69fbf66e5ba431c133.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2983bce2fb62663ef1c1bb3dfa5a353.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2bec2fae37fe4502cb53ecff9be1b6b.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2d9f3757c2dad99ec8f45240d125369.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c3960b5c98ffe2f6f5b9f3f30bbd679e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c3ae2001bc948489f52dea7ca6e95fc9.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c3fba3e40a39a345fc1a32d2c0e586c4.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c47e0ee821c908eb775487c485a1f011.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c4dee3d62365554783e3696baa67fe81.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c52724e65a186042b9991d546ca8353e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c528c8c781aabb8841188b6c6870ef60.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c5383a5b4f6737d8a8aab45b34d75c85.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c6d8f37a44040738b00b6329975739f1.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c741348f69f3d93bca532c04d013d2ff.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c799e2d03ce8c169db17c2764eb15649.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c7c7760b123788dfc300c00f550c0c8b.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c81c448c1a4c106d2c0c65af9d171e84.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ca310ecb2347058231a4f39abe2a4b37.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cb3d6d429e9939b00f70b6b93f75e13c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cbb3af2be8d11a04174cb3108ab47fd6.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cc6d83459819b0a75b6adc146f1bb21c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ccd349028db6c236ae4dc2f72467013d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cd5d962cad7da958ea255fb19a3dd930.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cda3322118354a1e2b32b97b8529e414.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ce0847f5942db97d0f8685af8167e89f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cf4cb3db4ccc0a7ab9e9a2c4da9329a3.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cf5bffdcae03e2026d162acd7dbb567f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cf8ebd04bf14d8ab3c4567c7e5fbb2af.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cfa7a42afb19842fef8d76b41f20758f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d0208bea6e7dbf8ac017d394d06a6d97.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d0f201925be9f4efbaafe8620119875d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d12354801e2a2689afabfaf237796d6f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d123dc82eefece187055aba6869b95cd.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d1b7b384daafd2472881aed64e1468a7.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d22deb4dece26c8ed02e8a3f05dd0395.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d275671cecfe7df4e5219cd774826825.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d27a33ed1a6bf7de764fdb8b12440665.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d2bc4f474885b48501283f19d2a2dd80.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d3feb187cabf2b68f42d72c5f2c6d115.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d430ed3650c4c82c2a452f3ffc7690a9.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d48510fe6ec84c879f68b9f9385f5e14.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d49f32b48a997565aed8380dd447ef91.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d4ed6e5c29a19cace6f9c3a81ac3c961.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d59bd1237fe3ec57bec775cefe34fc59.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d6880efc983939a8bc39133bee849242.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d6efc173b527acd06565cce8947c68ed.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d712db479ec92c0b37b0801161820366.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d83e9ba661aaa1233102de0409b6832b.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d8526b86e748354547ff3c210e2c177b.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d8a4b88ac006bf17f9d46ff487f4e481.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d9e1da1b60affbc48272520117bf47d9.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/da612470ecad5530274e30a0c519c26c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dab87e721f5a1e8410af38bc09db6112.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/db0b23b7c4b284e1901ac146f62345c8.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dbbe55447ad34d282c50beefa138cdfb.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dbc7066a0923685debf5925f6e9cb980.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dcfedaf9eddb9ce0a3c98d5fb29e9072.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dd730346a8a66e841d06223364ab66df.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ddd7b5b5ac9bba4014a6decf60e4bb66.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/de23b7a87cd2a4fe477bebf589ebf278.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/deffd3c1c8784398a62c8d1ebfb3e436.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/df6c4c7dc3c069d53125e9b5014d1396.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dfc1aea91a1471e2a59c7e7d113ba6e1.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e05a5fbc31da900cdb2586cc9fcecd67.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e09bc7551899dbca3d98b3fa38790fea.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e10ab369a27acb2093e56d5ea4e9029a.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e133e335b9e34caa8297e7aa4e7baacc.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e20f844b4406d5935f605a65f589635d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e26188d532509f649c96e984c95cf7aa.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e39a86e6070757a12ffe8b4970e94eb9.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e49863c40c18b9049601ae9dcd6511f7.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e4df16396ed7363d7f748680fb379f4c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e55ec704a3a5c728d28ddbca60f7392e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e65cf91b00d1eabe632cb6065fc58f1f.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e6cef5e7cdcd2ba2370e8ff7b2df9351.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e725d377ec830c8b0daa5e02261ceae0.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e74893a8e18678fb991bf242688ee2d5.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e83de5862e651226e954f206a8bfe2a1.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e887607248f7391b080c7a50af22d464.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e8a154d6c301c9ff032879f86d2f9b89.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ea1cb7d34fe49bbbb6e9251b16657918.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/eabc94c7e737d3fdcb4b737f73f23db8.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/eb14edc170ff105fde8cdcd83dd942c6.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/eb4ea9d5d92a8c02c079ce4518e0e608.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ecf9efb8308a694a32d3fa64933e1752.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/edfa08514ee31d005331d683ac0cbe5e.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ef0bab363420f2105bef4a4c30d823b4.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f005ad99e1ae30a0a5d4fd0b3dad7770.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f0749b18aa0747b73ac74d36c9ac5317.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f0b35ba8adfa960168421e0d7e2291d1.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f0d088d42bc11b780b4307eead291fd4.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f101f8745b2fc2a1dfd62faf74a5c53a.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f128bc5093ce92f6948a3846c2cdaa23.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f1370c1c58c5249c336abda28de9c58b.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f1df5ec7fc32fd167fe5e2bba70b5e90.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f2e0a2a2ba5b631b50364e9424d8a399.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f44189b1241a054fd74f1416e50ef578.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f4e820989083bf0d3f6a6fa58d23cf53.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f5552b84d08a383e183a2d4380cf3904.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f5d23fc3190f08cbef79623ebe31a3b4.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f6c0a1a8e44fbce047d5ee1ce4b7d563.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f6ec1b24e1a5cb0b3b5db121d901498d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f7617b0afb68d73f7e004ee314352d91.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f7903039de6b51cd3953fbdfc8bae34c.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f7b3ea98396a0dd9549f4b4196cdb067.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f7da67a66d65dbe721d9359a064ab5cc.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f9f64c7eedcd4ade9c06ee23b326cb96.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fa4ff538d0763758fdcdf91ee0cc5ec1.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fa6c79a0fff4fdb246aa7dcdebaa7173.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fb162b8848d3b4d814ebeeef4e055cb7.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fb9c3337c7bb67f82c60e95e883e49fa.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fc687339c6964908a927657374dc0f0d.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fd2e892a2768cf93c57af72355073882.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fd5d72dcfdee2a36615a11ad69077808.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ff0817df5eb677c91d4dda6c1d4074dc.txt create mode 100644 hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ff9f936e5f3dd45ab09465d39d379763.txt create mode 100755 hanzi_detection/include/darknet.h create mode 100755 hanzi_detection/libdarknet.so create mode 100755 hanzi_detection/model/jiyan_classify.cfg create mode 100755 hanzi_detection/model/jiyan_yolov3.cfg create mode 100755 hanzi_detection/python/darknet.py create mode 100755 hanzi_detection/python/proverbot.py create mode 100644 hanzi_detection/readme_classify.md create mode 100755 hanzi_detection/scripts/dice_label.sh create mode 100755 hanzi_detection/scripts/gen_tactic.sh create mode 100755 hanzi_detection/scripts/get_coco_dataset.sh create mode 100755 hanzi_detection/scripts/imagenet_label.sh create mode 100755 hanzi_detection/scripts/voc_label.py create mode 100755 hanzi_detection/src/activation_kernels.cu create mode 100755 hanzi_detection/src/activation_layer.c create mode 100755 hanzi_detection/src/activation_layer.h create mode 100755 hanzi_detection/src/activations.c create mode 100755 hanzi_detection/src/activations.h create mode 100755 hanzi_detection/src/avgpool_layer.c create mode 100755 hanzi_detection/src/avgpool_layer.h create mode 100755 hanzi_detection/src/avgpool_layer_kernels.cu create mode 100755 hanzi_detection/src/batchnorm_layer.c create mode 100755 hanzi_detection/src/batchnorm_layer.h create mode 100755 hanzi_detection/src/blas.c create mode 100755 hanzi_detection/src/blas.h create mode 100755 hanzi_detection/src/blas_kernels.cu create mode 100755 hanzi_detection/src/box.c create mode 100755 hanzi_detection/src/box.h create mode 100755 hanzi_detection/src/classifier.h create mode 100755 hanzi_detection/src/col2im.c create mode 100755 hanzi_detection/src/col2im.h create mode 100755 hanzi_detection/src/col2im_kernels.cu create mode 100755 hanzi_detection/src/compare.c create mode 100755 hanzi_detection/src/connected_layer.c create mode 100755 hanzi_detection/src/connected_layer.h create mode 100755 hanzi_detection/src/convolutional_kernels.cu create mode 100755 hanzi_detection/src/convolutional_layer.c create mode 100755 hanzi_detection/src/convolutional_layer.h create mode 100755 hanzi_detection/src/cost_layer.c create mode 100755 hanzi_detection/src/cost_layer.h create mode 100755 hanzi_detection/src/crnn_layer.c create mode 100755 hanzi_detection/src/crnn_layer.h create mode 100755 hanzi_detection/src/crop_layer.c create mode 100755 hanzi_detection/src/crop_layer.h create mode 100755 hanzi_detection/src/crop_layer_kernels.cu create mode 100755 hanzi_detection/src/cuda.c create mode 100755 hanzi_detection/src/cuda.h create mode 100755 hanzi_detection/src/data.c create mode 100755 hanzi_detection/src/data.h create mode 100755 hanzi_detection/src/deconvolutional_kernels.cu create mode 100755 hanzi_detection/src/deconvolutional_layer.c create mode 100755 hanzi_detection/src/deconvolutional_layer.h create mode 100755 hanzi_detection/src/demo.c create mode 100755 hanzi_detection/src/demo.h create mode 100755 hanzi_detection/src/detection_layer.c create mode 100755 hanzi_detection/src/detection_layer.h create mode 100755 hanzi_detection/src/dropout_layer.c create mode 100755 hanzi_detection/src/dropout_layer.h create mode 100755 hanzi_detection/src/dropout_layer_kernels.cu create mode 100755 hanzi_detection/src/gemm.c create mode 100755 hanzi_detection/src/gemm.h create mode 100755 hanzi_detection/src/gru_layer.c create mode 100755 hanzi_detection/src/gru_layer.h create mode 100755 hanzi_detection/src/im2col.c create mode 100755 hanzi_detection/src/im2col.h create mode 100755 hanzi_detection/src/im2col_kernels.cu create mode 100755 hanzi_detection/src/image.c create mode 100755 hanzi_detection/src/image.h create mode 100755 hanzi_detection/src/image_opencv.cpp create mode 100755 hanzi_detection/src/iseg_layer.c create mode 100755 hanzi_detection/src/iseg_layer.h create mode 100755 hanzi_detection/src/l2norm_layer.c create mode 100755 hanzi_detection/src/l2norm_layer.h create mode 100755 hanzi_detection/src/layer.c create mode 100755 hanzi_detection/src/layer.h create mode 100755 hanzi_detection/src/list.c create mode 100755 hanzi_detection/src/list.h create mode 100755 hanzi_detection/src/local_layer.c create mode 100755 hanzi_detection/src/local_layer.h create mode 100755 hanzi_detection/src/logistic_layer.c create mode 100755 hanzi_detection/src/logistic_layer.h create mode 100755 hanzi_detection/src/lstm_layer.c create mode 100755 hanzi_detection/src/lstm_layer.h create mode 100755 hanzi_detection/src/matrix.c create mode 100755 hanzi_detection/src/matrix.h create mode 100755 hanzi_detection/src/maxpool_layer.c create mode 100755 hanzi_detection/src/maxpool_layer.h create mode 100755 hanzi_detection/src/maxpool_layer_kernels.cu create mode 100755 hanzi_detection/src/network.c create mode 100755 hanzi_detection/src/network.h create mode 100755 hanzi_detection/src/normalization_layer.c create mode 100755 hanzi_detection/src/normalization_layer.h create mode 100755 hanzi_detection/src/option_list.c create mode 100755 hanzi_detection/src/option_list.h create mode 100755 hanzi_detection/src/parser.c create mode 100755 hanzi_detection/src/parser.h create mode 100755 hanzi_detection/src/region_layer.c create mode 100755 hanzi_detection/src/region_layer.h create mode 100755 hanzi_detection/src/reorg_layer.c create mode 100755 hanzi_detection/src/reorg_layer.h create mode 100755 hanzi_detection/src/rnn_layer.c create mode 100755 hanzi_detection/src/rnn_layer.h create mode 100755 hanzi_detection/src/route_layer.c create mode 100755 hanzi_detection/src/route_layer.h create mode 100755 hanzi_detection/src/shortcut_layer.c create mode 100755 hanzi_detection/src/shortcut_layer.h create mode 100755 hanzi_detection/src/softmax_layer.c create mode 100755 hanzi_detection/src/softmax_layer.h create mode 100755 hanzi_detection/src/stb_image.h create mode 100755 hanzi_detection/src/stb_image_write.h create mode 100755 hanzi_detection/src/tree.c create mode 100755 hanzi_detection/src/tree.h create mode 100755 hanzi_detection/src/upsample_layer.c create mode 100755 hanzi_detection/src/upsample_layer.h create mode 100755 hanzi_detection/src/utils.c create mode 100755 hanzi_detection/src/utils.h create mode 100755 hanzi_detection/src/yolo_layer.c create mode 100755 hanzi_detection/src/yolo_layer.h create mode 100644 "media/0b7bbb3595309f7f9123704ef354a52d\346\227\205_u65c5.jpg" create mode 100755 media/1590951689.png create mode 100644 media/ab9a8dcdda85f1d8789909803374fbea.jpg create mode 100644 media/e697bc6aa912eeb2610998833f209242.jpg create mode 100644 media/geet_demo.jpg create mode 100644 media/jiyan_test_api.png create mode 100644 media/yidun_demo.jpg create mode 100644 "media/\351\230\277_1cde28c6abce11eab97c0242ac110002.jpg" create mode 160000 nine diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8c498d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +^. +.idea +.DS_Store +.gitattributes diff --git a/IMG_1766.JPG b/IMG_1766.JPG new file mode 100644 index 0000000000000000000000000000000000000000..4f7e7a76e149339bb98c64f6fc760f9914466fef GIT binary patch literal 219722 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 + geet + geet + yidun + geet + menghuan + menghuan +

+ + + +--- + +### 本项目供大家一起学习交流,群里大佬们会免费一起训练模型 + +--- + + + +## 待更新内容 + +如果对您有用,请给个star:star::star::star:谢谢。点赞可让我看到大家的关注情况,持续更新的动力,谢谢支持。 + +刚建了个群,随缘加加!不能分享的代码在群里交流!群号::rocket:`1040784971`:rocket: + +许多内容待整理。 + +:star: **~~更新极验打码测试接口~~**:star:: + +~~垃圾服务器,图片识别速度很慢,随便用用,随时会挂掉,有疑问请留言~~ + +~~可用于学习性质的数据标注和测试,严禁用于商业项目,谢谢配合~~ + +~~(接口已关闭,谢谢关注)~~ + +### 极验的JS破解流程以及点选验证码识别模型 + +极验分为三个部分,1. 破解了前端,获取validate参数;2. 文字类的验证码;3. 滑动验证码。验证码部分结合机器学习在本地打码。 + +- [极验验证码前端JS破解思路](./doc/jiyan_gt_challenge.md) + + 极验js方面,获取validate就完结了。 + + - [x] gt、challenge + - [ ] validate + - [x] [获取gt、challenge、validate,代码DEMO](./doc/jiyan_gt_challenge_demo.ipynb) + +- 点选验证码汉字识别模型 + + 这部分极验和易盾是通用的,数据集改改就好了。如果有数据集可以和我共享,我收集完统一标注然后共享出来。数据集完备后更新一波`一步识别`的模型出来。 + + - [x] [Ubuntu环境安装](./doc/Ubuntu18.04%20install%20darknet%20yolo-v3%7Ccuda%7Ccudnn%7Copencv%7Canaconda.md) + - NVIDIA-SMI|CUDA|cuDNN|OpenCV|Anacoda + - [x] [汉字定位(目标检测)](./hanzi_detection/README.md) + - [x] [汉字识别](./hanzi_detection/readme_classify.md) + - [x] [定位模型训练手册(含数据)](./doc/detector_train_handbook.md) + - [x] [识别模型训练手册(含数据)](./doc/classifier_train_handbook.md) + - [x] [Python中使用模型](./doc/在Python中使用模型.ipynb) + - [ ] 模型速度优化 + +- 九宫格类型验证码 + + - [x] [数据准备](./doc/九宫格图片验证码训练集.md) + - [ ] 分类模型训练手册 + +- 滑动3.0和机器学习 + + - [ ] 滑动轨迹 + +### 瑞数JS + + + + +## 联系方式 +欢迎技术交流:`huaiyukeji@gmail.com` + + + +TG电报群:https://t.me/joinchat/99xuS4HiOIc2YTU1(老群已解散) + diff --git a/doc/.ipynb_checkpoints/jiyan_gt_challenge_demo-checkpoint.ipynb b/doc/.ipynb_checkpoints/jiyan_gt_challenge_demo-checkpoint.ipynb new file mode 100644 index 0000000..a95d7a4 --- /dev/null +++ b/doc/.ipynb_checkpoints/jiyan_gt_challenge_demo-checkpoint.ipynb @@ -0,0 +1,708 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 使用企业公示网做例子\n", + "\n", + "获取gt和challenge两个参数" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import requests" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# 企业公示网做例子\n", + "index_url = 'http://www.gsxt.gov.cn/index.html'\n", + "index_header= {\n", + " 'accept': \"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\",\n", + " 'accept-encoding': \"gzip, deflate\",\n", + " 'accept-language': \"zh-CN,zh;q=0.9\",\n", + " 'connection': \"keep-alive\",\n", + " 'host': \"www.gsxt.gov.cn\",\n", + " 'upgrade-insecure-requests': \"1\",\n", + " 'Referer': 'http://www.gsxt.gov.cn/index.html',\n", + " \"User-Agent\": \"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36\",\n", + " }" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# 代理手动配置,避免本地的IP被封了\n", + "proxy = {\n", + " \"https\": \"https://\" + \"60.188.9.176:3000\",\n", + " # \"http\": \"http://\" + \"60.167.135.237:8118\"\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "response = requests.get(index_url, headers=index_header, proxies=proxy)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "获取到第一段JS代码" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\n'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "response.text # 获取第一段js" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "获取jsluid参数" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'3873563fb2bec146ee50d1146cda3483'" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "jsluid = response.headers['Set-Cookie'].split('=')[1].split(';')[0] \n", + "jsluid" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "解密出第二段js代码" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"var _1v=function(){setTimeout('location.href=location.pathname+location.search.replace(/[\\\\\\\\?|&]captcha-challenge/,\\\\\\\\'\\\\\\\\')',1500);document.cookie='__jsl_clearance=1589364371.438|0|'+(function(){var _1t=[function(_1v){return _1v},function(_1t){return _1t},function(_1v){return eval('String.fromCharCode('+_1v+')')},function(_1v){for(var _1t=0;_1t<_1v.length;_1t++){_1v[_1t]=parseInt(_1v[_1t]).toString(36)};return _1v.join('')}],_1v=[[[(-~~~''+[-~-~~~'']>>-~-~~~'')]+[-~-~~~''+((-~{}<<-~{})^-~~~'')]],'S',[[((-~{}<<-~{})^-~~~'')-~~~''-~!{}+((-~{}<<-~{})^-~~~'')]+[-~[-~-~~~''-~-~~~''-~-~~~'']]],'d',[[((-~{}<<-~{})^-~~~'')-~~~''-~!{}+((-~{}<<-~{})^-~~~'')]+(-~[]-~[]+[[]][0])],'F',[[(-~~~''+[-~-~~~'']>>-~-~~~'')]+[-~-~~~''+((-~{}<<-~{})^-~~~'')]],[[(-~{}<<-~{})]*(((-~{}<<-~{})^-~~~''))],'Hkav',[[(-~~~''+[-~-~~~'']>>-~-~~~'')]+[~~[]]],'G',[((-~{}<<-~{})^-~~~'')-~~~''-~!{}+((-~{}<<-~{})^-~~~'')],'D',[[-~{}]+[-~[-~-~~~''-~-~~~''-~-~~~'']]],[[-~[-~-~~~''-~-~~~''-~-~~~'']]+[((-~{}<<-~{})<<-~{})]],[(-~[]-~[]+[[]][0])+[(-~~~''+[-~-~~~'']>>-~-~~~'')],[(-~~~''+[-~-~~~'']>>-~-~~~'')]+[(-~~~''+[-~-~~~'']>>-~-~~~'')]],[[-~[-~-~~~''-~-~~~''-~-~~~'']]+(-~[]-~[]+[[]][0])],[(-~[]-~[]+[[]][0])+(-~!{}+(-~[]-~[]<<-~[]-~[])+[]+[[]][0])],'WO',[[[(-~{}<<-~{})]*(((-~{}<<-~{})^-~~~''))]+[-~-~~~''+((-~{}<<-~{})^-~~~'')]],[[(-~~~''+[-~-~~~'']>>-~-~~~'')]+[((-~{}<<-~{})<<-~{})]],[[[(-~{}<<-~{})]*(((-~{}<<-~{})^-~~~''))]+(-~!{}+(-~[]-~[]<<-~[]-~[])+[]+[[]][0])],'%',[(-~~~''+[-~-~~~'']>>-~-~~~'')],'D'];for(var _t=0;_t<_1v.length;_t++){_1v[_t]=_1t[[3,1,2,1,2,1,3,0,1,3,1,0,1,3,2,3,2,3,1,2,3,2,1,0,1][_t]](_1v[_t])};return _1v.join('')})()+';Expires=Wed, 13-May-20 11:06:11 GMT;Path=/;'};if((function(){try{return !!window.addEventListener;}catch(e){return false;}})()){document.addEventListener('DOMContentLoaded',_1v,false)}else{document.attachEvent('onreadystatechange',_1v)}\"" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import re\n", + "import execjs\n", + "\n", + "\n", + "des_js = 'function get_z(x, y) {\\n f = function (x, y) {\\n var a = 0,\\n b = 0,\\n c = 0;\\n x = x.split(\"\");\\n y = y || 99;\\n while ((a = x.shift()) && (b = a.charCodeAt(0) - 77.5)) c = (Math.abs(b) < 13 ? (b + 48.5) : parseInt(a, 36)) + y * c;\\n return c\\n };\\n x = x.replace(/@*$/, \"\").split(\"@\");\\n z = f(y.match(/\\\\w/g).sort(function (x, y) {\\n return f(x) - f(y)\\n }).pop());\\n return [x, y, z]\\n\\n}\\n\\nfunction get_js(x, y, z) {\\n f = function (x, y) {\\n var a = 0,\\n b = 0,\\n c = 0;\\n x = x.split(\"\");\\n y = y || 99;\\n while ((a = x.shift()) && (b = a.charCodeAt(0) - 77.5)) c = (Math.abs(b) < 13 ? (b + 48.5) : parseInt(a, 36)) + y * c;\\n return c\\n };\\n x = eval(x);\\n z = z + 1;\\n p = y.replace(/\\\\b\\\\w+\\\\b/g,\\n function (y) {\\n return x[f(y, z) - 1] || (\"_\" + y)\\n });\\n return p\\n\\n}\\n\\n\\nfunction once_js(x, y) {\\n f = function (x, y) {\\n var a = 0,\\n b = 0,\\n c = 0;\\n x = x.split(\"\");\\n y = y || 99;\\n while ((a = x.shift()) && (b = a.charCodeAt(0) - 77.5)) c = (Math.abs(b) < 13 ? (b + 48.5) : parseInt(a, 36)) + y * c;\\n return c\\n },\\n x = x.replace(/@*$/, \"\").split(\"@\");\\n z = f(y.match(/\\\\w/g).sort(function (x, y) {\\n return f(x) - f(y)\\n }).pop());\\n while (z++) try {\\n g = y.replace(/\\\\b\\\\w+\\\\b/g,\\n function (y) {\\n return x[f(y, z) - 1] || (\"_\" + y)\\n });\\n return g\\n } catch (_) {\\n }\\n}'\n", + "des_js = execjs.compile(des_js)\n", + "first_js = response.text\n", + "x = re.findall('var x=\"(.*?)\"', first_js)[0]\n", + "y = re.findall(',y=\"(.*?)\"', first_js)[0]\n", + "second_js = des_js.call('once_js', x, y)\n", + "second_js" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "处理第二段js,去除document" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"cookie='__jsl_clearance=1589364371.438|0|'+(function(){var _1t=[function(_1v){return _1v},function(_1t){return _1t},function(_1v){return eval('String.fromCharCode('+_1v+')')},function(_1v){for(var _1t=0;_1t<_1v.length;_1t++){_1v[_1t]=parseInt(_1v[_1t]).toString(36)};return _1v.join('')}],_1v=[[[(-~~~''+[-~-~~~'']>>-~-~~~'')]+[-~-~~~''+((-~{}<<-~{})^-~~~'')]],'S',[[((-~{}<<-~{})^-~~~'')-~~~''-~!{}+((-~{}<<-~{})^-~~~'')]+[-~[-~-~~~''-~-~~~''-~-~~~'']]],'d',[[((-~{}<<-~{})^-~~~'')-~~~''-~!{}+((-~{}<<-~{})^-~~~'')]+(-~[]-~[]+[[]][0])],'F',[[(-~~~''+[-~-~~~'']>>-~-~~~'')]+[-~-~~~''+((-~{}<<-~{})^-~~~'')]],[[(-~{}<<-~{})]*(((-~{}<<-~{})^-~~~''))],'Hkav',[[(-~~~''+[-~-~~~'']>>-~-~~~'')]+[~~[]]],'G',[((-~{}<<-~{})^-~~~'')-~~~''-~!{}+((-~{}<<-~{})^-~~~'')],'D',[[-~{}]+[-~[-~-~~~''-~-~~~''-~-~~~'']]],[[-~[-~-~~~''-~-~~~''-~-~~~'']]+[((-~{}<<-~{})<<-~{})]],[(-~[]-~[]+[[]][0])+[(-~~~''+[-~-~~~'']>>-~-~~~'')],[(-~~~''+[-~-~~~'']>>-~-~~~'')]+[(-~~~''+[-~-~~~'']>>-~-~~~'')]],[[-~[-~-~~~''-~-~~~''-~-~~~'']]+(-~[]-~[]+[[]][0])],[(-~[]-~[]+[[]][0])+(-~!{}+(-~[]-~[]<<-~[]-~[])+[]+[[]][0])],'WO',[[[(-~{}<<-~{})]*(((-~{}<<-~{})^-~~~''))]+[-~-~~~''+((-~{}<<-~{})^-~~~'')]],[[(-~~~''+[-~-~~~'']>>-~-~~~'')]+[((-~{}<<-~{})<<-~{})]],[[[(-~{}<<-~{})]*(((-~{}<<-~{})^-~~~''))]+(-~!{}+(-~[]-~[]<<-~[]-~[])+[]+[[]][0])],'%',[(-~~~''+[-~-~~~'']>>-~-~~~'')],'D'];for(var _t=0;_t<_1v.length;_t++){_1v[_t]=_1t[[3,1,2,1,2,1,3,0,1,3,1,0,1,3,2,3,2,3,1,2,3,2,1,0,1][_t]](_1v[_t])};return _1v.join('')})()+';Expires=Wed, 13-May-20 11:06:11 '\"" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "new_js = second_js.replace('\\\\\\\\', '\\\\')\n", + "\n", + "new_js = 'cookie' + new_js.split('document.cookie')[1]\n", + "new_js = new_js.split('GMT;Path=/;')[0] + \"'\"\n", + "\n", + "if re.findall(\"(var .{0,5}=)document\\.createElement\\('div'\\);\", new_js):\n", + " _3d = re.findall(\"(var .{0,5}=)document\\.createElement\\('div'\\);\", new_js)\n", + " _2b = re.findall(\"(var .{0,5}=).{0,5}\\.match\\(/https\\?:\\\\\\/\\\\\\//\\)\\[0\\];\", new_js)\n", + " new_js = re.sub(\n", + " \"var .{0,5}=document\\.createElement\\('div'\\);\", \n", + " _3d[0] + f'\"{index_url.replace(\"http://\", \"\")}\";',\n", + " new_js\n", + " )\n", + " new_js = re.sub(\"_.{0,5}\\.innerHTML='
';\", \"\", new_js)\n", + " new_js = re.sub(\"_.{0,5}=.{0,5}\\.firstChild\\.href;\", \"\", new_js)\n", + " new_js = re.sub(\"var .{0,5}=.{0,5}\\.match\\(/https\\?:\\\\\\/\\\\\\//\\)\\[0\\];\", _2b[0] + '\"http://\";', new_js)\n", + " new_js = re.sub(\"_.{0,5}=.{0,5}\\.substr\\(.{0,5}\\.length\\)\\.toLowerCase\\(\\);\", \"\", new_js)\n", + "new_js" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "处理js,去除Window" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "find = re.findall(\"!*window\\[.*?\\]\", new_js)\n", + "if find:\n", + " for f in find:\n", + " if '!' in f:\n", + " if len(re.findall('!', f)) % 2 == 0:\n", + " new_js = new_js.replace(f, 'false')\n", + " else:\n", + " new_js = new_js.replace(f, 'true')\n", + " else:\n", + " new_js = new_js.replace(f, 'undefined')\n", + "new_js = new_js.replace('window.headless', 'undefined')" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"cookie='__jsl_clearance=1589364371.438|0|'+(function(){var _1t=[function(_1v){return _1v},function(_1t){return _1t},function(_1v){return eval('String.fromCharCode('+_1v+')')},function(_1v){for(var _1t=0;_1t<_1v.length;_1t++){_1v[_1t]=parseInt(_1v[_1t]).toString(36)};return _1v.join('')}],_1v=[[[(-~~~''+[-~-~~~'']>>-~-~~~'')]+[-~-~~~''+((-~{}<<-~{})^-~~~'')]],'S',[[((-~{}<<-~{})^-~~~'')-~~~''-~!{}+((-~{}<<-~{})^-~~~'')]+[-~[-~-~~~''-~-~~~''-~-~~~'']]],'d',[[((-~{}<<-~{})^-~~~'')-~~~''-~!{}+((-~{}<<-~{})^-~~~'')]+(-~[]-~[]+[[]][0])],'F',[[(-~~~''+[-~-~~~'']>>-~-~~~'')]+[-~-~~~''+((-~{}<<-~{})^-~~~'')]],[[(-~{}<<-~{})]*(((-~{}<<-~{})^-~~~''))],'Hkav',[[(-~~~''+[-~-~~~'']>>-~-~~~'')]+[~~[]]],'G',[((-~{}<<-~{})^-~~~'')-~~~''-~!{}+((-~{}<<-~{})^-~~~'')],'D',[[-~{}]+[-~[-~-~~~''-~-~~~''-~-~~~'']]],[[-~[-~-~~~''-~-~~~''-~-~~~'']]+[((-~{}<<-~{})<<-~{})]],[(-~[]-~[]+[[]][0])+[(-~~~''+[-~-~~~'']>>-~-~~~'')],[(-~~~''+[-~-~~~'']>>-~-~~~'')]+[(-~~~''+[-~-~~~'']>>-~-~~~'')]],[[-~[-~-~~~''-~-~~~''-~-~~~'']]+(-~[]-~[]+[[]][0])],[(-~[]-~[]+[[]][0])+(-~!{}+(-~[]-~[]<<-~[]-~[])+[]+[[]][0])],'WO',[[[(-~{}<<-~{})]*(((-~{}<<-~{})^-~~~''))]+[-~-~~~''+((-~{}<<-~{})^-~~~'')]],[[(-~~~''+[-~-~~~'']>>-~-~~~'')]+[((-~{}<<-~{})<<-~{})]],[[[(-~{}<<-~{})]*(((-~{}<<-~{})^-~~~''))]+(-~!{}+(-~[]-~[]<<-~[]-~[])+[]+[[]][0])],'%',[(-~~~''+[-~-~~~'']>>-~-~~~'')],'D'];for(var _t=0;_t<_1v.length;_t++){_1v[_t]=_1t[[3,1,2,1,2,1,3,0,1,3,1,0,1,3,2,3,2,3,1,2,3,2,1,0,1][_t]](_1v[_t])};return _1v.join('')})()+';Expires=Wed, 13-May-20 11:06:11 '\"" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "new_js" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "获取jsl_clearance" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'1589364371.438|0|zSWdRFz6HkavuG8DhJnxHtWOAyE%3D'" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "js = \"\"\"\n", + " function getJS() {\n", + " %s\n", + " return cookie\n", + " }\n", + " \"\"\" % new_js\n", + "exec_js = execjs.compile(js)\n", + "jsl = exec_js.call('getJS')\n", + "jsl = jsl.split(';')[0]\n", + "jsl_clearance = jsl.split('=')[1]\n", + "jsl_clearance" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'8E11E8556264D5431C97B28A64F213DA-n2:-1'" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 获取第一个jessionid\n", + "headers = index_header.copy()\n", + "headers['Cookie'] = f'__jsluid_h={jsluid}; __jsl_clearance={jsl_clearance};'\n", + "response2 = requests.get(index_url, headers=headers, proxies=proxy)\n", + "JSESSIONID1 = re.findall('JSESSIONID=(.*?);', response2.headers['Set-Cookie'])[0]\n", + "JSESSIONID1" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'8E11E8556264D5431C97B28A64F213DA-n2:0'" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 获取第二个jessionid\n", + "import time\n", + "\n", + "url = 'http://www.gsxt.gov.cn/SearchItemCaptcha?t=' + str(int(time.time()*1000))\n", + "headers = index_header.copy()\n", + "headers['Cookie'] = f'__jsluid_h={jsluid}; __jsl_clearance={jsl_clearance};JSESSIONID={JSESSIONID1}'\n", + "response3 = requests.get(url, headers=headers, proxies=proxy)\n", + "JSESSIONID2 = re.findall('JSESSIONID=(.*?);', response3.headers['Set-Cookie'])[0]\n", + "JSESSIONID2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "测试cookie,如果状态码是200,获取gt和challenge" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "200" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import json\n", + "\n", + "headers = index_header.copy()\n", + "headers['Cookie'] = f'__jsluid_h={jsluid}; __jsl_clearance={jsl_clearance};JSESSIONID={JSESSIONID2}'\n", + "url = 'http://www.gsxt.gov.cn/SearchItemCaptcha?t=' + str(int(time.time()*1000))\n", + "response4 = requests.get(url, headers=headers, proxies=proxy)\n", + "response4.status_code" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "gt_challenge_json = json.loads(response4.text)\n", + "gt = gt_challenge_json['gt']\n", + "challenge = gt_challenge_json['challenge']" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'62756445cd524543f5a16418cd920ffd'" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gt" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'8a7c7f8b5b53a72f95d50b9181c758e6'" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "challenge" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 下面开始搜索企业信息" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 如果您看到这里,请给我一个star,谢谢,如有遗漏,请留言指正,感激!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "这里先走一遍采集流程,本地打码服务的实现稍后整理,要先整理完模型训练部分才能打码\n", + "服务实现流程:\n", + "1. 拿到gt和challenge获取验证码,验证码有两种\n", + " - 滑动3.0\n", + " - 文字点选,这部分的训练模型已经开源了,移步首页\n", + "2. 破解验证码,获取validate" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "# 本地打码服务器,所有验证码类型在这里统一处理,返回validate即可\n", + "get_valid_server = 'http://127.0.0.1:5051'" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "url = f'{get_valid_server}/geetest?gt={gt}&challenge={challenge}'\n", + "resp = requests.get(url)\n", + "resp" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'data': {'challenge': '8a7c7f8b5b53a72f95d50b9181c758e6',\n", + " 'result': 'success',\n", + " 'validate': 'fba9455b230064c63164bb06f453f52e'},\n", + " 'status': 'success'}" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "val_resu = json.loads(resp.text)\n", + "\n", + "val_resu" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "成功获取validate,开始进行搜索" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "from lxml.etree import _Element\n", + "from lxml import etree\n", + "\n", + "def parse_list(content):\n", + " def try_catch(data, patten):\n", + " if isinstance(data, _Element):\n", + " try:\n", + " target = re.sub('\\s', '', data.xpath(patten)[0].strip())\n", + " except:\n", + " target = None\n", + " return target\n", + " return data\n", + " a_list = []\n", + " content_list = content\n", + " html = etree.HTML(content_list)\n", + " list_len = int(html.xpath('//span[@class=\"search_result_span1\"]/text()')[0])\n", + " if list_len == 0:\n", + " return 'None'\n", + " else:\n", + " targit_len = 1\n", + " for i in range(1, targit_len + 1):\n", + " try:\n", + " url = html.xpath('//div[@class=\"main-layout fw f14\"]/div[2]/a[' + str(i) + ']/@href')[0]\n", + " href = 'http://www.gsxt.gov.cn{}'.format(url)\n", + " except:\n", + " href = None\n", + " dic = {\n", + " 'href': href\n", + " }\n", + " a_list.append(dic)\n", + " return a_list" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "def list_page(val_resu, jsluid, jsl_clearance, JSESSIONID, search_word):\n", + " time.sleep(1)\n", + " validate = val_resu['data']['validate']\n", + " chall = val_resu['data']['challenge']\n", + " data = {\n", + " 'tab': 'ent_tab',\n", + " 'province': '',\n", + " 'geetest_challenge': chall,\n", + " 'geetest_validate': validate,\n", + " 'geetest_seccode': '{}|jordan'.format(validate),\n", + " 'token': '57571798',\n", + " 'searchword': f'{search_word}',\n", + " }\n", + " time.sleep(5)\n", + " headers =index_header.copy()\n", + " headers['Cookie'] = f'__jsluid_h={jsluid}; __jsl_clearance={jsl_clearance};JSESSIONID={JSESSIONID}'\n", + " post_url = 'http://www.gsxt.gov.cn/corp-query-search-1.html'\n", + " content = requests.post(url=post_url, data=data, headers=headers, verify=False, timeout=(60, 60), proxies=proxy)\n", + " if content.status_code == 200:\n", + " if '您的IP地址' in content.text:\n", + " print('请更换代理')\n", + " else:\n", + " return content.text\n", + " else:\n", + " print('cookies失效')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "配置要搜索的关键词" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "search_word = \"百度\"" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "if val_resu['data']['result'] == 'fail':\n", + " print('get valid error')\n", + "else:\n", + " content_text = list_page(val_resu, jsluid, jsl_clearance, JSESSIONID2, search_word)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "href = parse_list(content_text)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'href': 'http://www.gsxt.gov.cn/%7BC132146AA913B5B85A24D3698BCF37F48AE6B456EC80C4B6902AE997FB525D23D4B8FC8EA812404D51929F83D12674CE8B7534DAFFFB498F8BCA2CEAEEE4298329BF29BF29CF7DB57DEBF41294709611BD80320BCAAD4BAF6EC2DD5BBD3ABC7A1D9AA720E1C3AB53FA3310F2B64E09FE3DDF8822880F998AD8D5C99BF70FEDBA108610861086-1589363839854%7D'}]" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "href" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "headers =index_header.copy()\n", + "headers['Cookie'] = f'__jsluid_h={jsluid}; __jsl_clearance={jsl_clearance};JSESSIONID={JSESSIONID2}'\n", + "detail = requests.get(url=href[0]['href'], headers = headers, proxies = proxy)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "输出结果正确" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'北京百度网讯科技有限公司'" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "etree.HTML(detail.text).xpath(\"//h1\")[0].text.strip()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 如果您看到这里,请给我一个star,谢谢,如有遗漏,请留言指正,感激!" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "blog", + "language": "python", + "name": "blog" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/doc/.ipynb_checkpoints/\345\234\250Python\344\270\255\344\275\277\347\224\250\346\250\241\345\236\213-checkpoint.ipynb" "b/doc/.ipynb_checkpoints/\345\234\250Python\344\270\255\344\275\277\347\224\250\346\250\241\345\236\213-checkpoint.ipynb" new file mode 100644 index 0000000..af73677 --- /dev/null +++ "b/doc/.ipynb_checkpoints/\345\234\250Python\344\270\255\344\275\277\347\224\250\346\250\241\345\236\213-checkpoint.ipynb" @@ -0,0 +1,225 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 在Python中使用我们训练好点模型" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "前面我们实现了`汉字位置检测`和`汉字分类识别`模型,实际使用肯定要结合封装成接口来使用,会比较方便。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "在darknet的官方项目中,已经为我们提供了一个demo" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from ctypes import *\n", + "import math\n", + "import random\n", + "\n", + "def sample(probs):\n", + " s = sum(probs)\n", + " probs = [a/s for a in probs]\n", + " r = random.uniform(0, 1)\n", + " for i in range(len(probs)):\n", + " r = r - probs[i]\n", + " if r <= 0:\n", + " return i\n", + " return len(probs)-1\n", + "\n", + "def c_array(ctype, values):\n", + " arr = (ctype*len(values))()\n", + " arr[:] = values\n", + " return arr\n", + "\n", + "class BOX(Structure):\n", + " _fields_ = [(\"x\", c_float),\n", + " (\"y\", c_float),\n", + " (\"w\", c_float),\n", + " (\"h\", c_float)]\n", + "\n", + "class DETECTION(Structure):\n", + " _fields_ = [(\"bbox\", BOX),\n", + " (\"classes\", c_int),\n", + " (\"prob\", POINTER(c_float)),\n", + " (\"mask\", POINTER(c_float)),\n", + " (\"objectness\", c_float),\n", + " (\"sort_class\", c_int)]\n", + "\n", + "\n", + "class IMAGE(Structure):\n", + " _fields_ = [(\"w\", c_int),\n", + " (\"h\", c_int),\n", + " (\"c\", c_int),\n", + " (\"data\", POINTER(c_float))]\n", + "\n", + "class METADATA(Structure):\n", + " _fields_ = [(\"classes\", c_int),\n", + " (\"names\", POINTER(c_char_p))]\n", + "\n", + " \n", + "\n", + "lib = CDLL(\"libdarknet.so\", RTLD_GLOBAL) # 配置so文件路径,最好是绝对路径\n", + "lib.network_width.argtypes = [c_void_p]\n", + "lib.network_width.restype = c_int\n", + "lib.network_height.argtypes = [c_void_p]\n", + "lib.network_height.restype = c_int\n", + "\n", + "predict = lib.network_predict\n", + "predict.argtypes = [c_void_p, POINTER(c_float)]\n", + "predict.restype = POINTER(c_float)\n", + "\n", + "set_gpu = lib.cuda_set_device\n", + "set_gpu.argtypes = [c_int]\n", + "\n", + "make_image = lib.make_image\n", + "make_image.argtypes = [c_int, c_int, c_int]\n", + "make_image.restype = IMAGE\n", + "\n", + "get_network_boxes = lib.get_network_boxes\n", + "get_network_boxes.argtypes = [c_void_p, c_int, c_int, c_float, c_float, POINTER(c_int), c_int, POINTER(c_int)]\n", + "get_network_boxes.restype = POINTER(DETECTION)\n", + "\n", + "make_network_boxes = lib.make_network_boxes\n", + "make_network_boxes.argtypes = [c_void_p]\n", + "make_network_boxes.restype = POINTER(DETECTION)\n", + "\n", + "free_detections = lib.free_detections\n", + "free_detections.argtypes = [POINTER(DETECTION), c_int]\n", + "\n", + "free_ptrs = lib.free_ptrs\n", + "free_ptrs.argtypes = [POINTER(c_void_p), c_int]\n", + "\n", + "network_predict = lib.network_predict\n", + "network_predict.argtypes = [c_void_p, POINTER(c_float)]\n", + "\n", + "reset_rnn = lib.reset_rnn\n", + "reset_rnn.argtypes = [c_void_p]\n", + "\n", + "load_net = lib.load_network\n", + "load_net.argtypes = [c_char_p, c_char_p, c_int]\n", + "load_net.restype = c_void_p\n", + "\n", + "do_nms_obj = lib.do_nms_obj\n", + "do_nms_obj.argtypes = [POINTER(DETECTION), c_int, c_int, c_float]\n", + "\n", + "do_nms_sort = lib.do_nms_sort\n", + "do_nms_sort.argtypes = [POINTER(DETECTION), c_int, c_int, c_float]\n", + "\n", + "free_image = lib.free_image\n", + "free_image.argtypes = [IMAGE]\n", + "\n", + "letterbox_image = lib.letterbox_image\n", + "letterbox_image.argtypes = [IMAGE, c_int, c_int]\n", + "letterbox_image.restype = IMAGE\n", + "\n", + "load_meta = lib.get_metadata\n", + "lib.get_metadata.argtypes = [c_char_p]\n", + "lib.get_metadata.restype = METADATA\n", + "\n", + "load_image = lib.load_image_color\n", + "load_image.argtypes = [c_char_p, c_int, c_int]\n", + "load_image.restype = IMAGE\n", + "\n", + "rgbgr_image = lib.rgbgr_image\n", + "rgbgr_image.argtypes = [IMAGE]\n", + "\n", + "predict_image = lib.network_predict_image\n", + "predict_image.argtypes = [c_void_p, IMAGE]\n", + "predict_image.restype = POINTER(c_float)\n", + "\n", + "def classify(net, meta, im):\n", + " out = predict_image(net, im)\n", + " res = []\n", + " for i in range(meta.classes):\n", + " res.append((meta.names[i], out[i]))\n", + " res = sorted(res, key=lambda x: -x[1])\n", + " return res\n", + "\n", + "def detect(net, meta, image, thresh=.5, hier_thresh=.5, nms=.45):\n", + " im = load_image(image, 0, 0)\n", + " num = c_int(0)\n", + " pnum = pointer(num)\n", + " predict_image(net, im)\n", + " dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, None, 0, pnum)\n", + " num = pnum[0]\n", + " if (nms): do_nms_obj(dets, num, meta.classes, nms);\n", + "\n", + " res = []\n", + " for j in range(num):\n", + " for i in range(meta.classes):\n", + " if dets[j].prob[i] > 0:\n", + " b = dets[j].bbox\n", + " res.append((meta.names[i], dets[j].prob[i], (b.x, b.y, b.w, b.h)))\n", + " res = sorted(res, key=lambda x: -x[1])\n", + " free_image(im)\n", + " free_detections(dets, num)\n", + " return res\n", + "\n", + "def run():\n", + " net = load_net(\n", + " \"\".encode(), # cfg文件路径\n", + " \"\".encode(), # weights权重文件路径\n", + " 0 # 默认0\n", + " )\n", + " meta = load_meta(\"\".encode()) # data文件路径\n", + " # 执行预测\n", + " r = detect(\n", + " net, \n", + " meta, \n", + " \"\".encode()\n", + " )\n", + " print(r)\n", + " \n", + " \n", + "if __name__ == \"__main__\":\n", + " run()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "这里几个要注意的点:\n", + "\n", + "- 文件路径编码\n", + "- libdarknet.so 文件的路径配置" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "blog", + "language": "python", + "name": "blog" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/doc/Ubuntu18.04 install darknet yolo-v3|cuda|cudnn|opencv|anaconda.md b/doc/Ubuntu18.04 install darknet yolo-v3|cuda|cudnn|opencv|anaconda.md new file mode 100755 index 0000000..f279d6d --- /dev/null +++ b/doc/Ubuntu18.04 install darknet yolo-v3|cuda|cudnn|opencv|anaconda.md @@ -0,0 +1,350 @@ +# Ubuntu18.04安装测试darknet yolo-v3|cuda|cudnn|opencv|anaconda + +> 机器配置: +> +> cpu:i3-9400 +> +> gpu:gtx1650-4g +> +> 系统版本:Ubuntu18.04 + +前段时间接触到darknet目标检测的项目,由于需要做效率优化,之前在mac上使用yolo3,项目开发很顺利,最终瓶颈是cpu的运算速度,故需要在有显卡的机器进行测试。 + +[TOC] + +--- + +## 一. Darknet项目 + +项目官网:https://pjreddie.com/darknet/yolo/ + +使用方式也很简单,官网都有介绍,这里就举个例子: + +- 下载编译项目: + +```shell +git clone https://github.com/pjreddie/darknet +cd darknet +make +``` + +- 下载权重文件: + +```shell +wget https://pjreddie.com/media/files/yolov3.weights +``` + +- 测试 + +```shell +./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg +``` + +然后在项目根目录下会生成`predictions.png`,打开即可看到效果。 + +到这里就可以进行二次开发了,但是都是基于CPU的,无论是前期的训练还是后期的测试,速度都是很慢的,GPU的速度在我测试下有200倍的提升(我的GPU一般,还有很大提升空间)。 + +--- + +## 二. Ubuntu安装NVIDIA显卡驱动|CUDA|CUDNN + +要使用GPU进行项目的运算,除了改项目的配置以外,最重要,也是比较麻烦的部分就是环境的安装,坑比较多,需要细心一点。 + +### 2.1 显卡驱动 + +输入命令看一下系统推荐的驱动版本号,再进行相应版本的驱动安装即可。 + +命令:`ubuntu-drivers devices` + +```shell +(base) iron@iron-H310M-S2-2-0:~/桌面/share/darknet$ ubuntu-drivers devices +== /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0 == +modalias : pci:v000010DEd00001F82sv00001B4Csd00001320bc03sc00i00 +vendor : NVIDIA Corporation +driver : nvidia-driver-435 - distro non-free +driver : nvidia-driver-440 - third-party free recommended +driver : xserver-xorg-video-nouveau - distro free builtin +``` + +可以看到我的系统`recommended`版本是`nvidia-driver-440`,直接使用命令安装: + +`sudo apt-get install nvidia-driver-440` + +测试安装是否成功: + +使用`nvidia-smi`命令,输出显卡信息即成功。 + +> 提示:显卡驱动也可以去NVIDIA官网查询对应的版本进行安装,下载Linux版本即可。我个人习惯使用上面的方式。 + +### 2.2 CUDA + +CUDA官网下载页面:https://developer.nvidia.com/cuda-toolkit-archive + +目前出到了`10.2`版本,不过我下载的`10.1`,为了求稳,也为了遇到问题能在网上找到更多的解决办法。 + +下载选择:Linux-->x86_64-->ubuntu-->18.04-->runfile + +这里将我下载的`10.1`版本传到百度了:`链接: https://pan.baidu.com/s/1PyQJcR3G-kKIHqOFtFiBHg 提取码: ssp9` + +- 安装依赖 + +`sudo apt-get install freeglut3-dev build-essential libx11-dev libxmu-dev libxi-dev libgl1-mesa-glx libglu1-mesa libglu1-mesa-dev` + +- 安装CUDA + +进入CUDA的下载目录,执行安装: + +`sudo ./cuda_10.1.105_418.39_linux.run ` + +安装过程没什么可说的,唯一要注意的是:在出现`Install NVIDIA Accelerated Graphics Driver for Linux-x86_64?`时,输入`no`,因为上一步我们装过显卡驱动了,这里不用安装,其他步骤都是`yes`或者`回车`。 + +- 配置环境变量 + +配置前确定指定的目录已经存在 + +```bash +sudo vi ~/.bashrc +#文件末尾添加 +export PATH=/usr/local/cuda-10.1/bin:$PATH +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda-10.1/lib64 +``` +```shell +#刷新配置文件 +sudo source ~/.bashrc +``` + +- 测试 + +检查是否安装成功 + +`cd /usr/local/cuda-10.1/samples/1_Utilities/deviceQuery` +`sudo make ` +`./deviceQuery` + +输出CUDA VERSION等信息即成功 + +### 2.3 CUDNN + +cudnn安装要注意的是版本要和cuda一致,下载页面:https://developer.nvidia.com/rdp/cudnn-download + +下载需要注册开发者账号,按照步骤注册即可。 + +百度云`10.1`版本:`链接: https://pan.baidu.com/s/1oAsw6LUMpjW9NfNL_JVIJA 提取码: zvui` + +- 将cudann的压缩包解压 +- 解压后得到cuda文件夹,文件夹和cuda安装目录中的文件夹是对应的,将文件复制到cuda对应的文件夹中即可 + +> 上一步的cuda安装完成以后路径为:/usr/local/cuda10.1 + +示例: + +```shell +tar -zxvf cudnn-10.1-linux-x64-v7.6.5.32.tgz + +sudo cp cuda/include/cudnn.h /usr/local/cuda10.1/include +sudo cp cuda/lib64/libcudnn* /usr/local/cuda10.1/lib64 +sudo chmod a+r /usr/local/cuda/include/cudnn.h /usr/local/cuda10.1/lib64/libcudnn* +``` + +最后更新软链接,这步如果不执行,后面会报错`xxxxxx.so.x 不是符号链接` + +> 这个so文件的版本要提前看好,我文件夹里的so文件是libcudnn.so.7.6.5 + +```shell +cd /usr/local/cuda-10.1/lib64/ + +sudo chmod +r libcudnn.so.7.6.5 +sudo ln -sf libcudnn.so.7.6.5 libcudnn.so.7 +sudo ln -sf libcudnn.so.7 libcudnn.so +sudo ldconfig +``` + +或者在遇到某某so文件不是符号链接的错误时,执行:`sudo ldconfig -v`,找到错误的so文件,创建一个软链。 + +--- + +## 三. 使用GPU测试运行项目 + +前面装好了所需的环境,接下来测试yolo项目是否可以在GPU下运行。 + +- 修改darknet项目配置文件 + +在darknet项目根目录下有`Makefile`文件,修改其中配置: + +```shell +GPU=1 +CUDNN=1 +``` + +- 重新编译项目: + +`make clean` + +`make` + +- 测试: + +`./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg` + +这里是我的测试速度对比:质的飞跃 + +- CPU + +```shell +Loading weights from yolov3.weights...Done! +data/dog.jpg: Predicted in 19.692001 seconds. +dog: 6379% +truck: 1609% +truck: 226% +bicycle: 3912% +``` + +- GPU + +```shell +Loading weights from yolov3.weights...Done! +data/dog.jpg: Predicted in 0.131651 seconds. +dog: 100% +truck: 92% +bicycle: 99% +``` + +--- + +## 四. 配置OPENCV + +出于对darknet视频实时检测的好奇,决定自己做一个目标检测的样例视频,自己拍摄剪辑然后做目标检测,所以又需要安装OPENCV来支持视频处理。 + +### 4.1 文件下载 + +文件需要下载两个,一个是`opencv`一个是`opencv_contrib`,版本要对应,我这里下载的是4.3版本 + +- 官方 + +opencv:https://opencv.org/releases/ + +opencv_contrib:https://github.com/opencv/opencv_contrib/releases + +- 百度盘 + +opencv:`链接: https://pan.baidu.com/s/163SbilBZdsS2MxqTdMaeEg 提取码: asja` + +opencv_contrib:`链接: https://pan.baidu.com/s/1LhMkqBr5U5b8b7qXTZDAtA 提取码: niqq` + +### 4.2 安装 + +- 安装依赖 + +```shell + sudo apt-get install build-essential + sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev + sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev +``` + +- 安装cmake-gui + +```shell + sudo apt-get install cmake-qt-gui +``` + +- 将`opencv`和`opencv_contrib`解压后放到统一目录下 +- 在`opencv`目录下创建`build`目录,用来存放编译文件 +- 进入`build`目录,执行:`cmake-gui` +- 在界面上方配置源码和编译目录 + - where is the source code:# 指定opencv的目录 + - where to build the binaries:# 指定编译目录(即上一步创建的build目录) +- 点击`configure` + - Unix Makefiles - > Use default native compilers- > Finish + +- 编译参数配置 + - CMAKE_BUILD_TYPE:RELEASE + - CMAKE_INSTALL_PREFIX:# 配置安装目录 + - OPENCV_EXTRA_MODULES_PATH:# 配置opencv_contrib的modules目录 + +- 点击`Generate` +- 在**终端**进入`build`目录,执行`make`,开始编译,没有意外会编译成功进行下一步,而现实是不可能没有意外... +- 编译成功后,再执行`make install `进行安装 + +#### 4.2.1 编译时的意外 + +- fatal error:boostdesc_bgm.i 没有那个文件或目录 + +文件下载:`链接: https://pan.baidu.com/s/1cjEtx0dIrmeUJdFDmb-KHw 提取码: ir4h ` + +全部文件放入`opencv_contrib/modules/xfeatures2d/src/`目录下 + +- fatal error : feature2d/test/test_detectors_regression.impl.hpp + +这是一类头文件的问题,提示找不到文件,可能错误地方不止一个,但是解决方法是一样的 + +> 定位到出错的`cpp`文件 +> +> 编辑这个文件,将`#include "feature2d/test/test_detectors_regression.impl.hpp"`改为`#include "test_detectors_regression.impl.hpp"` +> +> 然后将`test_detectors_regression.impl.hpp`文件放到当前`cpp`文件目录中就可以了 +> +> 那这个文件在哪呢? +> +> 所有缺失的hpp文件在opencv4.3/modules/features2d/test文件夹中都能找到 + +### 4.3 配置环境变量 +- 编辑文件sudo vim /etc/ld.so.conf.d/opencv.conf ,写入opencv安装目录下的lib目录路径 +- 编辑文件sudo vim /etc/bash.bashrc ,末尾添加两行内容: + - `PKG_CONFIG_PATH=$PKG_CONFIG_PATH:opencv安装目录/lib/pkgconfig ` + - `export PKG_CONFIG_PATH` +- 最后执行:source /etc/profile + +### 4.4 测试 + +测试是否安装成功:pkg-config --cflags --libs opencv + +```shell +(base) iron@iron-H310M-S2-2-0:/usr/local/cuda/lib64$ pkg-config --cflags --libs opencv +-I/home/iron/opencv-4.3.0/include/opencv4 -L/home/iron/opencv-4.3.0/lib -lopencv_shape -lopencv_stitching -lopencv_objdetect -lopencv_superres -lopencv_videostab -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_video -lopencv_photo -lopencv_ml -lopencv_imgproc -lopencv_flann -lopencv_core +``` + +--- + +## 五. 再次编译darknet项目 + +我们这次加入了opencv的支持,和之前一样,先改配置文件,再重新编译项目 + +- 改darknet项目下:Makefile文件 + +```shell +GPU=1 +CUDNN=1 +OPENCV=1 +``` + +- 重新编译项目: + +`make clean` + +`make` + +不出意外的话直接编译成功 + +### 5.1 darknet + opencv编译的意外 + +- image_opencv.cpp:12:1: error: ‘IplImage’ + +这看似是代码兼容问题,在我们的darknet项目下可以找到这个出错的文件:darknet/src/image_opencv.cpp + +最简单的解决办法是把文件替换成我的这个,我已经改好了: + +`链接: https://pan.baidu.com/s/1bns2HLAFd--pvBHJpTZaLQ 提取码: 929p` + + + +--- + +## 六、参考文献 + +> [opencv4.2.0+darknet安装 ./src/image_opencv.cpp:12:1: error: ‘IplImage’ 报错](https://blog.csdn.net/a135013563/article/details/104859395) +> +> [YOLO: Real-Time Object Detection](https://pjreddie.com/darknet/yolo/) + +--- + +**如果您看到了这里,请给我一个star:star:谢谢,如果有遗漏,请留言指正,感激!** \ No newline at end of file diff --git a/doc/classifier_train_handbook.md b/doc/classifier_train_handbook.md new file mode 100644 index 0000000..34db618 --- /dev/null +++ b/doc/classifier_train_handbook.md @@ -0,0 +1,108 @@ +# 汉字分类识别模型训练手册 + +理论上可以不用`汉字检测+汉字识别`分两步,一步就可以完成,目前局限在数据集上,我手里的一步模型识别效果不是很理想。 + +此次我会挑几个字出来训练,训练数据我会放在`files/train`目录下,供大家练习和参考,更多讨论和需求欢迎加入我刚刚建立的QQ群::rocket:`1040784971`:rocket: + +--- + +[环境的安装和准备看这里](./Ubuntu18.04%20install%20darknet%20yolo-v3%7Ccuda%7Ccudnn%7Copencv%7Canaconda.md) + +[汉字检测定位模型训练手册看这里](./detector_train_handbook.md) + +--- + +## 一、数据准备 + +这次的数据集比较简单,我都放好了在`files/train/hanzi_classification`目录下,每个文件的文件名即标签。 + +文件名如下: + +```shell +0092e7d888a1ab411eabd50e9cc5b2fa旅_u65c5.jpg 8b9c6569c7e55291f1dcff7026da1806区_u533a.jpg +036cac9f0db46babad19a9f129ed7587旅_u65c5.jpg 90e9fbca52b7faa571d430f9be27bfdd态_u6001.jpg +... +... +``` + +训练时读取的是`下划线_`后面的`Unicode`部分作为标签(中文支持不好),前面一段是为了方便区分。 + +训练数据包含了`生态旅游区`五个字,每个字`50`张图。 + +![](../media/0b7bbb3595309f7f9123704ef354a52d%E6%97%85_u65c5.jpg) + +接下来配置几个文件即可开始训练: + +- data文件:`data/hanzi_clas.data` + + ```txt + classes = 5 # 分类(标签)数 + train = data/hanzi_clas_train.txt # 训练数据路径 + labels = data/hanzi_clas.labels # 标签文件 + backup = backup/ # 模型保存文件 + ``` + + - `hanzi_clas_train.txt`文件的生成: + + 这个文件内容是每个训练图片的绝对路径,一共250条记录对应250张图片(修改成自己电脑上的路径) + + ```txt + /Users/hanzi_clas_train/719ce7a4febff78be03c33a6e11a3231生_u751f.jpg + /Users/hanzi_clas_train/fedb1de7214d3c429bcb05ea28e92862生_u751f.jpg + ... + ... + ``` + + - `data/hanzi_clas.labels`文件的生成: + + 记录需要分类的标签名称,我们有5个汉字需要分类,这里用`Unicode`编码来表示五个汉字 + + ```txt + u6001 + u65c5 + u6e38 + u751f + u533a + ``` + +- cfg文件:模型网络配置文件`cfg/hanzi_clas.cfg`,具体配置是什么意思Google吧,有感兴趣的童鞋再留言更新。 + +--- + +## 模型训练 + +1. 训练 + + `./darknet classifier train data/hanzi_clas.data cfg/hanzi_clas.cfg` + + ```shell + ... + ... + ... + 99, 25.344: 1.554884, 1.496595 avg, 0.000000 rate, 0.353925 seconds, 6336 images + Loaded: 0.000017 seconds + 100, 25.600: 1.523866, 1.499322 avg, 0.000000 rate, 0.419332 seconds, 6400 images + Saving weights to backup/hanzi_clas.weights + ``` + + 训练完成后,会在`backup`文件夹下生成`weights`文件 + +2. 测试 + + `./darknet classifier predict data/hanzi_clas.data cfg/hanzi_clas.cfg backup/hanzi_clas.weights ` + + ```shell + ... + ... + ... + Loading weights from backup/hanzi_clas.weights...Done! + top: Using default '1' + Enter Image Path: + ``` + + 输入要测试的图片地址即可。 + +--- + +**如果您看到了这里,给个star:star:,谢谢,如有遗漏请留言,感激** + diff --git a/doc/detector_train_handbook.md b/doc/detector_train_handbook.md new file mode 100644 index 0000000..497ad3a --- /dev/null +++ b/doc/detector_train_handbook.md @@ -0,0 +1,177 @@ +# 定位模型训练手册 + +此次更新了汉字目标检测的训练内容,从基础的环境编译开始。顺便说一下,GPU的环境是必要的,CPU训练极慢... + +关于最终模型识别效率:我生产环境是0.08S一张图,模型文件200多M,用的垃圾显卡。如果没有显卡,可以进行模型优化,如果有反应这个问题的童鞋,后续更新优化。 + +[环境的安装和准备看这里](./Ubuntu18.04%20install%20darknet%20yolo-v3%7Ccuda%7Ccudnn%7Copencv%7Canaconda.md) + +## 一、数据准备 + +数据包括了训练数据集和验证集。训练集我放了1K份在`files/train`目录下;验证集放了500份在`files/valid`目录下。 + +### 1.1 训练数据集的准备 + +介绍一下数据集的格式。目录`files/train/jiyan_train_imgs_txt_1K`下的文件形式如下: + +```shell +aba5bec4daa6c11fdd684594778e7737.jpg +aba5bec4daa6c11fdd684594778e7737.txt +5679c2443905cec1f43c9b2b69fd9efd.jpg +5679c2443905cec1f43c9b2b69fd9efd.txt +... +... +``` + +我们本次的检测目标只有一个是汉字`hanzi`(classes=1),简单来说目标就是输出一个图片中所有汉字的坐标。达到这种效果: + +![预测结果图片](../hanzi_detection/predictions.jpg) + +在构建训练集的时候,我们要同时准备`图片`和`坐标`两个文件。 + +一个`jpg`图片,对应一个同名的`txt`文件,图片文件没什么好说的,就是待检测的图片。 + +`txt`文件内容如下: + +```txt +0 0.6918604651162791 0.6875 0.20348837209302326 0.15625 +0 0.7441860465116279 0.1171875 0.20348837209302326 0.15625 +0 0.2616279069767442 0.203125 0.20348837209302326 0.15625 +0 0.3226744186046512 0.4895833333333333 0.20348837209302326 0.15625 +``` + +这里的四行内容,对应图片上的四个汉字的`classes`和`position`信息,因为我们就只有一个(标签)`classes`是`hanzi`,所以所有的值都是`0`。如果我们有两个目标需要检测,比如`中文`和`英文`,classes=2,`txt`文件的每一行的第一列就可能是:`0`或者`1`,多个目标,以此类推。 + +这个`txt`文件的构造需要说明一下,第一列上面已经说了;后面四列代表着汉字的`x,y,width,height`,而且是经过处理的值,这里介绍一下处理过程: + +我们在标记训练数据的时候,给每个汉字的位置信息都标注出来,如下: + +![ab9a8dcdda85f1d8789909803374fbea](../media/ab9a8dcdda85f1d8789909803374fbea.jpg) + +以`太`字为例,坐标为:`x1y1,x2y2`,整个图片大小为:`width:344,height:384` + +```python +Python 3.7.4 (default, Aug 13 2019, 15:17:50) +[Clang 4.0.1 (tags/RELEASE_401/final)] :: Anaconda, Inc. on darwin +Type "help", "copyright", "credits" or "license" for more information. +>>> def convert(size, box): +... dw = 1. / (size[0]) +... dh = 1. / (size[1]) +... x = (box[0] + box[1]) / 2.0 - 1 +... y = (box[2] + box[3]) / 2.0 - 1 +... w = box[1] - box[0] +... h = box[3] - box[2] +... x = x * dw +... w = w * dw +... y = y * dh +... h = h * dh +... return (x, y, w, h) +... + +>>> convert((344,384),(22,82,195,265)) +(0.14825581395348836, 0.5963541666666666, 0.1744186046511628, 0.18229166666666666) +``` + +这里的`convert`参数为:`convert((width, height), (x1, x2, y1, y2))`,输出的结果即为`txt`文件后四列的内容。 + +最重要的数据集准备完了,然后再配置一下模型数量参数即可开始训练,有如下几个文件: + +- data文件:data/detector.data,例子: + + ```data + classes = 1 # 检测目标数量 + train = train/train.txt # 训练文件路径 + valid = valid/valid.txt # 验证文件路径 + names = data/jiyan.names # names文件路径 + backup = backup/ # 训练完的模型保存路径 + ``` + + - `train.txt`文件的生成,这个文件内容是`训练数据集`中每个`jpg`文件的`绝对路径`,只要`jpg`文件的路径即可,模型会找对应路径下的`txt`文件。 + + ```txt + /home/files/jiyan_train_imgs_txt_1K/c5ff5214ef37bcf7db239b02a94a34da.jpg + /home/files/jiyan_train_imgs_txt_1K/d088c915a03c77bc89a9e466074f10a8.jpg + /home/files/jiyan_train_imgs_txt_1K/814613e0ac5d67cd9f9fdce55c8ec0d4.jpg + ... + ... + ``` + + 可以在Linux中直接生成: + + `find path_to_train_dir -name '*.jpg' > path/train.txt` + + - `valid.txt`文件生成同上 + +- names文件,内容如下:要检测的目标名称 + + ```txt + hanzi + ``` + +- 权重文件 + + 在训练的时候可以基于官方的`卷积权重`来开始,下载到项目的`backup`目录下即可。 + + 文件太大,请自行下载。 + + [下载地址](https://pjreddie.com/media/files/darknet53.conv.74) + +- 配置文件:`cfg/detecter.cfg` + + 其中`max_batches = 1500`是训练的轮数,可以根据需要修改。 + + + +## 训练模型 + +当我们所有数据文件都准备好后,就可以编译项目,开始训练了。 + +1. 首先进入项目文件夹:`cd hanzi_detection` + +2. 修改`Makefile`文件:`vim Makefile` + + 如果不用gpu训练,这步跳过。 + +```shell +GPU=1 # 使用GPU +... +... +NVCC=/usr/local/cuda-10.1/bin/nvcc # nvcc路径改为cuda的安装目录下的nvcc +``` + +3. 编译项目:`make clean` `make` + +4. 训练: + + `./darknet detector train data/detector.data cfg/detector.cfg backup/darknet53.conv.74` + + 训练完会在`backup`目录下生成`xxx_final.weights`文件 + +5. 验证集 + + `./darknet detector valid cfg/detector.data cfg/detector.cfg backup/xxx_final.weights` + + 在`results`目录下生成结果 + +6. 单张检测 + + `./darknet detector test cfg/detector.data cfg/detector.cfg backup/xxx_final.weights` + + 然后输入要检测的图片地址,即可在根目录下生成`predictions.jpg` + + ![](../hanzi_detection/predictions.jpg) + + + +**如果您看到了这里,请给个star,谢谢,如有错误遗漏,请留言指正,感激** + + + + + + + + + + + diff --git a/doc/jiyan_gt_challenge.md b/doc/jiyan_gt_challenge.md new file mode 100644 index 0000000..580939e --- /dev/null +++ b/doc/jiyan_gt_challenge.md @@ -0,0 +1,45 @@ +### 项目介绍 + +数据采集的过程中难免会遇到一些验证码需要解决,这里介绍一下我遇到jiyan平台的验证码是如何进行分析的。 + +**声明**: 本项目仅供学习交流使用,严禁用于商业和违法行为,否则产生的一切后果与本人无关。 + +利益相关,无法开放源码,为了方便说明,这里使用一些文字代替是必要的。 + +内容比较草率,不过我相信真正研究过的人可以看懂,伸手党估计不合适。 + +**如果对您有用,请给项目一个star,谢谢** + +> 感兴趣或者看不懂可以加项目首页的微信交流,记得备注 + +### 参数分析 + +jiyan的关键参数是`gt`和`challenge` + +1. 获取第一段加密JS和uid参数,解密后获得新的JS代码 + + ```python + s1 = re.findall('var x="(.*?)"', first_js)[0] + s2 = re.findall(',y="(.*?)"', first_js)[0] + second_js = self.wc_js.call('first_se_js', s1, s2) + ``` + +2. 新的JS运行后生成的`__jsl_clearance`参数和第一步的uid,请求得到JSESSIONID + + 这一步关键的两个参数是`__jsluid_h`和`__jsl_clearance` + + 在cookie中携带请求,可获得JSESSIONID + + ```python + headers['Cookie'] = '__jsluid_h=__jsluid_h; __jsl_clearance=__jsl_clearance;' + ``` + +3. 此时我们有了三个关键参数,携带三个参数去请求验证码接口,获取新的JSESSIONID + + ```python + headers['Cookie'] = '__jsluid_h=__jsluid_h; __jsl_clearance=jsl_clearance;JSESSIONID=JSESSIONID' + ``` + +4. 这时候有了所有的参数了,再携带访问jiyan的接口,即可获得`gt`和`challenge` + +5. 根据`gt`和`challenge`分析验证码类型,进行相应的处理,这里可以通过统一接口进行处理,也可以对`滑动验证`、`点选验证码`进行分别处理(这部分内容涉及比较广,新手可以使用打码平台,或者像我一样通过机器学习,产生`轨迹数据`以及训练`识别模型`) \ No newline at end of file diff --git a/doc/jiyan_gt_challenge_demo.ipynb b/doc/jiyan_gt_challenge_demo.ipynb new file mode 100644 index 0000000..b1ddfda --- /dev/null +++ b/doc/jiyan_gt_challenge_demo.ipynb @@ -0,0 +1,711 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 使用企业公示网做例子\n", + "\n", + "获取gt和challenge两个参数" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import requests" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# 企业公示网做例子\n", + "index_url = 'http://www.gsxt.gov.cn/index.html'\n", + "index_header= {\n", + " 'accept': \"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\",\n", + " 'accept-encoding': \"gzip, deflate\",\n", + " 'accept-language': \"zh-CN,zh;q=0.9\",\n", + " 'connection': \"keep-alive\",\n", + " 'host': \"www.gsxt.gov.cn\",\n", + " 'upgrade-insecure-requests': \"1\",\n", + " 'Referer': 'http://www.gsxt.gov.cn/index.html',\n", + " \"User-Agent\": \"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36\",\n", + " }" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# 代理手动配置,避免本地的IP被封了\n", + "\n", + "# 代理服务器\n", + "proxyHost = \"forward.apeyun.com\"\n", + "proxyPort = \"9082\"\n", + "\n", + "# 代理隧道验证信息\n", + "proxyUser = \"2020070100845351047\"\n", + "proxyPass = \"G8oyqzh6zswpSMtk\"\n", + "\n", + "proxyMeta = \"http://%(user)s:%(pass)s@%(host)s:%(port)s\" % {\n", + " \"host\" : proxyHost,\n", + " \"port\" : proxyPort,\n", + " \"user\" : proxyUser,\n", + " \"pass\" : proxyPass,\n", + "}\n", + "\n", + "proxy = {\n", + " \"http\" : \"\",\n", + " \"https\" : \"\",\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "response = requests.get(index_url, headers=index_header, proxies=proxy)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "获取到第一段JS代码" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\n'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "response.text # 获取第一段js" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "获取jsluid参数" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'697b3a8c209b3fcfafa830c6bc637392'" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "jsluid = response.headers['Set-Cookie'].split('=')[1].split(';')[0] \n", + "jsluid" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "解密出第二段js代码" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"var _36=function(){setTimeout('location.href=location.pathname+location.search.replace(/[\\\\\\\\?|&]captcha-challenge/,\\\\\\\\'\\\\\\\\')',1500);document.cookie='__jsl_clearance=1593670282.998|0|'+(function(){var _w=[function(_36){return _36},function(_w){return _w},(function(){var _36=document.createElement('div');_36.innerHTML='_1u';_36=_36.firstChild.href;var _w=_36.match(/https?:\\\\\\\\/\\\\\\\\//)[0];_36=_36.substr(_w.length).toLowerCase();return function(_w){for(var _1u=0;_1u<_w.length;_1u++){_w[_1u]=_36.charAt(_w[_1u])};return _w.join('')}})(),function(_36){for(var _w=0;_w<_36.length;_w++){_36[_w]=parseInt(_36[_w]).toString(36)};return _36.join('')}],_36=['DX',[(-~[2]+[])+(([-~-~{}]+(+[])>>-~-~{})+[]+[[]][0])],[(-~~~''+[]+[])+(-~[2]+[])],'r',[(-~~~''+[]+[])+(-~[2]+[])],'47V',[-~![]-~[((+!(+!{}))<<(+!(+!{})))-~{}-~(-~[-~[]-~[]])]],[(4+[]+[]),(-~[2]+4+[[]][0])],[(-~[2]+[])+(~~[]+[]+[]),(-~[2]+[])+(4+[]+[])],'OXM',[(-~~~''+[]+[])+(-~~~''+[]+[])],'RHu',[(-~~~''+[]+[])+(4+[]+[])],'APPlY%3D'];for(var _1u=0;_1u<_36.length;_1u++){_36[_1u]=_w[[1,3,2,1,3,1,0,2,3,1,2,1,2,1][_1u]](_36[_1u])};return _36.join('')})()+';Expires=Thu, 02-Jul-20 07:11:22 GMT;Path=/;'};if((function(){try{return !!window.addEventListener;}catch(e){return false;}})()){document.addEventListener('DOMContentLoaded',_36,false)}else{document.attachEvent('onreadystatechange',_36)}\"" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import re\n", + "import execjs\n", + "\n", + "\n", + "des_js = 'function get_z(x, y) {\\n f = function (x, y) {\\n var a = 0,\\n b = 0,\\n c = 0;\\n x = x.split(\"\");\\n y = y || 99;\\n while ((a = x.shift()) && (b = a.charCodeAt(0) - 77.5)) c = (Math.abs(b) < 13 ? (b + 48.5) : parseInt(a, 36)) + y * c;\\n return c\\n };\\n x = x.replace(/@*$/, \"\").split(\"@\");\\n z = f(y.match(/\\\\w/g).sort(function (x, y) {\\n return f(x) - f(y)\\n }).pop());\\n return [x, y, z]\\n\\n}\\n\\nfunction get_js(x, y, z) {\\n f = function (x, y) {\\n var a = 0,\\n b = 0,\\n c = 0;\\n x = x.split(\"\");\\n y = y || 99;\\n while ((a = x.shift()) && (b = a.charCodeAt(0) - 77.5)) c = (Math.abs(b) < 13 ? (b + 48.5) : parseInt(a, 36)) + y * c;\\n return c\\n };\\n x = eval(x);\\n z = z + 1;\\n p = y.replace(/\\\\b\\\\w+\\\\b/g,\\n function (y) {\\n return x[f(y, z) - 1] || (\"_\" + y)\\n });\\n return p\\n\\n}\\n\\n\\nfunction once_js(x, y) {\\n f = function (x, y) {\\n var a = 0,\\n b = 0,\\n c = 0;\\n x = x.split(\"\");\\n y = y || 99;\\n while ((a = x.shift()) && (b = a.charCodeAt(0) - 77.5)) c = (Math.abs(b) < 13 ? (b + 48.5) : parseInt(a, 36)) + y * c;\\n return c\\n },\\n x = x.replace(/@*$/, \"\").split(\"@\");\\n z = f(y.match(/\\\\w/g).sort(function (x, y) {\\n return f(x) - f(y)\\n }).pop());\\n while (z++) try {\\n g = y.replace(/\\\\b\\\\w+\\\\b/g,\\n function (y) {\\n return x[f(y, z) - 1] || (\"_\" + y)\\n });\\n return g\\n } catch (_) {\\n }\\n}'\n", + "des_js = execjs.compile(des_js)\n", + "first_js = response.text\n", + "x = re.findall('var x=\"(.*?)\"', first_js)[0]\n", + "y = re.findall(',y=\"(.*?)\"', first_js)[0]\n", + "second_js = des_js.call('once_js', x, y)\n", + "second_js" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "处理第二段js,去除document" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'cookie=\\'__jsl_clearance=1593670282.998|0|\\'+(function(){var _w=[function(_36){return _36},function(_w){return _w},(function(){var _36=\"www.gsxt.gov.cn/index.html\";var _w=\"http://\";return function(_w){for(var _1u=0;_1u<_w.length;_1u++){_w[_1u]=_36.charAt(_w[_1u])};return _w.join(\\'\\')}})(),function(_36){for(var _w=0;_w<_36.length;_w++){_36[_w]=parseInt(_36[_w]).toString(36)};return _36.join(\\'\\')}],_36=[\\'DX\\',[(-~[2]+[])+(([-~-~{}]+(+[])>>-~-~{})+[]+[[]][0])],[(-~~~\\'\\'+[]+[])+(-~[2]+[])],\\'r\\',[(-~~~\\'\\'+[]+[])+(-~[2]+[])],\\'47V\\',[-~![]-~[((+!(+!{}))<<(+!(+!{})))-~{}-~(-~[-~[]-~[]])]],[(4+[]+[]),(-~[2]+4+[[]][0])],[(-~[2]+[])+(~~[]+[]+[]),(-~[2]+[])+(4+[]+[])],\\'OXM\\',[(-~~~\\'\\'+[]+[])+(-~~~\\'\\'+[]+[])],\\'RHu\\',[(-~~~\\'\\'+[]+[])+(4+[]+[])],\\'APPlY%3D\\'];for(var _1u=0;_1u<_36.length;_1u++){_36[_1u]=_w[[1,3,2,1,3,1,0,2,3,1,2,1,2,1][_1u]](_36[_1u])};return _36.join(\\'\\')})()+\\';Expires=Thu, 02-Jul-20 07:11:22 \\''" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "new_js = second_js.replace('\\\\\\\\', '\\\\')\n", + "\n", + "new_js = 'cookie' + new_js.split('document.cookie')[1]\n", + "new_js = new_js.split('GMT;Path=/;')[0] + \"'\"\n", + "\n", + "if re.findall(\"(var .{0,5}=)document\\.createElement\\('div'\\);\", new_js):\n", + " _3d = re.findall(\"(var .{0,5}=)document\\.createElement\\('div'\\);\", new_js)\n", + " _2b = re.findall(\"(var .{0,5}=).{0,5}\\.match\\(/https\\?:\\\\\\/\\\\\\//\\)\\[0\\];\", new_js)\n", + " new_js = re.sub(\n", + " \"var .{0,5}=document\\.createElement\\('div'\\);\", \n", + " _3d[0] + f'\"{index_url.replace(\"http://\", \"\")}\";',\n", + " new_js\n", + " )\n", + " new_js = re.sub(\"_.{0,5}\\.innerHTML='';\", \"\", new_js)\n", + " new_js = re.sub(\"_.{0,5}=.{0,5}\\.firstChild\\.href;\", \"\", new_js)\n", + " new_js = re.sub(\"var .{0,5}=.{0,5}\\.match\\(/https\\?:\\\\\\/\\\\\\//\\)\\[0\\];\", _2b[0] + '\"http://\";', new_js)\n", + " new_js = re.sub(\"_.{0,5}=.{0,5}\\.substr\\(.{0,5}\\.length\\)\\.toLowerCase\\(\\);\", \"\", new_js)\n", + "new_js" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "处理js,去除Window" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "find = re.findall(\"!*window\\[.*?\\]\", new_js)\n", + "if find:\n", + " for f in find:\n", + " if '!' in f:\n", + " if len(re.findall('!', f)) % 2 == 0:\n", + " new_js = new_js.replace(f, 'false')\n", + " else:\n", + " new_js = new_js.replace(f, 'true')\n", + " else:\n", + " new_js = new_js.replace(f, 'undefined')\n", + "new_js = new_js.replace('window.headless', 'undefined')" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'cookie=\\'__jsl_clearance=1593670282.998|0|\\'+(function(){var _w=[function(_36){return _36},function(_w){return _w},(function(){var _36=\"www.gsxt.gov.cn/index.html\";var _w=\"http://\";return function(_w){for(var _1u=0;_1u<_w.length;_1u++){_w[_1u]=_36.charAt(_w[_1u])};return _w.join(\\'\\')}})(),function(_36){for(var _w=0;_w<_36.length;_w++){_36[_w]=parseInt(_36[_w]).toString(36)};return _36.join(\\'\\')}],_36=[\\'DX\\',[(-~[2]+[])+(([-~-~{}]+(+[])>>-~-~{})+[]+[[]][0])],[(-~~~\\'\\'+[]+[])+(-~[2]+[])],\\'r\\',[(-~~~\\'\\'+[]+[])+(-~[2]+[])],\\'47V\\',[-~![]-~[((+!(+!{}))<<(+!(+!{})))-~{}-~(-~[-~[]-~[]])]],[(4+[]+[]),(-~[2]+4+[[]][0])],[(-~[2]+[])+(~~[]+[]+[]),(-~[2]+[])+(4+[]+[])],\\'OXM\\',[(-~~~\\'\\'+[]+[])+(-~~~\\'\\'+[]+[])],\\'RHu\\',[(-~~~\\'\\'+[]+[])+(4+[]+[])],\\'APPlY%3D\\'];for(var _1u=0;_1u<_36.length;_1u++){_36[_1u]=_w[[1,3,2,1,3,1,0,2,3,1,2,1,2,1][_1u]](_36[_1u])};return _36.join(\\'\\')})()+\\';Expires=Thu, 02-Jul-20 07:11:22 \\''" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "new_js" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "获取jsl_clearance" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'1593670282.998|0|DXzcrd47V9gtuyOXMvRHunAPPlY%3D'" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "js = \"\"\"\n", + " function getJS() {\n", + " %s\n", + " return cookie\n", + " }\n", + " \"\"\" % new_js\n", + "exec_js = execjs.compile(js)\n", + "jsl = exec_js.call('getJS')\n", + "jsl = jsl.split(';')[0]\n", + "jsl_clearance = jsl.split('=')[1]\n", + "jsl_clearance" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'e1d92a59a5b23981cbfa00048eea'" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 获取第一个jessionid\n", + "headers = index_header.copy()\n", + "headers['Cookie'] = f'__jsluid_h={jsluid}; __jsl_clearance={jsl_clearance};'\n", + "response2 = requests.get(index_url, headers=headers, proxies=proxy)\n", + "JSESSIONID1 = re.findall('JSESSIONID=(.*?);', response2.headers['Set-Cookie'])[0]\n", + "JSESSIONID1" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'e1d92a59a5b23981cbfa00048eea'" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 获取第二个jessionid\n", + "import time\n", + "\n", + "url = 'http://www.gsxt.gov.cn/SearchItemCaptcha?t=' + str(int(time.time()*1000))\n", + "headers = index_header.copy()\n", + "headers['Cookie'] = f'__jsluid_h={jsluid}; __jsl_clearance={jsl_clearance};JSESSIONID={JSESSIONID1}'\n", + "response3 = requests.get(url, headers=headers, proxies=proxy)\n", + "JSESSIONID2 = re.findall('JSESSIONID=(.*?);', response3.headers['Set-Cookie'])[0]\n", + "JSESSIONID2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "测试cookie,如果状态码是200,获取gt和challenge" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "200" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import json\n", + "\n", + "headers = index_header.copy()\n", + "headers['Cookie'] = f'__jsluid_h={jsluid}; __jsl_clearance={jsl_clearance};JSESSIONID={JSESSIONID2}'\n", + "url = 'http://www.gsxt.gov.cn/SearchItemCaptcha?t=' + str(int(time.time()*1000))\n", + "response4 = requests.get(url, headers=headers, proxies=proxy)\n", + "response4.status_code" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "gt_challenge_json = json.loads(response4.text)\n", + "gt = gt_challenge_json['gt']\n", + "challenge = gt_challenge_json['challenge']" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'62756445cd524543f5a16418cd920ffd'" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gt" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'bc7be94649e930d1f8da98772e82060f'" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "challenge" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 下面开始搜索企业信息" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 如果您看到这里,请给我一个star,谢谢,如有遗漏,请留言指正,感激!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "这里先走一遍采集流程,本地打码服务的实现稍后整理,要先整理完模型训练部分才能打码\n", + "服务实现流程:\n", + "1. 拿到gt和challenge获取验证码,验证码有两种\n", + " - 滑动3.0\n", + " - 文字点选,这部分的训练模型已经开源了,移步首页\n", + "2. 破解验证码,获取validate" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "# 本地打码服务器,所有验证码类型在这里统一处理,返回validate即可\n", + "get_valid_server = 'http://49.235.209.176:5050'" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "ename": "JSONDecodeError", + "evalue": "Expecting value: line 1 column 1 (char 0)", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mJSONDecodeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0mresp\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrequests\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpost\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0murl\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mjson\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdumps\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 12\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjson\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m/opt/anaconda3/envs/blog/lib/python3.7/site-packages/requests/models.py\u001b[0m in \u001b[0;36mjson\u001b[0;34m(self, **kwargs)\u001b[0m\n\u001b[1;32m 896\u001b[0m \u001b[0;31m# used.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 897\u001b[0m \u001b[0;32mpass\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 898\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mcomplexjson\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mloads\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtext\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 899\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 900\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mproperty\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/opt/anaconda3/envs/blog/lib/python3.7/json/__init__.py\u001b[0m in \u001b[0;36mloads\u001b[0;34m(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)\u001b[0m\n\u001b[1;32m 346\u001b[0m \u001b[0mparse_int\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mparse_float\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 347\u001b[0m parse_constant is None and object_pairs_hook is None and not kw):\n\u001b[0;32m--> 348\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0m_default_decoder\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdecode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 349\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcls\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 350\u001b[0m \u001b[0mcls\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mJSONDecoder\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/opt/anaconda3/envs/blog/lib/python3.7/json/decoder.py\u001b[0m in \u001b[0;36mdecode\u001b[0;34m(self, s, _w)\u001b[0m\n\u001b[1;32m 335\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 336\u001b[0m \"\"\"\n\u001b[0;32m--> 337\u001b[0;31m \u001b[0mobj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mend\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mraw_decode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0midx\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0m_w\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 338\u001b[0m \u001b[0mend\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_w\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mend\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 339\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mend\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/opt/anaconda3/envs/blog/lib/python3.7/json/decoder.py\u001b[0m in \u001b[0;36mraw_decode\u001b[0;34m(self, s, idx)\u001b[0m\n\u001b[1;32m 353\u001b[0m \u001b[0mobj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mend\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mscan_once\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0midx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 354\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mStopIteration\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 355\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mJSONDecodeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Expecting value\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 356\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mobj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mend\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mJSONDecodeError\u001b[0m: Expecting value: line 1 column 1 (char 0)" + ] + } + ], + "source": [ + "# url = f'{get_valid_server}/geetest?gt={gt}&challenge={challenge}'\n", + "# resp = requests.get(url)\n", + "# resp\n", + "\n", + "data = {\n", + " 'gt': gt,\n", + " 'challenge': challenge\n", + "}\n", + "url = 'http://3215952j9f.qicp.vip:10682/captcha'\n", + "\n", + "resp = requests.post(url, data=json.dumps(data))\n", + "print(resp.json())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "val_resu = json.loads(resp.text)\n", + "\n", + "# def get_validate_wander(challenge,gt, vtype=1):\n", + "# data = {\n", + "# 'gt':gt,\n", + "# 'challenge':challenge\n", + "# }\n", + "# url='http://49.235.179.162:5000/geetest'\n", + "# response = requests.post(url=url,data=json.dumps(data))\n", + "# return response.json()\n", + "\n", + "# val_resu = get_validate_wander(challenge=challenge, gt=gt)\n", + "val_resu" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "成功获取validate,开始进行搜索" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from lxml.etree import _Element\n", + "from lxml import etree\n", + "\n", + "def parse_list(content):\n", + " def try_catch(data, patten):\n", + " if isinstance(data, _Element):\n", + " try:\n", + " target = re.sub('\\s', '', data.xpath(patten)[0].strip())\n", + " except:\n", + " target = None\n", + " return target\n", + " return data\n", + " a_list = []\n", + " content_list = content\n", + " html = etree.HTML(content_list)\n", + " list_len = int(html.xpath('//span[@class=\"search_result_span1\"]/text()')[0])\n", + " if list_len == 0:\n", + " return 'None'\n", + " else:\n", + " targit_len = 1\n", + " for i in range(1, targit_len + 1):\n", + " try:\n", + " url = html.xpath('//div[@class=\"main-layout fw f14\"]/div[2]/a[' + str(i) + ']/@href')[0]\n", + " href = 'http://www.gsxt.gov.cn{}'.format(url)\n", + " except:\n", + " href = None\n", + " dic = {\n", + " 'href': href\n", + " }\n", + " a_list.append(dic)\n", + " return a_list" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def list_page(val_resu, jsluid, jsl_clearance, JSESSIONID, search_word):\n", + " time.sleep(1)\n", + " validate = val_resu['data']['validate']\n", + " chall = val_resu['data']['challenge']\n", + " data = {\n", + " 'tab': 'ent_tab',\n", + " 'province': '',\n", + " 'geetest_challenge': chall,\n", + " 'geetest_validate': validate,\n", + " 'geetest_seccode': '{}|jordan'.format(validate),\n", + " 'token': '57571798',\n", + " 'searchword': f'{search_word}',\n", + " }\n", + " time.sleep(5)\n", + " headers =index_header.copy()\n", + " headers['Cookie'] = f'__jsluid_h={jsluid}; __jsl_clearance={jsl_clearance};JSESSIONID={JSESSIONID}'\n", + " post_url = 'http://www.gsxt.gov.cn/corp-query-search-1.html'\n", + " content = requests.post(url=post_url, data=data, headers=headers, verify=False, timeout=(60, 60), proxies=proxy)\n", + " if content.status_code == 200:\n", + " if '您的IP地址' in content.text:\n", + " print('请更换代理')\n", + " else:\n", + " return content.text\n", + " else:\n", + " print('cookies失效')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "配置要搜索的关键词" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "search_word = \"百度\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if val_resu['data']['result'] == 'fail':\n", + " print('get valid error')\n", + "else:\n", + " content_text = list_page(val_resu, jsluid, jsl_clearance, JSESSIONID2, search_word)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "href = parse_list(content_text)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "href" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "headers =index_header.copy()\n", + "headers['Cookie'] = f'__jsluid_h={jsluid}; __jsl_clearance={jsl_clearance};JSESSIONID={JSESSIONID2}'\n", + "detail = requests.get(url=href[0]['href'], headers = headers, proxies = proxy)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "输出结果正确" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etree.HTML(detail.text).xpath(\"//h1\")[0].text.strip()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 如果您看到这里,请给我一个star,谢谢,如有遗漏,请留言指正,感激!" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "blog", + "language": "python", + "name": "blog" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/doc/\344\271\235\345\256\253\346\240\274\345\233\276\347\211\207\351\252\214\350\257\201\347\240\201\350\256\255\347\273\203\351\233\206.md" "b/doc/\344\271\235\345\256\253\346\240\274\345\233\276\347\211\207\351\252\214\350\257\201\347\240\201\350\256\255\347\273\203\351\233\206.md" new file mode 100644 index 0000000..2f14d6a --- /dev/null +++ "b/doc/\344\271\235\345\256\253\346\240\274\345\233\276\347\211\207\351\252\214\350\257\201\347\240\201\350\256\255\347\273\203\351\233\206.md" @@ -0,0 +1,98 @@ +# 九宫格图片验证码训练集 + +这篇主要想记录一下yolo训练数据集的准备过程,毕竟数据才是价值所在。 + +## yolo训练集文件读取逻辑 + +下面说的内容都是基于`darknet`,已测试。 + +关于数据集准备过程我们之前说过,重复的内容就不说了([定位模型训练手册](./detector_train_handbook.md)),这里主要解决一下文件标注命名的问题,以及如何避免训练时遇到`Too many or too few labels`问题,这个问题的根源就是文件标签没有按yolo的规则整理好。 + +这里简单梳理一下逻辑,方便理解我们要怎么给训练集里的数据命名。 + +首先回忆一下我们训练分类器需要准备哪几个文件: + +1. xx.data:定义模型使用到的所有文件路径 + + ```t x t + classes = 144 + train = data/nine_train.txt + labels = data/nine.labels + backup = backup/ + top=1 + ``` + +2. xx.labels:所有分类的标签名称 + + ```t x t + 斧头 + 螃蟹 + 沙发 + 帽子 + 老虎 + 气球 + ... + ``` + +3. xx.txt:所有训练集文件的绝对路径 + + ```txt + /Users/train_file/nine/笔记本电脑_2dae8897ecb032a7daac908c31c596562.jpg + /Users/train_file/nine/笔记本电脑_2dc1ad266d264d40bab65095a5ef86157.jpg + /Users/train_file/nine/笔记本电脑_2dd25a294a4c7157f02aa92724d78ef31.jpg + /Users/train_file/nine/笔记本电脑_2df0b329e546630547a4f1aa816d03ee4.jpg + ... + ``` + +假设我们现在有一批训练数据是这样的: + +```text +/Users/train_file/nine/笔记本电脑_2dae8897ecb032a7daac908c31c596562.jpg +/Users/train_file/nine/笔记本电脑_2dc1ad266d264d40bab65095a5ef86157.jpg +/Users/train_file/nine/笔记本电脑_2dd25a294a4c7157f02aa92724d78ef31.jpg +/Users/train_file/nine/笔记本电脑_2df0b329e546630547a4f1aa816d03ee4.jpg +... +``` + +在训练图片分类器时,图片的文件名要包含标注的标签信息,比如: + +`/Users/train_file/nine/笔记本电脑_2dae8897ecb032a7daac908c31c596562.jpg`,这个图片文件 + +文件名分为三个部分 + +- 2dae8897ecb032a7daac908c31c596562:随机标签,用来防止文件名重复,用随机字符串都可以 +- 笔记本电脑:标注的图片内容 +- Jpg:文件格式 + +**这里要注意:yolo读取的是文件绝对路径,在整个路径中不能包含多个标签** + +什么意思呢?举个例子: + +- 在`/Users/train_file/nine/笔记本电脑_2dae8897ecb032a7daac908c31c596562.jpg`这个文件路径中,`笔记本电脑`是我们要分类的标签,因此不能用这种路径`/Users/train_file/nine/笔记本电脑/笔记本电脑_2dae8897ecb032a7daac908c31c596562.jpg`,这样的话yolo会在路径中读取到两个`笔记本电脑`标签,会提示`Too many or too few labels 2`; + +**分类的标签不能存在包含与被包含的关系** + +举个例子: + +- 我们当前的分类任务要分类这些标签: + + ```txt + 斧头 + 螃蟹 + 沙发 + 鳄鱼 + ... + ``` + + 但是如果我们现在要加一个分类,叫做`鱼`,此时就变成了: + + ```txt + 斧头 + 螃蟹 + 沙发 + 鳄鱼 + 鱼 + ... + ``` + + 这时候`鳄鱼`和`鱼`就组成了被包含的关系,也会报错。 \ No newline at end of file diff --git "a/doc/\345\234\250Python\344\270\255\344\275\277\347\224\250\346\250\241\345\236\213.ipynb" "b/doc/\345\234\250Python\344\270\255\344\275\277\347\224\250\346\250\241\345\236\213.ipynb" new file mode 100644 index 0000000..af73677 --- /dev/null +++ "b/doc/\345\234\250Python\344\270\255\344\275\277\347\224\250\346\250\241\345\236\213.ipynb" @@ -0,0 +1,225 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 在Python中使用我们训练好点模型" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "前面我们实现了`汉字位置检测`和`汉字分类识别`模型,实际使用肯定要结合封装成接口来使用,会比较方便。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "在darknet的官方项目中,已经为我们提供了一个demo" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from ctypes import *\n", + "import math\n", + "import random\n", + "\n", + "def sample(probs):\n", + " s = sum(probs)\n", + " probs = [a/s for a in probs]\n", + " r = random.uniform(0, 1)\n", + " for i in range(len(probs)):\n", + " r = r - probs[i]\n", + " if r <= 0:\n", + " return i\n", + " return len(probs)-1\n", + "\n", + "def c_array(ctype, values):\n", + " arr = (ctype*len(values))()\n", + " arr[:] = values\n", + " return arr\n", + "\n", + "class BOX(Structure):\n", + " _fields_ = [(\"x\", c_float),\n", + " (\"y\", c_float),\n", + " (\"w\", c_float),\n", + " (\"h\", c_float)]\n", + "\n", + "class DETECTION(Structure):\n", + " _fields_ = [(\"bbox\", BOX),\n", + " (\"classes\", c_int),\n", + " (\"prob\", POINTER(c_float)),\n", + " (\"mask\", POINTER(c_float)),\n", + " (\"objectness\", c_float),\n", + " (\"sort_class\", c_int)]\n", + "\n", + "\n", + "class IMAGE(Structure):\n", + " _fields_ = [(\"w\", c_int),\n", + " (\"h\", c_int),\n", + " (\"c\", c_int),\n", + " (\"data\", POINTER(c_float))]\n", + "\n", + "class METADATA(Structure):\n", + " _fields_ = [(\"classes\", c_int),\n", + " (\"names\", POINTER(c_char_p))]\n", + "\n", + " \n", + "\n", + "lib = CDLL(\"libdarknet.so\", RTLD_GLOBAL) # 配置so文件路径,最好是绝对路径\n", + "lib.network_width.argtypes = [c_void_p]\n", + "lib.network_width.restype = c_int\n", + "lib.network_height.argtypes = [c_void_p]\n", + "lib.network_height.restype = c_int\n", + "\n", + "predict = lib.network_predict\n", + "predict.argtypes = [c_void_p, POINTER(c_float)]\n", + "predict.restype = POINTER(c_float)\n", + "\n", + "set_gpu = lib.cuda_set_device\n", + "set_gpu.argtypes = [c_int]\n", + "\n", + "make_image = lib.make_image\n", + "make_image.argtypes = [c_int, c_int, c_int]\n", + "make_image.restype = IMAGE\n", + "\n", + "get_network_boxes = lib.get_network_boxes\n", + "get_network_boxes.argtypes = [c_void_p, c_int, c_int, c_float, c_float, POINTER(c_int), c_int, POINTER(c_int)]\n", + "get_network_boxes.restype = POINTER(DETECTION)\n", + "\n", + "make_network_boxes = lib.make_network_boxes\n", + "make_network_boxes.argtypes = [c_void_p]\n", + "make_network_boxes.restype = POINTER(DETECTION)\n", + "\n", + "free_detections = lib.free_detections\n", + "free_detections.argtypes = [POINTER(DETECTION), c_int]\n", + "\n", + "free_ptrs = lib.free_ptrs\n", + "free_ptrs.argtypes = [POINTER(c_void_p), c_int]\n", + "\n", + "network_predict = lib.network_predict\n", + "network_predict.argtypes = [c_void_p, POINTER(c_float)]\n", + "\n", + "reset_rnn = lib.reset_rnn\n", + "reset_rnn.argtypes = [c_void_p]\n", + "\n", + "load_net = lib.load_network\n", + "load_net.argtypes = [c_char_p, c_char_p, c_int]\n", + "load_net.restype = c_void_p\n", + "\n", + "do_nms_obj = lib.do_nms_obj\n", + "do_nms_obj.argtypes = [POINTER(DETECTION), c_int, c_int, c_float]\n", + "\n", + "do_nms_sort = lib.do_nms_sort\n", + "do_nms_sort.argtypes = [POINTER(DETECTION), c_int, c_int, c_float]\n", + "\n", + "free_image = lib.free_image\n", + "free_image.argtypes = [IMAGE]\n", + "\n", + "letterbox_image = lib.letterbox_image\n", + "letterbox_image.argtypes = [IMAGE, c_int, c_int]\n", + "letterbox_image.restype = IMAGE\n", + "\n", + "load_meta = lib.get_metadata\n", + "lib.get_metadata.argtypes = [c_char_p]\n", + "lib.get_metadata.restype = METADATA\n", + "\n", + "load_image = lib.load_image_color\n", + "load_image.argtypes = [c_char_p, c_int, c_int]\n", + "load_image.restype = IMAGE\n", + "\n", + "rgbgr_image = lib.rgbgr_image\n", + "rgbgr_image.argtypes = [IMAGE]\n", + "\n", + "predict_image = lib.network_predict_image\n", + "predict_image.argtypes = [c_void_p, IMAGE]\n", + "predict_image.restype = POINTER(c_float)\n", + "\n", + "def classify(net, meta, im):\n", + " out = predict_image(net, im)\n", + " res = []\n", + " for i in range(meta.classes):\n", + " res.append((meta.names[i], out[i]))\n", + " res = sorted(res, key=lambda x: -x[1])\n", + " return res\n", + "\n", + "def detect(net, meta, image, thresh=.5, hier_thresh=.5, nms=.45):\n", + " im = load_image(image, 0, 0)\n", + " num = c_int(0)\n", + " pnum = pointer(num)\n", + " predict_image(net, im)\n", + " dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, None, 0, pnum)\n", + " num = pnum[0]\n", + " if (nms): do_nms_obj(dets, num, meta.classes, nms);\n", + "\n", + " res = []\n", + " for j in range(num):\n", + " for i in range(meta.classes):\n", + " if dets[j].prob[i] > 0:\n", + " b = dets[j].bbox\n", + " res.append((meta.names[i], dets[j].prob[i], (b.x, b.y, b.w, b.h)))\n", + " res = sorted(res, key=lambda x: -x[1])\n", + " free_image(im)\n", + " free_detections(dets, num)\n", + " return res\n", + "\n", + "def run():\n", + " net = load_net(\n", + " \"\".encode(), # cfg文件路径\n", + " \"\".encode(), # weights权重文件路径\n", + " 0 # 默认0\n", + " )\n", + " meta = load_meta(\"\".encode()) # data文件路径\n", + " # 执行预测\n", + " r = detect(\n", + " net, \n", + " meta, \n", + " \"\".encode()\n", + " )\n", + " print(r)\n", + " \n", + " \n", + "if __name__ == \"__main__\":\n", + " run()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "这里几个要注意的点:\n", + "\n", + "- 文件路径编码\n", + "- libdarknet.so 文件的路径配置" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "blog", + "language": "python", + "name": "blog" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/hanzi_detection/.gitignore b/hanzi_detection/.gitignore new file mode 100755 index 0000000..bea19ff --- /dev/null +++ b/hanzi_detection/.gitignore @@ -0,0 +1,27 @@ +*.o +*.dSYM +*.csv +*.out +*.png +*.jpg +*.pyc +old/ +mnist/ +data/ +caffe/ +grasp/ +images/ +opencv/ +convnet/ +decaf/ +submission/ +cfg/ +darknet +.fuse* + +# OS Generated # +.DS_Store* +ehthumbs.db +Icon? +Thumbs.db +*.swp diff --git a/hanzi_detection/LICENSE b/hanzi_detection/LICENSE new file mode 100755 index 0000000..a50f7d7 --- /dev/null +++ b/hanzi_detection/LICENSE @@ -0,0 +1,12 @@ + YOLO LICENSE + Version 2, July 29 2016 + +THIS SOFTWARE LICENSE IS PROVIDED "ALL CAPS" SO THAT YOU KNOW IT IS SUPER +SERIOUS AND YOU DON'T MESS AROUND WITH COPYRIGHT LAW BECAUSE YOU WILL GET IN +TROUBLE HERE ARE SOME OTHER BUZZWORDS COMMONLY IN THESE THINGS WARRANTIES +LIABILITY CONTRACT TORT LIABLE CLAIMS RESTRICTION MERCHANTABILITY. NOW HERE'S +THE REAL LICENSE: + +0. Darknet is public domain. +1. Do whatever you want with it. +2. Stop emailing me about it! diff --git a/hanzi_detection/LICENSE.fuck b/hanzi_detection/LICENSE.fuck new file mode 100755 index 0000000..8b1a9d8 --- /dev/null +++ b/hanzi_detection/LICENSE.fuck @@ -0,0 +1,13 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + +Copyright (C) 2004 Sam Hocevar + +Everyone is permitted to copy and distribute verbatim or modified +copies of this license document, and changing it is allowed as long +as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/hanzi_detection/LICENSE.gen b/hanzi_detection/LICENSE.gen new file mode 100755 index 0000000..c541132 --- /dev/null +++ b/hanzi_detection/LICENSE.gen @@ -0,0 +1,91 @@ +RNN LICENSE Version 3, June 21 2017 + +Copyright (c) 1990, 1989, 1999 Free87337 May 48 THIRD PARTIES OR ANY OTHER THE +COMPLAIN OR CONSEQUENTIAL DAMAGES AND REGARDLESS OF WHETHER IN CONTRACT, TO THE +EXTENT REPAIR OR AGENTS (NOT THE IN ANY EVENT). THE SOFTWARE WILL BE +UNINTERRUPTED OR ERROR-FREE OR ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF ALL THE WORK (GOVERNED CODE) HIM RESPONSES, OR OF FINES, +SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR ANY OTHER OR OTHER HARL UNDER NO +CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), +PATENT PERMITTED BY THE INSTAGRAM PARENT STATE OR TORT (INCLUDING NEGLIGENCE), +PRODUCT LIABILITY OR OTHERWISE, ARISING OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR ANYTHING PROVIDED IN THIS PRODUCT, COMMIS AND SERVICES +ARE LICENSED SOFTWARE AND ANY RESULE OR ANY OTHER THE COPYRIGHT HOLDERS BE +LIABLE FOR ANY SPECIAL, INCIDENTAL, CASE, SUCH WARRANTIES, EXPRESS OR IMPLIED, +INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COPYRIGHT HOLDERS AND/OR ANY +PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY +EXPRESS OR DISTRIBUTE THAT ALL CLAIMS ARE SHALL CREATE DERAVE BE LIABLE TO YOU +WILL HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +6\. TERMINATION. TO THE EXTENT PERMITTED BY LAW, NO USE OF THE COVERED CODE IS +WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE +INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY +SERVICING, REPAIR OR COULT OR IN ANY WAY OUT OF THE USE OF THE WEBSITES OR +SERVICE WILL BE CONSEQUENTIAL DAMAGES OF ANY KIND HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + +This paragraph Agreement constitutes the entire agreement between the parties +with respect to the Work licensed here. However, if you place the name of the +fact that the arbitration was the consultation of the parties as a "patent is". +Subject to the terms and conditions of this License, Contributor has knowledge +that a license under a third party may also be used to endorse or promote +products derived from the Work, and there is no warranty on the Software and +Science Fees. For the purposes of this Agreement, attach the following +disclaimers (without liabilities of written notice to the Subject Software) in a +manner that a product is under common control with you. The Free Software +Foundation may publish revised and/or new versions of the License for the +Modifications made by the applicable terms. The Recipient shall promptly retain +the covered works for any reason be entered in any federal or state or login +Restricted Laws appearing in the United States or any of its own information +that is not disabled from a derivative work except as expressly permitted in +this License, to the extent that they are in receiving the Software and Source +Code or any exercise of the rights granted to You by this License or a +Contributor made by the Licensor or are authorized to make a reasonable +retirement by the courts of the courts located in Santa Clara County, California +printed and related to the Work or “Company” and Apache Software Foundation. If +the Licensor shall be entitled to reflect your rights to use the Software and +the Software to exercise the rights granted to the recipient without a +requirement to exercise the rights granted by the Agreement to the provision +will begin will appear in such cases, you will use such information without such +corporation shall be an officer with respect to any part of the Software or any +portion thereof. Capitalized terms are included in the Initial Contributor and +under no circumstances will license the Service at any time and for any direct, +indirect, special, incidental, or consequential damages of or assist in +connection with any Services or the registration purposes only to the extent +that it includes any or all means including the processing of which you download +any derivative work. Any of the purchases’ transmission purposes are made +available, if any, in other circumstances, we may review the copyright notice. +In the event that this Agreement is required to give us strict content. The +inclusion of the other party hereunder may also notify you Intellectual Property +Rights to any third party. This means that the Source Code exists of the Work +will not charge a program available to you at any time. You must include a +prominent statement that the Software is governed under a particular version of +this Agreement. You must include a provision to the extent that there is no +warranty for the content of others. You agree that the Recipient was appointed +as a Contributor, (c) are effective until terminated by hereunder, then the +registration are not disabled and not limited to, submit any Customer Data +without the updated use of the Software and that no fee is released. You grant +to Use Other Arbitration Rules for Diagnostic or Services may use or modify the +Apple Software and Consolidated Apple Software or Services. The Company may have +full risk as a product of the Compatible Source. A Contribution by the Licensor +or by the updated Software under the following conditions we can redistribute +any General Provision of this Agreement. If the Program is used in accordance +with the terms of this Agreement, Customer may provide advertisements from your +devices that clause you can your employer or a transaction or country that has +been controlled by the arbitrator, that they will be useful of this Agreement. +The term "Open Source Software is available in connection with the program, and +you may not protect the combination of the Covered Code. You should like to +select a user's rights to charge a copy of this License. I are Contributor's +confidentiality of the exercise of the rights granted herein. Such a covered +work is released as a consequence, the Licensor shall be eligible for a purpose +or subcontractor of the person or entity to the user of the user, then the word +"Application" means having the original fee for any reason; and that no patent +license to more than fifty stated close of the license term. The terms of this +License will the license terms and conditions set forth in Section 2.2 (OPEC) +and You will not use the Software or any set of responsibility for any resulting +information that the Original Code warrants that you have the right to disclose +these information (or in the notification; or (iii) late use of the software or +any third party to the three (50) days before such belief to the extent that it +includes a court court obtains the rights granted by this License. diff --git a/hanzi_detection/LICENSE.gpl b/hanzi_detection/LICENSE.gpl new file mode 100755 index 0000000..9cecc1d --- /dev/null +++ b/hanzi_detection/LICENSE.gpl @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/hanzi_detection/LICENSE.meta b/hanzi_detection/LICENSE.meta new file mode 100755 index 0000000..6728bd2 --- /dev/null +++ b/hanzi_detection/LICENSE.meta @@ -0,0 +1,8 @@ + META-LICENSE + Version 1, June 21 2017 + +Any and all licenses may be applied to the software either individually +or in concert. Any issues, ambiguities, paradoxes, or metaphysical quandries +arising from this combination should be discussed with a local faith leader, +hermit, or guru. The Oxford comma shall be used. + diff --git a/hanzi_detection/LICENSE.mit b/hanzi_detection/LICENSE.mit new file mode 100755 index 0000000..5bd806c --- /dev/null +++ b/hanzi_detection/LICENSE.mit @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2017 Joseph Redmon + +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. + diff --git a/hanzi_detection/LICENSE.v1 b/hanzi_detection/LICENSE.v1 new file mode 100755 index 0000000..5b8709a --- /dev/null +++ b/hanzi_detection/LICENSE.v1 @@ -0,0 +1,13 @@ + YOLO LICENSE + Version 1, July 10 2015 + +THIS SOFTWARE LICENSE IS PROVIDED "ALL CAPS" SO THAT YOU KNOW IT IS SUPER +SERIOUS AND YOU DON'T MESS AROUND WITH COPYRIGHT LAW BECAUSE YOU WILL GET IN +TROUBLE HERE ARE SOME OTHER BUZZWORDS COMMONLY IN THESE THINGS WARRANTIES +LIABILITY CONTRACT TORT LIABLE CLAIMS RESTRICTION MERCHANTABILITY SUBJECT TO +THE FOLLOWING CONDITIONS: + +1. #yolo +2. #swag +3. #blazeit + diff --git a/hanzi_detection/Makefile b/hanzi_detection/Makefile new file mode 100755 index 0000000..534dcab --- /dev/null +++ b/hanzi_detection/Makefile @@ -0,0 +1,105 @@ +GPU=0 +CUDNN=0 +OPENCV=0 +OPENMP=0 +DEBUG=0 + +ARCH= -gencode arch=compute_30,code=sm_30 \ + -gencode arch=compute_35,code=sm_35 \ + -gencode arch=compute_50,code=[sm_50,compute_50] \ + -gencode arch=compute_52,code=[sm_52,compute_52] +# -gencode arch=compute_20,code=[sm_20,sm_21] \ This one is deprecated? + +# This is what I use, uncomment if you know your arch and want to specify +# ARCH= -gencode arch=compute_52,code=compute_52 + +VPATH=./src/:./examples +SLIB=libdarknet.so +ALIB=libdarknet.a +EXEC=darknet +OBJDIR=./obj/ + +CC=gcc +CPP=g++ +NVCC=/usr/local/cuda-10.1/bin/nvcc +AR=ar +ARFLAGS=rcs +OPTS=-Ofast +LDFLAGS= -lm -pthread +COMMON= -Iinclude/ -Isrc/ +CFLAGS=-Wall -Wno-unused-result -Wno-unknown-pragmas -Wfatal-errors -fPIC + +ifeq ($(OPENMP), 1) +CFLAGS+= -fopenmp +endif + +ifeq ($(DEBUG), 1) +OPTS=-O0 -g +endif + +CFLAGS+=$(OPTS) + +ifeq ($(OPENCV), 1) +COMMON+= -DOPENCV +CFLAGS+= -DOPENCV +LDFLAGS+= `pkg-config --libs opencv` -lstdc++ +COMMON+= `pkg-config --cflags opencv` +endif + +ifeq ($(GPU), 1) +COMMON+= -DGPU -I/usr/local/cuda/include/ +CFLAGS+= -DGPU +LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand +endif + +ifeq ($(CUDNN), 1) +COMMON+= -DCUDNN +CFLAGS+= -DCUDNN +LDFLAGS+= -lcudnn +endif + +OBJ=gemm.o utils.o cuda.o deconvolutional_layer.o convolutional_layer.o list.o image.o activations.o im2col.o col2im.o blas.o crop_layer.o dropout_layer.o maxpool_layer.o softmax_layer.o data.o matrix.o network.o connected_layer.o cost_layer.o parser.o option_list.o detection_layer.o route_layer.o upsample_layer.o box.o normalization_layer.o avgpool_layer.o layer.o local_layer.o shortcut_layer.o logistic_layer.o activation_layer.o rnn_layer.o gru_layer.o crnn_layer.o demo.o batchnorm_layer.o region_layer.o reorg_layer.o tree.o lstm_layer.o l2norm_layer.o yolo_layer.o iseg_layer.o image_opencv.o +EXECOBJA=captcha.o lsd.o super.o art.o tag.o cifar.o go.o rnn.o segmenter.o regressor.o classifier.o coco.o yolo.o detector.o nightmare.o instance-segmenter.o darknet.o +ifeq ($(GPU), 1) +LDFLAGS+= -lstdc++ +OBJ+=convolutional_kernels.o deconvolutional_kernels.o activation_kernels.o im2col_kernels.o col2im_kernels.o blas_kernels.o crop_layer_kernels.o dropout_layer_kernels.o maxpool_layer_kernels.o avgpool_layer_kernels.o +endif + +EXECOBJ = $(addprefix $(OBJDIR), $(EXECOBJA)) +OBJS = $(addprefix $(OBJDIR), $(OBJ)) +DEPS = $(wildcard src/*.h) Makefile include/darknet.h + +all: obj backup results $(SLIB) $(ALIB) $(EXEC) +#all: obj results $(SLIB) $(ALIB) $(EXEC) + + +$(EXEC): $(EXECOBJ) $(ALIB) + $(CC) $(COMMON) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(ALIB) + +$(ALIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $^ + +$(SLIB): $(OBJS) + $(CC) $(CFLAGS) -shared $^ -o $@ $(LDFLAGS) + +$(OBJDIR)%.o: %.cpp $(DEPS) + $(CPP) $(COMMON) $(CFLAGS) -c $< -o $@ + +$(OBJDIR)%.o: %.c $(DEPS) + $(CC) $(COMMON) $(CFLAGS) -c $< -o $@ + +$(OBJDIR)%.o: %.cu $(DEPS) + $(NVCC) $(ARCH) $(COMMON) --compiler-options "$(CFLAGS)" -c $< -o $@ + +obj: + mkdir -p obj +backup: + mkdir -p backup +results: + mkdir -p results + +.PHONY: clean + +clean: + rm -rf $(OBJS) $(SLIB) $(ALIB) $(EXEC) $(EXECOBJ) $(OBJDIR)/* + diff --git a/hanzi_detection/README.md b/hanzi_detection/README.md new file mode 100755 index 0000000..97d9bda --- /dev/null +++ b/hanzi_detection/README.md @@ -0,0 +1,75 @@ +## 汉字位置检测模型文档 + +模型我已经训练好了,直接可以用。使用的darknet,模型使用方法见官网。**有问题咨询或者需要训练数据的童鞋可以加首页的微信跟我要,Git传不了这么多文件。** + +> 现已更新QQ群,请看首页 + +提示:backup/ 文件夹下缺少权重文件,不是我不想传,是大于100M的文件Git传不了。如果需要,微信跟我要吧。 + +Git star 过500+,微信关注人数1000+会推出油管视频,谢谢支持! + +### 使用方法 + +1. 编译 + + 打开终端 + + 进入项目文件夹:`cd hanzi_detection` + + 编译:`make` + +2. 测试 + + 编译成功后执行:`./darknet detector test data/jiyan.data model/jiyan_yolov3.cfg backup/jiyan_yolov3_final.weights ` + + 出现如下日志: + + ```shell + 100 conv 256 3 x 3 / 1 76 x 76 x 128 -> 76 x 76 x 256 3.407 BFLOPs + 101 conv 128 1 x 1 / 1 76 x 76 x 256 -> 76 x 76 x 128 0.379 BFLOPs + 102 conv 256 3 x 3 / 1 76 x 76 x 128 -> 76 x 76 x 256 3.407 BFLOPs + 103 conv 128 1 x 1 / 1 76 x 76 x 256 -> 76 x 76 x 128 0.379 BFLOPs + 104 conv 256 3 x 3 / 1 76 x 76 x 128 -> 76 x 76 x 256 3.407 BFLOPs + 105 conv 18 1 x 1 / 1 76 x 76 x 256 -> 76 x 76 x 18 0.053 BFLOPs + 106 yolo + Loading weights from backup/jiyan_yolov3_final.weights...Done! + + ``` + + 模型加载完成,输入一个图片地址进行测试: + + ```shell + Enter Image Path: ./809859eb7dbf70338f6c0dfa7c510c3a.jpg: Predicted in 18.303259 seconds. + hanzi: 100% + hanzi: 100% + hanzi: 100% + hanzi: 99% + ``` + + **识别结果会保存到当前文件夹下,名叫:predictions.jpg** + + 可以看到识别这个结果用了18.3秒,以及识别到四个结果。 + + 因为目前是直接用CPU识别的,速度慢,用GPU速度会提升几百倍。关于GPU的使用待稍后整理发出,也可加微信交流。 + + 贴一个效果图: + + ![predicted img](./predictions.jpg) + + ### 关于环境搭建以及GPU训练方面文档稍后整理发出 + + 内容涉及: + + - Ubuntu18.04下的环境搭建 + - cuda + cudnn + opencv + - Python3 + - NVIDIA 显卡驱动 + - GPU环境下模型的编译和使用 + + GPU的使用在生产环境是必须的,速度提升了几百倍... + + + + **如果您看到这里,请给我一个star:star:谢谢,如果有遗漏,请留言指正,感激!** + + \ No newline at end of file diff --git a/hanzi_detection/examples/art.c b/hanzi_detection/examples/art.c new file mode 100755 index 0000000..932688e --- /dev/null +++ b/hanzi_detection/examples/art.c @@ -0,0 +1,59 @@ +#include "darknet.h" + +#include + +void demo_art(char *cfgfile, char *weightfile, int cam_index) +{ +#ifdef OPENCV + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + + srand(2222222); + + void * cap = open_video_stream(0, cam_index, 0,0,0); + + char *window = "ArtJudgementBot9000!!!"; + if(!cap) error("Couldn't connect to webcam.\n"); + int i; + int idx[] = {37, 401, 434}; + int n = sizeof(idx)/sizeof(idx[0]); + + while(1){ + image in = get_image_from_stream(cap); + image in_s = resize_image(in, net->w, net->h); + + float *p = network_predict(net, in_s.data); + + printf("\033[2J"); + printf("\033[1;1H"); + + float score = 0; + for(i = 0; i < n; ++i){ + float s = p[idx[i]]; + if (s > score) score = s; + } + score = score; + printf("I APPRECIATE THIS ARTWORK: %10.7f%%\n", score*100); + printf("["); + int upper = 30; + for(i = 0; i < upper; ++i){ + printf("%c", ((i+.5) < score*upper) ? 219 : ' '); + } + printf("]\n"); + + show_image(in, window, 1); + free_image(in_s); + free_image(in); + } +#endif +} + + +void run_art(int argc, char **argv) +{ + int cam_index = find_int_arg(argc, argv, "-c", 0); + char *cfg = argv[2]; + char *weights = argv[3]; + demo_art(cfg, weights, cam_index); +} + diff --git a/hanzi_detection/examples/attention.c b/hanzi_detection/examples/attention.c new file mode 100755 index 0000000..cd1e579 --- /dev/null +++ b/hanzi_detection/examples/attention.c @@ -0,0 +1,459 @@ +#include "darknet.h" + +#include +#include + +void extend_data_truth(data *d, int n, float val) +{ + int i, j; + for(i = 0; i < d->y.rows; ++i){ + d->y.vals[i] = realloc(d->y.vals[i], (d->y.cols+n)*sizeof(float)); + for(j = 0; j < n; ++j){ + d->y.vals[i][d->y.cols + j] = val; + } + } + d->y.cols += n; +} + +matrix network_loss_data(network *net, data test) +{ + int i,b; + int k = 1; + matrix pred = make_matrix(test.X.rows, k); + float *X = calloc(net->batch*test.X.cols, sizeof(float)); + float *y = calloc(net->batch*test.y.cols, sizeof(float)); + for(i = 0; i < test.X.rows; i += net->batch){ + for(b = 0; b < net->batch; ++b){ + if(i+b == test.X.rows) break; + memcpy(X+b*test.X.cols, test.X.vals[i+b], test.X.cols*sizeof(float)); + memcpy(y+b*test.y.cols, test.y.vals[i+b], test.y.cols*sizeof(float)); + } + + network orig = *net; + net->input = X; + net->truth = y; + net->train = 0; + net->delta = 0; + forward_network(net); + *net = orig; + + float *delta = net->layers[net->n-1].output; + for(b = 0; b < net->batch; ++b){ + if(i+b == test.X.rows) break; + int t = max_index(y + b*test.y.cols, 1000); + float err = sum_array(delta + b*net->outputs, net->outputs); + pred.vals[i+b][0] = -err; + //pred.vals[i+b][0] = 1-delta[b*net->outputs + t]; + } + } + free(X); + free(y); + return pred; +} + +void train_attention(char *datacfg, char *cfgfile, char *weightfile, int *gpus, int ngpus, int clear) +{ + int i, j; + + float avg_cls_loss = -1; + float avg_att_loss = -1; + char *base = basecfg(cfgfile); + printf("%s\n", base); + printf("%d\n", ngpus); + network **nets = calloc(ngpus, sizeof(network*)); + + srand(time(0)); + int seed = rand(); + for(i = 0; i < ngpus; ++i){ + srand(seed); +#ifdef GPU + cuda_set_device(gpus[i]); +#endif + nets[i] = load_network(cfgfile, weightfile, clear); + nets[i]->learning_rate *= ngpus; + } + srand(time(0)); + network *net = nets[0]; + + int imgs = net->batch * net->subdivisions * ngpus; + + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + list *options = read_data_cfg(datacfg); + + char *backup_directory = option_find_str(options, "backup", "/backup/"); + char *label_list = option_find_str(options, "labels", "data/labels.list"); + char *train_list = option_find_str(options, "train", "data/train.list"); + int classes = option_find_int(options, "classes", 2); + + char **labels = get_labels(label_list); + list *plist = get_paths(train_list); + char **paths = (char **)list_to_array(plist); + printf("%d\n", plist->size); + int N = plist->size; + double time; + + int divs=3; + int size=2; + + load_args args = {0}; + args.w = divs*net->w/size; + args.h = divs*net->h/size; + args.size = divs*net->w/size; + args.threads = 32; + args.hierarchy = net->hierarchy; + + args.min = net->min_ratio*args.w; + args.max = net->max_ratio*args.w; + args.angle = net->angle; + args.aspect = net->aspect; + args.exposure = net->exposure; + args.saturation = net->saturation; + args.hue = net->hue; + + args.paths = paths; + args.classes = classes; + args.n = imgs; + args.m = N; + args.labels = labels; + args.type = CLASSIFICATION_DATA; + + data train; + data buffer; + pthread_t load_thread; + args.d = &buffer; + load_thread = load_data(args); + + int epoch = (*net->seen)/N; + while(get_current_batch(net) < net->max_batches || net->max_batches == 0){ + time = what_time_is_it_now(); + + pthread_join(load_thread, 0); + train = buffer; + load_thread = load_data(args); + data resized = resize_data(train, net->w, net->h); + extend_data_truth(&resized, divs*divs, 0); + data *tiles = tile_data(train, divs, size); + + printf("Loaded: %lf seconds\n", what_time_is_it_now()-time); + time = what_time_is_it_now(); + + float aloss = 0; + float closs = 0; + int z; + for (i = 0; i < divs*divs/ngpus; ++i) { +#pragma omp parallel for + for(j = 0; j < ngpus; ++j){ + int index = i*ngpus + j; + extend_data_truth(tiles+index, divs*divs, SECRET_NUM); + matrix deltas = network_loss_data(nets[j], tiles[index]); + for(z = 0; z < resized.y.rows; ++z){ + resized.y.vals[z][train.y.cols + index] = deltas.vals[z][0]; + } + free_matrix(deltas); + } + } + int *inds = calloc(resized.y.rows, sizeof(int)); + for(z = 0; z < resized.y.rows; ++z){ + int index = max_index(resized.y.vals[z] + train.y.cols, divs*divs); + inds[z] = index; + for(i = 0; i < divs*divs; ++i){ + resized.y.vals[z][train.y.cols + i] = (i == index)? 1 : 0; + } + } + data best = select_data(tiles, inds); + free(inds); + #ifdef GPU + if (ngpus == 1) { + closs = train_network(net, best); + } else { + closs = train_networks(nets, ngpus, best, 4); + } + #endif + for (i = 0; i < divs*divs; ++i) { + printf("%.2f ", resized.y.vals[0][train.y.cols + i]); + if((i+1)%divs == 0) printf("\n"); + free_data(tiles[i]); + } + free_data(best); + printf("\n"); + image im = float_to_image(64,64,3,resized.X.vals[0]); + //show_image(im, "orig"); + //cvWaitKey(100); + /* + image im1 = float_to_image(64,64,3,tiles[i].X.vals[0]); + image im2 = float_to_image(64,64,3,resized.X.vals[0]); + show_image(im1, "tile"); + show_image(im2, "res"); + */ +#ifdef GPU + if (ngpus == 1) { + aloss = train_network(net, resized); + } else { + aloss = train_networks(nets, ngpus, resized, 4); + } +#endif + for(i = 0; i < divs*divs; ++i){ + printf("%f ", nets[0]->output[1000 + i]); + if ((i+1) % divs == 0) printf("\n"); + } + printf("\n"); + + free_data(resized); + free_data(train); + if(avg_cls_loss == -1) avg_cls_loss = closs; + if(avg_att_loss == -1) avg_att_loss = aloss; + avg_cls_loss = avg_cls_loss*.9 + closs*.1; + avg_att_loss = avg_att_loss*.9 + aloss*.1; + + printf("%ld, %.3f: Att: %f, %f avg, Class: %f, %f avg, %f rate, %lf seconds, %ld images\n", get_current_batch(net), (float)(*net->seen)/N, aloss, avg_att_loss, closs, avg_cls_loss, get_current_rate(net), what_time_is_it_now()-time, *net->seen); + if(*net->seen/N > epoch){ + epoch = *net->seen/N; + char buff[256]; + sprintf(buff, "%s/%s_%d.weights",backup_directory,base, epoch); + save_weights(net, buff); + } + if(get_current_batch(net)%1000 == 0){ + char buff[256]; + sprintf(buff, "%s/%s.backup",backup_directory,base); + save_weights(net, buff); + } + } + char buff[256]; + sprintf(buff, "%s/%s.weights", backup_directory, base); + save_weights(net, buff); + pthread_join(load_thread, 0); + + free_network(net); + free_ptrs((void**)labels, classes); + free_ptrs((void**)paths, plist->size); + free_list(plist); + free(base); +} + +void validate_attention_single(char *datacfg, char *filename, char *weightfile) +{ + int i, j; + network *net = load_network(filename, weightfile, 0); + set_batch_network(net, 1); + srand(time(0)); + + list *options = read_data_cfg(datacfg); + + char *label_list = option_find_str(options, "labels", "data/labels.list"); + char *leaf_list = option_find_str(options, "leaves", 0); + if(leaf_list) change_leaves(net->hierarchy, leaf_list); + char *valid_list = option_find_str(options, "valid", "data/train.list"); + int classes = option_find_int(options, "classes", 2); + int topk = option_find_int(options, "top", 1); + + char **labels = get_labels(label_list); + list *plist = get_paths(valid_list); + + char **paths = (char **)list_to_array(plist); + int m = plist->size; + free_list(plist); + + float avg_acc = 0; + float avg_topk = 0; + int *indexes = calloc(topk, sizeof(int)); + int divs = 4; + int size = 2; + int extra = 0; + float *avgs = calloc(classes, sizeof(float)); + int *inds = calloc(divs*divs, sizeof(int)); + + for(i = 0; i < m; ++i){ + int class = -1; + char *path = paths[i]; + for(j = 0; j < classes; ++j){ + if(strstr(path, labels[j])){ + class = j; + break; + } + } + image im = load_image_color(paths[i], 0, 0); + image resized = resize_min(im, net->w*divs/size); + image crop = crop_image(resized, (resized.w - net->w*divs/size)/2, (resized.h - net->h*divs/size)/2, net->w*divs/size, net->h*divs/size); + image rcrop = resize_image(crop, net->w, net->h); + //show_image(im, "orig"); + //show_image(crop, "cropped"); + //cvWaitKey(0); + float *pred = network_predict(net, rcrop.data); + //pred[classes + 56] = 0; + for(j = 0; j < divs*divs; ++j){ + printf("%.2f ", pred[classes + j]); + if((j+1)%divs == 0) printf("\n"); + } + printf("\n"); + copy_cpu(classes, pred, 1, avgs, 1); + top_k(pred + classes, divs*divs, divs*divs, inds); + show_image(crop, "crop"); + for(j = 0; j < extra; ++j){ + int index = inds[j]; + int row = index / divs; + int col = index % divs; + int y = row * crop.h / divs - (net->h - crop.h/divs)/2; + int x = col * crop.w / divs - (net->w - crop.w/divs)/2; + printf("%d %d %d %d\n", row, col, y, x); + image tile = crop_image(crop, x, y, net->w, net->h); + float *pred = network_predict(net, tile.data); + axpy_cpu(classes, 1., pred, 1, avgs, 1); + show_image(tile, "tile"); + //cvWaitKey(10); + } + if(net->hierarchy) hierarchy_predictions(pred, net->outputs, net->hierarchy, 1, 1); + + if(rcrop.data != resized.data) free_image(rcrop); + if(resized.data != im.data) free_image(resized); + free_image(im); + free_image(crop); + top_k(pred, classes, topk, indexes); + + if(indexes[0] == class) avg_acc += 1; + for(j = 0; j < topk; ++j){ + if(indexes[j] == class) avg_topk += 1; + } + + printf("%d: top 1: %f, top %d: %f\n", i, avg_acc/(i+1), topk, avg_topk/(i+1)); + } +} + +void validate_attention_multi(char *datacfg, char *filename, char *weightfile) +{ + int i, j; + network *net = load_network(filename, weightfile, 0); + set_batch_network(net, 1); + srand(time(0)); + + list *options = read_data_cfg(datacfg); + + char *label_list = option_find_str(options, "labels", "data/labels.list"); + char *valid_list = option_find_str(options, "valid", "data/train.list"); + int classes = option_find_int(options, "classes", 2); + int topk = option_find_int(options, "top", 1); + + char **labels = get_labels(label_list); + list *plist = get_paths(valid_list); + int scales[] = {224, 288, 320, 352, 384}; + int nscales = sizeof(scales)/sizeof(scales[0]); + + char **paths = (char **)list_to_array(plist); + int m = plist->size; + free_list(plist); + + float avg_acc = 0; + float avg_topk = 0; + int *indexes = calloc(topk, sizeof(int)); + + for(i = 0; i < m; ++i){ + int class = -1; + char *path = paths[i]; + for(j = 0; j < classes; ++j){ + if(strstr(path, labels[j])){ + class = j; + break; + } + } + float *pred = calloc(classes, sizeof(float)); + image im = load_image_color(paths[i], 0, 0); + for(j = 0; j < nscales; ++j){ + image r = resize_min(im, scales[j]); + resize_network(net, r.w, r.h); + float *p = network_predict(net, r.data); + if(net->hierarchy) hierarchy_predictions(p, net->outputs, net->hierarchy, 1 , 1); + axpy_cpu(classes, 1, p, 1, pred, 1); + flip_image(r); + p = network_predict(net, r.data); + axpy_cpu(classes, 1, p, 1, pred, 1); + if(r.data != im.data) free_image(r); + } + free_image(im); + top_k(pred, classes, topk, indexes); + free(pred); + if(indexes[0] == class) avg_acc += 1; + for(j = 0; j < topk; ++j){ + if(indexes[j] == class) avg_topk += 1; + } + + printf("%d: top 1: %f, top %d: %f\n", i, avg_acc/(i+1), topk, avg_topk/(i+1)); + } +} + +void predict_attention(char *datacfg, char *cfgfile, char *weightfile, char *filename, int top) +{ + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + srand(2222222); + + list *options = read_data_cfg(datacfg); + + char *name_list = option_find_str(options, "names", 0); + if(!name_list) name_list = option_find_str(options, "labels", "data/labels.list"); + if(top == 0) top = option_find_int(options, "top", 1); + + int i = 0; + char **names = get_labels(name_list); + clock_t time; + int *indexes = calloc(top, sizeof(int)); + char buff[256]; + char *input = buff; + while(1){ + if(filename){ + strncpy(input, filename, 256); + }else{ + printf("Enter Image Path: "); + fflush(stdout); + input = fgets(input, 256, stdin); + if(!input) return; + strtok(input, "\n"); + } + image im = load_image_color(input, 0, 0); + image r = letterbox_image(im, net->w, net->h); + //resize_network(&net, r.w, r.h); + //printf("%d %d\n", r.w, r.h); + + float *X = r.data; + time=clock(); + float *predictions = network_predict(net, X); + if(net->hierarchy) hierarchy_predictions(predictions, net->outputs, net->hierarchy, 1, 1); + top_k(predictions, net->outputs, top, indexes); + fprintf(stderr, "%s: Predicted in %f seconds.\n", input, sec(clock()-time)); + for(i = 0; i < top; ++i){ + int index = indexes[i]; + //if(net->hierarchy) printf("%d, %s: %f, parent: %s \n",index, names[index], predictions[index], (net->hierarchy->parent[index] >= 0) ? names[net->hierarchy->parent[index]] : "Root"); + //else printf("%s: %f\n",names[index], predictions[index]); + printf("%5.2f%%: %s\n", predictions[index]*100, names[index]); + } + if(r.data != im.data) free_image(r); + free_image(im); + if (filename) break; + } +} + + +void run_attention(int argc, char **argv) +{ + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + + char *gpu_list = find_char_arg(argc, argv, "-gpus", 0); + int ngpus; + int *gpus = read_intlist(gpu_list, &ngpus, gpu_index); + + + int top = find_int_arg(argc, argv, "-t", 0); + int clear = find_arg(argc, argv, "-clear"); + char *data = argv[3]; + char *cfg = argv[4]; + char *weights = (argc > 5) ? argv[5] : 0; + char *filename = (argc > 6) ? argv[6]: 0; + char *layer_s = (argc > 7) ? argv[7]: 0; + if(0==strcmp(argv[2], "predict")) predict_attention(data, cfg, weights, filename, top); + else if(0==strcmp(argv[2], "train")) train_attention(data, cfg, weights, gpus, ngpus, clear); + else if(0==strcmp(argv[2], "valid")) validate_attention_single(data, cfg, weights); + else if(0==strcmp(argv[2], "validmulti")) validate_attention_multi(data, cfg, weights); +} + + diff --git a/hanzi_detection/examples/captcha.c b/hanzi_detection/examples/captcha.c new file mode 100755 index 0000000..41d6d07 --- /dev/null +++ b/hanzi_detection/examples/captcha.c @@ -0,0 +1,353 @@ +#include "darknet.h" + +void fix_data_captcha(data d, int mask) +{ + matrix labels = d.y; + int i, j; + for(i = 0; i < d.y.rows; ++i){ + for(j = 0; j < d.y.cols; j += 2){ + if (mask){ + if(!labels.vals[i][j]){ + labels.vals[i][j] = SECRET_NUM; + labels.vals[i][j+1] = SECRET_NUM; + }else if(labels.vals[i][j+1]){ + labels.vals[i][j] = 0; + } + } else{ + if (labels.vals[i][j]) { + labels.vals[i][j+1] = 0; + } else { + labels.vals[i][j+1] = 1; + } + } + } + } +} + +void train_captcha(char *cfgfile, char *weightfile) +{ + srand(time(0)); + float avg_loss = -1; + char *base = basecfg(cfgfile); + printf("%s\n", base); + network *net = load_network(cfgfile, weightfile, 0); + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + int imgs = 1024; + int i = *net->seen/imgs; + int solved = 1; + list *plist; + char **labels = get_labels("/data/captcha/reimgs.labels.list"); + if (solved){ + plist = get_paths("/data/captcha/reimgs.solved.list"); + }else{ + plist = get_paths("/data/captcha/reimgs.raw.list"); + } + char **paths = (char **)list_to_array(plist); + printf("%d\n", plist->size); + clock_t time; + pthread_t load_thread; + data train; + data buffer; + + load_args args = {0}; + args.w = net->w; + args.h = net->h; + args.paths = paths; + args.classes = 26; + args.n = imgs; + args.m = plist->size; + args.labels = labels; + args.d = &buffer; + args.type = CLASSIFICATION_DATA; + + load_thread = load_data_in_thread(args); + while(1){ + ++i; + time=clock(); + pthread_join(load_thread, 0); + train = buffer; + fix_data_captcha(train, solved); + + /* + image im = float_to_image(256, 256, 3, train.X.vals[114]); + show_image(im, "training"); + cvWaitKey(0); + */ + + load_thread = load_data_in_thread(args); + printf("Loaded: %lf seconds\n", sec(clock()-time)); + time=clock(); + float loss = train_network(net, train); + if(avg_loss == -1) avg_loss = loss; + avg_loss = avg_loss*.9 + loss*.1; + printf("%d: %f, %f avg, %lf seconds, %ld images\n", i, loss, avg_loss, sec(clock()-time), *net->seen); + free_data(train); + if(i%100==0){ + char buff[256]; + sprintf(buff, "/home/pjreddie/imagenet_backup/%s_%d.weights",base, i); + save_weights(net, buff); + } + } +} + +void test_captcha(char *cfgfile, char *weightfile, char *filename) +{ + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + srand(2222222); + int i = 0; + char **names = get_labels("/data/captcha/reimgs.labels.list"); + char buff[256]; + char *input = buff; + int indexes[26]; + while(1){ + if(filename){ + strncpy(input, filename, 256); + }else{ + //printf("Enter Image Path: "); + //fflush(stdout); + input = fgets(input, 256, stdin); + if(!input) return; + strtok(input, "\n"); + } + image im = load_image_color(input, net->w, net->h); + float *X = im.data; + float *predictions = network_predict(net, X); + top_predictions(net, 26, indexes); + //printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time)); + for(i = 0; i < 26; ++i){ + int index = indexes[i]; + if(i != 0) printf(", "); + printf("%s %f", names[index], predictions[index]); + } + printf("\n"); + fflush(stdout); + free_image(im); + if (filename) break; + } +} + +void valid_captcha(char *cfgfile, char *weightfile, char *filename) +{ + char **labels = get_labels("/data/captcha/reimgs.labels.list"); + network *net = load_network(cfgfile, weightfile, 0); + list *plist = get_paths("/data/captcha/reimgs.fg.list"); + char **paths = (char **)list_to_array(plist); + int N = plist->size; + int outputs = net->outputs; + + set_batch_network(net, 1); + srand(2222222); + int i, j; + for(i = 0; i < N; ++i){ + if (i%100 == 0) fprintf(stderr, "%d\n", i); + image im = load_image_color(paths[i], net->w, net->h); + float *X = im.data; + float *predictions = network_predict(net, X); + //printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time)); + int truth = -1; + for(j = 0; j < 13; ++j){ + if (strstr(paths[i], labels[j])) truth = j; + } + if (truth == -1){ + fprintf(stderr, "bad: %s\n", paths[i]); + return; + } + printf("%d, ", truth); + for(j = 0; j < outputs; ++j){ + if (j != 0) printf(", "); + printf("%f", predictions[j]); + } + printf("\n"); + fflush(stdout); + free_image(im); + if (filename) break; + } +} + +/* + void train_captcha(char *cfgfile, char *weightfile) + { + float avg_loss = -1; + srand(time(0)); + char *base = basecfg(cfgfile); + printf("%s\n", base); + network net = parse_network_cfg(cfgfile); + if(weightfile){ + load_weights(&net, weightfile); + } + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + int imgs = 1024; + int i = net->seen/imgs; + list *plist = get_paths("/data/captcha/train.auto5"); + char **paths = (char **)list_to_array(plist); + printf("%d\n", plist->size); + clock_t time; + while(1){ + ++i; + time=clock(); + data train = load_data_captcha(paths, imgs, plist->size, 10, 200, 60); + translate_data_rows(train, -128); + scale_data_rows(train, 1./128); + printf("Loaded: %lf seconds\n", sec(clock()-time)); + time=clock(); + float loss = train_network(net, train); + net->seen += imgs; + if(avg_loss == -1) avg_loss = loss; + avg_loss = avg_loss*.9 + loss*.1; + printf("%d: %f, %f avg, %lf seconds, %d images\n", i, loss, avg_loss, sec(clock()-time), net->seen); + free_data(train); + if(i%10==0){ + char buff[256]; + sprintf(buff, "/home/pjreddie/imagenet_backup/%s_%d.weights",base, i); + save_weights(net, buff); + } + } + } + + void decode_captcha(char *cfgfile, char *weightfile) + { + setbuf(stdout, NULL); + srand(time(0)); + network net = parse_network_cfg(cfgfile); + set_batch_network(&net, 1); + if(weightfile){ + load_weights(&net, weightfile); + } + char filename[256]; + while(1){ + printf("Enter filename: "); + fgets(filename, 256, stdin); + strtok(filename, "\n"); + image im = load_image_color(filename, 300, 57); + scale_image(im, 1./255.); + float *X = im.data; + float *predictions = network_predict(net, X); + image out = float_to_image(300, 57, 1, predictions); + show_image(out, "decoded"); +#ifdef OPENCV +cvWaitKey(0); +#endif +free_image(im); +} +} + +void encode_captcha(char *cfgfile, char *weightfile) +{ +float avg_loss = -1; +srand(time(0)); +char *base = basecfg(cfgfile); +printf("%s\n", base); +network net = parse_network_cfg(cfgfile); +if(weightfile){ + load_weights(&net, weightfile); +} +printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); +int imgs = 1024; +int i = net->seen/imgs; +list *plist = get_paths("/data/captcha/encode.list"); +char **paths = (char **)list_to_array(plist); +printf("%d\n", plist->size); +clock_t time; +while(1){ + ++i; + time=clock(); + data train = load_data_captcha_encode(paths, imgs, plist->size, 300, 57); + scale_data_rows(train, 1./255); + printf("Loaded: %lf seconds\n", sec(clock()-time)); + time=clock(); + float loss = train_network(net, train); + net->seen += imgs; + if(avg_loss == -1) avg_loss = loss; + avg_loss = avg_loss*.9 + loss*.1; + printf("%d: %f, %f avg, %lf seconds, %d images\n", i, loss, avg_loss, sec(clock()-time), net->seen); + free_matrix(train.X); + if(i%100==0){ + char buff[256]; + sprintf(buff, "/home/pjreddie/imagenet_backup/%s_%d.weights",base, i); + save_weights(net, buff); + } +} +} + +void validate_captcha(char *cfgfile, char *weightfile) +{ + srand(time(0)); + char *base = basecfg(cfgfile); + printf("%s\n", base); + network net = parse_network_cfg(cfgfile); + if(weightfile){ + load_weights(&net, weightfile); + } + int numchars = 37; + list *plist = get_paths("/data/captcha/solved.hard"); + char **paths = (char **)list_to_array(plist); + int imgs = plist->size; + data valid = load_data_captcha(paths, imgs, 0, 10, 200, 60); + translate_data_rows(valid, -128); + scale_data_rows(valid, 1./128); + matrix pred = network_predict_data(net, valid); + int i, k; + int correct = 0; + int total = 0; + int accuracy = 0; + for(i = 0; i < imgs; ++i){ + int allcorrect = 1; + for(k = 0; k < 10; ++k){ + char truth = int_to_alphanum(max_index(valid.y.vals[i]+k*numchars, numchars)); + char prediction = int_to_alphanum(max_index(pred.vals[i]+k*numchars, numchars)); + if (truth != prediction) allcorrect=0; + if (truth != '.' && truth == prediction) ++correct; + if (truth != '.' || truth != prediction) ++total; + } + accuracy += allcorrect; + } + printf("Word Accuracy: %f, Char Accuracy %f\n", (float)accuracy/imgs, (float)correct/total); + free_data(valid); +} + +void test_captcha(char *cfgfile, char *weightfile) +{ + setbuf(stdout, NULL); + srand(time(0)); + //char *base = basecfg(cfgfile); + //printf("%s\n", base); + network net = parse_network_cfg(cfgfile); + set_batch_network(&net, 1); + if(weightfile){ + load_weights(&net, weightfile); + } + char filename[256]; + while(1){ + //printf("Enter filename: "); + fgets(filename, 256, stdin); + strtok(filename, "\n"); + image im = load_image_color(filename, 200, 60); + translate_image(im, -128); + scale_image(im, 1/128.); + float *X = im.data; + float *predictions = network_predict(net, X); + print_letters(predictions, 10); + free_image(im); + } +} + */ +void run_captcha(int argc, char **argv) +{ + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + + char *cfg = argv[3]; + char *weights = (argc > 4) ? argv[4] : 0; + char *filename = (argc > 5) ? argv[5]: 0; + if(0==strcmp(argv[2], "train")) train_captcha(cfg, weights); + else if(0==strcmp(argv[2], "test")) test_captcha(cfg, weights, filename); + else if(0==strcmp(argv[2], "valid")) valid_captcha(cfg, weights, filename); + //if(0==strcmp(argv[2], "test")) test_captcha(cfg, weights); + //else if(0==strcmp(argv[2], "encode")) encode_captcha(cfg, weights); + //else if(0==strcmp(argv[2], "decode")) decode_captcha(cfg, weights); + //else if(0==strcmp(argv[2], "valid")) validate_captcha(cfg, weights); +} + diff --git a/hanzi_detection/examples/cifar.c b/hanzi_detection/examples/cifar.c new file mode 100755 index 0000000..a5f5f24 --- /dev/null +++ b/hanzi_detection/examples/cifar.c @@ -0,0 +1,251 @@ +#include "darknet.h" + +void train_cifar(char *cfgfile, char *weightfile) +{ + srand(time(0)); + float avg_loss = -1; + char *base = basecfg(cfgfile); + printf("%s\n", base); + network *net = load_network(cfgfile, weightfile, 0); + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + + char *backup_directory = "/home/pjreddie/backup/"; + int classes = 10; + int N = 50000; + + char **labels = get_labels("data/cifar/labels.txt"); + int epoch = (*net->seen)/N; + data train = load_all_cifar10(); + while(get_current_batch(net) < net->max_batches || net->max_batches == 0){ + clock_t time=clock(); + + float loss = train_network_sgd(net, train, 1); + if(avg_loss == -1) avg_loss = loss; + avg_loss = avg_loss*.95 + loss*.05; + printf("%ld, %.3f: %f, %f avg, %f rate, %lf seconds, %ld images\n", get_current_batch(net), (float)(*net->seen)/N, loss, avg_loss, get_current_rate(net), sec(clock()-time), *net->seen); + if(*net->seen/N > epoch){ + epoch = *net->seen/N; + char buff[256]; + sprintf(buff, "%s/%s_%d.weights",backup_directory,base, epoch); + save_weights(net, buff); + } + if(get_current_batch(net)%100 == 0){ + char buff[256]; + sprintf(buff, "%s/%s.backup",backup_directory,base); + save_weights(net, buff); + } + } + char buff[256]; + sprintf(buff, "%s/%s.weights", backup_directory, base); + save_weights(net, buff); + + free_network(net); + free_ptrs((void**)labels, classes); + free(base); + free_data(train); +} + +void train_cifar_distill(char *cfgfile, char *weightfile) +{ + srand(time(0)); + float avg_loss = -1; + char *base = basecfg(cfgfile); + printf("%s\n", base); + network *net = load_network(cfgfile, weightfile, 0); + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + + char *backup_directory = "/home/pjreddie/backup/"; + int classes = 10; + int N = 50000; + + char **labels = get_labels("data/cifar/labels.txt"); + int epoch = (*net->seen)/N; + + data train = load_all_cifar10(); + matrix soft = csv_to_matrix("results/ensemble.csv"); + + float weight = .9; + scale_matrix(soft, weight); + scale_matrix(train.y, 1. - weight); + matrix_add_matrix(soft, train.y); + + while(get_current_batch(net) < net->max_batches || net->max_batches == 0){ + clock_t time=clock(); + + float loss = train_network_sgd(net, train, 1); + if(avg_loss == -1) avg_loss = loss; + avg_loss = avg_loss*.95 + loss*.05; + printf("%ld, %.3f: %f, %f avg, %f rate, %lf seconds, %ld images\n", get_current_batch(net), (float)(*net->seen)/N, loss, avg_loss, get_current_rate(net), sec(clock()-time), *net->seen); + if(*net->seen/N > epoch){ + epoch = *net->seen/N; + char buff[256]; + sprintf(buff, "%s/%s_%d.weights",backup_directory,base, epoch); + save_weights(net, buff); + } + if(get_current_batch(net)%100 == 0){ + char buff[256]; + sprintf(buff, "%s/%s.backup",backup_directory,base); + save_weights(net, buff); + } + } + char buff[256]; + sprintf(buff, "%s/%s.weights", backup_directory, base); + save_weights(net, buff); + + free_network(net); + free_ptrs((void**)labels, classes); + free(base); + free_data(train); +} + +void test_cifar_multi(char *filename, char *weightfile) +{ + network *net = load_network(filename, weightfile, 0); + set_batch_network(net, 1); + srand(time(0)); + + float avg_acc = 0; + data test = load_cifar10_data("data/cifar/cifar-10-batches-bin/test_batch.bin"); + + int i; + for(i = 0; i < test.X.rows; ++i){ + image im = float_to_image(32, 32, 3, test.X.vals[i]); + + float pred[10] = {0}; + + float *p = network_predict(net, im.data); + axpy_cpu(10, 1, p, 1, pred, 1); + flip_image(im); + p = network_predict(net, im.data); + axpy_cpu(10, 1, p, 1, pred, 1); + + int index = max_index(pred, 10); + int class = max_index(test.y.vals[i], 10); + if(index == class) avg_acc += 1; + free_image(im); + printf("%4d: %.2f%%\n", i, 100.*avg_acc/(i+1)); + } +} + +void test_cifar(char *filename, char *weightfile) +{ + network *net = load_network(filename, weightfile, 0); + srand(time(0)); + + clock_t time; + float avg_acc = 0; + float avg_top5 = 0; + data test = load_cifar10_data("data/cifar/cifar-10-batches-bin/test_batch.bin"); + + time=clock(); + + float *acc = network_accuracies(net, test, 2); + avg_acc += acc[0]; + avg_top5 += acc[1]; + printf("top1: %f, %lf seconds, %d images\n", avg_acc, sec(clock()-time), test.X.rows); + free_data(test); +} + +void extract_cifar() +{ +char *labels[] = {"airplane","automobile","bird","cat","deer","dog","frog","horse","ship","truck"}; + int i; + data train = load_all_cifar10(); + data test = load_cifar10_data("data/cifar/cifar-10-batches-bin/test_batch.bin"); + for(i = 0; i < train.X.rows; ++i){ + image im = float_to_image(32, 32, 3, train.X.vals[i]); + int class = max_index(train.y.vals[i], 10); + char buff[256]; + sprintf(buff, "data/cifar/train/%d_%s",i,labels[class]); + save_image_options(im, buff, PNG, 0); + } + for(i = 0; i < test.X.rows; ++i){ + image im = float_to_image(32, 32, 3, test.X.vals[i]); + int class = max_index(test.y.vals[i], 10); + char buff[256]; + sprintf(buff, "data/cifar/test/%d_%s",i,labels[class]); + save_image_options(im, buff, PNG, 0); + } +} + +void test_cifar_csv(char *filename, char *weightfile) +{ + network *net = load_network(filename, weightfile, 0); + srand(time(0)); + + data test = load_cifar10_data("data/cifar/cifar-10-batches-bin/test_batch.bin"); + + matrix pred = network_predict_data(net, test); + + int i; + for(i = 0; i < test.X.rows; ++i){ + image im = float_to_image(32, 32, 3, test.X.vals[i]); + flip_image(im); + } + matrix pred2 = network_predict_data(net, test); + scale_matrix(pred, .5); + scale_matrix(pred2, .5); + matrix_add_matrix(pred2, pred); + + matrix_to_csv(pred); + fprintf(stderr, "Accuracy: %f\n", matrix_topk_accuracy(test.y, pred, 1)); + free_data(test); +} + +void test_cifar_csvtrain(char *cfg, char *weights) +{ + network *net = load_network(cfg, weights, 0); + srand(time(0)); + + data test = load_all_cifar10(); + + matrix pred = network_predict_data(net, test); + + int i; + for(i = 0; i < test.X.rows; ++i){ + image im = float_to_image(32, 32, 3, test.X.vals[i]); + flip_image(im); + } + matrix pred2 = network_predict_data(net, test); + scale_matrix(pred, .5); + scale_matrix(pred2, .5); + matrix_add_matrix(pred2, pred); + + matrix_to_csv(pred); + fprintf(stderr, "Accuracy: %f\n", matrix_topk_accuracy(test.y, pred, 1)); + free_data(test); +} + +void eval_cifar_csv() +{ + data test = load_cifar10_data("data/cifar/cifar-10-batches-bin/test_batch.bin"); + + matrix pred = csv_to_matrix("results/combined.csv"); + fprintf(stderr, "%d %d\n", pred.rows, pred.cols); + + fprintf(stderr, "Accuracy: %f\n", matrix_topk_accuracy(test.y, pred, 1)); + free_data(test); + free_matrix(pred); +} + + +void run_cifar(int argc, char **argv) +{ + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + + char *cfg = argv[3]; + char *weights = (argc > 4) ? argv[4] : 0; + if(0==strcmp(argv[2], "train")) train_cifar(cfg, weights); + else if(0==strcmp(argv[2], "extract")) extract_cifar(); + else if(0==strcmp(argv[2], "distill")) train_cifar_distill(cfg, weights); + else if(0==strcmp(argv[2], "test")) test_cifar(cfg, weights); + else if(0==strcmp(argv[2], "multi")) test_cifar_multi(cfg, weights); + else if(0==strcmp(argv[2], "csv")) test_cifar_csv(cfg, weights); + else if(0==strcmp(argv[2], "csvtrain")) test_cifar_csvtrain(cfg, weights); + else if(0==strcmp(argv[2], "eval")) eval_cifar_csv(); +} + + diff --git a/hanzi_detection/examples/classifier.c b/hanzi_detection/examples/classifier.c new file mode 100755 index 0000000..df91a08 --- /dev/null +++ b/hanzi_detection/examples/classifier.c @@ -0,0 +1,1098 @@ +#include "darknet.h" + +#include +#include + +float *get_regression_values(char **labels, int n) +{ + float *v = calloc(n, sizeof(float)); + int i; + for(i = 0; i < n; ++i){ + char *p = strchr(labels[i], ' '); + *p = 0; + v[i] = atof(p+1); + } + return v; +} + +void train_classifier(char *datacfg, char *cfgfile, char *weightfile, int *gpus, int ngpus, int clear) +{ + int i; + + float avg_loss = -1; + char *base = basecfg(cfgfile); + printf("%s\n", base); + printf("%d\n", ngpus); + network **nets = calloc(ngpus, sizeof(network*)); + + srand(time(0)); + int seed = rand(); + for(i = 0; i < ngpus; ++i){ + srand(seed); +#ifdef GPU + cuda_set_device(gpus[i]); +#endif + nets[i] = load_network(cfgfile, weightfile, clear); + nets[i]->learning_rate *= ngpus; + } + srand(time(0)); + network *net = nets[0]; + + int imgs = net->batch * net->subdivisions * ngpus; + + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + list *options = read_data_cfg(datacfg); + + char *backup_directory = option_find_str(options, "backup", "/backup/"); + int tag = option_find_int_quiet(options, "tag", 0); + char *label_list = option_find_str(options, "labels", "data/labels.list"); + char *train_list = option_find_str(options, "train", "data/train.list"); + char *tree = option_find_str(options, "tree", 0); + if (tree) net->hierarchy = read_tree(tree); + int classes = option_find_int(options, "classes", 2); + + char **labels = 0; + if(!tag){ + labels = get_labels(label_list); + } + list *plist = get_paths(train_list); + char **paths = (char **)list_to_array(plist); + printf("%d\n", plist->size); + int N = plist->size; + double time; + + load_args args = {0}; + args.w = net->w; + args.h = net->h; + args.threads = 32; + args.hierarchy = net->hierarchy; + + args.min = net->min_ratio*net->w; + args.max = net->max_ratio*net->w; + printf("%d %d\n", args.min, args.max); + args.angle = net->angle; + args.aspect = net->aspect; + args.exposure = net->exposure; + args.saturation = net->saturation; + args.hue = net->hue; + args.size = net->w; + + args.paths = paths; + args.classes = classes; + args.n = imgs; + args.m = N; + args.labels = labels; + if (tag){ + args.type = TAG_DATA; + } else { + args.type = CLASSIFICATION_DATA; + } + + data train; + data buffer; + pthread_t load_thread; + args.d = &buffer; + load_thread = load_data(args); + + int count = 0; + int epoch = (*net->seen)/N; + while(get_current_batch(net) < net->max_batches || net->max_batches == 0){ + if(net->random && count++%40 == 0){ + printf("Resizing\n"); + int dim = (rand() % 11 + 4) * 32; + //if (get_current_batch(net)+200 > net->max_batches) dim = 608; + //int dim = (rand() % 4 + 16) * 32; + printf("%d\n", dim); + args.w = dim; + args.h = dim; + args.size = dim; + args.min = net->min_ratio*dim; + args.max = net->max_ratio*dim; + printf("%d %d\n", args.min, args.max); + + pthread_join(load_thread, 0); + train = buffer; + free_data(train); + load_thread = load_data(args); + + for(i = 0; i < ngpus; ++i){ + resize_network(nets[i], dim, dim); + } + net = nets[0]; + } + time = what_time_is_it_now(); + + pthread_join(load_thread, 0); + train = buffer; + load_thread = load_data(args); + + printf("Loaded: %lf seconds\n", what_time_is_it_now()-time); + time = what_time_is_it_now(); + + float loss = 0; +#ifdef GPU + if(ngpus == 1){ + loss = train_network(net, train); + } else { + loss = train_networks(nets, ngpus, train, 4); + } +#else + loss = train_network(net, train); +#endif + if(avg_loss == -1) avg_loss = loss; + avg_loss = avg_loss*.9 + loss*.1; + printf("%ld, %.3f: %f, %f avg, %f rate, %lf seconds, %ld images\n", get_current_batch(net), (float)(*net->seen)/N, loss, avg_loss, get_current_rate(net), what_time_is_it_now()-time, *net->seen); + free_data(train); + if(*net->seen/N > epoch){ + epoch = *net->seen/N; + char buff[256]; + sprintf(buff, "%s/%s_%d.weights",backup_directory,base, epoch); + save_weights(net, buff); + } + if(get_current_batch(net)%1000 == 0){ + char buff[256]; + sprintf(buff, "%s/%s.backup",backup_directory,base); + save_weights(net, buff); + } + } + char buff[256]; + sprintf(buff, "%s/%s.weights", backup_directory, base); + save_weights(net, buff); + pthread_join(load_thread, 0); + + free_network(net); + if(labels) free_ptrs((void**)labels, classes); + free_ptrs((void**)paths, plist->size); + free_list(plist); + free(base); +} + +void validate_classifier_crop(char *datacfg, char *filename, char *weightfile) +{ + int i = 0; + network *net = load_network(filename, weightfile, 0); + srand(time(0)); + + list *options = read_data_cfg(datacfg); + + char *label_list = option_find_str(options, "labels", "data/labels.list"); + char *valid_list = option_find_str(options, "valid", "data/train.list"); + int classes = option_find_int(options, "classes", 2); + int topk = option_find_int(options, "top", 1); + + char **labels = get_labels(label_list); + list *plist = get_paths(valid_list); + + char **paths = (char **)list_to_array(plist); + int m = plist->size; + free_list(plist); + + clock_t time; + float avg_acc = 0; + float avg_topk = 0; + int splits = m/1000; + int num = (i+1)*m/splits - i*m/splits; + + data val, buffer; + + load_args args = {0}; + args.w = net->w; + args.h = net->h; + + args.paths = paths; + args.classes = classes; + args.n = num; + args.m = 0; + args.labels = labels; + args.d = &buffer; + args.type = OLD_CLASSIFICATION_DATA; + + pthread_t load_thread = load_data_in_thread(args); + for(i = 1; i <= splits; ++i){ + time=clock(); + + pthread_join(load_thread, 0); + val = buffer; + + num = (i+1)*m/splits - i*m/splits; + char **part = paths+(i*m/splits); + if(i != splits){ + args.paths = part; + load_thread = load_data_in_thread(args); + } + printf("Loaded: %d images in %lf seconds\n", val.X.rows, sec(clock()-time)); + + time=clock(); + float *acc = network_accuracies(net, val, topk); + avg_acc += acc[0]; + avg_topk += acc[1]; + printf("%d: top 1: %f, top %d: %f, %lf seconds, %d images\n", i, avg_acc/i, topk, avg_topk/i, sec(clock()-time), val.X.rows); + free_data(val); + } +} + +void validate_classifier_10(char *datacfg, char *filename, char *weightfile) +{ + int i, j; + network *net = load_network(filename, weightfile, 0); + set_batch_network(net, 1); + srand(time(0)); + + list *options = read_data_cfg(datacfg); + + char *label_list = option_find_str(options, "labels", "data/labels.list"); + char *valid_list = option_find_str(options, "valid", "data/train.list"); + int classes = option_find_int(options, "classes", 2); + int topk = option_find_int(options, "top", 1); + + char **labels = get_labels(label_list); + list *plist = get_paths(valid_list); + + char **paths = (char **)list_to_array(plist); + int m = plist->size; + free_list(plist); + + float avg_acc = 0; + float avg_topk = 0; + int *indexes = calloc(topk, sizeof(int)); + + for(i = 0; i < m; ++i){ + int class = -1; + char *path = paths[i]; + for(j = 0; j < classes; ++j){ + if(strstr(path, labels[j])){ + class = j; + break; + } + } + int w = net->w; + int h = net->h; + int shift = 32; + image im = load_image_color(paths[i], w+shift, h+shift); + image images[10]; + images[0] = crop_image(im, -shift, -shift, w, h); + images[1] = crop_image(im, shift, -shift, w, h); + images[2] = crop_image(im, 0, 0, w, h); + images[3] = crop_image(im, -shift, shift, w, h); + images[4] = crop_image(im, shift, shift, w, h); + flip_image(im); + images[5] = crop_image(im, -shift, -shift, w, h); + images[6] = crop_image(im, shift, -shift, w, h); + images[7] = crop_image(im, 0, 0, w, h); + images[8] = crop_image(im, -shift, shift, w, h); + images[9] = crop_image(im, shift, shift, w, h); + float *pred = calloc(classes, sizeof(float)); + for(j = 0; j < 10; ++j){ + float *p = network_predict(net, images[j].data); + if(net->hierarchy) hierarchy_predictions(p, net->outputs, net->hierarchy, 1, 1); + axpy_cpu(classes, 1, p, 1, pred, 1); + free_image(images[j]); + } + free_image(im); + top_k(pred, classes, topk, indexes); + free(pred); + if(indexes[0] == class) avg_acc += 1; + for(j = 0; j < topk; ++j){ + if(indexes[j] == class) avg_topk += 1; + } + + printf("%d: top 1: %f, top %d: %f\n", i, avg_acc/(i+1), topk, avg_topk/(i+1)); + } +} + +void validate_classifier_full(char *datacfg, char *filename, char *weightfile) +{ + int i, j; + network *net = load_network(filename, weightfile, 0); + set_batch_network(net, 1); + srand(time(0)); + + list *options = read_data_cfg(datacfg); + + char *label_list = option_find_str(options, "labels", "data/labels.list"); + char *valid_list = option_find_str(options, "valid", "data/train.list"); + int classes = option_find_int(options, "classes", 2); + int topk = option_find_int(options, "top", 1); + + char **labels = get_labels(label_list); + list *plist = get_paths(valid_list); + + char **paths = (char **)list_to_array(plist); + int m = plist->size; + free_list(plist); + + float avg_acc = 0; + float avg_topk = 0; + int *indexes = calloc(topk, sizeof(int)); + + int size = net->w; + for(i = 0; i < m; ++i){ + int class = -1; + char *path = paths[i]; + for(j = 0; j < classes; ++j){ + if(strstr(path, labels[j])){ + class = j; + break; + } + } + image im = load_image_color(paths[i], 0, 0); + image resized = resize_min(im, size); + resize_network(net, resized.w, resized.h); + //show_image(im, "orig"); + //show_image(crop, "cropped"); + //cvWaitKey(0); + float *pred = network_predict(net, resized.data); + if(net->hierarchy) hierarchy_predictions(pred, net->outputs, net->hierarchy, 1, 1); + + free_image(im); + free_image(resized); + top_k(pred, classes, topk, indexes); + + if(indexes[0] == class) avg_acc += 1; + for(j = 0; j < topk; ++j){ + if(indexes[j] == class) avg_topk += 1; + } + + printf("%d: top 1: %f, top %d: %f\n", i, avg_acc/(i+1), topk, avg_topk/(i+1)); + } +} + + +void validate_classifier_single(char *datacfg, char *filename, char *weightfile) +{ + int i, j; + network *net = load_network(filename, weightfile, 0); + set_batch_network(net, 1); + srand(time(0)); + + list *options = read_data_cfg(datacfg); + + char *label_list = option_find_str(options, "labels", "data/labels.list"); + char *leaf_list = option_find_str(options, "leaves", 0); + if(leaf_list) change_leaves(net->hierarchy, leaf_list); + char *valid_list = option_find_str(options, "valid", "data/train.list"); + int classes = option_find_int(options, "classes", 2); + int topk = option_find_int(options, "top", 1); + + char **labels = get_labels(label_list); + list *plist = get_paths(valid_list); + + char **paths = (char **)list_to_array(plist); + int m = plist->size; + free_list(plist); + + float avg_acc = 0; + float avg_topk = 0; + int *indexes = calloc(topk, sizeof(int)); + + for(i = 0; i < m; ++i){ + int class = -1; + char *path = paths[i]; + for(j = 0; j < classes; ++j){ + if(strstr(path, labels[j])){ + class = j; + break; + } + } + image im = load_image_color(paths[i], 0, 0); + image crop = center_crop_image(im, net->w, net->h); + //grayscale_image_3c(crop); + //show_image(im, "orig"); + //show_image(crop, "cropped"); + //cvWaitKey(0); + float *pred = network_predict(net, crop.data); + if(net->hierarchy) hierarchy_predictions(pred, net->outputs, net->hierarchy, 1, 1); + + free_image(im); + free_image(crop); + top_k(pred, classes, topk, indexes); + + if(indexes[0] == class) avg_acc += 1; + for(j = 0; j < topk; ++j){ + if(indexes[j] == class) avg_topk += 1; + } + + printf("%s, %d, %f, %f, \n", paths[i], class, pred[0], pred[1]); + printf("%d: top 1: %f, top %d: %f\n", i, avg_acc/(i+1), topk, avg_topk/(i+1)); + } +} + +void validate_classifier_multi(char *datacfg, char *cfg, char *weights) +{ + int i, j; + network *net = load_network(cfg, weights, 0); + set_batch_network(net, 1); + srand(time(0)); + + list *options = read_data_cfg(datacfg); + + char *label_list = option_find_str(options, "labels", "data/labels.list"); + char *valid_list = option_find_str(options, "valid", "data/train.list"); + int classes = option_find_int(options, "classes", 2); + int topk = option_find_int(options, "top", 1); + + char **labels = get_labels(label_list); + list *plist = get_paths(valid_list); + //int scales[] = {224, 288, 320, 352, 384}; + int scales[] = {224, 256, 288, 320}; + int nscales = sizeof(scales)/sizeof(scales[0]); + + char **paths = (char **)list_to_array(plist); + int m = plist->size; + free_list(plist); + + float avg_acc = 0; + float avg_topk = 0; + int *indexes = calloc(topk, sizeof(int)); + + for(i = 0; i < m; ++i){ + int class = -1; + char *path = paths[i]; + for(j = 0; j < classes; ++j){ + if(strstr(path, labels[j])){ + class = j; + break; + } + } + float *pred = calloc(classes, sizeof(float)); + image im = load_image_color(paths[i], 0, 0); + for(j = 0; j < nscales; ++j){ + image r = resize_max(im, scales[j]); + resize_network(net, r.w, r.h); + float *p = network_predict(net, r.data); + if(net->hierarchy) hierarchy_predictions(p, net->outputs, net->hierarchy, 1 , 1); + axpy_cpu(classes, 1, p, 1, pred, 1); + flip_image(r); + p = network_predict(net, r.data); + axpy_cpu(classes, 1, p, 1, pred, 1); + if(r.data != im.data) free_image(r); + } + free_image(im); + top_k(pred, classes, topk, indexes); + free(pred); + if(indexes[0] == class) avg_acc += 1; + for(j = 0; j < topk; ++j){ + if(indexes[j] == class) avg_topk += 1; + } + + printf("%d: top 1: %f, top %d: %f\n", i, avg_acc/(i+1), topk, avg_topk/(i+1)); + } +} + +void try_classifier(char *datacfg, char *cfgfile, char *weightfile, char *filename, int layer_num) +{ + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + srand(2222222); + + list *options = read_data_cfg(datacfg); + + char *name_list = option_find_str(options, "names", 0); + if(!name_list) name_list = option_find_str(options, "labels", "data/labels.list"); + int top = option_find_int(options, "top", 1); + + int i = 0; + char **names = get_labels(name_list); + clock_t time; + int *indexes = calloc(top, sizeof(int)); + char buff[256]; + char *input = buff; + while(1){ + if(filename){ + strncpy(input, filename, 256); + }else{ + printf("Enter Image Path: "); + fflush(stdout); + input = fgets(input, 256, stdin); + if(!input) return; + strtok(input, "\n"); + } + image orig = load_image_color(input, 0, 0); + image r = resize_min(orig, 256); + image im = crop_image(r, (r.w - 224 - 1)/2 + 1, (r.h - 224 - 1)/2 + 1, 224, 224); + float mean[] = {0.48263312050943, 0.45230225481413, 0.40099074308742}; + float std[] = {0.22590347483426, 0.22120921437787, 0.22103996251583}; + float var[3]; + var[0] = std[0]*std[0]; + var[1] = std[1]*std[1]; + var[2] = std[2]*std[2]; + + normalize_cpu(im.data, mean, var, 1, 3, im.w*im.h); + + float *X = im.data; + time=clock(); + float *predictions = network_predict(net, X); + + layer l = net->layers[layer_num]; + for(i = 0; i < l.c; ++i){ + if(l.rolling_mean) printf("%f %f %f\n", l.rolling_mean[i], l.rolling_variance[i], l.scales[i]); + } +#ifdef GPU + cuda_pull_array(l.output_gpu, l.output, l.outputs); +#endif + for(i = 0; i < l.outputs; ++i){ + printf("%f\n", l.output[i]); + } + /* + + printf("\n\nWeights\n"); + for(i = 0; i < l.n*l.size*l.size*l.c; ++i){ + printf("%f\n", l.filters[i]); + } + + printf("\n\nBiases\n"); + for(i = 0; i < l.n; ++i){ + printf("%f\n", l.biases[i]); + } + */ + + top_predictions(net, top, indexes); + printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time)); + for(i = 0; i < top; ++i){ + int index = indexes[i]; + printf("%s: %f\n", names[index], predictions[index]); + } + free_image(im); + if (filename) break; + } +} + +void predict_classifier(char *datacfg, char *cfgfile, char *weightfile, char *filename, int top) +{ + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + srand(2222222); + + list *options = read_data_cfg(datacfg); + + char *name_list = option_find_str(options, "names", 0); + if(!name_list) name_list = option_find_str(options, "labels", "data/labels.list"); + if(top == 0) top = option_find_int(options, "top", 1); + + int i = 0; + char **names = get_labels(name_list); + clock_t time; + int *indexes = calloc(top, sizeof(int)); + char buff[256]; + char *input = buff; + while(1){ + if(filename){ + strncpy(input, filename, 256); + }else{ + printf("Enter Image Path: "); + fflush(stdout); + input = fgets(input, 256, stdin); + if(!input) return; + strtok(input, "\n"); + } + image im = load_image_color(input, 0, 0); + image r = letterbox_image(im, net->w, net->h); + //image r = resize_min(im, 320); + //printf("%d %d\n", r.w, r.h); + //resize_network(net, r.w, r.h); + //printf("%d %d\n", r.w, r.h); + + float *X = r.data; + time=clock(); + float *predictions = network_predict(net, X); + if(net->hierarchy) hierarchy_predictions(predictions, net->outputs, net->hierarchy, 1, 1); + top_k(predictions, net->outputs, top, indexes); + fprintf(stderr, "%s: Predicted in %f seconds.\n", input, sec(clock()-time)); + for(i = 0; i < top; ++i){ + int index = indexes[i]; + //if(net->hierarchy) printf("%d, %s: %f, parent: %s \n",index, names[index], predictions[index], (net->hierarchy->parent[index] >= 0) ? names[net->hierarchy->parent[index]] : "Root"); + //else printf("%s: %f\n",names[index], predictions[index]); + printf("%5.2f%%: %s\n", predictions[index]*100, names[index]); + } + if(r.data != im.data) free_image(r); + free_image(im); + if (filename) break; + } +} + + +void label_classifier(char *datacfg, char *filename, char *weightfile) +{ + int i; + network *net = load_network(filename, weightfile, 0); + set_batch_network(net, 1); + srand(time(0)); + + list *options = read_data_cfg(datacfg); + + char *label_list = option_find_str(options, "names", "data/labels.list"); + char *test_list = option_find_str(options, "test", "data/train.list"); + int classes = option_find_int(options, "classes", 2); + + char **labels = get_labels(label_list); + list *plist = get_paths(test_list); + + char **paths = (char **)list_to_array(plist); + int m = plist->size; + free_list(plist); + + for(i = 0; i < m; ++i){ + image im = load_image_color(paths[i], 0, 0); + image resized = resize_min(im, net->w); + image crop = crop_image(resized, (resized.w - net->w)/2, (resized.h - net->h)/2, net->w, net->h); + float *pred = network_predict(net, crop.data); + + if(resized.data != im.data) free_image(resized); + free_image(im); + free_image(crop); + int ind = max_index(pred, classes); + + printf("%s\n", labels[ind]); + } +} + +void csv_classifier(char *datacfg, char *cfgfile, char *weightfile) +{ + int i,j; + network *net = load_network(cfgfile, weightfile, 0); + srand(time(0)); + + list *options = read_data_cfg(datacfg); + + char *test_list = option_find_str(options, "test", "data/test.list"); + int top = option_find_int(options, "top", 1); + + list *plist = get_paths(test_list); + + char **paths = (char **)list_to_array(plist); + int m = plist->size; + free_list(plist); + int *indexes = calloc(top, sizeof(int)); + + for(i = 0; i < m; ++i){ + double time = what_time_is_it_now(); + char *path = paths[i]; + image im = load_image_color(path, 0, 0); + image r = letterbox_image(im, net->w, net->h); + float *predictions = network_predict(net, r.data); + if(net->hierarchy) hierarchy_predictions(predictions, net->outputs, net->hierarchy, 1, 1); + top_k(predictions, net->outputs, top, indexes); + + printf("%s", path); + for(j = 0; j < top; ++j){ + printf("\t%d", indexes[j]); + } + printf("\n"); + + free_image(im); + free_image(r); + + fprintf(stderr, "%lf seconds, %d images, %d total\n", what_time_is_it_now() - time, i+1, m); + } +} + +void test_classifier(char *datacfg, char *cfgfile, char *weightfile, int target_layer) +{ + int curr = 0; + network *net = load_network(cfgfile, weightfile, 0); + srand(time(0)); + + list *options = read_data_cfg(datacfg); + + char *test_list = option_find_str(options, "test", "data/test.list"); + int classes = option_find_int(options, "classes", 2); + + list *plist = get_paths(test_list); + + char **paths = (char **)list_to_array(plist); + int m = plist->size; + free_list(plist); + + clock_t time; + + data val, buffer; + + load_args args = {0}; + args.w = net->w; + args.h = net->h; + args.paths = paths; + args.classes = classes; + args.n = net->batch; + args.m = 0; + args.labels = 0; + args.d = &buffer; + args.type = OLD_CLASSIFICATION_DATA; + + pthread_t load_thread = load_data_in_thread(args); + for(curr = net->batch; curr < m; curr += net->batch){ + time=clock(); + + pthread_join(load_thread, 0); + val = buffer; + + if(curr < m){ + args.paths = paths + curr; + if (curr + net->batch > m) args.n = m - curr; + load_thread = load_data_in_thread(args); + } + fprintf(stderr, "Loaded: %d images in %lf seconds\n", val.X.rows, sec(clock()-time)); + + time=clock(); + matrix pred = network_predict_data(net, val); + + int i, j; + if (target_layer >= 0){ + //layer l = net->layers[target_layer]; + } + + for(i = 0; i < pred.rows; ++i){ + printf("%s", paths[curr-net->batch+i]); + for(j = 0; j < pred.cols; ++j){ + printf("\t%g", pred.vals[i][j]); + } + printf("\n"); + } + + free_matrix(pred); + + fprintf(stderr, "%lf seconds, %d images, %d total\n", sec(clock()-time), val.X.rows, curr); + free_data(val); + } +} + +void file_output_classifier(char *datacfg, char *filename, char *weightfile, char *listfile) +{ + int i,j; + network *net = load_network(filename, weightfile, 0); + set_batch_network(net, 1); + srand(time(0)); + + list *options = read_data_cfg(datacfg); + + //char *label_list = option_find_str(options, "names", "data/labels.list"); + int classes = option_find_int(options, "classes", 2); + + list *plist = get_paths(listfile); + + char **paths = (char **)list_to_array(plist); + int m = plist->size; + free_list(plist); + + for(i = 0; i < m; ++i){ + image im = load_image_color(paths[i], 0, 0); + image resized = resize_min(im, net->w); + image crop = crop_image(resized, (resized.w - net->w)/2, (resized.h - net->h)/2, net->w, net->h); + + float *pred = network_predict(net, crop.data); + if(net->hierarchy) hierarchy_predictions(pred, net->outputs, net->hierarchy, 0, 1); + + if(resized.data != im.data) free_image(resized); + free_image(im); + free_image(crop); + + printf("%s", paths[i]); + for(j = 0; j < classes; ++j){ + printf("\t%g", pred[j]); + } + printf("\n"); + } +} + + +void threat_classifier(char *datacfg, char *cfgfile, char *weightfile, int cam_index, const char *filename) +{ +#ifdef OPENCV + float threat = 0; + float roll = .2; + + printf("Classifier Demo\n"); + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + list *options = read_data_cfg(datacfg); + + srand(2222222); + void * cap = open_video_stream(filename, cam_index, 0,0,0); + + int top = option_find_int(options, "top", 1); + + char *name_list = option_find_str(options, "names", 0); + char **names = get_labels(name_list); + + int *indexes = calloc(top, sizeof(int)); + + if(!cap) error("Couldn't connect to webcam.\n"); + //cvNamedWindow("Threat", CV_WINDOW_NORMAL); + //cvResizeWindow("Threat", 512, 512); + float fps = 0; + int i; + + int count = 0; + + while(1){ + ++count; + struct timeval tval_before, tval_after, tval_result; + gettimeofday(&tval_before, NULL); + + image in = get_image_from_stream(cap); + if(!in.data) break; + image in_s = resize_image(in, net->w, net->h); + + image out = in; + int x1 = out.w / 20; + int y1 = out.h / 20; + int x2 = 2*x1; + int y2 = out.h - out.h/20; + + int border = .01*out.h; + int h = y2 - y1 - 2*border; + int w = x2 - x1 - 2*border; + + float *predictions = network_predict(net, in_s.data); + float curr_threat = 0; + if(1){ + curr_threat = predictions[0] * 0 + + predictions[1] * .6 + + predictions[2]; + } else { + curr_threat = predictions[218] + + predictions[539] + + predictions[540] + + predictions[368] + + predictions[369] + + predictions[370]; + } + threat = roll * curr_threat + (1-roll) * threat; + + draw_box_width(out, x2 + border, y1 + .02*h, x2 + .5 * w, y1 + .02*h + border, border, 0,0,0); + if(threat > .97) { + draw_box_width(out, x2 + .5 * w + border, + y1 + .02*h - 2*border, + x2 + .5 * w + 6*border, + y1 + .02*h + 3*border, 3*border, 1,0,0); + } + draw_box_width(out, x2 + .5 * w + border, + y1 + .02*h - 2*border, + x2 + .5 * w + 6*border, + y1 + .02*h + 3*border, .5*border, 0,0,0); + draw_box_width(out, x2 + border, y1 + .42*h, x2 + .5 * w, y1 + .42*h + border, border, 0,0,0); + if(threat > .57) { + draw_box_width(out, x2 + .5 * w + border, + y1 + .42*h - 2*border, + x2 + .5 * w + 6*border, + y1 + .42*h + 3*border, 3*border, 1,1,0); + } + draw_box_width(out, x2 + .5 * w + border, + y1 + .42*h - 2*border, + x2 + .5 * w + 6*border, + y1 + .42*h + 3*border, .5*border, 0,0,0); + + draw_box_width(out, x1, y1, x2, y2, border, 0,0,0); + for(i = 0; i < threat * h ; ++i){ + float ratio = (float) i / h; + float r = (ratio < .5) ? (2*(ratio)) : 1; + float g = (ratio < .5) ? 1 : 1 - 2*(ratio - .5); + draw_box_width(out, x1 + border, y2 - border - i, x2 - border, y2 - border - i, 1, r, g, 0); + } + top_predictions(net, top, indexes); + char buff[256]; + sprintf(buff, "/home/pjreddie/tmp/threat_%06d", count); + //save_image(out, buff); + + printf("\033[2J"); + printf("\033[1;1H"); + printf("\nFPS:%.0f\n",fps); + + for(i = 0; i < top; ++i){ + int index = indexes[i]; + printf("%.1f%%: %s\n", predictions[index]*100, names[index]); + } + + if(1){ + show_image(out, "Threat", 10); + } + free_image(in_s); + free_image(in); + + gettimeofday(&tval_after, NULL); + timersub(&tval_after, &tval_before, &tval_result); + float curr = 1000000.f/((long int)tval_result.tv_usec); + fps = .9*fps + .1*curr; + } +#endif +} + + +void gun_classifier(char *datacfg, char *cfgfile, char *weightfile, int cam_index, const char *filename) +{ +#ifdef OPENCV + int bad_cats[] = {218, 539, 540, 1213, 1501, 1742, 1911, 2415, 4348, 19223, 368, 369, 370, 1133, 1200, 1306, 2122, 2301, 2537, 2823, 3179, 3596, 3639, 4489, 5107, 5140, 5289, 6240, 6631, 6762, 7048, 7171, 7969, 7984, 7989, 8824, 8927, 9915, 10270, 10448, 13401, 15205, 18358, 18894, 18895, 19249, 19697}; + + printf("Classifier Demo\n"); + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + list *options = read_data_cfg(datacfg); + + srand(2222222); + void * cap = open_video_stream(filename, cam_index, 0,0,0); + + int top = option_find_int(options, "top", 1); + + char *name_list = option_find_str(options, "names", 0); + char **names = get_labels(name_list); + + int *indexes = calloc(top, sizeof(int)); + + if(!cap) error("Couldn't connect to webcam.\n"); + float fps = 0; + int i; + + while(1){ + struct timeval tval_before, tval_after, tval_result; + gettimeofday(&tval_before, NULL); + + image in = get_image_from_stream(cap); + image in_s = resize_image(in, net->w, net->h); + + float *predictions = network_predict(net, in_s.data); + top_predictions(net, top, indexes); + + printf("\033[2J"); + printf("\033[1;1H"); + + int threat = 0; + for(i = 0; i < sizeof(bad_cats)/sizeof(bad_cats[0]); ++i){ + int index = bad_cats[i]; + if(predictions[index] > .01){ + printf("Threat Detected!\n"); + threat = 1; + break; + } + } + if(!threat) printf("Scanning...\n"); + for(i = 0; i < sizeof(bad_cats)/sizeof(bad_cats[0]); ++i){ + int index = bad_cats[i]; + if(predictions[index] > .01){ + printf("%s\n", names[index]); + } + } + + show_image(in, "Threat Detection", 10); + free_image(in_s); + free_image(in); + + gettimeofday(&tval_after, NULL); + timersub(&tval_after, &tval_before, &tval_result); + float curr = 1000000.f/((long int)tval_result.tv_usec); + fps = .9*fps + .1*curr; + } +#endif +} + +void demo_classifier(char *datacfg, char *cfgfile, char *weightfile, int cam_index, const char *filename) +{ +#ifdef OPENCV + char *base = basecfg(cfgfile); + image **alphabet = load_alphabet(); + printf("Classifier Demo\n"); + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + list *options = read_data_cfg(datacfg); + + srand(2222222); + + int w = 1280; + int h = 720; + void * cap = open_video_stream(filename, cam_index, w, h, 0); + + int top = option_find_int(options, "top", 1); + + char *label_list = option_find_str(options, "labels", 0); + char *name_list = option_find_str(options, "names", label_list); + char **names = get_labels(name_list); + + int *indexes = calloc(top, sizeof(int)); + + if(!cap) error("Couldn't connect to webcam.\n"); + float fps = 0; + int i; + + while(1){ + struct timeval tval_before, tval_after, tval_result; + gettimeofday(&tval_before, NULL); + + image in = get_image_from_stream(cap); + //image in_s = resize_image(in, net->w, net->h); + image in_s = letterbox_image(in, net->w, net->h); + + float *predictions = network_predict(net, in_s.data); + if(net->hierarchy) hierarchy_predictions(predictions, net->outputs, net->hierarchy, 1, 1); + top_predictions(net, top, indexes); + + printf("\033[2J"); + printf("\033[1;1H"); + printf("\nFPS:%.0f\n",fps); + + int lh = in.h*.03; + int toph = 3*lh; + + float rgb[3] = {1,1,1}; + for(i = 0; i < top; ++i){ + printf("%d\n", toph); + int index = indexes[i]; + printf("%.1f%%: %s\n", predictions[index]*100, names[index]); + + char buff[1024]; + sprintf(buff, "%3.1f%%: %s\n", predictions[index]*100, names[index]); + image label = get_label(alphabet, buff, lh); + draw_label(in, toph, lh, label, rgb); + toph += 2*lh; + free_image(label); + } + + show_image(in, base, 10); + free_image(in_s); + free_image(in); + + gettimeofday(&tval_after, NULL); + timersub(&tval_after, &tval_before, &tval_result); + float curr = 1000000.f/((long int)tval_result.tv_usec); + fps = .9*fps + .1*curr; + } +#endif +} + + +void run_classifier(int argc, char **argv) +{ + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + + char *gpu_list = find_char_arg(argc, argv, "-gpus", 0); + int ngpus; + int *gpus = read_intlist(gpu_list, &ngpus, gpu_index); + + + int cam_index = find_int_arg(argc, argv, "-c", 0); + int top = find_int_arg(argc, argv, "-t", 0); + int clear = find_arg(argc, argv, "-clear"); + char *data = argv[3]; + char *cfg = argv[4]; + char *weights = (argc > 5) ? argv[5] : 0; + char *filename = (argc > 6) ? argv[6]: 0; + char *layer_s = (argc > 7) ? argv[7]: 0; + int layer = layer_s ? atoi(layer_s) : -1; + if(0==strcmp(argv[2], "predict")) predict_classifier(data, cfg, weights, filename, top); + else if(0==strcmp(argv[2], "fout")) file_output_classifier(data, cfg, weights, filename); + else if(0==strcmp(argv[2], "try")) try_classifier(data, cfg, weights, filename, atoi(layer_s)); + else if(0==strcmp(argv[2], "train")) train_classifier(data, cfg, weights, gpus, ngpus, clear); + else if(0==strcmp(argv[2], "demo")) demo_classifier(data, cfg, weights, cam_index, filename); + else if(0==strcmp(argv[2], "gun")) gun_classifier(data, cfg, weights, cam_index, filename); + else if(0==strcmp(argv[2], "threat")) threat_classifier(data, cfg, weights, cam_index, filename); + else if(0==strcmp(argv[2], "test")) test_classifier(data, cfg, weights, layer); + else if(0==strcmp(argv[2], "csv")) csv_classifier(data, cfg, weights); + else if(0==strcmp(argv[2], "label")) label_classifier(data, cfg, weights); + else if(0==strcmp(argv[2], "valid")) validate_classifier_single(data, cfg, weights); + else if(0==strcmp(argv[2], "validmulti")) validate_classifier_multi(data, cfg, weights); + else if(0==strcmp(argv[2], "valid10")) validate_classifier_10(data, cfg, weights); + else if(0==strcmp(argv[2], "validcrop")) validate_classifier_crop(data, cfg, weights); + else if(0==strcmp(argv[2], "validfull")) validate_classifier_full(data, cfg, weights); +} + + diff --git a/hanzi_detection/examples/coco.c b/hanzi_detection/examples/coco.c new file mode 100755 index 0000000..6a50b89 --- /dev/null +++ b/hanzi_detection/examples/coco.c @@ -0,0 +1,357 @@ +#include "darknet.h" + +#include + +char *coco_classes[] = {"person","bicycle","car","motorcycle","airplane","bus","train","truck","boat","traffic light","fire hydrant","stop sign","parking meter","bench","bird","cat","dog","horse","sheep","cow","elephant","bear","zebra","giraffe","backpack","umbrella","handbag","tie","suitcase","frisbee","skis","snowboard","sports ball","kite","baseball bat","baseball glove","skateboard","surfboard","tennis racket","bottle","wine glass","cup","fork","knife","spoon","bowl","banana","apple","sandwich","orange","broccoli","carrot","hot dog","pizza","donut","cake","chair","couch","potted plant","bed","dining table","toilet","tv","laptop","mouse","remote","keyboard","cell phone","microwave","oven","toaster","sink","refrigerator","book","clock","vase","scissors","teddy bear","hair drier","toothbrush"}; + +int coco_ids[] = {1,2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19,20,21,22,23,24,25,27,28,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,67,70,72,73,74,75,76,77,78,79,80,81,82,84,85,86,87,88,89,90}; + +void train_coco(char *cfgfile, char *weightfile) +{ + //char *train_images = "/home/pjreddie/data/voc/test/train.txt"; + //char *train_images = "/home/pjreddie/data/coco/train.txt"; + char *train_images = "data/coco.trainval.txt"; + //char *train_images = "data/bags.train.list"; + char *backup_directory = "/home/pjreddie/backup/"; + srand(time(0)); + char *base = basecfg(cfgfile); + printf("%s\n", base); + float avg_loss = -1; + network *net = load_network(cfgfile, weightfile, 0); + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + int imgs = net->batch*net->subdivisions; + int i = *net->seen/imgs; + data train, buffer; + + + layer l = net->layers[net->n - 1]; + + int side = l.side; + int classes = l.classes; + float jitter = l.jitter; + + list *plist = get_paths(train_images); + //int N = plist->size; + char **paths = (char **)list_to_array(plist); + + load_args args = {0}; + args.w = net->w; + args.h = net->h; + args.paths = paths; + args.n = imgs; + args.m = plist->size; + args.classes = classes; + args.jitter = jitter; + args.num_boxes = side; + args.d = &buffer; + args.type = REGION_DATA; + + args.angle = net->angle; + args.exposure = net->exposure; + args.saturation = net->saturation; + args.hue = net->hue; + + pthread_t load_thread = load_data_in_thread(args); + clock_t time; + //while(i*imgs < N*120){ + while(get_current_batch(net) < net->max_batches){ + i += 1; + time=clock(); + pthread_join(load_thread, 0); + train = buffer; + load_thread = load_data_in_thread(args); + + printf("Loaded: %lf seconds\n", sec(clock()-time)); + + /* + image im = float_to_image(net->w, net->h, 3, train.X.vals[113]); + image copy = copy_image(im); + draw_coco(copy, train.y.vals[113], 7, "truth"); + cvWaitKey(0); + free_image(copy); + */ + + time=clock(); + float loss = train_network(net, train); + if (avg_loss < 0) avg_loss = loss; + avg_loss = avg_loss*.9 + loss*.1; + + printf("%d: %f, %f avg, %f rate, %lf seconds, %d images\n", i, loss, avg_loss, get_current_rate(net), sec(clock()-time), i*imgs); + if(i%1000==0 || (i < 1000 && i%100 == 0)){ + char buff[256]; + sprintf(buff, "%s/%s_%d.weights", backup_directory, base, i); + save_weights(net, buff); + } + if(i%100==0){ + char buff[256]; + sprintf(buff, "%s/%s.backup", backup_directory, base); + save_weights(net, buff); + } + free_data(train); + } + char buff[256]; + sprintf(buff, "%s/%s_final.weights", backup_directory, base); + save_weights(net, buff); +} + +static void print_cocos(FILE *fp, int image_id, detection *dets, int num_boxes, int classes, int w, int h) +{ + int i, j; + for(i = 0; i < num_boxes; ++i){ + float xmin = dets[i].bbox.x - dets[i].bbox.w/2.; + float xmax = dets[i].bbox.x + dets[i].bbox.w/2.; + float ymin = dets[i].bbox.y - dets[i].bbox.h/2.; + float ymax = dets[i].bbox.y + dets[i].bbox.h/2.; + + if (xmin < 0) xmin = 0; + if (ymin < 0) ymin = 0; + if (xmax > w) xmax = w; + if (ymax > h) ymax = h; + + float bx = xmin; + float by = ymin; + float bw = xmax - xmin; + float bh = ymax - ymin; + + for(j = 0; j < classes; ++j){ + if (dets[i].prob[j]) fprintf(fp, "{\"image_id\":%d, \"category_id\":%d, \"bbox\":[%f, %f, %f, %f], \"score\":%f},\n", image_id, coco_ids[j], bx, by, bw, bh, dets[i].prob[j]); + } + } +} + +int get_coco_image_id(char *filename) +{ + char *p = strrchr(filename, '_'); + return atoi(p+1); +} + +void validate_coco(char *cfg, char *weights) +{ + network *net = load_network(cfg, weights, 0); + set_batch_network(net, 1); + fprintf(stderr, "Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + srand(time(0)); + + char *base = "results/"; + list *plist = get_paths("data/coco_val_5k.list"); + //list *plist = get_paths("/home/pjreddie/data/people-art/test.txt"); + //list *plist = get_paths("/home/pjreddie/data/voc/test/2007_test.txt"); + char **paths = (char **)list_to_array(plist); + + layer l = net->layers[net->n-1]; + int classes = l.classes; + + char buff[1024]; + snprintf(buff, 1024, "%s/coco_results.json", base); + FILE *fp = fopen(buff, "w"); + fprintf(fp, "[\n"); + + int m = plist->size; + int i=0; + int t; + + float thresh = .01; + int nms = 1; + float iou_thresh = .5; + + int nthreads = 8; + image *val = calloc(nthreads, sizeof(image)); + image *val_resized = calloc(nthreads, sizeof(image)); + image *buf = calloc(nthreads, sizeof(image)); + image *buf_resized = calloc(nthreads, sizeof(image)); + pthread_t *thr = calloc(nthreads, sizeof(pthread_t)); + + load_args args = {0}; + args.w = net->w; + args.h = net->h; + args.type = IMAGE_DATA; + + for(t = 0; t < nthreads; ++t){ + args.path = paths[i+t]; + args.im = &buf[t]; + args.resized = &buf_resized[t]; + thr[t] = load_data_in_thread(args); + } + time_t start = time(0); + for(i = nthreads; i < m+nthreads; i += nthreads){ + fprintf(stderr, "%d\n", i); + for(t = 0; t < nthreads && i+t-nthreads < m; ++t){ + pthread_join(thr[t], 0); + val[t] = buf[t]; + val_resized[t] = buf_resized[t]; + } + for(t = 0; t < nthreads && i+t < m; ++t){ + args.path = paths[i+t]; + args.im = &buf[t]; + args.resized = &buf_resized[t]; + thr[t] = load_data_in_thread(args); + } + for(t = 0; t < nthreads && i+t-nthreads < m; ++t){ + char *path = paths[i+t-nthreads]; + int image_id = get_coco_image_id(path); + float *X = val_resized[t].data; + network_predict(net, X); + int w = val[t].w; + int h = val[t].h; + int nboxes = 0; + detection *dets = get_network_boxes(net, w, h, thresh, 0, 0, 0, &nboxes); + if (nms) do_nms_sort(dets, l.side*l.side*l.n, classes, iou_thresh); + print_cocos(fp, image_id, dets, l.side*l.side*l.n, classes, w, h); + free_detections(dets, nboxes); + free_image(val[t]); + free_image(val_resized[t]); + } + } + fseek(fp, -2, SEEK_CUR); + fprintf(fp, "\n]\n"); + fclose(fp); + + fprintf(stderr, "Total Detection Time: %f Seconds\n", (double)(time(0) - start)); +} + +void validate_coco_recall(char *cfgfile, char *weightfile) +{ + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + fprintf(stderr, "Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + srand(time(0)); + + char *base = "results/comp4_det_test_"; + list *plist = get_paths("/home/pjreddie/data/voc/test/2007_test.txt"); + char **paths = (char **)list_to_array(plist); + + layer l = net->layers[net->n-1]; + int classes = l.classes; + int side = l.side; + + int j, k; + FILE **fps = calloc(classes, sizeof(FILE *)); + for(j = 0; j < classes; ++j){ + char buff[1024]; + snprintf(buff, 1024, "%s%s.txt", base, coco_classes[j]); + fps[j] = fopen(buff, "w"); + } + + int m = plist->size; + int i=0; + + float thresh = .001; + int nms = 0; + float iou_thresh = .5; + + int total = 0; + int correct = 0; + int proposals = 0; + float avg_iou = 0; + + for(i = 0; i < m; ++i){ + char *path = paths[i]; + image orig = load_image_color(path, 0, 0); + image sized = resize_image(orig, net->w, net->h); + char *id = basecfg(path); + network_predict(net, sized.data); + + int nboxes = 0; + detection *dets = get_network_boxes(net, orig.w, orig.h, thresh, 0, 0, 1, &nboxes); + if (nms) do_nms_obj(dets, side*side*l.n, 1, nms); + + char labelpath[4096]; + find_replace(path, "images", "labels", labelpath); + find_replace(labelpath, "JPEGImages", "labels", labelpath); + find_replace(labelpath, ".jpg", ".txt", labelpath); + find_replace(labelpath, ".JPEG", ".txt", labelpath); + + int num_labels = 0; + box_label *truth = read_boxes(labelpath, &num_labels); + for(k = 0; k < side*side*l.n; ++k){ + if(dets[k].objectness > thresh){ + ++proposals; + } + } + for (j = 0; j < num_labels; ++j) { + ++total; + box t = {truth[j].x, truth[j].y, truth[j].w, truth[j].h}; + float best_iou = 0; + for(k = 0; k < side*side*l.n; ++k){ + float iou = box_iou(dets[k].bbox, t); + if(dets[k].objectness > thresh && iou > best_iou){ + best_iou = iou; + } + } + avg_iou += best_iou; + if(best_iou > iou_thresh){ + ++correct; + } + } + free_detections(dets, nboxes); + fprintf(stderr, "%5d %5d %5d\tRPs/Img: %.2f\tIOU: %.2f%%\tRecall:%.2f%%\n", i, correct, total, (float)proposals/(i+1), avg_iou*100/total, 100.*correct/total); + free(id); + free_image(orig); + free_image(sized); + } +} + +void test_coco(char *cfgfile, char *weightfile, char *filename, float thresh) +{ + image **alphabet = load_alphabet(); + network *net = load_network(cfgfile, weightfile, 0); + layer l = net->layers[net->n-1]; + set_batch_network(net, 1); + srand(2222222); + float nms = .4; + clock_t time; + char buff[256]; + char *input = buff; + while(1){ + if(filename){ + strncpy(input, filename, 256); + } else { + printf("Enter Image Path: "); + fflush(stdout); + input = fgets(input, 256, stdin); + if(!input) return; + strtok(input, "\n"); + } + image im = load_image_color(input,0,0); + image sized = resize_image(im, net->w, net->h); + float *X = sized.data; + time=clock(); + network_predict(net, X); + printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time)); + + int nboxes = 0; + detection *dets = get_network_boxes(net, 1, 1, thresh, 0, 0, 0, &nboxes); + if (nms) do_nms_sort(dets, l.side*l.side*l.n, l.classes, nms); + + draw_detections(im, dets, l.side*l.side*l.n, thresh, coco_classes, alphabet, 80); + save_image(im, "prediction"); + show_image(im, "predictions", 0); + free_detections(dets, nboxes); + free_image(im); + free_image(sized); + if (filename) break; + } +} + +void run_coco(int argc, char **argv) +{ + char *prefix = find_char_arg(argc, argv, "-prefix", 0); + float thresh = find_float_arg(argc, argv, "-thresh", .2); + int cam_index = find_int_arg(argc, argv, "-c", 0); + int frame_skip = find_int_arg(argc, argv, "-s", 0); + + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + + char *cfg = argv[3]; + char *weights = (argc > 4) ? argv[4] : 0; + char *filename = (argc > 5) ? argv[5]: 0; + int avg = find_int_arg(argc, argv, "-avg", 1); + if(0==strcmp(argv[2], "test")) test_coco(cfg, weights, filename, thresh); + else if(0==strcmp(argv[2], "train")) train_coco(cfg, weights); + else if(0==strcmp(argv[2], "valid")) validate_coco(cfg, weights); + else if(0==strcmp(argv[2], "recall")) validate_coco_recall(cfg, weights); + else if(0==strcmp(argv[2], "demo")) demo(cfg, weights, thresh, cam_index, filename, coco_classes, 80, frame_skip, prefix, avg, .5, 0,0,0,0); +} diff --git a/hanzi_detection/examples/darknet.c b/hanzi_detection/examples/darknet.c new file mode 100755 index 0000000..d538359 --- /dev/null +++ b/hanzi_detection/examples/darknet.c @@ -0,0 +1,503 @@ +#include "darknet.h" + +#include +#include +#include + +extern void predict_classifier(char *datacfg, char *cfgfile, char *weightfile, char *filename, int top); +extern void test_detector(char *datacfg, char *cfgfile, char *weightfile, char *filename, float thresh, float hier_thresh, char *outfile, int fullscreen); +extern void run_yolo(int argc, char **argv); +extern void run_detector(int argc, char **argv); +extern void run_coco(int argc, char **argv); +extern void run_nightmare(int argc, char **argv); +extern void run_classifier(int argc, char **argv); +extern void run_regressor(int argc, char **argv); +extern void run_segmenter(int argc, char **argv); +extern void run_isegmenter(int argc, char **argv); +extern void run_char_rnn(int argc, char **argv); +extern void run_tag(int argc, char **argv); +extern void run_cifar(int argc, char **argv); +extern void run_go(int argc, char **argv); +extern void run_art(int argc, char **argv); +extern void run_super(int argc, char **argv); +extern void run_lsd(int argc, char **argv); + +void average(int argc, char *argv[]) +{ + char *cfgfile = argv[2]; + char *outfile = argv[3]; + gpu_index = -1; + network *net = parse_network_cfg(cfgfile); + network *sum = parse_network_cfg(cfgfile); + + char *weightfile = argv[4]; + load_weights(sum, weightfile); + + int i, j; + int n = argc - 5; + for(i = 0; i < n; ++i){ + weightfile = argv[i+5]; + load_weights(net, weightfile); + for(j = 0; j < net->n; ++j){ + layer l = net->layers[j]; + layer out = sum->layers[j]; + if(l.type == CONVOLUTIONAL){ + int num = l.n*l.c*l.size*l.size; + axpy_cpu(l.n, 1, l.biases, 1, out.biases, 1); + axpy_cpu(num, 1, l.weights, 1, out.weights, 1); + if(l.batch_normalize){ + axpy_cpu(l.n, 1, l.scales, 1, out.scales, 1); + axpy_cpu(l.n, 1, l.rolling_mean, 1, out.rolling_mean, 1); + axpy_cpu(l.n, 1, l.rolling_variance, 1, out.rolling_variance, 1); + } + } + if(l.type == CONNECTED){ + axpy_cpu(l.outputs, 1, l.biases, 1, out.biases, 1); + axpy_cpu(l.outputs*l.inputs, 1, l.weights, 1, out.weights, 1); + } + } + } + n = n+1; + for(j = 0; j < net->n; ++j){ + layer l = sum->layers[j]; + if(l.type == CONVOLUTIONAL){ + int num = l.n*l.c*l.size*l.size; + scal_cpu(l.n, 1./n, l.biases, 1); + scal_cpu(num, 1./n, l.weights, 1); + if(l.batch_normalize){ + scal_cpu(l.n, 1./n, l.scales, 1); + scal_cpu(l.n, 1./n, l.rolling_mean, 1); + scal_cpu(l.n, 1./n, l.rolling_variance, 1); + } + } + if(l.type == CONNECTED){ + scal_cpu(l.outputs, 1./n, l.biases, 1); + scal_cpu(l.outputs*l.inputs, 1./n, l.weights, 1); + } + } + save_weights(sum, outfile); +} + +long numops(network *net) +{ + int i; + long ops = 0; + for(i = 0; i < net->n; ++i){ + layer l = net->layers[i]; + if(l.type == CONVOLUTIONAL){ + ops += 2l * l.n * l.size*l.size*l.c/l.groups * l.out_h*l.out_w; + } else if(l.type == CONNECTED){ + ops += 2l * l.inputs * l.outputs; + } else if (l.type == RNN){ + ops += 2l * l.input_layer->inputs * l.input_layer->outputs; + ops += 2l * l.self_layer->inputs * l.self_layer->outputs; + ops += 2l * l.output_layer->inputs * l.output_layer->outputs; + } else if (l.type == GRU){ + ops += 2l * l.uz->inputs * l.uz->outputs; + ops += 2l * l.uh->inputs * l.uh->outputs; + ops += 2l * l.ur->inputs * l.ur->outputs; + ops += 2l * l.wz->inputs * l.wz->outputs; + ops += 2l * l.wh->inputs * l.wh->outputs; + ops += 2l * l.wr->inputs * l.wr->outputs; + } else if (l.type == LSTM){ + ops += 2l * l.uf->inputs * l.uf->outputs; + ops += 2l * l.ui->inputs * l.ui->outputs; + ops += 2l * l.ug->inputs * l.ug->outputs; + ops += 2l * l.uo->inputs * l.uo->outputs; + ops += 2l * l.wf->inputs * l.wf->outputs; + ops += 2l * l.wi->inputs * l.wi->outputs; + ops += 2l * l.wg->inputs * l.wg->outputs; + ops += 2l * l.wo->inputs * l.wo->outputs; + } + } + return ops; +} + +void speed(char *cfgfile, int tics) +{ + if (tics == 0) tics = 1000; + network *net = parse_network_cfg(cfgfile); + set_batch_network(net, 1); + int i; + double time=what_time_is_it_now(); + image im = make_image(net->w, net->h, net->c*net->batch); + for(i = 0; i < tics; ++i){ + network_predict(net, im.data); + } + double t = what_time_is_it_now() - time; + long ops = numops(net); + printf("\n%d evals, %f Seconds\n", tics, t); + printf("Floating Point Operations: %.2f Bn\n", (float)ops/1000000000.); + printf("FLOPS: %.2f Bn\n", (float)ops/1000000000.*tics/t); + printf("Speed: %f sec/eval\n", t/tics); + printf("Speed: %f Hz\n", tics/t); +} + +void operations(char *cfgfile) +{ + gpu_index = -1; + network *net = parse_network_cfg(cfgfile); + long ops = numops(net); + printf("Floating Point Operations: %ld\n", ops); + printf("Floating Point Operations: %.2f Bn\n", (float)ops/1000000000.); +} + +void oneoff(char *cfgfile, char *weightfile, char *outfile) +{ + gpu_index = -1; + network *net = parse_network_cfg(cfgfile); + int oldn = net->layers[net->n - 2].n; + int c = net->layers[net->n - 2].c; + scal_cpu(oldn*c, .1, net->layers[net->n - 2].weights, 1); + scal_cpu(oldn, 0, net->layers[net->n - 2].biases, 1); + net->layers[net->n - 2].n = 11921; + net->layers[net->n - 2].biases += 5; + net->layers[net->n - 2].weights += 5*c; + if(weightfile){ + load_weights(net, weightfile); + } + net->layers[net->n - 2].biases -= 5; + net->layers[net->n - 2].weights -= 5*c; + net->layers[net->n - 2].n = oldn; + printf("%d\n", oldn); + layer l = net->layers[net->n - 2]; + copy_cpu(l.n/3, l.biases, 1, l.biases + l.n/3, 1); + copy_cpu(l.n/3, l.biases, 1, l.biases + 2*l.n/3, 1); + copy_cpu(l.n/3*l.c, l.weights, 1, l.weights + l.n/3*l.c, 1); + copy_cpu(l.n/3*l.c, l.weights, 1, l.weights + 2*l.n/3*l.c, 1); + *net->seen = 0; + save_weights(net, outfile); +} + +void oneoff2(char *cfgfile, char *weightfile, char *outfile, int l) +{ + gpu_index = -1; + network *net = parse_network_cfg(cfgfile); + if(weightfile){ + load_weights_upto(net, weightfile, 0, net->n); + load_weights_upto(net, weightfile, l, net->n); + } + *net->seen = 0; + save_weights_upto(net, outfile, net->n); +} + +void partial(char *cfgfile, char *weightfile, char *outfile, int max) +{ + gpu_index = -1; + network *net = load_network(cfgfile, weightfile, 1); + save_weights_upto(net, outfile, max); +} + +void print_weights(char *cfgfile, char *weightfile, int n) +{ + gpu_index = -1; + network *net = load_network(cfgfile, weightfile, 1); + layer l = net->layers[n]; + int i, j; + //printf("["); + for(i = 0; i < l.n; ++i){ + //printf("["); + for(j = 0; j < l.size*l.size*l.c; ++j){ + //if(j > 0) printf(","); + printf("%g ", l.weights[i*l.size*l.size*l.c + j]); + } + printf("\n"); + //printf("]%s\n", (i == l.n-1)?"":","); + } + //printf("]"); +} + +void rescale_net(char *cfgfile, char *weightfile, char *outfile) +{ + gpu_index = -1; + network *net = load_network(cfgfile, weightfile, 0); + int i; + for(i = 0; i < net->n; ++i){ + layer l = net->layers[i]; + if(l.type == CONVOLUTIONAL){ + rescale_weights(l, 2, -.5); + break; + } + } + save_weights(net, outfile); +} + +void rgbgr_net(char *cfgfile, char *weightfile, char *outfile) +{ + gpu_index = -1; + network *net = load_network(cfgfile, weightfile, 0); + int i; + for(i = 0; i < net->n; ++i){ + layer l = net->layers[i]; + if(l.type == CONVOLUTIONAL){ + rgbgr_weights(l); + break; + } + } + save_weights(net, outfile); +} + +void reset_normalize_net(char *cfgfile, char *weightfile, char *outfile) +{ + gpu_index = -1; + network *net = load_network(cfgfile, weightfile, 0); + int i; + for (i = 0; i < net->n; ++i) { + layer l = net->layers[i]; + if (l.type == CONVOLUTIONAL && l.batch_normalize) { + denormalize_convolutional_layer(l); + } + if (l.type == CONNECTED && l.batch_normalize) { + denormalize_connected_layer(l); + } + if (l.type == GRU && l.batch_normalize) { + denormalize_connected_layer(*l.input_z_layer); + denormalize_connected_layer(*l.input_r_layer); + denormalize_connected_layer(*l.input_h_layer); + denormalize_connected_layer(*l.state_z_layer); + denormalize_connected_layer(*l.state_r_layer); + denormalize_connected_layer(*l.state_h_layer); + } + } + save_weights(net, outfile); +} + +layer normalize_layer(layer l, int n) +{ + int j; + l.batch_normalize=1; + l.scales = calloc(n, sizeof(float)); + for(j = 0; j < n; ++j){ + l.scales[j] = 1; + } + l.rolling_mean = calloc(n, sizeof(float)); + l.rolling_variance = calloc(n, sizeof(float)); + return l; +} + +void normalize_net(char *cfgfile, char *weightfile, char *outfile) +{ + gpu_index = -1; + network *net = load_network(cfgfile, weightfile, 0); + int i; + for(i = 0; i < net->n; ++i){ + layer l = net->layers[i]; + if(l.type == CONVOLUTIONAL && !l.batch_normalize){ + net->layers[i] = normalize_layer(l, l.n); + } + if (l.type == CONNECTED && !l.batch_normalize) { + net->layers[i] = normalize_layer(l, l.outputs); + } + if (l.type == GRU && l.batch_normalize) { + *l.input_z_layer = normalize_layer(*l.input_z_layer, l.input_z_layer->outputs); + *l.input_r_layer = normalize_layer(*l.input_r_layer, l.input_r_layer->outputs); + *l.input_h_layer = normalize_layer(*l.input_h_layer, l.input_h_layer->outputs); + *l.state_z_layer = normalize_layer(*l.state_z_layer, l.state_z_layer->outputs); + *l.state_r_layer = normalize_layer(*l.state_r_layer, l.state_r_layer->outputs); + *l.state_h_layer = normalize_layer(*l.state_h_layer, l.state_h_layer->outputs); + net->layers[i].batch_normalize=1; + } + } + save_weights(net, outfile); +} + +void statistics_net(char *cfgfile, char *weightfile) +{ + gpu_index = -1; + network *net = load_network(cfgfile, weightfile, 0); + int i; + for (i = 0; i < net->n; ++i) { + layer l = net->layers[i]; + if (l.type == CONNECTED && l.batch_normalize) { + printf("Connected Layer %d\n", i); + statistics_connected_layer(l); + } + if (l.type == GRU && l.batch_normalize) { + printf("GRU Layer %d\n", i); + printf("Input Z\n"); + statistics_connected_layer(*l.input_z_layer); + printf("Input R\n"); + statistics_connected_layer(*l.input_r_layer); + printf("Input H\n"); + statistics_connected_layer(*l.input_h_layer); + printf("State Z\n"); + statistics_connected_layer(*l.state_z_layer); + printf("State R\n"); + statistics_connected_layer(*l.state_r_layer); + printf("State H\n"); + statistics_connected_layer(*l.state_h_layer); + } + printf("\n"); + } +} + +void denormalize_net(char *cfgfile, char *weightfile, char *outfile) +{ + gpu_index = -1; + network *net = load_network(cfgfile, weightfile, 0); + int i; + for (i = 0; i < net->n; ++i) { + layer l = net->layers[i]; + if ((l.type == DECONVOLUTIONAL || l.type == CONVOLUTIONAL) && l.batch_normalize) { + denormalize_convolutional_layer(l); + net->layers[i].batch_normalize=0; + } + if (l.type == CONNECTED && l.batch_normalize) { + denormalize_connected_layer(l); + net->layers[i].batch_normalize=0; + } + if (l.type == GRU && l.batch_normalize) { + denormalize_connected_layer(*l.input_z_layer); + denormalize_connected_layer(*l.input_r_layer); + denormalize_connected_layer(*l.input_h_layer); + denormalize_connected_layer(*l.state_z_layer); + denormalize_connected_layer(*l.state_r_layer); + denormalize_connected_layer(*l.state_h_layer); + l.input_z_layer->batch_normalize = 0; + l.input_r_layer->batch_normalize = 0; + l.input_h_layer->batch_normalize = 0; + l.state_z_layer->batch_normalize = 0; + l.state_r_layer->batch_normalize = 0; + l.state_h_layer->batch_normalize = 0; + net->layers[i].batch_normalize=0; + } + } + save_weights(net, outfile); +} + +void mkimg(char *cfgfile, char *weightfile, int h, int w, int num, char *prefix) +{ + network *net = load_network(cfgfile, weightfile, 0); + image *ims = get_weights(net->layers[0]); + int n = net->layers[0].n; + int z; + for(z = 0; z < num; ++z){ + image im = make_image(h, w, 3); + fill_image(im, .5); + int i; + for(i = 0; i < 100; ++i){ + image r = copy_image(ims[rand()%n]); + rotate_image_cw(r, rand()%4); + random_distort_image(r, 1, 1.5, 1.5); + int dx = rand()%(w-r.w); + int dy = rand()%(h-r.h); + ghost_image(r, im, dx, dy); + free_image(r); + } + char buff[256]; + sprintf(buff, "%s/gen_%d", prefix, z); + save_image(im, buff); + free_image(im); + } +} + +void visualize(char *cfgfile, char *weightfile) +{ + network *net = load_network(cfgfile, weightfile, 0); + visualize_network(net); +} + +int main(int argc, char **argv) +{ + //test_resize("data/bad.jpg"); + //test_box(); + //test_convolutional_layer(); + if(argc < 2){ + fprintf(stderr, "usage: %s \n", argv[0]); + return 0; + } + gpu_index = find_int_arg(argc, argv, "-i", 0); + if(find_arg(argc, argv, "-nogpu")) { + gpu_index = -1; + } + +#ifndef GPU + gpu_index = -1; +#else + if(gpu_index >= 0){ + cuda_set_device(gpu_index); + } +#endif + + if (0 == strcmp(argv[1], "average")){ + average(argc, argv); + } else if (0 == strcmp(argv[1], "yolo")){ + run_yolo(argc, argv); + } else if (0 == strcmp(argv[1], "super")){ + run_super(argc, argv); + } else if (0 == strcmp(argv[1], "lsd")){ + run_lsd(argc, argv); + } else if (0 == strcmp(argv[1], "detector")){ + run_detector(argc, argv); + } else if (0 == strcmp(argv[1], "detect")){ + float thresh = find_float_arg(argc, argv, "-thresh", .5); + char *filename = (argc > 4) ? argv[4]: 0; + char *outfile = find_char_arg(argc, argv, "-out", 0); + int fullscreen = find_arg(argc, argv, "-fullscreen"); + test_detector("cfg/coco.data", argv[2], argv[3], filename, thresh, .5, outfile, fullscreen); + } else if (0 == strcmp(argv[1], "cifar")){ + run_cifar(argc, argv); + } else if (0 == strcmp(argv[1], "go")){ + run_go(argc, argv); + } else if (0 == strcmp(argv[1], "rnn")){ + run_char_rnn(argc, argv); + } else if (0 == strcmp(argv[1], "coco")){ + run_coco(argc, argv); + } else if (0 == strcmp(argv[1], "classify")){ + predict_classifier("cfg/imagenet1k.data", argv[2], argv[3], argv[4], 5); + } else if (0 == strcmp(argv[1], "classifier")){ + run_classifier(argc, argv); + } else if (0 == strcmp(argv[1], "regressor")){ + run_regressor(argc, argv); + } else if (0 == strcmp(argv[1], "isegmenter")){ + run_isegmenter(argc, argv); + } else if (0 == strcmp(argv[1], "segmenter")){ + run_segmenter(argc, argv); + } else if (0 == strcmp(argv[1], "art")){ + run_art(argc, argv); + } else if (0 == strcmp(argv[1], "tag")){ + run_tag(argc, argv); + } else if (0 == strcmp(argv[1], "3d")){ + composite_3d(argv[2], argv[3], argv[4], (argc > 5) ? atof(argv[5]) : 0); + } else if (0 == strcmp(argv[1], "test")){ + test_resize(argv[2]); + } else if (0 == strcmp(argv[1], "nightmare")){ + run_nightmare(argc, argv); + } else if (0 == strcmp(argv[1], "rgbgr")){ + rgbgr_net(argv[2], argv[3], argv[4]); + } else if (0 == strcmp(argv[1], "reset")){ + reset_normalize_net(argv[2], argv[3], argv[4]); + } else if (0 == strcmp(argv[1], "denormalize")){ + denormalize_net(argv[2], argv[3], argv[4]); + } else if (0 == strcmp(argv[1], "statistics")){ + statistics_net(argv[2], argv[3]); + } else if (0 == strcmp(argv[1], "normalize")){ + normalize_net(argv[2], argv[3], argv[4]); + } else if (0 == strcmp(argv[1], "rescale")){ + rescale_net(argv[2], argv[3], argv[4]); + } else if (0 == strcmp(argv[1], "ops")){ + operations(argv[2]); + } else if (0 == strcmp(argv[1], "speed")){ + speed(argv[2], (argc > 3 && argv[3]) ? atoi(argv[3]) : 0); + } else if (0 == strcmp(argv[1], "oneoff")){ + oneoff(argv[2], argv[3], argv[4]); + } else if (0 == strcmp(argv[1], "oneoff2")){ + oneoff2(argv[2], argv[3], argv[4], atoi(argv[5])); + } else if (0 == strcmp(argv[1], "print")){ + print_weights(argv[2], argv[3], atoi(argv[4])); + } else if (0 == strcmp(argv[1], "partial")){ + partial(argv[2], argv[3], argv[4], atoi(argv[5])); + } else if (0 == strcmp(argv[1], "average")){ + average(argc, argv); + } else if (0 == strcmp(argv[1], "visualize")){ + visualize(argv[2], (argc > 3) ? argv[3] : 0); + } else if (0 == strcmp(argv[1], "mkimg")){ + mkimg(argv[2], argv[3], atoi(argv[4]), atoi(argv[5]), atoi(argv[6]), argv[7]); + } else if (0 == strcmp(argv[1], "imtest")){ + test_resize(argv[2]); + } else { + fprintf(stderr, "Not an option: %s\n", argv[1]); + } + return 0; +} + diff --git a/hanzi_detection/examples/detector-scipy-opencv.py b/hanzi_detection/examples/detector-scipy-opencv.py new file mode 100755 index 0000000..684d6e1 --- /dev/null +++ b/hanzi_detection/examples/detector-scipy-opencv.py @@ -0,0 +1,56 @@ +# Stupid python path shit. +# Instead just add darknet.py to somewhere in your python path +# OK actually that might not be a great idea, idk, work in progress +# Use at your own risk. or don't, i don't care + +from scipy.misc import imread +import cv2 + +def array_to_image(arr): + arr = arr.transpose(2,0,1) + c = arr.shape[0] + h = arr.shape[1] + w = arr.shape[2] + arr = (arr/255.0).flatten() + data = dn.c_array(dn.c_float, arr) + im = dn.IMAGE(w,h,c,data) + return im + +def detect2(net, meta, image, thresh=.5, hier_thresh=.5, nms=.45): + boxes = dn.make_boxes(net) + probs = dn.make_probs(net) + num = dn.num_boxes(net) + dn.network_detect(net, image, thresh, hier_thresh, nms, boxes, probs) + res = [] + for j in range(num): + for i in range(meta.classes): + if probs[j][i] > 0: + res.append((meta.names[i], probs[j][i], (boxes[j].x, boxes[j].y, boxes[j].w, boxes[j].h))) + res = sorted(res, key=lambda x: -x[1]) + dn.free_ptrs(dn.cast(probs, dn.POINTER(dn.c_void_p)), num) + return res + +import sys, os +sys.path.append(os.path.join(os.getcwd(),'python/')) + +import nine as dn + +# Darknet +net = dn.load_net("cfg/tiny-yolo.cfg", "tiny-yolo.weights", 0) +meta = dn.load_meta("cfg/coco.data") +r = dn.detect(net, meta, "data/dog.jpg") +print r + +# scipy +arr= imread('data/dog.jpg') +im = array_to_image(arr) +r = detect2(net, meta, im) +print r + +# OpenCV +arr = cv2.imread('data/dog.jpg') +im = array_to_image(arr) +dn.rgbgr_image(im) +r = detect2(net, meta, im) +print r + diff --git a/hanzi_detection/examples/detector.c b/hanzi_detection/examples/detector.c new file mode 100755 index 0000000..318f7fb --- /dev/null +++ b/hanzi_detection/examples/detector.c @@ -0,0 +1,850 @@ +#include "darknet.h" + +static int coco_ids[] = {1,2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19,20,21,22,23,24,25,27,28,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,67,70,72,73,74,75,76,77,78,79,80,81,82,84,85,86,87,88,89,90}; + + +void train_detector(char *datacfg, char *cfgfile, char *weightfile, int *gpus, int ngpus, int clear) +{ + list *options = read_data_cfg(datacfg); + char *train_images = option_find_str(options, "train", "data/train.list"); + char *backup_directory = option_find_str(options, "backup", "/backup/"); + + srand(time(0)); + char *base = basecfg(cfgfile); + printf("%s\n", base); + float avg_loss = -1; + network **nets = calloc(ngpus, sizeof(network)); + + srand(time(0)); + int seed = rand(); + int i; + for(i = 0; i < ngpus; ++i){ + srand(seed); +#ifdef GPU + cuda_set_device(gpus[i]); +#endif + nets[i] = load_network(cfgfile, weightfile, clear); + nets[i]->learning_rate *= ngpus; + } + srand(time(0)); + network *net = nets[0]; + + int imgs = net->batch * net->subdivisions * ngpus; + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + data train, buffer; + + layer l = net->layers[net->n - 1]; + + int classes = l.classes; + float jitter = l.jitter; + + list *plist = get_paths(train_images); + //int N = plist->size; + char **paths = (char **)list_to_array(plist); + + load_args args = get_base_args(net); + args.coords = l.coords; + args.paths = paths; + args.n = imgs; + args.m = plist->size; + args.classes = classes; + args.jitter = jitter; + args.num_boxes = l.max_boxes; + args.d = &buffer; + args.type = DETECTION_DATA; + //args.type = INSTANCE_DATA; + args.threads = 64; + + pthread_t load_thread = load_data(args); + double time; + int count = 0; + //while(i*imgs < N*120){ + while(get_current_batch(net) < net->max_batches){ + if(l.random && count++%10 == 0){ + printf("Resizing\n"); + int dim = (rand() % 10 + 10) * 32; + if (get_current_batch(net)+200 > net->max_batches) dim = 608; + //int dim = (rand() % 4 + 16) * 32; + printf("%d\n", dim); + args.w = dim; + args.h = dim; + + pthread_join(load_thread, 0); + train = buffer; + free_data(train); + load_thread = load_data(args); + + #pragma omp parallel for + for(i = 0; i < ngpus; ++i){ + resize_network(nets[i], dim, dim); + } + net = nets[0]; + } + time=what_time_is_it_now(); + pthread_join(load_thread, 0); + train = buffer; + load_thread = load_data(args); + + /* + int k; + for(k = 0; k < l.max_boxes; ++k){ + box b = float_to_box(train.y.vals[10] + 1 + k*5); + if(!b.x) break; + printf("loaded: %f %f %f %f\n", b.x, b.y, b.w, b.h); + } + */ + /* + int zz; + for(zz = 0; zz < train.X.cols; ++zz){ + image im = float_to_image(net->w, net->h, 3, train.X.vals[zz]); + int k; + for(k = 0; k < l.max_boxes; ++k){ + box b = float_to_box(train.y.vals[zz] + k*5, 1); + printf("%f %f %f %f\n", b.x, b.y, b.w, b.h); + draw_bbox(im, b, 1, 1,0,0); + } + show_image(im, "truth11"); + cvWaitKey(0); + save_image(im, "truth11"); + } + */ + + printf("Loaded: %lf seconds\n", what_time_is_it_now()-time); + + time=what_time_is_it_now(); + float loss = 0; +#ifdef GPU + if(ngpus == 1){ + loss = train_network(net, train); + } else { + loss = train_networks(nets, ngpus, train, 4); + } +#else + loss = train_network(net, train); +#endif + if (avg_loss < 0) avg_loss = loss; + avg_loss = avg_loss*.9 + loss*.1; + + i = get_current_batch(net); + printf("%ld: %f, %f avg, %f rate, %lf seconds, %d images\n", get_current_batch(net), loss, avg_loss, get_current_rate(net), what_time_is_it_now()-time, i*imgs); + if(i%100==0){ +#ifdef GPU + if(ngpus != 1) sync_nets(nets, ngpus, 0); +#endif + char buff[256]; + sprintf(buff, "%s/%s.backup", backup_directory, base); + save_weights(net, buff); + } + if(i%10000==0 || (i < 1000 && i%100 == 0)){ +#ifdef GPU + if(ngpus != 1) sync_nets(nets, ngpus, 0); +#endif + char buff[256]; + sprintf(buff, "%s/%s_%d.weights", backup_directory, base, i); + save_weights(net, buff); + } + free_data(train); + } +#ifdef GPU + if(ngpus != 1) sync_nets(nets, ngpus, 0); +#endif + char buff[256]; + sprintf(buff, "%s/%s_final.weights", backup_directory, base); + save_weights(net, buff); +} + + +static int get_coco_image_id(char *filename) +{ + char *p = strrchr(filename, '/'); + char *c = strrchr(filename, '_'); + if(c) p = c; + return atoi(p+1); +} + +static void print_cocos(FILE *fp, char *image_path, detection *dets, int num_boxes, int classes, int w, int h) +{ + int i, j; + int image_id = get_coco_image_id(image_path); + for(i = 0; i < num_boxes; ++i){ + float xmin = dets[i].bbox.x - dets[i].bbox.w/2.; + float xmax = dets[i].bbox.x + dets[i].bbox.w/2.; + float ymin = dets[i].bbox.y - dets[i].bbox.h/2.; + float ymax = dets[i].bbox.y + dets[i].bbox.h/2.; + + if (xmin < 0) xmin = 0; + if (ymin < 0) ymin = 0; + if (xmax > w) xmax = w; + if (ymax > h) ymax = h; + + float bx = xmin; + float by = ymin; + float bw = xmax - xmin; + float bh = ymax - ymin; + + for(j = 0; j < classes; ++j){ + if (dets[i].prob[j]) fprintf(fp, "{\"image_id\":%d, \"category_id\":%d, \"bbox\":[%f, %f, %f, %f], \"score\":%f},\n", image_id, coco_ids[j], bx, by, bw, bh, dets[i].prob[j]); + } + } +} + +void print_detector_detections(FILE **fps, char *id, detection *dets, int total, int classes, int w, int h) +{ + int i, j; + for(i = 0; i < total; ++i){ + float xmin = dets[i].bbox.x - dets[i].bbox.w/2. + 1; + float xmax = dets[i].bbox.x + dets[i].bbox.w/2. + 1; + float ymin = dets[i].bbox.y - dets[i].bbox.h/2. + 1; + float ymax = dets[i].bbox.y + dets[i].bbox.h/2. + 1; + + if (xmin < 1) xmin = 1; + if (ymin < 1) ymin = 1; + if (xmax > w) xmax = w; + if (ymax > h) ymax = h; + + for(j = 0; j < classes; ++j){ + if (dets[i].prob[j]) fprintf(fps[j], "%s %f %f %f %f %f\n", id, dets[i].prob[j], + xmin, ymin, xmax, ymax); + } + } +} + +void print_imagenet_detections(FILE *fp, int id, detection *dets, int total, int classes, int w, int h) +{ + int i, j; + for(i = 0; i < total; ++i){ + float xmin = dets[i].bbox.x - dets[i].bbox.w/2.; + float xmax = dets[i].bbox.x + dets[i].bbox.w/2.; + float ymin = dets[i].bbox.y - dets[i].bbox.h/2.; + float ymax = dets[i].bbox.y + dets[i].bbox.h/2.; + + if (xmin < 0) xmin = 0; + if (ymin < 0) ymin = 0; + if (xmax > w) xmax = w; + if (ymax > h) ymax = h; + + for(j = 0; j < classes; ++j){ + int class = j; + if (dets[i].prob[class]) fprintf(fp, "%d %d %f %f %f %f %f\n", id, j+1, dets[i].prob[class], + xmin, ymin, xmax, ymax); + } + } +} + +void validate_detector_flip(char *datacfg, char *cfgfile, char *weightfile, char *outfile) +{ + int j; + list *options = read_data_cfg(datacfg); + char *valid_images = option_find_str(options, "valid", "data/train.list"); + char *name_list = option_find_str(options, "names", "data/names.list"); + char *prefix = option_find_str(options, "results", "results"); + char **names = get_labels(name_list); + char *mapf = option_find_str(options, "map", 0); + int *map = 0; + if (mapf) map = read_map(mapf); + + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 2); + fprintf(stderr, "Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + srand(time(0)); + + list *plist = get_paths(valid_images); + char **paths = (char **)list_to_array(plist); + + layer l = net->layers[net->n-1]; + int classes = l.classes; + + char buff[1024]; + char *type = option_find_str(options, "eval", "voc"); + FILE *fp = 0; + FILE **fps = 0; + int coco = 0; + int imagenet = 0; + if(0==strcmp(type, "coco")){ + if(!outfile) outfile = "coco_results"; + snprintf(buff, 1024, "%s/%s.json", prefix, outfile); + fp = fopen(buff, "w"); + fprintf(fp, "[\n"); + coco = 1; + } else if(0==strcmp(type, "imagenet")){ + if(!outfile) outfile = "imagenet-detection"; + snprintf(buff, 1024, "%s/%s.txt", prefix, outfile); + fp = fopen(buff, "w"); + imagenet = 1; + classes = 200; + } else { + if(!outfile) outfile = "comp4_det_test_"; + fps = calloc(classes, sizeof(FILE *)); + for(j = 0; j < classes; ++j){ + snprintf(buff, 1024, "%s/%s%s.txt", prefix, outfile, names[j]); + fps[j] = fopen(buff, "w"); + } + } + + int m = plist->size; + int i=0; + int t; + + float thresh = .005; + float nms = .45; + + int nthreads = 4; + image *val = calloc(nthreads, sizeof(image)); + image *val_resized = calloc(nthreads, sizeof(image)); + image *buf = calloc(nthreads, sizeof(image)); + image *buf_resized = calloc(nthreads, sizeof(image)); + pthread_t *thr = calloc(nthreads, sizeof(pthread_t)); + + image input = make_image(net->w, net->h, net->c*2); + + load_args args = {0}; + args.w = net->w; + args.h = net->h; + //args.type = IMAGE_DATA; + args.type = LETTERBOX_DATA; + + for(t = 0; t < nthreads; ++t){ + args.path = paths[i+t]; + args.im = &buf[t]; + args.resized = &buf_resized[t]; + thr[t] = load_data_in_thread(args); + } + double start = what_time_is_it_now(); + for(i = nthreads; i < m+nthreads; i += nthreads){ + fprintf(stderr, "%d\n", i); + for(t = 0; t < nthreads && i+t-nthreads < m; ++t){ + pthread_join(thr[t], 0); + val[t] = buf[t]; + val_resized[t] = buf_resized[t]; + } + for(t = 0; t < nthreads && i+t < m; ++t){ + args.path = paths[i+t]; + args.im = &buf[t]; + args.resized = &buf_resized[t]; + thr[t] = load_data_in_thread(args); + } + for(t = 0; t < nthreads && i+t-nthreads < m; ++t){ + char *path = paths[i+t-nthreads]; + char *id = basecfg(path); + copy_cpu(net->w*net->h*net->c, val_resized[t].data, 1, input.data, 1); + flip_image(val_resized[t]); + copy_cpu(net->w*net->h*net->c, val_resized[t].data, 1, input.data + net->w*net->h*net->c, 1); + + network_predict(net, input.data); + int w = val[t].w; + int h = val[t].h; + int num = 0; + detection *dets = get_network_boxes(net, w, h, thresh, .5, map, 0, &num); + if (nms) do_nms_sort(dets, num, classes, nms); + if (coco){ + print_cocos(fp, path, dets, num, classes, w, h); + } else if (imagenet){ + print_imagenet_detections(fp, i+t-nthreads+1, dets, num, classes, w, h); + } else { + print_detector_detections(fps, id, dets, num, classes, w, h); + } + free_detections(dets, num); + free(id); + free_image(val[t]); + free_image(val_resized[t]); + } + } + for(j = 0; j < classes; ++j){ + if(fps) fclose(fps[j]); + } + if(coco){ + fseek(fp, -2, SEEK_CUR); + fprintf(fp, "\n]\n"); + fclose(fp); + } + fprintf(stderr, "Total Detection Time: %f Seconds\n", what_time_is_it_now() - start); +} + + +void validate_detector(char *datacfg, char *cfgfile, char *weightfile, char *outfile) +{ + int j; + list *options = read_data_cfg(datacfg); + char *valid_images = option_find_str(options, "valid", "data/train.list"); + char *name_list = option_find_str(options, "names", "data/names.list"); + char *prefix = option_find_str(options, "results", "results"); + char **names = get_labels(name_list); + char *mapf = option_find_str(options, "map", 0); + int *map = 0; + if (mapf) map = read_map(mapf); + + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + fprintf(stderr, "Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + srand(time(0)); + + list *plist = get_paths(valid_images); + char **paths = (char **)list_to_array(plist); + + layer l = net->layers[net->n-1]; + int classes = l.classes; + + char buff[1024]; + char *type = option_find_str(options, "eval", "voc"); + FILE *fp = 0; + FILE **fps = 0; + int coco = 0; + int imagenet = 0; + if(0==strcmp(type, "coco")){ + if(!outfile) outfile = "coco_results"; + snprintf(buff, 1024, "%s/%s.json", prefix, outfile); + fp = fopen(buff, "w"); + fprintf(fp, "[\n"); + coco = 1; + } else if(0==strcmp(type, "imagenet")){ + if(!outfile) outfile = "imagenet-detection"; + snprintf(buff, 1024, "%s/%s.txt", prefix, outfile); + fp = fopen(buff, "w"); + imagenet = 1; + classes = 200; + } else { + if(!outfile) outfile = "comp4_det_test_"; + fps = calloc(classes, sizeof(FILE *)); + for(j = 0; j < classes; ++j){ + snprintf(buff, 1024, "%s/%s%s.txt", prefix, outfile, names[j]); + fps[j] = fopen(buff, "w"); + } + } + + + int m = plist->size; + int i=0; + int t; + + float thresh = .005; + float nms = .45; + + int nthreads = 4; + image *val = calloc(nthreads, sizeof(image)); + image *val_resized = calloc(nthreads, sizeof(image)); + image *buf = calloc(nthreads, sizeof(image)); + image *buf_resized = calloc(nthreads, sizeof(image)); + pthread_t *thr = calloc(nthreads, sizeof(pthread_t)); + + load_args args = {0}; + args.w = net->w; + args.h = net->h; + //args.type = IMAGE_DATA; + args.type = LETTERBOX_DATA; + + for(t = 0; t < nthreads; ++t){ + args.path = paths[i+t]; + args.im = &buf[t]; + args.resized = &buf_resized[t]; + thr[t] = load_data_in_thread(args); + } + double start = what_time_is_it_now(); + for(i = nthreads; i < m+nthreads; i += nthreads){ + fprintf(stderr, "%d\n", i); + for(t = 0; t < nthreads && i+t-nthreads < m; ++t){ + pthread_join(thr[t], 0); + val[t] = buf[t]; + val_resized[t] = buf_resized[t]; + } + for(t = 0; t < nthreads && i+t < m; ++t){ + args.path = paths[i+t]; + args.im = &buf[t]; + args.resized = &buf_resized[t]; + thr[t] = load_data_in_thread(args); + } + for(t = 0; t < nthreads && i+t-nthreads < m; ++t){ + char *path = paths[i+t-nthreads]; + char *id = basecfg(path); + float *X = val_resized[t].data; + network_predict(net, X); + int w = val[t].w; + int h = val[t].h; + int nboxes = 0; + detection *dets = get_network_boxes(net, w, h, thresh, .5, map, 0, &nboxes); + if (nms) do_nms_sort(dets, nboxes, classes, nms); + if (coco){ + print_cocos(fp, path, dets, nboxes, classes, w, h); + } else if (imagenet){ + print_imagenet_detections(fp, i+t-nthreads+1, dets, nboxes, classes, w, h); + } else { + print_detector_detections(fps, id, dets, nboxes, classes, w, h); + } + free_detections(dets, nboxes); + free(id); + free_image(val[t]); + free_image(val_resized[t]); + } + } + for(j = 0; j < classes; ++j){ + if(fps) fclose(fps[j]); + } + if(coco){ + fseek(fp, -2, SEEK_CUR); + fprintf(fp, "\n]\n"); + fclose(fp); + } + fprintf(stderr, "Total Detection Time: %f Seconds\n", what_time_is_it_now() - start); +} + +void validate_detector_recall(char *cfgfile, char *weightfile) +{ + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + fprintf(stderr, "Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + srand(time(0)); + + list *plist = get_paths("data/coco_val_5k.list"); + char **paths = (char **)list_to_array(plist); + + layer l = net->layers[net->n-1]; + + int j, k; + + int m = plist->size; + int i=0; + + float thresh = .001; + float iou_thresh = .5; + float nms = .4; + + int total = 0; + int correct = 0; + int proposals = 0; + float avg_iou = 0; + + for(i = 0; i < m; ++i){ + char *path = paths[i]; + image orig = load_image_color(path, 0, 0); + image sized = resize_image(orig, net->w, net->h); + char *id = basecfg(path); + network_predict(net, sized.data); + int nboxes = 0; + detection *dets = get_network_boxes(net, sized.w, sized.h, thresh, .5, 0, 1, &nboxes); + if (nms) do_nms_obj(dets, nboxes, 1, nms); + + char labelpath[4096]; + find_replace(path, "images", "labels", labelpath); + find_replace(labelpath, "JPEGImages", "labels", labelpath); + find_replace(labelpath, ".jpg", ".txt", labelpath); + find_replace(labelpath, ".JPEG", ".txt", labelpath); + + int num_labels = 0; + box_label *truth = read_boxes(labelpath, &num_labels); + for(k = 0; k < nboxes; ++k){ + if(dets[k].objectness > thresh){ + ++proposals; + } + } + for (j = 0; j < num_labels; ++j) { + ++total; + box t = {truth[j].x, truth[j].y, truth[j].w, truth[j].h}; + float best_iou = 0; + for(k = 0; k < l.w*l.h*l.n; ++k){ + float iou = box_iou(dets[k].bbox, t); + if(dets[k].objectness > thresh && iou > best_iou){ + best_iou = iou; + } + } + avg_iou += best_iou; + if(best_iou > iou_thresh){ + ++correct; + } + } + + fprintf(stderr, "%5d %5d %5d\tRPs/Img: %.2f\tIOU: %.2f%%\tRecall:%.2f%%\n", i, correct, total, (float)proposals/(i+1), avg_iou*100/total, 100.*correct/total); + free(id); + free_image(orig); + free_image(sized); + } +} + + +void test_detector(char *datacfg, char *cfgfile, char *weightfile, char *filename, float thresh, float hier_thresh, char *outfile, int fullscreen) +{ + list *options = read_data_cfg(datacfg); + char *name_list = option_find_str(options, "names", "data/names.list"); + char **names = get_labels(name_list); + + image **alphabet = load_alphabet(); + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + srand(2222222); + double time; + char buff[256]; + char *input = buff; + float nms=.45; + while(1){ + if(filename){ + strncpy(input, filename, 256); + } else { + printf("Enter Image Path: "); + fflush(stdout); + input = fgets(input, 256, stdin); + if(!input) return; + strtok(input, "\n"); + } + image im = load_image_color(input,0,0); + image sized = letterbox_image(im, net->w, net->h); + //image sized = resize_image(im, net->w, net->h); + //image sized2 = resize_max(im, net->w); + //image sized = crop_image(sized2, -((net->w - sized2.w)/2), -((net->h - sized2.h)/2), net->w, net->h); + //resize_network(net, sized.w, sized.h); + layer l = net->layers[net->n-1]; + + + float *X = sized.data; + time=what_time_is_it_now(); + network_predict(net, X); + printf("%s: Predicted in %f seconds.\n", input, what_time_is_it_now()-time); + int nboxes = 0; + detection *dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes); + //printf("%d\n", nboxes); + //if (nms) do_nms_obj(boxes, probs, l.w*l.h*l.n, l.classes, nms); + if (nms) do_nms_sort(dets, nboxes, l.classes, nms); + draw_detections(im, dets, nboxes, thresh, names, alphabet, l.classes); + free_detections(dets, nboxes); + if(outfile){ + save_image(im, outfile); + } + else{ + save_image(im, "predictions"); +#ifdef OPENCV + make_window("predictions", 512, 512, 0); + show_image(im, "predictions", 0); +#endif + } + + free_image(im); + free_image(sized); + if (filename) break; + } +} + +/* +void censor_detector(char *datacfg, char *cfgfile, char *weightfile, int cam_index, const char *filename, int class, float thresh, int skip) +{ +#ifdef OPENCV + char *base = basecfg(cfgfile); + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + + srand(2222222); + CvCapture * cap; + + int w = 1280; + int h = 720; + + if(filename){ + cap = cvCaptureFromFile(filename); + }else{ + cap = cvCaptureFromCAM(cam_index); + } + + if(w){ + cvSetCaptureProperty(cap, CV_CAP_PROP_FRAME_WIDTH, w); + } + if(h){ + cvSetCaptureProperty(cap, CV_CAP_PROP_FRAME_HEIGHT, h); + } + + if(!cap) error("Couldn't connect to webcam.\n"); + cvNamedWindow(base, CV_WINDOW_NORMAL); + cvResizeWindow(base, 512, 512); + float fps = 0; + int i; + float nms = .45; + + while(1){ + image in = get_image_from_stream(cap); + //image in_s = resize_image(in, net->w, net->h); + image in_s = letterbox_image(in, net->w, net->h); + layer l = net->layers[net->n-1]; + + float *X = in_s.data; + network_predict(net, X); + int nboxes = 0; + detection *dets = get_network_boxes(net, in.w, in.h, thresh, 0, 0, 0, &nboxes); + //if (nms) do_nms_obj(boxes, probs, l.w*l.h*l.n, l.classes, nms); + if (nms) do_nms_sort(dets, nboxes, l.classes, nms); + + for(i = 0; i < nboxes; ++i){ + if(dets[i].prob[class] > thresh){ + box b = dets[i].bbox; + int left = b.x-b.w/2.; + int top = b.y-b.h/2.; + censor_image(in, left, top, b.w, b.h); + } + } + show_image(in, base); + cvWaitKey(10); + free_detections(dets, nboxes); + + + free_image(in_s); + free_image(in); + + + float curr = 0; + fps = .9*fps + .1*curr; + for(i = 0; i < skip; ++i){ + image in = get_image_from_stream(cap); + free_image(in); + } + } + #endif +} + +void extract_detector(char *datacfg, char *cfgfile, char *weightfile, int cam_index, const char *filename, int class, float thresh, int skip) +{ +#ifdef OPENCV + char *base = basecfg(cfgfile); + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + + srand(2222222); + CvCapture * cap; + + int w = 1280; + int h = 720; + + if(filename){ + cap = cvCaptureFromFile(filename); + }else{ + cap = cvCaptureFromCAM(cam_index); + } + + if(w){ + cvSetCaptureProperty(cap, CV_CAP_PROP_FRAME_WIDTH, w); + } + if(h){ + cvSetCaptureProperty(cap, CV_CAP_PROP_FRAME_HEIGHT, h); + } + + if(!cap) error("Couldn't connect to webcam.\n"); + cvNamedWindow(base, CV_WINDOW_NORMAL); + cvResizeWindow(base, 512, 512); + float fps = 0; + int i; + int count = 0; + float nms = .45; + + while(1){ + image in = get_image_from_stream(cap); + //image in_s = resize_image(in, net->w, net->h); + image in_s = letterbox_image(in, net->w, net->h); + layer l = net->layers[net->n-1]; + + show_image(in, base); + + int nboxes = 0; + float *X = in_s.data; + network_predict(net, X); + detection *dets = get_network_boxes(net, in.w, in.h, thresh, 0, 0, 1, &nboxes); + //if (nms) do_nms_obj(boxes, probs, l.w*l.h*l.n, l.classes, nms); + if (nms) do_nms_sort(dets, nboxes, l.classes, nms); + + for(i = 0; i < nboxes; ++i){ + if(dets[i].prob[class] > thresh){ + box b = dets[i].bbox; + int size = b.w*in.w > b.h*in.h ? b.w*in.w : b.h*in.h; + int dx = b.x*in.w-size/2.; + int dy = b.y*in.h-size/2.; + image bim = crop_image(in, dx, dy, size, size); + char buff[2048]; + sprintf(buff, "results/extract/%07d", count); + ++count; + save_image(bim, buff); + free_image(bim); + } + } + free_detections(dets, nboxes); + + + free_image(in_s); + free_image(in); + + + float curr = 0; + fps = .9*fps + .1*curr; + for(i = 0; i < skip; ++i){ + image in = get_image_from_stream(cap); + free_image(in); + } + } + #endif +} +*/ + +/* +void network_detect(network *net, image im, float thresh, float hier_thresh, float nms, detection *dets) +{ + network_predict_image(net, im); + layer l = net->layers[net->n-1]; + int nboxes = num_boxes(net); + fill_network_boxes(net, im.w, im.h, thresh, hier_thresh, 0, 0, dets); + if (nms) do_nms_sort(dets, nboxes, l.classes, nms); +} +*/ + +void run_detector(int argc, char **argv) +{ + char *prefix = find_char_arg(argc, argv, "-prefix", 0); + float thresh = find_float_arg(argc, argv, "-thresh", .5); + float hier_thresh = find_float_arg(argc, argv, "-hier", .5); + int cam_index = find_int_arg(argc, argv, "-c", 0); + int frame_skip = find_int_arg(argc, argv, "-s", 0); + int avg = find_int_arg(argc, argv, "-avg", 3); + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + char *gpu_list = find_char_arg(argc, argv, "-gpus", 0); + char *outfile = find_char_arg(argc, argv, "-out", 0); + int *gpus = 0; + int gpu = 0; + int ngpus = 0; + if(gpu_list){ + printf("%s\n", gpu_list); + int len = strlen(gpu_list); + ngpus = 1; + int i; + for(i = 0; i < len; ++i){ + if (gpu_list[i] == ',') ++ngpus; + } + gpus = calloc(ngpus, sizeof(int)); + for(i = 0; i < ngpus; ++i){ + gpus[i] = atoi(gpu_list); + gpu_list = strchr(gpu_list, ',')+1; + } + } else { + gpu = gpu_index; + gpus = &gpu; + ngpus = 1; + } + + int clear = find_arg(argc, argv, "-clear"); + int fullscreen = find_arg(argc, argv, "-fullscreen"); + int width = find_int_arg(argc, argv, "-w", 0); + int height = find_int_arg(argc, argv, "-h", 0); + int fps = find_int_arg(argc, argv, "-fps", 0); + //int class = find_int_arg(argc, argv, "-class", 0); + + char *datacfg = argv[3]; + char *cfg = argv[4]; + char *weights = (argc > 5) ? argv[5] : 0; + char *filename = (argc > 6) ? argv[6]: 0; + if(0==strcmp(argv[2], "test")) test_detector(datacfg, cfg, weights, filename, thresh, hier_thresh, outfile, fullscreen); + else if(0==strcmp(argv[2], "train")) train_detector(datacfg, cfg, weights, gpus, ngpus, clear); + else if(0==strcmp(argv[2], "valid")) validate_detector(datacfg, cfg, weights, outfile); + else if(0==strcmp(argv[2], "valid2")) validate_detector_flip(datacfg, cfg, weights, outfile); + else if(0==strcmp(argv[2], "recall")) validate_detector_recall(cfg, weights); + else if(0==strcmp(argv[2], "demo")) { + list *options = read_data_cfg(datacfg); + int classes = option_find_int(options, "classes", 20); + char *name_list = option_find_str(options, "names", "data/names.list"); + char **names = get_labels(name_list); + demo(cfg, weights, thresh, cam_index, filename, names, classes, frame_skip, prefix, avg, hier_thresh, width, height, fps, fullscreen); + } + //else if(0==strcmp(argv[2], "extract")) extract_detector(datacfg, cfg, weights, cam_index, filename, class, thresh, frame_skip); + //else if(0==strcmp(argv[2], "censor")) censor_detector(datacfg, cfg, weights, cam_index, filename, class, thresh, frame_skip); +} diff --git a/hanzi_detection/examples/detector.py b/hanzi_detection/examples/detector.py new file mode 100755 index 0000000..1ed32d2 --- /dev/null +++ b/hanzi_detection/examples/detector.py @@ -0,0 +1,27 @@ +# Stupid python path shit. +# Instead just add darknet.py to somewhere in your python path +# OK actually that might not be a great idea, idk, work in progress +# Use at your own risk. or don't, i don't care + +import sys, os +sys.path.append(os.path.join(os.getcwd(),'python/')) + +import nine as dn +import pdb + +dn.set_gpu(0) +net = dn.load_net("cfg/yolo-thor.cfg", "/home/pjreddie/backup/yolo-thor_final.weights", 0) +meta = dn.load_meta("cfg/thor.data") +r = dn.detect(net, meta, "data/bedroom.jpg") +print r + +# And then down here you could detect a lot more images like: +r = dn.detect(net, meta, "data/eagle.jpg") +print r +r = dn.detect(net, meta, "data/giraffe.jpg") +print r +r = dn.detect(net, meta, "data/horses.jpg") +print r +r = dn.detect(net, meta, "data/person.jpg") +print r + diff --git a/hanzi_detection/examples/dice.c b/hanzi_detection/examples/dice.c new file mode 100755 index 0000000..f56d76c --- /dev/null +++ b/hanzi_detection/examples/dice.c @@ -0,0 +1,116 @@ +#include "darknet.h" + +char *dice_labels[] = {"face1","face2","face3","face4","face5","face6"}; + +void train_dice(char *cfgfile, char *weightfile) +{ + srand(time(0)); + float avg_loss = -1; + char *base = basecfg(cfgfile); + char *backup_directory = "/home/pjreddie/backup/"; + printf("%s\n", base); + network net = parse_network_cfg(cfgfile); + if(weightfile){ + load_weights(&net, weightfile); + } + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net.learning_rate, net.momentum, net.decay); + int imgs = 1024; + int i = *net.seen/imgs; + char **labels = dice_labels; + list *plist = get_paths("data/dice/dice.train.list"); + char **paths = (char **)list_to_array(plist); + printf("%d\n", plist->size); + clock_t time; + while(1){ + ++i; + time=clock(); + data train = load_data_old(paths, imgs, plist->size, labels, 6, net.w, net.h); + printf("Loaded: %lf seconds\n", sec(clock()-time)); + + time=clock(); + float loss = train_network(net, train); + if(avg_loss == -1) avg_loss = loss; + avg_loss = avg_loss*.9 + loss*.1; + printf("%d: %f, %f avg, %lf seconds, %ld images\n", i, loss, avg_loss, sec(clock()-time), *net.seen); + free_data(train); + if((i % 100) == 0) net.learning_rate *= .1; + if(i%100==0){ + char buff[256]; + sprintf(buff, "%s/%s_%d.weights",backup_directory,base, i); + save_weights(net, buff); + } + } +} + +void validate_dice(char *filename, char *weightfile) +{ + network net = parse_network_cfg(filename); + if(weightfile){ + load_weights(&net, weightfile); + } + srand(time(0)); + + char **labels = dice_labels; + list *plist = get_paths("data/dice/dice.val.list"); + + char **paths = (char **)list_to_array(plist); + int m = plist->size; + free_list(plist); + + data val = load_data_old(paths, m, 0, labels, 6, net.w, net.h); + float *acc = network_accuracies(net, val, 2); + printf("Validation Accuracy: %f, %d images\n", acc[0], m); + free_data(val); +} + +void test_dice(char *cfgfile, char *weightfile, char *filename) +{ + network net = parse_network_cfg(cfgfile); + if(weightfile){ + load_weights(&net, weightfile); + } + set_batch_network(&net, 1); + srand(2222222); + int i = 0; + char **names = dice_labels; + char buff[256]; + char *input = buff; + int indexes[6]; + while(1){ + if(filename){ + strncpy(input, filename, 256); + }else{ + printf("Enter Image Path: "); + fflush(stdout); + input = fgets(input, 256, stdin); + if(!input) return; + strtok(input, "\n"); + } + image im = load_image_color(input, net.w, net.h); + float *X = im.data; + float *predictions = network_predict(net, X); + top_predictions(net, 6, indexes); + for(i = 0; i < 6; ++i){ + int index = indexes[i]; + printf("%s: %f\n", names[index], predictions[index]); + } + free_image(im); + if (filename) break; + } +} + +void run_dice(int argc, char **argv) +{ + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + + char *cfg = argv[3]; + char *weights = (argc > 4) ? argv[4] : 0; + char *filename = (argc > 5) ? argv[5]: 0; + if(0==strcmp(argv[2], "test")) test_dice(cfg, weights, filename); + else if(0==strcmp(argv[2], "train")) train_dice(cfg, weights); + else if(0==strcmp(argv[2], "valid")) validate_dice(cfg, weights); +} + diff --git a/hanzi_detection/examples/go.c b/hanzi_detection/examples/go.c new file mode 100755 index 0000000..688579d --- /dev/null +++ b/hanzi_detection/examples/go.c @@ -0,0 +1,1370 @@ +#include "darknet.h" + +#include +#include +#include + +int inverted = 1; +int noi = 1; +static const int nind = 10; +int legal_go(float *b, float *ko, int p, int r, int c); +int check_ko(float *x, float *ko); + +typedef struct { + char **data; + int n; +} moves; + +char *fgetgo(FILE *fp) +{ + if(feof(fp)) return 0; + size_t size = 96; + char *line = malloc(size*sizeof(char)); + if(size != fread(line, sizeof(char), size, fp)){ + free(line); + return 0; + } + + return line; +} + +moves load_go_moves(char *filename) +{ + moves m; + m.n = 128; + m.data = calloc(128, sizeof(char*)); + FILE *fp = fopen(filename, "rb"); + int count = 0; + char *line = 0; + while ((line = fgetgo(fp))) { + if (count >= m.n) { + m.n *= 2; + m.data = realloc(m.data, m.n*sizeof(char*)); + } + m.data[count] = line; + ++count; + } + printf("%d\n", count); + m.n = count; + m.data = realloc(m.data, count*sizeof(char*)); + return m; +} + +void string_to_board(char *s, float *board) +{ + int i, j; + memset(board, 0, 2*19*19*sizeof(float)); + int count = 0; + for(i = 0; i < 91; ++i){ + char c = s[i]; + for(j = 0; j < 4; ++j){ + int me = (c >> (2*j)) & 1; + int you = (c >> (2*j + 1)) & 1; + if (me) board[count] = 1; + else if (you) board[count + 19*19] = 1; + ++count; + if(count >= 19*19) break; + } + } +} + +void board_to_string(char *s, float *board) +{ + int i, j; + memset(s, 0, (19*19/4+1)*sizeof(char)); + int count = 0; + for(i = 0; i < 91; ++i){ + for(j = 0; j < 4; ++j){ + int me = (board[count] == 1); + int you = (board[count + 19*19] == 1); + if (me) s[i] = s[i] | (1<<(2*j)); + if (you) s[i] = s[i] | (1<<(2*j + 1)); + ++count; + if(count >= 19*19) break; + } + } +} + +static int occupied(float *b, int i) +{ + if (b[i]) return 1; + if (b[i+19*19]) return -1; + return 0; +} + +data random_go_moves(moves m, int n) +{ + data d = {0}; + d.X = make_matrix(n, 19*19*3); + d.y = make_matrix(n, 19*19+2); + int i, j; + for(i = 0; i < n; ++i){ + float *board = d.X.vals[i]; + float *label = d.y.vals[i]; + char *b = m.data[rand()%m.n]; + int player = b[0] - '0'; + int result = b[1] - '0'; + int row = b[2]; + int col = b[3]; + string_to_board(b+4, board); + if(player > 0) for(j = 0; j < 19*19; ++j) board[19*19*2 + j] = 1; + label[19*19+1] = (player==result); + if(row >= 19 || col >= 19){ + label[19*19] = 1; + } else { + label[col + 19*row] = 1; + if(occupied(board, col + 19*row)) printf("hey\n"); + } + + int flip = rand()%2; + int rotate = rand()%4; + image in = float_to_image(19, 19, 3, board); + image out = float_to_image(19, 19, 1, label); + if(flip){ + flip_image(in); + flip_image(out); + } + rotate_image_cw(in, rotate); + rotate_image_cw(out, rotate); + } + return d; +} + + +void train_go(char *cfgfile, char *weightfile, char *filename, int *gpus, int ngpus, int clear) +{ + int i; + float avg_loss = -1; + char *base = basecfg(cfgfile); + printf("%s\n", base); + printf("%d\n", ngpus); + network **nets = calloc(ngpus, sizeof(network*)); + + srand(time(0)); + int seed = rand(); + for(i = 0; i < ngpus; ++i){ + srand(seed); +#ifdef GPU + cuda_set_device(gpus[i]); +#endif + nets[i] = load_network(cfgfile, weightfile, clear); + nets[i]->learning_rate *= ngpus; + } + network *net = nets[0]; + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + + char *backup_directory = "/home/pjreddie/backup/"; + + char buff[256]; + moves m = load_go_moves(filename); + //moves m = load_go_moves("games.txt"); + + int N = m.n; + printf("Moves: %d\n", N); + int epoch = (*net->seen)/N; + while(get_current_batch(net) < net->max_batches || net->max_batches == 0){ + double time=what_time_is_it_now(); + + data train = random_go_moves(m, net->batch*net->subdivisions*ngpus); + printf("Loaded: %lf seconds\n", what_time_is_it_now() - time); + time=what_time_is_it_now(); + + float loss = 0; +#ifdef GPU + if(ngpus == 1){ + loss = train_network(net, train); + } else { + loss = train_networks(nets, ngpus, train, 10); + } +#else + loss = train_network(net, train); +#endif + free_data(train); + + if(avg_loss == -1) avg_loss = loss; + avg_loss = avg_loss*.95 + loss*.05; + printf("%ld, %.3f: %f, %f avg, %f rate, %lf seconds, %ld images\n", get_current_batch(net), (float)(*net->seen)/N, loss, avg_loss, get_current_rate(net), what_time_is_it_now()-time, *net->seen); + if(*net->seen/N > epoch){ + epoch = *net->seen/N; + char buff[256]; + sprintf(buff, "%s/%s_%d.weights", backup_directory,base, epoch); + save_weights(net, buff); + + } + if(get_current_batch(net)%1000 == 0){ + char buff[256]; + sprintf(buff, "%s/%s.backup",backup_directory,base); + save_weights(net, buff); + } + if(get_current_batch(net)%10000 == 0){ + char buff[256]; + sprintf(buff, "%s/%s_%ld.backup",backup_directory,base,get_current_batch(net)); + save_weights(net, buff); + } + } + sprintf(buff, "%s/%s.weights", backup_directory, base); + save_weights(net, buff); + + free_network(net); + free(base); +} + +static void propagate_liberty(float *board, int *lib, int *visited, int row, int col, int side) +{ + if (row < 0 || row > 18 || col < 0 || col > 18) return; + int index = row*19 + col; + if (occupied(board,index) != side) return; + if (visited[index]) return; + visited[index] = 1; + lib[index] += 1; + propagate_liberty(board, lib, visited, row+1, col, side); + propagate_liberty(board, lib, visited, row-1, col, side); + propagate_liberty(board, lib, visited, row, col+1, side); + propagate_liberty(board, lib, visited, row, col-1, side); +} + + +static int *calculate_liberties(float *board) +{ + int *lib = calloc(19*19, sizeof(int)); + int visited[19*19]; + int i, j; + for(j = 0; j < 19; ++j){ + for(i = 0; i < 19; ++i){ + memset(visited, 0, 19*19*sizeof(int)); + int index = j*19 + i; + if(!occupied(board,index)){ + if ((i > 0) && occupied(board,index - 1)) propagate_liberty(board, lib, visited, j, i-1, occupied(board,index-1)); + if ((i < 18) && occupied(board,index + 1)) propagate_liberty(board, lib, visited, j, i+1, occupied(board,index+1)); + if ((j > 0) && occupied(board,index - 19)) propagate_liberty(board, lib, visited, j-1, i, occupied(board,index-19)); + if ((j < 18) && occupied(board,index + 19)) propagate_liberty(board, lib, visited, j+1, i, occupied(board,index+19)); + } + } + } + return lib; +} + +void print_board(FILE *stream, float *board, int player, int *indexes) +{ + int i,j,n; + fprintf(stream, " "); + for(i = 0; i < 19; ++i){ + fprintf(stream, "%c ", 'A' + i + 1*(i > 7 && noi)); + } + fprintf(stream, "\n"); + for(j = 0; j < 19; ++j){ + fprintf(stream, "%2d", (inverted) ? 19-j : j+1); + for(i = 0; i < 19; ++i){ + int index = j*19 + i; + if(indexes){ + int found = 0; + for(n = 0; n < nind; ++n){ + if(index == indexes[n]){ + found = 1; + /* + if(n == 0) fprintf(stream, "\uff11"); + else if(n == 1) fprintf(stream, "\uff12"); + else if(n == 2) fprintf(stream, "\uff13"); + else if(n == 3) fprintf(stream, "\uff14"); + else if(n == 4) fprintf(stream, "\uff15"); + */ + fprintf(stream, " %d", n+1); + } + } + if(found) continue; + } + //if(board[index]*-swap > 0) fprintf(stream, "\u25C9 "); + //else if(board[index]*-swap < 0) fprintf(stream, "\u25EF "); + if (occupied(board, index) == player) fprintf(stream, " X"); + else if (occupied(board, index) ==-player) fprintf(stream, " O"); + else fprintf(stream, " ."); + } + fprintf(stream, "\n"); + } +} + +void flip_board(float *board) +{ + int i; + for(i = 0; i < 19*19; ++i){ + float swap = board[i]; + board[i] = board[i+19*19]; + board[i+19*19] = swap; + board[i+19*19*2] = 1-board[i+19*19*2]; + } +} + +float predict_move2(network *net, float *board, float *move, int multi) +{ + float *output = network_predict(net, board); + copy_cpu(19*19+1, output, 1, move, 1); + float result = output[19*19 + 1]; + int i; + if(multi){ + image bim = float_to_image(19, 19, 3, board); + for(i = 1; i < 8; ++i){ + rotate_image_cw(bim, i); + if(i >= 4) flip_image(bim); + + float *output = network_predict(net, board); + image oim = float_to_image(19, 19, 1, output); + result += output[19*19 + 1]; + + if(i >= 4) flip_image(oim); + rotate_image_cw(oim, -i); + + axpy_cpu(19*19+1, 1, output, 1, move, 1); + + if(i >= 4) flip_image(bim); + rotate_image_cw(bim, -i); + } + result = result/8; + scal_cpu(19*19+1, 1./8., move, 1); + } + for(i = 0; i < 19*19; ++i){ + if(board[i] || board[i+19*19]) move[i] = 0; + } + return result; +} + +static void remove_connected(float *b, int *lib, int p, int r, int c) +{ + if (r < 0 || r >= 19 || c < 0 || c >= 19) return; + if (occupied(b, r*19 + c) != p) return; + if (lib[r*19 + c] != 1) return; + b[r*19 + c] = 0; + b[19*19 + r*19 + c] = 0; + remove_connected(b, lib, p, r+1, c); + remove_connected(b, lib, p, r-1, c); + remove_connected(b, lib, p, r, c+1); + remove_connected(b, lib, p, r, c-1); +} + + +void move_go(float *b, int p, int r, int c) +{ + int *l = calculate_liberties(b); + if(p > 0) b[r*19 + c] = 1; + else b[19*19 + r*19 + c] = 1; + remove_connected(b, l, -p, r+1, c); + remove_connected(b, l, -p, r-1, c); + remove_connected(b, l, -p, r, c+1); + remove_connected(b, l, -p, r, c-1); + free(l); +} + +int compare_board(float *a, float *b) +{ + if(memcmp(a, b, 19*19*3*sizeof(float)) == 0) return 1; + return 0; +} + +typedef struct mcts_tree{ + float *board; + struct mcts_tree **children; + float *prior; + int *visit_count; + float *value; + float *mean; + float *prob; + int total_count; + float result; + int done; + int pass; +} mcts_tree; + +void free_mcts(mcts_tree *root) +{ + if(!root) return; + int i; + free(root->board); + for(i = 0; i < 19*19+1; ++i){ + if(root->children[i]) free_mcts(root->children[i]); + } + free(root->children); + free(root->prior); + free(root->visit_count); + free(root->value); + free(root->mean); + free(root->prob); + free(root); +} + +float *network_predict_rotations(network *net, float *next) +{ + int n = net->batch; + float *in = calloc(19*19*3*n, sizeof(float)); + image im = float_to_image(19, 19, 3, next); + int i,j; + int *inds = random_index_order(0, 8); + for(j = 0; j < n; ++j){ + i = inds[j]; + rotate_image_cw(im, i); + if(i >= 4) flip_image(im); + memcpy(in + 19*19*3*j, im.data, 19*19*3*sizeof(float)); + if(i >= 4) flip_image(im); + rotate_image_cw(im, -i); + } + float *pred = network_predict(net, in); + for(j = 0; j < n; ++j){ + i = inds[j]; + image im = float_to_image(19, 19, 1, pred + j*(19*19 + 2)); + if(i >= 4) flip_image(im); + rotate_image_cw(im, -i); + if(j > 0){ + axpy_cpu(19*19+2, 1, im.data, 1, pred, 1); + } + } + free(in); + free(inds); + scal_cpu(19*19+2, 1./n, pred, 1); + return pred; +} + +mcts_tree *expand(float *next, float *ko, network *net) +{ + mcts_tree *root = calloc(1, sizeof(mcts_tree)); + root->board = next; + root->children = calloc(19*19+1, sizeof(mcts_tree*)); + root->prior = calloc(19*19 + 1, sizeof(float)); + root->prob = calloc(19*19 + 1, sizeof(float)); + root->mean = calloc(19*19 + 1, sizeof(float)); + root->value = calloc(19*19 + 1, sizeof(float)); + root->visit_count = calloc(19*19 + 1, sizeof(int)); + root->total_count = 1; + int i; + float *pred = network_predict_rotations(net, next); + copy_cpu(19*19+1, pred, 1, root->prior, 1); + float val = 2*pred[19*19 + 1] - 1; + root->result = val; + for(i = 0; i < 19*19+1; ++i) { + root->visit_count[i] = 0; + root->value[i] = 0; + root->mean[i] = val; + if(i < 19*19 && occupied(next, i)){ + root->value[i] = -1; + root->mean[i] = -1; + root->prior[i] = 0; + } + } + //print_board(stderr, next, flip?-1:1, 0); + return root; +} + +float *copy_board(float *board) +{ + float *next = calloc(19*19*3, sizeof(float)); + copy_cpu(19*19*3, board, 1, next, 1); + return next; +} + +float select_mcts(mcts_tree *root, network *net, float *prev, float cpuct) +{ + if(root->done) return -root->result; + int i; + float max = -1000; + int max_i = 0; + for(i = 0; i < 19*19+1; ++i){ + root->prob[i] = root->mean[i] + cpuct*root->prior[i] * sqrt(root->total_count) / (1. + root->visit_count[i]); + if(root->prob[i] > max){ + max = root->prob[i]; + max_i = i; + } + } + float val; + i = max_i; + root->visit_count[i]++; + root->total_count++; + if (root->children[i]) { + val = select_mcts(root->children[i], net, root->board, cpuct); + } else { + if(max_i < 19*19 && !legal_go(root->board, prev, 1, max_i/19, max_i%19)) { + root->mean[i] = -1; + root->value[i] = -1; + root->prior[i] = 0; + --root->total_count; + return select_mcts(root, net, prev, cpuct); + //printf("Detected ko\n"); + //getchar(); + } else { + float *next = copy_board(root->board); + if (max_i < 19*19) { + move_go(next, 1, max_i / 19, max_i % 19); + } + flip_board(next); + root->children[i] = expand(next, root->board, net); + val = -root->children[i]->result; + if(max_i == 19*19){ + root->children[i]->pass = 1; + if (root->pass){ + root->children[i]->done = 1; + } + } + } + } + root->value[i] += val; + root->mean[i] = root->value[i]/root->visit_count[i]; + return -val; +} + +mcts_tree *run_mcts(mcts_tree *tree, network *net, float *board, float *ko, int player, int n, float cpuct, float secs) +{ + int i; + double t = what_time_is_it_now(); + if(player < 0) flip_board(board); + if(!tree) tree = expand(copy_board(board), ko, net); + assert(compare_board(tree->board, board)); + for(i = 0; i < n; ++i){ + if (secs > 0 && (what_time_is_it_now() - t) > secs) break; + int max_i = max_int_index(tree->visit_count, 19*19+1); + if (tree->visit_count[max_i] >= n) break; + select_mcts(tree, net, ko, cpuct); + } + if(player < 0) flip_board(board); + //fprintf(stderr, "%f Seconds\n", what_time_is_it_now() - t); + return tree; +} + +mcts_tree *move_mcts(mcts_tree *tree, int index) +{ + if(index < 0 || index > 19*19 || !tree || !tree->children[index]) { + free_mcts(tree); + tree = 0; + } else { + mcts_tree *swap = tree; + tree = tree->children[index]; + swap->children[index] = 0; + free_mcts(swap); + } + return tree; +} + +typedef struct { + float value; + float mcts; + int row; + int col; +} move; + +move pick_move(mcts_tree *tree, float temp, int player) +{ + int i; + float probs[19*19+1] = {0}; + move m = {0}; + double sum = 0; + /* + for(i = 0; i < 19*19+1; ++i){ + probs[i] = tree->visit_count[i]; + } + */ + //softmax(probs, 19*19+1, temp, 1, probs); + for(i = 0; i < 19*19+1; ++i){ + sum += pow(tree->visit_count[i], 1./temp); + } + for(i = 0; i < 19*19+1; ++i){ + probs[i] = pow(tree->visit_count[i], 1./temp) / sum; + } + + int index = sample_array(probs, 19*19+1); + m.row = index / 19; + m.col = index % 19; + m.value = (tree->result+1.)/2.; + m.mcts = (tree->mean[index]+1.)/2.; + + int indexes[nind]; + top_k(probs, 19*19+1, nind, indexes); + print_board(stderr, tree->board, player, indexes); + + fprintf(stderr, "%d %d, Result: %f, Prior: %f, Prob: %f, Mean Value: %f, Child Result: %f, Visited: %d\n", index/19, index%19, tree->result, tree->prior[index], probs[index], tree->mean[index], (tree->children[index])?tree->children[index]->result:0, tree->visit_count[index]); + int ind = max_index(probs, 19*19+1); + fprintf(stderr, "%d %d, Result: %f, Prior: %f, Prob: %f, Mean Value: %f, Child Result: %f, Visited: %d\n", ind/19, ind%19, tree->result, tree->prior[ind], probs[ind], tree->mean[ind], (tree->children[ind])?tree->children[ind]->result:0, tree->visit_count[ind]); + ind = max_index(tree->prior, 19*19+1); + fprintf(stderr, "%d %d, Result: %f, Prior: %f, Prob: %f, Mean Value: %f, Child Result: %f, Visited: %d\n", ind/19, ind%19, tree->result, tree->prior[ind], probs[ind], tree->mean[ind], (tree->children[ind])?tree->children[ind]->result:0, tree->visit_count[ind]); + return m; +} + +/* + float predict_move(network *net, float *board, float *move, int multi, float *ko, float temp) + { + + int i; + + int max_v = 0; + int max_i = 0; + for(i = 0; i < 19*19+1; ++i){ + if(root->visit_count[i] > max_v){ + max_v = root->visit_count[i]; + max_i = i; + } + } + fprintf(stderr, "%f Seconds\n", what_time_is_it_now() - t); + int ind = max_index(root->mean, 19*19+1); + fprintf(stderr, "%d %d, Result: %f, Prior: %f, Prob: %f, Mean Value: %f, Child Result: %f, Visited: %d\n", max_i/19, max_i%19, root->result, root->prior[max_i], root->prob[max_i], root->mean[max_i], (root->children[max_i])?root->children[max_i]->result:0, root->visit_count[max_i]); + fprintf(stderr, "%d %d, Result: %f, Prior: %f, Prob: %f, Mean Value: %f, Child Result: %f, Visited: %d\n", ind/19, ind%19, root->result, root->prior[ind], root->prob[ind], root->mean[ind], (root->children[ind])?root->children[ind]->result:0, root->visit_count[ind]); + ind = max_index(root->prior, 19*19+1); + fprintf(stderr, "%d %d, Result: %f, Prior: %f, Prob: %f, Mean Value: %f, Child Result: %f, Visited: %d\n", ind/19, ind%19, root->result, root->prior[ind], root->prob[ind], root->mean[ind], (root->children[ind])?root->children[ind]->result:0, root->visit_count[ind]); + if(root->result < -.9 && root->mean[max_i] < -.9) return -1000.f; + + float val = root->result; + free_mcts(root); + return val; + } + */ + +static int makes_safe_go(float *b, int *lib, int p, int r, int c){ + if (r < 0 || r >= 19 || c < 0 || c >= 19) return 0; + if (occupied(b,r*19 + c) == -p){ + if (lib[r*19 + c] > 1) return 0; + else return 1; + } + if (!occupied(b,r*19 + c)) return 1; + if (lib[r*19 + c] > 1) return 1; + return 0; +} + +int suicide_go(float *b, int p, int r, int c) +{ + int *l = calculate_liberties(b); + int safe = 0; + safe = safe || makes_safe_go(b, l, p, r+1, c); + safe = safe || makes_safe_go(b, l, p, r-1, c); + safe = safe || makes_safe_go(b, l, p, r, c+1); + safe = safe || makes_safe_go(b, l, p, r, c-1); + free(l); + return !safe; +} + +int check_ko(float *x, float *ko) +{ + if(!ko) return 0; + float curr[19*19*3]; + copy_cpu(19*19*3, x, 1, curr, 1); + if(curr[19*19*2] != ko[19*19*2]) flip_board(curr); + if(compare_board(curr, ko)) return 1; + return 0; +} + +int legal_go(float *b, float *ko, int p, int r, int c) +{ + if (occupied(b, r*19+c)) return 0; + float curr[19*19*3]; + copy_cpu(19*19*3, b, 1, curr, 1); + move_go(curr, p, r, c); + if(check_ko(curr, ko)) return 0; + if(suicide_go(b, p, r, c)) return 0; + return 1; +} + +/* + move generate_move(mcts_tree *root, network *net, int player, float *board, int multi, float temp, float *ko, int print) + { + move m = {0}; +//root = run_mcts(tree, network *net, float *board, float *ko, int n, float cpuct) +int i, j; +int empty = 1; +for(i = 0; i < 19*19; ++i){ +if (occupied(board, i)) { +empty = 0; +break; +} +} +if(empty) { +m.value = .5; +m.mcts = .5; +m.row = 3; +m.col = 15; +return m; +} + +float move[362]; +if (player < 0) flip_board(board); +float result = predict_move(net, board, move, multi, ko, temp); +if (player < 0) flip_board(board); +if(result == -1000.f) return -2; + +for(i = 0; i < 19; ++i){ +for(j = 0; j < 19; ++j){ +if (!legal_go(board, ko, player, i, j)) move[i*19 + j] = 0; +} +} + +int indexes[nind]; +top_k(move, 19*19+1, nind, indexes); + + +int max = max_index(move, 19*19+1); +int row = max / 19; +int col = max % 19; +int index = sample_array(move, 19*19+1); + +if(print){ +top_k(move, 19*19+1, nind, indexes); +for(i = 0; i < nind; ++i){ +if (!move[indexes[i]]) indexes[i] = -1; +} +print_board(stderr, board, 1, indexes); +fprintf(stderr, "%s To Move\n", player > 0 ? "X" : "O"); +fprintf(stderr, "%.2f%% Win Chance\n", (result+1)/2*100); +for(i = 0; i < nind; ++i){ +int index = indexes[i]; +int row = index / 19; +int col = index % 19; +if(row == 19){ +fprintf(stderr, "%d: Pass, %.2f%%\n", i+1, move[index]*100); +} else { +fprintf(stderr, "%d: %c %d, %.2f%%\n", i+1, col + 'A' + 1*(col > 7 && noi), (inverted)?19 - row : row+1, move[index]*100); +} +} +} +if (row == 19) return -1; + +if (suicide_go(board, player, row, col)){ +return -1; +} + +if (suicide_go(board, player, index/19, index%19)){ +index = max; +} +if (index == 19*19) return -1; +return index; +} +*/ + +void valid_go(char *cfgfile, char *weightfile, int multi, char *filename) +{ + srand(time(0)); + char *base = basecfg(cfgfile); + printf("%s\n", base); + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + + float *board = calloc(19*19*3, sizeof(float)); + float *move = calloc(19*19+2, sizeof(float)); + // moves m = load_go_moves("/home/pjreddie/backup/go.test"); + moves m = load_go_moves(filename); + + int N = m.n; + int i,j; + int correct = 0; + for (i = 0; i 0) for(j = 0; j < 19*19; ++j) board[19*19*2 + j] = 1; + predict_move2(net, board, move, multi); + int index = max_index(move, 19*19+1); + if(index == truth) ++correct; + printf("%d Accuracy %f\n", i, (float) correct/(i+1)); + } +} + +int print_game(float *board, FILE *fp) +{ + int i, j; + int count = 3; + fprintf(fp, "komi 6.5\n"); + fprintf(fp, "boardsize 19\n"); + fprintf(fp, "clear_board\n"); + for(j = 0; j < 19; ++j){ + for(i = 0; i < 19; ++i){ + if(occupied(board,j*19 + i) == 1) fprintf(fp, "play black %c%d\n", 'A'+i+(i>=8), 19-j); + if(occupied(board,j*19 + i) == -1) fprintf(fp, "play white %c%d\n", 'A'+i+(i>=8), 19-j); + if(occupied(board,j*19 + i)) ++count; + } + } + return count; +} + + +int stdin_ready() +{ + fd_set readfds; + FD_ZERO(&readfds); + + struct timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 0; + FD_SET(STDIN_FILENO, &readfds); + + if (select(1, &readfds, NULL, NULL, &timeout)){ + return 1; + } + return 0; +} + +mcts_tree *ponder(mcts_tree *tree, network *net, float *b, float *ko, int player, float cpuct) +{ + double t = what_time_is_it_now(); + int count = 0; + if (tree) count = tree->total_count; + while(!stdin_ready()){ + if (what_time_is_it_now() - t > 120) break; + tree = run_mcts(tree, net, b, ko, player, 100000, cpuct, .1); + } + fprintf(stderr, "Pondered %d moves...\n", tree->total_count - count); + return tree; +} + +void engine_go(char *filename, char *weightfile, int mcts_iters, float secs, float temp, float cpuct, int anon, int resign) +{ + mcts_tree *root = 0; + network *net = load_network(filename, weightfile, 0); + set_batch_network(net, 1); + srand(time(0)); + float *board = calloc(19*19*3, sizeof(float)); + flip_board(board); + float *one = calloc(19*19*3, sizeof(float)); + float *two = calloc(19*19*3, sizeof(float)); + int ponder_player = 0; + int passed = 0; + int move_num = 0; + int main_time = 0; + int byo_yomi_time = 0; + int byo_yomi_stones = 0; + int black_time_left = 0; + int black_stones_left = 0; + int white_time_left = 0; + int white_stones_left = 0; + float orig_time = secs; + int old_ponder = 0; + while(1){ + if(ponder_player){ + root = ponder(root, net, board, two, ponder_player, cpuct); + } + old_ponder = ponder_player; + ponder_player = 0; + char buff[256]; + int id = 0; + int has_id = (scanf("%d", &id) == 1); + scanf("%s", buff); + if (feof(stdin)) break; + fprintf(stderr, "%s\n", buff); + char ids[256]; + sprintf(ids, "%d", id); + //fprintf(stderr, "%s\n", buff); + if (!has_id) ids[0] = 0; + if (!strcmp(buff, "protocol_version")){ + printf("=%s 2\n\n", ids); + } else if (!strcmp(buff, "name")){ + if(anon){ + printf("=%s The Fool!\n\n", ids); + }else{ + printf("=%s DarkGo\n\n", ids); + } + } else if (!strcmp(buff, "time_settings")){ + ponder_player = old_ponder; + scanf("%d %d %d", &main_time, &byo_yomi_time, &byo_yomi_stones); + printf("=%s \n\n", ids); + } else if (!strcmp(buff, "time_left")){ + ponder_player = old_ponder; + char color[256]; + int time = 0, stones = 0; + scanf("%s %d %d", color, &time, &stones); + if (color[0] == 'b' || color[0] == 'B'){ + black_time_left = time; + black_stones_left = stones; + } else { + white_time_left = time; + white_stones_left = stones; + } + printf("=%s \n\n", ids); + } else if (!strcmp(buff, "version")){ + if(anon){ + printf("=%s :-DDDD\n\n", ids); + }else { + printf("=%s 1.0. Want more DarkGo? You can find me on OGS, unlimited games, no waiting! https://online-go.com/user/view/434218\n\n", ids); + } + } else if (!strcmp(buff, "known_command")){ + char comm[256]; + scanf("%s", comm); + int known = (!strcmp(comm, "protocol_version") || + !strcmp(comm, "name") || + !strcmp(comm, "version") || + !strcmp(comm, "known_command") || + !strcmp(comm, "list_commands") || + !strcmp(comm, "quit") || + !strcmp(comm, "boardsize") || + !strcmp(comm, "clear_board") || + !strcmp(comm, "komi") || + !strcmp(comm, "final_status_list") || + !strcmp(comm, "play") || + !strcmp(comm, "genmove_white") || + !strcmp(comm, "genmove_black") || + !strcmp(comm, "fixed_handicap") || + !strcmp(comm, "genmove")); + if(known) printf("=%s true\n\n", ids); + else printf("=%s false\n\n", ids); + } else if (!strcmp(buff, "list_commands")){ + printf("=%s protocol_version\nshowboard\nname\nversion\nknown_command\nlist_commands\nquit\nboardsize\nclear_board\nkomi\nplay\ngenmove_black\ngenmove_white\ngenmove\nfinal_status_list\nfixed_handicap\n\n", ids); + } else if (!strcmp(buff, "quit")){ + break; + } else if (!strcmp(buff, "boardsize")){ + int boardsize = 0; + scanf("%d", &boardsize); + //fprintf(stderr, "%d\n", boardsize); + if(boardsize != 19){ + printf("?%s unacceptable size\n\n", ids); + } else { + root = move_mcts(root, -1); + memset(board, 0, 3*19*19*sizeof(float)); + flip_board(board); + move_num = 0; + printf("=%s \n\n", ids); + } + } else if (!strcmp(buff, "fixed_handicap")){ + int handicap = 0; + scanf("%d", &handicap); + int indexes[] = {72, 288, 300, 60, 180, 174, 186, 66, 294}; + int i; + for(i = 0; i < handicap; ++i){ + board[indexes[i]] = 1; + ++move_num; + } + root = move_mcts(root, -1); + } else if (!strcmp(buff, "clear_board")){ + passed = 0; + memset(board, 0, 3*19*19*sizeof(float)); + flip_board(board); + move_num = 0; + root = move_mcts(root, -1); + printf("=%s \n\n", ids); + } else if (!strcmp(buff, "komi")){ + float komi = 0; + scanf("%f", &komi); + printf("=%s \n\n", ids); + } else if (!strcmp(buff, "showboard")){ + printf("=%s \n", ids); + print_board(stdout, board, 1, 0); + printf("\n"); + } else if (!strcmp(buff, "play") || !strcmp(buff, "black") || !strcmp(buff, "white")){ + ++move_num; + char color[256]; + if(!strcmp(buff, "play")) + { + scanf("%s ", color); + } else { + scanf(" "); + color[0] = buff[0]; + } + char c; + int r; + int count = scanf("%c%d", &c, &r); + int player = (color[0] == 'b' || color[0] == 'B') ? 1 : -1; + if((c == 'p' || c == 'P') && count < 2) { + passed = 1; + printf("=%s \n\n", ids); + char *line = fgetl(stdin); + free(line); + fflush(stdout); + fflush(stderr); + root = move_mcts(root, 19*19); + continue; + } else { + passed = 0; + } + if(c >= 'A' && c <= 'Z') c = c - 'A'; + if(c >= 'a' && c <= 'z') c = c - 'a'; + if(c >= 8) --c; + r = 19 - r; + fprintf(stderr, "move: %d %d\n", r, c); + + float *swap = two; + two = one; + one = swap; + move_go(board, player, r, c); + copy_cpu(19*19*3, board, 1, one, 1); + if(root) fprintf(stderr, "Prior: %f\n", root->prior[r*19 + c]); + if(root) fprintf(stderr, "Mean: %f\n", root->mean[r*19 + c]); + if(root) fprintf(stderr, "Result: %f\n", root->result); + root = move_mcts(root, r*19 + c); + if(root) fprintf(stderr, "Visited: %d\n", root->total_count); + else fprintf(stderr, "NOT VISITED\n"); + + printf("=%s \n\n", ids); + //print_board(stderr, board, 1, 0); + } else if (!strcmp(buff, "genmove") || !strcmp(buff, "genmove_black") || !strcmp(buff, "genmove_white")){ + ++move_num; + int player = 0; + if(!strcmp(buff, "genmove")){ + char color[256]; + scanf("%s", color); + player = (color[0] == 'b' || color[0] == 'B') ? 1 : -1; + } else if (!strcmp(buff, "genmove_black")){ + player = 1; + } else { + player = -1; + } + if(player > 0){ + if(black_time_left <= 30) secs = 2.5; + else secs = orig_time; + } else { + if(white_time_left <= 30) secs = 2.5; + else secs = orig_time; + } + ponder_player = -player; + + //tree = generate_move(net, player, board, multi, .1, two, 1); + double t = what_time_is_it_now(); + root = run_mcts(root, net, board, two, player, mcts_iters, cpuct, secs); + fprintf(stderr, "%f Seconds\n", what_time_is_it_now() - t); + move m = pick_move(root, temp, player); + root = move_mcts(root, m.row*19 + m.col); + + + if(move_num > resign && m.value < .1 && m.mcts < .1){ + printf("=%s resign\n\n", ids); + } else if(m.row == 19){ + printf("=%s pass\n\n", ids); + passed = 0; + } else { + int row = m.row; + int col = m.col; + + float *swap = two; + two = one; + one = swap; + + move_go(board, player, row, col); + copy_cpu(19*19*3, board, 1, one, 1); + row = 19 - row; + if (col >= 8) ++col; + printf("=%s %c%d\n\n", ids, 'A' + col, row); + } + + } else if (!strcmp(buff, "p")){ + //print_board(board, 1, 0); + } else if (!strcmp(buff, "final_status_list")){ + char type[256]; + scanf("%s", type); + fprintf(stderr, "final_status\n"); + char *line = fgetl(stdin); + free(line); + if(type[0] == 'd' || type[0] == 'D'){ + int i; + FILE *f = fopen("game.txt", "w"); + int count = print_game(board, f); + fprintf(f, "%s final_status_list dead\n", ids); + fclose(f); + FILE *p = popen("./gnugo --mode gtp < game.txt", "r"); + for(i = 0; i < count; ++i){ + free(fgetl(p)); + free(fgetl(p)); + } + char *l = 0; + while((l = fgetl(p))){ + printf("%s\n", l); + free(l); + } + } else { + printf("?%s unknown command\n\n", ids); + } + } else if (!strcmp(buff, "kgs-genmove_cleanup")){ + char type[256]; + scanf("%s", type); + fprintf(stderr, "kgs-genmove_cleanup\n"); + char *line = fgetl(stdin); + free(line); + int i; + FILE *f = fopen("game.txt", "w"); + int count = print_game(board, f); + fprintf(f, "%s kgs-genmove_cleanup %s\n", ids, type); + fclose(f); + FILE *p = popen("./gnugo --mode gtp < game.txt", "r"); + for(i = 0; i < count; ++i){ + free(fgetl(p)); + free(fgetl(p)); + } + char *l = 0; + while((l = fgetl(p))){ + printf("%s\n", l); + free(l); + } + } else { + char *line = fgetl(stdin); + free(line); + printf("?%s unknown command\n\n", ids); + } + fflush(stdout); + fflush(stderr); + } + printf("%d %d %d\n",passed, black_stones_left, white_stones_left); +} + +void test_go(char *cfg, char *weights, int multi) +{ + int i; + network *net = load_network(cfg, weights, 0); + set_batch_network(net, 1); + srand(time(0)); + float *board = calloc(19*19*3, sizeof(float)); + flip_board(board); + float *move = calloc(19*19+1, sizeof(float)); + int color = 1; + while(1){ + float result = predict_move2(net, board, move, multi); + printf("%.2f%% Win Chance\n", (result+1)/2*100); + + int indexes[nind]; + int row, col; + top_k(move, 19*19+1, nind, indexes); + print_board(stderr, board, color, indexes); + for(i = 0; i < nind; ++i){ + int index = indexes[i]; + row = index / 19; + col = index % 19; + if(row == 19){ + printf("%d: Pass, %.2f%%\n", i+1, move[index]*100); + } else { + printf("%d: %c %d, %.2f%%\n", i+1, col + 'A' + 1*(col > 7 && noi), (inverted)?19 - row : row+1, move[index]*100); + } + } + //if(color == 1) printf("\u25EF Enter move: "); + //else printf("\u25C9 Enter move: "); + if(color == 1) printf("X Enter move: "); + else printf("O Enter move: "); + + char c; + char *line = fgetl(stdin); + int picked = 1; + int dnum = sscanf(line, "%d", &picked); + int cnum = sscanf(line, "%c", &c); + if (strlen(line) == 0 || dnum) { + --picked; + if (picked < nind){ + int index = indexes[picked]; + row = index / 19; + col = index % 19; + if(row < 19){ + move_go(board, 1, row, col); + } + } + } else if (cnum){ + if (c <= 'T' && c >= 'A'){ + int num = sscanf(line, "%c %d", &c, &row); + row = (inverted)?19 - row : row-1; + col = c - 'A'; + if (col > 7 && noi) col -= 1; + if (num == 2) move_go(board, 1, row, col); + } else if (c == 'p') { + // Pass + } else if(c=='b' || c == 'w'){ + char g; + int num = sscanf(line, "%c %c %d", &g, &c, &row); + row = (inverted)?19 - row : row-1; + col = c - 'A'; + if (col > 7 && noi) col -= 1; + if (num == 3) { + int mc = (g == 'b') ? 1 : -1; + if (mc == color) { + board[row*19 + col] = 1; + } else { + board[19*19 + row*19 + col] = 1; + } + } + } else if(c == 'c'){ + char g; + int num = sscanf(line, "%c %c %d", &g, &c, &row); + row = (inverted)?19 - row : row-1; + col = c - 'A'; + if (col > 7 && noi) col -= 1; + if (num == 3) { + board[row*19 + col] = 0; + board[19*19 + row*19 + col] = 0; + } + } + } + free(line); + flip_board(board); + color = -color; + } +} + +float score_game(float *board) +{ + int i; + FILE *f = fopen("game.txt", "w"); + int count = print_game(board, f); + fprintf(f, "final_score\n"); + fclose(f); + FILE *p = popen("./gnugo --mode gtp < game.txt", "r"); + for(i = 0; i < count; ++i){ + free(fgetl(p)); + free(fgetl(p)); + } + char *l = 0; + float score = 0; + char player = 0; + while((l = fgetl(p))){ + fprintf(stderr, "%s \t", l); + int n = sscanf(l, "= %c+%f", &player, &score); + free(l); + if (n == 2) break; + } + if(player == 'W') score = -score; + pclose(p); + return score; +} + +void self_go(char *filename, char *weightfile, char *f2, char *w2, int multi) +{ + mcts_tree *tree1 = 0; + mcts_tree *tree2 = 0; + network *net = load_network(filename, weightfile, 0); + //set_batch_network(net, 1); + + network *net2; + if (f2) { + net2 = parse_network_cfg(f2); + if(w2){ + load_weights(net2, w2); + } + } else { + net2 = calloc(1, sizeof(network)); + *net2 = *net; + } + srand(time(0)); + char boards[600][93]; + int count = 0; + //set_batch_network(net, 1); + //set_batch_network(net2, 1); + float *board = calloc(19*19*3, sizeof(float)); + flip_board(board); + float *one = calloc(19*19*3, sizeof(float)); + float *two = calloc(19*19*3, sizeof(float)); + int done = 0; + int player = 1; + int p1 = 0; + int p2 = 0; + int total = 0; + float temp = .1; + int mcts_iters = 500; + float cpuct = 5; + while(1){ + if (done){ + tree1 = move_mcts(tree1, -1); + tree2 = move_mcts(tree2, -1); + float score = score_game(board); + if((score > 0) == (total%2==0)) ++p1; + else ++p2; + ++total; + fprintf(stderr, "Total: %d, Player 1: %f, Player 2: %f\n", total, (float)p1/total, (float)p2/total); + sleep(1); + /* + int i = (score > 0)? 0 : 1; + int j; + for(; i < count; i += 2){ + for(j = 0; j < 93; ++j){ + printf("%c", boards[i][j]); + } + printf("\n"); + } + */ + memset(board, 0, 3*19*19*sizeof(float)); + flip_board(board); + player = 1; + done = 0; + count = 0; + fflush(stdout); + fflush(stderr); + } + //print_board(stderr, board, 1, 0); + //sleep(1); + + if ((total%2==0) == (player==1)){ + //mcts_iters = 4500; + cpuct = 5; + } else { + //mcts_iters = 500; + cpuct = 1; + } + network *use = ((total%2==0) == (player==1)) ? net : net2; + mcts_tree *t = ((total%2==0) == (player==1)) ? tree1 : tree2; + t = run_mcts(t, use, board, two, player, mcts_iters, cpuct, 0); + move m = pick_move(t, temp, player); + if(((total%2==0) == (player==1))) tree1 = t; + else tree2 = t; + + tree1 = move_mcts(tree1, m.row*19 + m.col); + tree2 = move_mcts(tree2, m.row*19 + m.col); + + if(m.row == 19){ + done = 1; + continue; + } + int row = m.row; + int col = m.col; + + float *swap = two; + two = one; + one = swap; + + if(player < 0) flip_board(board); + boards[count][0] = row; + boards[count][1] = col; + board_to_string(boards[count] + 2, board); + if(player < 0) flip_board(board); + ++count; + + move_go(board, player, row, col); + copy_cpu(19*19*3, board, 1, one, 1); + + player = -player; + } +} + +void run_go(int argc, char **argv) +{ + //boards_go(); + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + + char *gpu_list = find_char_arg(argc, argv, "-gpus", 0); + int *gpus = 0; + int gpu = 0; + int ngpus = 0; + if(gpu_list){ + printf("%s\n", gpu_list); + int len = strlen(gpu_list); + ngpus = 1; + int i; + for(i = 0; i < len; ++i){ + if (gpu_list[i] == ',') ++ngpus; + } + gpus = calloc(ngpus, sizeof(int)); + for(i = 0; i < ngpus; ++i){ + gpus[i] = atoi(gpu_list); + gpu_list = strchr(gpu_list, ',')+1; + } + } else { + gpu = gpu_index; + gpus = &gpu; + ngpus = 1; + } + int clear = find_arg(argc, argv, "-clear"); + + char *cfg = argv[3]; + char *weights = (argc > 4) ? argv[4] : 0; + char *c2 = (argc > 5) ? argv[5] : 0; + char *w2 = (argc > 6) ? argv[6] : 0; + int multi = find_arg(argc, argv, "-multi"); + int anon = find_arg(argc, argv, "-anon"); + int iters = find_int_arg(argc, argv, "-iters", 500); + int resign = find_int_arg(argc, argv, "-resign", 175); + float cpuct = find_float_arg(argc, argv, "-cpuct", 5); + float temp = find_float_arg(argc, argv, "-temp", .1); + float time = find_float_arg(argc, argv, "-time", 0); + if(0==strcmp(argv[2], "train")) train_go(cfg, weights, c2, gpus, ngpus, clear); + else if(0==strcmp(argv[2], "valid")) valid_go(cfg, weights, multi, c2); + else if(0==strcmp(argv[2], "self")) self_go(cfg, weights, c2, w2, multi); + else if(0==strcmp(argv[2], "test")) test_go(cfg, weights, multi); + else if(0==strcmp(argv[2], "engine")) engine_go(cfg, weights, iters, time, temp, cpuct, anon, resign); +} + + diff --git a/hanzi_detection/examples/instance-segmenter.c b/hanzi_detection/examples/instance-segmenter.c new file mode 100755 index 0000000..664e714 --- /dev/null +++ b/hanzi_detection/examples/instance-segmenter.c @@ -0,0 +1,267 @@ +#include "darknet.h" +#include +#include + +void normalize_image2(image p); +void train_isegmenter(char *datacfg, char *cfgfile, char *weightfile, int *gpus, int ngpus, int clear, int display) +{ + int i; + + float avg_loss = -1; + char *base = basecfg(cfgfile); + printf("%s\n", base); + printf("%d\n", ngpus); + network **nets = calloc(ngpus, sizeof(network*)); + + srand(time(0)); + int seed = rand(); + for(i = 0; i < ngpus; ++i){ + srand(seed); +#ifdef GPU + cuda_set_device(gpus[i]); +#endif + nets[i] = load_network(cfgfile, weightfile, clear); + nets[i]->learning_rate *= ngpus; + } + srand(time(0)); + network *net = nets[0]; + image pred = get_network_image(net); + + image embed = pred; + embed.c = 3; + embed.data += embed.w*embed.h*80; + + int div = net->w/pred.w; + assert(pred.w * div == net->w); + assert(pred.h * div == net->h); + + int imgs = net->batch * net->subdivisions * ngpus; + + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + list *options = read_data_cfg(datacfg); + + char *backup_directory = option_find_str(options, "backup", "/backup/"); + char *train_list = option_find_str(options, "train", "data/train.list"); + + list *plist = get_paths(train_list); + char **paths = (char **)list_to_array(plist); + printf("%d\n", plist->size); + int N = plist->size; + + load_args args = {0}; + args.w = net->w; + args.h = net->h; + args.threads = 32; + args.scale = div; + args.num_boxes = 90; + + args.min = net->min_crop; + args.max = net->max_crop; + args.angle = net->angle; + args.aspect = net->aspect; + args.exposure = net->exposure; + args.saturation = net->saturation; + args.hue = net->hue; + args.size = net->w; + args.classes = 80; + + args.paths = paths; + args.n = imgs; + args.m = N; + args.type = ISEG_DATA; + + data train; + data buffer; + pthread_t load_thread; + args.d = &buffer; + load_thread = load_data(args); + + int epoch = (*net->seen)/N; + while(get_current_batch(net) < net->max_batches || net->max_batches == 0){ + double time = what_time_is_it_now(); + + pthread_join(load_thread, 0); + train = buffer; + load_thread = load_data(args); + + printf("Loaded: %lf seconds\n", what_time_is_it_now()-time); + time = what_time_is_it_now(); + + float loss = 0; +#ifdef GPU + if(ngpus == 1){ + loss = train_network(net, train); + } else { + loss = train_networks(nets, ngpus, train, 4); + } +#else + loss = train_network(net, train); +#endif + if(display){ + image tr = float_to_image(net->w/div, net->h/div, 80, train.y.vals[net->batch*(net->subdivisions-1)]); + image im = float_to_image(net->w, net->h, net->c, train.X.vals[net->batch*(net->subdivisions-1)]); + pred.c = 80; + image mask = mask_to_rgb(tr); + image prmask = mask_to_rgb(pred); + image ecopy = copy_image(embed); + normalize_image2(ecopy); + show_image(ecopy, "embed", 1); + free_image(ecopy); + + show_image(im, "input", 1); + show_image(prmask, "pred", 1); + show_image(mask, "truth", 100); + free_image(mask); + free_image(prmask); + } + if(avg_loss == -1) avg_loss = loss; + avg_loss = avg_loss*.9 + loss*.1; + printf("%ld, %.3f: %f, %f avg, %f rate, %lf seconds, %ld images\n", get_current_batch(net), (float)(*net->seen)/N, loss, avg_loss, get_current_rate(net), what_time_is_it_now()-time, *net->seen); + free_data(train); + if(*net->seen/N > epoch){ + epoch = *net->seen/N; + char buff[256]; + sprintf(buff, "%s/%s_%d.weights",backup_directory,base, epoch); + save_weights(net, buff); + } + if(get_current_batch(net)%100 == 0){ + char buff[256]; + sprintf(buff, "%s/%s.backup",backup_directory,base); + save_weights(net, buff); + } + } + char buff[256]; + sprintf(buff, "%s/%s.weights", backup_directory, base); + save_weights(net, buff); + + free_network(net); + free_ptrs((void**)paths, plist->size); + free_list(plist); + free(base); +} + +void predict_isegmenter(char *datafile, char *cfg, char *weights, char *filename) +{ + network *net = load_network(cfg, weights, 0); + set_batch_network(net, 1); + srand(2222222); + + clock_t time; + char buff[256]; + char *input = buff; + while(1){ + if(filename){ + strncpy(input, filename, 256); + }else{ + printf("Enter Image Path: "); + fflush(stdout); + input = fgets(input, 256, stdin); + if(!input) return; + strtok(input, "\n"); + } + image im = load_image_color(input, 0, 0); + image sized = letterbox_image(im, net->w, net->h); + + float *X = sized.data; + time=clock(); + float *predictions = network_predict(net, X); + image pred = get_network_image(net); + image prmask = mask_to_rgb(pred); + printf("Predicted: %f\n", predictions[0]); + printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time)); + show_image(sized, "orig", 1); + show_image(prmask, "pred", 0); + free_image(im); + free_image(sized); + free_image(prmask); + if (filename) break; + } +} + + +void demo_isegmenter(char *datacfg, char *cfg, char *weights, int cam_index, const char *filename) +{ +#ifdef OPENCV + printf("Classifier Demo\n"); + network *net = load_network(cfg, weights, 0); + set_batch_network(net, 1); + + srand(2222222); + void * cap = open_video_stream(filename, cam_index, 0,0,0); + + if(!cap) error("Couldn't connect to webcam.\n"); + float fps = 0; + + while(1){ + struct timeval tval_before, tval_after, tval_result; + gettimeofday(&tval_before, NULL); + + image in = get_image_from_stream(cap); + image in_s = letterbox_image(in, net->w, net->h); + + network_predict(net, in_s.data); + + printf("\033[2J"); + printf("\033[1;1H"); + printf("\nFPS:%.0f\n",fps); + + image pred = get_network_image(net); + image prmask = mask_to_rgb(pred); + show_image(prmask, "Segmenter", 10); + + free_image(in_s); + free_image(in); + free_image(prmask); + + gettimeofday(&tval_after, NULL); + timersub(&tval_after, &tval_before, &tval_result); + float curr = 1000000.f/((long int)tval_result.tv_usec); + fps = .9*fps + .1*curr; + } +#endif +} + + +void run_isegmenter(int argc, char **argv) +{ + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + + char *gpu_list = find_char_arg(argc, argv, "-gpus", 0); + int *gpus = 0; + int gpu = 0; + int ngpus = 0; + if(gpu_list){ + printf("%s\n", gpu_list); + int len = strlen(gpu_list); + ngpus = 1; + int i; + for(i = 0; i < len; ++i){ + if (gpu_list[i] == ',') ++ngpus; + } + gpus = calloc(ngpus, sizeof(int)); + for(i = 0; i < ngpus; ++i){ + gpus[i] = atoi(gpu_list); + gpu_list = strchr(gpu_list, ',')+1; + } + } else { + gpu = gpu_index; + gpus = &gpu; + ngpus = 1; + } + + int cam_index = find_int_arg(argc, argv, "-c", 0); + int clear = find_arg(argc, argv, "-clear"); + int display = find_arg(argc, argv, "-display"); + char *data = argv[3]; + char *cfg = argv[4]; + char *weights = (argc > 5) ? argv[5] : 0; + char *filename = (argc > 6) ? argv[6]: 0; + if(0==strcmp(argv[2], "test")) predict_isegmenter(data, cfg, weights, filename); + else if(0==strcmp(argv[2], "train")) train_isegmenter(data, cfg, weights, gpus, ngpus, clear, display); + else if(0==strcmp(argv[2], "demo")) demo_isegmenter(data, cfg, weights, cam_index, filename); +} + + diff --git a/hanzi_detection/examples/lsd.c b/hanzi_detection/examples/lsd.c new file mode 100755 index 0000000..4ab944c --- /dev/null +++ b/hanzi_detection/examples/lsd.c @@ -0,0 +1,1378 @@ +#include +#include "darknet.h" + +/* +void train_lsd3(char *fcfg, char *fweight, char *gcfg, char *gweight, char *acfg, char *aweight, int clear) +{ +#ifdef GPU + //char *train_images = "/home/pjreddie/data/coco/trainvalno5k.txt"; + char *train_images = "/home/pjreddie/data/imagenet/imagenet1k.train.list"; + //char *style_images = "/home/pjreddie/data/coco/trainvalno5k.txt"; + char *style_images = "/home/pjreddie/zelda.txt"; + char *backup_directory = "/home/pjreddie/backup/"; + srand(time(0)); + network fnet = load_network(fcfg, fweight, clear); + network gnet = load_network(gcfg, gweight, clear); + network anet = load_network(acfg, aweight, clear); + char *gbase = basecfg(gcfg); + char *abase = basecfg(acfg); + + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", gnet->learning_rate, gnet->momentum, gnet->decay); + int imgs = gnet->batch*gnet->subdivisions; + int i = *gnet->seen/imgs; + data train, tbuffer; + data style, sbuffer; + + + list *slist = get_paths(style_images); + char **spaths = (char **)list_to_array(slist); + + list *tlist = get_paths(train_images); + char **tpaths = (char **)list_to_array(tlist); + + load_args targs= get_base_args(gnet); + targs.paths = tpaths; + targs.n = imgs; + targs.m = tlist->size; + targs.d = &tbuffer; + targs.type = CLASSIFICATION_DATA; + targs.classes = 1; + char *ls[1] = {"zelda"}; + targs.labels = ls; + + load_args sargs = get_base_args(gnet); + sargs.paths = spaths; + sargs.n = imgs; + sargs.m = slist->size; + sargs.d = &sbuffer; + sargs.type = CLASSIFICATION_DATA; + sargs.classes = 1; + sargs.labels = ls; + + pthread_t tload_thread = load_data_in_thread(targs); + pthread_t sload_thread = load_data_in_thread(sargs); + clock_t time; + + float aloss_avg = -1; + float floss_avg = -1; + + fnet->train=1; + int x_size = fnet->inputs*fnet->batch; + int y_size = fnet->truths*fnet->batch; + float *X = calloc(x_size, sizeof(float)); + float *y = calloc(y_size, sizeof(float)); + + + int ax_size = anet->inputs*anet->batch; + int ay_size = anet->truths*anet->batch; + fill_gpu(ay_size, .9, anet->truth_gpu, 1); + anet->delta_gpu = cuda_make_array(0, ax_size); + anet->train = 1; + + int gx_size = gnet->inputs*gnet->batch; + int gy_size = gnet->truths*gnet->batch; + gstate.input = cuda_make_array(0, gx_size); + gstate.truth = 0; + gstate.delta = 0; + gstate.train = 1; + + while (get_current_batch(gnet) < gnet->max_batches) { + i += 1; + time=clock(); + pthread_join(tload_thread, 0); + pthread_join(sload_thread, 0); + train = tbuffer; + style = sbuffer; + tload_thread = load_data_in_thread(targs); + sload_thread = load_data_in_thread(sargs); + + printf("Loaded: %lf seconds\n", sec(clock()-time)); + + data generated = copy_data(train); + time=clock(); + + int j, k; + float floss = 0; + for(j = 0; j < fnet->subdivisions; ++j){ + layer imlayer = gnet->layers[gnet->n - 1]; + get_next_batch(train, fnet->batch, j*fnet->batch, X, y); + + cuda_push_array(fstate.input, X, x_size); + cuda_push_array(gstate.input, X, gx_size); + *gnet->seen += gnet->batch; + + forward_network_gpu(fnet, fstate); + float *feats = fnet->layers[fnet->n - 2].output_gpu; + copy_gpu(y_size, feats, 1, fstate.truth, 1); + + forward_network_gpu(gnet, gstate); + float *gen = gnet->layers[gnet->n-1].output_gpu; + copy_gpu(x_size, gen, 1, fstate.input, 1); + + fill_gpu(x_size, 0, fstate.delta, 1); + forward_network_gpu(fnet, fstate); + backward_network_gpu(fnet, fstate); + //HERE + + astate.input = gen; + fill_gpu(ax_size, 0, astate.delta, 1); + forward_network_gpu(anet, astate); + backward_network_gpu(anet, astate); + + float *delta = imlayer.delta_gpu; + fill_gpu(x_size, 0, delta, 1); + scal_gpu(x_size, 100, astate.delta, 1); + scal_gpu(x_size, .001, fstate.delta, 1); + axpy_gpu(x_size, 1, fstate.delta, 1, delta, 1); + axpy_gpu(x_size, 1, astate.delta, 1, delta, 1); + + //fill_gpu(x_size, 0, delta, 1); + //cuda_push_array(delta, X, x_size); + //axpy_gpu(x_size, -1, imlayer.output_gpu, 1, delta, 1); + //printf("pix error: %f\n", cuda_mag_array(delta, x_size)); + printf("fea error: %f\n", cuda_mag_array(fstate.delta, x_size)); + printf("adv error: %f\n", cuda_mag_array(astate.delta, x_size)); + //axpy_gpu(x_size, 1, astate.delta, 1, delta, 1); + + backward_network_gpu(gnet, gstate); + + floss += get_network_cost(fnet) /(fnet->subdivisions*fnet->batch); + + cuda_pull_array(imlayer.output_gpu, imlayer.output, imlayer.outputs*imlayer.batch); + for(k = 0; k < gnet->batch; ++k){ + int index = j*gnet->batch + k; + copy_cpu(imlayer.outputs, imlayer.output + k*imlayer.outputs, 1, generated.X.vals[index], 1); + generated.y.vals[index][0] = .1; + style.y.vals[index][0] = .9; + } + } + +*/ +/* + image sim = float_to_image(anet->w, anet->h, anet->c, style.X.vals[j]); + show_image(sim, "style"); + cvWaitKey(0); + */ + /* + + harmless_update_network_gpu(anet); + + data merge = concat_data(style, generated); + randomize_data(merge); + float aloss = train_network(anet, merge); + + update_network_gpu(gnet); + + free_data(merge); + free_data(train); + free_data(generated); + free_data(style); + if (aloss_avg < 0) aloss_avg = aloss; + if (floss_avg < 0) floss_avg = floss; + aloss_avg = aloss_avg*.9 + aloss*.1; + floss_avg = floss_avg*.9 + floss*.1; + + printf("%d: gen: %f, adv: %f | gen_avg: %f, adv_avg: %f, %f rate, %lf seconds, %d images\n", i, floss, aloss, floss_avg, aloss_avg, get_current_rate(gnet), sec(clock()-time), i*imgs); + if(i%1000==0){ + char buff[256]; + sprintf(buff, "%s/%s_%d.weights", backup_directory, gbase, i); + save_weights(gnet, buff); + sprintf(buff, "%s/%s_%d.weights", backup_directory, abase, i); + save_weights(anet, buff); + } + if(i%100==0){ + char buff[256]; + sprintf(buff, "%s/%s.backup", backup_directory, gbase); + save_weights(gnet, buff); + sprintf(buff, "%s/%s.backup", backup_directory, abase); + save_weights(anet, buff); + } + } +#endif +} +*/ + +/* +void train_pix2pix(char *cfg, char *weight, char *acfg, char *aweight, int clear) +{ +#ifdef GPU + //char *train_images = "/home/pjreddie/data/coco/train1.txt"; + //char *train_images = "/home/pjreddie/data/coco/trainvalno5k.txt"; + char *train_images = "/home/pjreddie/data/imagenet/imagenet1k.train.list"; + char *backup_directory = "/home/pjreddie/backup/"; + srand(time(0)); + char *base = basecfg(cfg); + char *abase = basecfg(acfg); + printf("%s\n", base); + network net = load_network(cfg, weight, clear); + network anet = load_network(acfg, aweight, clear); + + int i, j, k; + layer imlayer = {0}; + for (i = 0; i < net->n; ++i) { + if (net->layers[i].out_c == 3) { + imlayer = net->layers[i]; + break; + } + } + + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + int imgs = net->batch*net->subdivisions; + i = *net->seen/imgs; + data train, buffer; + + + list *plist = get_paths(train_images); + //int N = plist->size; + char **paths = (char **)list_to_array(plist); + + load_args args = {0}; + args.w = net->w; + args.h = net->h; + args.paths = paths; + args.n = imgs; + args.m = plist->size; + args.d = &buffer; + + args.min = net->min_crop; + args.max = net->max_crop; + args.angle = net->angle; + args.aspect = net->aspect; + args.exposure = net->exposure; + args.saturation = net->saturation; + args.hue = net->hue; + args.size = net->w; + args.type = CLASSIFICATION_DATA; + args.classes = 1; + char *ls[1] = {"coco"}; + args.labels = ls; + + pthread_t load_thread = load_data_in_thread(args); + clock_t time; + + network_state gstate = {0}; + gstate.index = 0; + gstate.net = net; + int x_size = get_network_input_size(net)*net->batch; + int y_size = x_size; + gstate.input = cuda_make_array(0, x_size); + gstate.truth = cuda_make_array(0, y_size); + gstate.delta = 0; + gstate.train = 1; + float *pixs = calloc(x_size, sizeof(float)); + float *graypixs = calloc(x_size, sizeof(float)); + float *y = calloc(y_size, sizeof(float)); + + network_state astate = {0}; + astate.index = 0; + astate.net = anet; + int ay_size = get_network_output_size(anet)*anet->batch; + astate.input = 0; + astate.truth = 0; + astate.delta = 0; + astate.train = 1; + + float *imerror = cuda_make_array(0, imlayer.outputs); + float *ones_gpu = cuda_make_array(0, ay_size); + fill_gpu(ay_size, .9, ones_gpu, 1); + + float aloss_avg = -1; + float gloss_avg = -1; + + //data generated = copy_data(train); + + while (get_current_batch(net) < net->max_batches) { + i += 1; + time=clock(); + pthread_join(load_thread, 0); + train = buffer; + load_thread = load_data_in_thread(args); + + printf("Loaded: %lf seconds\n", sec(clock()-time)); + + data gray = copy_data(train); + for(j = 0; j < imgs; ++j){ + image gim = float_to_image(net->w, net->h, net->c, gray.X.vals[j]); + grayscale_image_3c(gim); + train.y.vals[j][0] = .9; + + image yim = float_to_image(net->w, net->h, net->c, train.X.vals[j]); + //rgb_to_yuv(yim); + } + time=clock(); + float gloss = 0; + + for(j = 0; j < net->subdivisions; ++j){ + get_next_batch(train, net->batch, j*net->batch, pixs, y); + get_next_batch(gray, net->batch, j*net->batch, graypixs, y); + cuda_push_array(gstate.input, graypixs, x_size); + cuda_push_array(gstate.truth, pixs, y_size); + */ + /* + image origi = float_to_image(net->w, net->h, 3, pixs); + image grayi = float_to_image(net->w, net->h, 3, graypixs); + show_image(grayi, "gray"); + show_image(origi, "orig"); + cvWaitKey(0); + */ + /* + *net->seen += net->batch; + forward_network_gpu(net, gstate); + + fill_gpu(imlayer.outputs, 0, imerror, 1); + astate.input = imlayer.output_gpu; + astate.delta = imerror; + astate.truth = ones_gpu; + forward_network_gpu(anet, astate); + backward_network_gpu(anet, astate); + + scal_gpu(imlayer.outputs, .1, net->layers[net->n-1].delta_gpu, 1); + + backward_network_gpu(net, gstate); + + scal_gpu(imlayer.outputs, 1000, imerror, 1); + + printf("realness %f\n", cuda_mag_array(imerror, imlayer.outputs)); + printf("features %f\n", cuda_mag_array(net->layers[net->n-1].delta_gpu, imlayer.outputs)); + + axpy_gpu(imlayer.outputs, 1, imerror, 1, imlayer.delta_gpu, 1); + + gloss += get_network_cost(net) /(net->subdivisions*net->batch); + + cuda_pull_array(imlayer.output_gpu, imlayer.output, imlayer.outputs*imlayer.batch); + for(k = 0; k < net->batch; ++k){ + int index = j*net->batch + k; + copy_cpu(imlayer.outputs, imlayer.output + k*imlayer.outputs, 1, gray.X.vals[index], 1); + gray.y.vals[index][0] = .1; + } + } + harmless_update_network_gpu(anet); + + data merge = concat_data(train, gray); + randomize_data(merge); + float aloss = train_network(anet, merge); + + update_network_gpu(net); + update_network_gpu(anet); + free_data(merge); + free_data(train); + free_data(gray); + if (aloss_avg < 0) aloss_avg = aloss; + aloss_avg = aloss_avg*.9 + aloss*.1; + gloss_avg = gloss_avg*.9 + gloss*.1; + + printf("%d: gen: %f, adv: %f | gen_avg: %f, adv_avg: %f, %f rate, %lf seconds, %d images\n", i, gloss, aloss, gloss_avg, aloss_avg, get_current_rate(net), sec(clock()-time), i*imgs); + if(i%1000==0){ + char buff[256]; + sprintf(buff, "%s/%s_%d.weights", backup_directory, base, i); + save_weights(net, buff); + sprintf(buff, "%s/%s_%d.weights", backup_directory, abase, i); + save_weights(anet, buff); + } + if(i%100==0){ + char buff[256]; + sprintf(buff, "%s/%s.backup", backup_directory, base); + save_weights(net, buff); + sprintf(buff, "%s/%s.backup", backup_directory, abase); + save_weights(anet, buff); + } + } + char buff[256]; + sprintf(buff, "%s/%s_final.weights", backup_directory, base); + save_weights(net, buff); +#endif +} +*/ + +void slerp(float *start, float *end, float s, int n, float *out) +{ + float omega = acos(dot_cpu(n, start, 1, end, 1)); + float so = sin(omega); + fill_cpu(n, 0, out, 1); + axpy_cpu(n, sin((1-s)*omega)/so, start, 1, out, 1); + axpy_cpu(n, sin(s*omega)/so, end, 1, out, 1); + + float mag = mag_array(out, n); + scale_array(out, n, 1./mag); +} + +image random_unit_vector_image(int w, int h, int c) +{ + image im = make_image(w, h, c); + int i; + for(i = 0; i < im.w*im.h*im.c; ++i){ + im.data[i] = rand_normal(); + } + float mag = mag_array(im.data, im.w*im.h*im.c); + scale_array(im.data, im.w*im.h*im.c, 1./mag); + return im; +} + +void inter_dcgan(char *cfgfile, char *weightfile) +{ + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + srand(2222222); + + clock_t time; + char buff[256]; + char *input = buff; + int i, imlayer = 0; + + for (i = 0; i < net->n; ++i) { + if (net->layers[i].out_c == 3) { + imlayer = i; + printf("%d\n", i); + break; + } + } + image start = random_unit_vector_image(net->w, net->h, net->c); + image end = random_unit_vector_image(net->w, net->h, net->c); + image im = make_image(net->w, net->h, net->c); + image orig = copy_image(start); + + int c = 0; + int count = 0; + int max_count = 15; + while(1){ + ++c; + + if(count == max_count){ + count = 0; + free_image(start); + start = end; + end = random_unit_vector_image(net->w, net->h, net->c); + if(c > 300){ + end = orig; + } + if(c>300 + max_count) return; + } + ++count; + + slerp(start.data, end.data, (float)count / max_count, im.w*im.h*im.c, im.data); + + float *X = im.data; + time=clock(); + network_predict(net, X); + image out = get_network_image_layer(net, imlayer); + //yuv_to_rgb(out); + normalize_image(out); + printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time)); + //char buff[256]; + sprintf(buff, "out%05d", c); + save_image(out, "out"); + save_image(out, buff); + show_image(out, "out", 0); + } +} + +void test_dcgan(char *cfgfile, char *weightfile) +{ + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + srand(2222222); + + clock_t time; + char buff[256]; + char *input = buff; + int imlayer = 0; + + imlayer = net->n-1; + + while(1){ + image im = make_image(net->w, net->h, net->c); + int i; + for(i = 0; i < im.w*im.h*im.c; ++i){ + im.data[i] = rand_normal(); + } + //float mag = mag_array(im.data, im.w*im.h*im.c); + //scale_array(im.data, im.w*im.h*im.c, 1./mag); + + float *X = im.data; + time=clock(); + network_predict(net, X); + image out = get_network_image_layer(net, imlayer); + //yuv_to_rgb(out); + normalize_image(out); + printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time)); + save_image(out, "out"); + show_image(out, "out", 0); + + free_image(im); + } +} + +void set_network_alpha_beta(network *net, float alpha, float beta) +{ + int i; + for(i = 0; i < net->n; ++i){ + if(net->layers[i].type == SHORTCUT){ + net->layers[i].alpha = alpha; + net->layers[i].beta = beta; + } + } +} + +void train_prog(char *cfg, char *weight, char *acfg, char *aweight, int clear, int display, char *train_images, int maxbatch) +{ +#ifdef GPU + char *backup_directory = "/home/pjreddie/backup/"; + srand(time(0)); + char *base = basecfg(cfg); + char *abase = basecfg(acfg); + printf("%s\n", base); + network *gnet = load_network(cfg, weight, clear); + network *anet = load_network(acfg, aweight, clear); + + int i, j, k; + layer imlayer = gnet->layers[gnet->n-1]; + + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", gnet->learning_rate, gnet->momentum, gnet->decay); + int imgs = gnet->batch*gnet->subdivisions; + i = *gnet->seen/imgs; + data train, buffer; + + + list *plist = get_paths(train_images); + char **paths = (char **)list_to_array(plist); + + load_args args= get_base_args(anet); + args.paths = paths; + args.n = imgs; + args.m = plist->size; + args.d = &buffer; + args.type = CLASSIFICATION_DATA; + args.threads=16; + args.classes = 1; + char *ls[2] = {"imagenet", "zzzzzzzz"}; + args.labels = ls; + + pthread_t load_thread = load_data_in_thread(args); + clock_t time; + + gnet->train = 1; + anet->train = 1; + + int x_size = gnet->inputs*gnet->batch; + int y_size = gnet->truths*gnet->batch; + float *imerror = cuda_make_array(0, y_size); + + float aloss_avg = -1; + + if (maxbatch == 0) maxbatch = gnet->max_batches; + while (get_current_batch(gnet) < maxbatch) { + { + int cb = get_current_batch(gnet); + float alpha = (float) cb / (maxbatch/2); + if(alpha > 1) alpha = 1; + float beta = 1 - alpha; + printf("%f %f\n", alpha, beta); + set_network_alpha_beta(gnet, alpha, beta); + set_network_alpha_beta(anet, beta, alpha); + } + + i += 1; + time=clock(); + pthread_join(load_thread, 0); + train = buffer; + + load_thread = load_data_in_thread(args); + + printf("Loaded: %lf seconds\n", sec(clock()-time)); + + data gen = copy_data(train); + for (j = 0; j < imgs; ++j) { + train.y.vals[j][0] = 1; + gen.y.vals[j][0] = 0; + } + time=clock(); + + for (j = 0; j < gnet->subdivisions; ++j) { + get_next_batch(train, gnet->batch, j*gnet->batch, gnet->truth, 0); + int z; + for(z = 0; z < x_size; ++z){ + gnet->input[z] = rand_normal(); + } + /* + for(z = 0; z < gnet->batch; ++z){ + float mag = mag_array(gnet->input + z*gnet->inputs, gnet->inputs); + scale_array(gnet->input + z*gnet->inputs, gnet->inputs, 1./mag); + } + */ + *gnet->seen += gnet->batch; + forward_network(gnet); + + fill_gpu(imlayer.outputs*imlayer.batch, 0, imerror, 1); + fill_cpu(anet->truths*anet->batch, 1, anet->truth, 1); + copy_cpu(anet->inputs*anet->batch, imlayer.output, 1, anet->input, 1); + anet->delta_gpu = imerror; + forward_network(anet); + backward_network(anet); + + //float genaloss = *anet->cost / anet->batch; + + scal_gpu(imlayer.outputs*imlayer.batch, 1, imerror, 1); + scal_gpu(imlayer.outputs*imlayer.batch, 0, gnet->layers[gnet->n-1].delta_gpu, 1); + + axpy_gpu(imlayer.outputs*imlayer.batch, 1, imerror, 1, gnet->layers[gnet->n-1].delta_gpu, 1); + + backward_network(gnet); + + for(k = 0; k < gnet->batch; ++k){ + int index = j*gnet->batch + k; + copy_cpu(gnet->outputs, gnet->output + k*gnet->outputs, 1, gen.X.vals[index], 1); + } + } + harmless_update_network_gpu(anet); + + data merge = concat_data(train, gen); + float aloss = train_network(anet, merge); + +#ifdef OPENCV + if(display){ + image im = float_to_image(anet->w, anet->h, anet->c, gen.X.vals[0]); + image im2 = float_to_image(anet->w, anet->h, anet->c, train.X.vals[0]); + show_image(im, "gen", 1); + show_image(im2, "train", 1); + save_image(im, "gen"); + save_image(im2, "train"); + } +#endif + + update_network_gpu(gnet); + + free_data(merge); + free_data(train); + free_data(gen); + if (aloss_avg < 0) aloss_avg = aloss; + aloss_avg = aloss_avg*.9 + aloss*.1; + + printf("%d: adv: %f | adv_avg: %f, %f rate, %lf seconds, %d images\n", i, aloss, aloss_avg, get_current_rate(gnet), sec(clock()-time), i*imgs); + if(i%10000==0){ + char buff[256]; + sprintf(buff, "%s/%s_%d.weights", backup_directory, base, i); + save_weights(gnet, buff); + sprintf(buff, "%s/%s_%d.weights", backup_directory, abase, i); + save_weights(anet, buff); + } + if(i%1000==0){ + char buff[256]; + sprintf(buff, "%s/%s.backup", backup_directory, base); + save_weights(gnet, buff); + sprintf(buff, "%s/%s.backup", backup_directory, abase); + save_weights(anet, buff); + } + } + char buff[256]; + sprintf(buff, "%s/%s_final.weights", backup_directory, base); + save_weights(gnet, buff); +#endif +} + +void train_dcgan(char *cfg, char *weight, char *acfg, char *aweight, int clear, int display, char *train_images, int maxbatch) +{ +#ifdef GPU + char *backup_directory = "/home/pjreddie/backup/"; + srand(time(0)); + char *base = basecfg(cfg); + char *abase = basecfg(acfg); + printf("%s\n", base); + network *gnet = load_network(cfg, weight, clear); + network *anet = load_network(acfg, aweight, clear); + //float orig_rate = anet->learning_rate; + + int i, j, k; + layer imlayer = {0}; + for (i = 0; i < gnet->n; ++i) { + if (gnet->layers[i].out_c == 3) { + imlayer = gnet->layers[i]; + break; + } + } + + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", gnet->learning_rate, gnet->momentum, gnet->decay); + int imgs = gnet->batch*gnet->subdivisions; + i = *gnet->seen/imgs; + data train, buffer; + + + list *plist = get_paths(train_images); + //int N = plist->size; + char **paths = (char **)list_to_array(plist); + + load_args args= get_base_args(anet); + args.paths = paths; + args.n = imgs; + args.m = plist->size; + args.d = &buffer; + args.type = CLASSIFICATION_DATA; + args.threads=16; + args.classes = 1; + char *ls[2] = {"imagenet", "zzzzzzzz"}; + args.labels = ls; + + pthread_t load_thread = load_data_in_thread(args); + clock_t time; + + gnet->train = 1; + anet->train = 1; + + int x_size = gnet->inputs*gnet->batch; + int y_size = gnet->truths*gnet->batch; + float *imerror = cuda_make_array(0, y_size); + + //int ay_size = anet->truths*anet->batch; + + float aloss_avg = -1; + + //data generated = copy_data(train); + + if (maxbatch == 0) maxbatch = gnet->max_batches; + while (get_current_batch(gnet) < maxbatch) { + i += 1; + time=clock(); + pthread_join(load_thread, 0); + train = buffer; + + //translate_data_rows(train, -.5); + //scale_data_rows(train, 2); + + load_thread = load_data_in_thread(args); + + printf("Loaded: %lf seconds\n", sec(clock()-time)); + + data gen = copy_data(train); + for (j = 0; j < imgs; ++j) { + train.y.vals[j][0] = 1; + gen.y.vals[j][0] = 0; + } + time=clock(); + + for(j = 0; j < gnet->subdivisions; ++j){ + get_next_batch(train, gnet->batch, j*gnet->batch, gnet->truth, 0); + int z; + for(z = 0; z < x_size; ++z){ + gnet->input[z] = rand_normal(); + } + for(z = 0; z < gnet->batch; ++z){ + float mag = mag_array(gnet->input + z*gnet->inputs, gnet->inputs); + scale_array(gnet->input + z*gnet->inputs, gnet->inputs, 1./mag); + } + /* + for(z = 0; z < 100; ++z){ + printf("%f, ", gnet->input[z]); + } + printf("\n"); + printf("input: %f %f\n", mean_array(gnet->input, x_size), variance_array(gnet->input, x_size)); + */ + + //cuda_push_array(gnet->input_gpu, gnet->input, x_size); + //cuda_push_array(gnet->truth_gpu, gnet->truth, y_size); + *gnet->seen += gnet->batch; + forward_network(gnet); + + fill_gpu(imlayer.outputs*imlayer.batch, 0, imerror, 1); + fill_cpu(anet->truths*anet->batch, 1, anet->truth, 1); + copy_cpu(anet->inputs*anet->batch, imlayer.output, 1, anet->input, 1); + anet->delta_gpu = imerror; + forward_network(anet); + backward_network(anet); + + //float genaloss = *anet->cost / anet->batch; + //printf("%f\n", genaloss); + + scal_gpu(imlayer.outputs*imlayer.batch, 1, imerror, 1); + scal_gpu(imlayer.outputs*imlayer.batch, 0, gnet->layers[gnet->n-1].delta_gpu, 1); + + //printf("realness %f\n", cuda_mag_array(imerror, imlayer.outputs*imlayer.batch)); + //printf("features %f\n", cuda_mag_array(gnet->layers[gnet->n-1].delta_gpu, imlayer.outputs*imlayer.batch)); + + axpy_gpu(imlayer.outputs*imlayer.batch, 1, imerror, 1, gnet->layers[gnet->n-1].delta_gpu, 1); + + backward_network(gnet); + + /* + for(k = 0; k < gnet->n; ++k){ + layer l = gnet->layers[k]; + cuda_pull_array(l.output_gpu, l.output, l.outputs*l.batch); + printf("%d: %f %f\n", k, mean_array(l.output, l.outputs*l.batch), variance_array(l.output, l.outputs*l.batch)); + } + */ + + for(k = 0; k < gnet->batch; ++k){ + int index = j*gnet->batch + k; + copy_cpu(gnet->outputs, gnet->output + k*gnet->outputs, 1, gen.X.vals[index], 1); + } + } + harmless_update_network_gpu(anet); + + data merge = concat_data(train, gen); + //randomize_data(merge); + float aloss = train_network(anet, merge); + + //translate_image(im, 1); + //scale_image(im, .5); + //translate_image(im2, 1); + //scale_image(im2, .5); +#ifdef OPENCV + if(display){ + image im = float_to_image(anet->w, anet->h, anet->c, gen.X.vals[0]); + image im2 = float_to_image(anet->w, anet->h, anet->c, train.X.vals[0]); + show_image(im, "gen", 1); + show_image(im2, "train", 1); + save_image(im, "gen"); + save_image(im2, "train"); + } +#endif + + /* + if(aloss < .1){ + anet->learning_rate = 0; + } else if (aloss > .3){ + anet->learning_rate = orig_rate; + } + */ + + update_network_gpu(gnet); + + free_data(merge); + free_data(train); + free_data(gen); + if (aloss_avg < 0) aloss_avg = aloss; + aloss_avg = aloss_avg*.9 + aloss*.1; + + printf("%d: adv: %f | adv_avg: %f, %f rate, %lf seconds, %d images\n", i, aloss, aloss_avg, get_current_rate(gnet), sec(clock()-time), i*imgs); + if(i%10000==0){ + char buff[256]; + sprintf(buff, "%s/%s_%d.weights", backup_directory, base, i); + save_weights(gnet, buff); + sprintf(buff, "%s/%s_%d.weights", backup_directory, abase, i); + save_weights(anet, buff); + } + if(i%1000==0){ + char buff[256]; + sprintf(buff, "%s/%s.backup", backup_directory, base); + save_weights(gnet, buff); + sprintf(buff, "%s/%s.backup", backup_directory, abase); + save_weights(anet, buff); + } + } + char buff[256]; + sprintf(buff, "%s/%s_final.weights", backup_directory, base); + save_weights(gnet, buff); +#endif +} + +void train_colorizer(char *cfg, char *weight, char *acfg, char *aweight, int clear, int display) +{ +#ifdef GPU + //char *train_images = "/home/pjreddie/data/coco/train1.txt"; + //char *train_images = "/home/pjreddie/data/coco/trainvalno5k.txt"; + char *train_images = "/home/pjreddie/data/imagenet/imagenet1k.train.list"; + char *backup_directory = "/home/pjreddie/backup/"; + srand(time(0)); + char *base = basecfg(cfg); + char *abase = basecfg(acfg); + printf("%s\n", base); + network *net = load_network(cfg, weight, clear); + network *anet = load_network(acfg, aweight, clear); + + int i, j, k; + layer imlayer = {0}; + for (i = 0; i < net->n; ++i) { + if (net->layers[i].out_c == 3) { + imlayer = net->layers[i]; + break; + } + } + + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + int imgs = net->batch*net->subdivisions; + i = *net->seen/imgs; + data train, buffer; + + + list *plist = get_paths(train_images); + //int N = plist->size; + char **paths = (char **)list_to_array(plist); + + load_args args= get_base_args(net); + args.paths = paths; + args.n = imgs; + args.m = plist->size; + args.d = &buffer; + + args.type = CLASSIFICATION_DATA; + args.classes = 1; + char *ls[2] = {"imagenet"}; + args.labels = ls; + + pthread_t load_thread = load_data_in_thread(args); + clock_t time; + + int x_size = net->inputs*net->batch; + //int y_size = x_size; + net->delta = 0; + net->train = 1; + float *pixs = calloc(x_size, sizeof(float)); + float *graypixs = calloc(x_size, sizeof(float)); + //float *y = calloc(y_size, sizeof(float)); + + //int ay_size = anet->outputs*anet->batch; + anet->delta = 0; + anet->train = 1; + + float *imerror = cuda_make_array(0, imlayer.outputs*imlayer.batch); + + float aloss_avg = -1; + float gloss_avg = -1; + + //data generated = copy_data(train); + + while (get_current_batch(net) < net->max_batches) { + i += 1; + time=clock(); + pthread_join(load_thread, 0); + train = buffer; + load_thread = load_data_in_thread(args); + + printf("Loaded: %lf seconds\n", sec(clock()-time)); + + data gray = copy_data(train); + for(j = 0; j < imgs; ++j){ + image gim = float_to_image(net->w, net->h, net->c, gray.X.vals[j]); + grayscale_image_3c(gim); + train.y.vals[j][0] = .95; + gray.y.vals[j][0] = .05; + } + time=clock(); + float gloss = 0; + + for(j = 0; j < net->subdivisions; ++j){ + get_next_batch(train, net->batch, j*net->batch, pixs, 0); + get_next_batch(gray, net->batch, j*net->batch, graypixs, 0); + cuda_push_array(net->input_gpu, graypixs, net->inputs*net->batch); + cuda_push_array(net->truth_gpu, pixs, net->truths*net->batch); + /* + image origi = float_to_image(net->w, net->h, 3, pixs); + image grayi = float_to_image(net->w, net->h, 3, graypixs); + show_image(grayi, "gray"); + show_image(origi, "orig"); + cvWaitKey(0); + */ + *net->seen += net->batch; + forward_network_gpu(net); + + fill_gpu(imlayer.outputs*imlayer.batch, 0, imerror, 1); + copy_gpu(anet->inputs*anet->batch, imlayer.output_gpu, 1, anet->input_gpu, 1); + fill_gpu(anet->inputs*anet->batch, .95, anet->truth_gpu, 1); + anet->delta_gpu = imerror; + forward_network_gpu(anet); + backward_network_gpu(anet); + + scal_gpu(imlayer.outputs*imlayer.batch, 1./100., net->layers[net->n-1].delta_gpu, 1); + + scal_gpu(imlayer.outputs*imlayer.batch, 1, imerror, 1); + + printf("realness %f\n", cuda_mag_array(imerror, imlayer.outputs*imlayer.batch)); + printf("features %f\n", cuda_mag_array(net->layers[net->n-1].delta_gpu, imlayer.outputs*imlayer.batch)); + + axpy_gpu(imlayer.outputs*imlayer.batch, 1, imerror, 1, net->layers[net->n-1].delta_gpu, 1); + + backward_network_gpu(net); + + + gloss += *net->cost /(net->subdivisions*net->batch); + + for(k = 0; k < net->batch; ++k){ + int index = j*net->batch + k; + copy_cpu(imlayer.outputs, imlayer.output + k*imlayer.outputs, 1, gray.X.vals[index], 1); + } + } + harmless_update_network_gpu(anet); + + data merge = concat_data(train, gray); + //randomize_data(merge); + float aloss = train_network(anet, merge); + + update_network_gpu(net); + +#ifdef OPENCV + if(display){ + image im = float_to_image(anet->w, anet->h, anet->c, gray.X.vals[0]); + image im2 = float_to_image(anet->w, anet->h, anet->c, train.X.vals[0]); + show_image(im, "gen", 1); + show_image(im2, "train", 1); + } +#endif + free_data(merge); + free_data(train); + free_data(gray); + if (aloss_avg < 0) aloss_avg = aloss; + aloss_avg = aloss_avg*.9 + aloss*.1; + gloss_avg = gloss_avg*.9 + gloss*.1; + + printf("%d: gen: %f, adv: %f | gen_avg: %f, adv_avg: %f, %f rate, %lf seconds, %d images\n", i, gloss, aloss, gloss_avg, aloss_avg, get_current_rate(net), sec(clock()-time), i*imgs); + if(i%1000==0){ + char buff[256]; + sprintf(buff, "%s/%s_%d.weights", backup_directory, base, i); + save_weights(net, buff); + sprintf(buff, "%s/%s_%d.weights", backup_directory, abase, i); + save_weights(anet, buff); + } + if(i%100==0){ + char buff[256]; + sprintf(buff, "%s/%s.backup", backup_directory, base); + save_weights(net, buff); + sprintf(buff, "%s/%s.backup", backup_directory, abase); + save_weights(anet, buff); + } + } + char buff[256]; + sprintf(buff, "%s/%s_final.weights", backup_directory, base); + save_weights(net, buff); +#endif +} + +/* + void train_lsd2(char *cfgfile, char *weightfile, char *acfgfile, char *aweightfile, int clear) + { +#ifdef GPU +char *train_images = "/home/pjreddie/data/coco/trainvalno5k.txt"; +char *backup_directory = "/home/pjreddie/backup/"; +srand(time(0)); +char *base = basecfg(cfgfile); +printf("%s\n", base); +network net = parse_network_cfg(cfgfile); +if(weightfile){ +load_weights(&net, weightfile); +} +if(clear) *net->seen = 0; + +char *abase = basecfg(acfgfile); +network anet = parse_network_cfg(acfgfile); +if(aweightfile){ +load_weights(&anet, aweightfile); +} +if(clear) *anet->seen = 0; + +int i, j, k; +layer imlayer = {0}; +for (i = 0; i < net->n; ++i) { +if (net->layers[i].out_c == 3) { +imlayer = net->layers[i]; +break; +} +} + +printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); +int imgs = net->batch*net->subdivisions; +i = *net->seen/imgs; +data train, buffer; + + +list *plist = get_paths(train_images); +//int N = plist->size; +char **paths = (char **)list_to_array(plist); + +load_args args = {0}; +args.w = net->w; +args.h = net->h; +args.paths = paths; +args.n = imgs; +args.m = plist->size; +args.d = &buffer; + +args.min = net->min_crop; +args.max = net->max_crop; +args.angle = net->angle; +args.aspect = net->aspect; +args.exposure = net->exposure; +args.saturation = net->saturation; +args.hue = net->hue; +args.size = net->w; +args.type = CLASSIFICATION_DATA; +args.classes = 1; +char *ls[1] = {"coco"}; +args.labels = ls; + +pthread_t load_thread = load_data_in_thread(args); +clock_t time; + +network_state gstate = {0}; +gstate.index = 0; +gstate.net = net; +int x_size = get_network_input_size(net)*net->batch; +int y_size = 1*net->batch; +gstate.input = cuda_make_array(0, x_size); +gstate.truth = 0; +gstate.delta = 0; +gstate.train = 1; +float *X = calloc(x_size, sizeof(float)); +float *y = calloc(y_size, sizeof(float)); + +network_state astate = {0}; +astate.index = 0; +astate.net = anet; +int ay_size = get_network_output_size(anet)*anet->batch; +astate.input = 0; +astate.truth = 0; +astate.delta = 0; +astate.train = 1; + +float *imerror = cuda_make_array(0, imlayer.outputs); +float *ones_gpu = cuda_make_array(0, ay_size); +fill_gpu(ay_size, 1, ones_gpu, 1); + +float aloss_avg = -1; +float gloss_avg = -1; + +//data generated = copy_data(train); + +while (get_current_batch(net) < net->max_batches) { + i += 1; + time=clock(); + pthread_join(load_thread, 0); + train = buffer; + load_thread = load_data_in_thread(args); + + printf("Loaded: %lf seconds\n", sec(clock()-time)); + + data generated = copy_data(train); + time=clock(); + float gloss = 0; + + for(j = 0; j < net->subdivisions; ++j){ + get_next_batch(train, net->batch, j*net->batch, X, y); + cuda_push_array(gstate.input, X, x_size); + *net->seen += net->batch; + forward_network_gpu(net, gstate); + + fill_gpu(imlayer.outputs, 0, imerror, 1); + astate.input = imlayer.output_gpu; + astate.delta = imerror; + astate.truth = ones_gpu; + forward_network_gpu(anet, astate); + backward_network_gpu(anet, astate); + + scal_gpu(imlayer.outputs, 1, imerror, 1); + axpy_gpu(imlayer.outputs, 1, imerror, 1, imlayer.delta_gpu, 1); + + backward_network_gpu(net, gstate); + + printf("features %f\n", cuda_mag_array(imlayer.delta_gpu, imlayer.outputs)); + printf("realness %f\n", cuda_mag_array(imerror, imlayer.outputs)); + + gloss += get_network_cost(net) /(net->subdivisions*net->batch); + + cuda_pull_array(imlayer.output_gpu, imlayer.output, imlayer.outputs*imlayer.batch); + for(k = 0; k < net->batch; ++k){ + int index = j*net->batch + k; + copy_cpu(imlayer.outputs, imlayer.output + k*imlayer.outputs, 1, generated.X.vals[index], 1); + generated.y.vals[index][0] = 0; + } + } + harmless_update_network_gpu(anet); + + data merge = concat_data(train, generated); + randomize_data(merge); + float aloss = train_network(anet, merge); + + update_network_gpu(net); + update_network_gpu(anet); + free_data(merge); + free_data(train); + free_data(generated); + if (aloss_avg < 0) aloss_avg = aloss; + aloss_avg = aloss_avg*.9 + aloss*.1; + gloss_avg = gloss_avg*.9 + gloss*.1; + + printf("%d: gen: %f, adv: %f | gen_avg: %f, adv_avg: %f, %f rate, %lf seconds, %d images\n", i, gloss, aloss, gloss_avg, aloss_avg, get_current_rate(net), sec(clock()-time), i*imgs); + if(i%1000==0){ + char buff[256]; + sprintf(buff, "%s/%s_%d.weights", backup_directory, base, i); + save_weights(net, buff); + sprintf(buff, "%s/%s_%d.weights", backup_directory, abase, i); + save_weights(anet, buff); + } + if(i%100==0){ + char buff[256]; + sprintf(buff, "%s/%s.backup", backup_directory, base); + save_weights(net, buff); + sprintf(buff, "%s/%s.backup", backup_directory, abase); + save_weights(anet, buff); + } +} +char buff[256]; +sprintf(buff, "%s/%s_final.weights", backup_directory, base); +save_weights(net, buff); +#endif +} +*/ + +/* + void train_lsd(char *cfgfile, char *weightfile, int clear) + { + char *train_images = "/home/pjreddie/data/coco/trainvalno5k.txt"; + char *backup_directory = "/home/pjreddie/backup/"; + srand(time(0)); + char *base = basecfg(cfgfile); + printf("%s\n", base); + float avg_loss = -1; + network net = parse_network_cfg(cfgfile); + if(weightfile){ + load_weights(&net, weightfile); + } + if(clear) *net->seen = 0; + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + int imgs = net->batch*net->subdivisions; + int i = *net->seen/imgs; + data train, buffer; + + + list *plist = get_paths(train_images); +//int N = plist->size; +char **paths = (char **)list_to_array(plist); + +load_args args = {0}; +args.w = net->w; +args.h = net->h; +args.paths = paths; +args.n = imgs; +args.m = plist->size; +args.d = &buffer; + +args.min = net->min_crop; +args.max = net->max_crop; +args.angle = net->angle; +args.aspect = net->aspect; +args.exposure = net->exposure; +args.saturation = net->saturation; +args.hue = net->hue; +args.size = net->w; +args.type = CLASSIFICATION_DATA; +args.classes = 1; +char *ls[1] = {"coco"}; +args.labels = ls; + +pthread_t load_thread = load_data_in_thread(args); +clock_t time; +//while(i*imgs < N*120){ +while(get_current_batch(net) < net->max_batches){ +i += 1; +time=clock(); +pthread_join(load_thread, 0); +train = buffer; +load_thread = load_data_in_thread(args); + +printf("Loaded: %lf seconds\n", sec(clock()-time)); + +time=clock(); +float loss = train_network(net, train); +if (avg_loss < 0) avg_loss = loss; +avg_loss = avg_loss*.9 + loss*.1; + +printf("%d: %f, %f avg, %f rate, %lf seconds, %d images\n", i, loss, avg_loss, get_current_rate(net), sec(clock()-time), i*imgs); +if(i%1000==0){ +char buff[256]; +sprintf(buff, "%s/%s_%d.weights", backup_directory, base, i); +save_weights(net, buff); +} +if(i%100==0){ +char buff[256]; +sprintf(buff, "%s/%s.backup", backup_directory, base); +save_weights(net, buff); +} +free_data(train); +} +char buff[256]; +sprintf(buff, "%s/%s_final.weights", backup_directory, base); +save_weights(net, buff); +} +*/ + +void test_lsd(char *cfg, char *weights, char *filename, int gray) +{ + network *net = load_network(cfg, weights, 0); + set_batch_network(net, 1); + srand(2222222); + + clock_t time; + char buff[256]; + char *input = buff; + int i, imlayer = 0; + + for (i = 0; i < net->n; ++i) { + if (net->layers[i].out_c == 3) { + imlayer = i; + printf("%d\n", i); + break; + } + } + + while(1){ + if(filename){ + strncpy(input, filename, 256); + }else{ + printf("Enter Image Path: "); + fflush(stdout); + input = fgets(input, 256, stdin); + if(!input) return; + strtok(input, "\n"); + } + image im = load_image_color(input, 0, 0); + image resized = resize_min(im, net->w); + image crop = crop_image(resized, (resized.w - net->w)/2, (resized.h - net->h)/2, net->w, net->h); + if(gray) grayscale_image_3c(crop); + + float *X = crop.data; + time=clock(); + network_predict(net, X); + image out = get_network_image_layer(net, imlayer); + //yuv_to_rgb(out); + constrain_image(out); + printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time)); + save_image(out, "out"); + show_image(out, "out", 1); + show_image(crop, "crop", 0); + + free_image(im); + free_image(resized); + free_image(crop); + if (filename) break; + } +} + + +void run_lsd(int argc, char **argv) +{ + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + + int clear = find_arg(argc, argv, "-clear"); + int display = find_arg(argc, argv, "-display"); + int batches = find_int_arg(argc, argv, "-b", 0); + char *file = find_char_arg(argc, argv, "-file", "/home/pjreddie/data/imagenet/imagenet1k.train.list"); + + char *cfg = argv[3]; + char *weights = (argc > 4) ? argv[4] : 0; + char *filename = (argc > 5) ? argv[5] : 0; + char *acfg = argv[5]; + char *aweights = (argc > 6) ? argv[6] : 0; + //if(0==strcmp(argv[2], "train")) train_lsd(cfg, weights, clear); + //else if(0==strcmp(argv[2], "train2")) train_lsd2(cfg, weights, acfg, aweights, clear); + //else if(0==strcmp(argv[2], "traincolor")) train_colorizer(cfg, weights, acfg, aweights, clear); + //else if(0==strcmp(argv[2], "train3")) train_lsd3(argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], clear); + if(0==strcmp(argv[2], "traingan")) train_dcgan(cfg, weights, acfg, aweights, clear, display, file, batches); + else if(0==strcmp(argv[2], "trainprog")) train_prog(cfg, weights, acfg, aweights, clear, display, file, batches); + else if(0==strcmp(argv[2], "traincolor")) train_colorizer(cfg, weights, acfg, aweights, clear, display); + else if(0==strcmp(argv[2], "gan")) test_dcgan(cfg, weights); + else if(0==strcmp(argv[2], "inter")) inter_dcgan(cfg, weights); + else if(0==strcmp(argv[2], "test")) test_lsd(cfg, weights, filename, 0); + else if(0==strcmp(argv[2], "color")) test_lsd(cfg, weights, filename, 1); + /* + else if(0==strcmp(argv[2], "valid")) validate_lsd(cfg, weights); + */ +} diff --git a/hanzi_detection/examples/nightmare.c b/hanzi_detection/examples/nightmare.c new file mode 100755 index 0000000..2978eb6 --- /dev/null +++ b/hanzi_detection/examples/nightmare.c @@ -0,0 +1,414 @@ +#include "darknet.h" + +#include + +// ./darknet nightmare cfg/extractor.recon.cfg ~/trained/yolo-coco.conv frame6.png -reconstruct -iters 500 -i 3 -lambda .1 -rate .01 -smooth 2 + +float abs_mean(float *x, int n) +{ + int i; + float sum = 0; + for (i = 0; i < n; ++i){ + sum += fabs(x[i]); + } + return sum/n; +} + +void calculate_loss(float *output, float *delta, int n, float thresh) +{ + int i; + float mean = mean_array(output, n); + float var = variance_array(output, n); + for(i = 0; i < n; ++i){ + if(delta[i] > mean + thresh*sqrt(var)) delta[i] = output[i]; + else delta[i] = 0; + } +} + +void optimize_picture(network *net, image orig, int max_layer, float scale, float rate, float thresh, int norm) +{ + //scale_image(orig, 2); + //translate_image(orig, -1); + net->n = max_layer + 1; + + int dx = rand()%16 - 8; + int dy = rand()%16 - 8; + int flip = rand()%2; + + image crop = crop_image(orig, dx, dy, orig.w, orig.h); + image im = resize_image(crop, (int)(orig.w * scale), (int)(orig.h * scale)); + if(flip) flip_image(im); + + resize_network(net, im.w, im.h); + layer last = net->layers[net->n-1]; + //net->layers[net->n - 1].activation = LINEAR; + + image delta = make_image(im.w, im.h, im.c); + +#ifdef GPU + net->delta_gpu = cuda_make_array(delta.data, im.w*im.h*im.c); + copy_cpu(net->inputs, im.data, 1, net->input, 1); + + forward_network_gpu(net); + copy_gpu(last.outputs, last.output_gpu, 1, last.delta_gpu, 1); + + cuda_pull_array(last.delta_gpu, last.delta, last.outputs); + calculate_loss(last.delta, last.delta, last.outputs, thresh); + cuda_push_array(last.delta_gpu, last.delta, last.outputs); + + backward_network_gpu(net); + + cuda_pull_array(net->delta_gpu, delta.data, im.w*im.h*im.c); + cuda_free(net->delta_gpu); + net->delta_gpu = 0; +#else + printf("\nnet: %d %d %d im: %d %d %d\n", net->w, net->h, net->inputs, im.w, im.h, im.c); + copy_cpu(net->inputs, im.data, 1, net->input, 1); + net->delta = delta.data; + forward_network(net); + copy_cpu(last.outputs, last.output, 1, last.delta, 1); + calculate_loss(last.output, last.delta, last.outputs, thresh); + backward_network(net); +#endif + + if(flip) flip_image(delta); + //normalize_array(delta.data, delta.w*delta.h*delta.c); + image resized = resize_image(delta, orig.w, orig.h); + image out = crop_image(resized, -dx, -dy, orig.w, orig.h); + + /* + image g = grayscale_image(out); + free_image(out); + out = g; + */ + + //rate = rate / abs_mean(out.data, out.w*out.h*out.c); + image gray = make_image(out.w, out.h, out.c); + fill_image(gray, .5); + axpy_cpu(orig.w*orig.h*orig.c, -1, orig.data, 1, gray.data, 1); + axpy_cpu(orig.w*orig.h*orig.c, .1, gray.data, 1, out.data, 1); + + if(norm) normalize_array(out.data, out.w*out.h*out.c); + axpy_cpu(orig.w*orig.h*orig.c, rate, out.data, 1, orig.data, 1); + + /* + normalize_array(orig.data, orig.w*orig.h*orig.c); + scale_image(orig, sqrt(var)); + translate_image(orig, mean); + */ + + //translate_image(orig, 1); + //scale_image(orig, .5); + //normalize_image(orig); + + constrain_image(orig); + + free_image(crop); + free_image(im); + free_image(delta); + free_image(resized); + free_image(out); + +} + +void smooth(image recon, image update, float lambda, int num) +{ + int i, j, k; + int ii, jj; + for(k = 0; k < recon.c; ++k){ + for(j = 0; j < recon.h; ++j){ + for(i = 0; i < recon.w; ++i){ + int out_index = i + recon.w*(j + recon.h*k); + for(jj = j-num; jj <= j + num && jj < recon.h; ++jj){ + if (jj < 0) continue; + for(ii = i-num; ii <= i + num && ii < recon.w; ++ii){ + if (ii < 0) continue; + int in_index = ii + recon.w*(jj + recon.h*k); + update.data[out_index] += lambda * (recon.data[in_index] - recon.data[out_index]); + } + } + } + } + } +} + +void reconstruct_picture(network *net, float *features, image recon, image update, float rate, float momentum, float lambda, int smooth_size, int iters) +{ + int iter = 0; + for (iter = 0; iter < iters; ++iter) { + image delta = make_image(recon.w, recon.h, recon.c); + +#ifdef GPU + layer l = get_network_output_layer(net); + cuda_push_array(net->input_gpu, recon.data, recon.w*recon.h*recon.c); + //cuda_push_array(net->truth_gpu, features, net->truths); + net->delta_gpu = cuda_make_array(delta.data, delta.w*delta.h*delta.c); + + forward_network_gpu(net); + cuda_push_array(l.delta_gpu, features, l.outputs); + axpy_gpu(l.outputs, -1, l.output_gpu, 1, l.delta_gpu, 1); + backward_network_gpu(net); + + cuda_pull_array(net->delta_gpu, delta.data, delta.w*delta.h*delta.c); + + cuda_free(net->delta_gpu); +#else + net->input = recon.data; + net->delta = delta.data; + net->truth = features; + + forward_network(net); + backward_network(net); +#endif + + //normalize_array(delta.data, delta.w*delta.h*delta.c); + axpy_cpu(recon.w*recon.h*recon.c, 1, delta.data, 1, update.data, 1); + //smooth(recon, update, lambda, smooth_size); + + axpy_cpu(recon.w*recon.h*recon.c, rate, update.data, 1, recon.data, 1); + scal_cpu(recon.w*recon.h*recon.c, momentum, update.data, 1); + + float mag = mag_array(delta.data, recon.w*recon.h*recon.c); + printf("mag: %f\n", mag); + //scal_cpu(recon.w*recon.h*recon.c, 600/mag, recon.data, 1); + + constrain_image(recon); + free_image(delta); + } +} + +/* +void run_lsd(int argc, char **argv) +{ + srand(0); + if(argc < 3){ + fprintf(stderr, "usage: %s %s [cfg] [weights] [image] [options! (optional)]\n", argv[0], argv[1]); + return; + } + + char *cfg = argv[2]; + char *weights = argv[3]; + char *input = argv[4]; + + int norm = find_int_arg(argc, argv, "-norm", 1); + int rounds = find_int_arg(argc, argv, "-rounds", 1); + int iters = find_int_arg(argc, argv, "-iters", 10); + float rate = find_float_arg(argc, argv, "-rate", .04); + float momentum = find_float_arg(argc, argv, "-momentum", .9); + float lambda = find_float_arg(argc, argv, "-lambda", .01); + char *prefix = find_char_arg(argc, argv, "-prefix", 0); + int reconstruct = find_arg(argc, argv, "-reconstruct"); + int smooth_size = find_int_arg(argc, argv, "-smooth", 1); + + network net = parse_network_cfg(cfg); + load_weights(&net, weights); + char *cfgbase = basecfg(cfg); + char *imbase = basecfg(input); + + set_batch_network(&net, 1); + image im = load_image_color(input, 0, 0); + + float *features = 0; + image update; + if (reconstruct){ + im = letterbox_image(im, net->w, net->h); + + int zz = 0; + network_predict(net, im.data); + image out_im = get_network_image(net); + image crop = crop_image(out_im, zz, zz, out_im.w-2*zz, out_im.h-2*zz); + //flip_image(crop); + image f_im = resize_image(crop, out_im.w, out_im.h); + free_image(crop); + printf("%d features\n", out_im.w*out_im.h*out_im.c); + + + im = resize_image(im, im.w, im.h); + f_im = resize_image(f_im, f_im.w, f_im.h); + features = f_im.data; + + int i; + for(i = 0; i < 14*14*512; ++i){ + features[i] += rand_uniform(-.19, .19); + } + + free_image(im); + im = make_random_image(im.w, im.h, im.c); + update = make_image(im.w, im.h, im.c); + + } + + int e; + int n; + for(e = 0; e < rounds; ++e){ + fprintf(stderr, "Iteration: "); + fflush(stderr); + for(n = 0; n < iters; ++n){ + fprintf(stderr, "%d, ", n); + fflush(stderr); + if(reconstruct){ + reconstruct_picture(net, features, im, update, rate, momentum, lambda, smooth_size, 1); + //if ((n+1)%30 == 0) rate *= .5; + show_image(im, "reconstruction"); +#ifdef OPENCV + cvWaitKey(10); +#endif + }else{ + int layer = max_layer + rand()%range - range/2; + int octave = rand()%octaves; + optimize_picture(&net, im, layer, 1/pow(1.33333333, octave), rate, thresh, norm); + } + } + fprintf(stderr, "done\n"); + char buff[256]; + if (prefix){ + sprintf(buff, "%s/%s_%s_%d_%06d",prefix, imbase, cfgbase, max_layer, e); + }else{ + sprintf(buff, "%s_%s_%d_%06d",imbase, cfgbase, max_layer, e); + } + printf("%d %s\n", e, buff); + save_image(im, buff); + //show_image(im, buff); + //cvWaitKey(0); + + if(rotate){ + image rot = rotate_image(im, rotate); + free_image(im); + im = rot; + } + image crop = crop_image(im, im.w * (1. - zoom)/2., im.h * (1.-zoom)/2., im.w*zoom, im.h*zoom); + image resized = resize_image(crop, im.w, im.h); + free_image(im); + free_image(crop); + im = resized; + } +} +*/ + +void run_nightmare(int argc, char **argv) +{ + srand(0); + if(argc < 4){ + fprintf(stderr, "usage: %s %s [cfg] [weights] [image] [layer] [options! (optional)]\n", argv[0], argv[1]); + return; + } + + char *cfg = argv[2]; + char *weights = argv[3]; + char *input = argv[4]; + int max_layer = atoi(argv[5]); + + int range = find_int_arg(argc, argv, "-range", 1); + int norm = find_int_arg(argc, argv, "-norm", 1); + int rounds = find_int_arg(argc, argv, "-rounds", 1); + int iters = find_int_arg(argc, argv, "-iters", 10); + int octaves = find_int_arg(argc, argv, "-octaves", 4); + float zoom = find_float_arg(argc, argv, "-zoom", 1.); + float rate = find_float_arg(argc, argv, "-rate", .04); + float thresh = find_float_arg(argc, argv, "-thresh", 1.); + float rotate = find_float_arg(argc, argv, "-rotate", 0); + float momentum = find_float_arg(argc, argv, "-momentum", .9); + float lambda = find_float_arg(argc, argv, "-lambda", .01); + char *prefix = find_char_arg(argc, argv, "-prefix", 0); + int reconstruct = find_arg(argc, argv, "-reconstruct"); + int smooth_size = find_int_arg(argc, argv, "-smooth", 1); + + network *net = load_network(cfg, weights, 0); + char *cfgbase = basecfg(cfg); + char *imbase = basecfg(input); + + set_batch_network(net, 1); + image im = load_image_color(input, 0, 0); + if(0){ + float scale = 1; + if(im.w > 512 || im.h > 512){ + if(im.w > im.h) scale = 512.0/im.w; + else scale = 512.0/im.h; + } + image resized = resize_image(im, scale*im.w, scale*im.h); + free_image(im); + im = resized; + } + //im = letterbox_image(im, net->w, net->h); + + float *features = 0; + image update; + if (reconstruct){ + net->n = max_layer; + im = letterbox_image(im, net->w, net->h); + //resize_network(&net, im.w, im.h); + + network_predict(net, im.data); + if(net->layers[net->n-1].type == REGION){ + printf("region!\n"); + zero_objectness(net->layers[net->n-1]); + } + image out_im = copy_image(get_network_image(net)); + /* + image crop = crop_image(out_im, zz, zz, out_im.w-2*zz, out_im.h-2*zz); + //flip_image(crop); + image f_im = resize_image(crop, out_im.w, out_im.h); + free_image(crop); + */ + printf("%d features\n", out_im.w*out_im.h*out_im.c); + + features = out_im.data; + + /* + int i; + for(i = 0; i < 14*14*512; ++i){ + //features[i] += rand_uniform(-.19, .19); + } + free_image(im); + im = make_random_image(im.w, im.h, im.c); + */ + update = make_image(im.w, im.h, im.c); + } + + int e; + int n; + for(e = 0; e < rounds; ++e){ + fprintf(stderr, "Iteration: "); + fflush(stderr); + for(n = 0; n < iters; ++n){ + fprintf(stderr, "%d, ", n); + fflush(stderr); + if(reconstruct){ + reconstruct_picture(net, features, im, update, rate, momentum, lambda, smooth_size, 1); + //if ((n+1)%30 == 0) rate *= .5; + show_image(im, "reconstruction", 10); + }else{ + int layer = max_layer + rand()%range - range/2; + int octave = rand()%octaves; + optimize_picture(net, im, layer, 1/pow(1.33333333, octave), rate, thresh, norm); + } + } + fprintf(stderr, "done\n"); + if(0){ + image g = grayscale_image(im); + free_image(im); + im = g; + } + char buff[256]; + if (prefix){ + sprintf(buff, "%s/%s_%s_%d_%06d",prefix, imbase, cfgbase, max_layer, e); + }else{ + sprintf(buff, "%s_%s_%d_%06d",imbase, cfgbase, max_layer, e); + } + printf("%d %s\n", e, buff); + save_image(im, buff); + //show_image(im, buff, 0); + + if(rotate){ + image rot = rotate_image(im, rotate); + free_image(im); + im = rot; + } + image crop = crop_image(im, im.w * (1. - zoom)/2., im.h * (1.-zoom)/2., im.w*zoom, im.h*zoom); + image resized = resize_image(crop, im.w, im.h); + free_image(im); + free_image(crop); + im = resized; + } +} + diff --git a/hanzi_detection/examples/regressor.c b/hanzi_detection/examples/regressor.c new file mode 100755 index 0000000..20cec0f --- /dev/null +++ b/hanzi_detection/examples/regressor.c @@ -0,0 +1,240 @@ +#include "darknet.h" +#include +#include + +void train_regressor(char *datacfg, char *cfgfile, char *weightfile, int *gpus, int ngpus, int clear) +{ + int i; + + float avg_loss = -1; + char *base = basecfg(cfgfile); + printf("%s\n", base); + printf("%d\n", ngpus); + network **nets = calloc(ngpus, sizeof(network*)); + + srand(time(0)); + int seed = rand(); + for(i = 0; i < ngpus; ++i){ + srand(seed); +#ifdef GPU + cuda_set_device(gpus[i]); +#endif + nets[i] = load_network(cfgfile, weightfile, clear); + nets[i]->learning_rate *= ngpus; + } + srand(time(0)); + network *net = nets[0]; + + int imgs = net->batch * net->subdivisions * ngpus; + + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + list *options = read_data_cfg(datacfg); + + char *backup_directory = option_find_str(options, "backup", "/backup/"); + char *train_list = option_find_str(options, "train", "data/train.list"); + int classes = option_find_int(options, "classes", 1); + + list *plist = get_paths(train_list); + char **paths = (char **)list_to_array(plist); + printf("%d\n", plist->size); + int N = plist->size; + clock_t time; + + load_args args = {0}; + args.w = net->w; + args.h = net->h; + args.threads = 32; + args.classes = classes; + + args.min = net->min_ratio*net->w; + args.max = net->max_ratio*net->w; + args.angle = net->angle; + args.aspect = net->aspect; + args.exposure = net->exposure; + args.saturation = net->saturation; + args.hue = net->hue; + args.size = net->w; + + args.paths = paths; + args.n = imgs; + args.m = N; + args.type = REGRESSION_DATA; + + data train; + data buffer; + pthread_t load_thread; + args.d = &buffer; + load_thread = load_data(args); + + int epoch = (*net->seen)/N; + while(get_current_batch(net) < net->max_batches || net->max_batches == 0){ + time=clock(); + + pthread_join(load_thread, 0); + train = buffer; + load_thread = load_data(args); + + printf("Loaded: %lf seconds\n", sec(clock()-time)); + time=clock(); + + float loss = 0; +#ifdef GPU + if(ngpus == 1){ + loss = train_network(net, train); + } else { + loss = train_networks(nets, ngpus, train, 4); + } +#else + loss = train_network(net, train); +#endif + if(avg_loss == -1) avg_loss = loss; + avg_loss = avg_loss*.9 + loss*.1; + printf("%ld, %.3f: %f, %f avg, %f rate, %lf seconds, %ld images\n", get_current_batch(net), (float)(*net->seen)/N, loss, avg_loss, get_current_rate(net), sec(clock()-time), *net->seen); + free_data(train); + if(*net->seen/N > epoch){ + epoch = *net->seen/N; + char buff[256]; + sprintf(buff, "%s/%s_%d.weights",backup_directory,base, epoch); + save_weights(net, buff); + } + if(get_current_batch(net)%100 == 0){ + char buff[256]; + sprintf(buff, "%s/%s.backup",backup_directory,base); + save_weights(net, buff); + } + } + char buff[256]; + sprintf(buff, "%s/%s.weights", backup_directory, base); + save_weights(net, buff); + + free_network(net); + free_ptrs((void**)paths, plist->size); + free_list(plist); + free(base); +} + +void predict_regressor(char *cfgfile, char *weightfile, char *filename) +{ + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + srand(2222222); + + clock_t time; + char buff[256]; + char *input = buff; + while(1){ + if(filename){ + strncpy(input, filename, 256); + }else{ + printf("Enter Image Path: "); + fflush(stdout); + input = fgets(input, 256, stdin); + if(!input) return; + strtok(input, "\n"); + } + image im = load_image_color(input, 0, 0); + image sized = letterbox_image(im, net->w, net->h); + + float *X = sized.data; + time=clock(); + float *predictions = network_predict(net, X); + printf("Predicted: %f\n", predictions[0]); + printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time)); + free_image(im); + free_image(sized); + if (filename) break; + } +} + + +void demo_regressor(char *datacfg, char *cfgfile, char *weightfile, int cam_index, const char *filename) +{ +#ifdef OPENCV + printf("Regressor Demo\n"); + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + + srand(2222222); + list *options = read_data_cfg(datacfg); + int classes = option_find_int(options, "classes", 1); + char *name_list = option_find_str(options, "names", 0); + char **names = get_labels(name_list); + + void * cap = open_video_stream(filename, cam_index, 0,0,0); + if(!cap) error("Couldn't connect to webcam.\n"); + float fps = 0; + + while(1){ + struct timeval tval_before, tval_after, tval_result; + gettimeofday(&tval_before, NULL); + + image in = get_image_from_stream(cap); + image crop = center_crop_image(in, net->w, net->h); + grayscale_image_3c(crop); + + float *predictions = network_predict(net, crop.data); + + printf("\033[2J"); + printf("\033[1;1H"); + printf("\nFPS:%.0f\n",fps); + + int i; + for(i = 0; i < classes; ++i){ + printf("%s: %f\n", names[i], predictions[i]); + } + + show_image(crop, "Regressor", 10); + free_image(in); + free_image(crop); + + gettimeofday(&tval_after, NULL); + timersub(&tval_after, &tval_before, &tval_result); + float curr = 1000000.f/((long int)tval_result.tv_usec); + fps = .9*fps + .1*curr; + } +#endif +} + + +void run_regressor(int argc, char **argv) +{ + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + + char *gpu_list = find_char_arg(argc, argv, "-gpus", 0); + int *gpus = 0; + int gpu = 0; + int ngpus = 0; + if(gpu_list){ + printf("%s\n", gpu_list); + int len = strlen(gpu_list); + ngpus = 1; + int i; + for(i = 0; i < len; ++i){ + if (gpu_list[i] == ',') ++ngpus; + } + gpus = calloc(ngpus, sizeof(int)); + for(i = 0; i < ngpus; ++i){ + gpus[i] = atoi(gpu_list); + gpu_list = strchr(gpu_list, ',')+1; + } + } else { + gpu = gpu_index; + gpus = &gpu; + ngpus = 1; + } + + int cam_index = find_int_arg(argc, argv, "-c", 0); + int clear = find_arg(argc, argv, "-clear"); + char *data = argv[3]; + char *cfg = argv[4]; + char *weights = (argc > 5) ? argv[5] : 0; + char *filename = (argc > 6) ? argv[6]: 0; + if(0==strcmp(argv[2], "test")) predict_regressor(data, cfg, weights); + else if(0==strcmp(argv[2], "train")) train_regressor(data, cfg, weights, gpus, ngpus, clear); + else if(0==strcmp(argv[2], "demo")) demo_regressor(data, cfg, weights, cam_index, filename); +} + + diff --git a/hanzi_detection/examples/rnn.c b/hanzi_detection/examples/rnn.c new file mode 100755 index 0000000..5d49eaa --- /dev/null +++ b/hanzi_detection/examples/rnn.c @@ -0,0 +1,542 @@ +#include "darknet.h" + +#include + +typedef struct { + float *x; + float *y; +} float_pair; + +unsigned char **load_files(char *filename, int *n) +{ + list *paths = get_paths(filename); + *n = paths->size; + unsigned char **contents = calloc(*n, sizeof(char *)); + int i; + node *x = paths->front; + for(i = 0; i < *n; ++i){ + contents[i] = read_file((char *)x->val); + x = x->next; + } + return contents; +} + +int *read_tokenized_data(char *filename, size_t *read) +{ + size_t size = 512; + size_t count = 0; + FILE *fp = fopen(filename, "r"); + int *d = calloc(size, sizeof(int)); + int n, one; + one = fscanf(fp, "%d", &n); + while(one == 1){ + ++count; + if(count > size){ + size = size*2; + d = realloc(d, size*sizeof(int)); + } + d[count-1] = n; + one = fscanf(fp, "%d", &n); + } + fclose(fp); + d = realloc(d, count*sizeof(int)); + *read = count; + return d; +} + +char **read_tokens(char *filename, size_t *read) +{ + size_t size = 512; + size_t count = 0; + FILE *fp = fopen(filename, "r"); + char **d = calloc(size, sizeof(char *)); + char *line; + while((line=fgetl(fp)) != 0){ + ++count; + if(count > size){ + size = size*2; + d = realloc(d, size*sizeof(char *)); + } + if(0==strcmp(line, "")) line = "\n"; + d[count-1] = line; + } + fclose(fp); + d = realloc(d, count*sizeof(char *)); + *read = count; + return d; +} + + +float_pair get_rnn_token_data(int *tokens, size_t *offsets, int characters, size_t len, int batch, int steps) +{ + float *x = calloc(batch * steps * characters, sizeof(float)); + float *y = calloc(batch * steps * characters, sizeof(float)); + int i,j; + for(i = 0; i < batch; ++i){ + for(j = 0; j < steps; ++j){ + int curr = tokens[(offsets[i])%len]; + int next = tokens[(offsets[i] + 1)%len]; + + x[(j*batch + i)*characters + curr] = 1; + y[(j*batch + i)*characters + next] = 1; + + offsets[i] = (offsets[i] + 1) % len; + + if(curr >= characters || curr < 0 || next >= characters || next < 0){ + error("Bad char"); + } + } + } + float_pair p; + p.x = x; + p.y = y; + return p; +} + +float_pair get_seq2seq_data(char **source, char **dest, int n, int characters, size_t len, int batch, int steps) +{ + int i,j; + float *x = calloc(batch * steps * characters, sizeof(float)); + float *y = calloc(batch * steps * characters, sizeof(float)); + for(i = 0; i < batch; ++i){ + int index = rand()%n; + //int slen = strlen(source[index]); + //int dlen = strlen(dest[index]); + for(j = 0; j < steps; ++j){ + unsigned char curr = source[index][j]; + unsigned char next = dest[index][j]; + + x[(j*batch + i)*characters + curr] = 1; + y[(j*batch + i)*characters + next] = 1; + + if(curr > 255 || curr <= 0 || next > 255 || next <= 0){ + /*text[(index+j+2)%len] = 0; + printf("%ld %d %d %d %d\n", index, j, len, (int)text[index+j], (int)text[index+j+1]); + printf("%s", text+index); + */ + error("Bad char"); + } + } + } + float_pair p; + p.x = x; + p.y = y; + return p; +} + +float_pair get_rnn_data(unsigned char *text, size_t *offsets, int characters, size_t len, int batch, int steps) +{ + float *x = calloc(batch * steps * characters, sizeof(float)); + float *y = calloc(batch * steps * characters, sizeof(float)); + int i,j; + for(i = 0; i < batch; ++i){ + for(j = 0; j < steps; ++j){ + unsigned char curr = text[(offsets[i])%len]; + unsigned char next = text[(offsets[i] + 1)%len]; + + x[(j*batch + i)*characters + curr] = 1; + y[(j*batch + i)*characters + next] = 1; + + offsets[i] = (offsets[i] + 1) % len; + + if(curr > 255 || curr <= 0 || next > 255 || next <= 0){ + /*text[(index+j+2)%len] = 0; + printf("%ld %d %d %d %d\n", index, j, len, (int)text[index+j], (int)text[index+j+1]); + printf("%s", text+index); + */ + error("Bad char"); + } + } + } + float_pair p; + p.x = x; + p.y = y; + return p; +} + +void train_char_rnn(char *cfgfile, char *weightfile, char *filename, int clear, int tokenized) +{ + srand(time(0)); + unsigned char *text = 0; + int *tokens = 0; + size_t size; + if(tokenized){ + tokens = read_tokenized_data(filename, &size); + } else { + text = read_file(filename); + size = strlen((const char*)text); + } + + char *backup_directory = "/home/pjreddie/backup/"; + char *base = basecfg(cfgfile); + fprintf(stderr, "%s\n", base); + float avg_loss = -1; + network *net = load_network(cfgfile, weightfile, clear); + + int inputs = net->inputs; + fprintf(stderr, "Learning Rate: %g, Momentum: %g, Decay: %g, Inputs: %d %d %d\n", net->learning_rate, net->momentum, net->decay, inputs, net->batch, net->time_steps); + int batch = net->batch; + int steps = net->time_steps; + if(clear) *net->seen = 0; + int i = (*net->seen)/net->batch; + + int streams = batch/steps; + size_t *offsets = calloc(streams, sizeof(size_t)); + int j; + for(j = 0; j < streams; ++j){ + offsets[j] = rand_size_t()%size; + } + + clock_t time; + while(get_current_batch(net) < net->max_batches){ + i += 1; + time=clock(); + float_pair p; + if(tokenized){ + p = get_rnn_token_data(tokens, offsets, inputs, size, streams, steps); + }else{ + p = get_rnn_data(text, offsets, inputs, size, streams, steps); + } + + copy_cpu(net->inputs*net->batch, p.x, 1, net->input, 1); + copy_cpu(net->truths*net->batch, p.y, 1, net->truth, 1); + float loss = train_network_datum(net) / (batch); + free(p.x); + free(p.y); + if (avg_loss < 0) avg_loss = loss; + avg_loss = avg_loss*.9 + loss*.1; + + size_t chars = get_current_batch(net)*batch; + fprintf(stderr, "%d: %f, %f avg, %f rate, %lf seconds, %f epochs\n", i, loss, avg_loss, get_current_rate(net), sec(clock()-time), (float) chars/size); + + for(j = 0; j < streams; ++j){ + //printf("%d\n", j); + if(rand()%64 == 0){ + //fprintf(stderr, "Reset\n"); + offsets[j] = rand_size_t()%size; + reset_network_state(net, j); + } + } + + if(i%10000==0){ + char buff[256]; + sprintf(buff, "%s/%s_%d.weights", backup_directory, base, i); + save_weights(net, buff); + } + if(i%100==0){ + char buff[256]; + sprintf(buff, "%s/%s.backup", backup_directory, base); + save_weights(net, buff); + } + } + char buff[256]; + sprintf(buff, "%s/%s_final.weights", backup_directory, base); + save_weights(net, buff); +} + +void print_symbol(int n, char **tokens){ + if(tokens){ + printf("%s ", tokens[n]); + } else { + printf("%c", n); + } +} + +void test_char_rnn(char *cfgfile, char *weightfile, int num, char *seed, float temp, int rseed, char *token_file) +{ + char **tokens = 0; + if(token_file){ + size_t n; + tokens = read_tokens(token_file, &n); + } + + srand(rseed); + char *base = basecfg(cfgfile); + fprintf(stderr, "%s\n", base); + + network *net = load_network(cfgfile, weightfile, 0); + int inputs = net->inputs; + + int i, j; + for(i = 0; i < net->n; ++i) net->layers[i].temperature = temp; + int c = 0; + int len = strlen(seed); + float *input = calloc(inputs, sizeof(float)); + + /* + fill_cpu(inputs, 0, input, 1); + for(i = 0; i < 10; ++i){ + network_predict(net, input); + } + fill_cpu(inputs, 0, input, 1); + */ + + for(i = 0; i < len-1; ++i){ + c = seed[i]; + input[c] = 1; + network_predict(net, input); + input[c] = 0; + print_symbol(c, tokens); + } + if(len) c = seed[len-1]; + print_symbol(c, tokens); + for(i = 0; i < num; ++i){ + input[c] = 1; + float *out = network_predict(net, input); + input[c] = 0; + for(j = 32; j < 127; ++j){ + //printf("%d %c %f\n",j, j, out[j]); + } + for(j = 0; j < inputs; ++j){ + if (out[j] < .0001) out[j] = 0; + } + c = sample_array(out, inputs); + print_symbol(c, tokens); + } + printf("\n"); +} + +void test_tactic_rnn_multi(char *cfgfile, char *weightfile, int num, float temp, int rseed, char *token_file) +{ + char **tokens = 0; + if(token_file){ + size_t n; + tokens = read_tokens(token_file, &n); + } + + srand(rseed); + char *base = basecfg(cfgfile); + fprintf(stderr, "%s\n", base); + + network *net = load_network(cfgfile, weightfile, 0); + int inputs = net->inputs; + + int i, j; + for(i = 0; i < net->n; ++i) net->layers[i].temperature = temp; + int c = 0; + float *input = calloc(inputs, sizeof(float)); + float *out = 0; + + while(1){ + reset_network_state(net, 0); + while((c = getc(stdin)) != EOF && c != 0){ + input[c] = 1; + out = network_predict(net, input); + input[c] = 0; + } + for(i = 0; i < num; ++i){ + for(j = 0; j < inputs; ++j){ + if (out[j] < .0001) out[j] = 0; + } + int next = sample_array(out, inputs); + if(c == '.' && next == '\n') break; + c = next; + print_symbol(c, tokens); + + input[c] = 1; + out = network_predict(net, input); + input[c] = 0; + } + printf("\n"); + } +} + +void test_tactic_rnn(char *cfgfile, char *weightfile, int num, float temp, int rseed, char *token_file) +{ + char **tokens = 0; + if(token_file){ + size_t n; + tokens = read_tokens(token_file, &n); + } + + srand(rseed); + char *base = basecfg(cfgfile); + fprintf(stderr, "%s\n", base); + + network *net = load_network(cfgfile, weightfile, 0); + int inputs = net->inputs; + + int i, j; + for(i = 0; i < net->n; ++i) net->layers[i].temperature = temp; + int c = 0; + float *input = calloc(inputs, sizeof(float)); + float *out = 0; + + while((c = getc(stdin)) != EOF){ + input[c] = 1; + out = network_predict(net, input); + input[c] = 0; + } + for(i = 0; i < num; ++i){ + for(j = 0; j < inputs; ++j){ + if (out[j] < .0001) out[j] = 0; + } + int next = sample_array(out, inputs); + if(c == '.' && next == '\n') break; + c = next; + print_symbol(c, tokens); + + input[c] = 1; + out = network_predict(net, input); + input[c] = 0; + } + printf("\n"); +} + +void valid_tactic_rnn(char *cfgfile, char *weightfile, char *seed) +{ + char *base = basecfg(cfgfile); + fprintf(stderr, "%s\n", base); + + network *net = load_network(cfgfile, weightfile, 0); + int inputs = net->inputs; + + int count = 0; + int words = 1; + int c; + int len = strlen(seed); + float *input = calloc(inputs, sizeof(float)); + int i; + for(i = 0; i < len; ++i){ + c = seed[i]; + input[(int)c] = 1; + network_predict(net, input); + input[(int)c] = 0; + } + float sum = 0; + c = getc(stdin); + float log2 = log(2); + int in = 0; + while(c != EOF){ + int next = getc(stdin); + if(next == EOF) break; + if(next < 0 || next >= 255) error("Out of range character"); + + input[c] = 1; + float *out = network_predict(net, input); + input[c] = 0; + + if(c == '.' && next == '\n') in = 0; + if(!in) { + if(c == '>' && next == '>'){ + in = 1; + ++words; + } + c = next; + continue; + } + ++count; + sum += log(out[next])/log2; + c = next; + printf("%d %d Perplexity: %4.4f Word Perplexity: %4.4f\n", count, words, pow(2, -sum/count), pow(2, -sum/words)); + } +} + +void valid_char_rnn(char *cfgfile, char *weightfile, char *seed) +{ + char *base = basecfg(cfgfile); + fprintf(stderr, "%s\n", base); + + network *net = load_network(cfgfile, weightfile, 0); + int inputs = net->inputs; + + int count = 0; + int words = 1; + int c; + int len = strlen(seed); + float *input = calloc(inputs, sizeof(float)); + int i; + for(i = 0; i < len; ++i){ + c = seed[i]; + input[(int)c] = 1; + network_predict(net, input); + input[(int)c] = 0; + } + float sum = 0; + c = getc(stdin); + float log2 = log(2); + while(c != EOF){ + int next = getc(stdin); + if(next == EOF) break; + if(next < 0 || next >= 255) error("Out of range character"); + ++count; + if(next == ' ' || next == '\n' || next == '\t') ++words; + input[c] = 1; + float *out = network_predict(net, input); + input[c] = 0; + sum += log(out[next])/log2; + c = next; + printf("%d BPC: %4.4f Perplexity: %4.4f Word Perplexity: %4.4f\n", count, -sum/count, pow(2, -sum/count), pow(2, -sum/words)); + } +} + +void vec_char_rnn(char *cfgfile, char *weightfile, char *seed) +{ + char *base = basecfg(cfgfile); + fprintf(stderr, "%s\n", base); + + network *net = load_network(cfgfile, weightfile, 0); + int inputs = net->inputs; + + int c; + int seed_len = strlen(seed); + float *input = calloc(inputs, sizeof(float)); + int i; + char *line; + while((line=fgetl(stdin)) != 0){ + reset_network_state(net, 0); + for(i = 0; i < seed_len; ++i){ + c = seed[i]; + input[(int)c] = 1; + network_predict(net, input); + input[(int)c] = 0; + } + strip(line); + int str_len = strlen(line); + for(i = 0; i < str_len; ++i){ + c = line[i]; + input[(int)c] = 1; + network_predict(net, input); + input[(int)c] = 0; + } + c = ' '; + input[(int)c] = 1; + network_predict(net, input); + input[(int)c] = 0; + + layer l = net->layers[0]; + #ifdef GPU + cuda_pull_array(l.output_gpu, l.output, l.outputs); + #endif + printf("%s", line); + for(i = 0; i < l.outputs; ++i){ + printf(",%g", l.output[i]); + } + printf("\n"); + } +} + +void run_char_rnn(int argc, char **argv) +{ + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + char *filename = find_char_arg(argc, argv, "-file", "data/shakespeare.txt"); + char *seed = find_char_arg(argc, argv, "-seed", "\n\n"); + int len = find_int_arg(argc, argv, "-len", 1000); + float temp = find_float_arg(argc, argv, "-temp", .7); + int rseed = find_int_arg(argc, argv, "-srand", time(0)); + int clear = find_arg(argc, argv, "-clear"); + int tokenized = find_arg(argc, argv, "-tokenized"); + char *tokens = find_char_arg(argc, argv, "-tokens", 0); + + char *cfg = argv[3]; + char *weights = (argc > 4) ? argv[4] : 0; + if(0==strcmp(argv[2], "train")) train_char_rnn(cfg, weights, filename, clear, tokenized); + else if(0==strcmp(argv[2], "valid")) valid_char_rnn(cfg, weights, seed); + else if(0==strcmp(argv[2], "validtactic")) valid_tactic_rnn(cfg, weights, seed); + else if(0==strcmp(argv[2], "vec")) vec_char_rnn(cfg, weights, seed); + else if(0==strcmp(argv[2], "generate")) test_char_rnn(cfg, weights, len, seed, temp, rseed, tokens); + else if(0==strcmp(argv[2], "generatetactic")) test_tactic_rnn(cfg, weights, len, temp, rseed, tokens); +} diff --git a/hanzi_detection/examples/rnn_vid.c b/hanzi_detection/examples/rnn_vid.c new file mode 100755 index 0000000..e887923 --- /dev/null +++ b/hanzi_detection/examples/rnn_vid.c @@ -0,0 +1,208 @@ +#include "darknet.h" + +#ifdef OPENCV +image get_image_from_stream(CvCapture *cap); +image ipl_to_image(IplImage* src); + +void reconstruct_picture(network net, float *features, image recon, image update, float rate, float momentum, float lambda, int smooth_size, int iters); + + +typedef struct { + float *x; + float *y; +} float_pair; + +float_pair get_rnn_vid_data(network net, char **files, int n, int batch, int steps) +{ + int b; + assert(net.batch == steps + 1); + image out_im = get_network_image(net); + int output_size = out_im.w*out_im.h*out_im.c; + printf("%d %d %d\n", out_im.w, out_im.h, out_im.c); + float *feats = calloc(net.batch*batch*output_size, sizeof(float)); + for(b = 0; b < batch; ++b){ + int input_size = net.w*net.h*net.c; + float *input = calloc(input_size*net.batch, sizeof(float)); + char *filename = files[rand()%n]; + CvCapture *cap = cvCaptureFromFile(filename); + int frames = cvGetCaptureProperty(cap, CV_CAP_PROP_FRAME_COUNT); + int index = rand() % (frames - steps - 2); + if (frames < (steps + 4)){ + --b; + free(input); + continue; + } + + printf("frames: %d, index: %d\n", frames, index); + cvSetCaptureProperty(cap, CV_CAP_PROP_POS_FRAMES, index); + + int i; + for(i = 0; i < net.batch; ++i){ + IplImage* src = cvQueryFrame(cap); + image im = ipl_to_image(src); + rgbgr_image(im); + image re = resize_image(im, net.w, net.h); + //show_image(re, "loaded"); + //cvWaitKey(10); + memcpy(input + i*input_size, re.data, input_size*sizeof(float)); + free_image(im); + free_image(re); + } + float *output = network_predict(net, input); + + free(input); + + for(i = 0; i < net.batch; ++i){ + memcpy(feats + (b + i*batch)*output_size, output + i*output_size, output_size*sizeof(float)); + } + + cvReleaseCapture(&cap); + } + + //printf("%d %d %d\n", out_im.w, out_im.h, out_im.c); + float_pair p = {0}; + p.x = feats; + p.y = feats + output_size*batch; //+ out_im.w*out_im.h*out_im.c; + + return p; +} + + +void train_vid_rnn(char *cfgfile, char *weightfile) +{ + char *train_videos = "data/vid/train.txt"; + char *backup_directory = "/home/pjreddie/backup/"; + srand(time(0)); + char *base = basecfg(cfgfile); + printf("%s\n", base); + float avg_loss = -1; + network net = parse_network_cfg(cfgfile); + if(weightfile){ + load_weights(&net, weightfile); + } + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net.learning_rate, net.momentum, net.decay); + int imgs = net.batch*net.subdivisions; + int i = *net.seen/imgs; + + list *plist = get_paths(train_videos); + int N = plist->size; + char **paths = (char **)list_to_array(plist); + clock_t time; + int steps = net.time_steps; + int batch = net.batch / net.time_steps; + + network extractor = parse_network_cfg("cfg/extractor.cfg"); + load_weights(&extractor, "/home/pjreddie/trained/yolo-coco.conv"); + + while(get_current_batch(net) < net.max_batches){ + i += 1; + time=clock(); + float_pair p = get_rnn_vid_data(extractor, paths, N, batch, steps); + + copy_cpu(net.inputs*net.batch, p.x, 1, net.input, 1); + copy_cpu(net.truths*net.batch, p.y, 1, net.truth, 1); + float loss = train_network_datum(net) / (net.batch); + + + free(p.x); + if (avg_loss < 0) avg_loss = loss; + avg_loss = avg_loss*.9 + loss*.1; + + fprintf(stderr, "%d: %f, %f avg, %f rate, %lf seconds\n", i, loss, avg_loss, get_current_rate(net), sec(clock()-time)); + if(i%100==0){ + char buff[256]; + sprintf(buff, "%s/%s_%d.weights", backup_directory, base, i); + save_weights(net, buff); + } + if(i%10==0){ + char buff[256]; + sprintf(buff, "%s/%s.backup", backup_directory, base); + save_weights(net, buff); + } + } + char buff[256]; + sprintf(buff, "%s/%s_final.weights", backup_directory, base); + save_weights(net, buff); +} + + +image save_reconstruction(network net, image *init, float *feat, char *name, int i) +{ + image recon; + if (init) { + recon = copy_image(*init); + } else { + recon = make_random_image(net.w, net.h, 3); + } + + image update = make_image(net.w, net.h, 3); + reconstruct_picture(net, feat, recon, update, .01, .9, .1, 2, 50); + char buff[256]; + sprintf(buff, "%s%d", name, i); + save_image(recon, buff); + free_image(update); + return recon; +} + +void generate_vid_rnn(char *cfgfile, char *weightfile) +{ + network extractor = parse_network_cfg("cfg/extractor.recon.cfg"); + load_weights(&extractor, "/home/pjreddie/trained/yolo-coco.conv"); + + network net = parse_network_cfg(cfgfile); + if(weightfile){ + load_weights(&net, weightfile); + } + set_batch_network(&extractor, 1); + set_batch_network(&net, 1); + + int i; + CvCapture *cap = cvCaptureFromFile("/extra/vid/ILSVRC2015/Data/VID/snippets/val/ILSVRC2015_val_00007030.mp4"); + float *feat; + float *next; + image last; + for(i = 0; i < 25; ++i){ + image im = get_image_from_stream(cap); + image re = resize_image(im, extractor.w, extractor.h); + feat = network_predict(extractor, re.data); + if(i > 0){ + printf("%f %f\n", mean_array(feat, 14*14*512), variance_array(feat, 14*14*512)); + printf("%f %f\n", mean_array(next, 14*14*512), variance_array(next, 14*14*512)); + printf("%f\n", mse_array(feat, 14*14*512)); + axpy_cpu(14*14*512, -1, feat, 1, next, 1); + printf("%f\n", mse_array(next, 14*14*512)); + } + next = network_predict(net, feat); + + free_image(im); + + free_image(save_reconstruction(extractor, 0, feat, "feat", i)); + free_image(save_reconstruction(extractor, 0, next, "next", i)); + if (i==24) last = copy_image(re); + free_image(re); + } + for(i = 0; i < 30; ++i){ + next = network_predict(net, next); + image new = save_reconstruction(extractor, &last, next, "new", i); + free_image(last); + last = new; + } +} + +void run_vid_rnn(int argc, char **argv) +{ + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + + char *cfg = argv[3]; + char *weights = (argc > 4) ? argv[4] : 0; + //char *filename = (argc > 5) ? argv[5]: 0; + if(0==strcmp(argv[2], "train")) train_vid_rnn(cfg, weights); + else if(0==strcmp(argv[2], "generate")) generate_vid_rnn(cfg, weights); +} +#else +void run_vid_rnn(int argc, char **argv){} +#endif + diff --git a/hanzi_detection/examples/segmenter.c b/hanzi_detection/examples/segmenter.c new file mode 100755 index 0000000..2e7cea0 --- /dev/null +++ b/hanzi_detection/examples/segmenter.c @@ -0,0 +1,255 @@ +#include "darknet.h" +#include +#include + +void train_segmenter(char *datacfg, char *cfgfile, char *weightfile, int *gpus, int ngpus, int clear, int display) +{ + int i; + + float avg_loss = -1; + char *base = basecfg(cfgfile); + printf("%s\n", base); + printf("%d\n", ngpus); + network **nets = calloc(ngpus, sizeof(network*)); + + srand(time(0)); + int seed = rand(); + for(i = 0; i < ngpus; ++i){ + srand(seed); +#ifdef GPU + cuda_set_device(gpus[i]); +#endif + nets[i] = load_network(cfgfile, weightfile, clear); + nets[i]->learning_rate *= ngpus; + } + srand(time(0)); + network *net = nets[0]; + image pred = get_network_image(net); + + int div = net->w/pred.w; + assert(pred.w * div == net->w); + assert(pred.h * div == net->h); + + int imgs = net->batch * net->subdivisions * ngpus; + + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + list *options = read_data_cfg(datacfg); + + char *backup_directory = option_find_str(options, "backup", "/backup/"); + char *train_list = option_find_str(options, "train", "data/train.list"); + + list *plist = get_paths(train_list); + char **paths = (char **)list_to_array(plist); + printf("%d\n", plist->size); + int N = plist->size; + + load_args args = {0}; + args.w = net->w; + args.h = net->h; + args.threads = 32; + args.scale = div; + + args.min = net->min_crop; + args.max = net->max_crop; + args.angle = net->angle; + args.aspect = net->aspect; + args.exposure = net->exposure; + args.saturation = net->saturation; + args.hue = net->hue; + args.size = net->w; + args.classes = 80; + + args.paths = paths; + args.n = imgs; + args.m = N; + args.type = SEGMENTATION_DATA; + + data train; + data buffer; + pthread_t load_thread; + args.d = &buffer; + load_thread = load_data(args); + + int epoch = (*net->seen)/N; + while(get_current_batch(net) < net->max_batches || net->max_batches == 0){ + double time = what_time_is_it_now(); + + pthread_join(load_thread, 0); + train = buffer; + load_thread = load_data(args); + + printf("Loaded: %lf seconds\n", what_time_is_it_now()-time); + time = what_time_is_it_now(); + + float loss = 0; +#ifdef GPU + if(ngpus == 1){ + loss = train_network(net, train); + } else { + loss = train_networks(nets, ngpus, train, 4); + } +#else + loss = train_network(net, train); +#endif + if(display){ + image tr = float_to_image(net->w/div, net->h/div, 80, train.y.vals[net->batch*(net->subdivisions-1)]); + image im = float_to_image(net->w, net->h, net->c, train.X.vals[net->batch*(net->subdivisions-1)]); + image mask = mask_to_rgb(tr); + image prmask = mask_to_rgb(pred); + show_image(im, "input", 1); + show_image(prmask, "pred", 1); + show_image(mask, "truth", 100); + free_image(mask); + free_image(prmask); + } + if(avg_loss == -1) avg_loss = loss; + avg_loss = avg_loss*.9 + loss*.1; + printf("%ld, %.3f: %f, %f avg, %f rate, %lf seconds, %ld images\n", get_current_batch(net), (float)(*net->seen)/N, loss, avg_loss, get_current_rate(net), what_time_is_it_now()-time, *net->seen); + free_data(train); + if(*net->seen/N > epoch){ + epoch = *net->seen/N; + char buff[256]; + sprintf(buff, "%s/%s_%d.weights",backup_directory,base, epoch); + save_weights(net, buff); + } + if(get_current_batch(net)%100 == 0){ + char buff[256]; + sprintf(buff, "%s/%s.backup",backup_directory,base); + save_weights(net, buff); + } + } + char buff[256]; + sprintf(buff, "%s/%s.weights", backup_directory, base); + save_weights(net, buff); + + free_network(net); + free_ptrs((void**)paths, plist->size); + free_list(plist); + free(base); +} + +void predict_segmenter(char *datafile, char *cfg, char *weights, char *filename) +{ + network *net = load_network(cfg, weights, 0); + set_batch_network(net, 1); + srand(2222222); + + clock_t time; + char buff[256]; + char *input = buff; + while(1){ + if(filename){ + strncpy(input, filename, 256); + }else{ + printf("Enter Image Path: "); + fflush(stdout); + input = fgets(input, 256, stdin); + if(!input) return; + strtok(input, "\n"); + } + image im = load_image_color(input, 0, 0); + image sized = letterbox_image(im, net->w, net->h); + + float *X = sized.data; + time=clock(); + float *predictions = network_predict(net, X); + image pred = get_network_image(net); + image prmask = mask_to_rgb(pred); + printf("Predicted: %f\n", predictions[0]); + printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time)); + show_image(sized, "orig", 1); + show_image(prmask, "pred", 0); + free_image(im); + free_image(sized); + free_image(prmask); + if (filename) break; + } +} + + +void demo_segmenter(char *datacfg, char *cfg, char *weights, int cam_index, const char *filename) +{ +#ifdef OPENCV + printf("Classifier Demo\n"); + network *net = load_network(cfg, weights, 0); + set_batch_network(net, 1); + + srand(2222222); + void * cap = open_video_stream(filename, cam_index, 0,0,0); + + if(!cap) error("Couldn't connect to webcam.\n"); + float fps = 0; + + while(1){ + struct timeval tval_before, tval_after, tval_result; + gettimeofday(&tval_before, NULL); + + image in = get_image_from_stream(cap); + image in_s = letterbox_image(in, net->w, net->h); + + network_predict(net, in_s.data); + + printf("\033[2J"); + printf("\033[1;1H"); + printf("\nFPS:%.0f\n",fps); + + image pred = get_network_image(net); + image prmask = mask_to_rgb(pred); + show_image(prmask, "Segmenter", 10); + + free_image(in_s); + free_image(in); + free_image(prmask); + + gettimeofday(&tval_after, NULL); + timersub(&tval_after, &tval_before, &tval_result); + float curr = 1000000.f/((long int)tval_result.tv_usec); + fps = .9*fps + .1*curr; + } +#endif +} + + +void run_segmenter(int argc, char **argv) +{ + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + + char *gpu_list = find_char_arg(argc, argv, "-gpus", 0); + int *gpus = 0; + int gpu = 0; + int ngpus = 0; + if(gpu_list){ + printf("%s\n", gpu_list); + int len = strlen(gpu_list); + ngpus = 1; + int i; + for(i = 0; i < len; ++i){ + if (gpu_list[i] == ',') ++ngpus; + } + gpus = calloc(ngpus, sizeof(int)); + for(i = 0; i < ngpus; ++i){ + gpus[i] = atoi(gpu_list); + gpu_list = strchr(gpu_list, ',')+1; + } + } else { + gpu = gpu_index; + gpus = &gpu; + ngpus = 1; + } + + int cam_index = find_int_arg(argc, argv, "-c", 0); + int clear = find_arg(argc, argv, "-clear"); + int display = find_arg(argc, argv, "-display"); + char *data = argv[3]; + char *cfg = argv[4]; + char *weights = (argc > 5) ? argv[5] : 0; + char *filename = (argc > 6) ? argv[6]: 0; + if(0==strcmp(argv[2], "test")) predict_segmenter(data, cfg, weights, filename); + else if(0==strcmp(argv[2], "train")) train_segmenter(data, cfg, weights, gpus, ngpus, clear, display); + else if(0==strcmp(argv[2], "demo")) demo_segmenter(data, cfg, weights, cam_index, filename); +} + + diff --git a/hanzi_detection/examples/super.c b/hanzi_detection/examples/super.c new file mode 100755 index 0000000..d34406b --- /dev/null +++ b/hanzi_detection/examples/super.c @@ -0,0 +1,120 @@ +#include "darknet.h" + +void train_super(char *cfgfile, char *weightfile, int clear) +{ + char *train_images = "/data/imagenet/imagenet1k.train.list"; + char *backup_directory = "/home/pjreddie/backup/"; + srand(time(0)); + char *base = basecfg(cfgfile); + printf("%s\n", base); + float avg_loss = -1; + network *net = load_network(cfgfile, weightfile, clear); + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + int imgs = net->batch*net->subdivisions; + int i = *net->seen/imgs; + data train, buffer; + + + list *plist = get_paths(train_images); + //int N = plist->size; + char **paths = (char **)list_to_array(plist); + + load_args args = {0}; + args.w = net->w; + args.h = net->h; + args.scale = 4; + args.paths = paths; + args.n = imgs; + args.m = plist->size; + args.d = &buffer; + args.type = SUPER_DATA; + + pthread_t load_thread = load_data_in_thread(args); + clock_t time; + //while(i*imgs < N*120){ + while(get_current_batch(net) < net->max_batches){ + i += 1; + time=clock(); + pthread_join(load_thread, 0); + train = buffer; + load_thread = load_data_in_thread(args); + + printf("Loaded: %lf seconds\n", sec(clock()-time)); + + time=clock(); + float loss = train_network(net, train); + if (avg_loss < 0) avg_loss = loss; + avg_loss = avg_loss*.9 + loss*.1; + + printf("%d: %f, %f avg, %f rate, %lf seconds, %d images\n", i, loss, avg_loss, get_current_rate(net), sec(clock()-time), i*imgs); + if(i%1000==0){ + char buff[256]; + sprintf(buff, "%s/%s_%d.weights", backup_directory, base, i); + save_weights(net, buff); + } + if(i%100==0){ + char buff[256]; + sprintf(buff, "%s/%s.backup", backup_directory, base); + save_weights(net, buff); + } + free_data(train); + } + char buff[256]; + sprintf(buff, "%s/%s_final.weights", backup_directory, base); + save_weights(net, buff); +} + +void test_super(char *cfgfile, char *weightfile, char *filename) +{ + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + srand(2222222); + + clock_t time; + char buff[256]; + char *input = buff; + while(1){ + if(filename){ + strncpy(input, filename, 256); + }else{ + printf("Enter Image Path: "); + fflush(stdout); + input = fgets(input, 256, stdin); + if(!input) return; + strtok(input, "\n"); + } + image im = load_image_color(input, 0, 0); + resize_network(net, im.w, im.h); + printf("%d %d\n", im.w, im.h); + + float *X = im.data; + time=clock(); + network_predict(net, X); + image out = get_network_image(net); + printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time)); + save_image(out, "out"); + show_image(out, "out", 0); + + free_image(im); + if (filename) break; + } +} + + +void run_super(int argc, char **argv) +{ + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + + char *cfg = argv[3]; + char *weights = (argc > 4) ? argv[4] : 0; + char *filename = (argc > 5) ? argv[5] : 0; + int clear = find_arg(argc, argv, "-clear"); + if(0==strcmp(argv[2], "train")) train_super(cfg, weights, clear); + else if(0==strcmp(argv[2], "test")) test_super(cfg, weights, filename); + /* + else if(0==strcmp(argv[2], "valid")) validate_super(cfg, weights); + */ +} diff --git a/hanzi_detection/examples/swag.c b/hanzi_detection/examples/swag.c new file mode 100755 index 0000000..c22d785 --- /dev/null +++ b/hanzi_detection/examples/swag.c @@ -0,0 +1,83 @@ +#include "darknet.h" +#include + +void train_swag(char *cfgfile, char *weightfile) +{ + char *train_images = "data/voc.0712.trainval"; + char *backup_directory = "/home/pjreddie/backup/"; + srand(time(0)); + char *base = basecfg(cfgfile); + printf("%s\n", base); + float avg_loss = -1; + network net = parse_network_cfg(cfgfile); + if(weightfile){ + load_weights(&net, weightfile); + } + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net.learning_rate, net.momentum, net.decay); + int imgs = net.batch*net.subdivisions; + int i = *net.seen/imgs; + data train, buffer; + + layer l = net.layers[net.n - 1]; + + int side = l.side; + int classes = l.classes; + float jitter = l.jitter; + + list *plist = get_paths(train_images); + //int N = plist->size; + char **paths = (char **)list_to_array(plist); + + load_args args = {0}; + args.w = net.w; + args.h = net.h; + args.paths = paths; + args.n = imgs; + args.m = plist->size; + args.classes = classes; + args.jitter = jitter; + args.num_boxes = side; + args.d = &buffer; + args.type = REGION_DATA; + + pthread_t load_thread = load_data_in_thread(args); + clock_t time; + //while(i*imgs < N*120){ + while(get_current_batch(net) < net.max_batches){ + i += 1; + time=clock(); + pthread_join(load_thread, 0); + train = buffer; + load_thread = load_data_in_thread(args); + + printf("Loaded: %lf seconds\n", sec(clock()-time)); + + time=clock(); + float loss = train_network(net, train); + if (avg_loss < 0) avg_loss = loss; + avg_loss = avg_loss*.9 + loss*.1; + + printf("%d: %f, %f avg, %f rate, %lf seconds, %d images\n", i, loss, avg_loss, get_current_rate(net), sec(clock()-time), i*imgs); + if(i%1000==0 || i == 600){ + char buff[256]; + sprintf(buff, "%s/%s_%d.weights", backup_directory, base, i); + save_weights(net, buff); + } + free_data(train); + } + char buff[256]; + sprintf(buff, "%s/%s_final.weights", backup_directory, base); + save_weights(net, buff); +} + +void run_swag(int argc, char **argv) +{ + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + + char *cfg = argv[3]; + char *weights = (argc > 4) ? argv[4] : 0; + if(0==strcmp(argv[2], "train")) train_swag(cfg, weights); +} diff --git a/hanzi_detection/examples/tag.c b/hanzi_detection/examples/tag.c new file mode 100755 index 0000000..4caf8cb --- /dev/null +++ b/hanzi_detection/examples/tag.c @@ -0,0 +1,140 @@ +#include "darknet.h" + +void train_tag(char *cfgfile, char *weightfile, int clear) +{ + srand(time(0)); + float avg_loss = -1; + char *base = basecfg(cfgfile); + char *backup_directory = "/home/pjreddie/backup/"; + printf("%s\n", base); + network *net = load_network(cfgfile, weightfile, clear); + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + int imgs = 1024; + list *plist = get_paths("/home/pjreddie/tag/train.list"); + char **paths = (char **)list_to_array(plist); + printf("%d\n", plist->size); + int N = plist->size; + clock_t time; + pthread_t load_thread; + data train; + data buffer; + + load_args args = {0}; + args.w = net->w; + args.h = net->h; + + args.min = net->w; + args.max = net->max_crop; + args.size = net->w; + + args.paths = paths; + args.classes = net->outputs; + args.n = imgs; + args.m = N; + args.d = &buffer; + args.type = TAG_DATA; + + args.angle = net->angle; + args.exposure = net->exposure; + args.saturation = net->saturation; + args.hue = net->hue; + + fprintf(stderr, "%d classes\n", net->outputs); + + load_thread = load_data_in_thread(args); + int epoch = (*net->seen)/N; + while(get_current_batch(net) < net->max_batches || net->max_batches == 0){ + time=clock(); + pthread_join(load_thread, 0); + train = buffer; + + load_thread = load_data_in_thread(args); + printf("Loaded: %lf seconds\n", sec(clock()-time)); + time=clock(); + float loss = train_network(net, train); + if(avg_loss == -1) avg_loss = loss; + avg_loss = avg_loss*.9 + loss*.1; + printf("%ld, %.3f: %f, %f avg, %f rate, %lf seconds, %ld images\n", get_current_batch(net), (float)(*net->seen)/N, loss, avg_loss, get_current_rate(net), sec(clock()-time), *net->seen); + free_data(train); + if(*net->seen/N > epoch){ + epoch = *net->seen/N; + char buff[256]; + sprintf(buff, "%s/%s_%d.weights",backup_directory,base, epoch); + save_weights(net, buff); + } + if(get_current_batch(net)%100 == 0){ + char buff[256]; + sprintf(buff, "%s/%s.backup",backup_directory,base); + save_weights(net, buff); + } + } + char buff[256]; + sprintf(buff, "%s/%s.weights", backup_directory, base); + save_weights(net, buff); + + pthread_join(load_thread, 0); + free_data(buffer); + free_network(net); + free_ptrs((void**)paths, plist->size); + free_list(plist); + free(base); +} + +void test_tag(char *cfgfile, char *weightfile, char *filename) +{ + network *net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + srand(2222222); + int i = 0; + char **names = get_labels("data/tags.txt"); + clock_t time; + int indexes[10]; + char buff[256]; + char *input = buff; + int size = net->w; + while(1){ + if(filename){ + strncpy(input, filename, 256); + }else{ + printf("Enter Image Path: "); + fflush(stdout); + input = fgets(input, 256, stdin); + if(!input) return; + strtok(input, "\n"); + } + image im = load_image_color(input, 0, 0); + image r = resize_min(im, size); + resize_network(net, r.w, r.h); + printf("%d %d\n", r.w, r.h); + + float *X = r.data; + time=clock(); + float *predictions = network_predict(net, X); + top_predictions(net, 10, indexes); + printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time)); + for(i = 0; i < 10; ++i){ + int index = indexes[i]; + printf("%.1f%%: %s\n", predictions[index]*100, names[index]); + } + if(r.data != im.data) free_image(r); + free_image(im); + if (filename) break; + } +} + + +void run_tag(int argc, char **argv) +{ + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + + int clear = find_arg(argc, argv, "-clear"); + char *cfg = argv[3]; + char *weights = (argc > 4) ? argv[4] : 0; + char *filename = (argc > 5) ? argv[5] : 0; + if(0==strcmp(argv[2], "train")) train_tag(cfg, weights, clear); + else if(0==strcmp(argv[2], "test")) test_tag(cfg, weights, filename); +} + diff --git a/hanzi_detection/examples/voxel.c b/hanzi_detection/examples/voxel.c new file mode 100755 index 0000000..01ea9bb --- /dev/null +++ b/hanzi_detection/examples/voxel.c @@ -0,0 +1,161 @@ +#include "darknet.h" + +void extract_voxel(char *lfile, char *rfile, char *prefix) +{ +#ifdef OPENCV + int w = 1920; + int h = 1080; + int shift = 0; + int count = 0; + CvCapture *lcap = cvCaptureFromFile(lfile); + CvCapture *rcap = cvCaptureFromFile(rfile); + while(1){ + image l = get_image_from_stream(lcap); + image r = get_image_from_stream(rcap); + if(!l.w || !r.w) break; + if(count%100 == 0) { + shift = best_3d_shift_r(l, r, -l.h/100, l.h/100); + printf("%d\n", shift); + } + image ls = crop_image(l, (l.w - w)/2, (l.h - h)/2, w, h); + image rs = crop_image(r, 105 + (r.w - w)/2, (r.h - h)/2 + shift, w, h); + char buff[256]; + sprintf(buff, "%s_%05d_l", prefix, count); + save_image(ls, buff); + sprintf(buff, "%s_%05d_r", prefix, count); + save_image(rs, buff); + free_image(l); + free_image(r); + free_image(ls); + free_image(rs); + ++count; + } + +#else + printf("need OpenCV for extraction\n"); +#endif +} + +void train_voxel(char *cfgfile, char *weightfile) +{ + char *train_images = "/data/imagenet/imagenet1k.train.list"; + char *backup_directory = "/home/pjreddie/backup/"; + srand(time(0)); + char *base = basecfg(cfgfile); + printf("%s\n", base); + float avg_loss = -1; + network net = parse_network_cfg(cfgfile); + if(weightfile){ + load_weights(&net, weightfile); + } + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net.learning_rate, net.momentum, net.decay); + int imgs = net.batch*net.subdivisions; + int i = *net.seen/imgs; + data train, buffer; + + + list *plist = get_paths(train_images); + //int N = plist->size; + char **paths = (char **)list_to_array(plist); + + load_args args = {0}; + args.w = net.w; + args.h = net.h; + args.scale = 4; + args.paths = paths; + args.n = imgs; + args.m = plist->size; + args.d = &buffer; + args.type = SUPER_DATA; + + pthread_t load_thread = load_data_in_thread(args); + clock_t time; + //while(i*imgs < N*120){ + while(get_current_batch(net) < net.max_batches){ + i += 1; + time=clock(); + pthread_join(load_thread, 0); + train = buffer; + load_thread = load_data_in_thread(args); + + printf("Loaded: %lf seconds\n", sec(clock()-time)); + + time=clock(); + float loss = train_network(net, train); + if (avg_loss < 0) avg_loss = loss; + avg_loss = avg_loss*.9 + loss*.1; + + printf("%d: %f, %f avg, %f rate, %lf seconds, %d images\n", i, loss, avg_loss, get_current_rate(net), sec(clock()-time), i*imgs); + if(i%1000==0){ + char buff[256]; + sprintf(buff, "%s/%s_%d.weights", backup_directory, base, i); + save_weights(net, buff); + } + if(i%100==0){ + char buff[256]; + sprintf(buff, "%s/%s.backup", backup_directory, base); + save_weights(net, buff); + } + free_data(train); + } + char buff[256]; + sprintf(buff, "%s/%s_final.weights", backup_directory, base); + save_weights(net, buff); +} + +void test_voxel(char *cfgfile, char *weightfile, char *filename) +{ + network net = parse_network_cfg(cfgfile); + if(weightfile){ + load_weights(&net, weightfile); + } + set_batch_network(&net, 1); + srand(2222222); + + clock_t time; + char buff[256]; + char *input = buff; + while(1){ + if(filename){ + strncpy(input, filename, 256); + }else{ + printf("Enter Image Path: "); + fflush(stdout); + input = fgets(input, 256, stdin); + if(!input) return; + strtok(input, "\n"); + } + image im = load_image_color(input, 0, 0); + resize_network(&net, im.w, im.h); + printf("%d %d\n", im.w, im.h); + + float *X = im.data; + time=clock(); + network_predict(net, X); + image out = get_network_image(net); + printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time)); + save_image(out, "out"); + + free_image(im); + if (filename) break; + } +} + + +void run_voxel(int argc, char **argv) +{ + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + + char *cfg = argv[3]; + char *weights = (argc > 4) ? argv[4] : 0; + char *filename = (argc > 5) ? argv[5] : 0; + if(0==strcmp(argv[2], "train")) train_voxel(cfg, weights); + else if(0==strcmp(argv[2], "test")) test_voxel(cfg, weights, filename); + else if(0==strcmp(argv[2], "extract")) extract_voxel(argv[3], argv[4], argv[5]); + /* + else if(0==strcmp(argv[2], "valid")) validate_voxel(cfg, weights); + */ +} diff --git a/hanzi_detection/examples/writing.c b/hanzi_detection/examples/writing.c new file mode 100755 index 0000000..1b6ff83 --- /dev/null +++ b/hanzi_detection/examples/writing.c @@ -0,0 +1,144 @@ +#include "darknet.h" + +void train_writing(char *cfgfile, char *weightfile) +{ + char *backup_directory = "/home/pjreddie/backup/"; + srand(time(0)); + float avg_loss = -1; + char *base = basecfg(cfgfile); + printf("%s\n", base); + network net = parse_network_cfg(cfgfile); + if(weightfile){ + load_weights(&net, weightfile); + } + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net.learning_rate, net.momentum, net.decay); + int imgs = net.batch*net.subdivisions; + list *plist = get_paths("figures.list"); + char **paths = (char **)list_to_array(plist); + clock_t time; + int N = plist->size; + printf("N: %d\n", N); + image out = get_network_image(net); + + data train, buffer; + + load_args args = {0}; + args.w = net.w; + args.h = net.h; + args.out_w = out.w; + args.out_h = out.h; + args.paths = paths; + args.n = imgs; + args.m = N; + args.d = &buffer; + args.type = WRITING_DATA; + + pthread_t load_thread = load_data_in_thread(args); + int epoch = (*net.seen)/N; + while(get_current_batch(net) < net.max_batches || net.max_batches == 0){ + time=clock(); + pthread_join(load_thread, 0); + train = buffer; + load_thread = load_data_in_thread(args); + printf("Loaded %lf seconds\n",sec(clock()-time)); + + time=clock(); + float loss = train_network(net, train); + + /* + image pred = float_to_image(64, 64, 1, out); + print_image(pred); + */ + + /* + image im = float_to_image(256, 256, 3, train.X.vals[0]); + image lab = float_to_image(64, 64, 1, train.y.vals[0]); + image pred = float_to_image(64, 64, 1, out); + show_image(im, "image"); + show_image(lab, "label"); + print_image(lab); + show_image(pred, "pred"); + cvWaitKey(0); + */ + + if(avg_loss == -1) avg_loss = loss; + avg_loss = avg_loss*.9 + loss*.1; + printf("%ld, %.3f: %f, %f avg, %f rate, %lf seconds, %ld images\n", get_current_batch(net), (float)(*net.seen)/N, loss, avg_loss, get_current_rate(net), sec(clock()-time), *net.seen); + free_data(train); + if(get_current_batch(net)%100 == 0){ + char buff[256]; + sprintf(buff, "%s/%s_batch_%ld.weights", backup_directory, base, get_current_batch(net)); + save_weights(net, buff); + } + if(*net.seen/N > epoch){ + epoch = *net.seen/N; + char buff[256]; + sprintf(buff, "%s/%s_%d.weights",backup_directory,base, epoch); + save_weights(net, buff); + } + } +} + +void test_writing(char *cfgfile, char *weightfile, char *filename) +{ + network net = parse_network_cfg(cfgfile); + if(weightfile){ + load_weights(&net, weightfile); + } + set_batch_network(&net, 1); + srand(2222222); + clock_t time; + char buff[256]; + char *input = buff; + while(1){ + if(filename){ + strncpy(input, filename, 256); + }else{ + printf("Enter Image Path: "); + fflush(stdout); + input = fgets(input, 256, stdin); + if(!input) return; + strtok(input, "\n"); + } + + image im = load_image_color(input, 0, 0); + resize_network(&net, im.w, im.h); + printf("%d %d %d\n", im.h, im.w, im.c); + float *X = im.data; + time=clock(); + network_predict(net, X); + printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time)); + image pred = get_network_image(net); + + image upsampled = resize_image(pred, im.w, im.h); + image thresh = threshold_image(upsampled, .5); + pred = thresh; + + show_image(pred, "prediction"); + show_image(im, "orig"); +#ifdef OPENCV + cvWaitKey(0); + cvDestroyAllWindows(); +#endif + + free_image(upsampled); + free_image(thresh); + free_image(im); + if (filename) break; + } +} + +void run_writing(int argc, char **argv) +{ + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + + char *cfg = argv[3]; + char *weights = (argc > 4) ? argv[4] : 0; + char *filename = (argc > 5) ? argv[5] : 0; + if(0==strcmp(argv[2], "train")) train_writing(cfg, weights); + else if(0==strcmp(argv[2], "test")) test_writing(cfg, weights, filename); +} + diff --git a/hanzi_detection/examples/yolo.c b/hanzi_detection/examples/yolo.c new file mode 100755 index 0000000..4ddb69a --- /dev/null +++ b/hanzi_detection/examples/yolo.c @@ -0,0 +1,327 @@ +#include "darknet.h" + +char *voc_names[] = {"aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"}; + +void train_yolo(char *cfgfile, char *weightfile) +{ + char *train_images = "/data/voc/train.txt"; + char *backup_directory = "/home/pjreddie/backup/"; + srand(time(0)); + char *base = basecfg(cfgfile); + printf("%s\n", base); + float avg_loss = -1; + network *net = load_network(cfgfile, weightfile, 0); + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + int imgs = net->batch*net->subdivisions; + int i = *net->seen/imgs; + data train, buffer; + + + layer l = net->layers[net->n - 1]; + + int side = l.side; + int classes = l.classes; + float jitter = l.jitter; + + list *plist = get_paths(train_images); + //int N = plist->size; + char **paths = (char **)list_to_array(plist); + + load_args args = {0}; + args.w = net->w; + args.h = net->h; + args.paths = paths; + args.n = imgs; + args.m = plist->size; + args.classes = classes; + args.jitter = jitter; + args.num_boxes = side; + args.d = &buffer; + args.type = REGION_DATA; + + args.angle = net->angle; + args.exposure = net->exposure; + args.saturation = net->saturation; + args.hue = net->hue; + + pthread_t load_thread = load_data_in_thread(args); + clock_t time; + //while(i*imgs < N*120){ + while(get_current_batch(net) < net->max_batches){ + i += 1; + time=clock(); + pthread_join(load_thread, 0); + train = buffer; + load_thread = load_data_in_thread(args); + + printf("Loaded: %lf seconds\n", sec(clock()-time)); + + time=clock(); + float loss = train_network(net, train); + if (avg_loss < 0) avg_loss = loss; + avg_loss = avg_loss*.9 + loss*.1; + + printf("%d: %f, %f avg, %f rate, %lf seconds, %d images\n", i, loss, avg_loss, get_current_rate(net), sec(clock()-time), i*imgs); + if(i%1000==0 || (i < 1000 && i%100 == 0)){ + char buff[256]; + sprintf(buff, "%s/%s_%d.weights", backup_directory, base, i); + save_weights(net, buff); + } + free_data(train); + } + char buff[256]; + sprintf(buff, "%s/%s_final.weights", backup_directory, base); + save_weights(net, buff); +} + +void print_yolo_detections(FILE **fps, char *id, int total, int classes, int w, int h, detection *dets) +{ + int i, j; + for(i = 0; i < total; ++i){ + float xmin = dets[i].bbox.x - dets[i].bbox.w/2.; + float xmax = dets[i].bbox.x + dets[i].bbox.w/2.; + float ymin = dets[i].bbox.y - dets[i].bbox.h/2.; + float ymax = dets[i].bbox.y + dets[i].bbox.h/2.; + + if (xmin < 0) xmin = 0; + if (ymin < 0) ymin = 0; + if (xmax > w) xmax = w; + if (ymax > h) ymax = h; + + for(j = 0; j < classes; ++j){ + if (dets[i].prob[j]) fprintf(fps[j], "%s %f %f %f %f %f\n", id, dets[i].prob[j], + xmin, ymin, xmax, ymax); + } + } +} + +void validate_yolo(char *cfg, char *weights) +{ + network *net = load_network(cfg, weights, 0); + set_batch_network(net, 1); + fprintf(stderr, "Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + srand(time(0)); + + char *base = "results/comp4_det_test_"; + //list *plist = get_paths("data/voc.2007.test"); + list *plist = get_paths("/home/pjreddie/data/voc/2007_test.txt"); + //list *plist = get_paths("data/voc.2012.test"); + char **paths = (char **)list_to_array(plist); + + layer l = net->layers[net->n-1]; + int classes = l.classes; + + int j; + FILE **fps = calloc(classes, sizeof(FILE *)); + for(j = 0; j < classes; ++j){ + char buff[1024]; + snprintf(buff, 1024, "%s%s.txt", base, voc_names[j]); + fps[j] = fopen(buff, "w"); + } + + int m = plist->size; + int i=0; + int t; + + float thresh = .001; + int nms = 1; + float iou_thresh = .5; + + int nthreads = 8; + image *val = calloc(nthreads, sizeof(image)); + image *val_resized = calloc(nthreads, sizeof(image)); + image *buf = calloc(nthreads, sizeof(image)); + image *buf_resized = calloc(nthreads, sizeof(image)); + pthread_t *thr = calloc(nthreads, sizeof(pthread_t)); + + load_args args = {0}; + args.w = net->w; + args.h = net->h; + args.type = IMAGE_DATA; + + for(t = 0; t < nthreads; ++t){ + args.path = paths[i+t]; + args.im = &buf[t]; + args.resized = &buf_resized[t]; + thr[t] = load_data_in_thread(args); + } + time_t start = time(0); + for(i = nthreads; i < m+nthreads; i += nthreads){ + fprintf(stderr, "%d\n", i); + for(t = 0; t < nthreads && i+t-nthreads < m; ++t){ + pthread_join(thr[t], 0); + val[t] = buf[t]; + val_resized[t] = buf_resized[t]; + } + for(t = 0; t < nthreads && i+t < m; ++t){ + args.path = paths[i+t]; + args.im = &buf[t]; + args.resized = &buf_resized[t]; + thr[t] = load_data_in_thread(args); + } + for(t = 0; t < nthreads && i+t-nthreads < m; ++t){ + char *path = paths[i+t-nthreads]; + char *id = basecfg(path); + float *X = val_resized[t].data; + network_predict(net, X); + int w = val[t].w; + int h = val[t].h; + int nboxes = 0; + detection *dets = get_network_boxes(net, w, h, thresh, 0, 0, 0, &nboxes); + if (nms) do_nms_sort(dets, l.side*l.side*l.n, classes, iou_thresh); + print_yolo_detections(fps, id, l.side*l.side*l.n, classes, w, h, dets); + free_detections(dets, nboxes); + free(id); + free_image(val[t]); + free_image(val_resized[t]); + } + } + fprintf(stderr, "Total Detection Time: %f Seconds\n", (double)(time(0) - start)); +} + +void validate_yolo_recall(char *cfg, char *weights) +{ + network *net = load_network(cfg, weights, 0); + set_batch_network(net, 1); + fprintf(stderr, "Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay); + srand(time(0)); + + char *base = "results/comp4_det_test_"; + list *plist = get_paths("data/voc.2007.test"); + char **paths = (char **)list_to_array(plist); + + layer l = net->layers[net->n-1]; + int classes = l.classes; + int side = l.side; + + int j, k; + FILE **fps = calloc(classes, sizeof(FILE *)); + for(j = 0; j < classes; ++j){ + char buff[1024]; + snprintf(buff, 1024, "%s%s.txt", base, voc_names[j]); + fps[j] = fopen(buff, "w"); + } + + int m = plist->size; + int i=0; + + float thresh = .001; + float iou_thresh = .5; + float nms = 0; + + int total = 0; + int correct = 0; + int proposals = 0; + float avg_iou = 0; + + for(i = 0; i < m; ++i){ + char *path = paths[i]; + image orig = load_image_color(path, 0, 0); + image sized = resize_image(orig, net->w, net->h); + char *id = basecfg(path); + network_predict(net, sized.data); + + int nboxes = 0; + detection *dets = get_network_boxes(net, orig.w, orig.h, thresh, 0, 0, 1, &nboxes); + if (nms) do_nms_obj(dets, side*side*l.n, 1, nms); + + char labelpath[4096]; + find_replace(path, "images", "labels", labelpath); + find_replace(labelpath, "JPEGImages", "labels", labelpath); + find_replace(labelpath, ".jpg", ".txt", labelpath); + find_replace(labelpath, ".JPEG", ".txt", labelpath); + + int num_labels = 0; + box_label *truth = read_boxes(labelpath, &num_labels); + for(k = 0; k < side*side*l.n; ++k){ + if(dets[k].objectness > thresh){ + ++proposals; + } + } + for (j = 0; j < num_labels; ++j) { + ++total; + box t = {truth[j].x, truth[j].y, truth[j].w, truth[j].h}; + float best_iou = 0; + for(k = 0; k < side*side*l.n; ++k){ + float iou = box_iou(dets[k].bbox, t); + if(dets[k].objectness > thresh && iou > best_iou){ + best_iou = iou; + } + } + avg_iou += best_iou; + if(best_iou > iou_thresh){ + ++correct; + } + } + + fprintf(stderr, "%5d %5d %5d\tRPs/Img: %.2f\tIOU: %.2f%%\tRecall:%.2f%%\n", i, correct, total, (float)proposals/(i+1), avg_iou*100/total, 100.*correct/total); + free_detections(dets, nboxes); + free(id); + free_image(orig); + free_image(sized); + } +} + +void test_yolo(char *cfgfile, char *weightfile, char *filename, float thresh) +{ + image **alphabet = load_alphabet(); + network *net = load_network(cfgfile, weightfile, 0); + layer l = net->layers[net->n-1]; + set_batch_network(net, 1); + srand(2222222); + clock_t time; + char buff[256]; + char *input = buff; + float nms=.4; + while(1){ + if(filename){ + strncpy(input, filename, 256); + } else { + printf("Enter Image Path: "); + fflush(stdout); + input = fgets(input, 256, stdin); + if(!input) return; + strtok(input, "\n"); + } + image im = load_image_color(input,0,0); + image sized = resize_image(im, net->w, net->h); + float *X = sized.data; + time=clock(); + network_predict(net, X); + printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time)); + + int nboxes = 0; + detection *dets = get_network_boxes(net, 1, 1, thresh, 0, 0, 0, &nboxes); + if (nms) do_nms_sort(dets, l.side*l.side*l.n, l.classes, nms); + + draw_detections(im, dets, l.side*l.side*l.n, thresh, voc_names, alphabet, 20); + save_image(im, "predictions"); + show_image(im, "predictions", 0); + free_detections(dets, nboxes); + free_image(im); + free_image(sized); + if (filename) break; + } +} + +void run_yolo(int argc, char **argv) +{ + char *prefix = find_char_arg(argc, argv, "-prefix", 0); + float thresh = find_float_arg(argc, argv, "-thresh", .2); + int cam_index = find_int_arg(argc, argv, "-c", 0); + int frame_skip = find_int_arg(argc, argv, "-s", 0); + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + + int avg = find_int_arg(argc, argv, "-avg", 1); + char *cfg = argv[3]; + char *weights = (argc > 4) ? argv[4] : 0; + char *filename = (argc > 5) ? argv[5]: 0; + if(0==strcmp(argv[2], "test")) test_yolo(cfg, weights, filename, thresh); + else if(0==strcmp(argv[2], "train")) train_yolo(cfg, weights); + else if(0==strcmp(argv[2], "valid")) validate_yolo(cfg, weights); + else if(0==strcmp(argv[2], "recall")) validate_yolo_recall(cfg, weights); + else if(0==strcmp(argv[2], "demo")) demo(cfg, weights, thresh, cam_index, filename, voc_names, 20, frame_skip, prefix, avg, .5, 0,0,0,0); +} diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0015673f726b2a1ddd43c1758553093b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0015673f726b2a1ddd43c1758553093b.txt new file mode 100644 index 0000000..ce22e09 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0015673f726b2a1ddd43c1758553093b.txt @@ -0,0 +1,4 @@ +0 0.8691860465116279 0.18489583333333331 0.20348837209302326 0.15625 +0 0.5145348837209303 0.7552083333333333 0.20348837209302326 0.15625 +0 0.16279069767441862 0.5703125 0.20348837209302326 0.15625 +0 0.38372093023255816 0.22916666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0030fbc156e567a2c34afe4495318e16.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0030fbc156e567a2c34afe4495318e16.txt new file mode 100644 index 0000000..58bc5ad --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0030fbc156e567a2c34afe4495318e16.txt @@ -0,0 +1,4 @@ +0 0.7965116279069767 0.17708333333333331 0.20348837209302326 0.15625 +0 0.6540697674418604 0.48697916666666663 0.20348837209302326 0.15625 +0 0.1686046511627907 0.5755208333333333 0.20348837209302326 0.15625 +0 0.25872093023255816 0.2864583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0042d7d2797b26fcfc090e27678beedd.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0042d7d2797b26fcfc090e27678beedd.txt new file mode 100644 index 0000000..f47ff26 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0042d7d2797b26fcfc090e27678beedd.txt @@ -0,0 +1,5 @@ +0 0.21220930232558138 0.4348958333333333 0.20348837209302326 0.15625 +0 0.747093023255814 0.1484375 0.20348837209302326 0.15625 +0 0.7703488372093024 0.6770833333333333 0.20348837209302326 0.15625 +0 0.3023255813953488 0.21875 0.20348837209302326 0.15625 +0 0.47093023255813954 0.7239583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0048a76678a29202cf03731f46af9c64.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0048a76678a29202cf03731f46af9c64.txt new file mode 100644 index 0000000..c319f24 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0048a76678a29202cf03731f46af9c64.txt @@ -0,0 +1,4 @@ +0 0.7209302325581395 0.6328125 0.20348837209302326 0.15625 +0 0.3226744186046512 0.19791666666666666 0.20348837209302326 0.15625 +0 0.4273255813953488 0.7473958333333333 0.20348837209302326 0.15625 +0 0.8691860465116279 0.16145833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/00ce931e1afbaf47c62f6078e72014ce.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/00ce931e1afbaf47c62f6078e72014ce.txt new file mode 100644 index 0000000..e116ea2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/00ce931e1afbaf47c62f6078e72014ce.txt @@ -0,0 +1,4 @@ +0 0.6162790697674418 0.71875 0.20348837209302326 0.15625 +0 0.6627906976744186 0.359375 0.20348837209302326 0.15625 +0 0.7063953488372093 0.12239583333333333 0.20348837209302326 0.15625 +0 0.34011627906976744 0.609375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/00de8e4044705679726aa5d933d67552.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/00de8e4044705679726aa5d933d67552.txt new file mode 100644 index 0000000..4902875 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/00de8e4044705679726aa5d933d67552.txt @@ -0,0 +1,4 @@ +0 0.7732558139534884 0.13020833333333331 0.20348837209302326 0.15625 +0 0.3953488372093023 0.5520833333333333 0.20348837209302326 0.15625 +0 0.7558139534883721 0.45572916666666663 0.20348837209302326 0.15625 +0 0.3546511627906977 0.3125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/00e8f9ff61bf4198ea528683f78be58c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/00e8f9ff61bf4198ea528683f78be58c.txt new file mode 100644 index 0000000..de391b3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/00e8f9ff61bf4198ea528683f78be58c.txt @@ -0,0 +1,5 @@ +0 0.6453488372093024 0.12239583333333333 0.20348837209302326 0.15625 +0 0.25290697674418605 0.5078125 0.20348837209302326 0.15625 +0 0.7965116279069767 0.39322916666666663 0.20348837209302326 0.15625 +0 0.7703488372093024 0.6380208333333333 0.20348837209302326 0.15625 +0 0.24709302325581395 0.26822916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/01349f81609688ead3f4922171a990f5.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/01349f81609688ead3f4922171a990f5.txt new file mode 100644 index 0000000..879d622 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/01349f81609688ead3f4922171a990f5.txt @@ -0,0 +1,5 @@ +0 0.6918604651162791 0.6302083333333333 0.20348837209302326 0.15625 +0 0.16279069767441862 0.11197916666666666 0.20348837209302326 0.15625 +0 0.18023255813953487 0.47135416666666663 0.20348837209302326 0.15625 +0 0.8197674418604651 0.3411458333333333 0.20348837209302326 0.15625 +0 0.8226744186046512 0.109375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/018dd492b73e5858609dbf0f5488eb83.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/018dd492b73e5858609dbf0f5488eb83.txt new file mode 100644 index 0000000..b070259 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/018dd492b73e5858609dbf0f5488eb83.txt @@ -0,0 +1,4 @@ +0 0.29941860465116277 0.2630208333333333 0.20348837209302326 0.15625 +0 0.18604651162790697 0.703125 0.20348837209302326 0.15625 +0 0.5174418604651163 0.6927083333333333 0.20348837209302326 0.15625 +0 0.7412790697674418 0.4036458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/01d165ec1170956fe61d09c4e6f622ed.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/01d165ec1170956fe61d09c4e6f622ed.txt new file mode 100644 index 0000000..f25fded --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/01d165ec1170956fe61d09c4e6f622ed.txt @@ -0,0 +1,4 @@ +0 0.3953488372093023 0.3098958333333333 0.20348837209302326 0.15625 +0 0.3168604651162791 0.7317708333333333 0.20348837209302326 0.15625 +0 0.75 0.2552083333333333 0.20348837209302326 0.15625 +0 0.8633720930232558 0.5182291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/01ea835c546ad4d92f0f6b5c96433857.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/01ea835c546ad4d92f0f6b5c96433857.txt new file mode 100644 index 0000000..60d6389 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/01ea835c546ad4d92f0f6b5c96433857.txt @@ -0,0 +1,3 @@ +0 0.18023255813953487 0.578125 0.20348837209302326 0.15625 +0 0.7732558139534884 0.3333333333333333 0.20348837209302326 0.15625 +0 0.8313953488372093 0.6197916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/024a5273d7b06566748bc3af0fd0a5e2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/024a5273d7b06566748bc3af0fd0a5e2.txt new file mode 100644 index 0000000..6994c53 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/024a5273d7b06566748bc3af0fd0a5e2.txt @@ -0,0 +1,4 @@ +0 0.23546511627906977 0.4973958333333333 0.20348837209302326 0.15625 +0 0.5843023255813954 0.3958333333333333 0.20348837209302326 0.15625 +0 0.8197674418604651 0.7630208333333333 0.20348837209302326 0.15625 +0 0.5145348837209303 0.7708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/024a9fcf3c6839003a16f6697b23eb41.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/024a9fcf3c6839003a16f6697b23eb41.txt new file mode 100644 index 0000000..fe8101b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/024a9fcf3c6839003a16f6697b23eb41.txt @@ -0,0 +1,5 @@ +0 0.18313953488372092 0.4661458333333333 0.20348837209302326 0.15625 +0 0.7761627906976744 0.20833333333333331 0.20348837209302326 0.15625 +0 0.40988372093023256 0.23697916666666666 0.20348837209302326 0.15625 +0 0.7587209302325582 0.5104166666666666 0.20348837209302326 0.15625 +0 0.14244186046511628 0.7265625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/024d91a69f693c9f9e3261a11c7ddec3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/024d91a69f693c9f9e3261a11c7ddec3.txt new file mode 100644 index 0000000..c2e8a22 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/024d91a69f693c9f9e3261a11c7ddec3.txt @@ -0,0 +1,4 @@ +0 0.24709302325581395 0.5026041666666666 0.20348837209302326 0.15625 +0 0.6831395348837209 0.5598958333333333 0.20348837209302326 0.15625 +0 0.37209302325581395 0.1640625 0.20348837209302326 0.15625 +0 0.7616279069767442 0.29166666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/03135f6a3cec7f4e3399da4f3680aa67.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/03135f6a3cec7f4e3399da4f3680aa67.txt new file mode 100644 index 0000000..ccd9757 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/03135f6a3cec7f4e3399da4f3680aa67.txt @@ -0,0 +1,4 @@ +0 0.3488372093023256 0.23177083333333331 0.20348837209302326 0.15625 +0 0.14244186046511628 0.4661458333333333 0.20348837209302326 0.15625 +0 0.7180232558139534 0.6666666666666666 0.20348837209302326 0.15625 +0 0.8226744186046512 0.2734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0375e570bedd2c1971f3209966f8a016.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0375e570bedd2c1971f3209966f8a016.txt new file mode 100644 index 0000000..043e950 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0375e570bedd2c1971f3209966f8a016.txt @@ -0,0 +1,5 @@ +0 0.2063953488372093 0.7291666666666666 0.20348837209302326 0.15625 +0 0.5377906976744186 0.6510416666666666 0.20348837209302326 0.15625 +0 0.37790697674418605 0.3125 0.20348837209302326 0.15625 +0 0.688953488372093 0.21614583333333331 0.20348837209302326 0.15625 +0 0.8546511627906976 0.6640625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/03fb416e2ce8e109b230a1a5eef7f4e4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/03fb416e2ce8e109b230a1a5eef7f4e4.txt new file mode 100644 index 0000000..1c604dd --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/03fb416e2ce8e109b230a1a5eef7f4e4.txt @@ -0,0 +1,4 @@ +0 0.28488372093023256 0.26822916666666663 0.20348837209302326 0.15625 +0 0.4622093023255814 0.6145833333333333 0.20348837209302326 0.15625 +0 0.7325581395348837 0.4036458333333333 0.20348837209302326 0.15625 +0 0.6773255813953488 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0421f63e65b44b56c6cd6530680e5548.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0421f63e65b44b56c6cd6530680e5548.txt new file mode 100644 index 0000000..5b175e0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0421f63e65b44b56c6cd6530680e5548.txt @@ -0,0 +1,4 @@ +0 0.7848837209302325 0.08333333333333333 0.20348837209302326 0.15625 +0 0.16569767441860464 0.7760416666666666 0.20348837209302326 0.15625 +0 0.43023255813953487 0.234375 0.20348837209302326 0.15625 +0 0.6482558139534884 0.5442708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/04bc8a6657ead2cb0040495ee2449073.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/04bc8a6657ead2cb0040495ee2449073.txt new file mode 100644 index 0000000..331424f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/04bc8a6657ead2cb0040495ee2449073.txt @@ -0,0 +1,5 @@ +0 0.8372093023255813 0.4765625 0.20348837209302326 0.15625 +0 0.1569767441860465 0.22916666666666666 0.20348837209302326 0.15625 +0 0.4883720930232558 0.5885416666666666 0.20348837209302326 0.15625 +0 0.18604651162790697 0.7864583333333333 0.20348837209302326 0.15625 +0 0.7819767441860465 0.7265625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/04f36d827bf62ba22575845abd2cd686.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/04f36d827bf62ba22575845abd2cd686.txt new file mode 100644 index 0000000..837e538 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/04f36d827bf62ba22575845abd2cd686.txt @@ -0,0 +1,3 @@ +0 0.49127906976744184 0.30729166666666663 0.20348837209302326 0.15625 +0 0.6308139534883721 0.5729166666666666 0.20348837209302326 0.15625 +0 0.25872093023255816 0.6354166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0535f8e873fb35d9908080cfca034c2a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0535f8e873fb35d9908080cfca034c2a.txt new file mode 100644 index 0000000..922cb25 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0535f8e873fb35d9908080cfca034c2a.txt @@ -0,0 +1,5 @@ +0 0.2238372093023256 0.390625 0.20348837209302326 0.15625 +0 0.3808139534883721 0.6770833333333333 0.20348837209302326 0.15625 +0 0.75 0.5703125 0.20348837209302326 0.15625 +0 0.5901162790697674 0.16927083333333331 0.20348837209302326 0.15625 +0 0.2703488372093023 0.1328125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/05baf0f3e50f888066fa7a5089fd9430.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/05baf0f3e50f888066fa7a5089fd9430.txt new file mode 100644 index 0000000..f076ed1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/05baf0f3e50f888066fa7a5089fd9430.txt @@ -0,0 +1,4 @@ +0 0.5668604651162791 0.23177083333333331 0.20348837209302326 0.15625 +0 0.40406976744186046 0.7604166666666666 0.20348837209302326 0.15625 +0 0.20930232558139533 0.453125 0.20348837209302326 0.15625 +0 0.125 0.203125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/05c0562027595fdbe6ea4865b2857d88.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/05c0562027595fdbe6ea4865b2857d88.txt new file mode 100644 index 0000000..8c68470 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/05c0562027595fdbe6ea4865b2857d88.txt @@ -0,0 +1,4 @@ +0 0.7412790697674418 0.1484375 0.20348837209302326 0.15625 +0 0.2761627906976744 0.6145833333333333 0.20348837209302326 0.15625 +0 0.34011627906976744 0.23958333333333331 0.20348837209302326 0.15625 +0 0.6337209302325582 0.4348958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0616cfeaf489be156925e7f72933ad16.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0616cfeaf489be156925e7f72933ad16.txt new file mode 100644 index 0000000..39f36e3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0616cfeaf489be156925e7f72933ad16.txt @@ -0,0 +1,5 @@ +0 0.21220930232558138 0.21614583333333331 0.20348837209302326 0.15625 +0 0.8226744186046512 0.4270833333333333 0.20348837209302326 0.15625 +0 0.25 0.7942708333333333 0.20348837209302326 0.15625 +0 0.7325581395348837 0.1328125 0.20348837209302326 0.15625 +0 0.5116279069767442 0.515625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/063a4a8ad72b7e35028c538ad6ca0054.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/063a4a8ad72b7e35028c538ad6ca0054.txt new file mode 100644 index 0000000..b3df3d6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/063a4a8ad72b7e35028c538ad6ca0054.txt @@ -0,0 +1,4 @@ +0 0.811046511627907 0.2890625 0.20348837209302326 0.15625 +0 0.3313953488372093 0.5416666666666666 0.20348837209302326 0.15625 +0 0.27325581395348836 0.09895833333333333 0.20348837209302326 0.15625 +0 0.7732558139534884 0.75 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/068991d2c91c4557fd3b62caa14ac42b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/068991d2c91c4557fd3b62caa14ac42b.txt new file mode 100644 index 0000000..fab37c8 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/068991d2c91c4557fd3b62caa14ac42b.txt @@ -0,0 +1,4 @@ +0 0.1686046511627907 0.21875 0.20348837209302326 0.15625 +0 0.5232558139534884 0.6171875 0.20348837209302326 0.15625 +0 0.5581395348837209 0.29166666666666663 0.20348837209302326 0.15625 +0 0.12790697674418605 0.4505208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/06bb5442887985888d34813121e4e60f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/06bb5442887985888d34813121e4e60f.txt new file mode 100644 index 0000000..b9d6699 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/06bb5442887985888d34813121e4e60f.txt @@ -0,0 +1,4 @@ +0 0.5668604651162791 0.6458333333333333 0.20348837209302326 0.15625 +0 0.5901162790697674 0.171875 0.20348837209302326 0.15625 +0 0.21220930232558138 0.21875 0.20348837209302326 0.15625 +0 0.2180232558139535 0.5390625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/06c01c623ce3df90cfbcad78608b7e0b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/06c01c623ce3df90cfbcad78608b7e0b.txt new file mode 100644 index 0000000..91dde96 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/06c01c623ce3df90cfbcad78608b7e0b.txt @@ -0,0 +1,4 @@ +0 0.34593023255813954 0.17447916666666666 0.20348837209302326 0.15625 +0 0.6918604651162791 0.5182291666666666 0.20348837209302326 0.15625 +0 0.14534883720930233 0.6666666666666666 0.20348837209302326 0.15625 +0 0.7936046511627907 0.7786458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/06f78cfea588d3ab81e31307cedb40f3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/06f78cfea588d3ab81e31307cedb40f3.txt new file mode 100644 index 0000000..443d9cc --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/06f78cfea588d3ab81e31307cedb40f3.txt @@ -0,0 +1,4 @@ +0 0.7034883720930233 0.109375 0.20348837209302326 0.15625 +0 0.6017441860465116 0.4192708333333333 0.20348837209302326 0.15625 +0 0.5697674418604651 0.65625 0.20348837209302326 0.15625 +0 0.18895348837209303 0.7473958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/07198db7bebe69fdf9123a8878e15fe0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/07198db7bebe69fdf9123a8878e15fe0.txt new file mode 100644 index 0000000..3b75611 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/07198db7bebe69fdf9123a8878e15fe0.txt @@ -0,0 +1,4 @@ +0 0.49709302325581395 0.25260416666666663 0.20348837209302326 0.15625 +0 0.5406976744186046 0.5130208333333333 0.20348837209302326 0.15625 +0 0.4622093023255814 0.7786458333333333 0.20348837209302326 0.15625 +0 0.7819767441860465 0.17447916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/07e0a4d3d6d5d46bc18fc3f86fd8eccd.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/07e0a4d3d6d5d46bc18fc3f86fd8eccd.txt new file mode 100644 index 0000000..54f6dca --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/07e0a4d3d6d5d46bc18fc3f86fd8eccd.txt @@ -0,0 +1,5 @@ +0 0.8023255813953488 0.37760416666666663 0.20348837209302326 0.15625 +0 0.2238372093023256 0.3359375 0.20348837209302326 0.15625 +0 0.13662790697674418 0.625 0.20348837209302326 0.15625 +0 0.46511627906976744 0.7239583333333333 0.20348837209302326 0.15625 +0 0.8401162790697674 0.6770833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0838e809552b0e7687dff54b7d86bf8d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0838e809552b0e7687dff54b7d86bf8d.txt new file mode 100644 index 0000000..34f711c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0838e809552b0e7687dff54b7d86bf8d.txt @@ -0,0 +1,4 @@ +0 0.25290697674418605 0.11197916666666666 0.20348837209302326 0.15625 +0 0.125 0.5625 0.20348837209302326 0.15625 +0 0.8604651162790697 0.4505208333333333 0.20348837209302326 0.15625 +0 0.8459302325581395 0.15104166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/083996edc86518a47d0c162ad619dcca.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/083996edc86518a47d0c162ad619dcca.txt new file mode 100644 index 0000000..4674df6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/083996edc86518a47d0c162ad619dcca.txt @@ -0,0 +1,4 @@ +0 0.24709302325581395 0.5130208333333333 0.20348837209302326 0.15625 +0 0.313953488372093 0.7447916666666666 0.20348837209302326 0.15625 +0 0.7063953488372093 0.5260416666666666 0.20348837209302326 0.15625 +0 0.6104651162790697 0.19791666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/08565520e94a144d9e7724ed9faf6397.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/08565520e94a144d9e7724ed9faf6397.txt new file mode 100644 index 0000000..2dfe2ff --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/08565520e94a144d9e7724ed9faf6397.txt @@ -0,0 +1,5 @@ +0 0.8313953488372093 0.4739583333333333 0.20348837209302326 0.15625 +0 0.5377906976744186 0.23697916666666666 0.20348837209302326 0.15625 +0 0.25872093023255816 0.6536458333333333 0.20348837209302326 0.15625 +0 0.11918604651162791 0.140625 0.20348837209302326 0.15625 +0 0.5261627906976745 0.53125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/08890d707663fddf9b508bf9974438d0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/08890d707663fddf9b508bf9974438d0.txt new file mode 100644 index 0000000..369490a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/08890d707663fddf9b508bf9974438d0.txt @@ -0,0 +1,5 @@ +0 0.46511627906976744 0.29166666666666663 0.20348837209302326 0.15625 +0 0.7790697674418604 0.26041666666666663 0.20348837209302326 0.15625 +0 0.2761627906976744 0.6119791666666666 0.20348837209302326 0.15625 +0 0.6511627906976745 0.5338541666666666 0.20348837209302326 0.15625 +0 0.14534883720930233 0.31510416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/088b1c0b5fa93a460c680481278f5247.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/088b1c0b5fa93a460c680481278f5247.txt new file mode 100644 index 0000000..976b9b6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/088b1c0b5fa93a460c680481278f5247.txt @@ -0,0 +1,5 @@ +0 0.19767441860465115 0.48697916666666663 0.20348837209302326 0.15625 +0 0.7151162790697674 0.5729166666666666 0.20348837209302326 0.15625 +0 0.4883720930232558 0.21354166666666666 0.20348837209302326 0.15625 +0 0.16279069767441862 0.1328125 0.20348837209302326 0.15625 +0 0.21511627906976744 0.7916666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/08a89aa6731e641e7412d3822060b42c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/08a89aa6731e641e7412d3822060b42c.txt new file mode 100644 index 0000000..7c5b958 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/08a89aa6731e641e7412d3822060b42c.txt @@ -0,0 +1,5 @@ +0 0.24127906976744184 0.203125 0.20348837209302326 0.15625 +0 0.30523255813953487 0.6666666666666666 0.20348837209302326 0.15625 +0 0.6482558139534884 0.6067708333333333 0.20348837209302326 0.15625 +0 0.8691860465116279 0.15104166666666666 0.20348837209302326 0.15625 +0 0.35174418604651164 0.41666666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/092d2caa24368f56233612b6019b2cfe.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/092d2caa24368f56233612b6019b2cfe.txt new file mode 100644 index 0000000..62ba8e9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/092d2caa24368f56233612b6019b2cfe.txt @@ -0,0 +1,5 @@ +0 0.563953488372093 0.32291666666666663 0.20348837209302326 0.15625 +0 0.8226744186046512 0.671875 0.20348837209302326 0.15625 +0 0.32848837209302323 0.6848958333333333 0.20348837209302326 0.15625 +0 0.23837209302325582 0.1171875 0.20348837209302326 0.15625 +0 0.14534883720930233 0.3880208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/09aaae767c369d3dcb56095e80518ea9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/09aaae767c369d3dcb56095e80518ea9.txt new file mode 100644 index 0000000..c8a7b9d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/09aaae767c369d3dcb56095e80518ea9.txt @@ -0,0 +1,4 @@ +0 0.563953488372093 0.3958333333333333 0.20348837209302326 0.15625 +0 0.6191860465116279 0.7916666666666666 0.20348837209302326 0.15625 +0 0.29941860465116277 0.7317708333333333 0.20348837209302326 0.15625 +0 0.688953488372093 0.17447916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/09ff8eeb96236d7d7c944c55cb65bf8e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/09ff8eeb96236d7d7c944c55cb65bf8e.txt new file mode 100644 index 0000000..028d88f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/09ff8eeb96236d7d7c944c55cb65bf8e.txt @@ -0,0 +1,4 @@ +0 0.3023255813953488 0.3489583333333333 0.20348837209302326 0.15625 +0 0.18604651162790697 0.71875 0.20348837209302326 0.15625 +0 0.7034883720930233 0.5963541666666666 0.20348837209302326 0.15625 +0 0.7674418604651163 0.2708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0a15af430229d19ba86493002a728d6b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0a15af430229d19ba86493002a728d6b.txt new file mode 100644 index 0000000..879956c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0a15af430229d19ba86493002a728d6b.txt @@ -0,0 +1,5 @@ +0 0.19186046511627908 0.5130208333333333 0.20348837209302326 0.15625 +0 0.5930232558139534 0.6953125 0.20348837209302326 0.15625 +0 0.4883720930232558 0.3567708333333333 0.20348837209302326 0.15625 +0 0.7936046511627907 0.4114583333333333 0.20348837209302326 0.15625 +0 0.3895348837209302 0.12760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0a3fb252edf036d0befc7197abd7afc2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0a3fb252edf036d0befc7197abd7afc2.txt new file mode 100644 index 0000000..f2a6a6b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0a3fb252edf036d0befc7197abd7afc2.txt @@ -0,0 +1,3 @@ +0 0.5581395348837209 0.12760416666666666 0.20348837209302326 0.15625 +0 0.6715116279069767 0.4817708333333333 0.20348837209302326 0.15625 +0 0.3168604651162791 0.5390625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0ac2879f54b40e477f004c5b575e3ae2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0ac2879f54b40e477f004c5b575e3ae2.txt new file mode 100644 index 0000000..7b18dd4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0ac2879f54b40e477f004c5b575e3ae2.txt @@ -0,0 +1,4 @@ +0 0.5813953488372093 0.19791666666666666 0.20348837209302326 0.15625 +0 0.622093023255814 0.4895833333333333 0.20348837209302326 0.15625 +0 0.2645348837209302 0.5494791666666666 0.20348837209302326 0.15625 +0 0.1308139534883721 0.2630208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0ac54a37fbb19e4d38a949b9d213db6f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0ac54a37fbb19e4d38a949b9d213db6f.txt new file mode 100644 index 0000000..7b45bc6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0ac54a37fbb19e4d38a949b9d213db6f.txt @@ -0,0 +1,4 @@ +0 0.5581395348837209 0.6640625 0.20348837209302326 0.15625 +0 0.6831395348837209 0.3671875 0.20348837209302326 0.15625 +0 0.2761627906976744 0.3411458333333333 0.20348837209302326 0.15625 +0 0.875 0.09895833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0ba19a1362f1827134c58420316639ce.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0ba19a1362f1827134c58420316639ce.txt new file mode 100644 index 0000000..0eff920 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0ba19a1362f1827134c58420316639ce.txt @@ -0,0 +1,4 @@ +0 0.31976744186046513 0.5625 0.20348837209302326 0.15625 +0 0.32558139534883723 0.16145833333333331 0.20348837209302326 0.15625 +0 0.7122093023255814 0.4375 0.20348837209302326 0.15625 +0 0.7558139534883721 0.125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0bc9fc26ea8517f1ca84aaa20778d2be.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0bc9fc26ea8517f1ca84aaa20778d2be.txt new file mode 100644 index 0000000..5d7c046 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0bc9fc26ea8517f1ca84aaa20778d2be.txt @@ -0,0 +1,4 @@ +0 0.7790697674418604 0.171875 0.20348837209302326 0.15625 +0 0.14244186046511628 0.6354166666666666 0.20348837209302326 0.15625 +0 0.6482558139534884 0.7864583333333333 0.20348837209302326 0.15625 +0 0.15406976744186046 0.24739583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0bccf4ff604195e928da0f96ce17cb3d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0bccf4ff604195e928da0f96ce17cb3d.txt new file mode 100644 index 0000000..8818973 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0bccf4ff604195e928da0f96ce17cb3d.txt @@ -0,0 +1,4 @@ +0 0.49709302325581395 0.5572916666666666 0.20348837209302326 0.15625 +0 0.15406976744186046 0.15885416666666666 0.20348837209302326 0.15625 +0 0.6453488372093024 0.16145833333333331 0.20348837209302326 0.15625 +0 0.8488372093023255 0.765625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0bddb0e71ae5e10ac50af3998c82aa24.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0bddb0e71ae5e10ac50af3998c82aa24.txt new file mode 100644 index 0000000..888ffbe --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0bddb0e71ae5e10ac50af3998c82aa24.txt @@ -0,0 +1,3 @@ +0 0.44476744186046513 0.29166666666666663 0.20348837209302326 0.15625 +0 0.38372093023255816 0.7213541666666666 0.20348837209302326 0.15625 +0 0.8372093023255813 0.7135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0c9cecb6017cd048c027c5c00a3e005a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0c9cecb6017cd048c027c5c00a3e005a.txt new file mode 100644 index 0000000..7e02a0c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0c9cecb6017cd048c027c5c00a3e005a.txt @@ -0,0 +1,4 @@ +0 0.5 0.3645833333333333 0.20348837209302326 0.15625 +0 0.6686046511627907 0.14583333333333331 0.20348837209302326 0.15625 +0 0.8023255813953488 0.7630208333333333 0.20348837209302326 0.15625 +0 0.14825581395348836 0.6354166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0cbd494511dc9d3f08462aebb3f08a0e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0cbd494511dc9d3f08462aebb3f08a0e.txt new file mode 100644 index 0000000..db79bd6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0cbd494511dc9d3f08462aebb3f08a0e.txt @@ -0,0 +1,5 @@ +0 0.7906976744186046 0.6588541666666666 0.20348837209302326 0.15625 +0 0.14244186046511628 0.4609375 0.20348837209302326 0.15625 +0 0.5843023255813954 0.44010416666666663 0.20348837209302326 0.15625 +0 0.375 0.203125 0.20348837209302326 0.15625 +0 0.8633720930232558 0.16666666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0d420d53d31ad18f63030453ee07df30.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0d420d53d31ad18f63030453ee07df30.txt new file mode 100644 index 0000000..9f56451 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0d420d53d31ad18f63030453ee07df30.txt @@ -0,0 +1,5 @@ +0 0.37209302325581395 0.18489583333333331 0.20348837209302326 0.15625 +0 0.49127906976744184 0.48697916666666663 0.20348837209302326 0.15625 +0 0.6075581395348837 0.7552083333333333 0.20348837209302326 0.15625 +0 0.811046511627907 0.12760416666666666 0.20348837209302326 0.15625 +0 0.8313953488372093 0.4192708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0d50a0f54aec320e588a56d5e608ea3c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0d50a0f54aec320e588a56d5e608ea3c.txt new file mode 100644 index 0000000..b0a7941 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0d50a0f54aec320e588a56d5e608ea3c.txt @@ -0,0 +1,5 @@ +0 0.6511627906976745 0.47135416666666663 0.20348837209302326 0.15625 +0 0.2063953488372093 0.5494791666666666 0.20348837209302326 0.15625 +0 0.8372093023255813 0.23958333333333331 0.20348837209302326 0.15625 +0 0.4476744186046512 0.12239583333333333 0.20348837209302326 0.15625 +0 0.17151162790697674 0.12760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0d7bff55519270e35592453080503caf.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0d7bff55519270e35592453080503caf.txt new file mode 100644 index 0000000..8b6b215 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0d7bff55519270e35592453080503caf.txt @@ -0,0 +1,4 @@ +0 0.5058139534883721 0.328125 0.20348837209302326 0.15625 +0 0.22674418604651161 0.5989583333333333 0.20348837209302326 0.15625 +0 0.15988372093023256 0.36197916666666663 0.20348837209302326 0.15625 +0 0.6569767441860465 0.7473958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0d93825688787383bdfc3928313e6317.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0d93825688787383bdfc3928313e6317.txt new file mode 100644 index 0000000..3edb2dc --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0d93825688787383bdfc3928313e6317.txt @@ -0,0 +1,4 @@ +0 0.7877906976744186 0.36979166666666663 0.20348837209302326 0.15625 +0 0.32558139534883723 0.1171875 0.20348837209302326 0.15625 +0 0.7819767441860465 0.6302083333333333 0.20348837209302326 0.15625 +0 0.32848837209302323 0.5416666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0dd2286d9b48b256cce0dc7f5e787a53.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0dd2286d9b48b256cce0dc7f5e787a53.txt new file mode 100644 index 0000000..42fd260 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0dd2286d9b48b256cce0dc7f5e787a53.txt @@ -0,0 +1,3 @@ +0 0.7790697674418604 0.1953125 0.20348837209302326 0.15625 +0 0.2877906976744186 0.6067708333333333 0.20348837209302326 0.15625 +0 0.8197674418604651 0.6302083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0e4c55874ee43a24a1417bff7d4e3243.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0e4c55874ee43a24a1417bff7d4e3243.txt new file mode 100644 index 0000000..f0ee9a8 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0e4c55874ee43a24a1417bff7d4e3243.txt @@ -0,0 +1,3 @@ +0 0.28488372093023256 0.16666666666666666 0.20348837209302326 0.15625 +0 0.6453488372093024 0.3880208333333333 0.20348837209302326 0.15625 +0 0.18895348837209303 0.7213541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0e7be3751e71b7d2e3a08e7d403339de.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0e7be3751e71b7d2e3a08e7d403339de.txt new file mode 100644 index 0000000..5a4a20c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0e7be3751e71b7d2e3a08e7d403339de.txt @@ -0,0 +1,4 @@ +0 0.38372093023255816 0.5390625 0.20348837209302326 0.15625 +0 0.6656976744186046 0.7734375 0.20348837209302326 0.15625 +0 0.7209302325581395 0.13541666666666666 0.20348837209302326 0.15625 +0 0.688953488372093 0.3958333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0eb4748c9cddfef8e2b3b8d24a527213.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0eb4748c9cddfef8e2b3b8d24a527213.txt new file mode 100644 index 0000000..230e905 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0eb4748c9cddfef8e2b3b8d24a527213.txt @@ -0,0 +1,5 @@ +0 0.6133720930232558 0.7395833333333333 0.20348837209302326 0.15625 +0 0.2703488372093023 0.4192708333333333 0.20348837209302326 0.15625 +0 0.5348837209302325 0.2265625 0.20348837209302326 0.15625 +0 0.7383720930232558 0.5078125 0.20348837209302326 0.15625 +0 0.27906976744186046 0.703125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0f018811743efcc8abaa0291a55e9489.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0f018811743efcc8abaa0291a55e9489.txt new file mode 100644 index 0000000..958d3dc --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0f018811743efcc8abaa0291a55e9489.txt @@ -0,0 +1,4 @@ +0 0.5290697674418604 0.40104166666666663 0.20348837209302326 0.15625 +0 0.5232558139534884 0.6614583333333333 0.20348837209302326 0.15625 +0 0.688953488372093 0.1953125 0.20348837209302326 0.15625 +0 0.313953488372093 0.1171875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0f2b0cff03a943ad3e77017a5f652d7e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0f2b0cff03a943ad3e77017a5f652d7e.txt new file mode 100644 index 0000000..7e6aa2c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0f2b0cff03a943ad3e77017a5f652d7e.txt @@ -0,0 +1,5 @@ +0 0.8284883720930233 0.18489583333333331 0.20348837209302326 0.15625 +0 0.7674418604651163 0.6536458333333333 0.20348837209302326 0.15625 +0 0.311046511627907 0.4661458333333333 0.20348837209302326 0.15625 +0 0.4476744186046512 0.7083333333333333 0.20348837209302326 0.15625 +0 0.4680232558139535 0.21354166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0f6f3b9381ed7c5e3300950b1de87d0a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0f6f3b9381ed7c5e3300950b1de87d0a.txt new file mode 100644 index 0000000..fda28c4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0f6f3b9381ed7c5e3300950b1de87d0a.txt @@ -0,0 +1,4 @@ +0 0.627906976744186 0.25 0.20348837209302326 0.15625 +0 0.6162790697674418 0.7786458333333333 0.20348837209302326 0.15625 +0 0.8023255813953488 0.4765625 0.20348837209302326 0.15625 +0 0.2761627906976744 0.40625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0f92c06c08a03be7d3cd7beaf2595a4a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0f92c06c08a03be7d3cd7beaf2595a4a.txt new file mode 100644 index 0000000..2f51ed2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0f92c06c08a03be7d3cd7beaf2595a4a.txt @@ -0,0 +1,5 @@ +0 0.6162790697674418 0.19270833333333331 0.20348837209302326 0.15625 +0 0.14534883720930233 0.7395833333333333 0.20348837209302326 0.15625 +0 0.7819767441860465 0.4921875 0.20348837209302326 0.15625 +0 0.7703488372093024 0.7890625 0.20348837209302326 0.15625 +0 0.14825581395348836 0.1015625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0fba588204945afbe73b4dda96f17c67.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0fba588204945afbe73b4dda96f17c67.txt new file mode 100644 index 0000000..38181f9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0fba588204945afbe73b4dda96f17c67.txt @@ -0,0 +1,4 @@ +0 0.16569767441860464 0.17708333333333331 0.20348837209302326 0.15625 +0 0.5901162790697674 0.6796875 0.20348837209302326 0.15625 +0 0.16569767441860464 0.4609375 0.20348837209302326 0.15625 +0 0.4883720930232558 0.38541666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0fbca2e637530cfe656a5afd6f93df1e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0fbca2e637530cfe656a5afd6f93df1e.txt new file mode 100644 index 0000000..258c0ee --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0fbca2e637530cfe656a5afd6f93df1e.txt @@ -0,0 +1,4 @@ +0 0.14244186046511628 0.171875 0.20348837209302326 0.15625 +0 0.5494186046511628 0.5286458333333333 0.20348837209302326 0.15625 +0 0.1569767441860465 0.6432291666666666 0.20348837209302326 0.15625 +0 0.8372093023255813 0.359375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0fd53c38ff13f0b5c21460a7e81da046.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0fd53c38ff13f0b5c21460a7e81da046.txt new file mode 100644 index 0000000..d01b31d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/0fd53c38ff13f0b5c21460a7e81da046.txt @@ -0,0 +1,4 @@ +0 0.7674418604651163 0.15885416666666666 0.20348837209302326 0.15625 +0 0.2005813953488372 0.234375 0.20348837209302326 0.15625 +0 0.37209302325581395 0.6276041666666666 0.20348837209302326 0.15625 +0 0.8691860465116279 0.7161458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/10267c0ea85d17f4345f04a5f94a25c3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/10267c0ea85d17f4345f04a5f94a25c3.txt new file mode 100644 index 0000000..6be8a5d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/10267c0ea85d17f4345f04a5f94a25c3.txt @@ -0,0 +1,4 @@ +0 0.5581395348837209 0.3567708333333333 0.20348837209302326 0.15625 +0 0.18023255813953487 0.29166666666666663 0.20348837209302326 0.15625 +0 0.7151162790697674 0.6432291666666666 0.20348837209302326 0.15625 +0 0.20930232558139533 0.7291666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/102b99628f017bb3836cc370ac140a1c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/102b99628f017bb3836cc370ac140a1c.txt new file mode 100644 index 0000000..ae63425 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/102b99628f017bb3836cc370ac140a1c.txt @@ -0,0 +1,4 @@ +0 0.6308139534883721 0.5807291666666666 0.20348837209302326 0.15625 +0 0.2645348837209302 0.2578125 0.20348837209302326 0.15625 +0 0.686046511627907 0.22916666666666666 0.20348837209302326 0.15625 +0 0.20930232558139533 0.7447916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1057a07b83ba65107342a7356ee335ee.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1057a07b83ba65107342a7356ee335ee.txt new file mode 100644 index 0000000..1af5028 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1057a07b83ba65107342a7356ee335ee.txt @@ -0,0 +1,4 @@ +0 0.38372093023255816 0.6875 0.20348837209302326 0.15625 +0 0.36627906976744184 0.14583333333333331 0.20348837209302326 0.15625 +0 0.8488372093023255 0.18229166666666666 0.20348837209302326 0.15625 +0 0.7790697674418604 0.7682291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1058037bf1fdf0ce15e141ca4a8c5130.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1058037bf1fdf0ce15e141ca4a8c5130.txt new file mode 100644 index 0000000..013c79b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1058037bf1fdf0ce15e141ca4a8c5130.txt @@ -0,0 +1,4 @@ +0 0.7761627906976744 0.4609375 0.20348837209302326 0.15625 +0 0.3372093023255814 0.484375 0.20348837209302326 0.15625 +0 0.6395348837209303 0.7005208333333333 0.20348837209302326 0.15625 +0 0.7674418604651163 0.1796875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1089399d6818798ead8e206af6b93c64.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1089399d6818798ead8e206af6b93c64.txt new file mode 100644 index 0000000..f9b5e5d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1089399d6818798ead8e206af6b93c64.txt @@ -0,0 +1,4 @@ +0 0.32848837209302323 0.5546875 0.20348837209302326 0.15625 +0 0.7296511627906976 0.5598958333333333 0.20348837209302326 0.15625 +0 0.5843023255813954 0.2265625 0.20348837209302326 0.15625 +0 0.2616279069767442 0.3255208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/11708c6d46c68a498ed251b2a4b31661.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/11708c6d46c68a498ed251b2a4b31661.txt new file mode 100644 index 0000000..b991413 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/11708c6d46c68a498ed251b2a4b31661.txt @@ -0,0 +1,4 @@ +0 0.3488372093023256 0.5026041666666666 0.20348837209302326 0.15625 +0 0.3808139534883721 0.21354166666666666 0.20348837209302326 0.15625 +0 0.24709302325581395 0.7552083333333333 0.20348837209302326 0.15625 +0 0.6598837209302325 0.5703125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/12a2dafccccdebfca7f9b6014a998908.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/12a2dafccccdebfca7f9b6014a998908.txt new file mode 100644 index 0000000..fa61760 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/12a2dafccccdebfca7f9b6014a998908.txt @@ -0,0 +1,4 @@ +0 0.7441860465116279 0.4817708333333333 0.20348837209302326 0.15625 +0 0.25290697674418605 0.7526041666666666 0.20348837209302326 0.15625 +0 0.19186046511627908 0.34635416666666663 0.20348837209302326 0.15625 +0 0.6133720930232558 0.7473958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/12c267146d5575e3daf0387b24d34757.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/12c267146d5575e3daf0387b24d34757.txt new file mode 100644 index 0000000..5f62fc5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/12c267146d5575e3daf0387b24d34757.txt @@ -0,0 +1,4 @@ +0 0.24709302325581395 0.26822916666666663 0.20348837209302326 0.15625 +0 0.7005813953488372 0.1640625 0.20348837209302326 0.15625 +0 0.3023255813953488 0.546875 0.20348837209302326 0.15625 +0 0.8459302325581395 0.7369791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/12e571e75e6807539e853f96362448bc.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/12e571e75e6807539e853f96362448bc.txt new file mode 100644 index 0000000..84930d4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/12e571e75e6807539e853f96362448bc.txt @@ -0,0 +1,4 @@ +0 0.22674418604651161 0.390625 0.20348837209302326 0.15625 +0 0.8546511627906976 0.7161458333333333 0.20348837209302326 0.15625 +0 0.13953488372093023 0.09895833333333333 0.20348837209302326 0.15625 +0 0.7005813953488372 0.20572916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/131295e0302cbc98854b360ff1b440b4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/131295e0302cbc98854b360ff1b440b4.txt new file mode 100644 index 0000000..1a9d7fb --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/131295e0302cbc98854b360ff1b440b4.txt @@ -0,0 +1,4 @@ +0 0.7994186046511628 0.6276041666666666 0.20348837209302326 0.15625 +0 0.22965116279069767 0.10416666666666666 0.20348837209302326 0.15625 +0 0.22674418604651161 0.6901041666666666 0.20348837209302326 0.15625 +0 0.35174418604651164 0.4114583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/13367be1abe079551709c1d78d307b2c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/13367be1abe079551709c1d78d307b2c.txt new file mode 100644 index 0000000..ec13d01 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/13367be1abe079551709c1d78d307b2c.txt @@ -0,0 +1,4 @@ +0 0.7645348837209303 0.23697916666666666 0.20348837209302326 0.15625 +0 0.6453488372093024 0.5703125 0.20348837209302326 0.15625 +0 0.41860465116279066 0.15104166666666666 0.20348837209302326 0.15625 +0 0.36046511627906974 0.7161458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1338212e36abce3bec13a5f94f947041.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1338212e36abce3bec13a5f94f947041.txt new file mode 100644 index 0000000..566dadc --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1338212e36abce3bec13a5f94f947041.txt @@ -0,0 +1,4 @@ +0 0.3633720930232558 0.1953125 0.20348837209302326 0.15625 +0 0.438953488372093 0.671875 0.20348837209302326 0.15625 +0 0.7383720930232558 0.6197916666666666 0.20348837209302326 0.15625 +0 0.747093023255814 0.2864583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1339fab26e29b773cf6fad0a80be8af7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1339fab26e29b773cf6fad0a80be8af7.txt new file mode 100644 index 0000000..714fc64 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1339fab26e29b773cf6fad0a80be8af7.txt @@ -0,0 +1,4 @@ +0 0.16569767441860464 0.4375 0.20348837209302326 0.15625 +0 0.6104651162790697 0.15364583333333331 0.20348837209302326 0.15625 +0 0.5203488372093024 0.7447916666666666 0.20348837209302326 0.15625 +0 0.2616279069767442 0.17708333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/139cdc6c1010890a7bd7e2fe33d653ac.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/139cdc6c1010890a7bd7e2fe33d653ac.txt new file mode 100644 index 0000000..8b3e8d3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/139cdc6c1010890a7bd7e2fe33d653ac.txt @@ -0,0 +1,3 @@ +0 0.8168604651162791 0.65625 0.20348837209302326 0.15625 +0 0.34011627906976744 0.10677083333333333 0.20348837209302326 0.15625 +0 0.4563953488372093 0.45572916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/13af453e5931bc27b2c6d857db4734d1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/13af453e5931bc27b2c6d857db4734d1.txt new file mode 100644 index 0000000..7c171c2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/13af453e5931bc27b2c6d857db4734d1.txt @@ -0,0 +1,3 @@ +0 0.16279069767441862 0.18489583333333331 0.20348837209302326 0.15625 +0 0.5145348837209303 0.7786458333333333 0.20348837209302326 0.15625 +0 0.49127906976744184 0.33854166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/13ef50a6498949c46390239e9f389c6e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/13ef50a6498949c46390239e9f389c6e.txt new file mode 100644 index 0000000..abf4a2a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/13ef50a6498949c46390239e9f389c6e.txt @@ -0,0 +1,4 @@ +0 0.7296511627906976 0.25260416666666663 0.20348837209302326 0.15625 +0 0.34011627906976744 0.265625 0.20348837209302326 0.15625 +0 0.18313953488372092 0.5026041666666666 0.20348837209302326 0.15625 +0 0.7848837209302325 0.5729166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1462ae1ff9710380029bb8085f0a09f5.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1462ae1ff9710380029bb8085f0a09f5.txt new file mode 100644 index 0000000..20a043c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1462ae1ff9710380029bb8085f0a09f5.txt @@ -0,0 +1,4 @@ +0 0.7383720930232558 0.6666666666666666 0.20348837209302326 0.15625 +0 0.42441860465116277 0.5859375 0.20348837209302326 0.15625 +0 0.4069767441860465 0.12760416666666666 0.20348837209302326 0.15625 +0 0.8197674418604651 0.09635416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/14a6f9165625b7ff823e06f3d337c3ce.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/14a6f9165625b7ff823e06f3d337c3ce.txt new file mode 100644 index 0000000..a26a271 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/14a6f9165625b7ff823e06f3d337c3ce.txt @@ -0,0 +1,4 @@ +0 0.17151162790697674 0.3255208333333333 0.20348837209302326 0.15625 +0 0.8517441860465116 0.23958333333333331 0.20348837209302326 0.15625 +0 0.5784883720930233 0.2942708333333333 0.20348837209302326 0.15625 +0 0.5232558139534884 0.7057291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/14c38cbce9c8f0dec58a4c2e80d6a64b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/14c38cbce9c8f0dec58a4c2e80d6a64b.txt new file mode 100644 index 0000000..d19ce0f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/14c38cbce9c8f0dec58a4c2e80d6a64b.txt @@ -0,0 +1,4 @@ +0 0.686046511627907 0.09895833333333333 0.20348837209302326 0.15625 +0 0.16569767441860464 0.7578125 0.20348837209302326 0.15625 +0 0.5784883720930233 0.5234375 0.20348837209302326 0.15625 +0 0.12790697674418605 0.140625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/155034b20152b8ee2b713117a6dc3fff.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/155034b20152b8ee2b713117a6dc3fff.txt new file mode 100644 index 0000000..42a85bf --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/155034b20152b8ee2b713117a6dc3fff.txt @@ -0,0 +1,4 @@ +0 0.14534883720930233 0.7864583333333333 0.20348837209302326 0.15625 +0 0.11918604651162791 0.12760416666666666 0.20348837209302326 0.15625 +0 0.7674418604651163 0.4661458333333333 0.20348837209302326 0.15625 +0 0.2005813953488372 0.5260416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1557d239ebbe9fc78408b86057ff31d3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1557d239ebbe9fc78408b86057ff31d3.txt new file mode 100644 index 0000000..33522b2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1557d239ebbe9fc78408b86057ff31d3.txt @@ -0,0 +1,4 @@ +0 0.3081395348837209 0.22135416666666666 0.20348837209302326 0.15625 +0 0.563953488372093 0.6484375 0.20348837209302326 0.15625 +0 0.6744186046511628 0.28385416666666663 0.20348837209302326 0.15625 +0 0.2703488372093023 0.6171875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/156cd8f615704a54fcbca2c78f455581.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/156cd8f615704a54fcbca2c78f455581.txt new file mode 100644 index 0000000..d0ab4aa --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/156cd8f615704a54fcbca2c78f455581.txt @@ -0,0 +1,4 @@ +0 0.502906976744186 0.5833333333333333 0.20348837209302326 0.15625 +0 0.686046511627907 0.3359375 0.20348837209302326 0.15625 +0 0.13372093023255813 0.6145833333333333 0.20348837209302326 0.15625 +0 0.8430232558139534 0.5859375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/15a3d1098204e3698244b0b1fe28ba4b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/15a3d1098204e3698244b0b1fe28ba4b.txt new file mode 100644 index 0000000..cf85729 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/15a3d1098204e3698244b0b1fe28ba4b.txt @@ -0,0 +1,4 @@ +0 0.14534883720930233 0.5104166666666666 0.20348837209302326 0.15625 +0 0.3023255813953488 0.7552083333333333 0.20348837209302326 0.15625 +0 0.8052325581395349 0.19270833333333331 0.20348837209302326 0.15625 +0 0.8197674418604651 0.7291666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/15f562ab07b6729287fc291de5985c5d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/15f562ab07b6729287fc291de5985c5d.txt new file mode 100644 index 0000000..70087e9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/15f562ab07b6729287fc291de5985c5d.txt @@ -0,0 +1,4 @@ +0 0.7238372093023255 0.7630208333333333 0.20348837209302326 0.15625 +0 0.4069767441860465 0.7005208333333333 0.20348837209302326 0.15625 +0 0.7063953488372093 0.26041666666666663 0.20348837209302326 0.15625 +0 0.436046511627907 0.45572916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/161a0941bfb4f401d4bd2ef02bfb1cc1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/161a0941bfb4f401d4bd2ef02bfb1cc1.txt new file mode 100644 index 0000000..619816e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/161a0941bfb4f401d4bd2ef02bfb1cc1.txt @@ -0,0 +1,4 @@ +0 0.21511627906976744 0.10677083333333333 0.20348837209302326 0.15625 +0 0.5145348837209303 0.31510416666666663 0.20348837209302326 0.15625 +0 0.4825581395348837 0.6640625 0.20348837209302326 0.15625 +0 0.8633720930232558 0.6197916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/161e73bf0edc5b668560c363ea9291e1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/161e73bf0edc5b668560c363ea9291e1.txt new file mode 100644 index 0000000..3de086c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/161e73bf0edc5b668560c363ea9291e1.txt @@ -0,0 +1,2 @@ +0 0.7383720930232558 0.33072916666666663 0.20348837209302326 0.15625 +0 0.5959302325581395 0.7213541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1636430a6cd50dcdd4912dc80117450b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1636430a6cd50dcdd4912dc80117450b.txt new file mode 100644 index 0000000..d02d8c1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1636430a6cd50dcdd4912dc80117450b.txt @@ -0,0 +1,4 @@ +0 0.32558139534883723 0.6380208333333333 0.20348837209302326 0.15625 +0 0.42441860465116277 0.41666666666666663 0.20348837209302326 0.15625 +0 0.7616279069767442 0.7161458333333333 0.20348837209302326 0.15625 +0 0.12209302325581395 0.23958333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/164f00b8a34453467cbdf39d6f5ae05a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/164f00b8a34453467cbdf39d6f5ae05a.txt new file mode 100644 index 0000000..697733f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/164f00b8a34453467cbdf39d6f5ae05a.txt @@ -0,0 +1,4 @@ +0 0.6395348837209303 0.44010416666666663 0.20348837209302326 0.15625 +0 0.2616279069767442 0.2265625 0.20348837209302326 0.15625 +0 0.22093023255813954 0.5729166666666666 0.20348837209302326 0.15625 +0 0.622093023255814 0.20052083333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1655730eaba36f88e24eef1f62ca06ba.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1655730eaba36f88e24eef1f62ca06ba.txt new file mode 100644 index 0000000..e605345 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1655730eaba36f88e24eef1f62ca06ba.txt @@ -0,0 +1,5 @@ +0 0.7877906976744186 0.33854166666666663 0.20348837209302326 0.15625 +0 0.18023255813953487 0.5755208333333333 0.20348837209302326 0.15625 +0 0.6918604651162791 0.6510416666666666 0.20348837209302326 0.15625 +0 0.5988372093023255 0.0859375 0.20348837209302326 0.15625 +0 0.4011627906976744 0.36197916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1656ec17e43048f7adf1a0bf14d2eb04.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1656ec17e43048f7adf1a0bf14d2eb04.txt new file mode 100644 index 0000000..9d10305 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1656ec17e43048f7adf1a0bf14d2eb04.txt @@ -0,0 +1,4 @@ +0 0.1744186046511628 0.7578125 0.20348837209302326 0.15625 +0 0.7965116279069767 0.2786458333333333 0.20348837209302326 0.15625 +0 0.16279069767441862 0.32291666666666663 0.20348837209302326 0.15625 +0 0.48546511627906974 0.5703125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/16b9855ea43e138c1ea9f757b9541298.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/16b9855ea43e138c1ea9f757b9541298.txt new file mode 100644 index 0000000..ccc999f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/16b9855ea43e138c1ea9f757b9541298.txt @@ -0,0 +1,4 @@ +0 0.40406976744186046 0.24739583333333331 0.20348837209302326 0.15625 +0 0.4069767441860465 0.5963541666666666 0.20348837209302326 0.15625 +0 0.8430232558139534 0.7213541666666666 0.20348837209302326 0.15625 +0 0.7093023255813954 0.4661458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/16d63c91dad3b2fb7f587c0fbb10c4b9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/16d63c91dad3b2fb7f587c0fbb10c4b9.txt new file mode 100644 index 0000000..0b1e1e3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/16d63c91dad3b2fb7f587c0fbb10c4b9.txt @@ -0,0 +1,4 @@ +0 0.16279069767441862 0.48697916666666663 0.20348837209302326 0.15625 +0 0.8197674418604651 0.5130208333333333 0.20348837209302326 0.15625 +0 0.2616279069767442 0.11979166666666666 0.20348837209302326 0.15625 +0 0.6017441860465116 0.14583333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/17e119c9c56a343e6bf1db39479eeaac.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/17e119c9c56a343e6bf1db39479eeaac.txt new file mode 100644 index 0000000..3db6048 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/17e119c9c56a343e6bf1db39479eeaac.txt @@ -0,0 +1,5 @@ +0 0.2877906976744186 0.6484375 0.20348837209302326 0.15625 +0 0.8633720930232558 0.6614583333333333 0.20348837209302326 0.15625 +0 0.5813953488372093 0.23697916666666666 0.20348837209302326 0.15625 +0 0.22965116279069767 0.28385416666666663 0.20348837209302326 0.15625 +0 0.872093023255814 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/17eb067409590d1d36eb775aecfde424.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/17eb067409590d1d36eb775aecfde424.txt new file mode 100644 index 0000000..eed860f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/17eb067409590d1d36eb775aecfde424.txt @@ -0,0 +1,4 @@ +0 0.4622093023255814 0.6223958333333333 0.20348837209302326 0.15625 +0 0.7848837209302325 0.7213541666666666 0.20348837209302326 0.15625 +0 0.5406976744186046 0.18229166666666666 0.20348837209302326 0.15625 +0 0.7965116279069767 0.4348958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/17f183afbe5f16297c833295cb2d3385.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/17f183afbe5f16297c833295cb2d3385.txt new file mode 100644 index 0000000..175ffc7 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/17f183afbe5f16297c833295cb2d3385.txt @@ -0,0 +1,5 @@ +0 0.7761627906976744 0.5755208333333333 0.20348837209302326 0.15625 +0 0.3081395348837209 0.7890625 0.20348837209302326 0.15625 +0 0.2965116279069767 0.22395833333333331 0.20348837209302326 0.15625 +0 0.5726744186046512 0.23177083333333331 0.20348837209302326 0.15625 +0 0.4738372093023256 0.4895833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1816fd114e0a72c42d8646593985424e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1816fd114e0a72c42d8646593985424e.txt new file mode 100644 index 0000000..3a992af --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1816fd114e0a72c42d8646593985424e.txt @@ -0,0 +1,5 @@ +0 0.5465116279069767 0.6640625 0.20348837209302326 0.15625 +0 0.6511627906976745 0.44010416666666663 0.20348837209302326 0.15625 +0 0.18023255813953487 0.7005208333333333 0.20348837209302326 0.15625 +0 0.311046511627907 0.19791666666666666 0.20348837209302326 0.15625 +0 0.6656976744186046 0.09895833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/182e9412144c9c76e4db5d551f00c8ee.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/182e9412144c9c76e4db5d551f00c8ee.txt new file mode 100644 index 0000000..21185c9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/182e9412144c9c76e4db5d551f00c8ee.txt @@ -0,0 +1,5 @@ +0 0.5726744186046512 0.7864583333333333 0.20348837209302326 0.15625 +0 0.5523255813953488 0.203125 0.20348837209302326 0.15625 +0 0.20930232558139533 0.6276041666666666 0.20348837209302326 0.15625 +0 0.502906976744186 0.5182291666666666 0.20348837209302326 0.15625 +0 0.8197674418604651 0.5572916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/185bf6065ea7e52a8790fb6fdb00a3fe.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/185bf6065ea7e52a8790fb6fdb00a3fe.txt new file mode 100644 index 0000000..f7eecb2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/185bf6065ea7e52a8790fb6fdb00a3fe.txt @@ -0,0 +1,4 @@ +0 0.21511627906976744 0.33854166666666663 0.20348837209302326 0.15625 +0 0.4563953488372093 0.7239583333333333 0.20348837209302326 0.15625 +0 0.622093023255814 0.20833333333333331 0.20348837209302326 0.15625 +0 0.16279069767441862 0.78125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/18a19da15a777de664434709365248b9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/18a19da15a777de664434709365248b9.txt new file mode 100644 index 0000000..adedcfe --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/18a19da15a777de664434709365248b9.txt @@ -0,0 +1,4 @@ +0 0.8313953488372093 0.1171875 0.20348837209302326 0.15625 +0 0.25872093023255816 0.1640625 0.20348837209302326 0.15625 +0 0.7906976744186046 0.7395833333333333 0.20348837209302326 0.15625 +0 0.4622093023255814 0.40625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/18d1c97cd1a9fa1151aef69e7a84650c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/18d1c97cd1a9fa1151aef69e7a84650c.txt new file mode 100644 index 0000000..0dcf6f2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/18d1c97cd1a9fa1151aef69e7a84650c.txt @@ -0,0 +1,2 @@ +0 0.6715116279069767 0.4609375 0.20348837209302326 0.15625 +0 0.23546511627906977 0.5364583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/18e2487614c8d4e42bb661894dc2710a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/18e2487614c8d4e42bb661894dc2710a.txt new file mode 100644 index 0000000..5ce7d7f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/18e2487614c8d4e42bb661894dc2710a.txt @@ -0,0 +1,3 @@ +0 0.3372093023255814 0.16927083333333331 0.20348837209302326 0.15625 +0 0.5494186046511628 0.5703125 0.20348837209302326 0.15625 +0 0.24127906976744184 0.5807291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/192848b00b4aa9abae37328e3e3461b3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/192848b00b4aa9abae37328e3e3461b3.txt new file mode 100644 index 0000000..59bd189 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/192848b00b4aa9abae37328e3e3461b3.txt @@ -0,0 +1,4 @@ +0 0.5523255813953488 0.21354166666666666 0.20348837209302326 0.15625 +0 0.7616279069767442 0.6276041666666666 0.20348837209302326 0.15625 +0 0.4505813953488372 0.5546875 0.20348837209302326 0.15625 +0 0.8517441860465116 0.3984375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/19629e0ac4e90db1530ed27f7d3ea572.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/19629e0ac4e90db1530ed27f7d3ea572.txt new file mode 100644 index 0000000..be3c9bd --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/19629e0ac4e90db1530ed27f7d3ea572.txt @@ -0,0 +1,5 @@ +0 0.8343023255813954 0.4036458333333333 0.20348837209302326 0.15625 +0 0.7994186046511628 0.13541666666666666 0.20348837209302326 0.15625 +0 0.4331395348837209 0.4114583333333333 0.20348837209302326 0.15625 +0 0.3226744186046512 0.7473958333333333 0.20348837209302326 0.15625 +0 0.4796511627906977 0.11458333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/198643733bbecb9983b9a9b6ba09d104.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/198643733bbecb9983b9a9b6ba09d104.txt new file mode 100644 index 0000000..eb75ae1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/198643733bbecb9983b9a9b6ba09d104.txt @@ -0,0 +1,4 @@ +0 0.7761627906976744 0.09895833333333333 0.20348837209302326 0.15625 +0 0.36627906976744184 0.6484375 0.20348837209302326 0.15625 +0 0.7761627906976744 0.4296875 0.20348837209302326 0.15625 +0 0.18313953488372092 0.39322916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1998e89be33f97aa321d40657779f1b8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1998e89be33f97aa321d40657779f1b8.txt new file mode 100644 index 0000000..173060e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1998e89be33f97aa321d40657779f1b8.txt @@ -0,0 +1,5 @@ +0 0.5436046511627907 0.75 0.20348837209302326 0.15625 +0 0.17151162790697674 0.3020833333333333 0.20348837209302326 0.15625 +0 0.6191860465116279 0.4739583333333333 0.20348837209302326 0.15625 +0 0.8691860465116279 0.7708333333333333 0.20348837209302326 0.15625 +0 0.22965116279069767 0.7578125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/19a3ab4f6dd50bfa59bc273b9756e28c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/19a3ab4f6dd50bfa59bc273b9756e28c.txt new file mode 100644 index 0000000..ff31b4b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/19a3ab4f6dd50bfa59bc273b9756e28c.txt @@ -0,0 +1,5 @@ +0 0.42441860465116277 0.4583333333333333 0.20348837209302326 0.15625 +0 0.8197674418604651 0.21614583333333331 0.20348837209302326 0.15625 +0 0.7441860465116279 0.5755208333333333 0.20348837209302326 0.15625 +0 0.39244186046511625 0.10677083333333333 0.20348837209302326 0.15625 +0 0.23546511627906977 0.7604166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/19b320409f359a5076ebf86b6db93f49.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/19b320409f359a5076ebf86b6db93f49.txt new file mode 100644 index 0000000..dcc1f37 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/19b320409f359a5076ebf86b6db93f49.txt @@ -0,0 +1,4 @@ +0 0.10755813953488372 0.703125 0.20348837209302326 0.15625 +0 0.17151162790697674 0.1328125 0.20348837209302326 0.15625 +0 0.16569767441860464 0.484375 0.20348837209302326 0.15625 +0 0.561046511627907 0.6536458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1a334a887020bedfdf686212d6ee8fc9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1a334a887020bedfdf686212d6ee8fc9.txt new file mode 100644 index 0000000..332d8f9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1a334a887020bedfdf686212d6ee8fc9.txt @@ -0,0 +1,5 @@ +0 0.7383720930232558 0.5546875 0.20348837209302326 0.15625 +0 0.2238372093023256 0.28385416666666663 0.20348837209302326 0.15625 +0 0.19767441860465115 0.5494791666666666 0.20348837209302326 0.15625 +0 0.75 0.29947916666666663 0.20348837209302326 0.15625 +0 0.1511627906976744 0.7734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1a7c00fb964dcce4013ca613a4ecffb1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1a7c00fb964dcce4013ca613a4ecffb1.txt new file mode 100644 index 0000000..ee2ad7d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1a7c00fb964dcce4013ca613a4ecffb1.txt @@ -0,0 +1,4 @@ +0 0.4738372093023256 0.234375 0.20348837209302326 0.15625 +0 0.13372093023255813 0.12239583333333333 0.20348837209302326 0.15625 +0 0.2645348837209302 0.7473958333333333 0.20348837209302326 0.15625 +0 0.7994186046511628 0.765625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1aa7a73ae4066c73c0171c2c0171120f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1aa7a73ae4066c73c0171c2c0171120f.txt new file mode 100644 index 0000000..ba76e25 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1aa7a73ae4066c73c0171c2c0171120f.txt @@ -0,0 +1,3 @@ +0 0.5784883720930233 0.5572916666666666 0.20348837209302326 0.15625 +0 0.5058139534883721 0.2890625 0.20348837209302326 0.15625 +0 0.2005813953488372 0.15104166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1abbeb512eb0ee31e594286f7378483a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1abbeb512eb0ee31e594286f7378483a.txt new file mode 100644 index 0000000..22a8715 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1abbeb512eb0ee31e594286f7378483a.txt @@ -0,0 +1,4 @@ +0 0.45348837209302323 0.15104166666666666 0.20348837209302326 0.15625 +0 0.4418604651162791 0.5104166666666666 0.20348837209302326 0.15625 +0 0.1686046511627907 0.23177083333333331 0.20348837209302326 0.15625 +0 0.8023255813953488 0.7447916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1b328e79270431411a4105cc04766f81.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1b328e79270431411a4105cc04766f81.txt new file mode 100644 index 0000000..79aaef1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1b328e79270431411a4105cc04766f81.txt @@ -0,0 +1,5 @@ +0 0.8372093023255813 0.703125 0.20348837209302326 0.15625 +0 0.14825581395348836 0.3359375 0.20348837209302326 0.15625 +0 0.3895348837209302 0.6119791666666666 0.20348837209302326 0.15625 +0 0.6424418604651163 0.11979166666666666 0.20348837209302326 0.15625 +0 0.563953488372093 0.3671875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1b64dd87c266e3a1a3b8bc47ca7f8f9c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1b64dd87c266e3a1a3b8bc47ca7f8f9c.txt new file mode 100644 index 0000000..f8563bf --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1b64dd87c266e3a1a3b8bc47ca7f8f9c.txt @@ -0,0 +1,4 @@ +0 0.6482558139534884 0.19791666666666666 0.20348837209302326 0.15625 +0 0.2063953488372093 0.7890625 0.20348837209302326 0.15625 +0 0.622093023255814 0.7291666666666666 0.20348837209302326 0.15625 +0 0.1744186046511628 0.1171875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1b96328cfd5161240b956c50db9da611.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1b96328cfd5161240b956c50db9da611.txt new file mode 100644 index 0000000..7d97fbd --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1b96328cfd5161240b956c50db9da611.txt @@ -0,0 +1,5 @@ +0 0.47093023255813954 0.19791666666666666 0.20348837209302326 0.15625 +0 0.4825581395348837 0.5130208333333333 0.20348837209302326 0.15625 +0 0.1686046511627907 0.2734375 0.20348837209302326 0.15625 +0 0.8633720930232558 0.29166666666666663 0.20348837209302326 0.15625 +0 0.5290697674418604 0.7708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1bac247e288ffc2f39b69afb5edd85d0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1bac247e288ffc2f39b69afb5edd85d0.txt new file mode 100644 index 0000000..e0e0e7f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1bac247e288ffc2f39b69afb5edd85d0.txt @@ -0,0 +1,4 @@ +0 0.36627906976744184 0.5 0.20348837209302326 0.15625 +0 0.8575581395348837 0.6744791666666666 0.20348837209302326 0.15625 +0 0.7063953488372093 0.16145833333333331 0.20348837209302326 0.15625 +0 0.35174418604651164 0.22395833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1bc89cbb8478e47ea5f21dbe1b5aef2e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1bc89cbb8478e47ea5f21dbe1b5aef2e.txt new file mode 100644 index 0000000..263d4a9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1bc89cbb8478e47ea5f21dbe1b5aef2e.txt @@ -0,0 +1,3 @@ +0 0.5959302325581395 0.14322916666666666 0.20348837209302326 0.15625 +0 0.27906976744186046 0.16145833333333331 0.20348837209302326 0.15625 +0 0.311046511627907 0.5703125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1bcc2e765f3ec9325eb3e7f26a80efb9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1bcc2e765f3ec9325eb3e7f26a80efb9.txt new file mode 100644 index 0000000..cd2ebf4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1bcc2e765f3ec9325eb3e7f26a80efb9.txt @@ -0,0 +1,4 @@ +0 0.6511627906976745 0.6822916666666666 0.20348837209302326 0.15625 +0 0.22674418604651161 0.7161458333333333 0.20348837209302326 0.15625 +0 0.6453488372093024 0.13020833333333331 0.20348837209302326 0.15625 +0 0.44476744186046513 0.3489583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1c54362cc06c10affe0ad5dc391fc097.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1c54362cc06c10affe0ad5dc391fc097.txt new file mode 100644 index 0000000..fc99527 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1c54362cc06c10affe0ad5dc391fc097.txt @@ -0,0 +1,5 @@ +0 0.8343023255813954 0.6276041666666666 0.20348837209302326 0.15625 +0 0.3168604651162791 0.2552083333333333 0.20348837209302326 0.15625 +0 0.45348837209302323 0.6328125 0.20348837209302326 0.15625 +0 0.7936046511627907 0.3723958333333333 0.20348837209302326 0.15625 +0 0.8197674418604651 0.1015625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1cecbc5941bb3f2fc7d77eb856c8174b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1cecbc5941bb3f2fc7d77eb856c8174b.txt new file mode 100644 index 0000000..127b8fb --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1cecbc5941bb3f2fc7d77eb856c8174b.txt @@ -0,0 +1,3 @@ +0 0.17151162790697674 0.1328125 0.20348837209302326 0.15625 +0 0.125 0.7291666666666666 0.20348837209302326 0.15625 +0 0.438953488372093 0.125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1d1316acd36600691c3a3a469732ed3b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1d1316acd36600691c3a3a469732ed3b.txt new file mode 100644 index 0000000..56a2c3d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1d1316acd36600691c3a3a469732ed3b.txt @@ -0,0 +1,4 @@ +0 0.8459302325581395 0.3567708333333333 0.20348837209302326 0.15625 +0 0.686046511627907 0.09114583333333333 0.20348837209302326 0.15625 +0 0.12209302325581395 0.43229166666666663 0.20348837209302326 0.15625 +0 0.5087209302325582 0.375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1d30c3c97478102ffa4695269f1872bb.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1d30c3c97478102ffa4695269f1872bb.txt new file mode 100644 index 0000000..3ac9b5f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1d30c3c97478102ffa4695269f1872bb.txt @@ -0,0 +1,3 @@ +0 0.2965116279069767 0.7526041666666666 0.20348837209302326 0.15625 +0 0.7209302325581395 0.1953125 0.20348837209302326 0.15625 +0 0.40406976744186046 0.4296875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1db380775a448eca6f6ca1b7e9cac997.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1db380775a448eca6f6ca1b7e9cac997.txt new file mode 100644 index 0000000..4010c71 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1db380775a448eca6f6ca1b7e9cac997.txt @@ -0,0 +1,3 @@ +0 0.8488372093023255 0.4296875 0.20348837209302326 0.15625 +0 0.3691860465116279 0.2864583333333333 0.20348837209302326 0.15625 +0 0.43023255813953487 0.7395833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1db907ebd4ef8927e6129edd4bd51a79.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1db907ebd4ef8927e6129edd4bd51a79.txt new file mode 100644 index 0000000..4e18926 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1db907ebd4ef8927e6129edd4bd51a79.txt @@ -0,0 +1,5 @@ +0 0.45348837209302323 0.7604166666666666 0.20348837209302326 0.15625 +0 0.375 0.19791666666666666 0.20348837209302326 0.15625 +0 0.7761627906976744 0.40885416666666663 0.20348837209302326 0.15625 +0 0.19186046511627908 0.71875 0.20348837209302326 0.15625 +0 0.7238372093023255 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1de1a2db534fa54404d252a930d67791.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1de1a2db534fa54404d252a930d67791.txt new file mode 100644 index 0000000..34f8a57 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1de1a2db534fa54404d252a930d67791.txt @@ -0,0 +1,4 @@ +0 0.125 0.5026041666666666 0.20348837209302326 0.15625 +0 0.7151162790697674 0.2734375 0.20348837209302326 0.15625 +0 0.44476744186046513 0.7447916666666666 0.20348837209302326 0.15625 +0 0.46511627906976744 0.5234375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1e337714085bc8f81959ee583b2bac59.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1e337714085bc8f81959ee583b2bac59.txt new file mode 100644 index 0000000..511f388 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1e337714085bc8f81959ee583b2bac59.txt @@ -0,0 +1,5 @@ +0 0.2877906976744186 0.7604166666666666 0.20348837209302326 0.15625 +0 0.7209302325581395 0.6145833333333333 0.20348837209302326 0.15625 +0 0.561046511627907 0.3645833333333333 0.20348837209302326 0.15625 +0 0.5436046511627907 0.1171875 0.20348837209302326 0.15625 +0 0.18313953488372092 0.23697916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1e43173fe41b7bedd6b0443c9f8f52c1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1e43173fe41b7bedd6b0443c9f8f52c1.txt new file mode 100644 index 0000000..8a6fe80 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1e43173fe41b7bedd6b0443c9f8f52c1.txt @@ -0,0 +1,5 @@ +0 0.3546511627906977 0.5052083333333333 0.20348837209302326 0.15625 +0 0.40988372093023256 0.15885416666666666 0.20348837209302326 0.15625 +0 0.811046511627907 0.3098958333333333 0.20348837209302326 0.15625 +0 0.7703488372093024 0.5833333333333333 0.20348837209302326 0.15625 +0 0.4127906976744186 0.7473958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1e54d43e51d4a8c7c681413cd8a010e9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1e54d43e51d4a8c7c681413cd8a010e9.txt new file mode 100644 index 0000000..7605371 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1e54d43e51d4a8c7c681413cd8a010e9.txt @@ -0,0 +1,5 @@ +0 0.3023255813953488 0.7786458333333333 0.20348837209302326 0.15625 +0 0.6598837209302325 0.6067708333333333 0.20348837209302326 0.15625 +0 0.25 0.3984375 0.20348837209302326 0.15625 +0 0.4738372093023256 0.16666666666666666 0.20348837209302326 0.15625 +0 0.7703488372093024 0.25 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1ebeaad92c47ae8659221affb32c0c24.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1ebeaad92c47ae8659221affb32c0c24.txt new file mode 100644 index 0000000..66c075d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1ebeaad92c47ae8659221affb32c0c24.txt @@ -0,0 +1,5 @@ +0 0.2005813953488372 0.6927083333333333 0.20348837209302326 0.15625 +0 0.5581395348837209 0.6458333333333333 0.20348837209302326 0.15625 +0 0.6540697674418604 0.21614583333333331 0.20348837209302326 0.15625 +0 0.27906976744186046 0.3359375 0.20348837209302326 0.15625 +0 0.8313953488372093 0.7604166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1ec56554bd6d6a61921ffe4b3adf68a0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1ec56554bd6d6a61921ffe4b3adf68a0.txt new file mode 100644 index 0000000..8f9184a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1ec56554bd6d6a61921ffe4b3adf68a0.txt @@ -0,0 +1,4 @@ +0 0.18313953488372092 0.37760416666666663 0.20348837209302326 0.15625 +0 0.6627906976744186 0.14583333333333331 0.20348837209302326 0.15625 +0 0.40988372093023256 0.6432291666666666 0.20348837209302326 0.15625 +0 0.8488372093023255 0.7135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1eee3dbb935848d69fa712136f58a52f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1eee3dbb935848d69fa712136f58a52f.txt new file mode 100644 index 0000000..6bcf6f9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1eee3dbb935848d69fa712136f58a52f.txt @@ -0,0 +1,3 @@ +0 0.8488372093023255 0.5104166666666666 0.20348837209302326 0.15625 +0 0.18895348837209303 0.4140625 0.20348837209302326 0.15625 +0 0.19767441860465115 0.1015625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1ef9d8c97f05081cde0d8817b337d2f0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1ef9d8c97f05081cde0d8817b337d2f0.txt new file mode 100644 index 0000000..d72e14c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1ef9d8c97f05081cde0d8817b337d2f0.txt @@ -0,0 +1,5 @@ +0 0.7034883720930233 0.7421875 0.20348837209302326 0.15625 +0 0.2616279069767442 0.2864583333333333 0.20348837209302326 0.15625 +0 0.8197674418604651 0.3255208333333333 0.20348837209302326 0.15625 +0 0.14534883720930233 0.5130208333333333 0.20348837209302326 0.15625 +0 0.23255813953488372 0.7916666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1f0e7c0ddd27073e1c3cd1ba51943e8b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1f0e7c0ddd27073e1c3cd1ba51943e8b.txt new file mode 100644 index 0000000..99e3f4e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1f0e7c0ddd27073e1c3cd1ba51943e8b.txt @@ -0,0 +1,5 @@ +0 0.4273255813953488 0.5625 0.20348837209302326 0.15625 +0 0.4273255813953488 0.796875 0.20348837209302326 0.15625 +0 0.5523255813953488 0.32291666666666663 0.20348837209302326 0.15625 +0 0.8662790697674418 0.4296875 0.20348837209302326 0.15625 +0 0.8517441860465116 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1f375507c30e04a415fe1430a2e348d3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1f375507c30e04a415fe1430a2e348d3.txt new file mode 100644 index 0000000..4ff13fd --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1f375507c30e04a415fe1430a2e348d3.txt @@ -0,0 +1,4 @@ +0 0.7441860465116279 0.5026041666666666 0.20348837209302326 0.15625 +0 0.6947674418604651 0.7760416666666666 0.20348837209302326 0.15625 +0 0.24127906976744184 0.5364583333333333 0.20348837209302326 0.15625 +0 0.6453488372093024 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1f729d61063c58610385bc4736bbe328.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1f729d61063c58610385bc4736bbe328.txt new file mode 100644 index 0000000..7b7473c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1f729d61063c58610385bc4736bbe328.txt @@ -0,0 +1,2 @@ +0 0.75 0.5026041666666666 0.20348837209302326 0.15625 +0 0.19186046511627908 0.39322916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1f9e28171dc32f9f6b6b38864ab91544.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1f9e28171dc32f9f6b6b38864ab91544.txt new file mode 100644 index 0000000..d66483f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1f9e28171dc32f9f6b6b38864ab91544.txt @@ -0,0 +1,5 @@ +0 0.8401162790697674 0.6536458333333333 0.20348837209302326 0.15625 +0 0.3488372093023256 0.24479166666666666 0.20348837209302326 0.15625 +0 0.8401162790697674 0.39322916666666663 0.20348837209302326 0.15625 +0 0.2441860465116279 0.4817708333333333 0.20348837209302326 0.15625 +0 0.6918604651162791 0.11979166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1fd9c3c35a0a8319c1840cefd43ebf59.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1fd9c3c35a0a8319c1840cefd43ebf59.txt new file mode 100644 index 0000000..22160f9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1fd9c3c35a0a8319c1840cefd43ebf59.txt @@ -0,0 +1,4 @@ +0 0.37790697674418605 0.6901041666666666 0.20348837209302326 0.15625 +0 0.7732558139534884 0.7890625 0.20348837209302326 0.15625 +0 0.5843023255813954 0.46354166666666663 0.20348837209302326 0.15625 +0 0.3313953488372093 0.21614583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1fefe4293d23b1997764d240aa199bab.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1fefe4293d23b1997764d240aa199bab.txt new file mode 100644 index 0000000..f2dd8cb --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/1fefe4293d23b1997764d240aa199bab.txt @@ -0,0 +1,4 @@ +0 0.2180232558139535 0.4817708333333333 0.20348837209302326 0.15625 +0 0.6133720930232558 0.10677083333333333 0.20348837209302326 0.15625 +0 0.8226744186046512 0.4661458333333333 0.20348837209302326 0.15625 +0 0.313953488372093 0.25260416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/203473aef6cb33fc75f1ec547a91a860.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/203473aef6cb33fc75f1ec547a91a860.txt new file mode 100644 index 0000000..7bc0abe --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/203473aef6cb33fc75f1ec547a91a860.txt @@ -0,0 +1,4 @@ +0 0.3430232558139535 0.43229166666666663 0.20348837209302326 0.15625 +0 0.37209302325581395 0.7265625 0.20348837209302326 0.15625 +0 0.7819767441860465 0.75 0.20348837209302326 0.15625 +0 0.7267441860465116 0.47135416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2056f79ca3d5a6130d0cf4f0d8d5116d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2056f79ca3d5a6130d0cf4f0d8d5116d.txt new file mode 100644 index 0000000..c0dd532 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2056f79ca3d5a6130d0cf4f0d8d5116d.txt @@ -0,0 +1,4 @@ +0 0.4622093023255814 0.2786458333333333 0.20348837209302326 0.15625 +0 0.125 0.5442708333333333 0.20348837209302326 0.15625 +0 0.7441860465116279 0.375 0.20348837209302326 0.15625 +0 0.46511627906976744 0.7890625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/20688e29e9e30e36c1feaba958758cca.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/20688e29e9e30e36c1feaba958758cca.txt new file mode 100644 index 0000000..8ff3125 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/20688e29e9e30e36c1feaba958758cca.txt @@ -0,0 +1,3 @@ +0 0.3488372093023256 0.15364583333333331 0.20348837209302326 0.15625 +0 0.43023255813953487 0.5963541666666666 0.20348837209302326 0.15625 +0 0.7354651162790697 0.3411458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/20c6853fe3e50a43ebe1ac3b78d6bcb2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/20c6853fe3e50a43ebe1ac3b78d6bcb2.txt new file mode 100644 index 0000000..517c061 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/20c6853fe3e50a43ebe1ac3b78d6bcb2.txt @@ -0,0 +1,5 @@ +0 0.7180232558139534 0.10416666666666666 0.20348837209302326 0.15625 +0 0.21511627906976744 0.6145833333333333 0.20348837209302326 0.15625 +0 0.26744186046511625 0.1015625 0.20348837209302326 0.15625 +0 0.8052325581395349 0.3958333333333333 0.20348837209302326 0.15625 +0 0.6598837209302325 0.6276041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/20cb791f2fcca081fa86c3b05ae0d279.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/20cb791f2fcca081fa86c3b05ae0d279.txt new file mode 100644 index 0000000..4e2bcc9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/20cb791f2fcca081fa86c3b05ae0d279.txt @@ -0,0 +1,4 @@ +0 0.1569767441860465 0.12239583333333333 0.20348837209302326 0.15625 +0 0.4622093023255814 0.1015625 0.20348837209302326 0.15625 +0 0.19186046511627908 0.5390625 0.20348837209302326 0.15625 +0 0.8168604651162791 0.25260416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2124e1eb90cd78a04d3e9de5c6a0ca56.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2124e1eb90cd78a04d3e9de5c6a0ca56.txt new file mode 100644 index 0000000..fba7251 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2124e1eb90cd78a04d3e9de5c6a0ca56.txt @@ -0,0 +1,4 @@ +0 0.747093023255814 0.5703125 0.20348837209302326 0.15625 +0 0.7732558139534884 0.3020833333333333 0.20348837209302326 0.15625 +0 0.13662790697674418 0.3567708333333333 0.20348837209302326 0.15625 +0 0.23255813953488372 0.7838541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/212b0e07e39b78f98abfdb543aa23233.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/212b0e07e39b78f98abfdb543aa23233.txt new file mode 100644 index 0000000..7fad300 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/212b0e07e39b78f98abfdb543aa23233.txt @@ -0,0 +1,4 @@ +0 0.4273255813953488 0.4609375 0.20348837209302326 0.15625 +0 0.7674418604651163 0.6171875 0.20348837209302326 0.15625 +0 0.14244186046511628 0.5807291666666666 0.20348837209302326 0.15625 +0 0.7296511627906976 0.3177083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/214a7fa290fb1d4e781d1a74d8304e1d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/214a7fa290fb1d4e781d1a74d8304e1d.txt new file mode 100644 index 0000000..7fdc414 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/214a7fa290fb1d4e781d1a74d8304e1d.txt @@ -0,0 +1,5 @@ +0 0.18313953488372092 0.5703125 0.20348837209302326 0.15625 +0 0.7761627906976744 0.12239583333333333 0.20348837209302326 0.15625 +0 0.8633720930232558 0.7473958333333333 0.20348837209302326 0.15625 +0 0.5145348837209303 0.7552083333333333 0.20348837209302326 0.15625 +0 0.438953488372093 0.10677083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/22ca2fb7130874d362fa27f1fcd42a97.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/22ca2fb7130874d362fa27f1fcd42a97.txt new file mode 100644 index 0000000..2ec0ced --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/22ca2fb7130874d362fa27f1fcd42a97.txt @@ -0,0 +1,4 @@ +0 0.7936046511627907 0.5833333333333333 0.20348837209302326 0.15625 +0 0.752906976744186 0.08854166666666666 0.20348837209302326 0.15625 +0 0.3546511627906977 0.2578125 0.20348837209302326 0.15625 +0 0.3168604651162791 0.5807291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/230d9b2ba814cb55ea2ddfd262ac3f05.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/230d9b2ba814cb55ea2ddfd262ac3f05.txt new file mode 100644 index 0000000..ea05261 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/230d9b2ba814cb55ea2ddfd262ac3f05.txt @@ -0,0 +1,5 @@ +0 0.7819767441860465 0.30729166666666663 0.20348837209302326 0.15625 +0 0.45930232558139533 0.5963541666666666 0.20348837209302326 0.15625 +0 0.8023255813953488 0.7317708333333333 0.20348837209302326 0.15625 +0 0.2761627906976744 0.10416666666666666 0.20348837209302326 0.15625 +0 0.18023255813953487 0.53125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/23ad24f4ba9c49dcc0556d223244cfca.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/23ad24f4ba9c49dcc0556d223244cfca.txt new file mode 100644 index 0000000..0c1152e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/23ad24f4ba9c49dcc0556d223244cfca.txt @@ -0,0 +1,4 @@ +0 0.3895348837209302 0.5260416666666666 0.20348837209302326 0.15625 +0 0.686046511627907 0.5989583333333333 0.20348837209302326 0.15625 +0 0.4563953488372093 0.27604166666666663 0.20348837209302326 0.15625 +0 0.7674418604651163 0.09635416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/23b763675fdcbcc8231a7331a5ee2054.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/23b763675fdcbcc8231a7331a5ee2054.txt new file mode 100644 index 0000000..8f78eff --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/23b763675fdcbcc8231a7331a5ee2054.txt @@ -0,0 +1,4 @@ +0 0.12209302325581395 0.09114583333333333 0.20348837209302326 0.15625 +0 0.16569767441860464 0.671875 0.20348837209302326 0.15625 +0 0.8197674418604651 0.2265625 0.20348837209302326 0.15625 +0 0.7645348837209303 0.6432291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/23b7bb244e75296aa9d3c9ce8909776f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/23b7bb244e75296aa9d3c9ce8909776f.txt new file mode 100644 index 0000000..0c2039f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/23b7bb244e75296aa9d3c9ce8909776f.txt @@ -0,0 +1,4 @@ +0 0.5552325581395349 0.7526041666666666 0.20348837209302326 0.15625 +0 0.25872093023255816 0.234375 0.20348837209302326 0.15625 +0 0.2819767441860465 0.7161458333333333 0.20348837209302326 0.15625 +0 0.7790697674418604 0.46875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2405b94d92350980466907ad21b177fd.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2405b94d92350980466907ad21b177fd.txt new file mode 100644 index 0000000..2bddfd5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2405b94d92350980466907ad21b177fd.txt @@ -0,0 +1,4 @@ +0 0.47093023255813954 0.5052083333333333 0.20348837209302326 0.15625 +0 0.8546511627906976 0.21614583333333331 0.20348837209302326 0.15625 +0 0.18023255813953487 0.6484375 0.20348837209302326 0.15625 +0 0.5668604651162791 0.7473958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/243b73642e664939459c368e8b961eed.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/243b73642e664939459c368e8b961eed.txt new file mode 100644 index 0000000..a760cf2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/243b73642e664939459c368e8b961eed.txt @@ -0,0 +1,5 @@ +0 0.43023255813953487 0.6692708333333333 0.20348837209302326 0.15625 +0 0.6744186046511628 0.0859375 0.20348837209302326 0.15625 +0 0.2761627906976744 0.15625 0.20348837209302326 0.15625 +0 0.7412790697674418 0.6822916666666666 0.20348837209302326 0.15625 +0 0.6104651162790697 0.32291666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2482b9ea7ec49ff82dfbdd25a165ac11.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2482b9ea7ec49ff82dfbdd25a165ac11.txt new file mode 100644 index 0000000..c27e2a4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2482b9ea7ec49ff82dfbdd25a165ac11.txt @@ -0,0 +1,4 @@ +0 0.18895348837209303 0.484375 0.20348837209302326 0.15625 +0 0.5058139534883721 0.5182291666666666 0.20348837209302326 0.15625 +0 0.7122093023255814 0.24479166666666666 0.20348837209302326 0.15625 +0 0.31976744186046513 0.17708333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/24b31e4dc0ef9a1b7fb4982fa6fa1d67.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/24b31e4dc0ef9a1b7fb4982fa6fa1d67.txt new file mode 100644 index 0000000..384380c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/24b31e4dc0ef9a1b7fb4982fa6fa1d67.txt @@ -0,0 +1,2 @@ +0 0.2005813953488372 0.5494791666666666 0.20348837209302326 0.15625 +0 0.7790697674418604 0.21875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/24c4675db1fc6ce5fef94865f8e8657f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/24c4675db1fc6ce5fef94865f8e8657f.txt new file mode 100644 index 0000000..c39db68 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/24c4675db1fc6ce5fef94865f8e8657f.txt @@ -0,0 +1,5 @@ +0 0.4883720930232558 0.7734375 0.20348837209302326 0.15625 +0 0.4127906976744186 0.5104166666666666 0.20348837209302326 0.15625 +0 0.7180232558139534 0.5572916666666666 0.20348837209302326 0.15625 +0 0.12790697674418605 0.23177083333333331 0.20348837209302326 0.15625 +0 0.5348837209302325 0.2421875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/24c4e43259813c107e1880cef1259ae2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/24c4e43259813c107e1880cef1259ae2.txt new file mode 100644 index 0000000..10c6c50 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/24c4e43259813c107e1880cef1259ae2.txt @@ -0,0 +1,4 @@ +0 0.2441860465116279 0.609375 0.20348837209302326 0.15625 +0 0.6366279069767442 0.31510416666666663 0.20348837209302326 0.15625 +0 0.8255813953488372 0.6692708333333333 0.20348837209302326 0.15625 +0 0.21220930232558138 0.11197916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/24e532b00dbb22fbf8d3eb69d9c43fe2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/24e532b00dbb22fbf8d3eb69d9c43fe2.txt new file mode 100644 index 0000000..ac4d230 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/24e532b00dbb22fbf8d3eb69d9c43fe2.txt @@ -0,0 +1,3 @@ +0 0.23546511627906977 0.5338541666666666 0.20348837209302326 0.15625 +0 0.5203488372093024 0.7760416666666666 0.20348837209302326 0.15625 +0 0.7732558139534884 0.3177083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2528763dfb1415935b12345e46536883.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2528763dfb1415935b12345e46536883.txt new file mode 100644 index 0000000..c6fa528 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2528763dfb1415935b12345e46536883.txt @@ -0,0 +1,5 @@ +0 0.5 0.2864583333333333 0.20348837209302326 0.15625 +0 0.8168604651162791 0.6875 0.20348837209302326 0.15625 +0 0.8197674418604651 0.296875 0.20348837209302326 0.15625 +0 0.375 0.6953125 0.20348837209302326 0.15625 +0 0.1686046511627907 0.2578125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/252c16abff5c2aa55d5f5649653cff6d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/252c16abff5c2aa55d5f5649653cff6d.txt new file mode 100644 index 0000000..b7d6a8d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/252c16abff5c2aa55d5f5649653cff6d.txt @@ -0,0 +1,5 @@ +0 0.3023255813953488 0.703125 0.20348837209302326 0.15625 +0 0.8081395348837209 0.22135416666666666 0.20348837209302326 0.15625 +0 0.2616279069767442 0.33854166666666663 0.20348837209302326 0.15625 +0 0.6511627906976745 0.7057291666666666 0.20348837209302326 0.15625 +0 0.5203488372093024 0.43229166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/252dc1039d55faf8f96f0d0522a87f68.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/252dc1039d55faf8f96f0d0522a87f68.txt new file mode 100644 index 0000000..114ba7b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/252dc1039d55faf8f96f0d0522a87f68.txt @@ -0,0 +1,4 @@ +0 0.7034883720930233 0.265625 0.20348837209302326 0.15625 +0 0.625 0.6979166666666666 0.20348837209302326 0.15625 +0 0.3372093023255814 0.6796875 0.20348837209302326 0.15625 +0 0.34593023255813954 0.19010416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/253c1cf9c37f194ff42dfd8d699f542b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/253c1cf9c37f194ff42dfd8d699f542b.txt new file mode 100644 index 0000000..4fd29ec --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/253c1cf9c37f194ff42dfd8d699f542b.txt @@ -0,0 +1,4 @@ +0 0.1569767441860465 0.15364583333333331 0.20348837209302326 0.15625 +0 0.7906976744186046 0.7786458333333333 0.20348837209302326 0.15625 +0 0.47093023255813954 0.4739583333333333 0.20348837209302326 0.15625 +0 0.8459302325581395 0.4609375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/25442cd7d6867aa14a8b4f3e84fcd312.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/25442cd7d6867aa14a8b4f3e84fcd312.txt new file mode 100644 index 0000000..b79a837 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/25442cd7d6867aa14a8b4f3e84fcd312.txt @@ -0,0 +1,4 @@ +0 0.7790697674418604 0.18229166666666666 0.20348837209302326 0.15625 +0 0.25872093023255816 0.484375 0.20348837209302326 0.15625 +0 0.7965116279069767 0.47135416666666663 0.20348837209302326 0.15625 +0 0.30523255813953487 0.7942708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2572489e8fbda978b69ad5701ac183ca.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2572489e8fbda978b69ad5701ac183ca.txt new file mode 100644 index 0000000..0e2162b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2572489e8fbda978b69ad5701ac183ca.txt @@ -0,0 +1,3 @@ +0 0.5058139534883721 0.390625 0.20348837209302326 0.15625 +0 0.21220930232558138 0.6588541666666666 0.20348837209302326 0.15625 +0 0.1947674418604651 0.2890625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/25a8971dbaf318a9fafa771398d2bb27.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/25a8971dbaf318a9fafa771398d2bb27.txt new file mode 100644 index 0000000..9806d46 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/25a8971dbaf318a9fafa771398d2bb27.txt @@ -0,0 +1,4 @@ +0 0.6598837209302325 0.11197916666666666 0.20348837209302326 0.15625 +0 0.2819767441860465 0.6119791666666666 0.20348837209302326 0.15625 +0 0.7441860465116279 0.4739583333333333 0.20348837209302326 0.15625 +0 0.25290697674418605 0.375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/266ebc793a3a4f768f51843d30d928b4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/266ebc793a3a4f768f51843d30d928b4.txt new file mode 100644 index 0000000..9f5b808 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/266ebc793a3a4f768f51843d30d928b4.txt @@ -0,0 +1,3 @@ +0 0.26744186046511625 0.7578125 0.20348837209302326 0.15625 +0 0.7558139534883721 0.2421875 0.20348837209302326 0.15625 +0 0.47093023255813954 0.3645833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2692ad9b21167e92aeb5f680d04b2943.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2692ad9b21167e92aeb5f680d04b2943.txt new file mode 100644 index 0000000..bffb528 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2692ad9b21167e92aeb5f680d04b2943.txt @@ -0,0 +1,3 @@ +0 0.6540697674418604 0.3671875 0.20348837209302326 0.15625 +0 0.311046511627907 0.140625 0.20348837209302326 0.15625 +0 0.5697674418604651 0.7526041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/26ab9ad844e0fb566acecc33a59d8f0c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/26ab9ad844e0fb566acecc33a59d8f0c.txt new file mode 100644 index 0000000..aa243e7 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/26ab9ad844e0fb566acecc33a59d8f0c.txt @@ -0,0 +1,4 @@ +0 0.2616279069767442 0.16145833333333331 0.20348837209302326 0.15625 +0 0.8691860465116279 0.203125 0.20348837209302326 0.15625 +0 0.7238372093023255 0.7630208333333333 0.20348837209302326 0.15625 +0 0.13953488372093023 0.5963541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/26c9b08fe3a222681c30e122d7100cfb.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/26c9b08fe3a222681c30e122d7100cfb.txt new file mode 100644 index 0000000..af8a543 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/26c9b08fe3a222681c30e122d7100cfb.txt @@ -0,0 +1,4 @@ +0 0.8197674418604651 0.6901041666666666 0.20348837209302326 0.15625 +0 0.21511627906976744 0.5234375 0.20348837209302326 0.15625 +0 0.5058139534883721 0.11458333333333333 0.20348837209302326 0.15625 +0 0.5087209302325582 0.41666666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/26ff5049791fd2ca3b340179e8bd2f6e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/26ff5049791fd2ca3b340179e8bd2f6e.txt new file mode 100644 index 0000000..e83c681 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/26ff5049791fd2ca3b340179e8bd2f6e.txt @@ -0,0 +1,4 @@ +0 0.313953488372093 0.4270833333333333 0.20348837209302326 0.15625 +0 0.32848837209302323 0.7265625 0.20348837209302326 0.15625 +0 0.6802325581395349 0.6666666666666666 0.20348837209302326 0.15625 +0 0.37790697674418605 0.1875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/275824c44f2764e3dabc1aa394a63f5d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/275824c44f2764e3dabc1aa394a63f5d.txt new file mode 100644 index 0000000..5de65f0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/275824c44f2764e3dabc1aa394a63f5d.txt @@ -0,0 +1,4 @@ +0 0.27325581395348836 0.21875 0.20348837209302326 0.15625 +0 0.686046511627907 0.59375 0.20348837209302326 0.15625 +0 0.2645348837209302 0.6458333333333333 0.20348837209302326 0.15625 +0 0.8662790697674418 0.14583333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/27614a499cd42da30086c5fc04357495.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/27614a499cd42da30086c5fc04357495.txt new file mode 100644 index 0000000..a8abbd0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/27614a499cd42da30086c5fc04357495.txt @@ -0,0 +1,3 @@ +0 0.6831395348837209 0.15625 0.20348837209302326 0.15625 +0 0.2936046511627907 0.36197916666666663 0.20348837209302326 0.15625 +0 0.752906976744186 0.7760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2785b56988566f9b40632aa4dd2639c0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2785b56988566f9b40632aa4dd2639c0.txt new file mode 100644 index 0000000..31d161b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2785b56988566f9b40632aa4dd2639c0.txt @@ -0,0 +1,4 @@ +0 0.2005813953488372 0.578125 0.20348837209302326 0.15625 +0 0.16279069767441862 0.1796875 0.20348837209302326 0.15625 +0 0.5581395348837209 0.7291666666666666 0.20348837209302326 0.15625 +0 0.6482558139534884 0.2734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/27cedc437426bbc65ea5eaf99a103f93.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/27cedc437426bbc65ea5eaf99a103f93.txt new file mode 100644 index 0000000..e2b58f2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/27cedc437426bbc65ea5eaf99a103f93.txt @@ -0,0 +1,3 @@ +0 0.5872093023255814 0.515625 0.20348837209302326 0.15625 +0 0.6453488372093024 0.20833333333333331 0.20348837209302326 0.15625 +0 0.2645348837209302 0.23958333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/27e4f1d606aa041331f837fc36d80303.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/27e4f1d606aa041331f837fc36d80303.txt new file mode 100644 index 0000000..9300e6e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/27e4f1d606aa041331f837fc36d80303.txt @@ -0,0 +1,3 @@ +0 0.75 0.5182291666666666 0.20348837209302326 0.15625 +0 0.6046511627906976 0.2630208333333333 0.20348837209302326 0.15625 +0 0.38372093023255816 0.6692708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2802b54b9ce502a3d0223373ef29f9e5.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2802b54b9ce502a3d0223373ef29f9e5.txt new file mode 100644 index 0000000..9b8f4ce --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2802b54b9ce502a3d0223373ef29f9e5.txt @@ -0,0 +1,5 @@ +0 0.45348837209302323 0.6953125 0.20348837209302326 0.15625 +0 0.8604651162790697 0.6067708333333333 0.20348837209302326 0.15625 +0 0.6656976744186046 0.14322916666666666 0.20348837209302326 0.15625 +0 0.5145348837209303 0.37760416666666663 0.20348837209302326 0.15625 +0 0.18313953488372092 0.11458333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/29217bf09348fc6672f31a2b0b75dddf.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/29217bf09348fc6672f31a2b0b75dddf.txt new file mode 100644 index 0000000..8a3fd9e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/29217bf09348fc6672f31a2b0b75dddf.txt @@ -0,0 +1,4 @@ +0 0.6511627906976745 0.515625 0.20348837209302326 0.15625 +0 0.2703488372093023 0.2734375 0.20348837209302326 0.15625 +0 0.7063953488372093 0.7526041666666666 0.20348837209302326 0.15625 +0 0.7034883720930233 0.12239583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/29531f6ee4db068fef479ffe078d3407.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/29531f6ee4db068fef479ffe078d3407.txt new file mode 100644 index 0000000..c078345 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/29531f6ee4db068fef479ffe078d3407.txt @@ -0,0 +1,4 @@ +0 0.1569767441860465 0.40104166666666663 0.20348837209302326 0.15625 +0 0.8284883720930233 0.6848958333333333 0.20348837209302326 0.15625 +0 0.3546511627906977 0.1171875 0.20348837209302326 0.15625 +0 0.45930232558139533 0.6432291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/297e8f9878261738824b46a843101fad.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/297e8f9878261738824b46a843101fad.txt new file mode 100644 index 0000000..a870599 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/297e8f9878261738824b46a843101fad.txt @@ -0,0 +1,4 @@ +0 0.7936046511627907 0.5833333333333333 0.20348837209302326 0.15625 +0 0.22965116279069767 0.65625 0.20348837209302326 0.15625 +0 0.5930232558139534 0.265625 0.20348837209302326 0.15625 +0 0.24127906976744184 0.33854166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/29e4037dfe177961578e61016abc238b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/29e4037dfe177961578e61016abc238b.txt new file mode 100644 index 0000000..fa60bd3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/29e4037dfe177961578e61016abc238b.txt @@ -0,0 +1,5 @@ +0 0.18895348837209303 0.7395833333333333 0.20348837209302326 0.15625 +0 0.7005813953488372 0.26041666666666663 0.20348837209302326 0.15625 +0 0.7674418604651163 0.7890625 0.20348837209302326 0.15625 +0 0.20930232558139533 0.11197916666666666 0.20348837209302326 0.15625 +0 0.5087209302325582 0.7734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2a11e5c25520dfbf4f7acfe8eeb17ac8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2a11e5c25520dfbf4f7acfe8eeb17ac8.txt new file mode 100644 index 0000000..1b22122 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2a11e5c25520dfbf4f7acfe8eeb17ac8.txt @@ -0,0 +1,3 @@ +0 0.3430232558139535 0.2708333333333333 0.20348837209302326 0.15625 +0 0.6075581395348837 0.390625 0.20348837209302326 0.15625 +0 0.25290697674418605 0.6432291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2a12d8bad11354d42223677b019756f4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2a12d8bad11354d42223677b019756f4.txt new file mode 100644 index 0000000..93888b9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2a12d8bad11354d42223677b019756f4.txt @@ -0,0 +1,4 @@ +0 0.46511627906976744 0.7473958333333333 0.20348837209302326 0.15625 +0 0.6569767441860465 0.32291666666666663 0.20348837209302326 0.15625 +0 0.28488372093023256 0.29947916666666663 0.20348837209302326 0.15625 +0 0.7819767441860465 0.5729166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2a51f4389143ab687afff1d2c48e11de.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2a51f4389143ab687afff1d2c48e11de.txt new file mode 100644 index 0000000..0d6766d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2a51f4389143ab687afff1d2c48e11de.txt @@ -0,0 +1,5 @@ +0 0.6308139534883721 0.34635416666666663 0.20348837209302326 0.15625 +0 0.3313953488372093 0.6796875 0.20348837209302326 0.15625 +0 0.747093023255814 0.09114583333333333 0.20348837209302326 0.15625 +0 0.19767441860465115 0.3098958333333333 0.20348837209302326 0.15625 +0 0.7761627906976744 0.6145833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2bc569ff922b5e5721ec56382c202a08.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2bc569ff922b5e5721ec56382c202a08.txt new file mode 100644 index 0000000..16167b1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2bc569ff922b5e5721ec56382c202a08.txt @@ -0,0 +1,5 @@ +0 0.7994186046511628 0.4921875 0.20348837209302326 0.15625 +0 0.2238372093023256 0.546875 0.20348837209302326 0.15625 +0 0.5232558139534884 0.5390625 0.20348837209302326 0.15625 +0 0.47674418604651164 0.26822916666666663 0.20348837209302326 0.15625 +0 0.2819767441860465 0.7864583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2bf7d3943ea7c1c1f769454a0532b5cc.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2bf7d3943ea7c1c1f769454a0532b5cc.txt new file mode 100644 index 0000000..a394cbc --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2bf7d3943ea7c1c1f769454a0532b5cc.txt @@ -0,0 +1,4 @@ +0 0.8313953488372093 0.3828125 0.20348837209302326 0.15625 +0 0.23546511627906977 0.7265625 0.20348837209302326 0.15625 +0 0.436046511627907 0.3255208333333333 0.20348837209302326 0.15625 +0 0.8255813953488372 0.7291666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2cd539a53507a68be0b187b78220b5ae.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2cd539a53507a68be0b187b78220b5ae.txt new file mode 100644 index 0000000..847c875 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2cd539a53507a68be0b187b78220b5ae.txt @@ -0,0 +1,5 @@ +0 0.5872093023255814 0.34375 0.20348837209302326 0.15625 +0 0.13662790697674418 0.265625 0.20348837209302326 0.15625 +0 0.39825581395348836 0.7005208333333333 0.20348837209302326 0.15625 +0 0.7441860465116279 0.6223958333333333 0.20348837209302326 0.15625 +0 0.5348837209302325 0.1015625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2cf988cb3cbf0a33905d0eb8f22a4d10.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2cf988cb3cbf0a33905d0eb8f22a4d10.txt new file mode 100644 index 0000000..5ff51dc --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2cf988cb3cbf0a33905d0eb8f22a4d10.txt @@ -0,0 +1,3 @@ +0 0.5784883720930233 0.44010416666666663 0.20348837209302326 0.15625 +0 0.13662790697674418 0.11458333333333333 0.20348837209302326 0.15625 +0 0.5872093023255814 0.10416666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2cffbb67e88753b5ce9e76ad3ca8a02c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2cffbb67e88753b5ce9e76ad3ca8a02c.txt new file mode 100644 index 0000000..37cda6c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2cffbb67e88753b5ce9e76ad3ca8a02c.txt @@ -0,0 +1,4 @@ +0 0.2761627906976744 0.609375 0.20348837209302326 0.15625 +0 0.5581395348837209 0.15885416666666666 0.20348837209302326 0.15625 +0 0.6976744186046512 0.4296875 0.20348837209302326 0.15625 +0 0.2180232558139535 0.16145833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2d6644ac20fc154f3f87991a7a72ff0b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2d6644ac20fc154f3f87991a7a72ff0b.txt new file mode 100644 index 0000000..777fbfb --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2d6644ac20fc154f3f87991a7a72ff0b.txt @@ -0,0 +1,4 @@ +0 0.25 0.29947916666666663 0.20348837209302326 0.15625 +0 0.6511627906976745 0.4609375 0.20348837209302326 0.15625 +0 0.6627906976744186 0.703125 0.20348837209302326 0.15625 +0 0.21511627906976744 0.65625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2d81f892b114e8411d2ccefdce810344.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2d81f892b114e8411d2ccefdce810344.txt new file mode 100644 index 0000000..73bbc10 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2d81f892b114e8411d2ccefdce810344.txt @@ -0,0 +1,5 @@ +0 0.11918604651162791 0.6510416666666666 0.20348837209302326 0.15625 +0 0.7412790697674418 0.22135416666666666 0.20348837209302326 0.15625 +0 0.436046511627907 0.7786458333333333 0.20348837209302326 0.15625 +0 0.8284883720930233 0.484375 0.20348837209302326 0.15625 +0 0.37209302325581395 0.2578125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2dd7ac714f6f2d23274b25426ba48c28.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2dd7ac714f6f2d23274b25426ba48c28.txt new file mode 100644 index 0000000..d0671b3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2dd7ac714f6f2d23274b25426ba48c28.txt @@ -0,0 +1,5 @@ +0 0.6976744186046512 0.10416666666666666 0.20348837209302326 0.15625 +0 0.7238372093023255 0.6276041666666666 0.20348837209302326 0.15625 +0 0.7180232558139534 0.3671875 0.20348837209302326 0.15625 +0 0.38372093023255816 0.6848958333333333 0.20348837209302326 0.15625 +0 0.22674418604651161 0.15625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2de05aac0bfe7d09d439bd446a987cba.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2de05aac0bfe7d09d439bd446a987cba.txt new file mode 100644 index 0000000..49c05bf --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2de05aac0bfe7d09d439bd446a987cba.txt @@ -0,0 +1,5 @@ +0 0.5406976744186046 0.5885416666666666 0.20348837209302326 0.15625 +0 0.30523255813953487 0.3020833333333333 0.20348837209302326 0.15625 +0 0.15406976744186046 0.6901041666666666 0.20348837209302326 0.15625 +0 0.7761627906976744 0.3255208333333333 0.20348837209302326 0.15625 +0 0.8546511627906976 0.6692708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2e62bb50610ea90401f3f22af756bb90.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2e62bb50610ea90401f3f22af756bb90.txt new file mode 100644 index 0000000..84b62de --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2e62bb50610ea90401f3f22af756bb90.txt @@ -0,0 +1,4 @@ +0 0.4273255813953488 0.47916666666666663 0.20348837209302326 0.15625 +0 0.5348837209302325 0.18229166666666666 0.20348837209302326 0.15625 +0 0.7587209302325582 0.75 0.20348837209302326 0.15625 +0 0.13953488372093023 0.6171875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2e9c77df2fe9918c86b7dba5d8d4eb90.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2e9c77df2fe9918c86b7dba5d8d4eb90.txt new file mode 100644 index 0000000..424fa9d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2e9c77df2fe9918c86b7dba5d8d4eb90.txt @@ -0,0 +1,4 @@ +0 0.4418604651162791 0.2890625 0.20348837209302326 0.15625 +0 0.7936046511627907 0.5625 0.20348837209302326 0.15625 +0 0.26744186046511625 0.4895833333333333 0.20348837209302326 0.15625 +0 0.7761627906976744 0.140625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2ed9136952126655cd5aed1eabe4b643.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2ed9136952126655cd5aed1eabe4b643.txt new file mode 100644 index 0000000..3da9a4e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2ed9136952126655cd5aed1eabe4b643.txt @@ -0,0 +1,4 @@ +0 0.6511627906976745 0.21875 0.20348837209302326 0.15625 +0 0.24127906976744184 0.7213541666666666 0.20348837209302326 0.15625 +0 0.6424418604651163 0.5729166666666666 0.20348837209302326 0.15625 +0 0.23546511627906977 0.4140625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2ef14dde986e023e3b29a9418ac383aa.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2ef14dde986e023e3b29a9418ac383aa.txt new file mode 100644 index 0000000..74eb0d4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2ef14dde986e023e3b29a9418ac383aa.txt @@ -0,0 +1,5 @@ +0 0.29069767441860467 0.5755208333333333 0.20348837209302326 0.15625 +0 0.7616279069767442 0.7369791666666666 0.20348837209302326 0.15625 +0 0.42441860465116277 0.10416666666666666 0.20348837209302326 0.15625 +0 0.6308139534883721 0.421875 0.20348837209302326 0.15625 +0 0.8197674418604651 0.15364583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2f14336db03cb04a3a13672ec39d554e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2f14336db03cb04a3a13672ec39d554e.txt new file mode 100644 index 0000000..99faf98 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2f14336db03cb04a3a13672ec39d554e.txt @@ -0,0 +1,4 @@ +0 0.4476744186046512 0.5026041666666666 0.20348837209302326 0.15625 +0 0.11046511627906977 0.24739583333333331 0.20348837209302326 0.15625 +0 0.4738372093023256 0.7421875 0.20348837209302326 0.15625 +0 0.7994186046511628 0.15104166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2f661a1ccc172fc4d93b34125e501b7c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2f661a1ccc172fc4d93b34125e501b7c.txt new file mode 100644 index 0000000..fb1ad78 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/2f661a1ccc172fc4d93b34125e501b7c.txt @@ -0,0 +1,5 @@ +0 0.5261627906976745 0.12760416666666666 0.20348837209302326 0.15625 +0 0.686046511627907 0.7708333333333333 0.20348837209302326 0.15625 +0 0.8430232558139534 0.3359375 0.20348837209302326 0.15625 +0 0.25290697674418605 0.5364583333333333 0.20348837209302326 0.15625 +0 0.23837209302325582 0.13020833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/301bf216d9158e5e00cf733564fe8deb.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/301bf216d9158e5e00cf733564fe8deb.txt new file mode 100644 index 0000000..f7ba547 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/301bf216d9158e5e00cf733564fe8deb.txt @@ -0,0 +1,4 @@ +0 0.2761627906976744 0.26041666666666663 0.20348837209302326 0.15625 +0 0.7558139534883721 0.5625 0.20348837209302326 0.15625 +0 0.29941860465116277 0.4765625 0.20348837209302326 0.15625 +0 0.747093023255814 0.3567708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/304884b9fb08dfed4f6d0ad3302dd481.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/304884b9fb08dfed4f6d0ad3302dd481.txt new file mode 100644 index 0000000..c982954 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/304884b9fb08dfed4f6d0ad3302dd481.txt @@ -0,0 +1,4 @@ +0 0.4622093023255814 0.6458333333333333 0.20348837209302326 0.15625 +0 0.13953488372093023 0.21614583333333331 0.20348837209302326 0.15625 +0 0.7587209302325582 0.3125 0.20348837209302326 0.15625 +0 0.46511627906976744 0.2708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/30734a8d96f16fc032fdae23abb125fd.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/30734a8d96f16fc032fdae23abb125fd.txt new file mode 100644 index 0000000..42b0426 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/30734a8d96f16fc032fdae23abb125fd.txt @@ -0,0 +1,4 @@ +0 0.1947674418604651 0.6953125 0.20348837209302326 0.15625 +0 0.6075581395348837 0.7473958333333333 0.20348837209302326 0.15625 +0 0.27325581395348836 0.12239583333333333 0.20348837209302326 0.15625 +0 0.6656976744186046 0.5078125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/30c454de1091e2c8353031014f357d8a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/30c454de1091e2c8353031014f357d8a.txt new file mode 100644 index 0000000..4e79138 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/30c454de1091e2c8353031014f357d8a.txt @@ -0,0 +1,4 @@ +0 0.2645348837209302 0.5 0.20348837209302326 0.15625 +0 0.7994186046511628 0.24479166666666666 0.20348837209302326 0.15625 +0 0.23255813953488372 0.21875 0.20348837209302326 0.15625 +0 0.5348837209302325 0.6953125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/30ea0a988ada37d49ae0a3b625001a2b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/30ea0a988ada37d49ae0a3b625001a2b.txt new file mode 100644 index 0000000..7690c31 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/30ea0a988ada37d49ae0a3b625001a2b.txt @@ -0,0 +1,5 @@ +0 0.2703488372093023 0.17447916666666666 0.20348837209302326 0.15625 +0 0.1686046511627907 0.578125 0.20348837209302326 0.15625 +0 0.6191860465116279 0.22135416666666666 0.20348837209302326 0.15625 +0 0.7790697674418604 0.5572916666666666 0.20348837209302326 0.15625 +0 0.4563953488372093 0.7473958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/317fef1a77ccd76f488fd3d989d7277f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/317fef1a77ccd76f488fd3d989d7277f.txt new file mode 100644 index 0000000..f614758 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/317fef1a77ccd76f488fd3d989d7277f.txt @@ -0,0 +1,4 @@ +0 0.7034883720930233 0.15364583333333331 0.20348837209302326 0.15625 +0 0.4011627906976744 0.6145833333333333 0.20348837209302326 0.15625 +0 0.3226744186046512 0.3828125 0.20348837209302326 0.15625 +0 0.75 0.7265625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/31aff6c22410f62e6f81edda3c76bf37.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/31aff6c22410f62e6f81edda3c76bf37.txt new file mode 100644 index 0000000..8017c5a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/31aff6c22410f62e6f81edda3c76bf37.txt @@ -0,0 +1,3 @@ +0 0.8226744186046512 0.5208333333333333 0.20348837209302326 0.15625 +0 0.40406976744186046 0.2630208333333333 0.20348837209302326 0.15625 +0 0.7151162790697674 0.21875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/324cceb0ede63ea0451864b7374851ee.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/324cceb0ede63ea0451864b7374851ee.txt new file mode 100644 index 0000000..4d6b10a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/324cceb0ede63ea0451864b7374851ee.txt @@ -0,0 +1,4 @@ +0 0.1569767441860465 0.40104166666666663 0.20348837209302326 0.15625 +0 0.2238372093023256 0.6614583333333333 0.20348837209302326 0.15625 +0 0.688953488372093 0.4453125 0.20348837209302326 0.15625 +0 0.5203488372093024 0.19270833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/32931cea51d456eb118d48ba251fd96c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/32931cea51d456eb118d48ba251fd96c.txt new file mode 100644 index 0000000..86e8c6f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/32931cea51d456eb118d48ba251fd96c.txt @@ -0,0 +1,3 @@ +0 0.29941860465116277 0.7057291666666666 0.20348837209302326 0.15625 +0 0.30523255813953487 0.265625 0.20348837209302326 0.15625 +0 0.811046511627907 0.2265625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/32bcb16a2ac96d8d06a951f68454547e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/32bcb16a2ac96d8d06a951f68454547e.txt new file mode 100644 index 0000000..f34502f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/32bcb16a2ac96d8d06a951f68454547e.txt @@ -0,0 +1,4 @@ +0 0.622093023255814 0.7552083333333333 0.20348837209302326 0.15625 +0 0.8168604651162791 0.4348958333333333 0.20348837209302326 0.15625 +0 0.2761627906976744 0.7447916666666666 0.20348837209302326 0.15625 +0 0.7325581395348837 0.15885416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3358ec54f4f2d54e20a1afea0444603b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3358ec54f4f2d54e20a1afea0444603b.txt new file mode 100644 index 0000000..eea3097 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3358ec54f4f2d54e20a1afea0444603b.txt @@ -0,0 +1,5 @@ +0 0.5726744186046512 0.32291666666666663 0.20348837209302326 0.15625 +0 0.5813953488372093 0.6953125 0.20348837209302326 0.15625 +0 0.18313953488372092 0.6354166666666666 0.20348837209302326 0.15625 +0 0.27325581395348836 0.11979166666666666 0.20348837209302326 0.15625 +0 0.22965116279069767 0.359375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/33aafbf05b7a45ae5fd4305bd6b71bfd.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/33aafbf05b7a45ae5fd4305bd6b71bfd.txt new file mode 100644 index 0000000..5e0a2c3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/33aafbf05b7a45ae5fd4305bd6b71bfd.txt @@ -0,0 +1,4 @@ +0 0.6308139534883721 0.4505208333333333 0.20348837209302326 0.15625 +0 0.21220930232558138 0.3489583333333333 0.20348837209302326 0.15625 +0 0.8197674418604651 0.703125 0.20348837209302326 0.15625 +0 0.5232558139534884 0.203125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/33cc6dd020e9e87b38d6714ad48173b3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/33cc6dd020e9e87b38d6714ad48173b3.txt new file mode 100644 index 0000000..7dc8144 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/33cc6dd020e9e87b38d6714ad48173b3.txt @@ -0,0 +1,4 @@ +0 0.27325581395348836 0.5104166666666666 0.20348837209302326 0.15625 +0 0.7005813953488372 0.265625 0.20348837209302326 0.15625 +0 0.7790697674418604 0.6276041666666666 0.20348837209302326 0.15625 +0 0.28488372093023256 0.23697916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/33cc9a0a271a8969ce825a322d871eb0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/33cc9a0a271a8969ce825a322d871eb0.txt new file mode 100644 index 0000000..1820b8b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/33cc9a0a271a8969ce825a322d871eb0.txt @@ -0,0 +1,4 @@ +0 0.16279069767441862 0.29166666666666663 0.20348837209302326 0.15625 +0 0.6162790697674418 0.29947916666666663 0.20348837209302326 0.15625 +0 0.6686046511627907 0.5989583333333333 0.20348837209302326 0.15625 +0 0.313953488372093 0.6614583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/33f6fe0cc7349bc429d851070034b9c7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/33f6fe0cc7349bc429d851070034b9c7.txt new file mode 100644 index 0000000..cb76d13 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/33f6fe0cc7349bc429d851070034b9c7.txt @@ -0,0 +1,4 @@ +0 0.8604651162790697 0.6901041666666666 0.20348837209302326 0.15625 +0 0.5436046511627907 0.12760416666666666 0.20348837209302326 0.15625 +0 0.22093023255813954 0.7447916666666666 0.20348837209302326 0.15625 +0 0.5087209302325582 0.6901041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/34265621dc29035f2a6374aa4c0928cd.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/34265621dc29035f2a6374aa4c0928cd.txt new file mode 100644 index 0000000..8f150b3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/34265621dc29035f2a6374aa4c0928cd.txt @@ -0,0 +1,4 @@ +0 0.45348837209302323 0.18489583333333331 0.20348837209302326 0.15625 +0 0.1569767441860465 0.4895833333333333 0.20348837209302326 0.15625 +0 0.8459302325581395 0.4114583333333333 0.20348837209302326 0.15625 +0 0.39244186046511625 0.7369791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/344697d5ea9d8f7a88988a4c3c137e05.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/344697d5ea9d8f7a88988a4c3c137e05.txt new file mode 100644 index 0000000..65e2251 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/344697d5ea9d8f7a88988a4c3c137e05.txt @@ -0,0 +1,4 @@ +0 0.16279069767441862 0.7239583333333333 0.20348837209302326 0.15625 +0 0.6947674418604651 0.1640625 0.20348837209302326 0.15625 +0 0.3808139534883721 0.140625 0.20348837209302326 0.15625 +0 0.4563953488372093 0.7291666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/34859f8d0b5daf546cd23ca7f8980bec.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/34859f8d0b5daf546cd23ca7f8980bec.txt new file mode 100644 index 0000000..3380a53 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/34859f8d0b5daf546cd23ca7f8980bec.txt @@ -0,0 +1,5 @@ +0 0.20348837209302326 0.15885416666666666 0.20348837209302326 0.15625 +0 0.21511627906976744 0.5286458333333333 0.20348837209302326 0.15625 +0 0.6715116279069767 0.140625 0.20348837209302326 0.15625 +0 0.6627906976744186 0.546875 0.20348837209302326 0.15625 +0 0.13372093023255813 0.7734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/34cfa27bda86ba353341d82e6e2d3e3a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/34cfa27bda86ba353341d82e6e2d3e3a.txt new file mode 100644 index 0000000..9a34658 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/34cfa27bda86ba353341d82e6e2d3e3a.txt @@ -0,0 +1,4 @@ +0 0.5494186046511628 0.5625 0.20348837209302326 0.15625 +0 0.22674418604651161 0.6067708333333333 0.20348837209302326 0.15625 +0 0.8401162790697674 0.3723958333333333 0.20348837209302326 0.15625 +0 0.7238372093023255 0.1171875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/352087fdb9d79e15044d8cb56361b7f6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/352087fdb9d79e15044d8cb56361b7f6.txt new file mode 100644 index 0000000..6d334c3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/352087fdb9d79e15044d8cb56361b7f6.txt @@ -0,0 +1,3 @@ +0 0.6831395348837209 0.6328125 0.20348837209302326 0.15625 +0 0.3895348837209302 0.30729166666666663 0.20348837209302326 0.15625 +0 0.19767441860465115 0.5390625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/354270d1b5c84e02c6d8f45bd34c9f93.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/354270d1b5c84e02c6d8f45bd34c9f93.txt new file mode 100644 index 0000000..a9a4731 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/354270d1b5c84e02c6d8f45bd34c9f93.txt @@ -0,0 +1,5 @@ +0 0.19186046511627908 0.3359375 0.20348837209302326 0.15625 +0 0.5 0.24739583333333331 0.20348837209302326 0.15625 +0 0.14825581395348836 0.6666666666666666 0.20348837209302326 0.15625 +0 0.811046511627907 0.3880208333333333 0.20348837209302326 0.15625 +0 0.8081395348837209 0.1484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/35433a835cefecc321f4bc6a9bc71adb.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/35433a835cefecc321f4bc6a9bc71adb.txt new file mode 100644 index 0000000..1a3c8a2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/35433a835cefecc321f4bc6a9bc71adb.txt @@ -0,0 +1,4 @@ +0 0.18604651162790697 0.2864583333333333 0.20348837209302326 0.15625 +0 0.7936046511627907 0.16666666666666666 0.20348837209302326 0.15625 +0 0.49709302325581395 0.203125 0.20348837209302326 0.15625 +0 0.6831395348837209 0.5234375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/358ab3e8a509856a29aaff4ff98a2da0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/358ab3e8a509856a29aaff4ff98a2da0.txt new file mode 100644 index 0000000..f5d0401 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/358ab3e8a509856a29aaff4ff98a2da0.txt @@ -0,0 +1,4 @@ +0 0.4011627906976744 0.7578125 0.20348837209302326 0.15625 +0 0.20348837209302326 0.3333333333333333 0.20348837209302326 0.15625 +0 0.6366279069767442 0.4765625 0.20348837209302326 0.15625 +0 0.8197674418604651 0.09635416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/35bb5dc037981ac228b323279a392f05.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/35bb5dc037981ac228b323279a392f05.txt new file mode 100644 index 0000000..d0ffd63 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/35bb5dc037981ac228b323279a392f05.txt @@ -0,0 +1,4 @@ +0 0.6511627906976745 0.31510416666666663 0.20348837209302326 0.15625 +0 0.2180232558139535 0.578125 0.20348837209302326 0.15625 +0 0.7209302325581395 0.5598958333333333 0.20348837209302326 0.15625 +0 0.14244186046511628 0.31510416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3709202f37839ddfcac127e14830c031.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3709202f37839ddfcac127e14830c031.txt new file mode 100644 index 0000000..cdb7f96 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3709202f37839ddfcac127e14830c031.txt @@ -0,0 +1,4 @@ +0 0.22093023255813954 0.4895833333333333 0.20348837209302326 0.15625 +0 0.8197674418604651 0.2265625 0.20348837209302326 0.15625 +0 0.6453488372093024 0.6458333333333333 0.20348837209302326 0.15625 +0 0.4011627906976744 0.12760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/373ffa4e024d68f6718fef76d254c10a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/373ffa4e024d68f6718fef76d254c10a.txt new file mode 100644 index 0000000..8c6c6e2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/373ffa4e024d68f6718fef76d254c10a.txt @@ -0,0 +1,4 @@ +0 0.27906976744186046 0.5807291666666666 0.20348837209302326 0.15625 +0 0.13953488372093023 0.2734375 0.20348837209302326 0.15625 +0 0.7587209302325582 0.3645833333333333 0.20348837209302326 0.15625 +0 0.8459302325581395 0.6484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/37af211faff08dd7fcee38778b23c3c0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/37af211faff08dd7fcee38778b23c3c0.txt new file mode 100644 index 0000000..40a9b60 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/37af211faff08dd7fcee38778b23c3c0.txt @@ -0,0 +1,4 @@ +0 0.7877906976744186 0.7864583333333333 0.20348837209302326 0.15625 +0 0.11337209302325581 0.23697916666666666 0.20348837209302326 0.15625 +0 0.6715116279069767 0.4765625 0.20348837209302326 0.15625 +0 0.5872093023255814 0.20833333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/37e115a70165f9fb469417d674ed1159.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/37e115a70165f9fb469417d674ed1159.txt new file mode 100644 index 0000000..ec29d8f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/37e115a70165f9fb469417d674ed1159.txt @@ -0,0 +1,4 @@ +0 0.8430232558139534 0.7369791666666666 0.20348837209302326 0.15625 +0 0.38372093023255816 0.6432291666666666 0.20348837209302326 0.15625 +0 0.30523255813953487 0.20052083333333331 0.20348837209302326 0.15625 +0 0.5813953488372093 0.19791666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/380171932c2c5d30c6a872fcc7cf4f70.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/380171932c2c5d30c6a872fcc7cf4f70.txt new file mode 100644 index 0000000..d7bfa1a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/380171932c2c5d30c6a872fcc7cf4f70.txt @@ -0,0 +1,3 @@ +0 0.4796511627906977 0.36197916666666663 0.20348837209302326 0.15625 +0 0.3488372093023256 0.10416666666666666 0.20348837209302326 0.15625 +0 0.17151162790697674 0.3880208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/38141676ba07b3162e0880b7095690a7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/38141676ba07b3162e0880b7095690a7.txt new file mode 100644 index 0000000..9ef4185 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/38141676ba07b3162e0880b7095690a7.txt @@ -0,0 +1,5 @@ +0 0.3372093023255814 0.4583333333333333 0.20348837209302326 0.15625 +0 0.7703488372093024 0.6536458333333333 0.20348837209302326 0.15625 +0 0.622093023255814 0.40885416666666663 0.20348837209302326 0.15625 +0 0.7965116279069767 0.109375 0.20348837209302326 0.15625 +0 0.14534883720930233 0.7317708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/383c368d567ead936df453b31aafdf03.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/383c368d567ead936df453b31aafdf03.txt new file mode 100644 index 0000000..acd0185 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/383c368d567ead936df453b31aafdf03.txt @@ -0,0 +1,4 @@ +0 0.42441860465116277 0.30729166666666663 0.20348837209302326 0.15625 +0 0.6162790697674418 0.6744791666666666 0.20348837209302326 0.15625 +0 0.7761627906976744 0.23697916666666666 0.20348837209302326 0.15625 +0 0.24709302325581395 0.7083333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/38765786334f6ae590c67b304a89846e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/38765786334f6ae590c67b304a89846e.txt new file mode 100644 index 0000000..c92489e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/38765786334f6ae590c67b304a89846e.txt @@ -0,0 +1,4 @@ +0 0.2063953488372093 0.6171875 0.20348837209302326 0.15625 +0 0.5058139534883721 0.09375 0.20348837209302326 0.15625 +0 0.563953488372093 0.5859375 0.20348837209302326 0.15625 +0 0.8633720930232558 0.6979166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/38e8a13e37e89e9f155709eeacc0e130.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/38e8a13e37e89e9f155709eeacc0e130.txt new file mode 100644 index 0000000..6d02008 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/38e8a13e37e89e9f155709eeacc0e130.txt @@ -0,0 +1,3 @@ +0 0.5726744186046512 0.2890625 0.20348837209302326 0.15625 +0 0.7790697674418604 0.5078125 0.20348837209302326 0.15625 +0 0.8459302325581395 0.7395833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3947f53dbe2dfa9f425ee519fbbb9627.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3947f53dbe2dfa9f425ee519fbbb9627.txt new file mode 100644 index 0000000..fdf8e1d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3947f53dbe2dfa9f425ee519fbbb9627.txt @@ -0,0 +1,4 @@ +0 0.5290697674418604 0.578125 0.20348837209302326 0.15625 +0 0.8575581395348837 0.19791666666666666 0.20348837209302326 0.15625 +0 0.23546511627906977 0.125 0.20348837209302326 0.15625 +0 0.1686046511627907 0.47916666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/39572c8f0ee635b9582ebfc68867a583.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/39572c8f0ee635b9582ebfc68867a583.txt new file mode 100644 index 0000000..135c899 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/39572c8f0ee635b9582ebfc68867a583.txt @@ -0,0 +1,5 @@ +0 0.2645348837209302 0.36197916666666663 0.20348837209302326 0.15625 +0 0.6773255813953488 0.6067708333333333 0.20348837209302326 0.15625 +0 0.5668604651162791 0.17447916666666666 0.20348837209302326 0.15625 +0 0.125 0.6536458333333333 0.20348837209302326 0.15625 +0 0.8284883720930233 0.3333333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/39998cd68c76b506594c31c94de6a4e2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/39998cd68c76b506594c31c94de6a4e2.txt new file mode 100644 index 0000000..3ac67cd --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/39998cd68c76b506594c31c94de6a4e2.txt @@ -0,0 +1,4 @@ +0 0.8488372093023255 0.4661458333333333 0.20348837209302326 0.15625 +0 0.2936046511627907 0.11979166666666666 0.20348837209302326 0.15625 +0 0.2063953488372093 0.7708333333333333 0.20348837209302326 0.15625 +0 0.6627906976744186 0.734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/39a1abca7498e67aeefdf5ba470e5baf.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/39a1abca7498e67aeefdf5ba470e5baf.txt new file mode 100644 index 0000000..155fe05 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/39a1abca7498e67aeefdf5ba470e5baf.txt @@ -0,0 +1,5 @@ +0 0.3430232558139535 0.19270833333333331 0.20348837209302326 0.15625 +0 0.4011627906976744 0.7473958333333333 0.20348837209302326 0.15625 +0 0.6976744186046512 0.40625 0.20348837209302326 0.15625 +0 0.32848837209302323 0.44791666666666663 0.20348837209302326 0.15625 +0 0.8343023255813954 0.6432291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3a05ebbefa111e8abc5bfca916b29f0c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3a05ebbefa111e8abc5bfca916b29f0c.txt new file mode 100644 index 0000000..cab58e6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3a05ebbefa111e8abc5bfca916b29f0c.txt @@ -0,0 +1,4 @@ +0 0.44476744186046513 0.3020833333333333 0.20348837209302326 0.15625 +0 0.3575581395348837 0.7552083333333333 0.20348837209302326 0.15625 +0 0.14825581395348836 0.33072916666666663 0.20348837209302326 0.15625 +0 0.7296511627906976 0.17447916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3a4ddda1468ddf3bc421107a1151ec12.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3a4ddda1468ddf3bc421107a1151ec12.txt new file mode 100644 index 0000000..d67b338 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3a4ddda1468ddf3bc421107a1151ec12.txt @@ -0,0 +1,3 @@ +0 0.7180232558139534 0.5546875 0.20348837209302326 0.15625 +0 0.8488372093023255 0.2708333333333333 0.20348837209302326 0.15625 +0 0.2063953488372093 0.16927083333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3ac3c7892c28af27bdfa389f63348e40.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3ac3c7892c28af27bdfa389f63348e40.txt new file mode 100644 index 0000000..0251ece --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3ac3c7892c28af27bdfa389f63348e40.txt @@ -0,0 +1,4 @@ +0 0.6744186046511628 0.5390625 0.20348837209302326 0.15625 +0 0.1308139534883721 0.4739583333333333 0.20348837209302326 0.15625 +0 0.4796511627906977 0.10677083333333333 0.20348837209302326 0.15625 +0 0.25290697674418605 0.6927083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3ad248eb9a4b550fb9eeb6178eed85b7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3ad248eb9a4b550fb9eeb6178eed85b7.txt new file mode 100644 index 0000000..3296086 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3ad248eb9a4b550fb9eeb6178eed85b7.txt @@ -0,0 +1,5 @@ +0 0.6162790697674418 0.2578125 0.20348837209302326 0.15625 +0 0.29069767441860467 0.4921875 0.20348837209302326 0.15625 +0 0.22093023255813954 0.171875 0.20348837209302326 0.15625 +0 0.5726744186046512 0.6119791666666666 0.20348837209302326 0.15625 +0 0.29069767441860467 0.7265625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3b04e9d066ef9b9ab2e9513397872508.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3b04e9d066ef9b9ab2e9513397872508.txt new file mode 100644 index 0000000..8f50747 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3b04e9d066ef9b9ab2e9513397872508.txt @@ -0,0 +1,5 @@ +0 0.8459302325581395 0.7057291666666666 0.20348837209302326 0.15625 +0 0.7122093023255814 0.14583333333333331 0.20348837209302326 0.15625 +0 0.37209302325581395 0.546875 0.20348837209302326 0.15625 +0 0.40406976744186046 0.7864583333333333 0.20348837209302326 0.15625 +0 0.18604651162790697 0.2942708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3b0b2785db0720c42f788afeda444bf0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3b0b2785db0720c42f788afeda444bf0.txt new file mode 100644 index 0000000..98405a3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3b0b2785db0720c42f788afeda444bf0.txt @@ -0,0 +1,3 @@ +0 0.7761627906976744 0.5989583333333333 0.20348837209302326 0.15625 +0 0.46511627906976744 0.5520833333333333 0.20348837209302326 0.15625 +0 0.6366279069767442 0.09375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3b28f8967114d50e7c790ae4e58bc138.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3b28f8967114d50e7c790ae4e58bc138.txt new file mode 100644 index 0000000..4ba1723 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3b28f8967114d50e7c790ae4e58bc138.txt @@ -0,0 +1,3 @@ +0 0.6686046511627907 0.2552083333333333 0.20348837209302326 0.15625 +0 0.42441860465116277 0.5052083333333333 0.20348837209302326 0.15625 +0 0.1308139534883721 0.16145833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3b5b69512930da8394e1c516a89f7679.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3b5b69512930da8394e1c516a89f7679.txt new file mode 100644 index 0000000..23f087f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3b5b69512930da8394e1c516a89f7679.txt @@ -0,0 +1,4 @@ +0 0.6831395348837209 0.11458333333333333 0.20348837209302326 0.15625 +0 0.2616279069767442 0.3359375 0.20348837209302326 0.15625 +0 0.5377906976744186 0.31510416666666663 0.20348837209302326 0.15625 +0 0.47093023255813954 0.6588541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3bb814bb367bf8b22e903e9a783255a8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3bb814bb367bf8b22e903e9a783255a8.txt new file mode 100644 index 0000000..fa40e5e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3bb814bb367bf8b22e903e9a783255a8.txt @@ -0,0 +1,4 @@ +0 0.686046511627907 0.5989583333333333 0.20348837209302326 0.15625 +0 0.3168604651162791 0.16145833333333331 0.20348837209302326 0.15625 +0 0.3895348837209302 0.5052083333333333 0.20348837209302326 0.15625 +0 0.622093023255814 0.16666666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3c09cd0d477c5c818cbf337a4dce155f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3c09cd0d477c5c818cbf337a4dce155f.txt new file mode 100644 index 0000000..31a2541 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3c09cd0d477c5c818cbf337a4dce155f.txt @@ -0,0 +1,3 @@ +0 0.8488372093023255 0.4921875 0.20348837209302326 0.15625 +0 0.23255813953488372 0.12760416666666666 0.20348837209302326 0.15625 +0 0.13662790697674418 0.7395833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3c1535c54b706927a6b9c600ec82ac09.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3c1535c54b706927a6b9c600ec82ac09.txt new file mode 100644 index 0000000..8e29f37 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3c1535c54b706927a6b9c600ec82ac09.txt @@ -0,0 +1,4 @@ +0 0.6162790697674418 0.5130208333333333 0.20348837209302326 0.15625 +0 0.13372093023255813 0.6640625 0.20348837209302326 0.15625 +0 0.5436046511627907 0.2265625 0.20348837209302326 0.15625 +0 0.6162790697674418 0.7630208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3c559399b79d0d44f349620a953f400d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3c559399b79d0d44f349620a953f400d.txt new file mode 100644 index 0000000..d664077 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3c559399b79d0d44f349620a953f400d.txt @@ -0,0 +1,4 @@ +0 0.15988372093023256 0.6328125 0.20348837209302326 0.15625 +0 0.7209302325581395 0.3359375 0.20348837209302326 0.15625 +0 0.375 0.3411458333333333 0.20348837209302326 0.15625 +0 0.4680232558139535 0.11197916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3c89b85cf2566f5a97110e4f8ad1f9eb.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3c89b85cf2566f5a97110e4f8ad1f9eb.txt new file mode 100644 index 0000000..06dbe67 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3c89b85cf2566f5a97110e4f8ad1f9eb.txt @@ -0,0 +1,4 @@ +0 0.13662790697674418 0.671875 0.20348837209302326 0.15625 +0 0.6191860465116279 0.6744791666666666 0.20348837209302326 0.15625 +0 0.4738372093023256 0.12239583333333333 0.20348837209302326 0.15625 +0 0.7848837209302325 0.23697916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d0bd114bd539dca3c37c802d2d2bb82.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d0bd114bd539dca3c37c802d2d2bb82.txt new file mode 100644 index 0000000..a09b0a1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d0bd114bd539dca3c37c802d2d2bb82.txt @@ -0,0 +1,3 @@ +0 0.5406976744186046 0.6432291666666666 0.20348837209302326 0.15625 +0 0.28488372093023256 0.7864583333333333 0.20348837209302326 0.15625 +0 0.4505813953488372 0.2109375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d21cf9a8ccbc2009bc9310467df503d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d21cf9a8ccbc2009bc9310467df503d.txt new file mode 100644 index 0000000..de0e130 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d21cf9a8ccbc2009bc9310467df503d.txt @@ -0,0 +1,3 @@ +0 0.622093023255814 0.765625 0.20348837209302326 0.15625 +0 0.8023255813953488 0.19010416666666666 0.20348837209302326 0.15625 +0 0.23837209302325582 0.37760416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d2c231825835a7f33c3a8b9999b85da.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d2c231825835a7f33c3a8b9999b85da.txt new file mode 100644 index 0000000..87c3e7b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d2c231825835a7f33c3a8b9999b85da.txt @@ -0,0 +1,2 @@ +0 0.747093023255814 0.3255208333333333 0.20348837209302326 0.15625 +0 0.502906976744186 0.6614583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d495703dfc8712ca625622618c39adb.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d495703dfc8712ca625622618c39adb.txt new file mode 100644 index 0000000..01f602d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d495703dfc8712ca625622618c39adb.txt @@ -0,0 +1,4 @@ +0 0.17151162790697674 0.19270833333333331 0.20348837209302326 0.15625 +0 0.8226744186046512 0.265625 0.20348837209302326 0.15625 +0 0.5058139534883721 0.12239583333333333 0.20348837209302326 0.15625 +0 0.6453488372093024 0.5546875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d9c7eb149e5ef0c470fc5eeb3293e64.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d9c7eb149e5ef0c470fc5eeb3293e64.txt new file mode 100644 index 0000000..0e2e527 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3d9c7eb149e5ef0c470fc5eeb3293e64.txt @@ -0,0 +1,4 @@ +0 0.7703488372093024 0.4296875 0.20348837209302326 0.15625 +0 0.811046511627907 0.109375 0.20348837209302326 0.15625 +0 0.1569767441860465 0.765625 0.20348837209302326 0.15625 +0 0.31976744186046513 0.46354166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3da2cb4374aeef3779f181b50c67deef.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3da2cb4374aeef3779f181b50c67deef.txt new file mode 100644 index 0000000..89d221e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3da2cb4374aeef3779f181b50c67deef.txt @@ -0,0 +1,4 @@ +0 0.7558139534883721 0.171875 0.20348837209302326 0.15625 +0 0.23255813953488372 0.5885416666666666 0.20348837209302326 0.15625 +0 0.8517441860465116 0.453125 0.20348837209302326 0.15625 +0 0.16569767441860464 0.15364583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3e5f116148bfbe30079ea83289b85d39.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3e5f116148bfbe30079ea83289b85d39.txt new file mode 100644 index 0000000..cc80e08 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3e5f116148bfbe30079ea83289b85d39.txt @@ -0,0 +1,4 @@ +0 0.7674418604651163 0.20052083333333331 0.20348837209302326 0.15625 +0 0.5 0.5546875 0.20348837209302326 0.15625 +0 0.438953488372093 0.7864583333333333 0.20348837209302326 0.15625 +0 0.7936046511627907 0.5859375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3e6c5b9a345590ac8ed792f4a8f1f420.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3e6c5b9a345590ac8ed792f4a8f1f420.txt new file mode 100644 index 0000000..f333ffe --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3e6c5b9a345590ac8ed792f4a8f1f420.txt @@ -0,0 +1,4 @@ +0 0.2063953488372093 0.125 0.20348837209302326 0.15625 +0 0.7994186046511628 0.2864583333333333 0.20348837209302326 0.15625 +0 0.6744186046511628 0.5416666666666666 0.20348837209302326 0.15625 +0 0.31976744186046513 0.39322916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3e9755e6718b502b3379a86938fef3f1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3e9755e6718b502b3379a86938fef3f1.txt new file mode 100644 index 0000000..6b6ec95 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3e9755e6718b502b3379a86938fef3f1.txt @@ -0,0 +1,4 @@ +0 0.36627906976744184 0.7005208333333333 0.20348837209302326 0.15625 +0 0.24127906976744184 0.14322916666666666 0.20348837209302326 0.15625 +0 0.49127906976744184 0.3984375 0.20348837209302326 0.15625 +0 0.7994186046511628 0.6692708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3f0dfde55daeae85903abe53ec3829b9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3f0dfde55daeae85903abe53ec3829b9.txt new file mode 100644 index 0000000..9add880 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3f0dfde55daeae85903abe53ec3829b9.txt @@ -0,0 +1,4 @@ +0 0.34011627906976744 0.5989583333333333 0.20348837209302326 0.15625 +0 0.6453488372093024 0.12239583333333333 0.20348837209302326 0.15625 +0 0.2063953488372093 0.2708333333333333 0.20348837209302326 0.15625 +0 0.627906976744186 0.7005208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3f6d0954e7509c8b907de00979423cc6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3f6d0954e7509c8b907de00979423cc6.txt new file mode 100644 index 0000000..e80e0c2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3f6d0954e7509c8b907de00979423cc6.txt @@ -0,0 +1,4 @@ +0 0.438953488372093 0.28385416666666663 0.20348837209302326 0.15625 +0 0.7994186046511628 0.24739583333333331 0.20348837209302326 0.15625 +0 0.34011627906976744 0.5703125 0.20348837209302326 0.15625 +0 0.7674418604651163 0.7708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3f97dcb9dc399235558efc7b7e2a5e47.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3f97dcb9dc399235558efc7b7e2a5e47.txt new file mode 100644 index 0000000..da8463b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3f97dcb9dc399235558efc7b7e2a5e47.txt @@ -0,0 +1,4 @@ +0 0.6831395348837209 0.6067708333333333 0.20348837209302326 0.15625 +0 0.5988372093023255 0.2708333333333333 0.20348837209302326 0.15625 +0 0.1947674418604651 0.3255208333333333 0.20348837209302326 0.15625 +0 0.39825581395348836 0.65625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3f9c37a1d0b4e008de2a527054730cab.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3f9c37a1d0b4e008de2a527054730cab.txt new file mode 100644 index 0000000..ef39098 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/3f9c37a1d0b4e008de2a527054730cab.txt @@ -0,0 +1,5 @@ +0 0.26744186046511625 0.17708333333333331 0.20348837209302326 0.15625 +0 0.6715116279069767 0.7239583333333333 0.20348837209302326 0.15625 +0 0.625 0.22916666666666666 0.20348837209302326 0.15625 +0 0.2761627906976744 0.6145833333333333 0.20348837209302326 0.15625 +0 0.8488372093023255 0.46354166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/404fe4af760d2e7a22db64188004d17f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/404fe4af760d2e7a22db64188004d17f.txt new file mode 100644 index 0000000..b817c84 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/404fe4af760d2e7a22db64188004d17f.txt @@ -0,0 +1,5 @@ +0 0.7034883720930233 0.6901041666666666 0.20348837209302326 0.15625 +0 0.12790697674418605 0.22395833333333331 0.20348837209302326 0.15625 +0 0.6715116279069767 0.453125 0.20348837209302326 0.15625 +0 0.6046511627906976 0.13020833333333331 0.20348837209302326 0.15625 +0 0.25290697674418605 0.5755208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/40cf6cc0f27841b8e1b1126c05e94031.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/40cf6cc0f27841b8e1b1126c05e94031.txt new file mode 100644 index 0000000..66f9830 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/40cf6cc0f27841b8e1b1126c05e94031.txt @@ -0,0 +1,4 @@ +0 0.16569767441860464 0.5703125 0.20348837209302326 0.15625 +0 0.8517441860465116 0.17447916666666666 0.20348837209302326 0.15625 +0 0.8662790697674418 0.5338541666666666 0.20348837209302326 0.15625 +0 0.502906976744186 0.5729166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/41099fa89d0976dc14094190f9d81eae.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/41099fa89d0976dc14094190f9d81eae.txt new file mode 100644 index 0000000..c3e8b4b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/41099fa89d0976dc14094190f9d81eae.txt @@ -0,0 +1,4 @@ +0 0.17151162790697674 0.16145833333333331 0.20348837209302326 0.15625 +0 0.36046511627906974 0.3984375 0.20348837209302326 0.15625 +0 0.19767441860465115 0.7447916666666666 0.20348837209302326 0.15625 +0 0.7703488372093024 0.7604166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4127977ad3f5e5cbfabd7e1dd44c8b33.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4127977ad3f5e5cbfabd7e1dd44c8b33.txt new file mode 100644 index 0000000..e467a59 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4127977ad3f5e5cbfabd7e1dd44c8b33.txt @@ -0,0 +1,3 @@ +0 0.49127906976744184 0.296875 0.20348837209302326 0.15625 +0 0.27906976744186046 0.765625 0.20348837209302326 0.15625 +0 0.8052325581395349 0.7552083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4131f80c8c09c8d7010b0224adc9985b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4131f80c8c09c8d7010b0224adc9985b.txt new file mode 100644 index 0000000..1f2dbff --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4131f80c8c09c8d7010b0224adc9985b.txt @@ -0,0 +1,5 @@ +0 0.6511627906976745 0.33072916666666663 0.20348837209302326 0.15625 +0 0.22965116279069767 0.140625 0.20348837209302326 0.15625 +0 0.8633720930232558 0.5546875 0.20348837209302326 0.15625 +0 0.23255813953488372 0.5520833333333333 0.20348837209302326 0.15625 +0 0.8052325581395349 0.1015625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/413f7048cfedefd240d754103f4c5795.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/413f7048cfedefd240d754103f4c5795.txt new file mode 100644 index 0000000..1f1a453 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/413f7048cfedefd240d754103f4c5795.txt @@ -0,0 +1,4 @@ +0 0.26744186046511625 0.23958333333333331 0.20348837209302326 0.15625 +0 0.7267441860465116 0.24479166666666666 0.20348837209302326 0.15625 +0 0.7093023255813954 0.7890625 0.20348837209302326 0.15625 +0 0.24709302325581395 0.5182291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/424894fb7373acd4163a2d8974573b1c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/424894fb7373acd4163a2d8974573b1c.txt new file mode 100644 index 0000000..e241f3b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/424894fb7373acd4163a2d8974573b1c.txt @@ -0,0 +1,4 @@ +0 0.16569767441860464 0.2864583333333333 0.20348837209302326 0.15625 +0 0.21220930232558138 0.5911458333333333 0.20348837209302326 0.15625 +0 0.6162790697674418 0.3489583333333333 0.20348837209302326 0.15625 +0 0.6075581395348837 0.6328125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4255a578c0c4adea9e877ea07a42651e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4255a578c0c4adea9e877ea07a42651e.txt new file mode 100644 index 0000000..ddd93a8 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4255a578c0c4adea9e877ea07a42651e.txt @@ -0,0 +1,3 @@ +0 0.7005813953488372 0.28385416666666663 0.20348837209302326 0.15625 +0 0.6744186046511628 0.7265625 0.20348837209302326 0.15625 +0 0.2761627906976744 0.6875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/42c85c6092ae84555be25554924f8ac0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/42c85c6092ae84555be25554924f8ac0.txt new file mode 100644 index 0000000..6f160d9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/42c85c6092ae84555be25554924f8ac0.txt @@ -0,0 +1,4 @@ +0 0.2616279069767442 0.48697916666666663 0.20348837209302326 0.15625 +0 0.6482558139534884 0.5026041666666666 0.20348837209302326 0.15625 +0 0.6656976744186046 0.734375 0.20348837209302326 0.15625 +0 0.14244186046511628 0.23697916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/42e35b4e0a15c96f7603a71be92a0cf3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/42e35b4e0a15c96f7603a71be92a0cf3.txt new file mode 100644 index 0000000..2ad78d8 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/42e35b4e0a15c96f7603a71be92a0cf3.txt @@ -0,0 +1,5 @@ +0 0.3633720930232558 0.7708333333333333 0.20348837209302326 0.15625 +0 0.8517441860465116 0.45572916666666663 0.20348837209302326 0.15625 +0 0.18313953488372092 0.3515625 0.20348837209302326 0.15625 +0 0.5203488372093024 0.26041666666666663 0.20348837209302326 0.15625 +0 0.18604651162790697 0.11197916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/43c1d9494197ea8b750b25dc79e5df92.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/43c1d9494197ea8b750b25dc79e5df92.txt new file mode 100644 index 0000000..366679f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/43c1d9494197ea8b750b25dc79e5df92.txt @@ -0,0 +1,3 @@ +0 0.14825581395348836 0.7682291666666666 0.20348837209302326 0.15625 +0 0.4941860465116279 0.5364583333333333 0.20348837209302326 0.15625 +0 0.1511627906976744 0.3203125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/44250c2677e5f92e144996e809fbcd41.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/44250c2677e5f92e144996e809fbcd41.txt new file mode 100644 index 0000000..990fac6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/44250c2677e5f92e144996e809fbcd41.txt @@ -0,0 +1,4 @@ +0 0.5843023255813954 0.5182291666666666 0.20348837209302326 0.15625 +0 0.21511627906976744 0.17708333333333331 0.20348837209302326 0.15625 +0 0.18895348837209303 0.6302083333333333 0.20348837209302326 0.15625 +0 0.7412790697674418 0.7473958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/449bcec9a6c92331dc76e27325c5e57a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/449bcec9a6c92331dc76e27325c5e57a.txt new file mode 100644 index 0000000..0ed15ea --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/449bcec9a6c92331dc76e27325c5e57a.txt @@ -0,0 +1,4 @@ +0 0.7441860465116279 0.40885416666666663 0.20348837209302326 0.15625 +0 0.622093023255814 0.1484375 0.20348837209302326 0.15625 +0 0.20348837209302326 0.3489583333333333 0.20348837209302326 0.15625 +0 0.5523255813953488 0.7916666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/44ac74930cd0bdb395579fe7dbb11684.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/44ac74930cd0bdb395579fe7dbb11684.txt new file mode 100644 index 0000000..e2660d0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/44ac74930cd0bdb395579fe7dbb11684.txt @@ -0,0 +1,5 @@ +0 0.2238372093023256 0.5833333333333333 0.20348837209302326 0.15625 +0 0.8197674418604651 0.296875 0.20348837209302326 0.15625 +0 0.47093023255813954 0.1640625 0.20348837209302326 0.15625 +0 0.14244186046511628 0.27604166666666663 0.20348837209302326 0.15625 +0 0.5174418604651163 0.6588541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/453e3c641ffd8d9e18e8c97e35726e54.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/453e3c641ffd8d9e18e8c97e35726e54.txt new file mode 100644 index 0000000..99e3d76 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/453e3c641ffd8d9e18e8c97e35726e54.txt @@ -0,0 +1,3 @@ +0 0.7209302325581395 0.484375 0.20348837209302326 0.15625 +0 0.2877906976744186 0.3802083333333333 0.20348837209302326 0.15625 +0 0.29069767441860467 0.6119791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/45522e099c48a5b043cb2dfa33439f63.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/45522e099c48a5b043cb2dfa33439f63.txt new file mode 100644 index 0000000..d1997b9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/45522e099c48a5b043cb2dfa33439f63.txt @@ -0,0 +1,3 @@ +0 0.7063953488372093 0.21354166666666666 0.20348837209302326 0.15625 +0 0.25 0.6614583333333333 0.20348837209302326 0.15625 +0 0.8459302325581395 0.6614583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/45789d6753f3f127ea5dbca642664b2c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/45789d6753f3f127ea5dbca642664b2c.txt new file mode 100644 index 0000000..3745cd7 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/45789d6753f3f127ea5dbca642664b2c.txt @@ -0,0 +1,3 @@ +0 0.125 0.3020833333333333 0.20348837209302326 0.15625 +0 0.5697674418604651 0.47135416666666663 0.20348837209302326 0.15625 +0 0.5988372093023255 0.15625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4580f3f6bcb6ed28b79982c92ea5d7bf.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4580f3f6bcb6ed28b79982c92ea5d7bf.txt new file mode 100644 index 0000000..cd53d7d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4580f3f6bcb6ed28b79982c92ea5d7bf.txt @@ -0,0 +1,3 @@ +0 0.8168604651162791 0.33854166666666663 0.20348837209302326 0.15625 +0 0.3226744186046512 0.21354166666666666 0.20348837209302326 0.15625 +0 0.7877906976744186 0.7552083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/45e8630d55a70d218c92f37ad351c3af.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/45e8630d55a70d218c92f37ad351c3af.txt new file mode 100644 index 0000000..54fa92c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/45e8630d55a70d218c92f37ad351c3af.txt @@ -0,0 +1,5 @@ +0 0.2965116279069767 0.6770833333333333 0.20348837209302326 0.15625 +0 0.6627906976744186 0.7682291666666666 0.20348837209302326 0.15625 +0 0.5290697674418604 0.2786458333333333 0.20348837209302326 0.15625 +0 0.1308139534883721 0.27604166666666663 0.20348837209302326 0.15625 +0 0.8633720930232558 0.25 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/45e8ddd22bb30566d424faa33d6e38f2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/45e8ddd22bb30566d424faa33d6e38f2.txt new file mode 100644 index 0000000..4183fd3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/45e8ddd22bb30566d424faa33d6e38f2.txt @@ -0,0 +1,4 @@ +0 0.75 0.7265625 0.20348837209302326 0.15625 +0 0.7674418604651163 0.24739583333333331 0.20348837209302326 0.15625 +0 0.23837209302325582 0.3802083333333333 0.20348837209302326 0.15625 +0 0.3430232558139535 0.6302083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/47011c9a66be34f7f7c1ce5dd056fa3f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/47011c9a66be34f7f7c1ce5dd056fa3f.txt new file mode 100644 index 0000000..9176f11 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/47011c9a66be34f7f7c1ce5dd056fa3f.txt @@ -0,0 +1,4 @@ +0 0.20348837209302326 0.6015625 0.20348837209302326 0.15625 +0 0.19186046511627908 0.1328125 0.20348837209302326 0.15625 +0 0.561046511627907 0.2734375 0.20348837209302326 0.15625 +0 0.6133720930232558 0.7473958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4785b7a059fa0e0e21eef81afa2136d9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4785b7a059fa0e0e21eef81afa2136d9.txt new file mode 100644 index 0000000..5602bd9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4785b7a059fa0e0e21eef81afa2136d9.txt @@ -0,0 +1,3 @@ +0 0.6133720930232558 0.27604166666666663 0.20348837209302326 0.15625 +0 0.36627906976744184 0.5520833333333333 0.20348837209302326 0.15625 +0 0.8226744186046512 0.6640625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/47f1d5fffa38b7f18e6c9fe93ab5582a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/47f1d5fffa38b7f18e6c9fe93ab5582a.txt new file mode 100644 index 0000000..01576e8 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/47f1d5fffa38b7f18e6c9fe93ab5582a.txt @@ -0,0 +1,4 @@ +0 0.18313953488372092 0.5182291666666666 0.20348837209302326 0.15625 +0 0.7761627906976744 0.671875 0.20348837209302326 0.15625 +0 0.4680232558139535 0.19791666666666666 0.20348837209302326 0.15625 +0 0.13662790697674418 0.15364583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4814204b196308a1b07525a125ca774d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4814204b196308a1b07525a125ca774d.txt new file mode 100644 index 0000000..6442ed8 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4814204b196308a1b07525a125ca774d.txt @@ -0,0 +1,3 @@ +0 0.7848837209302325 0.19791666666666666 0.20348837209302326 0.15625 +0 0.5116279069767442 0.6328125 0.20348837209302326 0.15625 +0 0.4825581395348837 0.24739583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/487d269d8cb04ac063193a340dd128f8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/487d269d8cb04ac063193a340dd128f8.txt new file mode 100644 index 0000000..ce6a9d0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/487d269d8cb04ac063193a340dd128f8.txt @@ -0,0 +1,4 @@ +0 0.5116279069767442 0.21354166666666666 0.20348837209302326 0.15625 +0 0.7819767441860465 0.5182291666666666 0.20348837209302326 0.15625 +0 0.27906976744186046 0.5963541666666666 0.20348837209302326 0.15625 +0 0.6366279069767442 0.7786458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/487f2e24aa3452205edf6459aaabbbb2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/487f2e24aa3452205edf6459aaabbbb2.txt new file mode 100644 index 0000000..831c9d7 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/487f2e24aa3452205edf6459aaabbbb2.txt @@ -0,0 +1,5 @@ +0 0.18023255813953487 0.36197916666666663 0.20348837209302326 0.15625 +0 0.8633720930232558 0.29166666666666663 0.20348837209302326 0.15625 +0 0.7848837209302325 0.734375 0.20348837209302326 0.15625 +0 0.15988372093023256 0.7630208333333333 0.20348837209302326 0.15625 +0 0.5523255813953488 0.46354166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/48837cb6ce0fb59876adb982b5052edd.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/48837cb6ce0fb59876adb982b5052edd.txt new file mode 100644 index 0000000..fcc01c3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/48837cb6ce0fb59876adb982b5052edd.txt @@ -0,0 +1,4 @@ +0 0.4563953488372093 0.6770833333333333 0.20348837209302326 0.15625 +0 0.3691860465116279 0.15885416666666666 0.20348837209302326 0.15625 +0 0.22965116279069767 0.40625 0.20348837209302326 0.15625 +0 0.6104651162790697 0.4583333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/48c254260b982877992b4eeb61a81abf.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/48c254260b982877992b4eeb61a81abf.txt new file mode 100644 index 0000000..7298572 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/48c254260b982877992b4eeb61a81abf.txt @@ -0,0 +1,4 @@ +0 0.3895348837209302 0.171875 0.20348837209302326 0.15625 +0 0.6947674418604651 0.7473958333333333 0.20348837209302326 0.15625 +0 0.3546511627906977 0.75 0.20348837209302326 0.15625 +0 0.7267441860465116 0.29166666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/48e9362e6e4be312d32b38fcbd540fc9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/48e9362e6e4be312d32b38fcbd540fc9.txt new file mode 100644 index 0000000..7239128 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/48e9362e6e4be312d32b38fcbd540fc9.txt @@ -0,0 +1,4 @@ +0 0.4331395348837209 0.21354166666666666 0.20348837209302326 0.15625 +0 0.8023255813953488 0.12760416666666666 0.20348837209302326 0.15625 +0 0.8226744186046512 0.3671875 0.20348837209302326 0.15625 +0 0.3953488372093023 0.6588541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/49c4a01e2945484086efdae0008935d8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/49c4a01e2945484086efdae0008935d8.txt new file mode 100644 index 0000000..2154e32 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/49c4a01e2945484086efdae0008935d8.txt @@ -0,0 +1,5 @@ +0 0.27906976744186046 0.3333333333333333 0.20348837209302326 0.15625 +0 0.563953488372093 0.6276041666666666 0.20348837209302326 0.15625 +0 0.6453488372093024 0.3333333333333333 0.20348837209302326 0.15625 +0 0.24709302325581395 0.671875 0.20348837209302326 0.15625 +0 0.8488372093023255 0.7760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/49c83cc7b12efaa4caa9bffbaef78e3b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/49c83cc7b12efaa4caa9bffbaef78e3b.txt new file mode 100644 index 0000000..2b63d66 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/49c83cc7b12efaa4caa9bffbaef78e3b.txt @@ -0,0 +1,4 @@ +0 0.4273255813953488 0.19791666666666666 0.20348837209302326 0.15625 +0 0.15406976744186046 0.23177083333333331 0.20348837209302326 0.15625 +0 0.5058139534883721 0.5 0.20348837209302326 0.15625 +0 0.6773255813953488 0.7369791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4be2851e1ea3829c81f55c701a2f0187.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4be2851e1ea3829c81f55c701a2f0187.txt new file mode 100644 index 0000000..9e160f9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4be2851e1ea3829c81f55c701a2f0187.txt @@ -0,0 +1,5 @@ +0 0.7790697674418604 0.6536458333333333 0.20348837209302326 0.15625 +0 0.18895348837209303 0.7578125 0.20348837209302326 0.15625 +0 0.5901162790697674 0.125 0.20348837209302326 0.15625 +0 0.8488372093023255 0.3828125 0.20348837209302326 0.15625 +0 0.34011627906976744 0.375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4c010902a0a21d508521f55704315883.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4c010902a0a21d508521f55704315883.txt new file mode 100644 index 0000000..d11593b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4c010902a0a21d508521f55704315883.txt @@ -0,0 +1,5 @@ +0 0.3372093023255814 0.6796875 0.20348837209302326 0.15625 +0 0.45930232558139533 0.20572916666666666 0.20348837209302326 0.15625 +0 0.7965116279069767 0.5 0.20348837209302326 0.15625 +0 0.40406976744186046 0.44010416666666663 0.20348837209302326 0.15625 +0 0.8255813953488372 0.19270833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4c83b69d15bd0519b0b71185f0bcc56d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4c83b69d15bd0519b0b71185f0bcc56d.txt new file mode 100644 index 0000000..072834e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4c83b69d15bd0519b0b71185f0bcc56d.txt @@ -0,0 +1,4 @@ +0 0.747093023255814 0.5729166666666666 0.20348837209302326 0.15625 +0 0.22093023255813954 0.234375 0.20348837209302326 0.15625 +0 0.5261627906976745 0.3177083333333333 0.20348837209302326 0.15625 +0 0.4796511627906977 0.5390625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4c8e3b21d4e2473369fab4ded85c14bd.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4c8e3b21d4e2473369fab4ded85c14bd.txt new file mode 100644 index 0000000..6924bca --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4c8e3b21d4e2473369fab4ded85c14bd.txt @@ -0,0 +1,3 @@ +0 0.6191860465116279 0.5 0.20348837209302326 0.15625 +0 0.26744186046511625 0.7057291666666666 0.20348837209302326 0.15625 +0 0.3575581395348837 0.16145833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4c93c736f37e12c9d376fd42dfdcc60b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4c93c736f37e12c9d376fd42dfdcc60b.txt new file mode 100644 index 0000000..114b9d8 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4c93c736f37e12c9d376fd42dfdcc60b.txt @@ -0,0 +1,4 @@ +0 0.3226744186046512 0.6380208333333333 0.20348837209302326 0.15625 +0 0.8488372093023255 0.29947916666666663 0.20348837209302326 0.15625 +0 0.8517441860465116 0.6302083333333333 0.20348837209302326 0.15625 +0 0.4505813953488372 0.32291666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4ca2f7e6a71b78e101d3ddae7d362e85.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4ca2f7e6a71b78e101d3ddae7d362e85.txt new file mode 100644 index 0000000..ea89c0f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4ca2f7e6a71b78e101d3ddae7d362e85.txt @@ -0,0 +1,5 @@ +0 0.16279069767441862 0.47135416666666663 0.20348837209302326 0.15625 +0 0.25 0.7395833333333333 0.20348837209302326 0.15625 +0 0.46511627906976744 0.4296875 0.20348837209302326 0.15625 +0 0.21511627906976744 0.11197916666666666 0.20348837209302326 0.15625 +0 0.7790697674418604 0.2890625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4d070ac638da477048122564e402a359.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4d070ac638da477048122564e402a359.txt new file mode 100644 index 0000000..56f692f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4d070ac638da477048122564e402a359.txt @@ -0,0 +1,3 @@ +0 0.15406976744186046 0.4296875 0.20348837209302326 0.15625 +0 0.813953488372093 0.16666666666666666 0.20348837209302326 0.15625 +0 0.3575581395348837 0.16927083333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4d6ac172e896a7dcb24729b528cd3765.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4d6ac172e896a7dcb24729b528cd3765.txt new file mode 100644 index 0000000..3ae7696 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4d6ac172e896a7dcb24729b528cd3765.txt @@ -0,0 +1,3 @@ +0 0.4273255813953488 0.7135416666666666 0.20348837209302326 0.15625 +0 0.2819767441860465 0.125 0.20348837209302326 0.15625 +0 0.6802325581395349 0.4609375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4dde8b597fa0a9989b91887e207e0411.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4dde8b597fa0a9989b91887e207e0411.txt new file mode 100644 index 0000000..5c3a905 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4dde8b597fa0a9989b91887e207e0411.txt @@ -0,0 +1,5 @@ +0 0.49127906976744184 0.6484375 0.20348837209302326 0.15625 +0 0.13662790697674418 0.3645833333333333 0.20348837209302326 0.15625 +0 0.7994186046511628 0.25 0.20348837209302326 0.15625 +0 0.2965116279069767 0.125 0.20348837209302326 0.15625 +0 0.2005813953488372 0.7760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4de515d5e780a7859edabd14df82af32.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4de515d5e780a7859edabd14df82af32.txt new file mode 100644 index 0000000..09b0226 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4de515d5e780a7859edabd14df82af32.txt @@ -0,0 +1,4 @@ +0 0.13662790697674418 0.390625 0.20348837209302326 0.15625 +0 0.2616279069767442 0.13541666666666666 0.20348837209302326 0.15625 +0 0.8226744186046512 0.40885416666666663 0.20348837209302326 0.15625 +0 0.7587209302325582 0.1953125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4e017520fd4be6a4c1dfb9f70f8c7511.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4e017520fd4be6a4c1dfb9f70f8c7511.txt new file mode 100644 index 0000000..b633972 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4e017520fd4be6a4c1dfb9f70f8c7511.txt @@ -0,0 +1,4 @@ +0 0.622093023255814 0.734375 0.20348837209302326 0.15625 +0 0.627906976744186 0.2942708333333333 0.20348837209302326 0.15625 +0 0.2703488372093023 0.2265625 0.20348837209302326 0.15625 +0 0.14825581395348836 0.7161458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4e138cb90a8fec9e04c056c9363412d7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4e138cb90a8fec9e04c056c9363412d7.txt new file mode 100644 index 0000000..b2665df --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4e138cb90a8fec9e04c056c9363412d7.txt @@ -0,0 +1,3 @@ +0 0.6598837209302325 0.484375 0.20348837209302326 0.15625 +0 0.3313953488372093 0.796875 0.20348837209302326 0.15625 +0 0.24127906976744184 0.4348958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4e15d77b96f5f26585cb164e11ced558.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4e15d77b96f5f26585cb164e11ced558.txt new file mode 100644 index 0000000..4fab5f1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4e15d77b96f5f26585cb164e11ced558.txt @@ -0,0 +1,5 @@ +0 0.5436046511627907 0.7916666666666666 0.20348837209302326 0.15625 +0 0.29941860465116277 0.5546875 0.20348837209302326 0.15625 +0 0.3430232558139535 0.3125 0.20348837209302326 0.15625 +0 0.8081395348837209 0.37760416666666663 0.20348837209302326 0.15625 +0 0.21220930232558138 0.7916666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4e1f4012fb8e1cea6e187486c880aa63.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4e1f4012fb8e1cea6e187486c880aa63.txt new file mode 100644 index 0000000..5903580 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4e1f4012fb8e1cea6e187486c880aa63.txt @@ -0,0 +1,3 @@ +0 0.5116279069767442 0.703125 0.20348837209302326 0.15625 +0 0.6424418604651163 0.171875 0.20348837209302326 0.15625 +0 0.3691860465116279 0.29947916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4f00d944819bd9bd092ed77d596173b9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4f00d944819bd9bd092ed77d596173b9.txt new file mode 100644 index 0000000..83b7eda --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4f00d944819bd9bd092ed77d596173b9.txt @@ -0,0 +1,4 @@ +0 0.7151162790697674 0.53125 0.20348837209302326 0.15625 +0 0.1686046511627907 0.3802083333333333 0.20348837209302326 0.15625 +0 0.502906976744186 0.203125 0.20348837209302326 0.15625 +0 0.1744186046511628 0.7604166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4f667f12274be131d029491dad8a966e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4f667f12274be131d029491dad8a966e.txt new file mode 100644 index 0000000..593f00b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4f667f12274be131d029491dad8a966e.txt @@ -0,0 +1,3 @@ +0 0.7645348837209303 0.6171875 0.20348837209302326 0.15625 +0 0.3691860465116279 0.7786458333333333 0.20348837209302326 0.15625 +0 0.15406976744186046 0.4296875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4f958ed2f5d448829002ac08bf9c17b3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4f958ed2f5d448829002ac08bf9c17b3.txt new file mode 100644 index 0000000..a801e25 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4f958ed2f5d448829002ac08bf9c17b3.txt @@ -0,0 +1,5 @@ +0 0.45348837209302323 0.65625 0.20348837209302326 0.15625 +0 0.8197674418604651 0.6223958333333333 0.20348837209302326 0.15625 +0 0.625 0.36197916666666663 0.20348837209302326 0.15625 +0 0.18313953488372092 0.43229166666666663 0.20348837209302326 0.15625 +0 0.2238372093023256 0.16927083333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4ffc782b89c5dc232782abef5165c719.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4ffc782b89c5dc232782abef5165c719.txt new file mode 100644 index 0000000..db50da3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/4ffc782b89c5dc232782abef5165c719.txt @@ -0,0 +1,4 @@ +0 0.5552325581395349 0.3671875 0.20348837209302326 0.15625 +0 0.19767441860465115 0.484375 0.20348837209302326 0.15625 +0 0.16279069767441862 0.7161458333333333 0.20348837209302326 0.15625 +0 0.22093023255813954 0.20572916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/504589663fb6dd5062daa143fcba1ff6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/504589663fb6dd5062daa143fcba1ff6.txt new file mode 100644 index 0000000..14c67fc --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/504589663fb6dd5062daa143fcba1ff6.txt @@ -0,0 +1,5 @@ +0 0.8575581395348837 0.17447916666666666 0.20348837209302326 0.15625 +0 0.18023255813953487 0.16927083333333331 0.20348837209302326 0.15625 +0 0.5523255813953488 0.5703125 0.20348837209302326 0.15625 +0 0.8284883720930233 0.4765625 0.20348837209302326 0.15625 +0 0.2645348837209302 0.6510416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/50dcad12bd25596f0be4c14fbfa19cd9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/50dcad12bd25596f0be4c14fbfa19cd9.txt new file mode 100644 index 0000000..5dcc9fa --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/50dcad12bd25596f0be4c14fbfa19cd9.txt @@ -0,0 +1,4 @@ +0 0.6017441860465116 0.11979166666666666 0.20348837209302326 0.15625 +0 0.18313953488372092 0.14583333333333331 0.20348837209302326 0.15625 +0 0.22674418604651161 0.578125 0.20348837209302326 0.15625 +0 0.5581395348837209 0.7864583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/510e7af64cd053bb699ee49375095145.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/510e7af64cd053bb699ee49375095145.txt new file mode 100644 index 0000000..0411b9b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/510e7af64cd053bb699ee49375095145.txt @@ -0,0 +1,5 @@ +0 0.4825581395348837 0.1015625 0.20348837209302326 0.15625 +0 0.14534883720930233 0.36197916666666663 0.20348837209302326 0.15625 +0 0.4563953488372093 0.5859375 0.20348837209302326 0.15625 +0 0.7674418604651163 0.2786458333333333 0.20348837209302326 0.15625 +0 0.75 0.6041666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/514062c3edb164ab3948e4b1a0034dd1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/514062c3edb164ab3948e4b1a0034dd1.txt new file mode 100644 index 0000000..24e747c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/514062c3edb164ab3948e4b1a0034dd1.txt @@ -0,0 +1,5 @@ +0 0.4505813953488372 0.5364583333333333 0.20348837209302326 0.15625 +0 0.6686046511627907 0.140625 0.20348837209302326 0.15625 +0 0.1308139534883721 0.3645833333333333 0.20348837209302326 0.15625 +0 0.7180232558139534 0.484375 0.20348837209302326 0.15625 +0 0.32558139534883723 0.1484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/514b4e534abd39a0249f91a6e6582b1e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/514b4e534abd39a0249f91a6e6582b1e.txt new file mode 100644 index 0000000..5b248b6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/514b4e534abd39a0249f91a6e6582b1e.txt @@ -0,0 +1,2 @@ +0 0.5436046511627907 0.7057291666666666 0.20348837209302326 0.15625 +0 0.5348837209302325 0.24479166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/51f7ecde3dbd025454e5e4790f1063a9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/51f7ecde3dbd025454e5e4790f1063a9.txt new file mode 100644 index 0000000..a912cd6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/51f7ecde3dbd025454e5e4790f1063a9.txt @@ -0,0 +1,4 @@ +0 0.5959302325581395 0.7630208333333333 0.20348837209302326 0.15625 +0 0.6511627906976745 0.3958333333333333 0.20348837209302326 0.15625 +0 0.3226744186046512 0.5338541666666666 0.20348837209302326 0.15625 +0 0.37209302325581395 0.16145833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/52ce8d5066eecf62f2effa92b5d6e5c8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/52ce8d5066eecf62f2effa92b5d6e5c8.txt new file mode 100644 index 0000000..60a56ad --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/52ce8d5066eecf62f2effa92b5d6e5c8.txt @@ -0,0 +1,4 @@ +0 0.8546511627906976 0.125 0.20348837209302326 0.15625 +0 0.20348837209302326 0.2942708333333333 0.20348837209302326 0.15625 +0 0.5581395348837209 0.3333333333333333 0.20348837209302326 0.15625 +0 0.3633720930232558 0.7708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/52d2e885bcd02b78f5e1f354571a3165.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/52d2e885bcd02b78f5e1f354571a3165.txt new file mode 100644 index 0000000..c8f31e0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/52d2e885bcd02b78f5e1f354571a3165.txt @@ -0,0 +1,5 @@ +0 0.7180232558139534 0.7057291666666666 0.20348837209302326 0.15625 +0 0.18023255813953487 0.5885416666666666 0.20348837209302326 0.15625 +0 0.29069767441860467 0.2630208333333333 0.20348837209302326 0.15625 +0 0.627906976744186 0.14322916666666666 0.20348837209302326 0.15625 +0 0.5813953488372093 0.4140625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/52f499a872019fb8e145504313059613.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/52f499a872019fb8e145504313059613.txt new file mode 100644 index 0000000..45cdd38 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/52f499a872019fb8e145504313059613.txt @@ -0,0 +1,4 @@ +0 0.3866279069767442 0.12760416666666666 0.20348837209302326 0.15625 +0 0.14825581395348836 0.6119791666666666 0.20348837209302326 0.15625 +0 0.7034883720930233 0.16927083333333331 0.20348837209302326 0.15625 +0 0.6947674418604651 0.4427083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53392c800ef29685aacc26d7f10c94c1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53392c800ef29685aacc26d7f10c94c1.txt new file mode 100644 index 0000000..0aa2a4c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53392c800ef29685aacc26d7f10c94c1.txt @@ -0,0 +1,4 @@ +0 0.4476744186046512 0.5572916666666666 0.20348837209302326 0.15625 +0 0.6627906976744186 0.2734375 0.20348837209302326 0.15625 +0 0.13953488372093023 0.19010416666666666 0.20348837209302326 0.15625 +0 0.4331395348837209 0.7526041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53793eba05cf925b90660330b35f5815.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53793eba05cf925b90660330b35f5815.txt new file mode 100644 index 0000000..21c3f44 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53793eba05cf925b90660330b35f5815.txt @@ -0,0 +1,3 @@ +0 0.47093023255813954 0.7526041666666666 0.20348837209302326 0.15625 +0 0.375 0.4895833333333333 0.20348837209302326 0.15625 +0 0.8284883720930233 0.6796875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53b9f88af3390499559fcb880606f947.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53b9f88af3390499559fcb880606f947.txt new file mode 100644 index 0000000..27efb77 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53b9f88af3390499559fcb880606f947.txt @@ -0,0 +1,4 @@ +0 0.6947674418604651 0.6197916666666666 0.20348837209302326 0.15625 +0 0.7877906976744186 0.2942708333333333 0.20348837209302326 0.15625 +0 0.29941860465116277 0.2786458333333333 0.20348837209302326 0.15625 +0 0.125 0.6432291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53c27964917ae271a0b1fda1ae64609f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53c27964917ae271a0b1fda1ae64609f.txt new file mode 100644 index 0000000..e58b0ad --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53c27964917ae271a0b1fda1ae64609f.txt @@ -0,0 +1,5 @@ +0 0.3430232558139535 0.5026041666666666 0.20348837209302326 0.15625 +0 0.15988372093023256 0.265625 0.20348837209302326 0.15625 +0 0.7587209302325582 0.4036458333333333 0.20348837209302326 0.15625 +0 0.3691860465116279 0.7239583333333333 0.20348837209302326 0.15625 +0 0.811046511627907 0.6276041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53fe2e14274d4ac3fc8493d0682f5e71.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53fe2e14274d4ac3fc8493d0682f5e71.txt new file mode 100644 index 0000000..a498dab --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/53fe2e14274d4ac3fc8493d0682f5e71.txt @@ -0,0 +1,4 @@ +0 0.6104651162790697 0.2734375 0.20348837209302326 0.15625 +0 0.1947674418604651 0.7447916666666666 0.20348837209302326 0.15625 +0 0.5523255813953488 0.5182291666666666 0.20348837209302326 0.15625 +0 0.2645348837209302 0.15885416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/543f709458e1fc55d05426ade00a46ef.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/543f709458e1fc55d05426ade00a46ef.txt new file mode 100644 index 0000000..a32c4e3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/543f709458e1fc55d05426ade00a46ef.txt @@ -0,0 +1,5 @@ +0 0.3808139534883721 0.5911458333333333 0.20348837209302326 0.15625 +0 0.7296511627906976 0.17447916666666666 0.20348837209302326 0.15625 +0 0.752906976744186 0.4765625 0.20348837209302326 0.15625 +0 0.6598837209302325 0.7057291666666666 0.20348837209302326 0.15625 +0 0.34593023255813954 0.3046875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/548a1a221108ab5a7ff05518caab7781.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/548a1a221108ab5a7ff05518caab7781.txt new file mode 100644 index 0000000..59fbbdc --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/548a1a221108ab5a7ff05518caab7781.txt @@ -0,0 +1,3 @@ +0 0.5348837209302325 0.7942708333333333 0.20348837209302326 0.15625 +0 0.7994186046511628 0.22395833333333331 0.20348837209302326 0.15625 +0 0.2877906976744186 0.48697916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/554f45f4c1990b8e7b165a751a29fc28.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/554f45f4c1990b8e7b165a751a29fc28.txt new file mode 100644 index 0000000..164474f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/554f45f4c1990b8e7b165a751a29fc28.txt @@ -0,0 +1,4 @@ +0 0.688953488372093 0.4270833333333333 0.20348837209302326 0.15625 +0 0.375 0.7421875 0.20348837209302326 0.15625 +0 0.22674418604651161 0.36979166666666663 0.20348837209302326 0.15625 +0 0.6976744186046512 0.15625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5572755e5c6b811bf439f2fa3a3ec237.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5572755e5c6b811bf439f2fa3a3ec237.txt new file mode 100644 index 0000000..b97b716 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5572755e5c6b811bf439f2fa3a3ec237.txt @@ -0,0 +1,3 @@ +0 0.7877906976744186 0.27604166666666663 0.20348837209302326 0.15625 +0 0.18604651162790697 0.5963541666666666 0.20348837209302326 0.15625 +0 0.23255813953488372 0.109375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/55daede03319fc87bbb77803b3b2a285.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/55daede03319fc87bbb77803b3b2a285.txt new file mode 100644 index 0000000..4d04bb3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/55daede03319fc87bbb77803b3b2a285.txt @@ -0,0 +1,4 @@ +0 0.2238372093023256 0.3802083333333333 0.20348837209302326 0.15625 +0 0.7703488372093024 0.40885416666666663 0.20348837209302326 0.15625 +0 0.14825581395348836 0.59375 0.20348837209302326 0.15625 +0 0.5348837209302325 0.7005208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/564066b109017931039158168f5bba4b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/564066b109017931039158168f5bba4b.txt new file mode 100644 index 0000000..fb3f12f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/564066b109017931039158168f5bba4b.txt @@ -0,0 +1,4 @@ +0 0.6075581395348837 0.6458333333333333 0.20348837209302326 0.15625 +0 0.5697674418604651 0.22135416666666666 0.20348837209302326 0.15625 +0 0.2936046511627907 0.7265625 0.20348837209302326 0.15625 +0 0.18313953488372092 0.24739583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5679c2443905cec1f43c9b2b69fd9efd.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5679c2443905cec1f43c9b2b69fd9efd.txt new file mode 100644 index 0000000..2caa249 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5679c2443905cec1f43c9b2b69fd9efd.txt @@ -0,0 +1,4 @@ +0 0.22674418604651161 0.19791666666666666 0.20348837209302326 0.15625 +0 0.8081395348837209 0.4661458333333333 0.20348837209302326 0.15625 +0 0.18023255813953487 0.6901041666666666 0.20348837209302326 0.15625 +0 0.4825581395348837 0.4505208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5679d5cfa0558639c73d26e11a785f89.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5679d5cfa0558639c73d26e11a785f89.txt new file mode 100644 index 0000000..5d65098 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5679d5cfa0558639c73d26e11a785f89.txt @@ -0,0 +1,4 @@ +0 0.7848837209302325 0.703125 0.20348837209302326 0.15625 +0 0.25 0.4453125 0.20348837209302326 0.15625 +0 0.561046511627907 0.3177083333333333 0.20348837209302326 0.15625 +0 0.25290697674418605 0.7395833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/56abd6bf3a77580e1f7434b396332b9c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/56abd6bf3a77580e1f7434b396332b9c.txt new file mode 100644 index 0000000..980773a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/56abd6bf3a77580e1f7434b396332b9c.txt @@ -0,0 +1,5 @@ +0 0.25872093023255816 0.43229166666666663 0.20348837209302326 0.15625 +0 0.311046511627907 0.7682291666666666 0.20348837209302326 0.15625 +0 0.39825581395348836 0.109375 0.20348837209302326 0.15625 +0 0.5668604651162791 0.5130208333333333 0.20348837209302326 0.15625 +0 0.6453488372093024 0.7578125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5727e0644de09dd82e0f9ff84ae29d00.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5727e0644de09dd82e0f9ff84ae29d00.txt new file mode 100644 index 0000000..c0312c5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5727e0644de09dd82e0f9ff84ae29d00.txt @@ -0,0 +1,5 @@ +0 0.8575581395348837 0.65625 0.20348837209302326 0.15625 +0 0.125 0.2578125 0.20348837209302326 0.15625 +0 0.2819767441860465 0.5260416666666666 0.20348837209302326 0.15625 +0 0.8575581395348837 0.3411458333333333 0.20348837209302326 0.15625 +0 0.36627906976744184 0.7734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/57929e766af28dad62c3b6577689af07.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/57929e766af28dad62c3b6577689af07.txt new file mode 100644 index 0000000..3a60467 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/57929e766af28dad62c3b6577689af07.txt @@ -0,0 +1,3 @@ +0 0.13953488372093023 0.29947916666666663 0.20348837209302326 0.15625 +0 0.2063953488372093 0.7005208333333333 0.20348837209302326 0.15625 +0 0.5552325581395349 0.609375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/579a94ce642e496008d77b2685059844.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/579a94ce642e496008d77b2685059844.txt new file mode 100644 index 0000000..7a41a54 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/579a94ce642e496008d77b2685059844.txt @@ -0,0 +1,3 @@ +0 0.563953488372093 0.1328125 0.20348837209302326 0.15625 +0 0.16569767441860464 0.7395833333333333 0.20348837209302326 0.15625 +0 0.2819767441860465 0.16927083333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/57c18f8afa90c070e2c13cae889a068f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/57c18f8afa90c070e2c13cae889a068f.txt new file mode 100644 index 0000000..10a62c9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/57c18f8afa90c070e2c13cae889a068f.txt @@ -0,0 +1,5 @@ +0 0.8604651162790697 0.7161458333333333 0.20348837209302326 0.15625 +0 0.2645348837209302 0.22135416666666666 0.20348837209302326 0.15625 +0 0.7209302325581395 0.13020833333333331 0.20348837209302326 0.15625 +0 0.1308139534883721 0.5859375 0.20348837209302326 0.15625 +0 0.688953488372093 0.3671875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/581b98d8edfac3f24fc5208bc57b18fe.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/581b98d8edfac3f24fc5208bc57b18fe.txt new file mode 100644 index 0000000..700c7df --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/581b98d8edfac3f24fc5208bc57b18fe.txt @@ -0,0 +1,3 @@ +0 0.5436046511627907 0.640625 0.20348837209302326 0.15625 +0 0.6831395348837209 0.3411458333333333 0.20348837209302326 0.15625 +0 0.19767441860465115 0.4427083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/582afbda17bac0514ac6d9f0aeee9145.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/582afbda17bac0514ac6d9f0aeee9145.txt new file mode 100644 index 0000000..5eb2b92 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/582afbda17bac0514ac6d9f0aeee9145.txt @@ -0,0 +1,4 @@ +0 0.14534883720930233 0.5833333333333333 0.20348837209302326 0.15625 +0 0.4476744186046512 0.21875 0.20348837209302326 0.15625 +0 0.15988372093023256 0.11979166666666666 0.20348837209302326 0.15625 +0 0.7238372093023255 0.5 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/58ff00a62d7c69f0b5baeaf873efcc45.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/58ff00a62d7c69f0b5baeaf873efcc45.txt new file mode 100644 index 0000000..105157d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/58ff00a62d7c69f0b5baeaf873efcc45.txt @@ -0,0 +1,3 @@ +0 0.32558139534883723 0.5078125 0.20348837209302326 0.15625 +0 0.4796511627906977 0.1015625 0.20348837209302326 0.15625 +0 0.7703488372093024 0.11979166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5a304f6bcd90886702924b600c498fda.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5a304f6bcd90886702924b600c498fda.txt new file mode 100644 index 0000000..f77d6aa --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5a304f6bcd90886702924b600c498fda.txt @@ -0,0 +1,3 @@ +0 0.7616279069767442 0.75 0.20348837209302326 0.15625 +0 0.7151162790697674 0.40625 0.20348837209302326 0.15625 +0 0.13953488372093023 0.6328125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5a925a430b7771ae04739a101e5db4c6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5a925a430b7771ae04739a101e5db4c6.txt new file mode 100644 index 0000000..02ffff0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5a925a430b7771ae04739a101e5db4c6.txt @@ -0,0 +1,3 @@ +0 0.45930232558139533 0.2552083333333333 0.20348837209302326 0.15625 +0 0.1686046511627907 0.21614583333333331 0.20348837209302326 0.15625 +0 0.3691860465116279 0.6796875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5abef28ccb79b61c39e44bdaec2e8a9c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5abef28ccb79b61c39e44bdaec2e8a9c.txt new file mode 100644 index 0000000..8a5948c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5abef28ccb79b61c39e44bdaec2e8a9c.txt @@ -0,0 +1,4 @@ +0 0.6337209302325582 0.20572916666666666 0.20348837209302326 0.15625 +0 0.3226744186046512 0.7864583333333333 0.20348837209302326 0.15625 +0 0.5988372093023255 0.5052083333333333 0.20348837209302326 0.15625 +0 0.2965116279069767 0.4192708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5afcf9f6329d796897538eab444b65ee.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5afcf9f6329d796897538eab444b65ee.txt new file mode 100644 index 0000000..10715cd --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5afcf9f6329d796897538eab444b65ee.txt @@ -0,0 +1,4 @@ +0 0.3866279069767442 0.09895833333333333 0.20348837209302326 0.15625 +0 0.561046511627907 0.609375 0.20348837209302326 0.15625 +0 0.20348837209302326 0.765625 0.20348837209302326 0.15625 +0 0.21220930232558138 0.390625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5bd50732b523fe3c8fd746a621056e05.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5bd50732b523fe3c8fd746a621056e05.txt new file mode 100644 index 0000000..a2a7653 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5bd50732b523fe3c8fd746a621056e05.txt @@ -0,0 +1,2 @@ +0 0.4069767441860465 0.671875 0.20348837209302326 0.15625 +0 0.2180232558139535 0.15364583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5c403659a8d135fc7c77649459bec86a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5c403659a8d135fc7c77649459bec86a.txt new file mode 100644 index 0000000..c4c3251 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5c403659a8d135fc7c77649459bec86a.txt @@ -0,0 +1,4 @@ +0 0.7877906976744186 0.46875 0.20348837209302326 0.15625 +0 0.16279069767441862 0.109375 0.20348837209302326 0.15625 +0 0.6686046511627907 0.734375 0.20348837209302326 0.15625 +0 0.13372093023255813 0.7786458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5c79a45619326ae910ca749cba788f1e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5c79a45619326ae910ca749cba788f1e.txt new file mode 100644 index 0000000..2a0a325 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5c79a45619326ae910ca749cba788f1e.txt @@ -0,0 +1,4 @@ +0 0.7906976744186046 0.5364583333333333 0.20348837209302326 0.15625 +0 0.1308139534883721 0.5078125 0.20348837209302326 0.15625 +0 0.45930232558139533 0.6223958333333333 0.20348837209302326 0.15625 +0 0.3575581395348837 0.11979166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5c8113761dce030345c6ff1cf0c2fc65.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5c8113761dce030345c6ff1cf0c2fc65.txt new file mode 100644 index 0000000..a31cb4c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5c8113761dce030345c6ff1cf0c2fc65.txt @@ -0,0 +1,4 @@ +0 0.1511627906976744 0.44791666666666663 0.20348837209302326 0.15625 +0 0.29941860465116277 0.7291666666666666 0.20348837209302326 0.15625 +0 0.6831395348837209 0.40885416666666663 0.20348837209302326 0.15625 +0 0.6337209302325582 0.17708333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5cd4e48a1d7e81309ad024d7734d85a9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5cd4e48a1d7e81309ad024d7734d85a9.txt new file mode 100644 index 0000000..95ff2d7 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5cd4e48a1d7e81309ad024d7734d85a9.txt @@ -0,0 +1,3 @@ +0 0.8081395348837209 0.453125 0.20348837209302326 0.15625 +0 0.2180232558139535 0.6015625 0.20348837209302326 0.15625 +0 0.6133720930232558 0.21875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5cd686f9fa9595f01516468e55b15495.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5cd686f9fa9595f01516468e55b15495.txt new file mode 100644 index 0000000..a9a41c5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5cd686f9fa9595f01516468e55b15495.txt @@ -0,0 +1,4 @@ +0 0.2005813953488372 0.359375 0.20348837209302326 0.15625 +0 0.2761627906976744 0.7734375 0.20348837209302326 0.15625 +0 0.5697674418604651 0.08854166666666666 0.20348837209302326 0.15625 +0 0.7412790697674418 0.5807291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5cd74787a1abeb18be2616712a9a64f9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5cd74787a1abeb18be2616712a9a64f9.txt new file mode 100644 index 0000000..d202188 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5cd74787a1abeb18be2616712a9a64f9.txt @@ -0,0 +1,4 @@ +0 0.436046511627907 0.7369791666666666 0.20348837209302326 0.15625 +0 0.2877906976744186 0.12760416666666666 0.20348837209302326 0.15625 +0 0.6540697674418604 0.24479166666666666 0.20348837209302326 0.15625 +0 0.35174418604651164 0.3880208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5dc9d9c62c331354eb297145ccdcb11c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5dc9d9c62c331354eb297145ccdcb11c.txt new file mode 100644 index 0000000..a97fc3f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5dc9d9c62c331354eb297145ccdcb11c.txt @@ -0,0 +1,4 @@ +0 0.13372093023255813 0.7578125 0.20348837209302326 0.15625 +0 0.6540697674418604 0.3645833333333333 0.20348837209302326 0.15625 +0 0.6133720930232558 0.6979166666666666 0.20348837209302326 0.15625 +0 0.3691860465116279 0.3098958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5dde6a3854a3b65d2281ece59b1e97f4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5dde6a3854a3b65d2281ece59b1e97f4.txt new file mode 100644 index 0000000..60087fe --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5dde6a3854a3b65d2281ece59b1e97f4.txt @@ -0,0 +1,4 @@ +0 0.39244186046511625 0.14322916666666666 0.20348837209302326 0.15625 +0 0.75 0.19791666666666666 0.20348837209302326 0.15625 +0 0.7965116279069767 0.7369791666666666 0.20348837209302326 0.15625 +0 0.5232558139534884 0.5104166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5decce76eab508af166d5cc42f40e701.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5decce76eab508af166d5cc42f40e701.txt new file mode 100644 index 0000000..5a3702a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5decce76eab508af166d5cc42f40e701.txt @@ -0,0 +1,5 @@ +0 0.7034883720930233 0.71875 0.20348837209302326 0.15625 +0 0.1511627906976744 0.6067708333333333 0.20348837209302326 0.15625 +0 0.125 0.1015625 0.20348837209302326 0.15625 +0 0.7732558139534884 0.2890625 0.20348837209302326 0.15625 +0 0.32558139534883723 0.36979166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5f3a9aced738b75096c2c6fe31e3ab0a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5f3a9aced738b75096c2c6fe31e3ab0a.txt new file mode 100644 index 0000000..8dfff6c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5f3a9aced738b75096c2c6fe31e3ab0a.txt @@ -0,0 +1,3 @@ +0 0.47674418604651164 0.421875 0.20348837209302326 0.15625 +0 0.8604651162790697 0.1328125 0.20348837209302326 0.15625 +0 0.14244186046511628 0.10677083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5ffe6679b079f25980b01de470757dbf.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5ffe6679b079f25980b01de470757dbf.txt new file mode 100644 index 0000000..4f018f5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/5ffe6679b079f25980b01de470757dbf.txt @@ -0,0 +1,4 @@ +0 0.5058139534883721 0.53125 0.20348837209302326 0.15625 +0 0.7703488372093024 0.14583333333333331 0.20348837209302326 0.15625 +0 0.7965116279069767 0.7005208333333333 0.20348837209302326 0.15625 +0 0.32558139534883723 0.31510416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/60506a3bbfbf61973a9561404d9696a7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/60506a3bbfbf61973a9561404d9696a7.txt new file mode 100644 index 0000000..7514f81 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/60506a3bbfbf61973a9561404d9696a7.txt @@ -0,0 +1,4 @@ +0 0.438953488372093 0.734375 0.20348837209302326 0.15625 +0 0.3372093023255814 0.4140625 0.20348837209302326 0.15625 +0 0.1569767441860465 0.71875 0.20348837209302326 0.15625 +0 0.8197674418604651 0.7005208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/606c176fcc677a75f5e9926e191f3cf2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/606c176fcc677a75f5e9926e191f3cf2.txt new file mode 100644 index 0000000..fd2c923 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/606c176fcc677a75f5e9926e191f3cf2.txt @@ -0,0 +1,4 @@ +0 0.37790697674418605 0.5104166666666666 0.20348837209302326 0.15625 +0 0.7383720930232558 0.5729166666666666 0.20348837209302326 0.15625 +0 0.7180232558139534 0.25 0.20348837209302326 0.15625 +0 0.39244186046511625 0.29166666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/609db062cfb76cfe8d37d7a9fdde4526.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/609db062cfb76cfe8d37d7a9fdde4526.txt new file mode 100644 index 0000000..c5c04c1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/609db062cfb76cfe8d37d7a9fdde4526.txt @@ -0,0 +1,5 @@ +0 0.7790697674418604 0.6458333333333333 0.20348837209302326 0.15625 +0 0.43023255813953487 0.35416666666666663 0.20348837209302326 0.15625 +0 0.2645348837209302 0.7708333333333333 0.20348837209302326 0.15625 +0 0.8488372093023255 0.14322916666666666 0.20348837209302326 0.15625 +0 0.13662790697674418 0.3671875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/60bd548ee4b8d76d50822ab8abc37e2f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/60bd548ee4b8d76d50822ab8abc37e2f.txt new file mode 100644 index 0000000..b87af92 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/60bd548ee4b8d76d50822ab8abc37e2f.txt @@ -0,0 +1,4 @@ +0 0.7441860465116279 0.5546875 0.20348837209302326 0.15625 +0 0.49127906976744184 0.3177083333333333 0.20348837209302326 0.15625 +0 0.1308139534883721 0.5520833333333333 0.20348837209302326 0.15625 +0 0.13953488372093023 0.3177083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/612de7dddb72056d5295d3f5daa9a331.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/612de7dddb72056d5295d3f5daa9a331.txt new file mode 100644 index 0000000..e984a1d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/612de7dddb72056d5295d3f5daa9a331.txt @@ -0,0 +1,4 @@ +0 0.14534883720930233 0.2890625 0.20348837209302326 0.15625 +0 0.7238372093023255 0.5807291666666666 0.20348837209302326 0.15625 +0 0.4505813953488372 0.11979166666666666 0.20348837209302326 0.15625 +0 0.4476744186046512 0.59375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/614858730a1db249067581a0000d3eba.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/614858730a1db249067581a0000d3eba.txt new file mode 100644 index 0000000..a50e465 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/614858730a1db249067581a0000d3eba.txt @@ -0,0 +1,4 @@ +0 0.5290697674418604 0.7708333333333333 0.20348837209302326 0.15625 +0 0.40988372093023256 0.1484375 0.20348837209302326 0.15625 +0 0.5348837209302325 0.5520833333333333 0.20348837209302326 0.15625 +0 0.1947674418604651 0.5130208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/614ebd6252861be15e74420e75bb87d9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/614ebd6252861be15e74420e75bb87d9.txt new file mode 100644 index 0000000..5302a40 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/614ebd6252861be15e74420e75bb87d9.txt @@ -0,0 +1,4 @@ +0 0.42441860465116277 0.7916666666666666 0.20348837209302326 0.15625 +0 0.1308139534883721 0.3828125 0.20348837209302326 0.15625 +0 0.45930232558139533 0.5104166666666666 0.20348837209302326 0.15625 +0 0.5668604651162791 0.08854166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/615c95ac02a3050083dd03213844c953.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/615c95ac02a3050083dd03213844c953.txt new file mode 100644 index 0000000..4c7578f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/615c95ac02a3050083dd03213844c953.txt @@ -0,0 +1,4 @@ +0 0.4883720930232558 0.6640625 0.20348837209302326 0.15625 +0 0.4011627906976744 0.15104166666666666 0.20348837209302326 0.15625 +0 0.7151162790697674 0.3255208333333333 0.20348837209302326 0.15625 +0 0.3226744186046512 0.4453125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6160431243ccd47e3c99710890816fe2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6160431243ccd47e3c99710890816fe2.txt new file mode 100644 index 0000000..3c0ccb2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6160431243ccd47e3c99710890816fe2.txt @@ -0,0 +1,4 @@ +0 0.2616279069767442 0.43229166666666663 0.20348837209302326 0.15625 +0 0.7616279069767442 0.15104166666666666 0.20348837209302326 0.15625 +0 0.8604651162790697 0.5755208333333333 0.20348837209302326 0.15625 +0 0.25 0.09635416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/61863761596832d6a3a5a572221c1c0a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/61863761596832d6a3a5a572221c1c0a.txt new file mode 100644 index 0000000..3eb6a06 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/61863761596832d6a3a5a572221c1c0a.txt @@ -0,0 +1,4 @@ +0 0.49127906976744184 0.6197916666666666 0.20348837209302326 0.15625 +0 0.20930232558139533 0.7161458333333333 0.20348837209302326 0.15625 +0 0.2703488372093023 0.24479166666666666 0.20348837209302326 0.15625 +0 0.7441860465116279 0.28385416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/61ca751747d09316c5a5da4df72d9f75.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/61ca751747d09316c5a5da4df72d9f75.txt new file mode 100644 index 0000000..6dd3df6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/61ca751747d09316c5a5da4df72d9f75.txt @@ -0,0 +1,4 @@ +0 0.27906976744186046 0.5989583333333333 0.20348837209302326 0.15625 +0 0.6686046511627907 0.1484375 0.20348837209302326 0.15625 +0 0.6424418604651163 0.39322916666666663 0.20348837209302326 0.15625 +0 0.14534883720930233 0.30729166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/61d0ff7b49020dd380cf1946ecbd6460.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/61d0ff7b49020dd380cf1946ecbd6460.txt new file mode 100644 index 0000000..3148750 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/61d0ff7b49020dd380cf1946ecbd6460.txt @@ -0,0 +1,4 @@ +0 0.4825581395348837 0.6796875 0.20348837209302326 0.15625 +0 0.6802325581395349 0.4296875 0.20348837209302326 0.15625 +0 0.2965116279069767 0.33854166666666663 0.20348837209302326 0.15625 +0 0.8372093023255813 0.7291666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/62098e3c2fdfa614e90b97793475c05a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/62098e3c2fdfa614e90b97793475c05a.txt new file mode 100644 index 0000000..391609a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/62098e3c2fdfa614e90b97793475c05a.txt @@ -0,0 +1,5 @@ +0 0.8197674418604651 0.46354166666666663 0.20348837209302326 0.15625 +0 0.5813953488372093 0.15104166666666666 0.20348837209302326 0.15625 +0 0.1569767441860465 0.125 0.20348837209302326 0.15625 +0 0.4563953488372093 0.7317708333333333 0.20348837209302326 0.15625 +0 0.8226744186046512 0.7604166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/627d9e84c2050f1e63ad8b21dfe0aad4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/627d9e84c2050f1e63ad8b21dfe0aad4.txt new file mode 100644 index 0000000..427dea0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/627d9e84c2050f1e63ad8b21dfe0aad4.txt @@ -0,0 +1,4 @@ +0 0.6744186046511628 0.3255208333333333 0.20348837209302326 0.15625 +0 0.1947674418604651 0.140625 0.20348837209302326 0.15625 +0 0.2877906976744186 0.4453125 0.20348837209302326 0.15625 +0 0.43023255813953487 0.6796875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/62c9a42a4ffc7ebc2e2da3f7da351ac5.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/62c9a42a4ffc7ebc2e2da3f7da351ac5.txt new file mode 100644 index 0000000..5372ac0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/62c9a42a4ffc7ebc2e2da3f7da351ac5.txt @@ -0,0 +1,4 @@ +0 0.2616279069767442 0.12239583333333333 0.20348837209302326 0.15625 +0 0.8604651162790697 0.5390625 0.20348837209302326 0.15625 +0 0.4796511627906977 0.37760416666666663 0.20348837209302326 0.15625 +0 0.622093023255814 0.09375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/62cf881287600117953c63b739a2249f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/62cf881287600117953c63b739a2249f.txt new file mode 100644 index 0000000..a4593e6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/62cf881287600117953c63b739a2249f.txt @@ -0,0 +1,4 @@ +0 0.8430232558139534 0.6119791666666666 0.20348837209302326 0.15625 +0 0.22965116279069767 0.19791666666666666 0.20348837209302326 0.15625 +0 0.25 0.7395833333333333 0.20348837209302326 0.15625 +0 0.7296511627906976 0.2552083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6316e194764d0919061f95ee95c24d52.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6316e194764d0919061f95ee95c24d52.txt new file mode 100644 index 0000000..8e4b7fa --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6316e194764d0919061f95ee95c24d52.txt @@ -0,0 +1,3 @@ +0 0.26744186046511625 0.24739583333333331 0.20348837209302326 0.15625 +0 0.5116279069767442 0.59375 0.20348837209302326 0.15625 +0 0.8313953488372093 0.6458333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/63350fd5fe8aa1bb577fce9f577bfd53.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/63350fd5fe8aa1bb577fce9f577bfd53.txt new file mode 100644 index 0000000..203f84d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/63350fd5fe8aa1bb577fce9f577bfd53.txt @@ -0,0 +1,4 @@ +0 0.686046511627907 0.1484375 0.20348837209302326 0.15625 +0 0.3081395348837209 0.578125 0.20348837209302326 0.15625 +0 0.15988372093023256 0.10416666666666666 0.20348837209302326 0.15625 +0 0.7965116279069767 0.4140625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/63bb13a2d95eedb57d2c566f2df33173.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/63bb13a2d95eedb57d2c566f2df33173.txt new file mode 100644 index 0000000..6feac09 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/63bb13a2d95eedb57d2c566f2df33173.txt @@ -0,0 +1,3 @@ +0 0.16569767441860464 0.5130208333333333 0.20348837209302326 0.15625 +0 0.811046511627907 0.2552083333333333 0.20348837209302326 0.15625 +0 0.4563953488372093 0.5052083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/641cbee1c55bb852d9a76acbfaff0996.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/641cbee1c55bb852d9a76acbfaff0996.txt new file mode 100644 index 0000000..7692242 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/641cbee1c55bb852d9a76acbfaff0996.txt @@ -0,0 +1,4 @@ +0 0.6918604651162791 0.6953125 0.20348837209302326 0.15625 +0 0.7587209302325582 0.45572916666666663 0.20348837209302326 0.15625 +0 0.15406976744186046 0.296875 0.20348837209302326 0.15625 +0 0.25 0.5625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6469e4239304a13274b0af6a2e6cb8be.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6469e4239304a13274b0af6a2e6cb8be.txt new file mode 100644 index 0000000..121946b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6469e4239304a13274b0af6a2e6cb8be.txt @@ -0,0 +1,4 @@ +0 0.29069767441860467 0.6614583333333333 0.20348837209302326 0.15625 +0 0.1308139534883721 0.31510416666666663 0.20348837209302326 0.15625 +0 0.6075581395348837 0.36197916666666663 0.20348837209302326 0.15625 +0 0.7645348837209303 0.7057291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/647f279d088b08e79ee57029ceddf366.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/647f279d088b08e79ee57029ceddf366.txt new file mode 100644 index 0000000..7edb10a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/647f279d088b08e79ee57029ceddf366.txt @@ -0,0 +1,3 @@ +0 0.18604651162790697 0.7604166666666666 0.20348837209302326 0.15625 +0 0.436046511627907 0.38541666666666663 0.20348837209302326 0.15625 +0 0.2703488372093023 0.109375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/64f121f89408216490af015f122f5626.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/64f121f89408216490af015f122f5626.txt new file mode 100644 index 0000000..521f9b2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/64f121f89408216490af015f122f5626.txt @@ -0,0 +1,5 @@ +0 0.7965116279069767 0.48697916666666663 0.20348837209302326 0.15625 +0 0.24709302325581395 0.21354166666666666 0.20348837209302326 0.15625 +0 0.3546511627906977 0.4661458333333333 0.20348837209302326 0.15625 +0 0.5988372093023255 0.13020833333333331 0.20348837209302326 0.15625 +0 0.4331395348837209 0.7630208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6531967f2e93a316e85968ad011ab298.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6531967f2e93a316e85968ad011ab298.txt new file mode 100644 index 0000000..3c1df7c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6531967f2e93a316e85968ad011ab298.txt @@ -0,0 +1,4 @@ +0 0.3081395348837209 0.7421875 0.20348837209302326 0.15625 +0 0.7296511627906976 0.3880208333333333 0.20348837209302326 0.15625 +0 0.24127906976744184 0.19791666666666666 0.20348837209302326 0.15625 +0 0.27325581395348836 0.46875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/654da3f9d5a6f3f8ebd4657cfb60e0fa.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/654da3f9d5a6f3f8ebd4657cfb60e0fa.txt new file mode 100644 index 0000000..44eb7fc --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/654da3f9d5a6f3f8ebd4657cfb60e0fa.txt @@ -0,0 +1,5 @@ +0 0.2645348837209302 0.1484375 0.20348837209302326 0.15625 +0 0.8343023255813954 0.5390625 0.20348837209302326 0.15625 +0 0.39244186046511625 0.5963541666666666 0.20348837209302326 0.15625 +0 0.8023255813953488 0.13020833333333331 0.20348837209302326 0.15625 +0 0.4505813953488372 0.3828125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/65a205310ec88ecdc9b0e143987f8323.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/65a205310ec88ecdc9b0e143987f8323.txt new file mode 100644 index 0000000..908d487 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/65a205310ec88ecdc9b0e143987f8323.txt @@ -0,0 +1,3 @@ +0 0.6366279069767442 0.7317708333333333 0.20348837209302326 0.15625 +0 0.13662790697674418 0.21875 0.20348837209302326 0.15625 +0 0.4622093023255814 0.3984375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/65e1d36f8ade84826fe1a011a13db813.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/65e1d36f8ade84826fe1a011a13db813.txt new file mode 100644 index 0000000..bdaf4b9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/65e1d36f8ade84826fe1a011a13db813.txt @@ -0,0 +1,5 @@ +0 0.49127906976744184 0.7421875 0.20348837209302326 0.15625 +0 0.8284883720930233 0.5703125 0.20348837209302326 0.15625 +0 0.5319767441860465 0.21614583333333331 0.20348837209302326 0.15625 +0 0.8604651162790697 0.22395833333333331 0.20348837209302326 0.15625 +0 0.15406976744186046 0.3046875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/66686038b549eb8ff43b82bd40232971.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/66686038b549eb8ff43b82bd40232971.txt new file mode 100644 index 0000000..0ea8543 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/66686038b549eb8ff43b82bd40232971.txt @@ -0,0 +1,4 @@ +0 0.42441860465116277 0.6484375 0.20348837209302326 0.15625 +0 0.6918604651162791 0.21875 0.20348837209302326 0.15625 +0 0.22093023255813954 0.3567708333333333 0.20348837209302326 0.15625 +0 0.7936046511627907 0.6015625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/669f3f863917812a5aad9467713035eb.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/669f3f863917812a5aad9467713035eb.txt new file mode 100644 index 0000000..20293bb --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/669f3f863917812a5aad9467713035eb.txt @@ -0,0 +1,4 @@ +0 0.2616279069767442 0.7239583333333333 0.20348837209302326 0.15625 +0 0.3808139534883721 0.4192708333333333 0.20348837209302326 0.15625 +0 0.8459302325581395 0.6354166666666666 0.20348837209302326 0.15625 +0 0.7151162790697674 0.25 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/66f5727e00ab69c6ef495fa5762bd3ac.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/66f5727e00ab69c6ef495fa5762bd3ac.txt new file mode 100644 index 0000000..9a8f2c6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/66f5727e00ab69c6ef495fa5762bd3ac.txt @@ -0,0 +1,5 @@ +0 0.6947674418604651 0.4427083333333333 0.20348837209302326 0.15625 +0 0.5523255813953488 0.19270833333333331 0.20348837209302326 0.15625 +0 0.747093023255814 0.6953125 0.20348837209302326 0.15625 +0 0.22965116279069767 0.6614583333333333 0.20348837209302326 0.15625 +0 0.15988372093023256 0.19270833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/671dcfa5790bce42ff42e7361adef981.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/671dcfa5790bce42ff42e7361adef981.txt new file mode 100644 index 0000000..62357b0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/671dcfa5790bce42ff42e7361adef981.txt @@ -0,0 +1,4 @@ +0 0.8575581395348837 0.6979166666666666 0.20348837209302326 0.15625 +0 0.29069767441860467 0.7005208333333333 0.20348837209302326 0.15625 +0 0.6744186046511628 0.44791666666666663 0.20348837209302326 0.15625 +0 0.5494186046511628 0.14583333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/674cdcfc5e75d72e67a57b268cb2d7c8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/674cdcfc5e75d72e67a57b268cb2d7c8.txt new file mode 100644 index 0000000..d0ddc29 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/674cdcfc5e75d72e67a57b268cb2d7c8.txt @@ -0,0 +1,5 @@ +0 0.5581395348837209 0.5104166666666666 0.20348837209302326 0.15625 +0 0.44476744186046513 0.21614583333333331 0.20348837209302326 0.15625 +0 0.1686046511627907 0.671875 0.20348837209302326 0.15625 +0 0.7005813953488372 0.7473958333333333 0.20348837209302326 0.15625 +0 0.8081395348837209 0.09895833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/675960daaf242fc304acc42997f5f5e8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/675960daaf242fc304acc42997f5f5e8.txt new file mode 100644 index 0000000..2af0f39 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/675960daaf242fc304acc42997f5f5e8.txt @@ -0,0 +1,4 @@ +0 0.5145348837209303 0.15364583333333331 0.20348837209302326 0.15625 +0 0.2238372093023256 0.6953125 0.20348837209302326 0.15625 +0 0.7906976744186046 0.6979166666666666 0.20348837209302326 0.15625 +0 0.8197674418604651 0.4505208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6761d9a3692394a926b110231cc9faa1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6761d9a3692394a926b110231cc9faa1.txt new file mode 100644 index 0000000..8c41974 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6761d9a3692394a926b110231cc9faa1.txt @@ -0,0 +1,2 @@ +0 0.6453488372093024 0.5651041666666666 0.20348837209302326 0.15625 +0 0.3430232558139535 0.71875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/67cc2082f51c3493d37927b395d7857f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/67cc2082f51c3493d37927b395d7857f.txt new file mode 100644 index 0000000..f4e73b8 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/67cc2082f51c3493d37927b395d7857f.txt @@ -0,0 +1,5 @@ +0 0.2936046511627907 0.6276041666666666 0.20348837209302326 0.15625 +0 0.7412790697674418 0.2864583333333333 0.20348837209302326 0.15625 +0 0.6308139534883721 0.7421875 0.20348837209302326 0.15625 +0 0.41860465116279066 0.11979166666666666 0.20348837209302326 0.15625 +0 0.34593023255813954 0.40625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/67cc43fadd103cabd453ce0e781c613a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/67cc43fadd103cabd453ce0e781c613a.txt new file mode 100644 index 0000000..11e3379 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/67cc43fadd103cabd453ce0e781c613a.txt @@ -0,0 +1,4 @@ +0 0.8168604651162791 0.7239583333333333 0.20348837209302326 0.15625 +0 0.3808139534883721 0.421875 0.20348837209302326 0.15625 +0 0.6686046511627907 0.09635416666666666 0.20348837209302326 0.15625 +0 0.39244186046511625 0.22135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/67d8f80d5128e94afcd8e05c9d63b318.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/67d8f80d5128e94afcd8e05c9d63b318.txt new file mode 100644 index 0000000..1390daf --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/67d8f80d5128e94afcd8e05c9d63b318.txt @@ -0,0 +1,4 @@ +0 0.5319767441860465 0.41666666666666663 0.20348837209302326 0.15625 +0 0.18023255813953487 0.546875 0.20348837209302326 0.15625 +0 0.1744186046511628 0.171875 0.20348837209302326 0.15625 +0 0.8401162790697674 0.14583333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/68021589884976b211fea7a1b536746b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/68021589884976b211fea7a1b536746b.txt new file mode 100644 index 0000000..30b5f04 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/68021589884976b211fea7a1b536746b.txt @@ -0,0 +1,4 @@ +0 0.41860465116279066 0.3203125 0.20348837209302326 0.15625 +0 0.6831395348837209 0.7838541666666666 0.20348837209302326 0.15625 +0 0.7761627906976744 0.09635416666666666 0.20348837209302326 0.15625 +0 0.8255813953488372 0.5182291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6811c132f0c1fdb54289db99fb7f8466.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6811c132f0c1fdb54289db99fb7f8466.txt new file mode 100644 index 0000000..5d237ff --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6811c132f0c1fdb54289db99fb7f8466.txt @@ -0,0 +1,4 @@ +0 0.6104651162790697 0.578125 0.20348837209302326 0.15625 +0 0.5 0.21354166666666666 0.20348837209302326 0.15625 +0 0.2441860465116279 0.6640625 0.20348837209302326 0.15625 +0 0.18023255813953487 0.4296875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6814fd1f5a973d88ad8e18db290763fa.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6814fd1f5a973d88ad8e18db290763fa.txt new file mode 100644 index 0000000..42bbaac --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6814fd1f5a973d88ad8e18db290763fa.txt @@ -0,0 +1,5 @@ +0 0.3953488372093023 0.5859375 0.20348837209302326 0.15625 +0 0.22093023255813954 0.22135416666666666 0.20348837209302326 0.15625 +0 0.7412790697674418 0.2552083333333333 0.20348837209302326 0.15625 +0 0.7906976744186046 0.6796875 0.20348837209302326 0.15625 +0 0.1511627906976744 0.5442708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/685a00671ecc6674b52dab309f709a39.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/685a00671ecc6674b52dab309f709a39.txt new file mode 100644 index 0000000..688f4d6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/685a00671ecc6674b52dab309f709a39.txt @@ -0,0 +1,3 @@ +0 0.6133720930232558 0.22395833333333331 0.20348837209302326 0.15625 +0 0.3808139534883721 0.4583333333333333 0.20348837209302326 0.15625 +0 0.7093023255813954 0.515625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/685fbde97e162e8e898316a0ca5eb1ea.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/685fbde97e162e8e898316a0ca5eb1ea.txt new file mode 100644 index 0000000..0e5b907 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/685fbde97e162e8e898316a0ca5eb1ea.txt @@ -0,0 +1,5 @@ +0 0.13953488372093023 0.20052083333333331 0.20348837209302326 0.15625 +0 0.44476744186046513 0.140625 0.20348837209302326 0.15625 +0 0.5465116279069767 0.609375 0.20348837209302326 0.15625 +0 0.8401162790697674 0.3255208333333333 0.20348837209302326 0.15625 +0 0.14534883720930233 0.6041666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6874e45cafb16e88a3f184673284ea5e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6874e45cafb16e88a3f184673284ea5e.txt new file mode 100644 index 0000000..44b0b1d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6874e45cafb16e88a3f184673284ea5e.txt @@ -0,0 +1,3 @@ +0 0.7994186046511628 0.26041666666666663 0.20348837209302326 0.15625 +0 0.313953488372093 0.5104166666666666 0.20348837209302326 0.15625 +0 0.8401162790697674 0.7265625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/689e03d98c9ada4ea288165a9ccae310.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/689e03d98c9ada4ea288165a9ccae310.txt new file mode 100644 index 0000000..0485012 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/689e03d98c9ada4ea288165a9ccae310.txt @@ -0,0 +1,4 @@ +0 0.4273255813953488 0.20572916666666666 0.20348837209302326 0.15625 +0 0.12209302325581395 0.7447916666666666 0.20348837209302326 0.15625 +0 0.7936046511627907 0.32291666666666663 0.20348837209302326 0.15625 +0 0.13372093023255813 0.12239583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/68c20ca22679dd2e57a12461c69872aa.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/68c20ca22679dd2e57a12461c69872aa.txt new file mode 100644 index 0000000..3f3d6cf --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/68c20ca22679dd2e57a12461c69872aa.txt @@ -0,0 +1,4 @@ +0 0.34593023255813954 0.6588541666666666 0.20348837209302326 0.15625 +0 0.5087209302325582 0.1640625 0.20348837209302326 0.15625 +0 0.7732558139534884 0.7734375 0.20348837209302326 0.15625 +0 0.8343023255813954 0.234375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6a256b4463c2bfc2d41be1ffc23630c1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6a256b4463c2bfc2d41be1ffc23630c1.txt new file mode 100644 index 0000000..0fc0a85 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6a256b4463c2bfc2d41be1ffc23630c1.txt @@ -0,0 +1,4 @@ +0 0.7180232558139534 0.23958333333333331 0.20348837209302326 0.15625 +0 0.27325581395348836 0.3645833333333333 0.20348837209302326 0.15625 +0 0.8226744186046512 0.4609375 0.20348837209302326 0.15625 +0 0.27906976744186046 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6ae427c6254f66fc62732edc6ddc1ace.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6ae427c6254f66fc62732edc6ddc1ace.txt new file mode 100644 index 0000000..6c74549 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6ae427c6254f66fc62732edc6ddc1ace.txt @@ -0,0 +1,4 @@ +0 0.5726744186046512 0.7395833333333333 0.20348837209302326 0.15625 +0 0.2936046511627907 0.4036458333333333 0.20348837209302326 0.15625 +0 0.622093023255814 0.109375 0.20348837209302326 0.15625 +0 0.29941860465116277 0.7291666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6b5c01d5529e03f00b956735300e43b6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6b5c01d5529e03f00b956735300e43b6.txt new file mode 100644 index 0000000..bf9614c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6b5c01d5529e03f00b956735300e43b6.txt @@ -0,0 +1,5 @@ +0 0.8430232558139534 0.25260416666666663 0.20348837209302326 0.15625 +0 0.5988372093023255 0.6953125 0.20348837209302326 0.15625 +0 0.2005813953488372 0.5208333333333333 0.20348837209302326 0.15625 +0 0.438953488372093 0.2942708333333333 0.20348837209302326 0.15625 +0 0.17151162790697674 0.7708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6b8156e47350f0706fe6e62cd6bffcff.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6b8156e47350f0706fe6e62cd6bffcff.txt new file mode 100644 index 0000000..c20030c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6b8156e47350f0706fe6e62cd6bffcff.txt @@ -0,0 +1,5 @@ +0 0.2936046511627907 0.3333333333333333 0.20348837209302326 0.15625 +0 0.7005813953488372 0.38541666666666663 0.20348837209302326 0.15625 +0 0.3488372093023256 0.6328125 0.20348837209302326 0.15625 +0 0.6366279069767442 0.6770833333333333 0.20348837209302326 0.15625 +0 0.3488372093023256 0.09635416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6bad8bc610e01619ee550b2955ba8ad7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6bad8bc610e01619ee550b2955ba8ad7.txt new file mode 100644 index 0000000..3ae4ea0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6bad8bc610e01619ee550b2955ba8ad7.txt @@ -0,0 +1,5 @@ +0 0.25290697674418605 0.7890625 0.20348837209302326 0.15625 +0 0.18604651162790697 0.4921875 0.20348837209302326 0.15625 +0 0.6337209302325582 0.7838541666666666 0.20348837209302326 0.15625 +0 0.7180232558139534 0.3671875 0.20348837209302326 0.15625 +0 0.34011627906976744 0.1953125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6bfae2cb6f4bd0a25c84cd1b4873b90d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6bfae2cb6f4bd0a25c84cd1b4873b90d.txt new file mode 100644 index 0000000..2a41e57 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6bfae2cb6f4bd0a25c84cd1b4873b90d.txt @@ -0,0 +1,5 @@ +0 0.6308139534883721 0.10677083333333333 0.20348837209302326 0.15625 +0 0.7790697674418604 0.484375 0.20348837209302326 0.15625 +0 0.30523255813953487 0.7760416666666666 0.20348837209302326 0.15625 +0 0.5988372093023255 0.7760416666666666 0.20348837209302326 0.15625 +0 0.34011627906976744 0.17708333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6ccc2daae37222aaf0735232c9ccf397.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6ccc2daae37222aaf0735232c9ccf397.txt new file mode 100644 index 0000000..15603f9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6ccc2daae37222aaf0735232c9ccf397.txt @@ -0,0 +1,5 @@ +0 0.6744186046511628 0.30729166666666663 0.20348837209302326 0.15625 +0 0.3691860465116279 0.5625 0.20348837209302326 0.15625 +0 0.21511627906976744 0.0859375 0.20348837209302326 0.15625 +0 0.3372093023255814 0.3098958333333333 0.20348837209302326 0.15625 +0 0.6656976744186046 0.6666666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6d0bbede8f34a0d2964de8f6103276b5.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6d0bbede8f34a0d2964de8f6103276b5.txt new file mode 100644 index 0000000..af11f3e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6d0bbede8f34a0d2964de8f6103276b5.txt @@ -0,0 +1,5 @@ +0 0.34593023255813954 0.23958333333333331 0.20348837209302326 0.15625 +0 0.47674418604651164 0.7057291666666666 0.20348837209302326 0.15625 +0 0.747093023255814 0.37760416666666663 0.20348837209302326 0.15625 +0 0.16569767441860464 0.671875 0.20348837209302326 0.15625 +0 0.75 0.12239583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6d52ce280a29a63de6c9075a433b35b9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6d52ce280a29a63de6c9075a433b35b9.txt new file mode 100644 index 0000000..80ead6f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6d52ce280a29a63de6c9075a433b35b9.txt @@ -0,0 +1,4 @@ +0 0.5232558139534884 0.4505208333333333 0.20348837209302326 0.15625 +0 0.12209302325581395 0.5598958333333333 0.20348837209302326 0.15625 +0 0.5930232558139534 0.7708333333333333 0.20348837209302326 0.15625 +0 0.6947674418604651 0.23958333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6d8fa2539a2ef1645a8c701182dedd0a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6d8fa2539a2ef1645a8c701182dedd0a.txt new file mode 100644 index 0000000..d99a838 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6d8fa2539a2ef1645a8c701182dedd0a.txt @@ -0,0 +1,5 @@ +0 0.48546511627906974 0.09895833333333333 0.20348837209302326 0.15625 +0 0.37790697674418605 0.5598958333333333 0.20348837209302326 0.15625 +0 0.7994186046511628 0.7291666666666666 0.20348837209302326 0.15625 +0 0.688953488372093 0.47135416666666663 0.20348837209302326 0.15625 +0 0.15988372093023256 0.21354166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6f1725e81669f9305a3439151ef72f8c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6f1725e81669f9305a3439151ef72f8c.txt new file mode 100644 index 0000000..1110fa1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6f1725e81669f9305a3439151ef72f8c.txt @@ -0,0 +1,2 @@ +0 0.436046511627907 0.5625 0.20348837209302326 0.15625 +0 0.8255813953488372 0.18229166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6f223bc6b316b0b23092440555a896fa.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6f223bc6b316b0b23092440555a896fa.txt new file mode 100644 index 0000000..1af4c20 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6f223bc6b316b0b23092440555a896fa.txt @@ -0,0 +1,4 @@ +0 0.8488372093023255 0.7630208333333333 0.20348837209302326 0.15625 +0 0.22093023255813954 0.7708333333333333 0.20348837209302326 0.15625 +0 0.5784883720930233 0.3671875 0.20348837209302326 0.15625 +0 0.6947674418604651 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6f6c2db4d2ce36081ac59018fbd038f3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6f6c2db4d2ce36081ac59018fbd038f3.txt new file mode 100644 index 0000000..12ae496 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6f6c2db4d2ce36081ac59018fbd038f3.txt @@ -0,0 +1,4 @@ +0 0.8313953488372093 0.3125 0.20348837209302326 0.15625 +0 0.3081395348837209 0.6875 0.20348837209302326 0.15625 +0 0.7848837209302325 0.6901041666666666 0.20348837209302326 0.15625 +0 0.09011627906976744 0.3177083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6f9ddbf3c152d3883f97d49209103a28.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6f9ddbf3c152d3883f97d49209103a28.txt new file mode 100644 index 0000000..58295c7 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6f9ddbf3c152d3883f97d49209103a28.txt @@ -0,0 +1,3 @@ +0 0.8517441860465116 0.39322916666666663 0.20348837209302326 0.15625 +0 0.48546511627906974 0.12239583333333333 0.20348837209302326 0.15625 +0 0.11046511627906977 0.10677083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6faed00d4e3c1920e974a95a269c6849.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6faed00d4e3c1920e974a95a269c6849.txt new file mode 100644 index 0000000..3a064c2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6faed00d4e3c1920e974a95a269c6849.txt @@ -0,0 +1,4 @@ +0 0.7093023255813954 0.4270833333333333 0.20348837209302326 0.15625 +0 0.3953488372093023 0.32291666666666663 0.20348837209302326 0.15625 +0 0.8255813953488372 0.0859375 0.20348837209302326 0.15625 +0 0.37209302325581395 0.6223958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6fb30e63335e1f7bac4ffdf25b3e1755.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6fb30e63335e1f7bac4ffdf25b3e1755.txt new file mode 100644 index 0000000..226ab72 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6fb30e63335e1f7bac4ffdf25b3e1755.txt @@ -0,0 +1,4 @@ +0 0.42441860465116277 0.6067708333333333 0.20348837209302326 0.15625 +0 0.7412790697674418 0.1640625 0.20348837209302326 0.15625 +0 0.7877906976744186 0.6901041666666666 0.20348837209302326 0.15625 +0 0.22674418604651161 0.29947916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6ff25b93f67c0e1ad048553fe613cb90.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6ff25b93f67c0e1ad048553fe613cb90.txt new file mode 100644 index 0000000..4437f93 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/6ff25b93f67c0e1ad048553fe613cb90.txt @@ -0,0 +1,3 @@ +0 0.34593023255813954 0.7630208333333333 0.20348837209302326 0.15625 +0 0.747093023255814 0.5026041666666666 0.20348837209302326 0.15625 +0 0.42441860465116277 0.3723958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/706210c7ac57c921f111e72f880eba05.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/706210c7ac57c921f111e72f880eba05.txt new file mode 100644 index 0000000..77d1c29 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/706210c7ac57c921f111e72f880eba05.txt @@ -0,0 +1,4 @@ +0 0.6133720930232558 0.3177083333333333 0.20348837209302326 0.15625 +0 0.09302325581395349 0.4296875 0.20348837209302326 0.15625 +0 0.8284883720930233 0.6875 0.20348837209302326 0.15625 +0 0.4273255813953488 0.7994791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/70802160fb371dabcbb4bb1337a5f961.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/70802160fb371dabcbb4bb1337a5f961.txt new file mode 100644 index 0000000..b859b84 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/70802160fb371dabcbb4bb1337a5f961.txt @@ -0,0 +1,4 @@ +0 0.18313953488372092 0.5234375 0.20348837209302326 0.15625 +0 0.4476744186046512 0.1171875 0.20348837209302326 0.15625 +0 0.7994186046511628 0.7421875 0.20348837209302326 0.15625 +0 0.2645348837209302 0.8020833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/71174b75dec785c7788664f7e55489b3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/71174b75dec785c7788664f7e55489b3.txt new file mode 100644 index 0000000..491a614 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/71174b75dec785c7788664f7e55489b3.txt @@ -0,0 +1,5 @@ +0 0.1947674418604651 0.7734375 0.20348837209302326 0.15625 +0 0.16569767441860464 0.5260416666666666 0.20348837209302326 0.15625 +0 0.8517441860465116 0.5286458333333333 0.20348837209302326 0.15625 +0 0.5174418604651163 0.75 0.20348837209302326 0.15625 +0 0.18313953488372092 0.12760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7134f47548c2b955351652ff5645afa0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7134f47548c2b955351652ff5645afa0.txt new file mode 100644 index 0000000..b9686fc --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7134f47548c2b955351652ff5645afa0.txt @@ -0,0 +1,4 @@ +0 0.8226744186046512 0.546875 0.20348837209302326 0.15625 +0 0.16569767441860464 0.5520833333333333 0.20348837209302326 0.15625 +0 0.7877906976744186 0.20833333333333331 0.20348837209302326 0.15625 +0 0.43023255813953487 0.29947916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/71d08cef5ef7e0f411e76c72374323f2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/71d08cef5ef7e0f411e76c72374323f2.txt new file mode 100644 index 0000000..afd0d8e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/71d08cef5ef7e0f411e76c72374323f2.txt @@ -0,0 +1,4 @@ +0 0.6017441860465116 0.21354166666666666 0.20348837209302326 0.15625 +0 0.5377906976744186 0.7734375 0.20348837209302326 0.15625 +0 0.8023255813953488 0.4765625 0.20348837209302326 0.15625 +0 0.4883720930232558 0.453125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/72026cff158522b81511ec70dcdf4aa0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/72026cff158522b81511ec70dcdf4aa0.txt new file mode 100644 index 0000000..7d75c1f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/72026cff158522b81511ec70dcdf4aa0.txt @@ -0,0 +1,5 @@ +0 0.13953488372093023 0.3567708333333333 0.20348837209302326 0.15625 +0 0.4127906976744186 0.44791666666666663 0.20348837209302326 0.15625 +0 0.8168604651162791 0.6171875 0.20348837209302326 0.15625 +0 0.2936046511627907 0.7265625 0.20348837209302326 0.15625 +0 0.7616279069767442 0.38541666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/72836c22972e722dac846a1335740981.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/72836c22972e722dac846a1335740981.txt new file mode 100644 index 0000000..e89bcff --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/72836c22972e722dac846a1335740981.txt @@ -0,0 +1,5 @@ +0 0.7441860465116279 0.65625 0.20348837209302326 0.15625 +0 0.15988372093023256 0.3333333333333333 0.20348837209302326 0.15625 +0 0.40988372093023256 0.7552083333333333 0.20348837209302326 0.15625 +0 0.5901162790697674 0.359375 0.20348837209302326 0.15625 +0 0.6133720930232558 0.13020833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/72cc72e4557a4e81cf22abc1c528736b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/72cc72e4557a4e81cf22abc1c528736b.txt new file mode 100644 index 0000000..3b7561a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/72cc72e4557a4e81cf22abc1c528736b.txt @@ -0,0 +1,4 @@ +0 0.8604651162790697 0.14322916666666666 0.20348837209302326 0.15625 +0 0.31976744186046513 0.296875 0.20348837209302326 0.15625 +0 0.688953488372093 0.5755208333333333 0.20348837209302326 0.15625 +0 0.16569767441860464 0.7578125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/732aff09bd2c2cd1d0819518db9d0350.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/732aff09bd2c2cd1d0819518db9d0350.txt new file mode 100644 index 0000000..61053b0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/732aff09bd2c2cd1d0819518db9d0350.txt @@ -0,0 +1,5 @@ +0 0.18604651162790697 0.4505208333333333 0.20348837209302326 0.15625 +0 0.3575581395348837 0.11197916666666666 0.20348837209302326 0.15625 +0 0.5290697674418604 0.7708333333333333 0.20348837209302326 0.15625 +0 0.7645348837209303 0.17708333333333331 0.20348837209302326 0.15625 +0 0.8343023255813954 0.53125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/73441b2ac1f58597e7ab1b53e17f13b6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/73441b2ac1f58597e7ab1b53e17f13b6.txt new file mode 100644 index 0000000..118b985 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/73441b2ac1f58597e7ab1b53e17f13b6.txt @@ -0,0 +1,3 @@ +0 0.25 0.12239583333333333 0.20348837209302326 0.15625 +0 0.7383720930232558 0.4348958333333333 0.20348837209302326 0.15625 +0 0.5813953488372093 0.6614583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/73aa55f4cd9bcfb421deb1af301ffc21.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/73aa55f4cd9bcfb421deb1af301ffc21.txt new file mode 100644 index 0000000..68b5e1c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/73aa55f4cd9bcfb421deb1af301ffc21.txt @@ -0,0 +1,5 @@ +0 0.45930232558139533 0.6015625 0.20348837209302326 0.15625 +0 0.40988372093023256 0.1015625 0.20348837209302326 0.15625 +0 0.8633720930232558 0.5911458333333333 0.20348837209302326 0.15625 +0 0.7645348837209303 0.25 0.20348837209302326 0.15625 +0 0.11046511627906977 0.34375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/73cba4855d73187819c25cf87099a594.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/73cba4855d73187819c25cf87099a594.txt new file mode 100644 index 0000000..52d5146 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/73cba4855d73187819c25cf87099a594.txt @@ -0,0 +1,3 @@ +0 0.36046511627906974 0.20572916666666666 0.20348837209302326 0.15625 +0 0.24127906976744184 0.6614583333333333 0.20348837209302326 0.15625 +0 0.7383720930232558 0.578125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7415d41effa5df58627bd735635d4218.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7415d41effa5df58627bd735635d4218.txt new file mode 100644 index 0000000..f0f226e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7415d41effa5df58627bd735635d4218.txt @@ -0,0 +1,4 @@ +0 0.7790697674418604 0.2734375 0.20348837209302326 0.15625 +0 0.39244186046511625 0.5078125 0.20348837209302326 0.15625 +0 0.5 0.1640625 0.20348837209302326 0.15625 +0 0.7965116279069767 0.7421875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/741f932ae86107ee315fbdb88bfa6a0d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/741f932ae86107ee315fbdb88bfa6a0d.txt new file mode 100644 index 0000000..1b1d888 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/741f932ae86107ee315fbdb88bfa6a0d.txt @@ -0,0 +1,5 @@ +0 0.7122093023255814 0.5859375 0.20348837209302326 0.15625 +0 0.18313953488372092 0.6796875 0.20348837209302326 0.15625 +0 0.4825581395348837 0.296875 0.20348837209302326 0.15625 +0 0.8662790697674418 0.296875 0.20348837209302326 0.15625 +0 0.15988372093023256 0.3671875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7507925f7256682ed6aaea4c2d2aca10.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7507925f7256682ed6aaea4c2d2aca10.txt new file mode 100644 index 0000000..b462451 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7507925f7256682ed6aaea4c2d2aca10.txt @@ -0,0 +1,4 @@ +0 0.6686046511627907 0.10416666666666666 0.20348837209302326 0.15625 +0 0.5 0.41666666666666663 0.20348837209302326 0.15625 +0 0.3808139534883721 0.6927083333333333 0.20348837209302326 0.15625 +0 0.8604651162790697 0.59375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7512c7cd273ab4222c4271c553c9abc7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7512c7cd273ab4222c4271c553c9abc7.txt new file mode 100644 index 0000000..d2c0c94 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7512c7cd273ab4222c4271c553c9abc7.txt @@ -0,0 +1,3 @@ +0 0.747093023255814 0.4036458333333333 0.20348837209302326 0.15625 +0 0.7674418604651163 0.6614583333333333 0.20348837209302326 0.15625 +0 0.4738372093023256 0.15364583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7558d6ecd55b8cfa8c735d006368acbf.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7558d6ecd55b8cfa8c735d006368acbf.txt new file mode 100644 index 0000000..9650c6b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7558d6ecd55b8cfa8c735d006368acbf.txt @@ -0,0 +1,3 @@ +0 0.313953488372093 0.6276041666666666 0.20348837209302326 0.15625 +0 0.31976744186046513 0.33854166666666663 0.20348837209302326 0.15625 +0 0.752906976744186 0.5104166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/757b85c3f6201ca3cd2fe354f27b3c3d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/757b85c3f6201ca3cd2fe354f27b3c3d.txt new file mode 100644 index 0000000..730e679 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/757b85c3f6201ca3cd2fe354f27b3c3d.txt @@ -0,0 +1,4 @@ +0 0.6482558139534884 0.6484375 0.20348837209302326 0.15625 +0 0.7819767441860465 0.16927083333333331 0.20348837209302326 0.15625 +0 0.22093023255813954 0.6354166666666666 0.20348837209302326 0.15625 +0 0.4796511627906977 0.0859375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/759531a2d64ac993772dab9c346f9b43.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/759531a2d64ac993772dab9c346f9b43.txt new file mode 100644 index 0000000..176e576 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/759531a2d64ac993772dab9c346f9b43.txt @@ -0,0 +1,4 @@ +0 0.7965116279069767 0.6640625 0.20348837209302326 0.15625 +0 0.38372093023255816 0.75 0.20348837209302326 0.15625 +0 0.3430232558139535 0.1328125 0.20348837209302326 0.15625 +0 0.36046511627906974 0.5208333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/75f79b51486951278990668460cef32b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/75f79b51486951278990668460cef32b.txt new file mode 100644 index 0000000..b96290c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/75f79b51486951278990668460cef32b.txt @@ -0,0 +1,5 @@ +0 0.3633720930232558 0.6953125 0.20348837209302326 0.15625 +0 0.7703488372093024 0.45572916666666663 0.20348837209302326 0.15625 +0 0.14534883720930233 0.1015625 0.20348837209302326 0.15625 +0 0.8255813953488372 0.7526041666666666 0.20348837209302326 0.15625 +0 0.21220930232558138 0.3645833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/76235edd4142671e43e1eb29f69d3554.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/76235edd4142671e43e1eb29f69d3554.txt new file mode 100644 index 0000000..c4b5ab4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/76235edd4142671e43e1eb29f69d3554.txt @@ -0,0 +1,5 @@ +0 0.5552325581395349 0.5807291666666666 0.20348837209302326 0.15625 +0 0.6744186046511628 0.328125 0.20348837209302326 0.15625 +0 0.7819767441860465 0.09635416666666666 0.20348837209302326 0.15625 +0 0.1569767441860465 0.5416666666666666 0.20348837209302326 0.15625 +0 0.8691860465116279 0.6770833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7653741a4131b7ef6209fc437ae56964.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7653741a4131b7ef6209fc437ae56964.txt new file mode 100644 index 0000000..1cb5a74 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7653741a4131b7ef6209fc437ae56964.txt @@ -0,0 +1,4 @@ +0 0.622093023255814 0.26041666666666663 0.20348837209302326 0.15625 +0 0.6424418604651163 0.5026041666666666 0.20348837209302326 0.15625 +0 0.22965116279069767 0.6796875 0.20348837209302326 0.15625 +0 0.6482558139534884 0.7760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/767b2849dd02b721e2025bd9665cd08e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/767b2849dd02b721e2025bd9665cd08e.txt new file mode 100644 index 0000000..791ea53 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/767b2849dd02b721e2025bd9665cd08e.txt @@ -0,0 +1,4 @@ +0 0.4883720930232558 0.296875 0.20348837209302326 0.15625 +0 0.7819767441860465 0.7630208333333333 0.20348837209302326 0.15625 +0 0.8052325581395349 0.27604166666666663 0.20348837209302326 0.15625 +0 0.5959302325581395 0.5390625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/768e06591d853849afafee9dd970df4e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/768e06591d853849afafee9dd970df4e.txt new file mode 100644 index 0000000..8de3841 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/768e06591d853849afafee9dd970df4e.txt @@ -0,0 +1,4 @@ +0 0.747093023255814 0.5442708333333333 0.20348837209302326 0.15625 +0 0.47093023255813954 0.3177083333333333 0.20348837209302326 0.15625 +0 0.7645348837209303 0.31510416666666663 0.20348837209302326 0.15625 +0 0.4011627906976744 0.6770833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/768fcfee15a5acbc6deabcb1741d283a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/768fcfee15a5acbc6deabcb1741d283a.txt new file mode 100644 index 0000000..7d3af04 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/768fcfee15a5acbc6deabcb1741d283a.txt @@ -0,0 +1,4 @@ +0 0.16279069767441862 0.5885416666666666 0.20348837209302326 0.15625 +0 0.6017441860465116 0.6927083333333333 0.20348837209302326 0.15625 +0 0.30523255813953487 0.3723958333333333 0.20348837209302326 0.15625 +0 0.688953488372093 0.30729166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/76aa4f48dfc92400900361b27ce458a2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/76aa4f48dfc92400900361b27ce458a2.txt new file mode 100644 index 0000000..4788665 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/76aa4f48dfc92400900361b27ce458a2.txt @@ -0,0 +1,5 @@ +0 0.7238372093023255 0.3177083333333333 0.20348837209302326 0.15625 +0 0.3866279069767442 0.16145833333333331 0.20348837209302326 0.15625 +0 0.5261627906976745 0.71875 0.20348837209302326 0.15625 +0 0.3023255813953488 0.4296875 0.20348837209302326 0.15625 +0 0.8197674418604651 0.6223958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/775446ae1ae0487f41edf9102969aede.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/775446ae1ae0487f41edf9102969aede.txt new file mode 100644 index 0000000..7884f2a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/775446ae1ae0487f41edf9102969aede.txt @@ -0,0 +1,4 @@ +0 0.3488372093023256 0.5130208333333333 0.20348837209302326 0.15625 +0 0.6308139534883721 0.15104166666666666 0.20348837209302326 0.15625 +0 0.6598837209302325 0.6145833333333333 0.20348837209302326 0.15625 +0 0.16569767441860464 0.2734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7758166810159b5fc089bb8763925d4e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7758166810159b5fc089bb8763925d4e.txt new file mode 100644 index 0000000..aa772d8 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7758166810159b5fc089bb8763925d4e.txt @@ -0,0 +1,4 @@ +0 0.5465116279069767 0.5078125 0.20348837209302326 0.15625 +0 0.2238372093023256 0.609375 0.20348837209302326 0.15625 +0 0.42441860465116277 0.19791666666666666 0.20348837209302326 0.15625 +0 0.8488372093023255 0.21354166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/77eba7306c042aa7b2693e432834a6f6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/77eba7306c042aa7b2693e432834a6f6.txt new file mode 100644 index 0000000..258abc4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/77eba7306c042aa7b2693e432834a6f6.txt @@ -0,0 +1,4 @@ +0 0.8226744186046512 0.6666666666666666 0.20348837209302326 0.15625 +0 0.44476744186046513 0.6979166666666666 0.20348837209302326 0.15625 +0 0.14825581395348836 0.22135416666666666 0.20348837209302326 0.15625 +0 0.5465116279069767 0.1875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/78365d652a587dcef8698b8b4f6aab68.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/78365d652a587dcef8698b8b4f6aab68.txt new file mode 100644 index 0000000..2d9372b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/78365d652a587dcef8698b8b4f6aab68.txt @@ -0,0 +1,4 @@ +0 0.7180232558139534 0.734375 0.20348837209302326 0.15625 +0 0.2180232558139535 0.16666666666666666 0.20348837209302326 0.15625 +0 0.688953488372093 0.4270833333333333 0.20348837209302326 0.15625 +0 0.3575581395348837 0.6302083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/789f90be8c819a3e1f7cc73ff4ee54d0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/789f90be8c819a3e1f7cc73ff4ee54d0.txt new file mode 100644 index 0000000..d0515f5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/789f90be8c819a3e1f7cc73ff4ee54d0.txt @@ -0,0 +1,4 @@ +0 0.7267441860465116 0.5052083333333333 0.20348837209302326 0.15625 +0 0.3168604651162791 0.4817708333333333 0.20348837209302326 0.15625 +0 0.3808139534883721 0.75 0.20348837209302326 0.15625 +0 0.6104651162790697 0.2552083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/78c4e10d7042750e25a0df8dab2a4f77.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/78c4e10d7042750e25a0df8dab2a4f77.txt new file mode 100644 index 0000000..3efbdf2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/78c4e10d7042750e25a0df8dab2a4f77.txt @@ -0,0 +1,4 @@ +0 0.17151162790697674 0.6145833333333333 0.20348837209302326 0.15625 +0 0.3953488372093023 0.20833333333333331 0.20348837209302326 0.15625 +0 0.47093023255813954 0.703125 0.20348837209302326 0.15625 +0 0.8401162790697674 0.44791666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/792bceff46c5343c4927e09c984c9a07.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/792bceff46c5343c4927e09c984c9a07.txt new file mode 100644 index 0000000..cb725d9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/792bceff46c5343c4927e09c984c9a07.txt @@ -0,0 +1,4 @@ +0 0.8052325581395349 0.6875 0.20348837209302326 0.15625 +0 0.3488372093023256 0.5598958333333333 0.20348837209302326 0.15625 +0 0.23546511627906977 0.1953125 0.20348837209302326 0.15625 +0 0.6453488372093024 0.2890625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/79ef570dd5d7ed7eb257f489c333ee2a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/79ef570dd5d7ed7eb257f489c333ee2a.txt new file mode 100644 index 0000000..d8cd488 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/79ef570dd5d7ed7eb257f489c333ee2a.txt @@ -0,0 +1,4 @@ +0 0.37209302325581395 0.734375 0.20348837209302326 0.15625 +0 0.45348837209302323 0.1953125 0.20348837209302326 0.15625 +0 0.7122093023255814 0.6875 0.20348837209302326 0.15625 +0 0.1686046511627907 0.5026041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7a6076274dc0ffa021d5ceed99d2705b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7a6076274dc0ffa021d5ceed99d2705b.txt new file mode 100644 index 0000000..d51c2d9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7a6076274dc0ffa021d5ceed99d2705b.txt @@ -0,0 +1,4 @@ +0 0.7383720930232558 0.14583333333333331 0.20348837209302326 0.15625 +0 0.7674418604651163 0.65625 0.20348837209302326 0.15625 +0 0.13662790697674418 0.6015625 0.20348837209302326 0.15625 +0 0.3023255813953488 0.125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7a8141295a15a0d2c16117a359d7ea87.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7a8141295a15a0d2c16117a359d7ea87.txt new file mode 100644 index 0000000..50903a6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7a8141295a15a0d2c16117a359d7ea87.txt @@ -0,0 +1,4 @@ +0 0.563953488372093 0.5078125 0.20348837209302326 0.15625 +0 0.6947674418604651 0.16145833333333331 0.20348837209302326 0.15625 +0 0.13372093023255813 0.2421875 0.20348837209302326 0.15625 +0 0.16279069767441862 0.5625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7b3eec52b87c51b8587ce68e77c65428.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7b3eec52b87c51b8587ce68e77c65428.txt new file mode 100644 index 0000000..810c5f2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7b3eec52b87c51b8587ce68e77c65428.txt @@ -0,0 +1,5 @@ +0 0.4883720930232558 0.23958333333333331 0.20348837209302326 0.15625 +0 0.6482558139534884 0.7578125 0.20348837209302326 0.15625 +0 0.3023255813953488 0.5494791666666666 0.20348837209302326 0.15625 +0 0.8255813953488372 0.14583333333333331 0.20348837209302326 0.15625 +0 0.6773255813953488 0.5286458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7b484005392e1185cd9942f0f1ee32d4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7b484005392e1185cd9942f0f1ee32d4.txt new file mode 100644 index 0000000..516f944 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7b484005392e1185cd9942f0f1ee32d4.txt @@ -0,0 +1,5 @@ +0 0.7761627906976744 0.40104166666666663 0.20348837209302326 0.15625 +0 0.37209302325581395 0.5338541666666666 0.20348837209302326 0.15625 +0 0.44476744186046513 0.15104166666666666 0.20348837209302326 0.15625 +0 0.8197674418604651 0.6848958333333333 0.20348837209302326 0.15625 +0 0.8430232558139534 0.11979166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7b816e5ef036f986eb27e74e88588e67.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7b816e5ef036f986eb27e74e88588e67.txt new file mode 100644 index 0000000..748c362 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7b816e5ef036f986eb27e74e88588e67.txt @@ -0,0 +1,4 @@ +0 0.5406976744186046 0.171875 0.20348837209302326 0.15625 +0 0.5290697674418604 0.5885416666666666 0.20348837209302326 0.15625 +0 0.1511627906976744 0.6744791666666666 0.20348837209302326 0.15625 +0 0.24127906976744184 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7baeafd04b96b5bb5f8c4905a0276f28.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7baeafd04b96b5bb5f8c4905a0276f28.txt new file mode 100644 index 0000000..af7264d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7baeafd04b96b5bb5f8c4905a0276f28.txt @@ -0,0 +1,4 @@ +0 0.3866279069767442 0.4375 0.20348837209302326 0.15625 +0 0.752906976744186 0.5078125 0.20348837209302326 0.15625 +0 0.2703488372093023 0.09635416666666666 0.20348837209302326 0.15625 +0 0.7645348837209303 0.13541666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7beb94930af6c2c3d922b6886f1785b2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7beb94930af6c2c3d922b6886f1785b2.txt new file mode 100644 index 0000000..1125968 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7beb94930af6c2c3d922b6886f1785b2.txt @@ -0,0 +1,5 @@ +0 0.23837209302325582 0.1796875 0.20348837209302326 0.15625 +0 0.7936046511627907 0.7213541666666666 0.20348837209302326 0.15625 +0 0.8197674418604651 0.4192708333333333 0.20348837209302326 0.15625 +0 0.20348837209302326 0.5026041666666666 0.20348837209302326 0.15625 +0 0.5901162790697674 0.16145833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7bf9c0312e56614367ed476ab26fdfe0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7bf9c0312e56614367ed476ab26fdfe0.txt new file mode 100644 index 0000000..f69285d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7bf9c0312e56614367ed476ab26fdfe0.txt @@ -0,0 +1,4 @@ +0 0.5436046511627907 0.5260416666666666 0.20348837209302326 0.15625 +0 0.6540697674418604 0.19010416666666666 0.20348837209302326 0.15625 +0 0.752906976744186 0.7734375 0.20348837209302326 0.15625 +0 0.1569767441860465 0.359375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c15d51dd9459b70b6986576e00a35ba.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c15d51dd9459b70b6986576e00a35ba.txt new file mode 100644 index 0000000..afd8a01 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c15d51dd9459b70b6986576e00a35ba.txt @@ -0,0 +1,5 @@ +0 0.502906976744186 0.2734375 0.20348837209302326 0.15625 +0 0.20930232558139533 0.12239583333333333 0.20348837209302326 0.15625 +0 0.7761627906976744 0.7239583333333333 0.20348837209302326 0.15625 +0 0.3226744186046512 0.5833333333333333 0.20348837209302326 0.15625 +0 0.11337209302325581 0.34375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c2f257420c98a77608f3546e2d4e42b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c2f257420c98a77608f3546e2d4e42b.txt new file mode 100644 index 0000000..36ce098 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c2f257420c98a77608f3546e2d4e42b.txt @@ -0,0 +1,4 @@ +0 0.563953488372093 0.5755208333333333 0.20348837209302326 0.15625 +0 0.4738372093023256 0.09895833333333333 0.20348837209302326 0.15625 +0 0.18604651162790697 0.2864583333333333 0.20348837209302326 0.15625 +0 0.15406976744186046 0.7630208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c4bfea85556d58cafe707b639044c21.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c4bfea85556d58cafe707b639044c21.txt new file mode 100644 index 0000000..c448ba4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c4bfea85556d58cafe707b639044c21.txt @@ -0,0 +1,4 @@ +0 0.40406976744186046 0.6979166666666666 0.20348837209302326 0.15625 +0 0.7674418604651163 0.7682291666666666 0.20348837209302326 0.15625 +0 0.15988372093023256 0.12239583333333333 0.20348837209302326 0.15625 +0 0.6627906976744186 0.12760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c726d2505d5d202db8107a3e7d214f7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c726d2505d5d202db8107a3e7d214f7.txt new file mode 100644 index 0000000..61d2de7 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c726d2505d5d202db8107a3e7d214f7.txt @@ -0,0 +1,5 @@ +0 0.2238372093023256 0.20052083333333331 0.20348837209302326 0.15625 +0 0.6162790697674418 0.6041666666666666 0.20348837209302326 0.15625 +0 0.8517441860465116 0.17447916666666666 0.20348837209302326 0.15625 +0 0.12209302325581395 0.4895833333333333 0.20348837209302326 0.15625 +0 0.5494186046511628 0.25 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c7c9a078033ab1200e8f5538da60604.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c7c9a078033ab1200e8f5538da60604.txt new file mode 100644 index 0000000..eeb8ba1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7c7c9a078033ab1200e8f5538da60604.txt @@ -0,0 +1,4 @@ +0 0.2645348837209302 0.7317708333333333 0.20348837209302326 0.15625 +0 0.3895348837209302 0.3723958333333333 0.20348837209302326 0.15625 +0 0.7296511627906976 0.5182291666666666 0.20348837209302326 0.15625 +0 0.7412790697674418 0.3046875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7cbc1e10898652b59115dddc9beec11d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7cbc1e10898652b59115dddc9beec11d.txt new file mode 100644 index 0000000..6593363 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7cbc1e10898652b59115dddc9beec11d.txt @@ -0,0 +1,5 @@ +0 0.44476744186046513 0.2890625 0.20348837209302326 0.15625 +0 0.45930232558139533 0.6744791666666666 0.20348837209302326 0.15625 +0 0.8052325581395349 0.20572916666666666 0.20348837209302326 0.15625 +0 0.7732558139534884 0.65625 0.20348837209302326 0.15625 +0 0.1308139534883721 0.16666666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7cfde6ebf9eec8a96243199d81d90978.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7cfde6ebf9eec8a96243199d81d90978.txt new file mode 100644 index 0000000..94b11c8 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7cfde6ebf9eec8a96243199d81d90978.txt @@ -0,0 +1,4 @@ +0 0.3808139534883721 0.5963541666666666 0.20348837209302326 0.15625 +0 0.8575581395348837 0.4739583333333333 0.20348837209302326 0.15625 +0 0.502906976744186 0.1328125 0.20348837209302326 0.15625 +0 0.6715116279069767 0.765625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d0702e464105b4cec37e157eb019f72.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d0702e464105b4cec37e157eb019f72.txt new file mode 100644 index 0000000..55f9982 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d0702e464105b4cec37e157eb019f72.txt @@ -0,0 +1,4 @@ +0 0.3633720930232558 0.65625 0.20348837209302326 0.15625 +0 0.27906976744186046 0.3645833333333333 0.20348837209302326 0.15625 +0 0.8284883720930233 0.6432291666666666 0.20348837209302326 0.15625 +0 0.752906976744186 0.36197916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d2b68cafe16cdd220b703eaa11c045a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d2b68cafe16cdd220b703eaa11c045a.txt new file mode 100644 index 0000000..9ea0a92 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d2b68cafe16cdd220b703eaa11c045a.txt @@ -0,0 +1,4 @@ +0 0.5377906976744186 0.10677083333333333 0.20348837209302326 0.15625 +0 0.7151162790697674 0.5182291666666666 0.20348837209302326 0.15625 +0 0.25290697674418605 0.4609375 0.20348837209302326 0.15625 +0 0.8372093023255813 0.2890625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d7ee2f85103ef65dfc74ecec42135f7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d7ee2f85103ef65dfc74ecec42135f7.txt new file mode 100644 index 0000000..a56f1e1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d7ee2f85103ef65dfc74ecec42135f7.txt @@ -0,0 +1,4 @@ +0 0.4505813953488372 0.5104166666666666 0.20348837209302326 0.15625 +0 0.4883720930232558 0.16927083333333331 0.20348837209302326 0.15625 +0 0.7645348837209303 0.5052083333333333 0.20348837209302326 0.15625 +0 0.1308139534883721 0.625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d85c83c09fa5d41f0e75e53fbb034fe.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d85c83c09fa5d41f0e75e53fbb034fe.txt new file mode 100644 index 0000000..f93e153 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d85c83c09fa5d41f0e75e53fbb034fe.txt @@ -0,0 +1,4 @@ +0 0.13662790697674418 0.14583333333333331 0.20348837209302326 0.15625 +0 0.6162790697674418 0.375 0.20348837209302326 0.15625 +0 0.18313953488372092 0.7317708333333333 0.20348837209302326 0.15625 +0 0.8023255813953488 0.65625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d9097329ae92c57796325322a926af8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d9097329ae92c57796325322a926af8.txt new file mode 100644 index 0000000..986476f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7d9097329ae92c57796325322a926af8.txt @@ -0,0 +1,4 @@ +0 0.6918604651162791 0.3567708333333333 0.20348837209302326 0.15625 +0 0.12790697674418605 0.4739583333333333 0.20348837209302326 0.15625 +0 0.34011627906976744 0.10677083333333333 0.20348837209302326 0.15625 +0 0.6686046511627907 0.6171875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e119a08bbd67f2a15cd2b58d30cb9f1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e119a08bbd67f2a15cd2b58d30cb9f1.txt new file mode 100644 index 0000000..1b29039 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e119a08bbd67f2a15cd2b58d30cb9f1.txt @@ -0,0 +1,3 @@ +0 0.5174418604651163 0.375 0.20348837209302326 0.15625 +0 0.29069767441860467 0.6171875 0.20348837209302326 0.15625 +0 0.6162790697674418 0.6614583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e60fd470b78624fc0575ba9754e3c45.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e60fd470b78624fc0575ba9754e3c45.txt new file mode 100644 index 0000000..5ea9026 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e60fd470b78624fc0575ba9754e3c45.txt @@ -0,0 +1,3 @@ +0 0.48546511627906974 0.453125 0.20348837209302326 0.15625 +0 0.43023255813953487 0.109375 0.20348837209302326 0.15625 +0 0.8546511627906976 0.6953125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e893ae3a6c6e47235b86f85d8e56bc3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e893ae3a6c6e47235b86f85d8e56bc3.txt new file mode 100644 index 0000000..b53f13a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e893ae3a6c6e47235b86f85d8e56bc3.txt @@ -0,0 +1,4 @@ +0 0.4796511627906977 0.7161458333333333 0.20348837209302326 0.15625 +0 0.29941860465116277 0.36197916666666663 0.20348837209302326 0.15625 +0 0.8284883720930233 0.7630208333333333 0.20348837209302326 0.15625 +0 0.15988372093023256 0.671875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e8e2b60ce201607bb7016d56d1fb4f8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e8e2b60ce201607bb7016d56d1fb4f8.txt new file mode 100644 index 0000000..04867c2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e8e2b60ce201607bb7016d56d1fb4f8.txt @@ -0,0 +1,5 @@ +0 0.313953488372093 0.7447916666666666 0.20348837209302326 0.15625 +0 0.5406976744186046 0.47135416666666663 0.20348837209302326 0.15625 +0 0.21220930232558138 0.44791666666666663 0.20348837209302326 0.15625 +0 0.4331395348837209 0.109375 0.20348837209302326 0.15625 +0 0.11627906976744186 0.15104166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e9a0961535e3804022f1ee6d5e2a436.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e9a0961535e3804022f1ee6d5e2a436.txt new file mode 100644 index 0000000..0baeb88 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7e9a0961535e3804022f1ee6d5e2a436.txt @@ -0,0 +1,4 @@ +0 0.19186046511627908 0.44010416666666663 0.20348837209302326 0.15625 +0 0.5988372093023255 0.5859375 0.20348837209302326 0.15625 +0 0.4825581395348837 0.21875 0.20348837209302326 0.15625 +0 0.12790697674418605 0.7890625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7ea6b24a19e30ea712147ea82ca375f9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7ea6b24a19e30ea712147ea82ca375f9.txt new file mode 100644 index 0000000..e2ab78f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7ea6b24a19e30ea712147ea82ca375f9.txt @@ -0,0 +1,4 @@ +0 0.1744186046511628 0.34375 0.20348837209302326 0.15625 +0 0.6075581395348837 0.5625 0.20348837209302326 0.15625 +0 0.5959302325581395 0.23697916666666666 0.20348837209302326 0.15625 +0 0.14825581395348836 0.5989583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7eab038fb6a9b2a516fa43d19c3e114f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7eab038fb6a9b2a516fa43d19c3e114f.txt new file mode 100644 index 0000000..5615cf2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7eab038fb6a9b2a516fa43d19c3e114f.txt @@ -0,0 +1,4 @@ +0 0.12790697674418605 0.08854166666666666 0.20348837209302326 0.15625 +0 0.11627906976744186 0.6015625 0.20348837209302326 0.15625 +0 0.7645348837209303 0.18489583333333331 0.20348837209302326 0.15625 +0 0.8604651162790697 0.7734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7ee89ab02954a8b62efb3b8ab560a603.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7ee89ab02954a8b62efb3b8ab560a603.txt new file mode 100644 index 0000000..94d5e65 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7ee89ab02954a8b62efb3b8ab560a603.txt @@ -0,0 +1,5 @@ +0 0.6831395348837209 0.7239583333333333 0.20348837209302326 0.15625 +0 0.42441860465116277 0.1328125 0.20348837209302326 0.15625 +0 0.7936046511627907 0.4661458333333333 0.20348837209302326 0.15625 +0 0.3546511627906977 0.7005208333333333 0.20348837209302326 0.15625 +0 0.11627906976744186 0.125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7f0d0c08702801cb4c2c36d71e494ee2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7f0d0c08702801cb4c2c36d71e494ee2.txt new file mode 100644 index 0000000..36da9cc --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7f0d0c08702801cb4c2c36d71e494ee2.txt @@ -0,0 +1,4 @@ +0 0.5523255813953488 0.6354166666666666 0.20348837209302326 0.15625 +0 0.2180232558139535 0.4895833333333333 0.20348837209302326 0.15625 +0 0.622093023255814 0.265625 0.20348837209302326 0.15625 +0 0.18604651162790697 0.7864583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7f950692da36b446ee8e3bfb9b7bf34c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7f950692da36b446ee8e3bfb9b7bf34c.txt new file mode 100644 index 0000000..41a8364 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7f950692da36b446ee8e3bfb9b7bf34c.txt @@ -0,0 +1,4 @@ +0 0.35174418604651164 0.390625 0.20348837209302326 0.15625 +0 0.1947674418604651 0.6276041666666666 0.20348837209302326 0.15625 +0 0.3168604651162791 0.15885416666666666 0.20348837209302326 0.15625 +0 0.7383720930232558 0.6770833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7fc6c0a4d7fc53ecda70eb3ff5d655a8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7fc6c0a4d7fc53ecda70eb3ff5d655a8.txt new file mode 100644 index 0000000..8905465 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/7fc6c0a4d7fc53ecda70eb3ff5d655a8.txt @@ -0,0 +1,4 @@ +0 0.16279069767441862 0.234375 0.20348837209302326 0.15625 +0 0.6947674418604651 0.46354166666666663 0.20348837209302326 0.15625 +0 0.3895348837209302 0.46354166666666663 0.20348837209302326 0.15625 +0 0.7180232558139534 0.12239583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/807a237f14859821ced70c98a08ba231.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/807a237f14859821ced70c98a08ba231.txt new file mode 100644 index 0000000..76cd402 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/807a237f14859821ced70c98a08ba231.txt @@ -0,0 +1,4 @@ +0 0.7093023255813954 0.26041666666666663 0.20348837209302326 0.15625 +0 0.25 0.5416666666666666 0.20348837209302326 0.15625 +0 0.36046511627906974 0.7708333333333333 0.20348837209302326 0.15625 +0 0.311046511627907 0.19791666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/80d888e66f661473ce0a4583cb0c3e97.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/80d888e66f661473ce0a4583cb0c3e97.txt new file mode 100644 index 0000000..e3902da --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/80d888e66f661473ce0a4583cb0c3e97.txt @@ -0,0 +1,5 @@ +0 0.12209302325581395 0.19010416666666666 0.20348837209302326 0.15625 +0 0.7877906976744186 0.7057291666666666 0.20348837209302326 0.15625 +0 0.7645348837209303 0.4375 0.20348837209302326 0.15625 +0 0.6831395348837209 0.15885416666666666 0.20348837209302326 0.15625 +0 0.12209302325581395 0.41666666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/814613e0ac5d67cd9f9fdce55c8ec0d4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/814613e0ac5d67cd9f9fdce55c8ec0d4.txt new file mode 100644 index 0000000..89f19e0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/814613e0ac5d67cd9f9fdce55c8ec0d4.txt @@ -0,0 +1,5 @@ +0 0.6104651162790697 0.703125 0.20348837209302326 0.15625 +0 0.5058139534883721 0.34635416666666663 0.20348837209302326 0.15625 +0 0.31976744186046513 0.6041666666666666 0.20348837209302326 0.15625 +0 0.13953488372093023 0.20052083333333331 0.20348837209302326 0.15625 +0 0.8284883720930233 0.5 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/816ab02d5092e43d35754dd87997967b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/816ab02d5092e43d35754dd87997967b.txt new file mode 100644 index 0000000..1dfb8b1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/816ab02d5092e43d35754dd87997967b.txt @@ -0,0 +1,4 @@ +0 0.7936046511627907 0.59375 0.20348837209302326 0.15625 +0 0.5959302325581395 0.15885416666666666 0.20348837209302326 0.15625 +0 0.1511627906976744 0.3645833333333333 0.20348837209302326 0.15625 +0 0.34011627906976744 0.6197916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/816ba6108358498c381c6a697b15fe99.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/816ba6108358498c381c6a697b15fe99.txt new file mode 100644 index 0000000..e03ad0b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/816ba6108358498c381c6a697b15fe99.txt @@ -0,0 +1,5 @@ +0 0.7441860465116279 0.6484375 0.20348837209302326 0.15625 +0 0.5116279069767442 0.140625 0.20348837209302326 0.15625 +0 0.1569767441860465 0.4895833333333333 0.20348837209302326 0.15625 +0 0.8284883720930233 0.33854166666666663 0.20348837209302326 0.15625 +0 0.14825581395348836 0.17708333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/819b61a21f99e6ddb7b249e1468e2c7c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/819b61a21f99e6ddb7b249e1468e2c7c.txt new file mode 100644 index 0000000..20a5093 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/819b61a21f99e6ddb7b249e1468e2c7c.txt @@ -0,0 +1,4 @@ +0 0.4622093023255814 0.10416666666666666 0.20348837209302326 0.15625 +0 0.36627906976744184 0.5729166666666666 0.20348837209302326 0.15625 +0 0.8168604651162791 0.16666666666666666 0.20348837209302326 0.15625 +0 0.1569767441860465 0.1796875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/819fb3068bf1dbbc6c9b62d9a6802700.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/819fb3068bf1dbbc6c9b62d9a6802700.txt new file mode 100644 index 0000000..0a0d50f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/819fb3068bf1dbbc6c9b62d9a6802700.txt @@ -0,0 +1,4 @@ +0 0.7093023255813954 0.21614583333333331 0.20348837209302326 0.15625 +0 0.2238372093023256 0.7421875 0.20348837209302326 0.15625 +0 0.6715116279069767 0.5182291666666666 0.20348837209302326 0.15625 +0 0.2877906976744186 0.265625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/82531ad88eac23be3c89801a6be66fdc.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/82531ad88eac23be3c89801a6be66fdc.txt new file mode 100644 index 0000000..38355e5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/82531ad88eac23be3c89801a6be66fdc.txt @@ -0,0 +1,4 @@ +0 0.625 0.4661458333333333 0.20348837209302326 0.15625 +0 0.21511627906976744 0.5390625 0.20348837209302326 0.15625 +0 0.8284883720930233 0.1015625 0.20348837209302326 0.15625 +0 0.26744186046511625 0.09375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/829540032c7152c607fd4a1d16ae497a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/829540032c7152c607fd4a1d16ae497a.txt new file mode 100644 index 0000000..7573482 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/829540032c7152c607fd4a1d16ae497a.txt @@ -0,0 +1,3 @@ +0 0.47093023255813954 0.578125 0.20348837209302326 0.15625 +0 0.15988372093023256 0.40885416666666663 0.20348837209302326 0.15625 +0 0.7994186046511628 0.7760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/83626424d2bc3065e66eb4fb0298b60a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/83626424d2bc3065e66eb4fb0298b60a.txt new file mode 100644 index 0000000..1875f49 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/83626424d2bc3065e66eb4fb0298b60a.txt @@ -0,0 +1,5 @@ +0 0.48546511627906974 0.4036458333333333 0.20348837209302326 0.15625 +0 0.18313953488372092 0.390625 0.20348837209302326 0.15625 +0 0.8226744186046512 0.6979166666666666 0.20348837209302326 0.15625 +0 0.8575581395348837 0.4296875 0.20348837209302326 0.15625 +0 0.15988372093023256 0.6848958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/841b6aedaab5148e1fa1f00a3ef6d760.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/841b6aedaab5148e1fa1f00a3ef6d760.txt new file mode 100644 index 0000000..0be05c6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/841b6aedaab5148e1fa1f00a3ef6d760.txt @@ -0,0 +1,4 @@ +0 0.8488372093023255 0.21354166666666666 0.20348837209302326 0.15625 +0 0.22965116279069767 0.5546875 0.20348837209302326 0.15625 +0 0.688953488372093 0.6223958333333333 0.20348837209302326 0.15625 +0 0.3488372093023256 0.3046875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8431ae708a8ea4a39780a61a3d1920f3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8431ae708a8ea4a39780a61a3d1920f3.txt new file mode 100644 index 0000000..ccc9fe8 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8431ae708a8ea4a39780a61a3d1920f3.txt @@ -0,0 +1,5 @@ +0 0.15988372093023256 0.4140625 0.20348837209302326 0.15625 +0 0.7994186046511628 0.5598958333333333 0.20348837209302326 0.15625 +0 0.7238372093023255 0.33072916666666663 0.20348837209302326 0.15625 +0 0.2005813953488372 0.16666666666666666 0.20348837209302326 0.15625 +0 0.25290697674418605 0.7552083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/844360515e72f5309e4646d0c2fd1af3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/844360515e72f5309e4646d0c2fd1af3.txt new file mode 100644 index 0000000..963e75c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/844360515e72f5309e4646d0c2fd1af3.txt @@ -0,0 +1,3 @@ +0 0.375 0.2578125 0.20348837209302326 0.15625 +0 0.4680232558139535 0.7447916666666666 0.20348837209302326 0.15625 +0 0.7587209302325582 0.2734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/84563c5fe1937ff4e3c443c387be2519.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/84563c5fe1937ff4e3c443c387be2519.txt new file mode 100644 index 0000000..8ec3756 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/84563c5fe1937ff4e3c443c387be2519.txt @@ -0,0 +1,3 @@ +0 0.7296511627906976 0.359375 0.20348837209302326 0.15625 +0 0.34011627906976744 0.44791666666666663 0.20348837209302326 0.15625 +0 0.7325581395348837 0.09895833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8461e90ae88f7ffd7221df75ff3632e1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8461e90ae88f7ffd7221df75ff3632e1.txt new file mode 100644 index 0000000..d459814 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8461e90ae88f7ffd7221df75ff3632e1.txt @@ -0,0 +1,3 @@ +0 0.6569767441860465 0.6015625 0.20348837209302326 0.15625 +0 0.2877906976744186 0.359375 0.20348837209302326 0.15625 +0 0.34011627906976744 0.6510416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8525ea80a0ddcfabc3d5d2a2d1f7f4fe.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8525ea80a0ddcfabc3d5d2a2d1f7f4fe.txt new file mode 100644 index 0000000..2e13909 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8525ea80a0ddcfabc3d5d2a2d1f7f4fe.txt @@ -0,0 +1,4 @@ +0 0.8081395348837209 0.3333333333333333 0.20348837209302326 0.15625 +0 0.19767441860465115 0.3125 0.20348837209302326 0.15625 +0 0.752906976744186 0.75 0.20348837209302326 0.15625 +0 0.15988372093023256 0.7473958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8546938654dcc948343c8887bdae97f6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8546938654dcc948343c8887bdae97f6.txt new file mode 100644 index 0000000..3e6577e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8546938654dcc948343c8887bdae97f6.txt @@ -0,0 +1,4 @@ +0 0.7732558139534884 0.7630208333333333 0.20348837209302326 0.15625 +0 0.3430232558139535 0.23958333333333331 0.20348837209302326 0.15625 +0 0.39825581395348836 0.5833333333333333 0.20348837209302326 0.15625 +0 0.7703488372093024 0.19791666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/855b46a37a8e7a2981b0214bbcbb26d6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/855b46a37a8e7a2981b0214bbcbb26d6.txt new file mode 100644 index 0000000..9c8c38a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/855b46a37a8e7a2981b0214bbcbb26d6.txt @@ -0,0 +1,3 @@ +0 0.31976744186046513 0.6145833333333333 0.20348837209302326 0.15625 +0 0.7122093023255814 0.7473958333333333 0.20348837209302326 0.15625 +0 0.23255813953488372 0.1328125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/85a622ab119518199a9fbcad4b85849a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/85a622ab119518199a9fbcad4b85849a.txt new file mode 100644 index 0000000..9a39f61 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/85a622ab119518199a9fbcad4b85849a.txt @@ -0,0 +1,3 @@ +0 0.8197674418604651 0.3984375 0.20348837209302326 0.15625 +0 0.7790697674418604 0.10677083333333333 0.20348837209302326 0.15625 +0 0.27906976744186046 0.17447916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/85a87be26b73191ae881543d8f5bd12c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/85a87be26b73191ae881543d8f5bd12c.txt new file mode 100644 index 0000000..672002e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/85a87be26b73191ae881543d8f5bd12c.txt @@ -0,0 +1,4 @@ +0 0.313953488372093 0.5052083333333333 0.20348837209302326 0.15625 +0 0.3633720930232558 0.16145833333333331 0.20348837209302326 0.15625 +0 0.8372093023255813 0.4921875 0.20348837209302326 0.15625 +0 0.6337209302325582 0.7864583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/85dfaadf855933693738def81442c090.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/85dfaadf855933693738def81442c090.txt new file mode 100644 index 0000000..a42c065 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/85dfaadf855933693738def81442c090.txt @@ -0,0 +1,5 @@ +0 0.8168604651162791 0.4348958333333333 0.20348837209302326 0.15625 +0 0.4825581395348837 0.5390625 0.20348837209302326 0.15625 +0 0.4331395348837209 0.2630208333333333 0.20348837209302326 0.15625 +0 0.14534883720930233 0.5807291666666666 0.20348837209302326 0.15625 +0 0.8255813953488372 0.7942708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8666d150ab4b46ade2ed09fd5948f624.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8666d150ab4b46ade2ed09fd5948f624.txt new file mode 100644 index 0000000..0ad58e8 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8666d150ab4b46ade2ed09fd5948f624.txt @@ -0,0 +1,5 @@ +0 0.622093023255814 0.4270833333333333 0.20348837209302326 0.15625 +0 0.46511627906976744 0.14322916666666666 0.20348837209302326 0.15625 +0 0.16279069767441862 0.5963541666666666 0.20348837209302326 0.15625 +0 0.7441860465116279 0.7005208333333333 0.20348837209302326 0.15625 +0 0.15988372093023256 0.171875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8676e9276e7ad1e688eb7fcc2bfc48b7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8676e9276e7ad1e688eb7fcc2bfc48b7.txt new file mode 100644 index 0000000..ca79a9b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8676e9276e7ad1e688eb7fcc2bfc48b7.txt @@ -0,0 +1,4 @@ +0 0.8575581395348837 0.39322916666666663 0.20348837209302326 0.15625 +0 0.2877906976744186 0.45572916666666663 0.20348837209302326 0.15625 +0 0.8372093023255813 0.7526041666666666 0.20348837209302326 0.15625 +0 0.34011627906976744 0.11197916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/86973ee052966ffce0ccf1a0a324585a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/86973ee052966ffce0ccf1a0a324585a.txt new file mode 100644 index 0000000..4306874 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/86973ee052966ffce0ccf1a0a324585a.txt @@ -0,0 +1,5 @@ +0 0.563953488372093 0.2890625 0.20348837209302326 0.15625 +0 0.7063953488372093 0.640625 0.20348837209302326 0.15625 +0 0.2761627906976744 0.7395833333333333 0.20348837209302326 0.15625 +0 0.17151162790697674 0.21875 0.20348837209302326 0.15625 +0 0.24127906976744184 0.4765625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/86a9f4a069ab2fd1fc70a67556d28e50.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/86a9f4a069ab2fd1fc70a67556d28e50.txt new file mode 100644 index 0000000..74a6f8a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/86a9f4a069ab2fd1fc70a67556d28e50.txt @@ -0,0 +1,4 @@ +0 0.3546511627906977 0.5052083333333333 0.20348837209302326 0.15625 +0 0.625 0.15364583333333331 0.20348837209302326 0.15625 +0 0.6715116279069767 0.6354166666666666 0.20348837209302326 0.15625 +0 0.24709302325581395 0.25260416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/86cabdc3564921a02ea6c430ffcb3e61.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/86cabdc3564921a02ea6c430ffcb3e61.txt new file mode 100644 index 0000000..291c621 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/86cabdc3564921a02ea6c430ffcb3e61.txt @@ -0,0 +1,5 @@ +0 0.6773255813953488 0.6223958333333333 0.20348837209302326 0.15625 +0 0.39244186046511625 0.171875 0.20348837209302326 0.15625 +0 0.2063953488372093 0.4739583333333333 0.20348837209302326 0.15625 +0 0.811046511627907 0.125 0.20348837209302326 0.15625 +0 0.8197674418604651 0.40104166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/86cbadafab7cc34a9b23181507d720eb.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/86cbadafab7cc34a9b23181507d720eb.txt new file mode 100644 index 0000000..6ef0a14 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/86cbadafab7cc34a9b23181507d720eb.txt @@ -0,0 +1,5 @@ +0 0.46511627906976744 0.4505208333333333 0.20348837209302326 0.15625 +0 0.6802325581395349 0.14583333333333331 0.20348837209302326 0.15625 +0 0.25 0.7421875 0.20348837209302326 0.15625 +0 0.75 0.4036458333333333 0.20348837209302326 0.15625 +0 0.5465116279069767 0.7682291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/870780cca5d71b362695166e90e0fa29.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/870780cca5d71b362695166e90e0fa29.txt new file mode 100644 index 0000000..b19e722 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/870780cca5d71b362695166e90e0fa29.txt @@ -0,0 +1,5 @@ +0 0.7790697674418604 0.4427083333333333 0.20348837209302326 0.15625 +0 0.15406976744186046 0.703125 0.20348837209302326 0.15625 +0 0.561046511627907 0.6692708333333333 0.20348837209302326 0.15625 +0 0.8197674418604651 0.1953125 0.20348837209302326 0.15625 +0 0.3866279069767442 0.3802083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/87230572cabd7f7cc731ddbd5f05cc19.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/87230572cabd7f7cc731ddbd5f05cc19.txt new file mode 100644 index 0000000..eff316e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/87230572cabd7f7cc731ddbd5f05cc19.txt @@ -0,0 +1,5 @@ +0 0.7180232558139534 0.7421875 0.20348837209302326 0.15625 +0 0.21220930232558138 0.7421875 0.20348837209302326 0.15625 +0 0.14534883720930233 0.27604166666666663 0.20348837209302326 0.15625 +0 0.6453488372093024 0.3177083333333333 0.20348837209302326 0.15625 +0 0.3546511627906977 0.5130208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8736405022503e64c12ebd5e5c8f1b03.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8736405022503e64c12ebd5e5c8f1b03.txt new file mode 100644 index 0000000..2181e05 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8736405022503e64c12ebd5e5c8f1b03.txt @@ -0,0 +1,3 @@ +0 0.1308139534883721 0.44791666666666663 0.20348837209302326 0.15625 +0 0.7558139534883721 0.13802083333333331 0.20348837209302326 0.15625 +0 0.5872093023255814 0.6171875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/874c14f81060497417ac949eaf19794f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/874c14f81060497417ac949eaf19794f.txt new file mode 100644 index 0000000..4e4f63a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/874c14f81060497417ac949eaf19794f.txt @@ -0,0 +1,4 @@ +0 0.2819767441860465 0.734375 0.20348837209302326 0.15625 +0 0.8459302325581395 0.125 0.20348837209302326 0.15625 +0 0.5 0.3567708333333333 0.20348837209302326 0.15625 +0 0.7965116279069767 0.8046875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/875c4a110234095486828834b0203b33.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/875c4a110234095486828834b0203b33.txt new file mode 100644 index 0000000..54f4d53 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/875c4a110234095486828834b0203b33.txt @@ -0,0 +1,3 @@ +0 0.2965116279069767 0.33854166666666663 0.20348837209302326 0.15625 +0 0.6947674418604651 0.140625 0.20348837209302326 0.15625 +0 0.7209302325581395 0.37760416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/875f2eb24f01a380e58f4a3f89115468.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/875f2eb24f01a380e58f4a3f89115468.txt new file mode 100644 index 0000000..998cd36 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/875f2eb24f01a380e58f4a3f89115468.txt @@ -0,0 +1,4 @@ +0 0.8081395348837209 0.44010416666666663 0.20348837209302326 0.15625 +0 0.8488372093023255 0.7291666666666666 0.20348837209302326 0.15625 +0 0.4505813953488372 0.09895833333333333 0.20348837209302326 0.15625 +0 0.752906976744186 0.19270833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/878ce89141988cae8a469ef16c04aa0f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/878ce89141988cae8a469ef16c04aa0f.txt new file mode 100644 index 0000000..a2f85bf --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/878ce89141988cae8a469ef16c04aa0f.txt @@ -0,0 +1,5 @@ +0 0.34011627906976744 0.15885416666666666 0.20348837209302326 0.15625 +0 0.3691860465116279 0.40625 0.20348837209302326 0.15625 +0 0.6308139534883721 0.7708333333333333 0.20348837209302326 0.15625 +0 0.6686046511627907 0.20052083333333331 0.20348837209302326 0.15625 +0 0.34011627906976744 0.6744791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/880d7342370f7a03b57e9b3b52b3f74f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/880d7342370f7a03b57e9b3b52b3f74f.txt new file mode 100644 index 0000000..7cc7114 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/880d7342370f7a03b57e9b3b52b3f74f.txt @@ -0,0 +1,5 @@ +0 0.5494186046511628 0.2890625 0.20348837209302326 0.15625 +0 0.4011627906976744 0.7005208333333333 0.20348837209302326 0.15625 +0 0.2441860465116279 0.3125 0.20348837209302326 0.15625 +0 0.8546511627906976 0.6640625 0.20348837209302326 0.15625 +0 0.12209302325581395 0.5546875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/885a0329f7b7e835c42f60476d4d8f10.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/885a0329f7b7e835c42f60476d4d8f10.txt new file mode 100644 index 0000000..5601412 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/885a0329f7b7e835c42f60476d4d8f10.txt @@ -0,0 +1,4 @@ +0 0.8459302325581395 0.25260416666666663 0.20348837209302326 0.15625 +0 0.8226744186046512 0.5885416666666666 0.20348837209302326 0.15625 +0 0.21220930232558138 0.7630208333333333 0.20348837209302326 0.15625 +0 0.4738372093023256 0.08333333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/886ccb8a6bbcda450f889ab0f690c1c2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/886ccb8a6bbcda450f889ab0f690c1c2.txt new file mode 100644 index 0000000..546d93f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/886ccb8a6bbcda450f889ab0f690c1c2.txt @@ -0,0 +1,4 @@ +0 0.19186046511627908 0.6770833333333333 0.20348837209302326 0.15625 +0 0.5697674418604651 0.6432291666666666 0.20348837209302326 0.15625 +0 0.8372093023255813 0.17708333333333331 0.20348837209302326 0.15625 +0 0.5174418604651163 0.17708333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8888f6cdc1120161964a6200de3c6809.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8888f6cdc1120161964a6200de3c6809.txt new file mode 100644 index 0000000..7cef850 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8888f6cdc1120161964a6200de3c6809.txt @@ -0,0 +1,4 @@ +0 0.7732558139534884 0.15625 0.20348837209302326 0.15625 +0 0.41860465116279066 0.39322916666666663 0.20348837209302326 0.15625 +0 0.3808139534883721 0.11979166666666666 0.20348837209302326 0.15625 +0 0.7674418604651163 0.3880208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/88ce36b0ccc7e1820c4c17c580d352ff.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/88ce36b0ccc7e1820c4c17c580d352ff.txt new file mode 100644 index 0000000..0679dd5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/88ce36b0ccc7e1820c4c17c580d352ff.txt @@ -0,0 +1,4 @@ +0 0.4563953488372093 0.43229166666666663 0.20348837209302326 0.15625 +0 0.14825581395348836 0.44010416666666663 0.20348837209302326 0.15625 +0 0.7441860465116279 0.18229166666666666 0.20348837209302326 0.15625 +0 0.6598837209302325 0.6432291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89033239c7d547e5aa8410e09011134c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89033239c7d547e5aa8410e09011134c.txt new file mode 100644 index 0000000..2624395 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89033239c7d547e5aa8410e09011134c.txt @@ -0,0 +1,4 @@ +0 0.4331395348837209 0.14322916666666666 0.20348837209302326 0.15625 +0 0.3488372093023256 0.47135416666666663 0.20348837209302326 0.15625 +0 0.7994186046511628 0.17708333333333331 0.20348837209302326 0.15625 +0 0.8343023255813954 0.6067708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/890902ded3e227cf4a3f724aedd7aad5.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/890902ded3e227cf4a3f724aedd7aad5.txt new file mode 100644 index 0000000..c629b0c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/890902ded3e227cf4a3f724aedd7aad5.txt @@ -0,0 +1,2 @@ +0 0.6627906976744186 0.5546875 0.20348837209302326 0.15625 +0 0.23255813953488372 0.7552083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/891d42e635294e5cad8dc8d008337db3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/891d42e635294e5cad8dc8d008337db3.txt new file mode 100644 index 0000000..d346bef --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/891d42e635294e5cad8dc8d008337db3.txt @@ -0,0 +1,4 @@ +0 0.24709302325581395 0.32291666666666663 0.20348837209302326 0.15625 +0 0.5872093023255814 0.4817708333333333 0.20348837209302326 0.15625 +0 0.6453488372093024 0.7213541666666666 0.20348837209302326 0.15625 +0 0.2180232558139535 0.5833333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/891dbbbed3c2d0c197f71b0656f186c7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/891dbbbed3c2d0c197f71b0656f186c7.txt new file mode 100644 index 0000000..adff30e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/891dbbbed3c2d0c197f71b0656f186c7.txt @@ -0,0 +1,4 @@ +0 0.2761627906976744 0.265625 0.20348837209302326 0.15625 +0 0.6802325581395349 0.6848958333333333 0.20348837209302326 0.15625 +0 0.2238372093023256 0.7369791666666666 0.20348837209302326 0.15625 +0 0.8372093023255813 0.4296875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89276d62d6f90ddfe13e8245115c7faa.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89276d62d6f90ddfe13e8245115c7faa.txt new file mode 100644 index 0000000..12a6ec1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89276d62d6f90ddfe13e8245115c7faa.txt @@ -0,0 +1,4 @@ +0 0.39825581395348836 0.796875 0.20348837209302326 0.15625 +0 0.47674418604651164 0.15885416666666666 0.20348837209302326 0.15625 +0 0.7936046511627907 0.40885416666666663 0.20348837209302326 0.15625 +0 0.22965116279069767 0.5208333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89a952ae9456c577b25ab8ce86f9b127.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89a952ae9456c577b25ab8ce86f9b127.txt new file mode 100644 index 0000000..e4c8b6f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89a952ae9456c577b25ab8ce86f9b127.txt @@ -0,0 +1,4 @@ +0 0.563953488372093 0.2864583333333333 0.20348837209302326 0.15625 +0 0.2877906976744186 0.7265625 0.20348837209302326 0.15625 +0 0.8546511627906976 0.7265625 0.20348837209302326 0.15625 +0 0.24709302325581395 0.2864583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89d595f80f108db3dd567a0467c3d88c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89d595f80f108db3dd567a0467c3d88c.txt new file mode 100644 index 0000000..29d282f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89d595f80f108db3dd567a0467c3d88c.txt @@ -0,0 +1,4 @@ +0 0.5872093023255814 0.6979166666666666 0.20348837209302326 0.15625 +0 0.20930232558139533 0.234375 0.20348837209302326 0.15625 +0 0.688953488372093 0.3359375 0.20348837209302326 0.15625 +0 0.2936046511627907 0.578125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89f5de3b9ca0a34a978ca34ec7d87984.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89f5de3b9ca0a34a978ca34ec7d87984.txt new file mode 100644 index 0000000..02e1bdc --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/89f5de3b9ca0a34a978ca34ec7d87984.txt @@ -0,0 +1,3 @@ +0 0.5843023255813954 0.53125 0.20348837209302326 0.15625 +0 0.7063953488372093 0.14322916666666666 0.20348837209302326 0.15625 +0 0.13953488372093023 0.4739583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8a4f82bedea3fbb3acc230df7db97a45.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8a4f82bedea3fbb3acc230df7db97a45.txt new file mode 100644 index 0000000..7576672 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8a4f82bedea3fbb3acc230df7db97a45.txt @@ -0,0 +1,4 @@ +0 0.23255813953488372 0.6875 0.20348837209302326 0.15625 +0 0.34593023255813954 0.171875 0.20348837209302326 0.15625 +0 0.7063953488372093 0.515625 0.20348837209302326 0.15625 +0 0.2005813953488372 0.4036458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8a9a7b77de49a07e58174c8c323840fe.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8a9a7b77de49a07e58174c8c323840fe.txt new file mode 100644 index 0000000..1d80f16 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8a9a7b77de49a07e58174c8c323840fe.txt @@ -0,0 +1,4 @@ +0 0.44476744186046513 0.5885416666666666 0.20348837209302326 0.15625 +0 0.5436046511627907 0.19791666666666666 0.20348837209302326 0.15625 +0 0.21511627906976744 0.171875 0.20348837209302326 0.15625 +0 0.8430232558139534 0.7421875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8ad2c75e04c0a31b6efc9c4c73cce91e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8ad2c75e04c0a31b6efc9c4c73cce91e.txt new file mode 100644 index 0000000..8a94c63 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8ad2c75e04c0a31b6efc9c4c73cce91e.txt @@ -0,0 +1,3 @@ +0 0.2645348837209302 0.671875 0.20348837209302326 0.15625 +0 0.75 0.4296875 0.20348837209302326 0.15625 +0 0.5697674418604651 0.6796875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8ad723cb07f038c69451b25205c9cc81.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8ad723cb07f038c69451b25205c9cc81.txt new file mode 100644 index 0000000..e2e37c4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8ad723cb07f038c69451b25205c9cc81.txt @@ -0,0 +1,5 @@ +0 0.4476744186046512 0.6197916666666666 0.20348837209302326 0.15625 +0 0.3488372093023256 0.1953125 0.20348837209302326 0.15625 +0 0.8662790697674418 0.5104166666666666 0.20348837209302326 0.15625 +0 0.6947674418604651 0.2864583333333333 0.20348837209302326 0.15625 +0 0.1511627906976744 0.6953125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8b0ebee39a1bab46c59e9d64f9070352.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8b0ebee39a1bab46c59e9d64f9070352.txt new file mode 100644 index 0000000..4d18701 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8b0ebee39a1bab46c59e9d64f9070352.txt @@ -0,0 +1,3 @@ +0 0.6395348837209303 0.7005208333333333 0.20348837209302326 0.15625 +0 0.27906976744186046 0.5546875 0.20348837209302326 0.15625 +0 0.7209302325581395 0.09114583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8bdcd29e44362431dcc99d3408686f24.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8bdcd29e44362431dcc99d3408686f24.txt new file mode 100644 index 0000000..032c549 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8bdcd29e44362431dcc99d3408686f24.txt @@ -0,0 +1,4 @@ +0 0.747093023255814 0.421875 0.20348837209302326 0.15625 +0 0.7093023255813954 0.6927083333333333 0.20348837209302326 0.15625 +0 0.39825581395348836 0.28385416666666663 0.20348837209302326 0.15625 +0 0.3808139534883721 0.5390625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8c46a9c71bfe05333f8722f1daffd655.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8c46a9c71bfe05333f8722f1daffd655.txt new file mode 100644 index 0000000..d10e60a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8c46a9c71bfe05333f8722f1daffd655.txt @@ -0,0 +1,4 @@ +0 0.5377906976744186 0.5052083333333333 0.20348837209302326 0.15625 +0 0.7819767441860465 0.140625 0.20348837209302326 0.15625 +0 0.11337209302325581 0.3567708333333333 0.20348837209302326 0.15625 +0 0.4738372093023256 0.7369791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8c5f4578d3c3aba5d3ff56bc85d5fd7d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8c5f4578d3c3aba5d3ff56bc85d5fd7d.txt new file mode 100644 index 0000000..b10fc8a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8c5f4578d3c3aba5d3ff56bc85d5fd7d.txt @@ -0,0 +1,5 @@ +0 0.7616279069767442 0.5494791666666666 0.20348837209302326 0.15625 +0 0.4476744186046512 0.5807291666666666 0.20348837209302326 0.15625 +0 0.6802325581395349 0.18229166666666666 0.20348837209302326 0.15625 +0 0.3546511627906977 0.09375 0.20348837209302326 0.15625 +0 0.34593023255813954 0.359375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8ce0eaa8ced7a0fedc8ba3f7c617afd9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8ce0eaa8ced7a0fedc8ba3f7c617afd9.txt new file mode 100644 index 0000000..2bfa8c7 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8ce0eaa8ced7a0fedc8ba3f7c617afd9.txt @@ -0,0 +1,5 @@ +0 0.16279069767441862 0.234375 0.20348837209302326 0.15625 +0 0.5843023255813954 0.11197916666666666 0.20348837209302326 0.15625 +0 0.30523255813953487 0.5989583333333333 0.20348837209302326 0.15625 +0 0.6976744186046512 0.5755208333333333 0.20348837209302326 0.15625 +0 0.6656976744186046 0.31510416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8cece25086fce7e18417b586928cd678.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8cece25086fce7e18417b586928cd678.txt new file mode 100644 index 0000000..47ac7ab --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8cece25086fce7e18417b586928cd678.txt @@ -0,0 +1,4 @@ +0 0.5261627906976745 0.5859375 0.20348837209302326 0.15625 +0 0.313953488372093 0.21354166666666666 0.20348837209302326 0.15625 +0 0.8284883720930233 0.18229166666666666 0.20348837209302326 0.15625 +0 0.19186046511627908 0.5234375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8d121244a22346cbf3f1f66c9e39b3e9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8d121244a22346cbf3f1f66c9e39b3e9.txt new file mode 100644 index 0000000..cfd97ec --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8d121244a22346cbf3f1f66c9e39b3e9.txt @@ -0,0 +1,4 @@ +0 0.5116279069767442 0.32291666666666663 0.20348837209302326 0.15625 +0 0.3430232558139535 0.5390625 0.20348837209302326 0.15625 +0 0.19186046511627908 0.15625 0.20348837209302326 0.15625 +0 0.6191860465116279 0.5260416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8d2b1d6a62ac697a438255bd8f592278.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8d2b1d6a62ac697a438255bd8f592278.txt new file mode 100644 index 0000000..5958a0e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8d2b1d6a62ac697a438255bd8f592278.txt @@ -0,0 +1,4 @@ +0 0.25872093023255816 0.6588541666666666 0.20348837209302326 0.15625 +0 0.15988372093023256 0.21354166666666666 0.20348837209302326 0.15625 +0 0.7034883720930233 0.36979166666666663 0.20348837209302326 0.15625 +0 0.5319767441860465 0.7916666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8e36bc2c5a0f8f265b48477b305b6a65.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8e36bc2c5a0f8f265b48477b305b6a65.txt new file mode 100644 index 0000000..bb5fd97 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8e36bc2c5a0f8f265b48477b305b6a65.txt @@ -0,0 +1,4 @@ +0 0.7877906976744186 0.15885416666666666 0.20348837209302326 0.15625 +0 0.8052325581395349 0.515625 0.20348837209302326 0.15625 +0 0.3633720930232558 0.6848958333333333 0.20348837209302326 0.15625 +0 0.3430232558139535 0.40885416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8e598176aed7b7d1ef9ee2ee97c6313c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8e598176aed7b7d1ef9ee2ee97c6313c.txt new file mode 100644 index 0000000..d970635 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8e598176aed7b7d1ef9ee2ee97c6313c.txt @@ -0,0 +1,4 @@ +0 0.1686046511627907 0.6458333333333333 0.20348837209302326 0.15625 +0 0.6976744186046512 0.1640625 0.20348837209302326 0.15625 +0 0.6540697674418604 0.5 0.20348837209302326 0.15625 +0 0.6686046511627907 0.7708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8e8f50e29b22be7a9e57492dcf64b08a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8e8f50e29b22be7a9e57492dcf64b08a.txt new file mode 100644 index 0000000..a9b9962 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8e8f50e29b22be7a9e57492dcf64b08a.txt @@ -0,0 +1,3 @@ +0 0.625 0.38541666666666663 0.20348837209302326 0.15625 +0 0.438953488372093 0.6354166666666666 0.20348837209302326 0.15625 +0 0.2005813953488372 0.09895833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f119bfbf2f0180405939f6b15fc9101.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f119bfbf2f0180405939f6b15fc9101.txt new file mode 100644 index 0000000..ad68e23 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f119bfbf2f0180405939f6b15fc9101.txt @@ -0,0 +1,4 @@ +0 0.6773255813953488 0.3489583333333333 0.20348837209302326 0.15625 +0 0.1569767441860465 0.7734375 0.20348837209302326 0.15625 +0 0.3081395348837209 0.32291666666666663 0.20348837209302326 0.15625 +0 0.8023255813953488 0.6354166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f1c87fc30fde6c850e14942621797e7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f1c87fc30fde6c850e14942621797e7.txt new file mode 100644 index 0000000..cd5b468 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f1c87fc30fde6c850e14942621797e7.txt @@ -0,0 +1,4 @@ +0 0.1308139534883721 0.5625 0.20348837209302326 0.15625 +0 0.12790697674418605 0.3567708333333333 0.20348837209302326 0.15625 +0 0.48546511627906974 0.5729166666666666 0.20348837209302326 0.15625 +0 0.6744186046511628 0.2864583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f4536d37e41ef35d57d386b6ec21f00.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f4536d37e41ef35d57d386b6ec21f00.txt new file mode 100644 index 0000000..5f9687f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f4536d37e41ef35d57d386b6ec21f00.txt @@ -0,0 +1,3 @@ +0 0.48546511627906974 0.10416666666666666 0.20348837209302326 0.15625 +0 0.7151162790697674 0.5546875 0.20348837209302326 0.15625 +0 0.24709302325581395 0.4895833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f6119695d73c3dd763b856ea399cac1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f6119695d73c3dd763b856ea399cac1.txt new file mode 100644 index 0000000..32274cb --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f6119695d73c3dd763b856ea399cac1.txt @@ -0,0 +1,5 @@ +0 0.627906976744186 0.2552083333333333 0.20348837209302326 0.15625 +0 0.11918604651162791 0.43229166666666663 0.20348837209302326 0.15625 +0 0.31976744186046513 0.13020833333333331 0.20348837209302326 0.15625 +0 0.31976744186046513 0.7578125 0.20348837209302326 0.15625 +0 0.44476744186046513 0.49479166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f6bb4abc2e8d4f5743e3475b095f866.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f6bb4abc2e8d4f5743e3475b095f866.txt new file mode 100644 index 0000000..20e5deb --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f6bb4abc2e8d4f5743e3475b095f866.txt @@ -0,0 +1,4 @@ +0 0.5813953488372093 0.109375 0.20348837209302326 0.15625 +0 0.7063953488372093 0.671875 0.20348837209302326 0.15625 +0 0.31976744186046513 0.5546875 0.20348837209302326 0.15625 +0 0.5319767441860465 0.3203125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f8f44e8967a0361c0e9a331e308bf9c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f8f44e8967a0361c0e9a331e308bf9c.txt new file mode 100644 index 0000000..2d83d63 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f8f44e8967a0361c0e9a331e308bf9c.txt @@ -0,0 +1,3 @@ +0 0.7616279069767442 0.3984375 0.20348837209302326 0.15625 +0 0.4215116279069767 0.6588541666666666 0.20348837209302326 0.15625 +0 0.2965116279069767 0.3125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f9a20148094ef5b65e07936803831d7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f9a20148094ef5b65e07936803831d7.txt new file mode 100644 index 0000000..f79dbeb --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8f9a20148094ef5b65e07936803831d7.txt @@ -0,0 +1,3 @@ +0 0.47674418604651164 0.2734375 0.20348837209302326 0.15625 +0 0.8488372093023255 0.7552083333333333 0.20348837209302326 0.15625 +0 0.2238372093023256 0.7447916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8fa5aa8ea22070d7cb1d55e23aae9184.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8fa5aa8ea22070d7cb1d55e23aae9184.txt new file mode 100644 index 0000000..6634bbf --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/8fa5aa8ea22070d7cb1d55e23aae9184.txt @@ -0,0 +1,5 @@ +0 0.6976744186046512 0.27604166666666663 0.20348837209302326 0.15625 +0 0.6075581395348837 0.7239583333333333 0.20348837209302326 0.15625 +0 0.5319767441860465 0.4895833333333333 0.20348837209302326 0.15625 +0 0.21220930232558138 0.7916666666666666 0.20348837209302326 0.15625 +0 0.23837209302325582 0.10677083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/90397cf9d5a60d158d139c458162e4ee.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/90397cf9d5a60d158d139c458162e4ee.txt new file mode 100644 index 0000000..be994a0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/90397cf9d5a60d158d139c458162e4ee.txt @@ -0,0 +1,4 @@ +0 0.8546511627906976 0.5052083333333333 0.20348837209302326 0.15625 +0 0.561046511627907 0.36197916666666663 0.20348837209302326 0.15625 +0 0.4011627906976744 0.6640625 0.20348837209302326 0.15625 +0 0.125 0.21354166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/90e1b3f232acb9332b2c7f10ce3c87af.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/90e1b3f232acb9332b2c7f10ce3c87af.txt new file mode 100644 index 0000000..993e613 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/90e1b3f232acb9332b2c7f10ce3c87af.txt @@ -0,0 +1,4 @@ +0 0.36627906976744184 0.5026041666666666 0.20348837209302326 0.15625 +0 0.7034883720930233 0.6536458333333333 0.20348837209302326 0.15625 +0 0.2703488372093023 0.11979166666666666 0.20348837209302326 0.15625 +0 0.7965116279069767 0.15364583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/91b9f129de7a430de4125136fa577b7b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/91b9f129de7a430de4125136fa577b7b.txt new file mode 100644 index 0000000..3fbf0f4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/91b9f129de7a430de4125136fa577b7b.txt @@ -0,0 +1,4 @@ +0 0.5813953488372093 0.2421875 0.20348837209302326 0.15625 +0 0.18023255813953487 0.40885416666666663 0.20348837209302326 0.15625 +0 0.6511627906976745 0.6197916666666666 0.20348837209302326 0.15625 +0 0.1744186046511628 0.7864583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9285f113bb1c93841f0aa339b2a97497.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9285f113bb1c93841f0aa339b2a97497.txt new file mode 100644 index 0000000..1fe2c68 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9285f113bb1c93841f0aa339b2a97497.txt @@ -0,0 +1,3 @@ +0 0.24709302325581395 0.609375 0.20348837209302326 0.15625 +0 0.14244186046511628 0.15885416666666666 0.20348837209302326 0.15625 +0 0.5465116279069767 0.1875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/92d2733e159d0c348452b92d5edc50c6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/92d2733e159d0c348452b92d5edc50c6.txt new file mode 100644 index 0000000..75f050b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/92d2733e159d0c348452b92d5edc50c6.txt @@ -0,0 +1,3 @@ +0 0.2063953488372093 0.3411458333333333 0.20348837209302326 0.15625 +0 0.5901162790697674 0.37760416666666663 0.20348837209302326 0.15625 +0 0.4011627906976744 0.6796875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/932e8588ca7b1c8bbd649abc3a374119.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/932e8588ca7b1c8bbd649abc3a374119.txt new file mode 100644 index 0000000..937ef90 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/932e8588ca7b1c8bbd649abc3a374119.txt @@ -0,0 +1,4 @@ +0 0.14534883720930233 0.26822916666666663 0.20348837209302326 0.15625 +0 0.8255813953488372 0.34635416666666663 0.20348837209302326 0.15625 +0 0.15988372093023256 0.5598958333333333 0.20348837209302326 0.15625 +0 0.5174418604651163 0.7057291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/935d66a51028b14e51839dfe133d4d36.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/935d66a51028b14e51839dfe133d4d36.txt new file mode 100644 index 0000000..c86f60f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/935d66a51028b14e51839dfe133d4d36.txt @@ -0,0 +1,4 @@ +0 0.2936046511627907 0.1875 0.20348837209302326 0.15625 +0 0.7848837209302325 0.22135416666666666 0.20348837209302326 0.15625 +0 0.2616279069767442 0.4114583333333333 0.20348837209302326 0.15625 +0 0.36627906976744184 0.7213541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9361a0552be8ca021465b5d0fefef83a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9361a0552be8ca021465b5d0fefef83a.txt new file mode 100644 index 0000000..74600fc --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9361a0552be8ca021465b5d0fefef83a.txt @@ -0,0 +1,3 @@ +0 0.5668604651162791 0.36197916666666663 0.20348837209302326 0.15625 +0 0.6424418604651163 0.6067708333333333 0.20348837209302326 0.15625 +0 0.22093023255813954 0.5260416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/93c99695327cac738efbc1711ba8546f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/93c99695327cac738efbc1711ba8546f.txt new file mode 100644 index 0000000..4817d0a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/93c99695327cac738efbc1711ba8546f.txt @@ -0,0 +1,3 @@ +0 0.6104651162790697 0.7447916666666666 0.20348837209302326 0.15625 +0 0.6424418604651163 0.359375 0.20348837209302326 0.15625 +0 0.3430232558139535 0.3020833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9468038a7d7e411f416cc27b84bf1598.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9468038a7d7e411f416cc27b84bf1598.txt new file mode 100644 index 0000000..65c89a8 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9468038a7d7e411f416cc27b84bf1598.txt @@ -0,0 +1,3 @@ +0 0.5523255813953488 0.6276041666666666 0.20348837209302326 0.15625 +0 0.28488372093023256 0.3958333333333333 0.20348837209302326 0.15625 +0 0.7296511627906976 0.1015625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/949f402eae7c2e3efd72a2d78a773849.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/949f402eae7c2e3efd72a2d78a773849.txt new file mode 100644 index 0000000..daf699d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/949f402eae7c2e3efd72a2d78a773849.txt @@ -0,0 +1,4 @@ +0 0.14825581395348836 0.6432291666666666 0.20348837209302326 0.15625 +0 0.6773255813953488 0.09375 0.20348837209302326 0.15625 +0 0.3430232558139535 0.26041666666666663 0.20348837209302326 0.15625 +0 0.6133720930232558 0.3489583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/94a7b31d3a962fa9e2037659aba91eb1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/94a7b31d3a962fa9e2037659aba91eb1.txt new file mode 100644 index 0000000..5d50bbb --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/94a7b31d3a962fa9e2037659aba91eb1.txt @@ -0,0 +1,3 @@ +0 0.4883720930232558 0.6432291666666666 0.20348837209302326 0.15625 +0 0.11918604651162791 0.46354166666666663 0.20348837209302326 0.15625 +0 0.46511627906976744 0.26041666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/94b50768c69af3f3236d8d60e493e88c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/94b50768c69af3f3236d8d60e493e88c.txt new file mode 100644 index 0000000..ec8ecde --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/94b50768c69af3f3236d8d60e493e88c.txt @@ -0,0 +1,4 @@ +0 0.6395348837209303 0.3177083333333333 0.20348837209302326 0.15625 +0 0.8488372093023255 0.6953125 0.20348837209302326 0.15625 +0 0.5552325581395349 0.75 0.20348837209302326 0.15625 +0 0.2965116279069767 0.234375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/950f2041abd8569848e5229eaa92f42a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/950f2041abd8569848e5229eaa92f42a.txt new file mode 100644 index 0000000..d45de63 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/950f2041abd8569848e5229eaa92f42a.txt @@ -0,0 +1,5 @@ +0 0.6191860465116279 0.3125 0.20348837209302326 0.15625 +0 0.30523255813953487 0.26041666666666663 0.20348837209302326 0.15625 +0 0.6133720930232558 0.5416666666666666 0.20348837209302326 0.15625 +0 0.27325581395348836 0.7734375 0.20348837209302326 0.15625 +0 0.22965116279069767 0.5026041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/953a44f985bc9ea38ddca4cdc71b76ed.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/953a44f985bc9ea38ddca4cdc71b76ed.txt new file mode 100644 index 0000000..7efaafe --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/953a44f985bc9ea38ddca4cdc71b76ed.txt @@ -0,0 +1,4 @@ +0 0.19767441860465115 0.21354166666666666 0.20348837209302326 0.15625 +0 0.6308139534883721 0.2864583333333333 0.20348837209302326 0.15625 +0 0.4127906976744186 0.5885416666666666 0.20348837209302326 0.15625 +0 0.7325581395348837 0.59375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/95a05e377d4a97bfd20aed87d987871e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/95a05e377d4a97bfd20aed87d987871e.txt new file mode 100644 index 0000000..972feec --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/95a05e377d4a97bfd20aed87d987871e.txt @@ -0,0 +1,4 @@ +0 0.20930232558139533 0.59375 0.20348837209302326 0.15625 +0 0.14534883720930233 0.1484375 0.20348837209302326 0.15625 +0 0.8052325581395349 0.45572916666666663 0.20348837209302326 0.15625 +0 0.4273255813953488 0.26822916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/96919433ed7bcc4951847a9e2599d005.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/96919433ed7bcc4951847a9e2599d005.txt new file mode 100644 index 0000000..3799e0c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/96919433ed7bcc4951847a9e2599d005.txt @@ -0,0 +1,4 @@ +0 0.26744186046511625 0.6822916666666666 0.20348837209302326 0.15625 +0 0.6686046511627907 0.6197916666666666 0.20348837209302326 0.15625 +0 0.3546511627906977 0.3125 0.20348837209302326 0.15625 +0 0.6627906976744186 0.3098958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9717485c255ec2689f5774c5434fe07b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9717485c255ec2689f5774c5434fe07b.txt new file mode 100644 index 0000000..d8f2714 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9717485c255ec2689f5774c5434fe07b.txt @@ -0,0 +1,4 @@ +0 0.36627906976744184 0.4739583333333333 0.20348837209302326 0.15625 +0 0.7209302325581395 0.7369791666666666 0.20348837209302326 0.15625 +0 0.5290697674418604 0.21875 0.20348837209302326 0.15625 +0 0.31976744186046513 0.71875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/978f6bf7b09be180c9fcf9a14e4286ac.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/978f6bf7b09be180c9fcf9a14e4286ac.txt new file mode 100644 index 0000000..2f6ec95 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/978f6bf7b09be180c9fcf9a14e4286ac.txt @@ -0,0 +1,4 @@ +0 0.23837209302325582 0.2421875 0.20348837209302326 0.15625 +0 0.5348837209302325 0.6171875 0.20348837209302326 0.15625 +0 0.8488372093023255 0.3203125 0.20348837209302326 0.15625 +0 0.14244186046511628 0.5598958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/97b91816db30b87582cc0fa687b0a249.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/97b91816db30b87582cc0fa687b0a249.txt new file mode 100644 index 0000000..b533e45 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/97b91816db30b87582cc0fa687b0a249.txt @@ -0,0 +1,4 @@ +0 0.375 0.7578125 0.20348837209302326 0.15625 +0 0.15406976744186046 0.14322916666666666 0.20348837209302326 0.15625 +0 0.6627906976744186 0.22916666666666666 0.20348837209302326 0.15625 +0 0.29941860465116277 0.3723958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/97ba02a27c83f4d4e746a7ae547c30da.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/97ba02a27c83f4d4e746a7ae547c30da.txt new file mode 100644 index 0000000..095816b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/97ba02a27c83f4d4e746a7ae547c30da.txt @@ -0,0 +1,4 @@ +0 0.2238372093023256 0.32291666666666663 0.20348837209302326 0.15625 +0 0.6133720930232558 0.6041666666666666 0.20348837209302326 0.15625 +0 0.7005813953488372 0.3125 0.20348837209302326 0.15625 +0 0.2819767441860465 0.5651041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/97c1d5b2c30f10b94179c9798881d634.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/97c1d5b2c30f10b94179c9798881d634.txt new file mode 100644 index 0000000..b08eeb3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/97c1d5b2c30f10b94179c9798881d634.txt @@ -0,0 +1,4 @@ +0 0.6366279069767442 0.6015625 0.20348837209302326 0.15625 +0 0.6482558139534884 0.125 0.20348837209302326 0.15625 +0 0.7238372093023255 0.36197916666666663 0.20348837209302326 0.15625 +0 0.3575581395348837 0.17447916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/97e0730901729fa04d92bf38badbb678.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/97e0730901729fa04d92bf38badbb678.txt new file mode 100644 index 0000000..541da6f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/97e0730901729fa04d92bf38badbb678.txt @@ -0,0 +1,5 @@ +0 0.5872093023255814 0.23697916666666666 0.20348837209302326 0.15625 +0 0.811046511627907 0.6666666666666666 0.20348837209302326 0.15625 +0 0.2616279069767442 0.2552083333333333 0.20348837209302326 0.15625 +0 0.32848837209302323 0.65625 0.20348837209302326 0.15625 +0 0.872093023255814 0.3671875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/98524e97400db3d5cec8d815615e8ecc.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/98524e97400db3d5cec8d815615e8ecc.txt new file mode 100644 index 0000000..ced780c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/98524e97400db3d5cec8d815615e8ecc.txt @@ -0,0 +1,4 @@ +0 0.5290697674418604 0.40625 0.20348837209302326 0.15625 +0 0.2761627906976744 0.6979166666666666 0.20348837209302326 0.15625 +0 0.8023255813953488 0.6510416666666666 0.20348837209302326 0.15625 +0 0.16569767441860464 0.3125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/98b219b75cb72c27367677fd23b38f05.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/98b219b75cb72c27367677fd23b38f05.txt new file mode 100644 index 0000000..0b84f22 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/98b219b75cb72c27367677fd23b38f05.txt @@ -0,0 +1,4 @@ +0 0.3808139534883721 0.2265625 0.20348837209302326 0.15625 +0 0.8430232558139534 0.18489583333333331 0.20348837209302326 0.15625 +0 0.4418604651162791 0.6848958333333333 0.20348837209302326 0.15625 +0 0.19767441860465115 0.44010416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/98ca5251916504dec58abde2e3c502e6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/98ca5251916504dec58abde2e3c502e6.txt new file mode 100644 index 0000000..5c8dad0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/98ca5251916504dec58abde2e3c502e6.txt @@ -0,0 +1,4 @@ +0 0.5319767441860465 0.45572916666666663 0.20348837209302326 0.15625 +0 0.16569767441860464 0.5494791666666666 0.20348837209302326 0.15625 +0 0.688953488372093 0.18489583333333331 0.20348837209302326 0.15625 +0 0.7936046511627907 0.7447916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99bfea652214a6a41b74106f9dedd3a5.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99bfea652214a6a41b74106f9dedd3a5.txt new file mode 100644 index 0000000..2426b56 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99bfea652214a6a41b74106f9dedd3a5.txt @@ -0,0 +1,4 @@ +0 0.2965116279069767 0.1640625 0.20348837209302326 0.15625 +0 0.5145348837209303 0.44010416666666663 0.20348837209302326 0.15625 +0 0.6976744186046512 0.15104166666666666 0.20348837209302326 0.15625 +0 0.5726744186046512 0.6901041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99e45f9544b53f4e31f711518c2841e7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99e45f9544b53f4e31f711518c2841e7.txt new file mode 100644 index 0000000..b7a91a0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99e45f9544b53f4e31f711518c2841e7.txt @@ -0,0 +1,5 @@ +0 0.625 0.17708333333333331 0.20348837209302326 0.15625 +0 0.8081395348837209 0.75 0.20348837209302326 0.15625 +0 0.34593023255813954 0.359375 0.20348837209302326 0.15625 +0 0.7587209302325582 0.4921875 0.20348837209302326 0.15625 +0 0.23837209302325582 0.7135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99ec5f725326327ed8034925522d941e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99ec5f725326327ed8034925522d941e.txt new file mode 100644 index 0000000..684b7f5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99ec5f725326327ed8034925522d941e.txt @@ -0,0 +1,4 @@ +0 0.7965116279069767 0.23697916666666666 0.20348837209302326 0.15625 +0 0.686046511627907 0.5755208333333333 0.20348837209302326 0.15625 +0 0.2965116279069767 0.4921875 0.20348837209302326 0.15625 +0 0.2965116279069767 0.21875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99eff4f19cfd6f1a75aaa834aa8ead8a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99eff4f19cfd6f1a75aaa834aa8ead8a.txt new file mode 100644 index 0000000..f2ef3da --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99eff4f19cfd6f1a75aaa834aa8ead8a.txt @@ -0,0 +1,3 @@ +0 0.6162790697674418 0.3098958333333333 0.20348837209302326 0.15625 +0 0.8604651162790697 0.7317708333333333 0.20348837209302326 0.15625 +0 0.18023255813953487 0.5807291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99f53490264348c56c275acca0fc2adf.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99f53490264348c56c275acca0fc2adf.txt new file mode 100644 index 0000000..c789e27 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/99f53490264348c56c275acca0fc2adf.txt @@ -0,0 +1,4 @@ +0 0.563953488372093 0.6666666666666666 0.20348837209302326 0.15625 +0 0.48546511627906974 0.20052083333333331 0.20348837209302326 0.15625 +0 0.5843023255813954 0.43229166666666663 0.20348837209302326 0.15625 +0 0.18313953488372092 0.21875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9a79b11711d54dcd262eb0c777e8b7dd.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9a79b11711d54dcd262eb0c777e8b7dd.txt new file mode 100644 index 0000000..5caa7f6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9a79b11711d54dcd262eb0c777e8b7dd.txt @@ -0,0 +1,4 @@ +0 0.8488372093023255 0.5 0.20348837209302326 0.15625 +0 0.28488372093023256 0.6640625 0.20348837209302326 0.15625 +0 0.5465116279069767 0.21614583333333331 0.20348837209302326 0.15625 +0 0.7703488372093024 0.7916666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9a93361aaf6a7612454502e9b7b071a7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9a93361aaf6a7612454502e9b7b071a7.txt new file mode 100644 index 0000000..81c17da --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9a93361aaf6a7612454502e9b7b071a7.txt @@ -0,0 +1,4 @@ +0 0.6191860465116279 0.5208333333333333 0.20348837209302326 0.15625 +0 0.8372093023255813 0.171875 0.20348837209302326 0.15625 +0 0.7180232558139534 0.7760416666666666 0.20348837209302326 0.15625 +0 0.1511627906976744 0.15625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9ad5a22c7c6ed587c9bec18e32075604.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9ad5a22c7c6ed587c9bec18e32075604.txt new file mode 100644 index 0000000..5f466dd --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9ad5a22c7c6ed587c9bec18e32075604.txt @@ -0,0 +1,3 @@ +0 0.11918604651162791 0.6432291666666666 0.20348837209302326 0.15625 +0 0.5203488372093024 0.1015625 0.20348837209302326 0.15625 +0 0.5523255813953488 0.7239583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9aefe57a6886c4c63b2dcfb25bc628b6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9aefe57a6886c4c63b2dcfb25bc628b6.txt new file mode 100644 index 0000000..64512a2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9aefe57a6886c4c63b2dcfb25bc628b6.txt @@ -0,0 +1,5 @@ +0 0.6482558139534884 0.24739583333333331 0.20348837209302326 0.15625 +0 0.7151162790697674 0.578125 0.20348837209302326 0.15625 +0 0.19186046511627908 0.4375 0.20348837209302326 0.15625 +0 0.24709302325581395 0.1328125 0.20348837209302326 0.15625 +0 0.30523255813953487 0.703125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b0526a52d458eb2d80a7a58f6a9da8b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b0526a52d458eb2d80a7a58f6a9da8b.txt new file mode 100644 index 0000000..ccfe9a5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b0526a52d458eb2d80a7a58f6a9da8b.txt @@ -0,0 +1,5 @@ +0 0.8633720930232558 0.28385416666666663 0.20348837209302326 0.15625 +0 0.21220930232558138 0.5729166666666666 0.20348837209302326 0.15625 +0 0.5348837209302325 0.4661458333333333 0.20348837209302326 0.15625 +0 0.2616279069767442 0.22135416666666666 0.20348837209302326 0.15625 +0 0.5959302325581395 0.6796875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b193fb82af1fef76d2705e993ccce18.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b193fb82af1fef76d2705e993ccce18.txt new file mode 100644 index 0000000..220601a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b193fb82af1fef76d2705e993ccce18.txt @@ -0,0 +1,4 @@ +0 0.8081395348837209 0.3880208333333333 0.20348837209302326 0.15625 +0 0.7819767441860465 0.12760416666666666 0.20348837209302326 0.15625 +0 0.22093023255813954 0.19791666666666666 0.20348837209302326 0.15625 +0 0.38372093023255816 0.7473958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b2fb0d294f38aa22e8a94567195fed2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b2fb0d294f38aa22e8a94567195fed2.txt new file mode 100644 index 0000000..d7e1dc3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b2fb0d294f38aa22e8a94567195fed2.txt @@ -0,0 +1,3 @@ +0 0.8430232558139534 0.6276041666666666 0.20348837209302326 0.15625 +0 0.47674418604651164 0.125 0.20348837209302326 0.15625 +0 0.7093023255813954 0.3723958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b7bf2e1ee9b6c6f8520c5841617d491.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b7bf2e1ee9b6c6f8520c5841617d491.txt new file mode 100644 index 0000000..47bf545 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b7bf2e1ee9b6c6f8520c5841617d491.txt @@ -0,0 +1,5 @@ +0 0.14534883720930233 0.484375 0.20348837209302326 0.15625 +0 0.18313953488372092 0.24739583333333331 0.20348837209302326 0.15625 +0 0.4825581395348837 0.5182291666666666 0.20348837209302326 0.15625 +0 0.6395348837209303 0.13541666666666666 0.20348837209302326 0.15625 +0 0.8372093023255813 0.6692708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b7d9f137c885f5a0c697c7b81138347.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b7d9f137c885f5a0c697c7b81138347.txt new file mode 100644 index 0000000..6c485a4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9b7d9f137c885f5a0c697c7b81138347.txt @@ -0,0 +1,5 @@ +0 0.2063953488372093 0.19270833333333331 0.20348837209302326 0.15625 +0 0.39244186046511625 0.7161458333333333 0.20348837209302326 0.15625 +0 0.7209302325581395 0.5755208333333333 0.20348837209302326 0.15625 +0 0.18313953488372092 0.4739583333333333 0.20348837209302326 0.15625 +0 0.7122093023255814 0.296875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9bbc7d2d06425082472330d97296985c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9bbc7d2d06425082472330d97296985c.txt new file mode 100644 index 0000000..e636808 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9bbc7d2d06425082472330d97296985c.txt @@ -0,0 +1,5 @@ +0 0.3488372093023256 0.53125 0.20348837209302326 0.15625 +0 0.8575581395348837 0.6510416666666666 0.20348837209302326 0.15625 +0 0.4215116279069767 0.19010416666666666 0.20348837209302326 0.15625 +0 0.5523255813953488 0.7760416666666666 0.20348837209302326 0.15625 +0 0.75 0.31510416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c08c7848349823dffbf16ac1dd7fde2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c08c7848349823dffbf16ac1dd7fde2.txt new file mode 100644 index 0000000..ab5ea3d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c08c7848349823dffbf16ac1dd7fde2.txt @@ -0,0 +1,5 @@ +0 0.313953488372093 0.6276041666666666 0.20348837209302326 0.15625 +0 0.44476744186046513 0.15625 0.20348837209302326 0.15625 +0 0.8313953488372093 0.6536458333333333 0.20348837209302326 0.15625 +0 0.625 0.3958333333333333 0.20348837209302326 0.15625 +0 0.17151162790697674 0.109375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c4a9ffd665f6d4eaf7a6a8ed0a55914.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c4a9ffd665f6d4eaf7a6a8ed0a55914.txt new file mode 100644 index 0000000..156db9a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c4a9ffd665f6d4eaf7a6a8ed0a55914.txt @@ -0,0 +1,3 @@ +0 0.15406976744186046 0.21614583333333331 0.20348837209302326 0.15625 +0 0.5872093023255814 0.14583333333333331 0.20348837209302326 0.15625 +0 0.7674418604651163 0.5130208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c60cb4cbab7836c200707f43bb44051.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c60cb4cbab7836c200707f43bb44051.txt new file mode 100644 index 0000000..0d10f45 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c60cb4cbab7836c200707f43bb44051.txt @@ -0,0 +1,4 @@ +0 0.39825581395348836 0.22135416666666666 0.20348837209302326 0.15625 +0 0.4563953488372093 0.4921875 0.20348837209302326 0.15625 +0 0.13372093023255813 0.6875 0.20348837209302326 0.15625 +0 0.7848837209302325 0.09375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c784afe281faed6446cead9999468fe.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c784afe281faed6446cead9999468fe.txt new file mode 100644 index 0000000..fab93bb --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c784afe281faed6446cead9999468fe.txt @@ -0,0 +1,5 @@ +0 0.7645348837209303 0.36979166666666663 0.20348837209302326 0.15625 +0 0.13372093023255813 0.11197916666666666 0.20348837209302326 0.15625 +0 0.42441860465116277 0.6744791666666666 0.20348837209302326 0.15625 +0 0.11918604651162791 0.5598958333333333 0.20348837209302326 0.15625 +0 0.811046511627907 0.6536458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c7e324db2f6923088e1428a5bfc1853.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c7e324db2f6923088e1428a5bfc1853.txt new file mode 100644 index 0000000..f8329f1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c7e324db2f6923088e1428a5bfc1853.txt @@ -0,0 +1,4 @@ +0 0.8662790697674418 0.6744791666666666 0.20348837209302326 0.15625 +0 0.2877906976744186 0.6927083333333333 0.20348837209302326 0.15625 +0 0.7441860465116279 0.14322916666666666 0.20348837209302326 0.15625 +0 0.6395348837209303 0.4375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c8ae58463757708733c1377972765d1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c8ae58463757708733c1377972765d1.txt new file mode 100644 index 0000000..c4acb58 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c8ae58463757708733c1377972765d1.txt @@ -0,0 +1,4 @@ +0 0.16569767441860464 0.6822916666666666 0.20348837209302326 0.15625 +0 0.5872093023255814 0.46354166666666663 0.20348837209302326 0.15625 +0 0.29941860465116277 0.2786458333333333 0.20348837209302326 0.15625 +0 0.627906976744186 0.20572916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c8d0ab038cf5908de0adad379438871.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c8d0ab038cf5908de0adad379438871.txt new file mode 100644 index 0000000..f706d4e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9c8d0ab038cf5908de0adad379438871.txt @@ -0,0 +1,5 @@ +0 0.6918604651162791 0.23958333333333331 0.20348837209302326 0.15625 +0 0.375 0.3645833333333333 0.20348837209302326 0.15625 +0 0.14825581395348836 0.7421875 0.20348837209302326 0.15625 +0 0.4505813953488372 0.671875 0.20348837209302326 0.15625 +0 0.8023255813953488 0.5963541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9cd94333961738671eb031f231f82682.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9cd94333961738671eb031f231f82682.txt new file mode 100644 index 0000000..208a7c9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9cd94333961738671eb031f231f82682.txt @@ -0,0 +1,4 @@ +0 0.36627906976744184 0.16145833333333331 0.20348837209302326 0.15625 +0 0.4127906976744186 0.46875 0.20348837209302326 0.15625 +0 0.7122093023255814 0.7578125 0.20348837209302326 0.15625 +0 0.8401162790697674 0.5286458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9cfadf14d721875a86a0a3b96663be99.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9cfadf14d721875a86a0a3b96663be99.txt new file mode 100644 index 0000000..c70b958 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9cfadf14d721875a86a0a3b96663be99.txt @@ -0,0 +1,4 @@ +0 0.6337209302325582 0.45572916666666663 0.20348837209302326 0.15625 +0 0.7151162790697674 0.1328125 0.20348837209302326 0.15625 +0 0.32848837209302323 0.53125 0.20348837209302326 0.15625 +0 0.4069767441860465 0.14583333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9d4a73d1872dd017871d75c634ef735a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9d4a73d1872dd017871d75c634ef735a.txt new file mode 100644 index 0000000..898c4c1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9d4a73d1872dd017871d75c634ef735a.txt @@ -0,0 +1,5 @@ +0 0.436046511627907 0.6666666666666666 0.20348837209302326 0.15625 +0 0.6133720930232558 0.4270833333333333 0.20348837209302326 0.15625 +0 0.1686046511627907 0.13541666666666666 0.20348837209302326 0.15625 +0 0.8546511627906976 0.12239583333333333 0.20348837209302326 0.15625 +0 0.25 0.37760416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9d5e6b6c7741e8f00d87ee67c643b04b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9d5e6b6c7741e8f00d87ee67c643b04b.txt new file mode 100644 index 0000000..7a3b362 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9d5e6b6c7741e8f00d87ee67c643b04b.txt @@ -0,0 +1,4 @@ +0 0.4563953488372093 0.5416666666666666 0.20348837209302326 0.15625 +0 0.43023255813953487 0.2734375 0.20348837209302326 0.15625 +0 0.125 0.14583333333333331 0.20348837209302326 0.15625 +0 0.13372093023255813 0.5208333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9dbda62a725307cab594a22c41318024.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9dbda62a725307cab594a22c41318024.txt new file mode 100644 index 0000000..0a0cae2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9dbda62a725307cab594a22c41318024.txt @@ -0,0 +1,4 @@ +0 0.5813953488372093 0.20052083333333331 0.20348837209302326 0.15625 +0 0.42441860465116277 0.5572916666666666 0.20348837209302326 0.15625 +0 0.313953488372093 0.7864583333333333 0.20348837209302326 0.15625 +0 0.7558139534883721 0.7265625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9e5e1d609b4b142a2fb588936ad39f05.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9e5e1d609b4b142a2fb588936ad39f05.txt new file mode 100644 index 0000000..299ebe6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9e5e1d609b4b142a2fb588936ad39f05.txt @@ -0,0 +1,4 @@ +0 0.7034883720930233 0.4583333333333333 0.20348837209302326 0.15625 +0 0.27906976744186046 0.7890625 0.20348837209302326 0.15625 +0 0.7296511627906976 0.7421875 0.20348837209302326 0.15625 +0 0.2238372093023256 0.5026041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9e819206363a80c61175f1e39b39d603.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9e819206363a80c61175f1e39b39d603.txt new file mode 100644 index 0000000..db4b730 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9e819206363a80c61175f1e39b39d603.txt @@ -0,0 +1,4 @@ +0 0.6017441860465116 0.7317708333333333 0.20348837209302326 0.15625 +0 0.16569767441860464 0.18489583333333331 0.20348837209302326 0.15625 +0 0.4941860465116279 0.1640625 0.20348837209302326 0.15625 +0 0.627906976744186 0.4427083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9efbc80a2ba6c3a256ae5bdd2677e147.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9efbc80a2ba6c3a256ae5bdd2677e147.txt new file mode 100644 index 0000000..1ff3700 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9efbc80a2ba6c3a256ae5bdd2677e147.txt @@ -0,0 +1,3 @@ +0 0.15406976744186046 0.13541666666666666 0.20348837209302326 0.15625 +0 0.7819767441860465 0.3203125 0.20348837209302326 0.15625 +0 0.13372093023255813 0.75 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9f191a293528f170b2fddc35889a3460.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9f191a293528f170b2fddc35889a3460.txt new file mode 100644 index 0000000..aae3e68 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9f191a293528f170b2fddc35889a3460.txt @@ -0,0 +1,3 @@ +0 0.2005813953488372 0.6197916666666666 0.20348837209302326 0.15625 +0 0.8197674418604651 0.3880208333333333 0.20348837209302326 0.15625 +0 0.6598837209302325 0.6302083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9f74e1e54c89d47ad93084ce1951258d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9f74e1e54c89d47ad93084ce1951258d.txt new file mode 100644 index 0000000..de3f488 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9f74e1e54c89d47ad93084ce1951258d.txt @@ -0,0 +1,5 @@ +0 0.6569767441860465 0.7265625 0.20348837209302326 0.15625 +0 0.36046511627906974 0.4921875 0.20348837209302326 0.15625 +0 0.3808139534883721 0.11979166666666666 0.20348837209302326 0.15625 +0 0.7063953488372093 0.26041666666666663 0.20348837209302326 0.15625 +0 0.7936046511627907 0.5026041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9f987287209598d5c53893415d99912e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9f987287209598d5c53893415d99912e.txt new file mode 100644 index 0000000..e170de1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/9f987287209598d5c53893415d99912e.txt @@ -0,0 +1,5 @@ +0 0.2645348837209302 0.5729166666666666 0.20348837209302326 0.15625 +0 0.2936046511627907 0.1875 0.20348837209302326 0.15625 +0 0.5668604651162791 0.6067708333333333 0.20348837209302326 0.15625 +0 0.7877906976744186 0.3802083333333333 0.20348837209302326 0.15625 +0 0.7616279069767442 0.09375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a074eccd420a1d404b7220f4dd0c0628.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a074eccd420a1d404b7220f4dd0c0628.txt new file mode 100644 index 0000000..752e7dc --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a074eccd420a1d404b7220f4dd0c0628.txt @@ -0,0 +1,4 @@ +0 0.5552325581395349 0.3255208333333333 0.20348837209302326 0.15625 +0 0.13953488372093023 0.5625 0.20348837209302326 0.15625 +0 0.5581395348837209 0.6145833333333333 0.20348837209302326 0.15625 +0 0.19186046511627908 0.1171875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a150b5e884cbc0fca16af4dad96c26a3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a150b5e884cbc0fca16af4dad96c26a3.txt new file mode 100644 index 0000000..7a1f51a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a150b5e884cbc0fca16af4dad96c26a3.txt @@ -0,0 +1,3 @@ +0 0.8168604651162791 0.7317708333333333 0.20348837209302326 0.15625 +0 0.23837209302325582 0.21354166666666666 0.20348837209302326 0.15625 +0 0.8430232558139534 0.41666666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a1e783dc063fd3d116ee9b15d7b79b97.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a1e783dc063fd3d116ee9b15d7b79b97.txt new file mode 100644 index 0000000..7415c1c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a1e783dc063fd3d116ee9b15d7b79b97.txt @@ -0,0 +1,4 @@ +0 0.16569767441860464 0.15104166666666666 0.20348837209302326 0.15625 +0 0.7383720930232558 0.359375 0.20348837209302326 0.15625 +0 0.7761627906976744 0.5833333333333333 0.20348837209302326 0.15625 +0 0.2819767441860465 0.7708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a1e91b083a1f5ee6b7c743cfebacd750.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a1e91b083a1f5ee6b7c743cfebacd750.txt new file mode 100644 index 0000000..fda375d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a1e91b083a1f5ee6b7c743cfebacd750.txt @@ -0,0 +1,3 @@ +0 0.4825581395348837 0.45572916666666663 0.20348837209302326 0.15625 +0 0.3430232558139535 0.7760416666666666 0.20348837209302326 0.15625 +0 0.8459302325581395 0.3489583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a1f7779bf16bf476c5c66672c33c7704.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a1f7779bf16bf476c5c66672c33c7704.txt new file mode 100644 index 0000000..0fa9de3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a1f7779bf16bf476c5c66672c33c7704.txt @@ -0,0 +1,4 @@ +0 0.8284883720930233 0.16927083333333331 0.20348837209302326 0.15625 +0 0.31976744186046513 0.12239583333333333 0.20348837209302326 0.15625 +0 0.5872093023255814 0.390625 0.20348837209302326 0.15625 +0 0.5319767441860465 0.6770833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a23af315d9cef507348c491f99cc3fb0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a23af315d9cef507348c491f99cc3fb0.txt new file mode 100644 index 0000000..694bdab --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a23af315d9cef507348c491f99cc3fb0.txt @@ -0,0 +1,5 @@ +0 0.7238372093023255 0.4036458333333333 0.20348837209302326 0.15625 +0 0.2616279069767442 0.4375 0.20348837209302326 0.15625 +0 0.3226744186046512 0.14322916666666666 0.20348837209302326 0.15625 +0 0.8343023255813954 0.08854166666666666 0.20348837209302326 0.15625 +0 0.2238372093023256 0.7421875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a23c75b1b09039db0be1664aeee60ad0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a23c75b1b09039db0be1664aeee60ad0.txt new file mode 100644 index 0000000..415ba9d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a23c75b1b09039db0be1664aeee60ad0.txt @@ -0,0 +1,4 @@ +0 0.40406976744186046 0.12760416666666666 0.20348837209302326 0.15625 +0 0.29941860465116277 0.53125 0.20348837209302326 0.15625 +0 0.7965116279069767 0.21614583333333331 0.20348837209302326 0.15625 +0 0.7063953488372093 0.5755208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a257fe1660b3c2e7e225ceb7ea9df189.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a257fe1660b3c2e7e225ceb7ea9df189.txt new file mode 100644 index 0000000..590e440 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a257fe1660b3c2e7e225ceb7ea9df189.txt @@ -0,0 +1,4 @@ +0 0.31976744186046513 0.5 0.20348837209302326 0.15625 +0 0.2238372093023256 0.1484375 0.20348837209302326 0.15625 +0 0.627906976744186 0.2864583333333333 0.20348837209302326 0.15625 +0 0.7383720930232558 0.7864583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a25e24900003730789465e978092520d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a25e24900003730789465e978092520d.txt new file mode 100644 index 0000000..d7d4268 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a25e24900003730789465e978092520d.txt @@ -0,0 +1,2 @@ +0 0.6453488372093024 0.21875 0.20348837209302326 0.15625 +0 0.7412790697674418 0.5703125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a25e346167348694e3c2417d3b40f424.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a25e346167348694e3c2417d3b40f424.txt new file mode 100644 index 0000000..8d0d787 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a25e346167348694e3c2417d3b40f424.txt @@ -0,0 +1,5 @@ +0 0.125 0.7239583333333333 0.20348837209302326 0.15625 +0 0.5377906976744186 0.6510416666666666 0.20348837209302326 0.15625 +0 0.8488372093023255 0.2734375 0.20348837209302326 0.15625 +0 0.5523255813953488 0.29947916666666663 0.20348837209302326 0.15625 +0 0.1947674418604651 0.3723958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a26dd757bda550ce54818a97af8f2b59.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a26dd757bda550ce54818a97af8f2b59.txt new file mode 100644 index 0000000..1767a5b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a26dd757bda550ce54818a97af8f2b59.txt @@ -0,0 +1,5 @@ +0 0.34011627906976744 0.328125 0.20348837209302326 0.15625 +0 0.8023255813953488 0.12760416666666666 0.20348837209302326 0.15625 +0 0.4622093023255814 0.6171875 0.20348837209302326 0.15625 +0 0.7994186046511628 0.4895833333333333 0.20348837209302326 0.15625 +0 0.14534883720930233 0.6875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a28e4a9541313bc27eb2c9058482d5e2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a28e4a9541313bc27eb2c9058482d5e2.txt new file mode 100644 index 0000000..9202864 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a28e4a9541313bc27eb2c9058482d5e2.txt @@ -0,0 +1,5 @@ +0 0.5872093023255814 0.3880208333333333 0.20348837209302326 0.15625 +0 0.2180232558139535 0.24739583333333331 0.20348837209302326 0.15625 +0 0.39825581395348836 0.7291666666666666 0.20348837209302326 0.15625 +0 0.5843023255813954 0.09375 0.20348837209302326 0.15625 +0 0.8197674418604651 0.7526041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a29560b4f90a3245e0ec054145809d47.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a29560b4f90a3245e0ec054145809d47.txt new file mode 100644 index 0000000..05392ec --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a29560b4f90a3245e0ec054145809d47.txt @@ -0,0 +1,5 @@ +0 0.2063953488372093 0.43229166666666663 0.20348837209302326 0.15625 +0 0.8604651162790697 0.26041666666666663 0.20348837209302326 0.15625 +0 0.5174418604651163 0.34375 0.20348837209302326 0.15625 +0 0.7412790697674418 0.6510416666666666 0.20348837209302326 0.15625 +0 0.4505813953488372 0.7161458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a2ac554fd0db3a5255a2ba1b97d801d7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a2ac554fd0db3a5255a2ba1b97d801d7.txt new file mode 100644 index 0000000..f3b2314 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a2ac554fd0db3a5255a2ba1b97d801d7.txt @@ -0,0 +1,4 @@ +0 0.6918604651162791 0.6197916666666666 0.20348837209302326 0.15625 +0 0.2063953488372093 0.71875 0.20348837209302326 0.15625 +0 0.34011627906976744 0.22395833333333331 0.20348837209302326 0.15625 +0 0.7034883720930233 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a2d39626b8795dc30e45b137fad78c02.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a2d39626b8795dc30e45b137fad78c02.txt new file mode 100644 index 0000000..edd8337 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a2d39626b8795dc30e45b137fad78c02.txt @@ -0,0 +1,4 @@ +0 0.5988372093023255 0.5833333333333333 0.20348837209302326 0.15625 +0 0.3023255813953488 0.7395833333333333 0.20348837209302326 0.15625 +0 0.18604651162790697 0.11197916666666666 0.20348837209302326 0.15625 +0 0.5494186046511628 0.15625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a31b10db33637e83d61d6c3bd4d2402e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a31b10db33637e83d61d6c3bd4d2402e.txt new file mode 100644 index 0000000..6c7d6ef --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a31b10db33637e83d61d6c3bd4d2402e.txt @@ -0,0 +1,5 @@ +0 0.14825581395348836 0.296875 0.20348837209302326 0.15625 +0 0.5058139534883721 0.7786458333333333 0.20348837209302326 0.15625 +0 0.7877906976744186 0.5729166666666666 0.20348837209302326 0.15625 +0 0.502906976744186 0.5494791666666666 0.20348837209302326 0.15625 +0 0.19186046511627908 0.7265625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a3929123e598daa1f7e5f3900bdd31b3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a3929123e598daa1f7e5f3900bdd31b3.txt new file mode 100644 index 0000000..bdb6c77 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a3929123e598daa1f7e5f3900bdd31b3.txt @@ -0,0 +1,5 @@ +0 0.5872093023255814 0.5260416666666666 0.20348837209302326 0.15625 +0 0.22093023255813954 0.3723958333333333 0.20348837209302326 0.15625 +0 0.2819767441860465 0.6145833333333333 0.20348837209302326 0.15625 +0 0.2645348837209302 0.13020833333333331 0.20348837209302326 0.15625 +0 0.5872093023255814 0.7682291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a3a8358e74acd7bf24b72a7e235c6ded.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a3a8358e74acd7bf24b72a7e235c6ded.txt new file mode 100644 index 0000000..47f1b65 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a3a8358e74acd7bf24b72a7e235c6ded.txt @@ -0,0 +1,5 @@ +0 0.5552325581395349 0.5885416666666666 0.20348837209302326 0.15625 +0 0.2703488372093023 0.28385416666666663 0.20348837209302326 0.15625 +0 0.7238372093023255 0.29166666666666663 0.20348837209302326 0.15625 +0 0.8808139534883721 0.7552083333333333 0.20348837209302326 0.15625 +0 0.2238372093023256 0.6953125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a3ccab85e1d389eb6d635159f3adf06a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a3ccab85e1d389eb6d635159f3adf06a.txt new file mode 100644 index 0000000..1dd56cb --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a3ccab85e1d389eb6d635159f3adf06a.txt @@ -0,0 +1,4 @@ +0 0.1686046511627907 0.140625 0.20348837209302326 0.15625 +0 0.6017441860465116 0.23177083333333331 0.20348837209302326 0.15625 +0 0.1947674418604651 0.6796875 0.20348837209302326 0.15625 +0 0.7674418604651163 0.5807291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a441b1b8061d039a90072ef9af820d14.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a441b1b8061d039a90072ef9af820d14.txt new file mode 100644 index 0000000..84ecf0a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a441b1b8061d039a90072ef9af820d14.txt @@ -0,0 +1,2 @@ +0 0.2703488372093023 0.14583333333333331 0.20348837209302326 0.15625 +0 0.21511627906976744 0.6692708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a44d6d0bd3d836d56e9c1eb8fe83ca83.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a44d6d0bd3d836d56e9c1eb8fe83ca83.txt new file mode 100644 index 0000000..adc6c36 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a44d6d0bd3d836d56e9c1eb8fe83ca83.txt @@ -0,0 +1,5 @@ +0 0.5087209302325582 0.7161458333333333 0.20348837209302326 0.15625 +0 0.15988372093023256 0.5208333333333333 0.20348837209302326 0.15625 +0 0.22965116279069767 0.2890625 0.20348837209302326 0.15625 +0 0.8197674418604651 0.6432291666666666 0.20348837209302326 0.15625 +0 0.7674418604651163 0.3828125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a484f6ee5d37eaa55aad1b1be8051d44.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a484f6ee5d37eaa55aad1b1be8051d44.txt new file mode 100644 index 0000000..6ef8866 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a484f6ee5d37eaa55aad1b1be8051d44.txt @@ -0,0 +1,4 @@ +0 0.19186046511627908 0.3802083333333333 0.20348837209302326 0.15625 +0 0.8226744186046512 0.3671875 0.20348837209302326 0.15625 +0 0.7645348837209303 0.09114583333333333 0.20348837209302326 0.15625 +0 0.7034883720930233 0.7161458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a48bcefc7c3b54bc773fa9f7ab6abb7e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a48bcefc7c3b54bc773fa9f7ab6abb7e.txt new file mode 100644 index 0000000..0d4c216 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a48bcefc7c3b54bc773fa9f7ab6abb7e.txt @@ -0,0 +1,5 @@ +0 0.8488372093023255 0.6666666666666666 0.20348837209302326 0.15625 +0 0.19186046511627908 0.125 0.20348837209302326 0.15625 +0 0.41860465116279066 0.5364583333333333 0.20348837209302326 0.15625 +0 0.8401162790697674 0.4375 0.20348837209302326 0.15625 +0 0.7732558139534884 0.1796875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a4f8c3b10d92497b501c1e9afa388421.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a4f8c3b10d92497b501c1e9afa388421.txt new file mode 100644 index 0000000..b0ab701 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a4f8c3b10d92497b501c1e9afa388421.txt @@ -0,0 +1,4 @@ +0 0.4273255813953488 0.2630208333333333 0.20348837209302326 0.15625 +0 0.4883720930232558 0.5494791666666666 0.20348837209302326 0.15625 +0 0.18023255813953487 0.5390625 0.20348837209302326 0.15625 +0 0.8226744186046512 0.1953125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a582a728879d60893bcd31db885fce59.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a582a728879d60893bcd31db885fce59.txt new file mode 100644 index 0000000..f86b63e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a582a728879d60893bcd31db885fce59.txt @@ -0,0 +1,3 @@ +0 0.6191860465116279 0.26041666666666663 0.20348837209302326 0.15625 +0 0.7645348837209303 0.7760416666666666 0.20348837209302326 0.15625 +0 0.31976744186046513 0.734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a5c14915cf7fadd6bc4fd1a818d02a01.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a5c14915cf7fadd6bc4fd1a818d02a01.txt new file mode 100644 index 0000000..7e84c9b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a5c14915cf7fadd6bc4fd1a818d02a01.txt @@ -0,0 +1,4 @@ +0 0.18604651162790697 0.5546875 0.20348837209302326 0.15625 +0 0.7122093023255814 0.5833333333333333 0.20348837209302326 0.15625 +0 0.7965116279069767 0.29947916666666663 0.20348837209302326 0.15625 +0 0.23255813953488372 0.22135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a5fa2a57512b0e221d1b8f998a48454f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a5fa2a57512b0e221d1b8f998a48454f.txt new file mode 100644 index 0000000..8003c7f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a5fa2a57512b0e221d1b8f998a48454f.txt @@ -0,0 +1,4 @@ +0 0.8197674418604651 0.22135416666666666 0.20348837209302326 0.15625 +0 0.41860465116279066 0.44010416666666663 0.20348837209302326 0.15625 +0 0.2703488372093023 0.12239583333333333 0.20348837209302326 0.15625 +0 0.5058139534883721 0.7421875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a5fb894586afc629fcf3e8e806465daa.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a5fb894586afc629fcf3e8e806465daa.txt new file mode 100644 index 0000000..210b9b3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a5fb894586afc629fcf3e8e806465daa.txt @@ -0,0 +1,4 @@ +0 0.4418604651162791 0.7578125 0.20348837209302326 0.15625 +0 0.43023255813953487 0.4453125 0.20348837209302326 0.15625 +0 0.7965116279069767 0.390625 0.20348837209302326 0.15625 +0 0.7965116279069767 0.1796875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a645e9b584f91c1b25bfdd44b1a1207c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a645e9b584f91c1b25bfdd44b1a1207c.txt new file mode 100644 index 0000000..d77a932 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a645e9b584f91c1b25bfdd44b1a1207c.txt @@ -0,0 +1,3 @@ +0 0.6424418604651163 0.5729166666666666 0.20348837209302326 0.15625 +0 0.2616279069767442 0.27604166666666663 0.20348837209302326 0.15625 +0 0.8284883720930233 0.23958333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a73988c400f0f2ad4e51db239375ef30.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a73988c400f0f2ad4e51db239375ef30.txt new file mode 100644 index 0000000..6560a2c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a73988c400f0f2ad4e51db239375ef30.txt @@ -0,0 +1,5 @@ +0 0.7674418604651163 0.7291666666666666 0.20348837209302326 0.15625 +0 0.34593023255813954 0.26822916666666663 0.20348837209302326 0.15625 +0 0.29069767441860467 0.7213541666666666 0.20348837209302326 0.15625 +0 0.7558139534883721 0.4765625 0.20348837209302326 0.15625 +0 0.7936046511627907 0.09114583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a7dbdfce74f20e69174bc2c77ff68b32.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a7dbdfce74f20e69174bc2c77ff68b32.txt new file mode 100644 index 0000000..d3ab566 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a7dbdfce74f20e69174bc2c77ff68b32.txt @@ -0,0 +1,4 @@ +0 0.6831395348837209 0.6328125 0.20348837209302326 0.15625 +0 0.7209302325581395 0.09114583333333333 0.20348837209302326 0.15625 +0 0.22965116279069767 0.7760416666666666 0.20348837209302326 0.15625 +0 0.40406976744186046 0.234375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a7f87cb1e96db0e16470b46b880b1c43.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a7f87cb1e96db0e16470b46b880b1c43.txt new file mode 100644 index 0000000..aac1d06 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a7f87cb1e96db0e16470b46b880b1c43.txt @@ -0,0 +1,4 @@ +0 0.5203488372093024 0.4739583333333333 0.20348837209302326 0.15625 +0 0.11627906976744186 0.6979166666666666 0.20348837209302326 0.15625 +0 0.11918604651162791 0.140625 0.20348837209302326 0.15625 +0 0.5523255813953488 0.17447916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a81c5093b057649726ec484351986fb7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a81c5093b057649726ec484351986fb7.txt new file mode 100644 index 0000000..f5ddff8 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a81c5093b057649726ec484351986fb7.txt @@ -0,0 +1,5 @@ +0 0.6453488372093024 0.109375 0.20348837209302326 0.15625 +0 0.6656976744186046 0.6458333333333333 0.20348837209302326 0.15625 +0 0.23837209302325582 0.3645833333333333 0.20348837209302326 0.15625 +0 0.18313953488372092 0.7734375 0.20348837209302326 0.15625 +0 0.7645348837209303 0.36197916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a8a38c2fa56faba0a9d526b857592aed.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a8a38c2fa56faba0a9d526b857592aed.txt new file mode 100644 index 0000000..0b1aee1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a8a38c2fa56faba0a9d526b857592aed.txt @@ -0,0 +1,4 @@ +0 0.27906976744186046 0.34635416666666663 0.20348837209302326 0.15625 +0 0.8401162790697674 0.5755208333333333 0.20348837209302326 0.15625 +0 0.752906976744186 0.2890625 0.20348837209302326 0.15625 +0 0.5377906976744186 0.703125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a8b96cff8494ff3fad291751bd814c63.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a8b96cff8494ff3fad291751bd814c63.txt new file mode 100644 index 0000000..a1c4836 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a8b96cff8494ff3fad291751bd814c63.txt @@ -0,0 +1,4 @@ +0 0.4680232558139535 0.31510416666666663 0.20348837209302326 0.15625 +0 0.18023255813953487 0.5364583333333333 0.20348837209302326 0.15625 +0 0.45348837209302323 0.5911458333333333 0.20348837209302326 0.15625 +0 0.7936046511627907 0.34375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a953f0291889f76911f8d7af7e8f00c0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a953f0291889f76911f8d7af7e8f00c0.txt new file mode 100644 index 0000000..17d1860 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a953f0291889f76911f8d7af7e8f00c0.txt @@ -0,0 +1,4 @@ +0 0.6337209302325582 0.7057291666666666 0.20348837209302326 0.15625 +0 0.39244186046511625 0.20052083333333331 0.20348837209302326 0.15625 +0 0.313953488372093 0.5 0.20348837209302326 0.15625 +0 0.19767441860465115 0.75 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a98a8a3c4c6888719543ebdb14ad6763.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a98a8a3c4c6888719543ebdb14ad6763.txt new file mode 100644 index 0000000..e3ccbb9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a98a8a3c4c6888719543ebdb14ad6763.txt @@ -0,0 +1,4 @@ +0 0.7063953488372093 0.09375 0.20348837209302326 0.15625 +0 0.3430232558139535 0.21614583333333331 0.20348837209302326 0.15625 +0 0.3953488372093023 0.6744791666666666 0.20348837209302326 0.15625 +0 0.561046511627907 0.4453125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a9be83d24ee39185a8be2e44b62bd1b8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a9be83d24ee39185a8be2e44b62bd1b8.txt new file mode 100644 index 0000000..be0ec1b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/a9be83d24ee39185a8be2e44b62bd1b8.txt @@ -0,0 +1,4 @@ +0 0.4505813953488372 0.6953125 0.20348837209302326 0.15625 +0 0.7267441860465116 0.17447916666666666 0.20348837209302326 0.15625 +0 0.7732558139534884 0.703125 0.20348837209302326 0.15625 +0 0.1947674418604651 0.453125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa0adc592954ac28e1394a341641c57b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa0adc592954ac28e1394a341641c57b.txt new file mode 100644 index 0000000..260842e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa0adc592954ac28e1394a341641c57b.txt @@ -0,0 +1,4 @@ +0 0.7819767441860465 0.7864583333333333 0.20348837209302326 0.15625 +0 0.2238372093023256 0.3125 0.20348837209302326 0.15625 +0 0.8255813953488372 0.5208333333333333 0.20348837209302326 0.15625 +0 0.5116279069767442 0.640625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa24b73a63d917835adfa87f802aef47.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa24b73a63d917835adfa87f802aef47.txt new file mode 100644 index 0000000..60c9861 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa24b73a63d917835adfa87f802aef47.txt @@ -0,0 +1,3 @@ +0 0.15988372093023256 0.7369791666666666 0.20348837209302326 0.15625 +0 0.23546511627906977 0.3880208333333333 0.20348837209302326 0.15625 +0 0.6598837209302325 0.5598958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa53c93fa15412f2dd49652d49f2cb0f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa53c93fa15412f2dd49652d49f2cb0f.txt new file mode 100644 index 0000000..5e1dd44 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa53c93fa15412f2dd49652d49f2cb0f.txt @@ -0,0 +1,4 @@ +0 0.17151162790697674 0.6692708333333333 0.20348837209302326 0.15625 +0 0.5087209302325582 0.3359375 0.20348837209302326 0.15625 +0 0.8343023255813954 0.14583333333333331 0.20348837209302326 0.15625 +0 0.6569767441860465 0.5833333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa611d42127919301e3a4b81254e9d02.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa611d42127919301e3a4b81254e9d02.txt new file mode 100644 index 0000000..e7acbda --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa611d42127919301e3a4b81254e9d02.txt @@ -0,0 +1,4 @@ +0 0.49127906976744184 0.47916666666666663 0.20348837209302326 0.15625 +0 0.4738372093023256 0.16145833333333331 0.20348837209302326 0.15625 +0 0.1947674418604651 0.5052083333333333 0.20348837209302326 0.15625 +0 0.18023255813953487 0.7552083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa792f1df61b084cbfbc612220b45c3b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa792f1df61b084cbfbc612220b45c3b.txt new file mode 100644 index 0000000..f4b9c28 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aa792f1df61b084cbfbc612220b45c3b.txt @@ -0,0 +1,4 @@ +0 0.125 0.4296875 0.20348837209302326 0.15625 +0 0.8081395348837209 0.7239583333333333 0.20348837209302326 0.15625 +0 0.5988372093023255 0.4817708333333333 0.20348837209302326 0.15625 +0 0.22965116279069767 0.65625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aadc37aef54962f2a7bb83ce41fc6a63.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aadc37aef54962f2a7bb83ce41fc6a63.txt new file mode 100644 index 0000000..335c171 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aadc37aef54962f2a7bb83ce41fc6a63.txt @@ -0,0 +1,4 @@ +0 0.5348837209302325 0.7604166666666666 0.20348837209302326 0.15625 +0 0.27906976744186046 0.20052083333333331 0.20348837209302326 0.15625 +0 0.8197674418604651 0.6901041666666666 0.20348837209302326 0.15625 +0 0.37209302325581395 0.5 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab20a003ffc7654bb720fbc672a39320.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab20a003ffc7654bb720fbc672a39320.txt new file mode 100644 index 0000000..d7f6898 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab20a003ffc7654bb720fbc672a39320.txt @@ -0,0 +1,3 @@ +0 0.45930232558139533 0.5052083333333333 0.20348837209302326 0.15625 +0 0.1511627906976744 0.5338541666666666 0.20348837209302326 0.15625 +0 0.4418604651162791 0.24739583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab20f82cf3fb2075507ceeeaac2d5cb6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab20f82cf3fb2075507ceeeaac2d5cb6.txt new file mode 100644 index 0000000..fa0e506 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab20f82cf3fb2075507ceeeaac2d5cb6.txt @@ -0,0 +1,4 @@ +0 0.375 0.140625 0.20348837209302326 0.15625 +0 0.7209302325581395 0.5833333333333333 0.20348837209302326 0.15625 +0 0.4011627906976744 0.625 0.20348837209302326 0.15625 +0 0.8343023255813954 0.10416666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab3c57d484ab0c8bca208a0d655c2e5b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab3c57d484ab0c8bca208a0d655c2e5b.txt new file mode 100644 index 0000000..f51c703 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab3c57d484ab0c8bca208a0d655c2e5b.txt @@ -0,0 +1,5 @@ +0 0.3168604651162791 0.4348958333333333 0.20348837209302326 0.15625 +0 0.12790697674418605 0.6588541666666666 0.20348837209302326 0.15625 +0 0.3866279069767442 0.1484375 0.20348837209302326 0.15625 +0 0.7761627906976744 0.5338541666666666 0.20348837209302326 0.15625 +0 0.8255813953488372 0.26041666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab622579e4dc104cd8f90dc0027b6835.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab622579e4dc104cd8f90dc0027b6835.txt new file mode 100644 index 0000000..9e74ce4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab622579e4dc104cd8f90dc0027b6835.txt @@ -0,0 +1,4 @@ +0 0.23837209302325582 0.4192708333333333 0.20348837209302326 0.15625 +0 0.8255813953488372 0.3671875 0.20348837209302326 0.15625 +0 0.6482558139534884 0.6666666666666666 0.20348837209302326 0.15625 +0 0.3488372093023256 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab780283f6bee797dabab0c67e596281.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab780283f6bee797dabab0c67e596281.txt new file mode 100644 index 0000000..f3588e1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab780283f6bee797dabab0c67e596281.txt @@ -0,0 +1,4 @@ +0 0.8197674418604651 0.3125 0.20348837209302326 0.15625 +0 0.5784883720930233 0.6692708333333333 0.20348837209302326 0.15625 +0 0.2180232558139535 0.5260416666666666 0.20348837209302326 0.15625 +0 0.4883720930232558 0.12760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab89b794693e3535e0b58539ec1669d7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab89b794693e3535e0b58539ec1669d7.txt new file mode 100644 index 0000000..22cc06a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab89b794693e3535e0b58539ec1669d7.txt @@ -0,0 +1,3 @@ +0 0.1947674418604651 0.3671875 0.20348837209302326 0.15625 +0 0.5465116279069767 0.24479166666666666 0.20348837209302326 0.15625 +0 0.5436046511627907 0.6197916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab9a8dcdda85f1d8789909803374fbea.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab9a8dcdda85f1d8789909803374fbea.txt new file mode 100644 index 0000000..260136e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ab9a8dcdda85f1d8789909803374fbea.txt @@ -0,0 +1,4 @@ +0 0.6918604651162791 0.6875 0.20348837209302326 0.15625 +0 0.7441860465116279 0.1171875 0.20348837209302326 0.15625 +0 0.2616279069767442 0.203125 0.20348837209302326 0.15625 +0 0.3226744186046512 0.4895833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aba5bec4daa6c11fdd684594778e7737.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aba5bec4daa6c11fdd684594778e7737.txt new file mode 100644 index 0000000..c82aa3b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/aba5bec4daa6c11fdd684594778e7737.txt @@ -0,0 +1,4 @@ +0 0.811046511627907 0.6041666666666666 0.20348837209302326 0.15625 +0 0.4825581395348837 0.7630208333333333 0.20348837209302326 0.15625 +0 0.47093023255813954 0.3645833333333333 0.20348837209302326 0.15625 +0 0.12790697674418605 0.2578125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ac0dbaf22bdb140be1a11c068f9698de.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ac0dbaf22bdb140be1a11c068f9698de.txt new file mode 100644 index 0000000..cae0aa0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ac0dbaf22bdb140be1a11c068f9698de.txt @@ -0,0 +1,4 @@ +0 0.32558139534883723 0.19791666666666666 0.20348837209302326 0.15625 +0 0.5581395348837209 0.7864583333333333 0.20348837209302326 0.15625 +0 0.7063953488372093 0.265625 0.20348837209302326 0.15625 +0 0.34593023255813954 0.5182291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ac87279344b5d0d4e22f91b8c2ff41a8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ac87279344b5d0d4e22f91b8c2ff41a8.txt new file mode 100644 index 0000000..e3aff3b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ac87279344b5d0d4e22f91b8c2ff41a8.txt @@ -0,0 +1,4 @@ +0 0.13953488372093023 0.3567708333333333 0.20348837209302326 0.15625 +0 0.7151162790697674 0.4921875 0.20348837209302326 0.15625 +0 0.2877906976744186 0.6848958333333333 0.20348837209302326 0.15625 +0 0.811046511627907 0.13020833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ad0138de5d88eb8dd7a7aab27947e539.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ad0138de5d88eb8dd7a7aab27947e539.txt new file mode 100644 index 0000000..52db61b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ad0138de5d88eb8dd7a7aab27947e539.txt @@ -0,0 +1,4 @@ +0 0.2005813953488372 0.140625 0.20348837209302326 0.15625 +0 0.436046511627907 0.5651041666666666 0.20348837209302326 0.15625 +0 0.6046511627906976 0.1796875 0.20348837209302326 0.15625 +0 0.8459302325581395 0.7135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ad40d44fea1e8518be56c72565cbcd59.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ad40d44fea1e8518be56c72565cbcd59.txt new file mode 100644 index 0000000..2e21890 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ad40d44fea1e8518be56c72565cbcd59.txt @@ -0,0 +1,3 @@ +0 0.2877906976744186 0.2552083333333333 0.20348837209302326 0.15625 +0 0.5901162790697674 0.4270833333333333 0.20348837209302326 0.15625 +0 0.3226744186046512 0.7890625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/add9a062cdb133e09ee686522d92f3c2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/add9a062cdb133e09ee686522d92f3c2.txt new file mode 100644 index 0000000..e238dc9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/add9a062cdb133e09ee686522d92f3c2.txt @@ -0,0 +1,4 @@ +0 0.8691860465116279 0.15625 0.20348837209302326 0.15625 +0 0.6918604651162791 0.5338541666666666 0.20348837209302326 0.15625 +0 0.37209302325581395 0.6458333333333333 0.20348837209302326 0.15625 +0 0.36627906976744184 0.15104166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ae13d3d287f61c40edb3ea2655d18ae4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ae13d3d287f61c40edb3ea2655d18ae4.txt new file mode 100644 index 0000000..eea6252 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ae13d3d287f61c40edb3ea2655d18ae4.txt @@ -0,0 +1,5 @@ +0 0.7093023255813954 0.203125 0.20348837209302326 0.15625 +0 0.622093023255814 0.5052083333333333 0.20348837209302326 0.15625 +0 0.436046511627907 0.8046875 0.20348837209302326 0.15625 +0 0.41860465116279066 0.1796875 0.20348837209302326 0.15625 +0 0.3023255813953488 0.4114583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af22ae4d9de1488b00816e6693c6394e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af22ae4d9de1488b00816e6693c6394e.txt new file mode 100644 index 0000000..574ae02 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af22ae4d9de1488b00816e6693c6394e.txt @@ -0,0 +1,4 @@ +0 0.5872093023255814 0.4036458333333333 0.20348837209302326 0.15625 +0 0.3081395348837209 0.5208333333333333 0.20348837209302326 0.15625 +0 0.5697674418604651 0.109375 0.20348837209302326 0.15625 +0 0.7790697674418604 0.7760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af3cdb723d7e28f0fb254165ba71d8b3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af3cdb723d7e28f0fb254165ba71d8b3.txt new file mode 100644 index 0000000..e35863d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af3cdb723d7e28f0fb254165ba71d8b3.txt @@ -0,0 +1,4 @@ +0 0.7034883720930233 0.625 0.20348837209302326 0.15625 +0 0.1686046511627907 0.2942708333333333 0.20348837209302326 0.15625 +0 0.12790697674418605 0.7291666666666666 0.20348837209302326 0.15625 +0 0.7790697674418604 0.2734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af5f90b0517ff108a2c089b6e8c183e9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af5f90b0517ff108a2c089b6e8c183e9.txt new file mode 100644 index 0000000..45dee10 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af5f90b0517ff108a2c089b6e8c183e9.txt @@ -0,0 +1,4 @@ +0 0.36627906976744184 0.48697916666666663 0.20348837209302326 0.15625 +0 0.7674418604651163 0.11458333333333333 0.20348837209302326 0.15625 +0 0.6598837209302325 0.4140625 0.20348837209302326 0.15625 +0 0.2616279069767442 0.25260416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af6d91402bf5bd9d18fbb5f080497ff8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af6d91402bf5bd9d18fbb5f080497ff8.txt new file mode 100644 index 0000000..5657446 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af6d91402bf5bd9d18fbb5f080497ff8.txt @@ -0,0 +1,4 @@ +0 0.14244186046511628 0.1328125 0.20348837209302326 0.15625 +0 0.7151162790697674 0.25 0.20348837209302326 0.15625 +0 0.36046511627906974 0.4505208333333333 0.20348837209302326 0.15625 +0 0.8808139534883721 0.4765625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af7e05ca9dc6e26118059bbc83f15ee2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af7e05ca9dc6e26118059bbc83f15ee2.txt new file mode 100644 index 0000000..270f72d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/af7e05ca9dc6e26118059bbc83f15ee2.txt @@ -0,0 +1,4 @@ +0 0.14244186046511628 0.3177083333333333 0.20348837209302326 0.15625 +0 0.5406976744186046 0.21354166666666666 0.20348837209302326 0.15625 +0 0.7122093023255814 0.5078125 0.20348837209302326 0.15625 +0 0.34593023255813954 0.7760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/afa66ae9a5d448ec2a2e1239026068a3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/afa66ae9a5d448ec2a2e1239026068a3.txt new file mode 100644 index 0000000..e6bd830 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/afa66ae9a5d448ec2a2e1239026068a3.txt @@ -0,0 +1,5 @@ +0 0.7005813953488372 0.35416666666666663 0.20348837209302326 0.15625 +0 0.7034883720930233 0.10416666666666666 0.20348837209302326 0.15625 +0 0.625 0.6197916666666666 0.20348837209302326 0.15625 +0 0.21511627906976744 0.28385416666666663 0.20348837209302326 0.15625 +0 0.3023255813953488 0.7135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b021c58e2f70a81cadaae120a4ac0b09.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b021c58e2f70a81cadaae120a4ac0b09.txt new file mode 100644 index 0000000..79d0951 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b021c58e2f70a81cadaae120a4ac0b09.txt @@ -0,0 +1,4 @@ +0 0.8226744186046512 0.5 0.20348837209302326 0.15625 +0 0.7296511627906976 0.24479166666666666 0.20348837209302326 0.15625 +0 0.311046511627907 0.5911458333333333 0.20348837209302326 0.15625 +0 0.22674418604651161 0.14583333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b02782fbd52d87eab17fe5c24b326e92.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b02782fbd52d87eab17fe5c24b326e92.txt new file mode 100644 index 0000000..081f50f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b02782fbd52d87eab17fe5c24b326e92.txt @@ -0,0 +1,4 @@ +0 0.125 0.6953125 0.20348837209302326 0.15625 +0 0.8284883720930233 0.40625 0.20348837209302326 0.15625 +0 0.16279069767441862 0.2708333333333333 0.20348837209302326 0.15625 +0 0.5406976744186046 0.6796875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b07b099229ce0784c0a985b8a1d9c7e9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b07b099229ce0784c0a985b8a1d9c7e9.txt new file mode 100644 index 0000000..c964e72 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b07b099229ce0784c0a985b8a1d9c7e9.txt @@ -0,0 +1,4 @@ +0 0.2877906976744186 0.2578125 0.20348837209302326 0.15625 +0 0.8023255813953488 0.2942708333333333 0.20348837209302326 0.15625 +0 0.4011627906976744 0.6510416666666666 0.20348837209302326 0.15625 +0 0.7848837209302325 0.6848958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b0c550e74255ed71c185b5c9c38f905f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b0c550e74255ed71c185b5c9c38f905f.txt new file mode 100644 index 0000000..a0cdc25 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b0c550e74255ed71c185b5c9c38f905f.txt @@ -0,0 +1,5 @@ +0 0.813953488372093 0.1640625 0.20348837209302326 0.15625 +0 0.3226744186046512 0.6536458333333333 0.20348837209302326 0.15625 +0 0.49127906976744184 0.36197916666666663 0.20348837209302326 0.15625 +0 0.6918604651162791 0.6484375 0.20348837209302326 0.15625 +0 0.1511627906976744 0.25 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b0cb4774fb649ad7cf42a61b1c88a9a3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b0cb4774fb649ad7cf42a61b1c88a9a3.txt new file mode 100644 index 0000000..2c0c817 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b0cb4774fb649ad7cf42a61b1c88a9a3.txt @@ -0,0 +1,4 @@ +0 0.2645348837209302 0.4505208333333333 0.20348837209302326 0.15625 +0 0.6918604651162791 0.2864583333333333 0.20348837209302326 0.15625 +0 0.7674418604651163 0.5651041666666666 0.20348837209302326 0.15625 +0 0.3023255813953488 0.7604166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b0db77aded4316b21d7f9d750b7d23fe.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b0db77aded4316b21d7f9d750b7d23fe.txt new file mode 100644 index 0000000..defa1c0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b0db77aded4316b21d7f9d750b7d23fe.txt @@ -0,0 +1,5 @@ +0 0.21511627906976744 0.6848958333333333 0.20348837209302326 0.15625 +0 0.688953488372093 0.6510416666666666 0.20348837209302326 0.15625 +0 0.34011627906976744 0.13020833333333331 0.20348837209302326 0.15625 +0 0.1686046511627907 0.375 0.20348837209302326 0.15625 +0 0.7761627906976744 0.17708333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b0ebc621829225814b6e2e16457842dc.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b0ebc621829225814b6e2e16457842dc.txt new file mode 100644 index 0000000..65b28e6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b0ebc621829225814b6e2e16457842dc.txt @@ -0,0 +1,3 @@ +0 0.28488372093023256 0.640625 0.20348837209302326 0.15625 +0 0.7296511627906976 0.29166666666666663 0.20348837209302326 0.15625 +0 0.6162790697674418 0.5338541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b1155e20b40430932a78807d5d6f28ed.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b1155e20b40430932a78807d5d6f28ed.txt new file mode 100644 index 0000000..3d5ff6c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b1155e20b40430932a78807d5d6f28ed.txt @@ -0,0 +1,4 @@ +0 0.4331395348837209 0.7421875 0.20348837209302326 0.15625 +0 0.37790697674418605 0.3802083333333333 0.20348837209302326 0.15625 +0 0.12790697674418605 0.12760416666666666 0.20348837209302326 0.15625 +0 0.6976744186046512 0.4348958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b17c3f2aec5ee198f8eb82e36606795a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b17c3f2aec5ee198f8eb82e36606795a.txt new file mode 100644 index 0000000..f49cc44 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b17c3f2aec5ee198f8eb82e36606795a.txt @@ -0,0 +1,3 @@ +0 0.3488372093023256 0.0859375 0.20348837209302326 0.15625 +0 0.44476744186046513 0.6770833333333333 0.20348837209302326 0.15625 +0 0.23255813953488372 0.359375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b21d921a6fe1ed762f066af97b77e37e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b21d921a6fe1ed762f066af97b77e37e.txt new file mode 100644 index 0000000..72e98b1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b21d921a6fe1ed762f066af97b77e37e.txt @@ -0,0 +1,4 @@ +0 0.5552325581395349 0.5260416666666666 0.20348837209302326 0.15625 +0 0.5261627906976745 0.24739583333333331 0.20348837209302326 0.15625 +0 0.15406976744186046 0.3177083333333333 0.20348837209302326 0.15625 +0 0.2877906976744186 0.6276041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b22ce1f95bb82dc2bf0b7de7d26eef1e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b22ce1f95bb82dc2bf0b7de7d26eef1e.txt new file mode 100644 index 0000000..70416f7 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b22ce1f95bb82dc2bf0b7de7d26eef1e.txt @@ -0,0 +1,3 @@ +0 0.5843023255813954 0.12239583333333333 0.20348837209302326 0.15625 +0 0.2761627906976744 0.625 0.20348837209302326 0.15625 +0 0.5552325581395349 0.37760416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b285a431eee55f896eece1af7fae362b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b285a431eee55f896eece1af7fae362b.txt new file mode 100644 index 0000000..7d394a2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b285a431eee55f896eece1af7fae362b.txt @@ -0,0 +1,4 @@ +0 0.438953488372093 0.22135416666666666 0.20348837209302326 0.15625 +0 0.5959302325581395 0.5859375 0.20348837209302326 0.15625 +0 0.30523255813953487 0.5 0.20348837209302326 0.15625 +0 0.7616279069767442 0.125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b2c76e9c0889c683ba9800aa6431e17e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b2c76e9c0889c683ba9800aa6431e17e.txt new file mode 100644 index 0000000..bf74a0e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b2c76e9c0889c683ba9800aa6431e17e.txt @@ -0,0 +1,4 @@ +0 0.23255813953488372 0.625 0.20348837209302326 0.15625 +0 0.8226744186046512 0.43229166666666663 0.20348837209302326 0.15625 +0 0.5348837209302325 0.7005208333333333 0.20348837209302326 0.15625 +0 0.5058139534883721 0.30729166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b2e333e8efafafffc1056cd478f6a93b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b2e333e8efafafffc1056cd478f6a93b.txt new file mode 100644 index 0000000..c7d3d53 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b2e333e8efafafffc1056cd478f6a93b.txt @@ -0,0 +1,4 @@ +0 0.7412790697674418 0.5286458333333333 0.20348837209302326 0.15625 +0 0.4883720930232558 0.23697916666666666 0.20348837209302326 0.15625 +0 0.7994186046511628 0.23958333333333331 0.20348837209302326 0.15625 +0 0.42441860465116277 0.7734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b2f36402178696779cbd5ae767761aca.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b2f36402178696779cbd5ae767761aca.txt new file mode 100644 index 0000000..6e59173 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b2f36402178696779cbd5ae767761aca.txt @@ -0,0 +1,4 @@ +0 0.5988372093023255 0.28385416666666663 0.20348837209302326 0.15625 +0 0.13662790697674418 0.4140625 0.20348837209302326 0.15625 +0 0.622093023255814 0.5911458333333333 0.20348837209302326 0.15625 +0 0.1686046511627907 0.6276041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b313d4445189b53f759366aa8cc290c1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b313d4445189b53f759366aa8cc290c1.txt new file mode 100644 index 0000000..c5316be --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b313d4445189b53f759366aa8cc290c1.txt @@ -0,0 +1,5 @@ +0 0.49709302325581395 0.75 0.20348837209302326 0.15625 +0 0.7209302325581395 0.421875 0.20348837209302326 0.15625 +0 0.8023255813953488 0.7369791666666666 0.20348837209302326 0.15625 +0 0.6686046511627907 0.15885416666666666 0.20348837209302326 0.15625 +0 0.2965116279069767 0.4348958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b33ba39bf871947275cc51c40e312f39.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b33ba39bf871947275cc51c40e312f39.txt new file mode 100644 index 0000000..1cbbfc5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b33ba39bf871947275cc51c40e312f39.txt @@ -0,0 +1,4 @@ +0 0.7267441860465116 0.32291666666666663 0.20348837209302326 0.15625 +0 0.40406976744186046 0.5390625 0.20348837209302326 0.15625 +0 0.11337209302325581 0.6458333333333333 0.20348837209302326 0.15625 +0 0.7383720930232558 0.5520833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b3ed2f6e000821a26cefe6b480784c9b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b3ed2f6e000821a26cefe6b480784c9b.txt new file mode 100644 index 0000000..a2bd4f0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b3ed2f6e000821a26cefe6b480784c9b.txt @@ -0,0 +1,5 @@ +0 0.5930232558139534 0.22395833333333331 0.20348837209302326 0.15625 +0 0.313953488372093 0.7213541666666666 0.20348837209302326 0.15625 +0 0.6162790697674418 0.5130208333333333 0.20348837209302326 0.15625 +0 0.30523255813953487 0.19270833333333331 0.20348837209302326 0.15625 +0 0.16569767441860464 0.4583333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b46e47020634c7480bd802fa7c65080b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b46e47020634c7480bd802fa7c65080b.txt new file mode 100644 index 0000000..86feba7 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b46e47020634c7480bd802fa7c65080b.txt @@ -0,0 +1,3 @@ +0 0.7238372093023255 0.43229166666666663 0.20348837209302326 0.15625 +0 0.28488372093023256 0.3567708333333333 0.20348837209302326 0.15625 +0 0.27906976744186046 0.6510416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b4c7cdb390fcf56407db19fec22bca8d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b4c7cdb390fcf56407db19fec22bca8d.txt new file mode 100644 index 0000000..ec041c3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b4c7cdb390fcf56407db19fec22bca8d.txt @@ -0,0 +1,3 @@ +0 0.2616279069767442 0.1796875 0.20348837209302326 0.15625 +0 0.3633720930232558 0.7708333333333333 0.20348837209302326 0.15625 +0 0.502906976744186 0.5286458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b4cae86b47a05979be465c64300ac09e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b4cae86b47a05979be465c64300ac09e.txt new file mode 100644 index 0000000..c9dfbd8 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b4cae86b47a05979be465c64300ac09e.txt @@ -0,0 +1,4 @@ +0 0.4273255813953488 0.36197916666666663 0.20348837209302326 0.15625 +0 0.8023255813953488 0.7317708333333333 0.20348837209302326 0.15625 +0 0.18895348837209303 0.7630208333333333 0.20348837209302326 0.15625 +0 0.7412790697674418 0.15104166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b518851c1217f7d4a074df1a43fdb82f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b518851c1217f7d4a074df1a43fdb82f.txt new file mode 100644 index 0000000..1c48ffa --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b518851c1217f7d4a074df1a43fdb82f.txt @@ -0,0 +1,4 @@ +0 0.5232558139534884 0.5859375 0.20348837209302326 0.15625 +0 0.22093023255813954 0.6458333333333333 0.20348837209302326 0.15625 +0 0.313953488372093 0.265625 0.20348837209302326 0.15625 +0 0.8372093023255813 0.4505208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b59366c05f0725f5eaaa0e87abc9b329.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b59366c05f0725f5eaaa0e87abc9b329.txt new file mode 100644 index 0000000..3de71e1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b59366c05f0725f5eaaa0e87abc9b329.txt @@ -0,0 +1,5 @@ +0 0.6424418604651163 0.22135416666666666 0.20348837209302326 0.15625 +0 0.8284883720930233 0.5130208333333333 0.20348837209302326 0.15625 +0 0.45348837209302323 0.6432291666666666 0.20348837209302326 0.15625 +0 0.27325581395348836 0.3645833333333333 0.20348837209302326 0.15625 +0 0.2238372093023256 0.13541666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b5c1a37feeb665781b937a84bb0389a1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b5c1a37feeb665781b937a84bb0389a1.txt new file mode 100644 index 0000000..920d265 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b5c1a37feeb665781b937a84bb0389a1.txt @@ -0,0 +1,5 @@ +0 0.7558139534883721 0.5755208333333333 0.20348837209302326 0.15625 +0 0.11918604651162791 0.21875 0.20348837209302326 0.15625 +0 0.6656976744186046 0.12760416666666666 0.20348837209302326 0.15625 +0 0.3226744186046512 0.7213541666666666 0.20348837209302326 0.15625 +0 0.4738372093023256 0.4453125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b5dcc36c30f6e4c6070a805973bb9770.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b5dcc36c30f6e4c6070a805973bb9770.txt new file mode 100644 index 0000000..896244b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b5dcc36c30f6e4c6070a805973bb9770.txt @@ -0,0 +1,5 @@ +0 0.7267441860465116 0.4973958333333333 0.20348837209302326 0.15625 +0 0.41860465116279066 0.4739583333333333 0.20348837209302326 0.15625 +0 0.25872093023255816 0.16666666666666666 0.20348837209302326 0.15625 +0 0.6773255813953488 0.09635416666666666 0.20348837209302326 0.15625 +0 0.21220930232558138 0.7213541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b61e121949adb85ef4f86bd3f050eb5a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b61e121949adb85ef4f86bd3f050eb5a.txt new file mode 100644 index 0000000..f5461e1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b61e121949adb85ef4f86bd3f050eb5a.txt @@ -0,0 +1,4 @@ +0 0.8052325581395349 0.17708333333333331 0.20348837209302326 0.15625 +0 0.44476744186046513 0.25 0.20348837209302326 0.15625 +0 0.28488372093023256 0.7317708333333333 0.20348837209302326 0.15625 +0 0.25 0.5 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b66c6447d452f9b13cc50cb0f8c03636.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b66c6447d452f9b13cc50cb0f8c03636.txt new file mode 100644 index 0000000..9fc1805 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b66c6447d452f9b13cc50cb0f8c03636.txt @@ -0,0 +1,5 @@ +0 0.7906976744186046 0.546875 0.20348837209302326 0.15625 +0 0.2936046511627907 0.765625 0.20348837209302326 0.15625 +0 0.375 0.22395833333333331 0.20348837209302326 0.15625 +0 0.25290697674418605 0.46354166666666663 0.20348837209302326 0.15625 +0 0.7645348837209303 0.1875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b694866d63fb09d8a512c9179126e28e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b694866d63fb09d8a512c9179126e28e.txt new file mode 100644 index 0000000..dabbe3c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b694866d63fb09d8a512c9179126e28e.txt @@ -0,0 +1,4 @@ +0 0.6947674418604651 0.15364583333333331 0.20348837209302326 0.15625 +0 0.3168604651162791 0.4609375 0.20348837209302326 0.15625 +0 0.8052325581395349 0.5052083333333333 0.20348837209302326 0.15625 +0 0.27906976744186046 0.1875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b699a9ce2c12fcd1a06b80a34ce477e5.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b699a9ce2c12fcd1a06b80a34ce477e5.txt new file mode 100644 index 0000000..09cbaf7 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b699a9ce2c12fcd1a06b80a34ce477e5.txt @@ -0,0 +1,4 @@ +0 0.6656976744186046 0.36979166666666663 0.20348837209302326 0.15625 +0 0.2645348837209302 0.43229166666666663 0.20348837209302326 0.15625 +0 0.24127906976744184 0.6744791666666666 0.20348837209302326 0.15625 +0 0.7267441860465116 0.7682291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b6b7c45763ffaff491fd4137f940602b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b6b7c45763ffaff491fd4137f940602b.txt new file mode 100644 index 0000000..d059b5a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b6b7c45763ffaff491fd4137f940602b.txt @@ -0,0 +1,5 @@ +0 0.7180232558139534 0.26041666666666663 0.20348837209302326 0.15625 +0 0.43023255813953487 0.484375 0.20348837209302326 0.15625 +0 0.7238372093023255 0.7161458333333333 0.20348837209302326 0.15625 +0 0.22965116279069767 0.09375 0.20348837209302326 0.15625 +0 0.10755813953488372 0.46354166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b6b9625dcb895b6dedcaa1a65d5589a1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b6b9625dcb895b6dedcaa1a65d5589a1.txt new file mode 100644 index 0000000..f3aaacb --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b6b9625dcb895b6dedcaa1a65d5589a1.txt @@ -0,0 +1,3 @@ +0 0.3430232558139535 0.7005208333333333 0.20348837209302326 0.15625 +0 0.22093023255813954 0.234375 0.20348837209302326 0.15625 +0 0.7558139534883721 0.5078125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b6bd0b66e0d14e44e3cd0fd48cdf37fb.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b6bd0b66e0d14e44e3cd0fd48cdf37fb.txt new file mode 100644 index 0000000..a1cfa31 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b6bd0b66e0d14e44e3cd0fd48cdf37fb.txt @@ -0,0 +1,4 @@ +0 0.686046511627907 0.53125 0.20348837209302326 0.15625 +0 0.4069767441860465 0.14583333333333331 0.20348837209302326 0.15625 +0 0.4796511627906977 0.7552083333333333 0.20348837209302326 0.15625 +0 0.29941860465116277 0.44010416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b6c214cc24e8f014c0074b2460cf8c4d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b6c214cc24e8f014c0074b2460cf8c4d.txt new file mode 100644 index 0000000..40d049a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b6c214cc24e8f014c0074b2460cf8c4d.txt @@ -0,0 +1,4 @@ +0 0.6133720930232558 0.5755208333333333 0.20348837209302326 0.15625 +0 0.3081395348837209 0.10677083333333333 0.20348837209302326 0.15625 +0 0.6976744186046512 0.3098958333333333 0.20348837209302326 0.15625 +0 0.37790697674418605 0.3359375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b70ba7a811a4a34a04aca8acc9ab6e04.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b70ba7a811a4a34a04aca8acc9ab6e04.txt new file mode 100644 index 0000000..a12beeb --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b70ba7a811a4a34a04aca8acc9ab6e04.txt @@ -0,0 +1,5 @@ +0 0.15988372093023256 0.6510416666666666 0.20348837209302326 0.15625 +0 0.688953488372093 0.13541666666666666 0.20348837209302326 0.15625 +0 0.311046511627907 0.4114583333333333 0.20348837209302326 0.15625 +0 0.7180232558139534 0.4739583333333333 0.20348837209302326 0.15625 +0 0.24127906976744184 0.1484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b715a54323e31072a4f61fe0a7c590b5.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b715a54323e31072a4f61fe0a7c590b5.txt new file mode 100644 index 0000000..f036d79 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b715a54323e31072a4f61fe0a7c590b5.txt @@ -0,0 +1,4 @@ +0 0.8343023255813954 0.23177083333333331 0.20348837209302326 0.15625 +0 0.5203488372093024 0.48697916666666663 0.20348837209302326 0.15625 +0 0.16569767441860464 0.5208333333333333 0.20348837209302326 0.15625 +0 0.29941860465116277 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b725b0f15c9e35827b939d571f3cc4cf.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b725b0f15c9e35827b939d571f3cc4cf.txt new file mode 100644 index 0000000..692c3a6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b725b0f15c9e35827b939d571f3cc4cf.txt @@ -0,0 +1,4 @@ +0 0.2441860465116279 0.5 0.20348837209302326 0.15625 +0 0.4883720930232558 0.23177083333333331 0.20348837209302326 0.15625 +0 0.8023255813953488 0.6692708333333333 0.20348837209302326 0.15625 +0 0.7616279069767442 0.26822916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b755aacaa2cc98b607fa1324e9bfe7a8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b755aacaa2cc98b607fa1324e9bfe7a8.txt new file mode 100644 index 0000000..781ad1c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b755aacaa2cc98b607fa1324e9bfe7a8.txt @@ -0,0 +1,2 @@ +0 0.2703488372093023 0.41666666666666663 0.20348837209302326 0.15625 +0 0.622093023255814 0.390625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b844017030d28071aac4d16e94dac7b7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b844017030d28071aac4d16e94dac7b7.txt new file mode 100644 index 0000000..4f09ed7 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b844017030d28071aac4d16e94dac7b7.txt @@ -0,0 +1,4 @@ +0 0.5813953488372093 0.296875 0.20348837209302326 0.15625 +0 0.13372093023255813 0.6484375 0.20348837209302326 0.15625 +0 0.22965116279069767 0.36197916666666663 0.20348837209302326 0.15625 +0 0.7383720930232558 0.6614583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b8512bcde0bd03f388666d453199912d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b8512bcde0bd03f388666d453199912d.txt new file mode 100644 index 0000000..2b8631f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b8512bcde0bd03f388666d453199912d.txt @@ -0,0 +1,4 @@ +0 0.7267441860465116 0.13541666666666666 0.20348837209302326 0.15625 +0 0.2936046511627907 0.5807291666666666 0.20348837209302326 0.15625 +0 0.6482558139534884 0.7552083333333333 0.20348837209302326 0.15625 +0 0.6046511627906976 0.5286458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b8806f0c9e5c5ca93fc549edf2493f63.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b8806f0c9e5c5ca93fc549edf2493f63.txt new file mode 100644 index 0000000..e200930 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b8806f0c9e5c5ca93fc549edf2493f63.txt @@ -0,0 +1,5 @@ +0 0.313953488372093 0.3125 0.20348837209302326 0.15625 +0 0.8023255813953488 0.59375 0.20348837209302326 0.15625 +0 0.7761627906976744 0.09375 0.20348837209302326 0.15625 +0 0.5058139534883721 0.5572916666666666 0.20348837209302326 0.15625 +0 0.12790697674418605 0.6484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b899d82377c5a9648da29177d541e451.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b899d82377c5a9648da29177d541e451.txt new file mode 100644 index 0000000..3b1229b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b899d82377c5a9648da29177d541e451.txt @@ -0,0 +1,4 @@ +0 0.28488372093023256 0.6536458333333333 0.20348837209302326 0.15625 +0 0.6424418604651163 0.22395833333333331 0.20348837209302326 0.15625 +0 0.625 0.7239583333333333 0.20348837209302326 0.15625 +0 0.23837209302325582 0.1640625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b8bfe236cb667466794b7ba4e7c5ff26.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b8bfe236cb667466794b7ba4e7c5ff26.txt new file mode 100644 index 0000000..e337107 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b8bfe236cb667466794b7ba4e7c5ff26.txt @@ -0,0 +1,4 @@ +0 0.7151162790697674 0.421875 0.20348837209302326 0.15625 +0 0.3430232558139535 0.0859375 0.20348837209302326 0.15625 +0 0.40406976744186046 0.7369791666666666 0.20348837209302326 0.15625 +0 0.16569767441860464 0.3333333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b8d38ca35d7b4556fa28dc08ace88a52.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b8d38ca35d7b4556fa28dc08ace88a52.txt new file mode 100644 index 0000000..740d133 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b8d38ca35d7b4556fa28dc08ace88a52.txt @@ -0,0 +1,3 @@ +0 0.1569767441860465 0.4140625 0.20348837209302326 0.15625 +0 0.8052325581395349 0.21354166666666666 0.20348837209302326 0.15625 +0 0.4883720930232558 0.5338541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b91179459dce704eacd8e56d47d4cd35.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b91179459dce704eacd8e56d47d4cd35.txt new file mode 100644 index 0000000..7504622 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b91179459dce704eacd8e56d47d4cd35.txt @@ -0,0 +1,4 @@ +0 0.5901162790697674 0.6979166666666666 0.20348837209302326 0.15625 +0 0.3546511627906977 0.2109375 0.20348837209302326 0.15625 +0 0.25 0.7213541666666666 0.20348837209302326 0.15625 +0 0.7732558139534884 0.38541666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b93a9f8a93cb56dd057eca621f377e39.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b93a9f8a93cb56dd057eca621f377e39.txt new file mode 100644 index 0000000..b49b4e9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b93a9f8a93cb56dd057eca621f377e39.txt @@ -0,0 +1,4 @@ +0 0.5872093023255814 0.6484375 0.20348837209302326 0.15625 +0 0.37209302325581395 0.36979166666666663 0.20348837209302326 0.15625 +0 0.2616279069767442 0.140625 0.20348837209302326 0.15625 +0 0.6191860465116279 0.12760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b97ff6246886a6d310f6547b054871a6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b97ff6246886a6d310f6547b054871a6.txt new file mode 100644 index 0000000..b42da68 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b97ff6246886a6d310f6547b054871a6.txt @@ -0,0 +1,5 @@ +0 0.7848837209302325 0.15885416666666666 0.20348837209302326 0.15625 +0 0.6627906976744186 0.3984375 0.20348837209302326 0.15625 +0 0.2616279069767442 0.21614583333333331 0.20348837209302326 0.15625 +0 0.5843023255813954 0.7161458333333333 0.20348837209302326 0.15625 +0 0.3633720930232558 0.4348958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b998e5ec5c52dc0a189d0c13e39735d5.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b998e5ec5c52dc0a189d0c13e39735d5.txt new file mode 100644 index 0000000..15e136d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b998e5ec5c52dc0a189d0c13e39735d5.txt @@ -0,0 +1,4 @@ +0 0.6453488372093024 0.5390625 0.20348837209302326 0.15625 +0 0.27325581395348836 0.4270833333333333 0.20348837209302326 0.15625 +0 0.6133720930232558 0.2942708333333333 0.20348837209302326 0.15625 +0 0.12209302325581395 0.7421875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b9a45fa17c93ae5367db8f88a3b4b78e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b9a45fa17c93ae5367db8f88a3b4b78e.txt new file mode 100644 index 0000000..107069f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b9a45fa17c93ae5367db8f88a3b4b78e.txt @@ -0,0 +1,5 @@ +0 0.17151162790697674 0.3645833333333333 0.20348837209302326 0.15625 +0 0.31976744186046513 0.7578125 0.20348837209302326 0.15625 +0 0.7558139534883721 0.5989583333333333 0.20348837209302326 0.15625 +0 0.6046511627906976 0.15885416666666666 0.20348837209302326 0.15625 +0 0.17151162790697674 0.13020833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b9b19de7ac9e3f0aff0fb1b0c4879140.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b9b19de7ac9e3f0aff0fb1b0c4879140.txt new file mode 100644 index 0000000..e06ee23 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/b9b19de7ac9e3f0aff0fb1b0c4879140.txt @@ -0,0 +1,4 @@ +0 0.3168604651162791 0.5 0.20348837209302326 0.15625 +0 0.6133720930232558 0.7317708333333333 0.20348837209302326 0.15625 +0 0.5261627906976745 0.1796875 0.20348837209302326 0.15625 +0 0.2005813953488372 0.7760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ba61cdbe4e7a38a43a5d2256d18d9870.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ba61cdbe4e7a38a43a5d2256d18d9870.txt new file mode 100644 index 0000000..f47c5a4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ba61cdbe4e7a38a43a5d2256d18d9870.txt @@ -0,0 +1,4 @@ +0 0.34011627906976744 0.390625 0.20348837209302326 0.15625 +0 0.7267441860465116 0.14583333333333331 0.20348837209302326 0.15625 +0 0.7906976744186046 0.4609375 0.20348837209302326 0.15625 +0 0.6831395348837209 0.7395833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ba8d0b375448ea588b520eccb6dd0d74.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ba8d0b375448ea588b520eccb6dd0d74.txt new file mode 100644 index 0000000..9c3f20c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ba8d0b375448ea588b520eccb6dd0d74.txt @@ -0,0 +1,3 @@ +0 0.6744186046511628 0.7421875 0.20348837209302326 0.15625 +0 0.7674418604651163 0.14322916666666666 0.20348837209302326 0.15625 +0 0.26744186046511625 0.15885416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/baba6733f7ae96945cee14f6842b230c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/baba6733f7ae96945cee14f6842b230c.txt new file mode 100644 index 0000000..d09e308 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/baba6733f7ae96945cee14f6842b230c.txt @@ -0,0 +1,4 @@ +0 0.25290697674418605 0.4661458333333333 0.20348837209302326 0.15625 +0 0.6424418604651163 0.10677083333333333 0.20348837209302326 0.15625 +0 0.12209302325581395 0.7682291666666666 0.20348837209302326 0.15625 +0 0.686046511627907 0.46354166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bacf33b57426360043832fc29d64e186.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bacf33b57426360043832fc29d64e186.txt new file mode 100644 index 0000000..21dc8c9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bacf33b57426360043832fc29d64e186.txt @@ -0,0 +1,4 @@ +0 0.25872093023255816 0.36979166666666663 0.20348837209302326 0.15625 +0 0.811046511627907 0.546875 0.20348837209302326 0.15625 +0 0.4127906976744186 0.7526041666666666 0.20348837209302326 0.15625 +0 0.811046511627907 0.2552083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bb07b0ab437edef64a9d7f69e7b063f9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bb07b0ab437edef64a9d7f69e7b063f9.txt new file mode 100644 index 0000000..2697f86 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bb07b0ab437edef64a9d7f69e7b063f9.txt @@ -0,0 +1,5 @@ +0 0.5436046511627907 0.6510416666666666 0.20348837209302326 0.15625 +0 0.7906976744186046 0.2864583333333333 0.20348837209302326 0.15625 +0 0.8604651162790697 0.5807291666666666 0.20348837209302326 0.15625 +0 0.48546511627906974 0.17447916666666666 0.20348837209302326 0.15625 +0 0.10755813953488372 0.7395833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bb1a3899de55a61ad453b19ed3649ca1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bb1a3899de55a61ad453b19ed3649ca1.txt new file mode 100644 index 0000000..2a7bbe6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bb1a3899de55a61ad453b19ed3649ca1.txt @@ -0,0 +1,3 @@ +0 0.6656976744186046 0.6484375 0.20348837209302326 0.15625 +0 0.6191860465116279 0.40625 0.20348837209302326 0.15625 +0 0.20930232558139533 0.7630208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bbb47f9068532c006e71213011bd9f17.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bbb47f9068532c006e71213011bd9f17.txt new file mode 100644 index 0000000..d58296f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bbb47f9068532c006e71213011bd9f17.txt @@ -0,0 +1,4 @@ +0 0.3488372093023256 0.16927083333333331 0.20348837209302326 0.15625 +0 0.5872093023255814 0.7083333333333333 0.20348837209302326 0.15625 +0 0.24709302325581395 0.5442708333333333 0.20348837209302326 0.15625 +0 0.7122093023255814 0.3515625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bc16f9c82b95c22ca419a9f55f7a4b15.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bc16f9c82b95c22ca419a9f55f7a4b15.txt new file mode 100644 index 0000000..4732090 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bc16f9c82b95c22ca419a9f55f7a4b15.txt @@ -0,0 +1,3 @@ +0 0.6511627906976745 0.4739583333333333 0.20348837209302326 0.15625 +0 0.36046511627906974 0.6354166666666666 0.20348837209302326 0.15625 +0 0.2761627906976744 0.19270833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bc531fca43eba674a8760b3042138cd5.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bc531fca43eba674a8760b3042138cd5.txt new file mode 100644 index 0000000..98734d5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bc531fca43eba674a8760b3042138cd5.txt @@ -0,0 +1,4 @@ +0 0.7906976744186046 0.6796875 0.20348837209302326 0.15625 +0 0.24127906976744184 0.43229166666666663 0.20348837209302326 0.15625 +0 0.8226744186046512 0.23697916666666666 0.20348837209302326 0.15625 +0 0.45930232558139533 0.7447916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bc61071b0b4d28a95323d661da61b21d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bc61071b0b4d28a95323d661da61b21d.txt new file mode 100644 index 0000000..cf0affb --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bc61071b0b4d28a95323d661da61b21d.txt @@ -0,0 +1,5 @@ +0 0.19767441860465115 0.15364583333333331 0.20348837209302326 0.15625 +0 0.5784883720930233 0.5052083333333333 0.20348837209302326 0.15625 +0 0.5872093023255814 0.7604166666666666 0.20348837209302326 0.15625 +0 0.1511627906976744 0.5130208333333333 0.20348837209302326 0.15625 +0 0.5087209302325582 0.2630208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bc8a2e588cfc24e47f152bad38a47ee8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bc8a2e588cfc24e47f152bad38a47ee8.txt new file mode 100644 index 0000000..b5aa161 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bc8a2e588cfc24e47f152bad38a47ee8.txt @@ -0,0 +1,4 @@ +0 0.7994186046511628 0.15625 0.20348837209302326 0.15625 +0 0.8546511627906976 0.7708333333333333 0.20348837209302326 0.15625 +0 0.43023255813953487 0.7135416666666666 0.20348837209302326 0.15625 +0 0.2616279069767442 0.43229166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bcbff27987e033a77bdff4adde10d377.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bcbff27987e033a77bdff4adde10d377.txt new file mode 100644 index 0000000..2e9cf23 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bcbff27987e033a77bdff4adde10d377.txt @@ -0,0 +1,4 @@ +0 0.2005813953488372 0.6953125 0.20348837209302326 0.15625 +0 0.7063953488372093 0.11197916666666666 0.20348837209302326 0.15625 +0 0.6598837209302325 0.41666666666666663 0.20348837209302326 0.15625 +0 0.1686046511627907 0.36979166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bd1fec8e38800e69e7ee0f036bc63c70.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bd1fec8e38800e69e7ee0f036bc63c70.txt new file mode 100644 index 0000000..3128f8a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bd1fec8e38800e69e7ee0f036bc63c70.txt @@ -0,0 +1,4 @@ +0 0.4273255813953488 0.125 0.20348837209302326 0.15625 +0 0.23837209302325582 0.5651041666666666 0.20348837209302326 0.15625 +0 0.6947674418604651 0.703125 0.20348837209302326 0.15625 +0 0.7034883720930233 0.36197916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bd738a5603e87873df7ffd3dbe6ac8da.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bd738a5603e87873df7ffd3dbe6ac8da.txt new file mode 100644 index 0000000..9112327 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bd738a5603e87873df7ffd3dbe6ac8da.txt @@ -0,0 +1,4 @@ +0 0.688953488372093 0.71875 0.20348837209302326 0.15625 +0 0.48546511627906974 0.3020833333333333 0.20348837209302326 0.15625 +0 0.14825581395348836 0.4427083333333333 0.20348837209302326 0.15625 +0 0.1511627906976744 0.15625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bd79800b60920e5af161c9d59d1b6b1d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bd79800b60920e5af161c9d59d1b6b1d.txt new file mode 100644 index 0000000..e623f95 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bd79800b60920e5af161c9d59d1b6b1d.txt @@ -0,0 +1,4 @@ +0 0.4796511627906977 0.6041666666666666 0.20348837209302326 0.15625 +0 0.21220930232558138 0.14583333333333331 0.20348837209302326 0.15625 +0 0.8023255813953488 0.765625 0.20348837209302326 0.15625 +0 0.5261627906976745 0.109375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bdd6eafea84a93540a5071822b121202.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bdd6eafea84a93540a5071822b121202.txt new file mode 100644 index 0000000..5d52085 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bdd6eafea84a93540a5071822b121202.txt @@ -0,0 +1,5 @@ +0 0.37209302325581395 0.3984375 0.20348837209302326 0.15625 +0 0.2616279069767442 0.6953125 0.20348837209302326 0.15625 +0 0.7848837209302325 0.23177083333333331 0.20348837209302326 0.15625 +0 0.3226744186046512 0.13020833333333331 0.20348837209302326 0.15625 +0 0.688953488372093 0.5078125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/be55a1c87bf1113731f813cf4d9ee505.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/be55a1c87bf1113731f813cf4d9ee505.txt new file mode 100644 index 0000000..306838f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/be55a1c87bf1113731f813cf4d9ee505.txt @@ -0,0 +1,4 @@ +0 0.23546511627906977 0.43229166666666663 0.20348837209302326 0.15625 +0 0.6656976744186046 0.6927083333333333 0.20348837209302326 0.15625 +0 0.6569767441860465 0.46875 0.20348837209302326 0.15625 +0 0.5552325581395349 0.18489583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/be60746abb5738d62705f2d83ef94c28.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/be60746abb5738d62705f2d83ef94c28.txt new file mode 100644 index 0000000..b083e40 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/be60746abb5738d62705f2d83ef94c28.txt @@ -0,0 +1,3 @@ +0 0.6104651162790697 0.3671875 0.20348837209302326 0.15625 +0 0.7906976744186046 0.5807291666666666 0.20348837209302326 0.15625 +0 0.20930232558139533 0.46875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bf1bd13cadb47854d58011eb951f09a8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bf1bd13cadb47854d58011eb951f09a8.txt new file mode 100644 index 0000000..425d1d3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bf1bd13cadb47854d58011eb951f09a8.txt @@ -0,0 +1,4 @@ +0 0.5668604651162791 0.3020833333333333 0.20348837209302326 0.15625 +0 0.39825581395348836 0.5859375 0.20348837209302326 0.15625 +0 0.11627906976744186 0.18229166666666666 0.20348837209302326 0.15625 +0 0.7732558139534884 0.5104166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bf3d15455b55b06f73e30fa8e7e74eb8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bf3d15455b55b06f73e30fa8e7e74eb8.txt new file mode 100644 index 0000000..55afc2d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bf3d15455b55b06f73e30fa8e7e74eb8.txt @@ -0,0 +1,5 @@ +0 0.10755813953488372 0.7890625 0.20348837209302326 0.15625 +0 0.5290697674418604 0.29947916666666663 0.20348837209302326 0.15625 +0 0.6656976744186046 0.7630208333333333 0.20348837209302326 0.15625 +0 0.25 0.5520833333333333 0.20348837209302326 0.15625 +0 0.18023255813953487 0.109375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bfb2b5cfa25f54dad21b1e622667b82f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bfb2b5cfa25f54dad21b1e622667b82f.txt new file mode 100644 index 0000000..07ac64f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bfb2b5cfa25f54dad21b1e622667b82f.txt @@ -0,0 +1,2 @@ +0 0.6715116279069767 0.38541666666666663 0.20348837209302326 0.15625 +0 0.25 0.2890625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bfb848fe4c0383bb780a3d463cf7a55c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bfb848fe4c0383bb780a3d463cf7a55c.txt new file mode 100644 index 0000000..a198ee2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/bfb848fe4c0383bb780a3d463cf7a55c.txt @@ -0,0 +1,4 @@ +0 0.7936046511627907 0.09635416666666666 0.20348837209302326 0.15625 +0 0.5232558139534884 0.796875 0.20348837209302326 0.15625 +0 0.8081395348837209 0.4453125 0.20348837209302326 0.15625 +0 0.37209302325581395 0.4348958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c01d1b790183f1317221ed5ac419b22b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c01d1b790183f1317221ed5ac419b22b.txt new file mode 100644 index 0000000..1667b39 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c01d1b790183f1317221ed5ac419b22b.txt @@ -0,0 +1,5 @@ +0 0.8197674418604651 0.5989583333333333 0.20348837209302326 0.15625 +0 0.42441860465116277 0.2708333333333333 0.20348837209302326 0.15625 +0 0.22674418604651161 0.5286458333333333 0.20348837209302326 0.15625 +0 0.4825581395348837 0.7135416666666666 0.20348837209302326 0.15625 +0 0.14534883720930233 0.7942708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c01fb35b68ee14941f5fef510fd245b4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c01fb35b68ee14941f5fef510fd245b4.txt new file mode 100644 index 0000000..17fe1a3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c01fb35b68ee14941f5fef510fd245b4.txt @@ -0,0 +1,5 @@ +0 0.4883720930232558 0.6041666666666666 0.20348837209302326 0.15625 +0 0.45348837209302323 0.09375 0.20348837209302326 0.15625 +0 0.16569767441860464 0.5390625 0.20348837209302326 0.15625 +0 0.8197674418604651 0.40625 0.20348837209302326 0.15625 +0 0.18313953488372092 0.203125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c01fd6ee1f631cd746a981cc5a56631c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c01fd6ee1f631cd746a981cc5a56631c.txt new file mode 100644 index 0000000..a81b4db --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c01fd6ee1f631cd746a981cc5a56631c.txt @@ -0,0 +1,5 @@ +0 0.5203488372093024 0.1640625 0.20348837209302326 0.15625 +0 0.5959302325581395 0.6276041666666666 0.20348837209302326 0.15625 +0 0.15988372093023256 0.2708333333333333 0.20348837209302326 0.15625 +0 0.19767441860465115 0.7135416666666666 0.20348837209302326 0.15625 +0 0.8633720930232558 0.2421875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c122f206d967b08f4bb4a7aefb7d566e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c122f206d967b08f4bb4a7aefb7d566e.txt new file mode 100644 index 0000000..d200130 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c122f206d967b08f4bb4a7aefb7d566e.txt @@ -0,0 +1,3 @@ +0 0.5813953488372093 0.59375 0.20348837209302326 0.15625 +0 0.2936046511627907 0.375 0.20348837209302326 0.15625 +0 0.6831395348837209 0.12760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c1f4a45ee5e1f363d12e03f66c2c2ef3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c1f4a45ee5e1f363d12e03f66c2c2ef3.txt new file mode 100644 index 0000000..d4d8a79 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c1f4a45ee5e1f363d12e03f66c2c2ef3.txt @@ -0,0 +1,4 @@ +0 0.6424418604651163 0.7552083333333333 0.20348837209302326 0.15625 +0 0.125 0.37760416666666663 0.20348837209302326 0.15625 +0 0.5 0.1484375 0.20348837209302326 0.15625 +0 0.5901162790697674 0.4973958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c218dc86cb609e450e5e0b3e2735bc37.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c218dc86cb609e450e5e0b3e2735bc37.txt new file mode 100644 index 0000000..79631ac --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c218dc86cb609e450e5e0b3e2735bc37.txt @@ -0,0 +1,5 @@ +0 0.4796511627906977 0.16666666666666666 0.20348837209302326 0.15625 +0 0.1744186046511628 0.6848958333333333 0.20348837209302326 0.15625 +0 0.622093023255814 0.578125 0.20348837209302326 0.15625 +0 0.14534883720930233 0.13020833333333331 0.20348837209302326 0.15625 +0 0.8517441860465116 0.16666666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c27180332a1e1390501a20a336afd0d7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c27180332a1e1390501a20a336afd0d7.txt new file mode 100644 index 0000000..3e184b3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c27180332a1e1390501a20a336afd0d7.txt @@ -0,0 +1,5 @@ +0 0.8197674418604651 0.26822916666666663 0.20348837209302326 0.15625 +0 0.4127906976744186 0.4114583333333333 0.20348837209302326 0.15625 +0 0.6802325581395349 0.734375 0.20348837209302326 0.15625 +0 0.13662790697674418 0.7760416666666666 0.20348837209302326 0.15625 +0 0.32848837209302323 0.12760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c298f9d8f0b021fe164c27607aa690df.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c298f9d8f0b021fe164c27607aa690df.txt new file mode 100644 index 0000000..a8bc83e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c298f9d8f0b021fe164c27607aa690df.txt @@ -0,0 +1,4 @@ +0 0.7819767441860465 0.6536458333333333 0.20348837209302326 0.15625 +0 0.14244186046511628 0.7473958333333333 0.20348837209302326 0.15625 +0 0.5203488372093024 0.22916666666666666 0.20348837209302326 0.15625 +0 0.15988372093023256 0.4375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c2af5b57f6e8e503dc2d7925fefa51ee.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c2af5b57f6e8e503dc2d7925fefa51ee.txt new file mode 100644 index 0000000..5210934 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c2af5b57f6e8e503dc2d7925fefa51ee.txt @@ -0,0 +1,5 @@ +0 0.20348837209302326 0.13541666666666666 0.20348837209302326 0.15625 +0 0.5203488372093024 0.3567708333333333 0.20348837209302326 0.15625 +0 0.7441860465116279 0.1015625 0.20348837209302326 0.15625 +0 0.8575581395348837 0.75 0.20348837209302326 0.15625 +0 0.436046511627907 0.6744791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c2e7b880f0f6a45836efa3445d86834a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c2e7b880f0f6a45836efa3445d86834a.txt new file mode 100644 index 0000000..6b00956 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c2e7b880f0f6a45836efa3445d86834a.txt @@ -0,0 +1,4 @@ +0 0.8546511627906976 0.6432291666666666 0.20348837209302326 0.15625 +0 0.125 0.21614583333333331 0.20348837209302326 0.15625 +0 0.2761627906976744 0.5364583333333333 0.20348837209302326 0.15625 +0 0.4418604651162791 0.7578125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c367b4ff98810bd8ebb03aed1eb7fdf0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c367b4ff98810bd8ebb03aed1eb7fdf0.txt new file mode 100644 index 0000000..4e22429 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c367b4ff98810bd8ebb03aed1eb7fdf0.txt @@ -0,0 +1,5 @@ +0 0.7441860465116279 0.5364583333333333 0.20348837209302326 0.15625 +0 0.2441860465116279 0.4583333333333333 0.20348837209302326 0.15625 +0 0.4476744186046512 0.10677083333333333 0.20348837209302326 0.15625 +0 0.7761627906976744 0.21354166666666666 0.20348837209302326 0.15625 +0 0.7674418604651163 0.7604166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c3ea24701ce2c070a187332432d69924.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c3ea24701ce2c070a187332432d69924.txt new file mode 100644 index 0000000..f006341 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c3ea24701ce2c070a187332432d69924.txt @@ -0,0 +1,4 @@ +0 0.22674418604651161 0.6484375 0.20348837209302326 0.15625 +0 0.4622093023255814 0.37760416666666663 0.20348837209302326 0.15625 +0 0.7441860465116279 0.6744791666666666 0.20348837209302326 0.15625 +0 0.8197674418604651 0.20052083333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c3f218074a5fa24554f35d41c7a8ed7a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c3f218074a5fa24554f35d41c7a8ed7a.txt new file mode 100644 index 0000000..4b3d77a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c3f218074a5fa24554f35d41c7a8ed7a.txt @@ -0,0 +1,4 @@ +0 0.2616279069767442 0.6328125 0.20348837209302326 0.15625 +0 0.2819767441860465 0.27604166666666663 0.20348837209302326 0.15625 +0 0.8459302325581395 0.140625 0.20348837209302326 0.15625 +0 0.8081395348837209 0.5130208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c41d724b4da6f27acf2f82dd6e01d7cf.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c41d724b4da6f27acf2f82dd6e01d7cf.txt new file mode 100644 index 0000000..1b29471 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c41d724b4da6f27acf2f82dd6e01d7cf.txt @@ -0,0 +1,4 @@ +0 0.47674418604651164 0.6328125 0.20348837209302326 0.15625 +0 0.5813953488372093 0.23697916666666666 0.20348837209302326 0.15625 +0 0.7761627906976744 0.5598958333333333 0.20348837209302326 0.15625 +0 0.2238372093023256 0.3020833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c5c10a2a03b99951c9bb7dd165699ae1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c5c10a2a03b99951c9bb7dd165699ae1.txt new file mode 100644 index 0000000..0f738b2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c5c10a2a03b99951c9bb7dd165699ae1.txt @@ -0,0 +1,3 @@ +0 0.5203488372093024 0.1484375 0.20348837209302326 0.15625 +0 0.6715116279069767 0.6640625 0.20348837209302326 0.15625 +0 0.7093023255813954 0.4296875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c5fc663fc131d710865184d950a8e6ae.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c5fc663fc131d710865184d950a8e6ae.txt new file mode 100644 index 0000000..ec97e53 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c5fc663fc131d710865184d950a8e6ae.txt @@ -0,0 +1,3 @@ +0 0.438953488372093 0.6223958333333333 0.20348837209302326 0.15625 +0 0.36627906976744184 0.3046875 0.20348837209302326 0.15625 +0 0.7122093023255814 0.6901041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c5fdbd5a41ac9b5ff6759b7fce6a032a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c5fdbd5a41ac9b5ff6759b7fce6a032a.txt new file mode 100644 index 0000000..57741e5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c5fdbd5a41ac9b5ff6759b7fce6a032a.txt @@ -0,0 +1,5 @@ +0 0.7209302325581395 0.6015625 0.20348837209302326 0.15625 +0 0.627906976744186 0.22395833333333331 0.20348837209302326 0.15625 +0 0.23546511627906977 0.44791666666666663 0.20348837209302326 0.15625 +0 0.3546511627906977 0.125 0.20348837209302326 0.15625 +0 0.2877906976744186 0.7057291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c5ff5214ef37bcf7db239b02a94a34da.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c5ff5214ef37bcf7db239b02a94a34da.txt new file mode 100644 index 0000000..ae79d02 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c5ff5214ef37bcf7db239b02a94a34da.txt @@ -0,0 +1,2 @@ +0 0.20348837209302326 0.5442708333333333 0.20348837209302326 0.15625 +0 0.5 0.1953125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c6a0cfc5364652cfbc5380750d34ba8e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c6a0cfc5364652cfbc5380750d34ba8e.txt new file mode 100644 index 0000000..8f76b17 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c6a0cfc5364652cfbc5380750d34ba8e.txt @@ -0,0 +1,3 @@ +0 0.19767441860465115 0.6328125 0.20348837209302326 0.15625 +0 0.2761627906976744 0.24479166666666666 0.20348837209302326 0.15625 +0 0.752906976744186 0.5729166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c728d6c7ebb6777f4b24f771407ceae1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c728d6c7ebb6777f4b24f771407ceae1.txt new file mode 100644 index 0000000..971da00 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c728d6c7ebb6777f4b24f771407ceae1.txt @@ -0,0 +1,5 @@ +0 0.6686046511627907 0.3046875 0.20348837209302326 0.15625 +0 0.3808139534883721 0.7265625 0.20348837209302326 0.15625 +0 0.34011627906976744 0.23177083333333331 0.20348837209302326 0.15625 +0 0.8023255813953488 0.7135416666666666 0.20348837209302326 0.15625 +0 0.25 0.4765625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c7323b3e0c6b01cbc672235442b1224f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c7323b3e0c6b01cbc672235442b1224f.txt new file mode 100644 index 0000000..fa22f25 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c7323b3e0c6b01cbc672235442b1224f.txt @@ -0,0 +1,5 @@ +0 0.5465116279069767 0.5390625 0.20348837209302326 0.15625 +0 0.8313953488372093 0.40625 0.20348837209302326 0.15625 +0 0.36046511627906974 0.265625 0.20348837209302326 0.15625 +0 0.7093023255813954 0.12239583333333333 0.20348837209302326 0.15625 +0 0.19186046511627908 0.6953125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c746e81377efc248393941ec62d016df.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c746e81377efc248393941ec62d016df.txt new file mode 100644 index 0000000..66a5be7 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c746e81377efc248393941ec62d016df.txt @@ -0,0 +1,4 @@ +0 0.7994186046511628 0.7239583333333333 0.20348837209302326 0.15625 +0 0.23255813953488372 0.125 0.20348837209302326 0.15625 +0 0.19767441860465115 0.7161458333333333 0.20348837209302326 0.15625 +0 0.13372093023255813 0.43229166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c86afc2f78633eba946086bba9f6e7b7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c86afc2f78633eba946086bba9f6e7b7.txt new file mode 100644 index 0000000..17f368e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c86afc2f78633eba946086bba9f6e7b7.txt @@ -0,0 +1,4 @@ +0 0.7994186046511628 0.6875 0.20348837209302326 0.15625 +0 0.1569767441860465 0.5703125 0.20348837209302326 0.15625 +0 0.20930232558139533 0.20572916666666666 0.20348837209302326 0.15625 +0 0.7412790697674418 0.1015625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c8c60165f252de8814e19f73e4c1ce81.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c8c60165f252de8814e19f73e4c1ce81.txt new file mode 100644 index 0000000..bd43bbf --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c8c60165f252de8814e19f73e4c1ce81.txt @@ -0,0 +1,5 @@ +0 0.6656976744186046 0.15104166666666666 0.20348837209302326 0.15625 +0 0.7906976744186046 0.7135416666666666 0.20348837209302326 0.15625 +0 0.11918604651162791 0.3802083333333333 0.20348837209302326 0.15625 +0 0.438953488372093 0.7890625 0.20348837209302326 0.15625 +0 0.502906976744186 0.5026041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c98a6a28cd3829b98d21d188a4601db1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c98a6a28cd3829b98d21d188a4601db1.txt new file mode 100644 index 0000000..b06b1d6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c98a6a28cd3829b98d21d188a4601db1.txt @@ -0,0 +1,4 @@ +0 0.39244186046511625 0.4765625 0.20348837209302326 0.15625 +0 0.8459302325581395 0.3020833333333333 0.20348837209302326 0.15625 +0 0.5465116279069767 0.7734375 0.20348837209302326 0.15625 +0 0.31976744186046513 0.140625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9afbcc0e44b41122e696e28136c88aa.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9afbcc0e44b41122e696e28136c88aa.txt new file mode 100644 index 0000000..be9b40a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9afbcc0e44b41122e696e28136c88aa.txt @@ -0,0 +1,4 @@ +0 0.45348837209302323 0.3645833333333333 0.20348837209302326 0.15625 +0 0.7877906976744186 0.16145833333333331 0.20348837209302326 0.15625 +0 0.48546511627906974 0.71875 0.20348837209302326 0.15625 +0 0.8284883720930233 0.6666666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9bb1999c72d2aaa0fcb999b8fdf7f0f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9bb1999c72d2aaa0fcb999b8fdf7f0f.txt new file mode 100644 index 0000000..c43dac8 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9bb1999c72d2aaa0fcb999b8fdf7f0f.txt @@ -0,0 +1,5 @@ +0 0.34011627906976744 0.6901041666666666 0.20348837209302326 0.15625 +0 0.563953488372093 0.40885416666666663 0.20348837209302326 0.15625 +0 0.6482558139534884 0.13020833333333331 0.20348837209302326 0.15625 +0 0.25290697674418605 0.203125 0.20348837209302326 0.15625 +0 0.6453488372093024 0.734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9e2becfbabaeac5b24c84939775b1cb.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9e2becfbabaeac5b24c84939775b1cb.txt new file mode 100644 index 0000000..2a9abf0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9e2becfbabaeac5b24c84939775b1cb.txt @@ -0,0 +1,4 @@ +0 0.16279069767441862 0.6458333333333333 0.20348837209302326 0.15625 +0 0.4883720930232558 0.2786458333333333 0.20348837209302326 0.15625 +0 0.8517441860465116 0.17708333333333331 0.20348837209302326 0.15625 +0 0.7790697674418604 0.734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9ea970d64c81dba3decc00ddddf6c43.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9ea970d64c81dba3decc00ddddf6c43.txt new file mode 100644 index 0000000..e98b415 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9ea970d64c81dba3decc00ddddf6c43.txt @@ -0,0 +1,5 @@ +0 0.1569767441860465 0.2552083333333333 0.20348837209302326 0.15625 +0 0.7819767441860465 0.5234375 0.20348837209302326 0.15625 +0 0.7761627906976744 0.14322916666666666 0.20348837209302326 0.15625 +0 0.6424418604651163 0.7760416666666666 0.20348837209302326 0.15625 +0 0.1511627906976744 0.6822916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9fe6aceba49d3b539c0de2a457008e8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9fe6aceba49d3b539c0de2a457008e8.txt new file mode 100644 index 0000000..57d4883 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/c9fe6aceba49d3b539c0de2a457008e8.txt @@ -0,0 +1,5 @@ +0 0.8226744186046512 0.5963541666666666 0.20348837209302326 0.15625 +0 0.33430232558139533 0.43229166666666663 0.20348837209302326 0.15625 +0 0.75 0.3359375 0.20348837209302326 0.15625 +0 0.36627906976744184 0.7317708333333333 0.20348837209302326 0.15625 +0 0.6046511627906976 0.1015625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ca1d6a3c144fcc2a8eca6e20130c6fd9.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ca1d6a3c144fcc2a8eca6e20130c6fd9.txt new file mode 100644 index 0000000..98f1a8f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ca1d6a3c144fcc2a8eca6e20130c6fd9.txt @@ -0,0 +1,3 @@ +0 0.8459302325581395 0.6666666666666666 0.20348837209302326 0.15625 +0 0.2936046511627907 0.4270833333333333 0.20348837209302326 0.15625 +0 0.8226744186046512 0.4427083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ca4467719d761828aea66d132d7de9e2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ca4467719d761828aea66d132d7de9e2.txt new file mode 100644 index 0000000..25b46e1 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ca4467719d761828aea66d132d7de9e2.txt @@ -0,0 +1,5 @@ +0 0.4738372093023256 0.7786458333333333 0.20348837209302326 0.15625 +0 0.2645348837209302 0.23177083333333331 0.20348837209302326 0.15625 +0 0.6715116279069767 0.2708333333333333 0.20348837209302326 0.15625 +0 0.6424418604651163 0.5572916666666666 0.20348837209302326 0.15625 +0 0.13372093023255813 0.484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cacac33e2e186579bd6f2717f432972a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cacac33e2e186579bd6f2717f432972a.txt new file mode 100644 index 0000000..6168c45 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cacac33e2e186579bd6f2717f432972a.txt @@ -0,0 +1,4 @@ +0 0.747093023255814 0.5286458333333333 0.20348837209302326 0.15625 +0 0.15988372093023256 0.11458333333333333 0.20348837209302326 0.15625 +0 0.22093023255813954 0.53125 0.20348837209302326 0.15625 +0 0.6976744186046512 0.22916666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cb1da9b6dc01bb86c1706839671602a6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cb1da9b6dc01bb86c1706839671602a6.txt new file mode 100644 index 0000000..829740c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cb1da9b6dc01bb86c1706839671602a6.txt @@ -0,0 +1,4 @@ +0 0.20348837209302326 0.1875 0.20348837209302326 0.15625 +0 0.23255813953488372 0.6692708333333333 0.20348837209302326 0.15625 +0 0.7994186046511628 0.29166666666666663 0.20348837209302326 0.15625 +0 0.7761627906976744 0.5729166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cb50b723f788f9cf7d2183650f235287.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cb50b723f788f9cf7d2183650f235287.txt new file mode 100644 index 0000000..664077f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cb50b723f788f9cf7d2183650f235287.txt @@ -0,0 +1,5 @@ +0 0.6424418604651163 0.10416666666666666 0.20348837209302326 0.15625 +0 0.6569767441860465 0.44010416666666663 0.20348837209302326 0.15625 +0 0.3168604651162791 0.7395833333333333 0.20348837209302326 0.15625 +0 0.30523255813953487 0.15364583333333331 0.20348837209302326 0.15625 +0 0.7325581395348837 0.7578125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cbdfb8e619f468e2abd1df334f238989.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cbdfb8e619f468e2abd1df334f238989.txt new file mode 100644 index 0000000..6ade443 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cbdfb8e619f468e2abd1df334f238989.txt @@ -0,0 +1,3 @@ +0 0.8284883720930233 0.4505208333333333 0.20348837209302326 0.15625 +0 0.41860465116279066 0.5729166666666666 0.20348837209302326 0.15625 +0 0.8430232558139534 0.6927083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cbee1d284945cab0dcfde91514f64d5c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cbee1d284945cab0dcfde91514f64d5c.txt new file mode 100644 index 0000000..12db8ba --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cbee1d284945cab0dcfde91514f64d5c.txt @@ -0,0 +1,3 @@ +0 0.49709302325581395 0.3046875 0.20348837209302326 0.15625 +0 0.7412790697674418 0.6614583333333333 0.20348837209302326 0.15625 +0 0.12790697674418605 0.7369791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cc0ef671b8168f7050e5d0f33bf22555.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cc0ef671b8168f7050e5d0f33bf22555.txt new file mode 100644 index 0000000..d3739ee --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cc0ef671b8168f7050e5d0f33bf22555.txt @@ -0,0 +1,4 @@ +0 0.4331395348837209 0.5833333333333333 0.20348837209302326 0.15625 +0 0.7965116279069767 0.6744791666666666 0.20348837209302326 0.15625 +0 0.6191860465116279 0.26822916666666663 0.20348837209302326 0.15625 +0 0.11918604651162791 0.5703125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ccaf3cbbd9490f2f0f30f6871848ebd2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ccaf3cbbd9490f2f0f30f6871848ebd2.txt new file mode 100644 index 0000000..d36650f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ccaf3cbbd9490f2f0f30f6871848ebd2.txt @@ -0,0 +1,5 @@ +0 0.3488372093023256 0.44791666666666663 0.20348837209302326 0.15625 +0 0.18023255813953487 0.6744791666666666 0.20348837209302326 0.15625 +0 0.1308139534883721 0.19791666666666666 0.20348837209302326 0.15625 +0 0.6627906976744186 0.7552083333333333 0.20348837209302326 0.15625 +0 0.6511627906976745 0.15104166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ccc6782058f6d04fe81dee47275ba6c8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ccc6782058f6d04fe81dee47275ba6c8.txt new file mode 100644 index 0000000..6f33b7b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ccc6782058f6d04fe81dee47275ba6c8.txt @@ -0,0 +1,2 @@ +0 0.34593023255813954 0.10677083333333333 0.20348837209302326 0.15625 +0 0.6627906976744186 0.22916666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cd371c72dac20e77788ab8f025d27522.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cd371c72dac20e77788ab8f025d27522.txt new file mode 100644 index 0000000..251756b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cd371c72dac20e77788ab8f025d27522.txt @@ -0,0 +1,3 @@ +0 0.8488372093023255 0.18229166666666666 0.20348837209302326 0.15625 +0 0.12790697674418605 0.5182291666666666 0.20348837209302326 0.15625 +0 0.6337209302325582 0.4973958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cd5638d0f0b089a8b72d21131052f744.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cd5638d0f0b089a8b72d21131052f744.txt new file mode 100644 index 0000000..dc9e1bf --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cd5638d0f0b089a8b72d21131052f744.txt @@ -0,0 +1,4 @@ +0 0.7296511627906976 0.3958333333333333 0.20348837209302326 0.15625 +0 0.25290697674418605 0.765625 0.20348837209302326 0.15625 +0 0.2645348837209302 0.08333333333333333 0.20348837209302326 0.15625 +0 0.6482558139534884 0.171875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cdb538530ed854a4421ae30f226ba5e6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cdb538530ed854a4421ae30f226ba5e6.txt new file mode 100644 index 0000000..f3fd150 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cdb538530ed854a4421ae30f226ba5e6.txt @@ -0,0 +1,4 @@ +0 0.7703488372093024 0.15625 0.20348837209302326 0.15625 +0 0.3168604651162791 0.265625 0.20348837209302326 0.15625 +0 0.24127906976744184 0.703125 0.20348837209302326 0.15625 +0 0.7209302325581395 0.5546875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cdf0391f10105d6ed10a6df8e1d99a94.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cdf0391f10105d6ed10a6df8e1d99a94.txt new file mode 100644 index 0000000..89699fa --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cdf0391f10105d6ed10a6df8e1d99a94.txt @@ -0,0 +1,3 @@ +0 0.4563953488372093 0.59375 0.20348837209302326 0.15625 +0 0.4622093023255814 0.2864583333333333 0.20348837209302326 0.15625 +0 0.11046511627906977 0.3984375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ce0c4554be8d8f03c5129e47e199eebe.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ce0c4554be8d8f03c5129e47e199eebe.txt new file mode 100644 index 0000000..79eb235 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ce0c4554be8d8f03c5129e47e199eebe.txt @@ -0,0 +1,5 @@ +0 0.30523255813953487 0.1328125 0.20348837209302326 0.15625 +0 0.13662790697674418 0.6666666666666666 0.20348837209302326 0.15625 +0 0.4273255813953488 0.5338541666666666 0.20348837209302326 0.15625 +0 0.7674418604651163 0.4192708333333333 0.20348837209302326 0.15625 +0 0.7819767441860465 0.09635416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ce4dea56cdf0a320ab3db6e53f912b08.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ce4dea56cdf0a320ab3db6e53f912b08.txt new file mode 100644 index 0000000..7da1ab5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ce4dea56cdf0a320ab3db6e53f912b08.txt @@ -0,0 +1,5 @@ +0 0.6686046511627907 0.10416666666666666 0.20348837209302326 0.15625 +0 0.8459302325581395 0.5104166666666666 0.20348837209302326 0.15625 +0 0.16279069767441862 0.7708333333333333 0.20348837209302326 0.15625 +0 0.311046511627907 0.4505208333333333 0.20348837209302326 0.15625 +0 0.15406976744186046 0.125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ceef3d514141c2e7d31f57f06748f0f4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ceef3d514141c2e7d31f57f06748f0f4.txt new file mode 100644 index 0000000..f0a3b71 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ceef3d514141c2e7d31f57f06748f0f4.txt @@ -0,0 +1,4 @@ +0 0.3488372093023256 0.5807291666666666 0.20348837209302326 0.15625 +0 0.5697674418604651 0.21875 0.20348837209302326 0.15625 +0 0.7877906976744186 0.7630208333333333 0.20348837209302326 0.15625 +0 0.7005813953488372 0.5 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cf133e9c5a15a1164a3d6d1319cf58fe.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cf133e9c5a15a1164a3d6d1319cf58fe.txt new file mode 100644 index 0000000..5cb8a5f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cf133e9c5a15a1164a3d6d1319cf58fe.txt @@ -0,0 +1,4 @@ +0 0.25290697674418605 0.5078125 0.20348837209302326 0.15625 +0 0.7587209302325582 0.5 0.20348837209302326 0.15625 +0 0.18023255813953487 0.171875 0.20348837209302326 0.15625 +0 0.49127906976744184 0.7864583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cf765ba6bb36fde7d35b2ed3f47b1dee.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cf765ba6bb36fde7d35b2ed3f47b1dee.txt new file mode 100644 index 0000000..06f9c47 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/cf765ba6bb36fde7d35b2ed3f47b1dee.txt @@ -0,0 +1,5 @@ +0 0.6453488372093024 0.5859375 0.20348837209302326 0.15625 +0 0.7732558139534884 0.2552083333333333 0.20348837209302326 0.15625 +0 0.18604651162790697 0.09375 0.20348837209302326 0.15625 +0 0.30523255813953487 0.4609375 0.20348837209302326 0.15625 +0 0.2965116279069767 0.7057291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d088c915a03c77bc89a9e466074f10a8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d088c915a03c77bc89a9e466074f10a8.txt new file mode 100644 index 0000000..bcdb60a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d088c915a03c77bc89a9e466074f10a8.txt @@ -0,0 +1,4 @@ +0 0.6511627906976745 0.375 0.20348837209302326 0.15625 +0 0.27906976744186046 0.6796875 0.20348837209302326 0.15625 +0 0.14825581395348836 0.32291666666666663 0.20348837209302326 0.15625 +0 0.4680232558139535 0.1171875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d0a1616529f654f8e85f409a8ff71970.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d0a1616529f654f8e85f409a8ff71970.txt new file mode 100644 index 0000000..3c3d88f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d0a1616529f654f8e85f409a8ff71970.txt @@ -0,0 +1,4 @@ +0 0.2819767441860465 0.1015625 0.20348837209302326 0.15625 +0 0.16569767441860464 0.7630208333333333 0.20348837209302326 0.15625 +0 0.18023255813953487 0.39322916666666663 0.20348837209302326 0.15625 +0 0.7819767441860465 0.296875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d12d9d53a57a563793906271a40d9007.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d12d9d53a57a563793906271a40d9007.txt new file mode 100644 index 0000000..13ba091 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d12d9d53a57a563793906271a40d9007.txt @@ -0,0 +1,4 @@ +0 0.75 0.7265625 0.20348837209302326 0.15625 +0 0.6918604651162791 0.3880208333333333 0.20348837209302326 0.15625 +0 0.30523255813953487 0.5260416666666666 0.20348837209302326 0.15625 +0 0.2761627906976744 0.7838541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d12df139d9d845b6612b28d63c6b7acb.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d12df139d9d845b6612b28d63c6b7acb.txt new file mode 100644 index 0000000..731288b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d12df139d9d845b6612b28d63c6b7acb.txt @@ -0,0 +1,4 @@ +0 0.2645348837209302 0.7395833333333333 0.20348837209302326 0.15625 +0 0.3895348837209302 0.359375 0.20348837209302326 0.15625 +0 0.18023255813953487 0.14583333333333331 0.20348837209302326 0.15625 +0 0.7383720930232558 0.5859375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d167decdf90bd31cf8895d3836378c79.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d167decdf90bd31cf8895d3836378c79.txt new file mode 100644 index 0000000..384f8b5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d167decdf90bd31cf8895d3836378c79.txt @@ -0,0 +1,4 @@ +0 0.1569767441860465 0.1484375 0.20348837209302326 0.15625 +0 0.7063953488372093 0.44791666666666663 0.20348837209302326 0.15625 +0 0.48546511627906974 0.16666666666666666 0.20348837209302326 0.15625 +0 0.31976744186046513 0.6067708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d16c68d0ab3a80081c7ec312ca323db4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d16c68d0ab3a80081c7ec312ca323db4.txt new file mode 100644 index 0000000..37972bc --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d16c68d0ab3a80081c7ec312ca323db4.txt @@ -0,0 +1,5 @@ +0 0.5406976744186046 0.48697916666666663 0.20348837209302326 0.15625 +0 0.13953488372093023 0.1328125 0.20348837209302326 0.15625 +0 0.3488372093023256 0.7161458333333333 0.20348837209302326 0.15625 +0 0.7994186046511628 0.3958333333333333 0.20348837209302326 0.15625 +0 0.19767441860465115 0.359375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d1a2bd7a51d77da0c53880d99cdf8e4f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d1a2bd7a51d77da0c53880d99cdf8e4f.txt new file mode 100644 index 0000000..c6d9e86 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d1a2bd7a51d77da0c53880d99cdf8e4f.txt @@ -0,0 +1,4 @@ +0 0.438953488372093 0.6302083333333333 0.20348837209302326 0.15625 +0 0.29069767441860467 0.14583333333333331 0.20348837209302326 0.15625 +0 0.8197674418604651 0.7708333333333333 0.20348837209302326 0.15625 +0 0.7209302325581395 0.11197916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d1b016c1e260b06c9f4e1fb15f88745c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d1b016c1e260b06c9f4e1fb15f88745c.txt new file mode 100644 index 0000000..79d9b1b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d1b016c1e260b06c9f4e1fb15f88745c.txt @@ -0,0 +1,4 @@ +0 0.313953488372093 0.75 0.20348837209302326 0.15625 +0 0.6598837209302325 0.3098958333333333 0.20348837209302326 0.15625 +0 0.2005813953488372 0.4114583333333333 0.20348837209302326 0.15625 +0 0.3081395348837209 0.16927083333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d1c315d9478470375d2f1bb8e226694f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d1c315d9478470375d2f1bb8e226694f.txt new file mode 100644 index 0000000..d3cdf52 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d1c315d9478470375d2f1bb8e226694f.txt @@ -0,0 +1,4 @@ +0 0.7994186046511628 0.5416666666666666 0.20348837209302326 0.15625 +0 0.4563953488372093 0.5807291666666666 0.20348837209302326 0.15625 +0 0.11918604651162791 0.3802083333333333 0.20348837209302326 0.15625 +0 0.40988372093023256 0.11979166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d1ddf3e95dc619553298fa38c325e3d7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d1ddf3e95dc619553298fa38c325e3d7.txt new file mode 100644 index 0000000..14420b0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d1ddf3e95dc619553298fa38c325e3d7.txt @@ -0,0 +1,5 @@ +0 0.14825581395348836 0.19791666666666666 0.20348837209302326 0.15625 +0 0.14244186046511628 0.7005208333333333 0.20348837209302326 0.15625 +0 0.5406976744186046 0.3046875 0.20348837209302326 0.15625 +0 0.5523255813953488 0.6796875 0.20348837209302326 0.15625 +0 0.811046511627907 0.59375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d213aa519d82c13695f294fe2b9f0082.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d213aa519d82c13695f294fe2b9f0082.txt new file mode 100644 index 0000000..da95ce6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d213aa519d82c13695f294fe2b9f0082.txt @@ -0,0 +1,4 @@ +0 0.8430232558139534 0.359375 0.20348837209302326 0.15625 +0 0.18604651162790697 0.6015625 0.20348837209302326 0.15625 +0 0.8226744186046512 0.6875 0.20348837209302326 0.15625 +0 0.5377906976744186 0.515625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d262c20cc228ad2f8742cc27973f5171.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d262c20cc228ad2f8742cc27973f5171.txt new file mode 100644 index 0000000..1aaf8c0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d262c20cc228ad2f8742cc27973f5171.txt @@ -0,0 +1,4 @@ +0 0.20348837209302326 0.10416666666666666 0.20348837209302326 0.15625 +0 0.14244186046511628 0.5078125 0.20348837209302326 0.15625 +0 0.6133720930232558 0.2734375 0.20348837209302326 0.15625 +0 0.6046511627906976 0.515625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d26c4932e2a6d260a6b748d6747e4207.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d26c4932e2a6d260a6b748d6747e4207.txt new file mode 100644 index 0000000..d8e4fd2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d26c4932e2a6d260a6b748d6747e4207.txt @@ -0,0 +1,4 @@ +0 0.35174418604651164 0.7317708333333333 0.20348837209302326 0.15625 +0 0.5901162790697674 0.375 0.20348837209302326 0.15625 +0 0.18604651162790697 0.453125 0.20348837209302326 0.15625 +0 0.18313953488372092 0.23177083333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d2c0d0a6ba3766469b6088673fccfa52.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d2c0d0a6ba3766469b6088673fccfa52.txt new file mode 100644 index 0000000..911d05b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d2c0d0a6ba3766469b6088673fccfa52.txt @@ -0,0 +1,3 @@ +0 0.5872093023255814 0.28385416666666663 0.20348837209302326 0.15625 +0 0.5872093023255814 0.5442708333333333 0.20348837209302326 0.15625 +0 0.26744186046511625 0.515625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d2cbaa87bb20f4c60fa52c7b01e7bc47.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d2cbaa87bb20f4c60fa52c7b01e7bc47.txt new file mode 100644 index 0000000..a6ae8fb --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d2cbaa87bb20f4c60fa52c7b01e7bc47.txt @@ -0,0 +1,4 @@ +0 0.20348837209302326 0.7916666666666666 0.20348837209302326 0.15625 +0 0.5930232558139534 0.5338541666666666 0.20348837209302326 0.15625 +0 0.1686046511627907 0.36979166666666663 0.20348837209302326 0.15625 +0 0.7005813953488372 0.2421875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d310f40678f868b83d762347c73174c6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d310f40678f868b83d762347c73174c6.txt new file mode 100644 index 0000000..a4e4fcd --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d310f40678f868b83d762347c73174c6.txt @@ -0,0 +1,4 @@ +0 0.8546511627906976 0.25 0.20348837209302326 0.15625 +0 0.40406976744186046 0.4453125 0.20348837209302326 0.15625 +0 0.27906976744186046 0.6770833333333333 0.20348837209302326 0.15625 +0 0.7616279069767442 0.7057291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d32016716f5bb487c7c22adedb06b350.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d32016716f5bb487c7c22adedb06b350.txt new file mode 100644 index 0000000..20f1d0c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d32016716f5bb487c7c22adedb06b350.txt @@ -0,0 +1,4 @@ +0 0.2005813953488372 0.515625 0.20348837209302326 0.15625 +0 0.5203488372093024 0.09375 0.20348837209302326 0.15625 +0 0.7093023255813954 0.31510416666666663 0.20348837209302326 0.15625 +0 0.6482558139534884 0.6276041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d342bbcaf71dd9fb28eaac993f523da8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d342bbcaf71dd9fb28eaac993f523da8.txt new file mode 100644 index 0000000..bf7c8ce --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d342bbcaf71dd9fb28eaac993f523da8.txt @@ -0,0 +1,5 @@ +0 0.18604651162790697 0.13020833333333331 0.20348837209302326 0.15625 +0 0.2616279069767442 0.5364583333333333 0.20348837209302326 0.15625 +0 0.8255813953488372 0.5182291666666666 0.20348837209302326 0.15625 +0 0.3808139534883721 0.7864583333333333 0.20348837209302326 0.15625 +0 0.6715116279069767 0.23697916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d3feb187cabf2b68f42d72c5f2c6d115.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d3feb187cabf2b68f42d72c5f2c6d115.txt new file mode 100644 index 0000000..7bdfa8e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d3feb187cabf2b68f42d72c5f2c6d115.txt @@ -0,0 +1,3 @@ +0 0.6656976744186046 0.4114583333333333 0.20348837209302326 0.15625 +0 0.3546511627906977 0.4973958333333333 0.20348837209302326 0.15625 +0 0.7093023255813954 0.7421875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d450e6a850bc1b9f570a6c9c4f53abb4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d450e6a850bc1b9f570a6c9c4f53abb4.txt new file mode 100644 index 0000000..5379086 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d450e6a850bc1b9f570a6c9c4f53abb4.txt @@ -0,0 +1,5 @@ +0 0.5988372093023255 0.4453125 0.20348837209302326 0.15625 +0 0.47674418604651164 0.21354166666666666 0.20348837209302326 0.15625 +0 0.24709302325581395 0.65625 0.20348837209302326 0.15625 +0 0.7732558139534884 0.15364583333333331 0.20348837209302326 0.15625 +0 0.7732558139534884 0.71875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d4c9419289b37089cc02c6c70b417826.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d4c9419289b37089cc02c6c70b417826.txt new file mode 100644 index 0000000..d3f7149 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d4c9419289b37089cc02c6c70b417826.txt @@ -0,0 +1,2 @@ +0 0.20348837209302326 0.578125 0.20348837209302326 0.15625 +0 0.747093023255814 0.5520833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d4e1c74859109413588d5aaba4b8ec2c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d4e1c74859109413588d5aaba4b8ec2c.txt new file mode 100644 index 0000000..016feac --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d4e1c74859109413588d5aaba4b8ec2c.txt @@ -0,0 +1,4 @@ +0 0.5174418604651163 0.609375 0.20348837209302326 0.15625 +0 0.6162790697674418 0.3177083333333333 0.20348837209302326 0.15625 +0 0.47093023255813954 0.09895833333333333 0.20348837209302326 0.15625 +0 0.14244186046511628 0.7552083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d503fd304a9f46d49d7819c6fe3008ea.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d503fd304a9f46d49d7819c6fe3008ea.txt new file mode 100644 index 0000000..9bf6ebd --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d503fd304a9f46d49d7819c6fe3008ea.txt @@ -0,0 +1,4 @@ +0 0.3488372093023256 0.14583333333333331 0.20348837209302326 0.15625 +0 0.13372093023255813 0.6119791666666666 0.20348837209302326 0.15625 +0 0.16279069767441862 0.35416666666666663 0.20348837209302326 0.15625 +0 0.7994186046511628 0.44010416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d5aed27f888ed08e77264f255f94aa3c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d5aed27f888ed08e77264f255f94aa3c.txt new file mode 100644 index 0000000..59cd7ba --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d5aed27f888ed08e77264f255f94aa3c.txt @@ -0,0 +1,4 @@ +0 0.1308139534883721 0.3020833333333333 0.20348837209302326 0.15625 +0 0.4476744186046512 0.17447916666666666 0.20348837209302326 0.15625 +0 0.6191860465116279 0.6666666666666666 0.20348837209302326 0.15625 +0 0.8430232558139534 0.19010416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d5beb716adf58c151412f2b2661666c7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d5beb716adf58c151412f2b2661666c7.txt new file mode 100644 index 0000000..0202375 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d5beb716adf58c151412f2b2661666c7.txt @@ -0,0 +1,3 @@ +0 0.6191860465116279 0.48697916666666663 0.20348837209302326 0.15625 +0 0.3488372093023256 0.2265625 0.20348837209302326 0.15625 +0 0.3226744186046512 0.5755208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d5ef18ce299f1cde496ed3478cf618a3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d5ef18ce299f1cde496ed3478cf618a3.txt new file mode 100644 index 0000000..3406419 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d5ef18ce299f1cde496ed3478cf618a3.txt @@ -0,0 +1,3 @@ +0 0.23255813953488372 0.3958333333333333 0.20348837209302326 0.15625 +0 0.42441860465116277 0.1015625 0.20348837209302326 0.15625 +0 0.7005813953488372 0.578125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d605923185af2e57c934f27c976dd055.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d605923185af2e57c934f27c976dd055.txt new file mode 100644 index 0000000..043fabc --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d605923185af2e57c934f27c976dd055.txt @@ -0,0 +1,4 @@ +0 0.44476744186046513 0.140625 0.20348837209302326 0.15625 +0 0.7848837209302325 0.7291666666666666 0.20348837209302326 0.15625 +0 0.8517441860465116 0.4661458333333333 0.20348837209302326 0.15625 +0 0.21220930232558138 0.7447916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d61f7561a0b075df7474e7907054bb64.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d61f7561a0b075df7474e7907054bb64.txt new file mode 100644 index 0000000..7e4903c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d61f7561a0b075df7474e7907054bb64.txt @@ -0,0 +1,4 @@ +0 0.23546511627906977 0.609375 0.20348837209302326 0.15625 +0 0.7616279069767442 0.5859375 0.20348837209302326 0.15625 +0 0.23546511627906977 0.2708333333333333 0.20348837209302326 0.15625 +0 0.625 0.2552083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d62482850bc9d4e89e34be5058672bc6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d62482850bc9d4e89e34be5058672bc6.txt new file mode 100644 index 0000000..db4e20c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d62482850bc9d4e89e34be5058672bc6.txt @@ -0,0 +1,3 @@ +0 0.34011627906976744 0.1015625 0.20348837209302326 0.15625 +0 0.622093023255814 0.7369791666666666 0.20348837209302326 0.15625 +0 0.2703488372093023 0.7083333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6518fd1a9d59445aea5d45d2937dbbb.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6518fd1a9d59445aea5d45d2937dbbb.txt new file mode 100644 index 0000000..dd260c5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6518fd1a9d59445aea5d45d2937dbbb.txt @@ -0,0 +1,4 @@ +0 0.2441860465116279 0.5130208333333333 0.20348837209302326 0.15625 +0 0.6656976744186046 0.24739583333333331 0.20348837209302326 0.15625 +0 0.6656976744186046 0.7265625 0.20348837209302326 0.15625 +0 0.20930232558139533 0.171875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6cf1842d8e87e7313d52264f716959e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6cf1842d8e87e7313d52264f716959e.txt new file mode 100644 index 0000000..e818505 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6cf1842d8e87e7313d52264f716959e.txt @@ -0,0 +1,3 @@ +0 0.41860465116279066 0.3125 0.20348837209302326 0.15625 +0 0.8808139534883721 0.3958333333333333 0.20348837209302326 0.15625 +0 0.18313953488372092 0.5885416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6d23263a8f514d9f710435ec907bc20.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6d23263a8f514d9f710435ec907bc20.txt new file mode 100644 index 0000000..1db7cd2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6d23263a8f514d9f710435ec907bc20.txt @@ -0,0 +1,4 @@ +0 0.36046511627906974 0.11197916666666666 0.20348837209302326 0.15625 +0 0.5494186046511628 0.4583333333333333 0.20348837209302326 0.15625 +0 0.09011627906976744 0.640625 0.20348837209302326 0.15625 +0 0.7296511627906976 0.1953125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6e10b9e51fc1d72a5c22dad51121486.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6e10b9e51fc1d72a5c22dad51121486.txt new file mode 100644 index 0000000..d7f3334 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6e10b9e51fc1d72a5c22dad51121486.txt @@ -0,0 +1,5 @@ +0 0.8343023255813954 0.484375 0.20348837209302326 0.15625 +0 0.5087209302325582 0.7239583333333333 0.20348837209302326 0.15625 +0 0.4825581395348837 0.12760416666666666 0.20348837209302326 0.15625 +0 0.3546511627906977 0.48697916666666663 0.20348837209302326 0.15625 +0 0.8313953488372093 0.13020833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6e9bddb772c7cb92fb82327a1310b02.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6e9bddb772c7cb92fb82327a1310b02.txt new file mode 100644 index 0000000..e6d983f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6e9bddb772c7cb92fb82327a1310b02.txt @@ -0,0 +1,4 @@ +0 0.75 0.16145833333333331 0.20348837209302326 0.15625 +0 0.7674418604651163 0.7161458333333333 0.20348837209302326 0.15625 +0 0.5901162790697674 0.4270833333333333 0.20348837209302326 0.15625 +0 0.24127906976744184 0.75 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6ed22a87864a99d17610cc5bba9aa18.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6ed22a87864a99d17610cc5bba9aa18.txt new file mode 100644 index 0000000..04d78aa --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d6ed22a87864a99d17610cc5bba9aa18.txt @@ -0,0 +1,5 @@ +0 0.8255813953488372 0.3802083333333333 0.20348837209302326 0.15625 +0 0.4563953488372093 0.359375 0.20348837209302326 0.15625 +0 0.7063953488372093 0.1015625 0.20348837209302326 0.15625 +0 0.4883720930232558 0.7552083333333333 0.20348837209302326 0.15625 +0 0.15406976744186046 0.21354166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d7298ddae4c93f1f02c93ff5eaa5eaf1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d7298ddae4c93f1f02c93ff5eaa5eaf1.txt new file mode 100644 index 0000000..3118b1b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d7298ddae4c93f1f02c93ff5eaa5eaf1.txt @@ -0,0 +1,4 @@ +0 0.3430232558139535 0.5026041666666666 0.20348837209302326 0.15625 +0 0.7151162790697674 0.2708333333333333 0.20348837209302326 0.15625 +0 0.3023255813953488 0.2265625 0.20348837209302326 0.15625 +0 0.37209302325581395 0.7760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d7540ca437085c9e4b7a982cebab8154.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d7540ca437085c9e4b7a982cebab8154.txt new file mode 100644 index 0000000..9c83f0d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d7540ca437085c9e4b7a982cebab8154.txt @@ -0,0 +1,4 @@ +0 0.45348837209302323 0.7421875 0.20348837209302326 0.15625 +0 0.6511627906976745 0.40104166666666663 0.20348837209302326 0.15625 +0 0.6656976744186046 0.1796875 0.20348837209302326 0.15625 +0 0.21511627906976744 0.10416666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d808680e3aa6391896e7f4182eb3a399.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d808680e3aa6391896e7f4182eb3a399.txt new file mode 100644 index 0000000..4b058cd --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d808680e3aa6391896e7f4182eb3a399.txt @@ -0,0 +1,5 @@ +0 0.6191860465116279 0.65625 0.20348837209302326 0.15625 +0 0.24709302325581395 0.5520833333333333 0.20348837209302326 0.15625 +0 0.5843023255813954 0.390625 0.20348837209302326 0.15625 +0 0.6686046511627907 0.15104166666666666 0.20348837209302326 0.15625 +0 0.2819767441860465 0.12760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d873341182a854350d35ac685378f543.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d873341182a854350d35ac685378f543.txt new file mode 100644 index 0000000..226c4c5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d873341182a854350d35ac685378f543.txt @@ -0,0 +1,4 @@ +0 0.7180232558139534 0.5651041666666666 0.20348837209302326 0.15625 +0 0.4127906976744186 0.16927083333333331 0.20348837209302326 0.15625 +0 0.11627906976744186 0.12760416666666666 0.20348837209302326 0.15625 +0 0.7877906976744186 0.15364583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d8cde834eec73f92117454119b428fbe.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d8cde834eec73f92117454119b428fbe.txt new file mode 100644 index 0000000..928a0a6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d8cde834eec73f92117454119b428fbe.txt @@ -0,0 +1,4 @@ +0 0.1947674418604651 0.1796875 0.20348837209302326 0.15625 +0 0.7238372093023255 0.16927083333333331 0.20348837209302326 0.15625 +0 0.23837209302325582 0.5546875 0.20348837209302326 0.15625 +0 0.8081395348837209 0.5729166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d8d5c3132ea0ded0bb15b46e8f4efdf0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d8d5c3132ea0ded0bb15b46e8f4efdf0.txt new file mode 100644 index 0000000..ac395f0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d8d5c3132ea0ded0bb15b46e8f4efdf0.txt @@ -0,0 +1,2 @@ +0 0.4825581395348837 0.4609375 0.20348837209302326 0.15625 +0 0.8401162790697674 0.47135416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d91f785fee9465ba52ca2037ea94afa1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d91f785fee9465ba52ca2037ea94afa1.txt new file mode 100644 index 0000000..2d1abea --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d91f785fee9465ba52ca2037ea94afa1.txt @@ -0,0 +1,4 @@ +0 0.686046511627907 0.6432291666666666 0.20348837209302326 0.15625 +0 0.25872093023255816 0.7760416666666666 0.20348837209302326 0.15625 +0 0.5784883720930233 0.19270833333333331 0.20348837209302326 0.15625 +0 0.2703488372093023 0.3802083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d9a69c46e6103a1bc7629a04b2ecee27.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d9a69c46e6103a1bc7629a04b2ecee27.txt new file mode 100644 index 0000000..bf87f34 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d9a69c46e6103a1bc7629a04b2ecee27.txt @@ -0,0 +1,4 @@ +0 0.42441860465116277 0.5390625 0.20348837209302326 0.15625 +0 0.8459302325581395 0.453125 0.20348837209302326 0.15625 +0 0.7209302325581395 0.7708333333333333 0.20348837209302326 0.15625 +0 0.34011627906976744 0.3203125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d9a8788c21d83541c6d00a5a947b73c2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d9a8788c21d83541c6d00a5a947b73c2.txt new file mode 100644 index 0000000..d9161f4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d9a8788c21d83541c6d00a5a947b73c2.txt @@ -0,0 +1,4 @@ +0 0.11046511627906977 0.14322916666666666 0.20348837209302326 0.15625 +0 0.4680232558139535 0.7239583333333333 0.20348837209302326 0.15625 +0 0.7645348837209303 0.7682291666666666 0.20348837209302326 0.15625 +0 0.8284883720930233 0.140625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d9dd6f9830ee77c859f620b6f4767e6e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d9dd6f9830ee77c859f620b6f4767e6e.txt new file mode 100644 index 0000000..f6559a7 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/d9dd6f9830ee77c859f620b6f4767e6e.txt @@ -0,0 +1,5 @@ +0 0.5581395348837209 0.28385416666666663 0.20348837209302326 0.15625 +0 0.8488372093023255 0.5546875 0.20348837209302326 0.15625 +0 0.8488372093023255 0.31510416666666663 0.20348837209302326 0.15625 +0 0.20930232558139533 0.7369791666666666 0.20348837209302326 0.15625 +0 0.5581395348837209 0.640625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/da02dd84d5912c2572c57a6f43d59632.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/da02dd84d5912c2572c57a6f43d59632.txt new file mode 100644 index 0000000..10c5657 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/da02dd84d5912c2572c57a6f43d59632.txt @@ -0,0 +1,4 @@ +0 0.5930232558139534 0.39322916666666663 0.20348837209302326 0.15625 +0 0.23255813953488372 0.28385416666666663 0.20348837209302326 0.15625 +0 0.7209302325581395 0.7890625 0.20348837209302326 0.15625 +0 0.2936046511627907 0.6223958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/da614350e7797b671b181dd7dbe4e86c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/da614350e7797b671b181dd7dbe4e86c.txt new file mode 100644 index 0000000..9873567 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/da614350e7797b671b181dd7dbe4e86c.txt @@ -0,0 +1,3 @@ +0 0.45930232558139533 0.23177083333333331 0.20348837209302326 0.15625 +0 0.3226744186046512 0.6848958333333333 0.20348837209302326 0.15625 +0 0.13662790697674418 0.1640625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/da978a8a0eb70e9f3a0874c94bce2de2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/da978a8a0eb70e9f3a0874c94bce2de2.txt new file mode 100644 index 0000000..356277d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/da978a8a0eb70e9f3a0874c94bce2de2.txt @@ -0,0 +1,5 @@ +0 0.4883720930232558 0.21875 0.20348837209302326 0.15625 +0 0.15406976744186046 0.36197916666666663 0.20348837209302326 0.15625 +0 0.7674418604651163 0.4661458333333333 0.20348837209302326 0.15625 +0 0.8081395348837209 0.22395833333333331 0.20348837209302326 0.15625 +0 0.7441860465116279 0.6953125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dadd516887f1ce445859a3a001fe22b4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dadd516887f1ce445859a3a001fe22b4.txt new file mode 100644 index 0000000..7841417 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dadd516887f1ce445859a3a001fe22b4.txt @@ -0,0 +1,5 @@ +0 0.16569767441860464 0.2630208333333333 0.20348837209302326 0.15625 +0 0.18895348837209303 0.5078125 0.20348837209302326 0.15625 +0 0.4825581395348837 0.09114583333333333 0.20348837209302326 0.15625 +0 0.7645348837209303 0.09635416666666666 0.20348837209302326 0.15625 +0 0.6598837209302325 0.578125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dae1862c2e81e3436854c7167a3d2c38.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dae1862c2e81e3436854c7167a3d2c38.txt new file mode 100644 index 0000000..290577d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dae1862c2e81e3436854c7167a3d2c38.txt @@ -0,0 +1,4 @@ +0 0.8284883720930233 0.4739583333333333 0.20348837209302326 0.15625 +0 0.2238372093023256 0.7447916666666666 0.20348837209302326 0.15625 +0 0.4127906976744186 0.3958333333333333 0.20348837209302326 0.15625 +0 0.6598837209302325 0.6953125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/db2f1ea74c09c97c21eabd75275b22ee.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/db2f1ea74c09c97c21eabd75275b22ee.txt new file mode 100644 index 0000000..aa7f521 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/db2f1ea74c09c97c21eabd75275b22ee.txt @@ -0,0 +1,4 @@ +0 0.1511627906976744 0.109375 0.20348837209302326 0.15625 +0 0.6744186046511628 0.3489583333333333 0.20348837209302326 0.15625 +0 0.22674418604651161 0.65625 0.20348837209302326 0.15625 +0 0.7587209302325582 0.59375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dbb669ea4fb993396d91a84e3c4e03ff.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dbb669ea4fb993396d91a84e3c4e03ff.txt new file mode 100644 index 0000000..2b59c7f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dbb669ea4fb993396d91a84e3c4e03ff.txt @@ -0,0 +1,3 @@ +0 0.2819767441860465 0.5364583333333333 0.20348837209302326 0.15625 +0 0.438953488372093 0.1171875 0.20348837209302326 0.15625 +0 0.7994186046511628 0.7526041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dbc87208c07b01ebada307292dac6ce0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dbc87208c07b01ebada307292dac6ce0.txt new file mode 100644 index 0000000..b57f07a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dbc87208c07b01ebada307292dac6ce0.txt @@ -0,0 +1,4 @@ +0 0.46511627906976744 0.5026041666666666 0.20348837209302326 0.15625 +0 0.3546511627906977 0.25 0.20348837209302326 0.15625 +0 0.7790697674418604 0.375 0.20348837209302326 0.15625 +0 0.6744186046511628 0.14583333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dbe533b180700cc5058b4cb38f2854fb.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dbe533b180700cc5058b4cb38f2854fb.txt new file mode 100644 index 0000000..b37ffd8 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dbe533b180700cc5058b4cb38f2854fb.txt @@ -0,0 +1,4 @@ +0 0.6017441860465116 0.11197916666666666 0.20348837209302326 0.15625 +0 0.5087209302325582 0.7604166666666666 0.20348837209302326 0.15625 +0 0.8052325581395349 0.3489583333333333 0.20348837209302326 0.15625 +0 0.4476744186046512 0.53125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dc7bd4dd36e1ac9d9dee9ae991776a1b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dc7bd4dd36e1ac9d9dee9ae991776a1b.txt new file mode 100644 index 0000000..b50086c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dc7bd4dd36e1ac9d9dee9ae991776a1b.txt @@ -0,0 +1,5 @@ +0 0.4796511627906977 0.16145833333333331 0.20348837209302326 0.15625 +0 0.3023255813953488 0.578125 0.20348837209302326 0.15625 +0 0.6598837209302325 0.7734375 0.20348837209302326 0.15625 +0 0.7093023255813954 0.5572916666666666 0.20348837209302326 0.15625 +0 0.1308139534883721 0.1875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dc7bdadd9163bff45cb3e6b0d37f04f6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dc7bdadd9163bff45cb3e6b0d37f04f6.txt new file mode 100644 index 0000000..b2bcf00 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dc7bdadd9163bff45cb3e6b0d37f04f6.txt @@ -0,0 +1,4 @@ +0 0.7965116279069767 0.6041666666666666 0.20348837209302326 0.15625 +0 0.2238372093023256 0.7239583333333333 0.20348837209302326 0.15625 +0 0.5726744186046512 0.2265625 0.20348837209302326 0.15625 +0 0.3953488372093023 0.4609375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dc9c97f593f5b328bc992b7d6cf3ae8d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dc9c97f593f5b328bc992b7d6cf3ae8d.txt new file mode 100644 index 0000000..a87bd5f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dc9c97f593f5b328bc992b7d6cf3ae8d.txt @@ -0,0 +1,5 @@ +0 0.26744186046511625 0.4348958333333333 0.20348837209302326 0.15625 +0 0.8081395348837209 0.1015625 0.20348837209302326 0.15625 +0 0.48546511627906974 0.14322916666666666 0.20348837209302326 0.15625 +0 0.4622093023255814 0.6744791666666666 0.20348837209302326 0.15625 +0 0.7412790697674418 0.375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dcb9ead591c60cc73bea72b0027b0e20.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dcb9ead591c60cc73bea72b0027b0e20.txt new file mode 100644 index 0000000..d3be5ed --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dcb9ead591c60cc73bea72b0027b0e20.txt @@ -0,0 +1,4 @@ +0 0.26744186046511625 0.5104166666666666 0.20348837209302326 0.15625 +0 0.6715116279069767 0.7239583333333333 0.20348837209302326 0.15625 +0 0.3895348837209302 0.29166666666666663 0.20348837209302326 0.15625 +0 0.6744186046511628 0.171875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dd4e01c3a404b697e120de5a08b1cd18.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dd4e01c3a404b697e120de5a08b1cd18.txt new file mode 100644 index 0000000..b847aed --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dd4e01c3a404b697e120de5a08b1cd18.txt @@ -0,0 +1,3 @@ +0 0.13372093023255813 0.14322916666666666 0.20348837209302326 0.15625 +0 0.8052325581395349 0.5 0.20348837209302326 0.15625 +0 0.4331395348837209 0.11458333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dd974a4b8094fe5b01a2a8ea91fa323b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dd974a4b8094fe5b01a2a8ea91fa323b.txt new file mode 100644 index 0000000..055ca69 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dd974a4b8094fe5b01a2a8ea91fa323b.txt @@ -0,0 +1,4 @@ +0 0.5058139534883721 0.4739583333333333 0.20348837209302326 0.15625 +0 0.18604651162790697 0.48697916666666663 0.20348837209302326 0.15625 +0 0.7412790697674418 0.09895833333333333 0.20348837209302326 0.15625 +0 0.7994186046511628 0.3645833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ddbf97a99c4b4cf4ee49ab0ee30f0a84.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ddbf97a99c4b4cf4ee49ab0ee30f0a84.txt new file mode 100644 index 0000000..3c42e5c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ddbf97a99c4b4cf4ee49ab0ee30f0a84.txt @@ -0,0 +1,5 @@ +0 0.34011627906976744 0.765625 0.20348837209302326 0.15625 +0 0.6831395348837209 0.5026041666666666 0.20348837209302326 0.15625 +0 0.32848837209302323 0.17447916666666666 0.20348837209302326 0.15625 +0 0.7848837209302325 0.7890625 0.20348837209302326 0.15625 +0 0.3313953488372093 0.47135416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/de97abcba845314e16d5ff2ca9287c05.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/de97abcba845314e16d5ff2ca9287c05.txt new file mode 100644 index 0000000..b819ba8 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/de97abcba845314e16d5ff2ca9287c05.txt @@ -0,0 +1,5 @@ +0 0.18313953488372092 0.5286458333333333 0.20348837209302326 0.15625 +0 0.8313953488372093 0.19270833333333331 0.20348837209302326 0.15625 +0 0.4418604651162791 0.2864583333333333 0.20348837209302326 0.15625 +0 0.15988372093023256 0.08072916666666666 0.20348837209302326 0.15625 +0 0.6802325581395349 0.7526041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ded32dc618e3429d7b284a1407bbf310.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ded32dc618e3429d7b284a1407bbf310.txt new file mode 100644 index 0000000..b23503a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ded32dc618e3429d7b284a1407bbf310.txt @@ -0,0 +1,4 @@ +0 0.29941860465116277 0.6536458333333333 0.20348837209302326 0.15625 +0 0.16279069767441862 0.36979166666666663 0.20348837209302326 0.15625 +0 0.6395348837209303 0.23697916666666666 0.20348837209302326 0.15625 +0 0.6424418604651163 0.6640625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dfce23f9859ef192ce441ff977676699.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dfce23f9859ef192ce441ff977676699.txt new file mode 100644 index 0000000..9514527 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dfce23f9859ef192ce441ff977676699.txt @@ -0,0 +1,3 @@ +0 0.6773255813953488 0.5546875 0.20348837209302326 0.15625 +0 0.622093023255814 0.21354166666666666 0.20348837209302326 0.15625 +0 0.40406976744186046 0.44791666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dfd5439e43fe87452411f4ebd3013fda.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dfd5439e43fe87452411f4ebd3013fda.txt new file mode 100644 index 0000000..a332b6e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/dfd5439e43fe87452411f4ebd3013fda.txt @@ -0,0 +1,3 @@ +0 0.2645348837209302 0.19791666666666666 0.20348837209302326 0.15625 +0 0.48546511627906974 0.640625 0.20348837209302326 0.15625 +0 0.7994186046511628 0.2421875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e01630daba9d7c685e21b66d0235da30.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e01630daba9d7c685e21b66d0235da30.txt new file mode 100644 index 0000000..2df4858 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e01630daba9d7c685e21b66d0235da30.txt @@ -0,0 +1,3 @@ +0 0.7005813953488372 0.25260416666666663 0.20348837209302326 0.15625 +0 0.41860465116279066 0.21875 0.20348837209302326 0.15625 +0 0.5726744186046512 0.7890625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e0768bec49c06b70064475f1d04620b8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e0768bec49c06b70064475f1d04620b8.txt new file mode 100644 index 0000000..65bbaae --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e0768bec49c06b70064475f1d04620b8.txt @@ -0,0 +1,5 @@ +0 0.6656976744186046 0.7265625 0.20348837209302326 0.15625 +0 0.4563953488372093 0.36197916666666663 0.20348837209302326 0.15625 +0 0.14825581395348836 0.21614583333333331 0.20348837209302326 0.15625 +0 0.23546511627906977 0.6979166666666666 0.20348837209302326 0.15625 +0 0.811046511627907 0.44010416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e0a0fb2c926b62aa0e9f3b7dd29ad2df.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e0a0fb2c926b62aa0e9f3b7dd29ad2df.txt new file mode 100644 index 0000000..f2447e8 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e0a0fb2c926b62aa0e9f3b7dd29ad2df.txt @@ -0,0 +1,4 @@ +0 0.5058139534883721 0.3645833333333333 0.20348837209302326 0.15625 +0 0.45930232558139533 0.09375 0.20348837209302326 0.15625 +0 0.10465116279069767 0.4348958333333333 0.20348837209302326 0.15625 +0 0.8168604651162791 0.22135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e0ee6b7033dbe46169b4518370bda33c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e0ee6b7033dbe46169b4518370bda33c.txt new file mode 100644 index 0000000..4799e43 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e0ee6b7033dbe46169b4518370bda33c.txt @@ -0,0 +1,5 @@ +0 0.13662790697674418 0.3255208333333333 0.20348837209302326 0.15625 +0 0.5436046511627907 0.48697916666666663 0.20348837209302326 0.15625 +0 0.48546511627906974 0.7864583333333333 0.20348837209302326 0.15625 +0 0.42441860465116277 0.21354166666666666 0.20348837209302326 0.15625 +0 0.8313953488372093 0.23177083333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e11bdd5667ec33b8bf5e4970cb61b590.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e11bdd5667ec33b8bf5e4970cb61b590.txt new file mode 100644 index 0000000..9046719 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e11bdd5667ec33b8bf5e4970cb61b590.txt @@ -0,0 +1,4 @@ +0 0.5436046511627907 0.40885416666666663 0.20348837209302326 0.15625 +0 0.13662790697674418 0.3411458333333333 0.20348837209302326 0.15625 +0 0.5784883720930233 0.1328125 0.20348837209302326 0.15625 +0 0.7383720930232558 0.75 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e133e335b9e34caa8297e7aa4e7baacc.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e133e335b9e34caa8297e7aa4e7baacc.txt new file mode 100644 index 0000000..454246d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e133e335b9e34caa8297e7aa4e7baacc.txt @@ -0,0 +1,4 @@ +0 0.14534883720930233 0.640625 0.20348837209302326 0.15625 +0 0.8691860465116279 0.359375 0.20348837209302326 0.15625 +0 0.6104651162790697 0.671875 0.20348837209302326 0.15625 +0 0.2965116279069767 0.30729166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e13491f7e4ce140ba7a97caf32e6bdf8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e13491f7e4ce140ba7a97caf32e6bdf8.txt new file mode 100644 index 0000000..8f5d725 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e13491f7e4ce140ba7a97caf32e6bdf8.txt @@ -0,0 +1,4 @@ +0 0.4505813953488372 0.140625 0.20348837209302326 0.15625 +0 0.4273255813953488 0.4895833333333333 0.20348837209302326 0.15625 +0 0.8023255813953488 0.16666666666666666 0.20348837209302326 0.15625 +0 0.8197674418604651 0.5208333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e14918f484b450b31449c9cfeadb4d74.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e14918f484b450b31449c9cfeadb4d74.txt new file mode 100644 index 0000000..7a009b4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e14918f484b450b31449c9cfeadb4d74.txt @@ -0,0 +1,4 @@ +0 0.8459302325581395 0.7760416666666666 0.20348837209302326 0.15625 +0 0.8372093023255813 0.328125 0.20348837209302326 0.15625 +0 0.43023255813953487 0.75 0.20348837209302326 0.15625 +0 0.29941860465116277 0.1953125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e1c8926c3d01980eafdc2c3180826b54.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e1c8926c3d01980eafdc2c3180826b54.txt new file mode 100644 index 0000000..074b916 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e1c8926c3d01980eafdc2c3180826b54.txt @@ -0,0 +1,4 @@ +0 0.1947674418604651 0.5989583333333333 0.20348837209302326 0.15625 +0 0.6773255813953488 0.5703125 0.20348837209302326 0.15625 +0 0.686046511627907 0.3098958333333333 0.20348837209302326 0.15625 +0 0.1686046511627907 0.32291666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e1dfb25a222de9e02093cd2320a01279.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e1dfb25a222de9e02093cd2320a01279.txt new file mode 100644 index 0000000..c53a146 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e1dfb25a222de9e02093cd2320a01279.txt @@ -0,0 +1,4 @@ +0 0.35174418604651164 0.22916666666666666 0.20348837209302326 0.15625 +0 0.5465116279069767 0.6927083333333333 0.20348837209302326 0.15625 +0 0.6424418604651163 0.3671875 0.20348837209302326 0.15625 +0 0.2645348837209302 0.7760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e22ac344d1d92d0a45d857319a31ab70.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e22ac344d1d92d0a45d857319a31ab70.txt new file mode 100644 index 0000000..509ee56 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e22ac344d1d92d0a45d857319a31ab70.txt @@ -0,0 +1,4 @@ +0 0.8168604651162791 0.5286458333333333 0.20348837209302326 0.15625 +0 0.39825581395348836 0.4296875 0.20348837209302326 0.15625 +0 0.1686046511627907 0.18489583333333331 0.20348837209302326 0.15625 +0 0.16279069767441862 0.6953125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e2a502f0402b637c3b5db1ccdb25fb61.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e2a502f0402b637c3b5db1ccdb25fb61.txt new file mode 100644 index 0000000..8cf7cf7 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e2a502f0402b637c3b5db1ccdb25fb61.txt @@ -0,0 +1,4 @@ +0 0.2645348837209302 0.171875 0.20348837209302326 0.15625 +0 0.8226744186046512 0.71875 0.20348837209302326 0.15625 +0 0.34011627906976744 0.6901041666666666 0.20348837209302326 0.15625 +0 0.6337209302325582 0.09895833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e2b67e42c1f88376694b6a4c4332f8ea.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e2b67e42c1f88376694b6a4c4332f8ea.txt new file mode 100644 index 0000000..d2f05ab --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e2b67e42c1f88376694b6a4c4332f8ea.txt @@ -0,0 +1,4 @@ +0 0.7616279069767442 0.5729166666666666 0.20348837209302326 0.15625 +0 0.14244186046511628 0.6901041666666666 0.20348837209302326 0.15625 +0 0.38372093023255816 0.16927083333333331 0.20348837209302326 0.15625 +0 0.42441860465116277 0.6458333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e349c3a317b4692f88fbe1c2f9550650.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e349c3a317b4692f88fbe1c2f9550650.txt new file mode 100644 index 0000000..9f8a98e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e349c3a317b4692f88fbe1c2f9550650.txt @@ -0,0 +1,4 @@ +0 0.438953488372093 0.18229166666666666 0.20348837209302326 0.15625 +0 0.17151162790697674 0.5572916666666666 0.20348837209302326 0.15625 +0 0.5377906976744186 0.47916666666666663 0.20348837209302326 0.15625 +0 0.8284883720930233 0.7552083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e381598da10b8a7bd22119e0d2fddd11.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e381598da10b8a7bd22119e0d2fddd11.txt new file mode 100644 index 0000000..4218529 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e381598da10b8a7bd22119e0d2fddd11.txt @@ -0,0 +1,3 @@ +0 0.8343023255813954 0.2890625 0.20348837209302326 0.15625 +0 0.45930232558139533 0.2421875 0.20348837209302326 0.15625 +0 0.24127906976744184 0.6223958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3bf512165d0cffeed9d91930b48a552.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3bf512165d0cffeed9d91930b48a552.txt new file mode 100644 index 0000000..b740f42 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3bf512165d0cffeed9d91930b48a552.txt @@ -0,0 +1,3 @@ +0 0.46511627906976744 0.2708333333333333 0.20348837209302326 0.15625 +0 0.37790697674418605 0.7317708333333333 0.20348837209302326 0.15625 +0 0.8023255813953488 0.484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3e2d910ace52fa2d6b81ca1ada0484c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3e2d910ace52fa2d6b81ca1ada0484c.txt new file mode 100644 index 0000000..9de81da --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3e2d910ace52fa2d6b81ca1ada0484c.txt @@ -0,0 +1,4 @@ +0 0.37790697674418605 0.2421875 0.20348837209302326 0.15625 +0 0.18895348837209303 0.5442708333333333 0.20348837209302326 0.15625 +0 0.7441860465116279 0.4348958333333333 0.20348837209302326 0.15625 +0 0.6773255813953488 0.1484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3e9ab66c181c1968c8cdb3bda22e3d8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3e9ab66c181c1968c8cdb3bda22e3d8.txt new file mode 100644 index 0000000..e27a43e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3e9ab66c181c1968c8cdb3bda22e3d8.txt @@ -0,0 +1,4 @@ +0 0.5116279069767442 0.5572916666666666 0.20348837209302326 0.15625 +0 0.7936046511627907 0.6458333333333333 0.20348837209302326 0.15625 +0 0.30523255813953487 0.14322916666666666 0.20348837209302326 0.15625 +0 0.8691860465116279 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3ecb138c60227b3d36960b80e6b9969.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3ecb138c60227b3d36960b80e6b9969.txt new file mode 100644 index 0000000..fbbdd99 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3ecb138c60227b3d36960b80e6b9969.txt @@ -0,0 +1,5 @@ +0 0.1686046511627907 0.3411458333333333 0.20348837209302326 0.15625 +0 0.5377906976744186 0.6276041666666666 0.20348837209302326 0.15625 +0 0.8255813953488372 0.265625 0.20348837209302326 0.15625 +0 0.18023255813953487 0.6588541666666666 0.20348837209302326 0.15625 +0 0.5058139534883721 0.18489583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3f2abeac581b5b6d531d5d6c1fe2972.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3f2abeac581b5b6d531d5d6c1fe2972.txt new file mode 100644 index 0000000..35dafbd --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e3f2abeac581b5b6d531d5d6c1fe2972.txt @@ -0,0 +1,4 @@ +0 0.6598837209302325 0.11979166666666666 0.20348837209302326 0.15625 +0 0.6075581395348837 0.7291666666666666 0.20348837209302326 0.15625 +0 0.2616279069767442 0.4036458333333333 0.20348837209302326 0.15625 +0 0.27906976744186046 0.15104166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e4ae4d0417907bc046df141816330761.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e4ae4d0417907bc046df141816330761.txt new file mode 100644 index 0000000..a3a7688 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e4ae4d0417907bc046df141816330761.txt @@ -0,0 +1,4 @@ +0 0.5843023255813954 0.7239583333333333 0.20348837209302326 0.15625 +0 0.29069767441860467 0.6458333333333333 0.20348837209302326 0.15625 +0 0.31976744186046513 0.22395833333333331 0.20348837209302326 0.15625 +0 0.7296511627906976 0.3802083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e5d29009315cdd9199c28f9b4b7fedc0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e5d29009315cdd9199c28f9b4b7fedc0.txt new file mode 100644 index 0000000..49b8b2c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e5d29009315cdd9199c28f9b4b7fedc0.txt @@ -0,0 +1,5 @@ +0 0.3023255813953488 0.7213541666666666 0.20348837209302326 0.15625 +0 0.37209302325581395 0.29166666666666663 0.20348837209302326 0.15625 +0 0.7790697674418604 0.171875 0.20348837209302326 0.15625 +0 0.7180232558139534 0.4375 0.20348837209302326 0.15625 +0 0.6453488372093024 0.7291666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e60a704fe016af2c1203fcc215932b89.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e60a704fe016af2c1203fcc215932b89.txt new file mode 100644 index 0000000..408e889 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e60a704fe016af2c1203fcc215932b89.txt @@ -0,0 +1,5 @@ +0 0.561046511627907 0.7682291666666666 0.20348837209302326 0.15625 +0 0.375 0.2552083333333333 0.20348837209302326 0.15625 +0 0.7267441860465116 0.171875 0.20348837209302326 0.15625 +0 0.49127906976744184 0.5286458333333333 0.20348837209302326 0.15625 +0 0.22093023255813954 0.6692708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e63d0af49aab5f943fb4c74216ae7969.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e63d0af49aab5f943fb4c74216ae7969.txt new file mode 100644 index 0000000..9b577d2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e63d0af49aab5f943fb4c74216ae7969.txt @@ -0,0 +1,4 @@ +0 0.5087209302325582 0.4192708333333333 0.20348837209302326 0.15625 +0 0.22965116279069767 0.578125 0.20348837209302326 0.15625 +0 0.438953488372093 0.10416666666666666 0.20348837209302326 0.15625 +0 0.8255813953488372 0.4661458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e64efc5cf5db058ed929e7d8a34bfeaf.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e64efc5cf5db058ed929e7d8a34bfeaf.txt new file mode 100644 index 0000000..f299abe --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e64efc5cf5db058ed929e7d8a34bfeaf.txt @@ -0,0 +1,4 @@ +0 0.5697674418604651 0.359375 0.20348837209302326 0.15625 +0 0.6976744186046512 0.1171875 0.20348837209302326 0.15625 +0 0.22674418604651161 0.6901041666666666 0.20348837209302326 0.15625 +0 0.5436046511627907 0.6692708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6511fe6ea5d4b1f4f0652534dcb98ec.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6511fe6ea5d4b1f4f0652534dcb98ec.txt new file mode 100644 index 0000000..3cb799c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6511fe6ea5d4b1f4f0652534dcb98ec.txt @@ -0,0 +1,4 @@ +0 0.4418604651162791 0.6171875 0.20348837209302326 0.15625 +0 0.3691860465116279 0.328125 0.20348837209302326 0.15625 +0 0.7645348837209303 0.3255208333333333 0.20348837209302326 0.15625 +0 0.13372093023255813 0.6979166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6748fe9f71e2d4cc2e56584ff7af39f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6748fe9f71e2d4cc2e56584ff7af39f.txt new file mode 100644 index 0000000..c641e69 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6748fe9f71e2d4cc2e56584ff7af39f.txt @@ -0,0 +1,5 @@ +0 0.4883720930232558 0.5807291666666666 0.20348837209302326 0.15625 +0 0.6104651162790697 0.1171875 0.20348837209302326 0.15625 +0 0.14534883720930233 0.1171875 0.20348837209302326 0.15625 +0 0.7819767441860465 0.40885416666666663 0.20348837209302326 0.15625 +0 0.13662790697674418 0.41666666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e67be5e6f883bdb1796d879ec9863175.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e67be5e6f883bdb1796d879ec9863175.txt new file mode 100644 index 0000000..e132def --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e67be5e6f883bdb1796d879ec9863175.txt @@ -0,0 +1,3 @@ +0 0.15406976744186046 0.11458333333333333 0.20348837209302326 0.15625 +0 0.6598837209302325 0.4765625 0.20348837209302326 0.15625 +0 0.2180232558139535 0.5494791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6950aeb6e43981bcd6c37503062b363.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6950aeb6e43981bcd6c37503062b363.txt new file mode 100644 index 0000000..2d30e4d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6950aeb6e43981bcd6c37503062b363.txt @@ -0,0 +1,5 @@ +0 0.40988372093023256 0.5416666666666666 0.20348837209302326 0.15625 +0 0.5494186046511628 0.11197916666666666 0.20348837209302326 0.15625 +0 0.22674418604651161 0.23177083333333331 0.20348837209302326 0.15625 +0 0.8023255813953488 0.5364583333333333 0.20348837209302326 0.15625 +0 0.8081395348837209 0.75 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6c42b9ef60841473295b5ac704f3066.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6c42b9ef60841473295b5ac704f3066.txt new file mode 100644 index 0000000..3c4c57f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6c42b9ef60841473295b5ac704f3066.txt @@ -0,0 +1,4 @@ +0 0.627906976744186 0.6067708333333333 0.20348837209302326 0.15625 +0 0.18895348837209303 0.3098958333333333 0.20348837209302326 0.15625 +0 0.3226744186046512 0.7578125 0.20348837209302326 0.15625 +0 0.4825581395348837 0.34375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6cfe8a895e3920fe6530d125607a661.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6cfe8a895e3920fe6530d125607a661.txt new file mode 100644 index 0000000..98490ae --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6cfe8a895e3920fe6530d125607a661.txt @@ -0,0 +1,4 @@ +0 0.8197674418604651 0.5859375 0.20348837209302326 0.15625 +0 0.5406976744186046 0.10677083333333333 0.20348837209302326 0.15625 +0 0.2645348837209302 0.27604166666666663 0.20348837209302326 0.15625 +0 0.7412790697674418 0.3411458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6dc56edf4211cf70bb21a9079e8fad4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6dc56edf4211cf70bb21a9079e8fad4.txt new file mode 100644 index 0000000..1bc25a7 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6dc56edf4211cf70bb21a9079e8fad4.txt @@ -0,0 +1,4 @@ +0 0.7732558139534884 0.4114583333333333 0.20348837209302326 0.15625 +0 0.35174418604651164 0.26041666666666663 0.20348837209302326 0.15625 +0 0.4563953488372093 0.6640625 0.20348837209302326 0.15625 +0 0.7790697674418604 0.6979166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6ed675168ed70283aa2cbca2ff8b375.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6ed675168ed70283aa2cbca2ff8b375.txt new file mode 100644 index 0000000..3d2c787 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6ed675168ed70283aa2cbca2ff8b375.txt @@ -0,0 +1,4 @@ +0 0.31976744186046513 0.1796875 0.20348837209302326 0.15625 +0 0.2645348837209302 0.5104166666666666 0.20348837209302326 0.15625 +0 0.8226744186046512 0.5963541666666666 0.20348837209302326 0.15625 +0 0.7819767441860465 0.36197916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6f46bf7797969bf38623ddd570a9408.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6f46bf7797969bf38623ddd570a9408.txt new file mode 100644 index 0000000..df3875f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e6f46bf7797969bf38623ddd570a9408.txt @@ -0,0 +1,5 @@ +0 0.47674418604651164 0.703125 0.20348837209302326 0.15625 +0 0.1947674418604651 0.6119791666666666 0.20348837209302326 0.15625 +0 0.8081395348837209 0.6302083333333333 0.20348837209302326 0.15625 +0 0.15406976744186046 0.3489583333333333 0.20348837209302326 0.15625 +0 0.4796511627906977 0.26822916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e71b0de681ce977be56b1fd764779892.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e71b0de681ce977be56b1fd764779892.txt new file mode 100644 index 0000000..80fd26b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e71b0de681ce977be56b1fd764779892.txt @@ -0,0 +1,3 @@ +0 0.6162790697674418 0.25 0.20348837209302326 0.15625 +0 0.8430232558139534 0.7708333333333333 0.20348837209302326 0.15625 +0 0.4563953488372093 0.6614583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e76267df26cb369b5ed1dbb7eb0a3304.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e76267df26cb369b5ed1dbb7eb0a3304.txt new file mode 100644 index 0000000..e034fbe --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e76267df26cb369b5ed1dbb7eb0a3304.txt @@ -0,0 +1,4 @@ +0 0.7936046511627907 0.4036458333333333 0.20348837209302326 0.15625 +0 0.4680232558139535 0.6822916666666666 0.20348837209302326 0.15625 +0 0.8023255813953488 0.6796875 0.20348837209302326 0.15625 +0 0.3866279069767442 0.15885416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e7a50aecb95568cde974a3155ba578b6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e7a50aecb95568cde974a3155ba578b6.txt new file mode 100644 index 0000000..a660b78 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e7a50aecb95568cde974a3155ba578b6.txt @@ -0,0 +1,5 @@ +0 0.6918604651162791 0.7317708333333333 0.20348837209302326 0.15625 +0 0.6598837209302325 0.3567708333333333 0.20348837209302326 0.15625 +0 0.3023255813953488 0.7395833333333333 0.20348837209302326 0.15625 +0 0.19186046511627908 0.5 0.20348837209302326 0.15625 +0 0.2819767441860465 0.09375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e7f387540578c6de71bca05335eb5db4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e7f387540578c6de71bca05335eb5db4.txt new file mode 100644 index 0000000..15fa6ca --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e7f387540578c6de71bca05335eb5db4.txt @@ -0,0 +1,4 @@ +0 0.3081395348837209 0.7213541666666666 0.20348837209302326 0.15625 +0 0.3691860465116279 0.2786458333333333 0.20348837209302326 0.15625 +0 0.7151162790697674 0.6796875 0.20348837209302326 0.15625 +0 0.7616279069767442 0.4296875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e81e2808fe55b860af30840346f58759.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e81e2808fe55b860af30840346f58759.txt new file mode 100644 index 0000000..50581be --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e81e2808fe55b860af30840346f58759.txt @@ -0,0 +1,4 @@ +0 0.502906976744186 0.33854166666666663 0.20348837209302326 0.15625 +0 0.8430232558139534 0.15364583333333331 0.20348837209302326 0.15625 +0 0.5494186046511628 0.6666666666666666 0.20348837209302326 0.15625 +0 0.1511627906976744 0.21875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e81f93a95008f3fd2ec191aaca86fe85.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e81f93a95008f3fd2ec191aaca86fe85.txt new file mode 100644 index 0000000..9932a60 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e81f93a95008f3fd2ec191aaca86fe85.txt @@ -0,0 +1,5 @@ +0 0.49127906976744184 0.5598958333333333 0.20348837209302326 0.15625 +0 0.2441860465116279 0.265625 0.20348837209302326 0.15625 +0 0.6918604651162791 0.21354166666666666 0.20348837209302326 0.15625 +0 0.8488372093023255 0.578125 0.20348837209302326 0.15625 +0 0.1686046511627907 0.7526041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e83668047e25d5f73d50252507f9f2d4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e83668047e25d5f73d50252507f9f2d4.txt new file mode 100644 index 0000000..abc54cd --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e83668047e25d5f73d50252507f9f2d4.txt @@ -0,0 +1,5 @@ +0 0.5523255813953488 0.65625 0.20348837209302326 0.15625 +0 0.12209302325581395 0.6458333333333333 0.20348837209302326 0.15625 +0 0.4069767441860465 0.21614583333333331 0.20348837209302326 0.15625 +0 0.8517441860465116 0.09114583333333333 0.20348837209302326 0.15625 +0 0.8052325581395349 0.328125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e845556a1b726d19eed64166a235e3cc.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e845556a1b726d19eed64166a235e3cc.txt new file mode 100644 index 0000000..a844371 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e845556a1b726d19eed64166a235e3cc.txt @@ -0,0 +1,3 @@ +0 0.3808139534883721 0.24739583333333331 0.20348837209302326 0.15625 +0 0.6627906976744186 0.6640625 0.20348837209302326 0.15625 +0 0.8488372093023255 0.3567708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e88189acf062d3c6017180b7e1c5daed.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e88189acf062d3c6017180b7e1c5daed.txt new file mode 100644 index 0000000..c5b53e3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e88189acf062d3c6017180b7e1c5daed.txt @@ -0,0 +1,4 @@ +0 0.22965116279069767 0.3671875 0.20348837209302326 0.15625 +0 0.6569767441860465 0.6302083333333333 0.20348837209302326 0.15625 +0 0.22965116279069767 0.7005208333333333 0.20348837209302326 0.15625 +0 0.7674418604651163 0.33854166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e884072b86f47778acef2f9a4378ab0d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e884072b86f47778acef2f9a4378ab0d.txt new file mode 100644 index 0000000..f4dfb3f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e884072b86f47778acef2f9a4378ab0d.txt @@ -0,0 +1 @@ +0 0.5494186046511628 0.7864583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e88fd65b1f4b16872f90a11efcd6101b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e88fd65b1f4b16872f90a11efcd6101b.txt new file mode 100644 index 0000000..c9b2394 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e88fd65b1f4b16872f90a11efcd6101b.txt @@ -0,0 +1,5 @@ +0 0.29941860465116277 0.4739583333333333 0.20348837209302326 0.15625 +0 0.7034883720930233 0.15104166666666666 0.20348837209302326 0.15625 +0 0.5813953488372093 0.7005208333333333 0.20348837209302326 0.15625 +0 0.6918604651162791 0.46354166666666663 0.20348837209302326 0.15625 +0 0.19186046511627908 0.109375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e89be41c77735c9123dca34218d6142d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e89be41c77735c9123dca34218d6142d.txt new file mode 100644 index 0000000..9a30b4b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e89be41c77735c9123dca34218d6142d.txt @@ -0,0 +1,5 @@ +0 0.6744186046511628 0.22135416666666666 0.20348837209302326 0.15625 +0 0.34011627906976744 0.16666666666666666 0.20348837209302326 0.15625 +0 0.8546511627906976 0.6927083333333333 0.20348837209302326 0.15625 +0 0.4331395348837209 0.4583333333333333 0.20348837209302326 0.15625 +0 0.38372093023255816 0.7708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e8bf5c849e8c6c07236b8cdfa743602b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e8bf5c849e8c6c07236b8cdfa743602b.txt new file mode 100644 index 0000000..13facfc --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e8bf5c849e8c6c07236b8cdfa743602b.txt @@ -0,0 +1,4 @@ +0 0.6773255813953488 0.484375 0.20348837209302326 0.15625 +0 0.35174418604651164 0.34375 0.20348837209302326 0.15625 +0 0.5 0.7864583333333333 0.20348837209302326 0.15625 +0 0.13662790697674418 0.09635416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e8cc2b2ff44787f04455e66006dd8e7d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e8cc2b2ff44787f04455e66006dd8e7d.txt new file mode 100644 index 0000000..c337c89 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e8cc2b2ff44787f04455e66006dd8e7d.txt @@ -0,0 +1,4 @@ +0 0.2761627906976744 0.47916666666666663 0.20348837209302326 0.15625 +0 0.6511627906976745 0.5833333333333333 0.20348837209302326 0.15625 +0 0.2063953488372093 0.734375 0.20348837209302326 0.15625 +0 0.3081395348837209 0.12239583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e8e45b323583b50ee94c81ab4dfd9447.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e8e45b323583b50ee94c81ab4dfd9447.txt new file mode 100644 index 0000000..0495b0e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e8e45b323583b50ee94c81ab4dfd9447.txt @@ -0,0 +1,4 @@ +0 0.6133720930232558 0.3046875 0.20348837209302326 0.15625 +0 0.5377906976744186 0.734375 0.20348837209302326 0.15625 +0 0.30523255813953487 0.17447916666666666 0.20348837209302326 0.15625 +0 0.8023255813953488 0.515625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e90cfb0d261392f86af98fe66bc3d7a1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e90cfb0d261392f86af98fe66bc3d7a1.txt new file mode 100644 index 0000000..9ce33e2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e90cfb0d261392f86af98fe66bc3d7a1.txt @@ -0,0 +1,4 @@ +0 0.561046511627907 0.5625 0.20348837209302326 0.15625 +0 0.18023255813953487 0.6901041666666666 0.20348837209302326 0.15625 +0 0.27325581395348836 0.18489583333333331 0.20348837209302326 0.15625 +0 0.7819767441860465 0.15364583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e93b7ed193aff748bab5506f0ecb17b0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e93b7ed193aff748bab5506f0ecb17b0.txt new file mode 100644 index 0000000..395d436 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e93b7ed193aff748bab5506f0ecb17b0.txt @@ -0,0 +1,3 @@ +0 0.6686046511627907 0.578125 0.20348837209302326 0.15625 +0 0.18313953488372092 0.6067708333333333 0.20348837209302326 0.15625 +0 0.2238372093023256 0.3359375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e966b5ddd5883b9d902757a63f811e97.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e966b5ddd5883b9d902757a63f811e97.txt new file mode 100644 index 0000000..c64c149 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e966b5ddd5883b9d902757a63f811e97.txt @@ -0,0 +1,3 @@ +0 0.3430232558139535 0.3802083333333333 0.20348837209302326 0.15625 +0 0.747093023255814 0.59375 0.20348837209302326 0.15625 +0 0.7732558139534884 0.3333333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e99913b8e2feec0714f9db3c4815e94e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e99913b8e2feec0714f9db3c4815e94e.txt new file mode 100644 index 0000000..999512b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e99913b8e2feec0714f9db3c4815e94e.txt @@ -0,0 +1,5 @@ +0 0.7790697674418604 0.3880208333333333 0.20348837209302326 0.15625 +0 0.26744186046511625 0.2708333333333333 0.20348837209302326 0.15625 +0 0.40406976744186046 0.6354166666666666 0.20348837209302326 0.15625 +0 0.561046511627907 0.10677083333333333 0.20348837209302326 0.15625 +0 0.8168604651162791 0.609375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e9a90694356db46c54e253119acea3a3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e9a90694356db46c54e253119acea3a3.txt new file mode 100644 index 0000000..5cc485a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/e9a90694356db46c54e253119acea3a3.txt @@ -0,0 +1,4 @@ +0 0.44476744186046513 0.5598958333333333 0.20348837209302326 0.15625 +0 0.8313953488372093 0.640625 0.20348837209302326 0.15625 +0 0.311046511627907 0.30729166666666663 0.20348837209302326 0.15625 +0 0.7936046511627907 0.19270833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ea3674e09b8de8e989bde545aa574bff.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ea3674e09b8de8e989bde545aa574bff.txt new file mode 100644 index 0000000..8df199f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ea3674e09b8de8e989bde545aa574bff.txt @@ -0,0 +1,4 @@ +0 0.6976744186046512 0.7942708333333333 0.20348837209302326 0.15625 +0 0.46511627906976744 0.3723958333333333 0.20348837209302326 0.15625 +0 0.8401162790697674 0.4348958333333333 0.20348837209302326 0.15625 +0 0.438953488372093 0.12239583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/eb009f3942389ab23b87c64e7db10dda.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/eb009f3942389ab23b87c64e7db10dda.txt new file mode 100644 index 0000000..76bf7c5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/eb009f3942389ab23b87c64e7db10dda.txt @@ -0,0 +1,5 @@ +0 0.4825581395348837 0.34375 0.20348837209302326 0.15625 +0 0.8343023255813954 0.7760416666666666 0.20348837209302326 0.15625 +0 0.13372093023255813 0.6692708333333333 0.20348837209302326 0.15625 +0 0.8430232558139534 0.31510416666666663 0.20348837209302326 0.15625 +0 0.2063953488372093 0.15364583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/eb0afb42fb2569620832f9fad5703b5e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/eb0afb42fb2569620832f9fad5703b5e.txt new file mode 100644 index 0000000..8d74d66 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/eb0afb42fb2569620832f9fad5703b5e.txt @@ -0,0 +1,4 @@ +0 0.3895348837209302 0.140625 0.20348837209302326 0.15625 +0 0.7994186046511628 0.4036458333333333 0.20348837209302326 0.15625 +0 0.1686046511627907 0.46354166666666663 0.20348837209302326 0.15625 +0 0.4505813953488372 0.7708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ec41cd654443d0332389db08ded1eb33.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ec41cd654443d0332389db08ded1eb33.txt new file mode 100644 index 0000000..d75efe7 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ec41cd654443d0332389db08ded1eb33.txt @@ -0,0 +1,5 @@ +0 0.8372093023255813 0.20572916666666666 0.20348837209302326 0.15625 +0 0.33430232558139533 0.7161458333333333 0.20348837209302326 0.15625 +0 0.14244186046511628 0.4453125 0.20348837209302326 0.15625 +0 0.7819767441860465 0.5442708333333333 0.20348837209302326 0.15625 +0 0.4505813953488372 0.4817708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ecaff9787a434308f5e7b5e26728b80b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ecaff9787a434308f5e7b5e26728b80b.txt new file mode 100644 index 0000000..bff4d68 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ecaff9787a434308f5e7b5e26728b80b.txt @@ -0,0 +1,3 @@ +0 0.2645348837209302 0.16145833333333331 0.20348837209302326 0.15625 +0 0.8459302325581395 0.4817708333333333 0.20348837209302326 0.15625 +0 0.10755813953488372 0.4375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ed2e95ed8716218b6caed4d6b6140050.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ed2e95ed8716218b6caed4d6b6140050.txt new file mode 100644 index 0000000..7ff42f2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ed2e95ed8716218b6caed4d6b6140050.txt @@ -0,0 +1,4 @@ +0 0.47674418604651164 0.7395833333333333 0.20348837209302326 0.15625 +0 0.8168604651162791 0.46875 0.20348837209302326 0.15625 +0 0.686046511627907 0.21354166666666666 0.20348837209302326 0.15625 +0 0.45930232558139533 0.4895833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ed7756c3f3c50164d26f8dbd623060a8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ed7756c3f3c50164d26f8dbd623060a8.txt new file mode 100644 index 0000000..0a0d10c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ed7756c3f3c50164d26f8dbd623060a8.txt @@ -0,0 +1,4 @@ +0 0.5872093023255814 0.23958333333333331 0.20348837209302326 0.15625 +0 0.16569767441860464 0.4895833333333333 0.20348837209302326 0.15625 +0 0.16569767441860464 0.7369791666666666 0.20348837209302326 0.15625 +0 0.5406976744186046 0.5989583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/eda5c3c7718f3070479dc8264b818972.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/eda5c3c7718f3070479dc8264b818972.txt new file mode 100644 index 0000000..0c01987 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/eda5c3c7718f3070479dc8264b818972.txt @@ -0,0 +1,2 @@ +0 0.6947674418604651 0.44010416666666663 0.20348837209302326 0.15625 +0 0.15988372093023256 0.6223958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/edad635a8ef302e06dc4cbecec03f056.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/edad635a8ef302e06dc4cbecec03f056.txt new file mode 100644 index 0000000..e626bdd --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/edad635a8ef302e06dc4cbecec03f056.txt @@ -0,0 +1,4 @@ +0 0.5203488372093024 0.671875 0.20348837209302326 0.15625 +0 0.30523255813953487 0.30729166666666663 0.20348837209302326 0.15625 +0 0.7790697674418604 0.4375 0.20348837209302326 0.15625 +0 0.16279069767441862 0.6614583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/edcde9aaa4d7b55b8034212857aca0e1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/edcde9aaa4d7b55b8034212857aca0e1.txt new file mode 100644 index 0000000..e324854 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/edcde9aaa4d7b55b8034212857aca0e1.txt @@ -0,0 +1,4 @@ +0 0.6046511627906976 0.6041666666666666 0.20348837209302326 0.15625 +0 0.18604651162790697 0.3984375 0.20348837209302326 0.15625 +0 0.8401162790697674 0.234375 0.20348837209302326 0.15625 +0 0.40406976744186046 0.11458333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/edd8f46d6e4ff0f193cc2d82ccb24f63.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/edd8f46d6e4ff0f193cc2d82ccb24f63.txt new file mode 100644 index 0000000..4e7f8a9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/edd8f46d6e4ff0f193cc2d82ccb24f63.txt @@ -0,0 +1,4 @@ +0 0.6453488372093024 0.19270833333333331 0.20348837209302326 0.15625 +0 0.14244186046511628 0.671875 0.20348837209302326 0.15625 +0 0.8081395348837209 0.7734375 0.20348837209302326 0.15625 +0 0.3546511627906977 0.3828125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ee6083c50b40ff0c8a2828a17324ba6c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ee6083c50b40ff0c8a2828a17324ba6c.txt new file mode 100644 index 0000000..ce23abd --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ee6083c50b40ff0c8a2828a17324ba6c.txt @@ -0,0 +1,4 @@ +0 0.3081395348837209 0.7864583333333333 0.20348837209302326 0.15625 +0 0.8284883720930233 0.3802083333333333 0.20348837209302326 0.15625 +0 0.3023255813953488 0.15625 0.20348837209302326 0.15625 +0 0.3575581395348837 0.5364583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef0e92bbbee4dcaa25363dd1ff9708c6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef0e92bbbee4dcaa25363dd1ff9708c6.txt new file mode 100644 index 0000000..a8bbe4f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef0e92bbbee4dcaa25363dd1ff9708c6.txt @@ -0,0 +1,5 @@ +0 0.11627906976744186 0.21614583333333331 0.20348837209302326 0.15625 +0 0.23837209302325582 0.6875 0.20348837209302326 0.15625 +0 0.4273255813953488 0.4140625 0.20348837209302326 0.15625 +0 0.8575581395348837 0.1796875 0.20348837209302326 0.15625 +0 0.4738372093023256 0.13541666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef142b889873ac51ff9b784d8db5e9a0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef142b889873ac51ff9b784d8db5e9a0.txt new file mode 100644 index 0000000..3922f2d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef142b889873ac51ff9b784d8db5e9a0.txt @@ -0,0 +1,5 @@ +0 0.36627906976744184 0.4505208333333333 0.20348837209302326 0.15625 +0 0.5406976744186046 0.7734375 0.20348837209302326 0.15625 +0 0.75 0.2421875 0.20348837209302326 0.15625 +0 0.18023255813953487 0.15104166666666666 0.20348837209302326 0.15625 +0 0.7267441860465116 0.5 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef2633e9d1e96b147eeaa2c12c896070.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef2633e9d1e96b147eeaa2c12c896070.txt new file mode 100644 index 0000000..269321b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef2633e9d1e96b147eeaa2c12c896070.txt @@ -0,0 +1,5 @@ +0 0.4476744186046512 0.16145833333333331 0.20348837209302326 0.15625 +0 0.8372093023255813 0.11197916666666666 0.20348837209302326 0.15625 +0 0.6802325581395349 0.43229166666666663 0.20348837209302326 0.15625 +0 0.2645348837209302 0.4270833333333333 0.20348837209302326 0.15625 +0 0.7761627906976744 0.7473958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef6f902af6acf7d065bfd20d91cb9ae5.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef6f902af6acf7d065bfd20d91cb9ae5.txt new file mode 100644 index 0000000..6ffb640 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef6f902af6acf7d065bfd20d91cb9ae5.txt @@ -0,0 +1,4 @@ +0 0.35174418604651164 0.09895833333333333 0.20348837209302326 0.15625 +0 0.4883720930232558 0.44010416666666663 0.20348837209302326 0.15625 +0 0.8604651162790697 0.3046875 0.20348837209302326 0.15625 +0 0.18313953488372092 0.4036458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef8337cf15c42924b10ae3a502cf0424.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef8337cf15c42924b10ae3a502cf0424.txt new file mode 100644 index 0000000..dc63108 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef8337cf15c42924b10ae3a502cf0424.txt @@ -0,0 +1,4 @@ +0 0.8430232558139534 0.7421875 0.20348837209302326 0.15625 +0 0.22093023255813954 0.6510416666666666 0.20348837209302326 0.15625 +0 0.563953488372093 0.4453125 0.20348837209302326 0.15625 +0 0.561046511627907 0.07552083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef98d3f6f1dc4fefad9f4a81c0560853.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef98d3f6f1dc4fefad9f4a81c0560853.txt new file mode 100644 index 0000000..65435c3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ef98d3f6f1dc4fefad9f4a81c0560853.txt @@ -0,0 +1,4 @@ +0 0.5058139534883721 0.19270833333333331 0.20348837209302326 0.15625 +0 0.20930232558139533 0.6979166666666666 0.20348837209302326 0.15625 +0 0.5697674418604651 0.7864583333333333 0.20348837209302326 0.15625 +0 0.8372093023255813 0.09375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/efad6135fc1469652c4e4a49b8e875e7.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/efad6135fc1469652c4e4a49b8e875e7.txt new file mode 100644 index 0000000..1ca98dd --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/efad6135fc1469652c4e4a49b8e875e7.txt @@ -0,0 +1,4 @@ +0 0.5436046511627907 0.4453125 0.20348837209302326 0.15625 +0 0.18313953488372092 0.4921875 0.20348837209302326 0.15625 +0 0.27906976744186046 0.75 0.20348837209302326 0.15625 +0 0.8343023255813954 0.7161458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/efb8e140b425665084ff3e98266b531a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/efb8e140b425665084ff3e98266b531a.txt new file mode 100644 index 0000000..43f44d6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/efb8e140b425665084ff3e98266b531a.txt @@ -0,0 +1,3 @@ +0 0.502906976744186 0.6171875 0.20348837209302326 0.15625 +0 0.6395348837209303 0.2630208333333333 0.20348837209302326 0.15625 +0 0.3023255813953488 0.3359375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f00bb17d85d51e29e4ec1d51a2226f17.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f00bb17d85d51e29e4ec1d51a2226f17.txt new file mode 100644 index 0000000..00c1cc2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f00bb17d85d51e29e4ec1d51a2226f17.txt @@ -0,0 +1,4 @@ +0 0.18313953488372092 0.14322916666666666 0.20348837209302326 0.15625 +0 0.6686046511627907 0.6380208333333333 0.20348837209302326 0.15625 +0 0.6569767441860465 0.16927083333333331 0.20348837209302326 0.15625 +0 0.313953488372093 0.4973958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f05d20abb2b9936d9a522fab738108d4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f05d20abb2b9936d9a522fab738108d4.txt new file mode 100644 index 0000000..964077a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f05d20abb2b9936d9a522fab738108d4.txt @@ -0,0 +1,4 @@ +0 0.36046511627906974 0.734375 0.20348837209302326 0.15625 +0 0.3895348837209302 0.3958333333333333 0.20348837209302326 0.15625 +0 0.8226744186046512 0.5208333333333333 0.20348837209302326 0.15625 +0 0.7005813953488372 0.7864583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f0db95fcb74fbc15d56e0ade5c34a96f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f0db95fcb74fbc15d56e0ade5c34a96f.txt new file mode 100644 index 0000000..f21d176 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f0db95fcb74fbc15d56e0ade5c34a96f.txt @@ -0,0 +1,4 @@ +0 0.4331395348837209 0.6458333333333333 0.20348837209302326 0.15625 +0 0.7122093023255814 0.13541666666666666 0.20348837209302326 0.15625 +0 0.7848837209302325 0.5520833333333333 0.20348837209302326 0.15625 +0 0.19767441860465115 0.21875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f104dc3ca2a0360bf8b854f76b5072ce.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f104dc3ca2a0360bf8b854f76b5072ce.txt new file mode 100644 index 0000000..bbfe1e6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f104dc3ca2a0360bf8b854f76b5072ce.txt @@ -0,0 +1,4 @@ +0 0.4418604651162791 0.7395833333333333 0.20348837209302326 0.15625 +0 0.6715116279069767 0.2708333333333333 0.20348837209302326 0.15625 +0 0.8226744186046512 0.6979166666666666 0.20348837209302326 0.15625 +0 0.12790697674418605 0.78125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f13fec218b99e2dc108126d2334a9ebf.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f13fec218b99e2dc108126d2334a9ebf.txt new file mode 100644 index 0000000..beaf9bc --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f13fec218b99e2dc108126d2334a9ebf.txt @@ -0,0 +1,2 @@ +0 0.16569767441860464 0.33072916666666663 0.20348837209302326 0.15625 +0 0.6308139534883721 0.5963541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f16c02e82910f941af67378563d3b415.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f16c02e82910f941af67378563d3b415.txt new file mode 100644 index 0000000..2382368 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f16c02e82910f941af67378563d3b415.txt @@ -0,0 +1,4 @@ +0 0.7325581395348837 0.21614583333333331 0.20348837209302326 0.15625 +0 0.4331395348837209 0.36197916666666663 0.20348837209302326 0.15625 +0 0.14534883720930233 0.1171875 0.20348837209302326 0.15625 +0 0.8430232558139534 0.5859375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f195752519f8dd4fd2a9bdbc1b141397.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f195752519f8dd4fd2a9bdbc1b141397.txt new file mode 100644 index 0000000..5bffa77 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f195752519f8dd4fd2a9bdbc1b141397.txt @@ -0,0 +1,5 @@ +0 0.7732558139534884 0.5416666666666666 0.20348837209302326 0.15625 +0 0.38372093023255816 0.20833333333333331 0.20348837209302326 0.15625 +0 0.32848837209302323 0.4583333333333333 0.20348837209302326 0.15625 +0 0.7819767441860465 0.22395833333333331 0.20348837209302326 0.15625 +0 0.4418604651162791 0.7239583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f1ea9f845f208c1bd0d5c86730759e1a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f1ea9f845f208c1bd0d5c86730759e1a.txt new file mode 100644 index 0000000..7188185 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f1ea9f845f208c1bd0d5c86730759e1a.txt @@ -0,0 +1,4 @@ +0 0.5988372093023255 0.125 0.20348837209302326 0.15625 +0 0.4215116279069767 0.6822916666666666 0.20348837209302326 0.15625 +0 0.8255813953488372 0.7708333333333333 0.20348837209302326 0.15625 +0 0.2761627906976744 0.21354166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f272b5c0201d78e19128800eafbbea76.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f272b5c0201d78e19128800eafbbea76.txt new file mode 100644 index 0000000..f5f20f2 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f272b5c0201d78e19128800eafbbea76.txt @@ -0,0 +1,4 @@ +0 0.31976744186046513 0.23958333333333331 0.20348837209302326 0.15625 +0 0.2703488372093023 0.7421875 0.20348837209302326 0.15625 +0 0.688953488372093 0.15364583333333331 0.20348837209302326 0.15625 +0 0.6918604651162791 0.7447916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f28c3cfc1c94c00febc3717f177e1e28.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f28c3cfc1c94c00febc3717f177e1e28.txt new file mode 100644 index 0000000..4f893d3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f28c3cfc1c94c00febc3717f177e1e28.txt @@ -0,0 +1,4 @@ +0 0.752906976744186 0.4661458333333333 0.20348837209302326 0.15625 +0 0.22093023255813954 0.4348958333333333 0.20348837209302326 0.15625 +0 0.27325581395348836 0.6666666666666666 0.20348837209302326 0.15625 +0 0.5901162790697674 0.15885416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f3870d18faf4bd7b6fac66f7119397cf.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f3870d18faf4bd7b6fac66f7119397cf.txt new file mode 100644 index 0000000..0f1200d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f3870d18faf4bd7b6fac66f7119397cf.txt @@ -0,0 +1,4 @@ +0 0.27325581395348836 0.14583333333333331 0.20348837209302326 0.15625 +0 0.27906976744186046 0.7239583333333333 0.20348837209302326 0.15625 +0 0.8401162790697674 0.11197916666666666 0.20348837209302326 0.15625 +0 0.8255813953488372 0.44791666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f409dfebaaae86cef4dcdf5306617649.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f409dfebaaae86cef4dcdf5306617649.txt new file mode 100644 index 0000000..e4b7c9c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f409dfebaaae86cef4dcdf5306617649.txt @@ -0,0 +1,4 @@ +0 0.47674418604651164 0.13541666666666666 0.20348837209302326 0.15625 +0 0.5232558139534884 0.6302083333333333 0.20348837209302326 0.15625 +0 0.7761627906976744 0.4296875 0.20348837209302326 0.15625 +0 0.12209302325581395 0.6458333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f419831f490ee7a0a50306b1f409d0a0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f419831f490ee7a0a50306b1f409d0a0.txt new file mode 100644 index 0000000..9fb57c4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f419831f490ee7a0a50306b1f409d0a0.txt @@ -0,0 +1,4 @@ +0 0.3226744186046512 0.21614583333333331 0.20348837209302326 0.15625 +0 0.2936046511627907 0.6223958333333333 0.20348837209302326 0.15625 +0 0.8168604651162791 0.11458333333333333 0.20348837209302326 0.15625 +0 0.6395348837209303 0.4192708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f47073b5a23aa6a01ae67530540b0c09.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f47073b5a23aa6a01ae67530540b0c09.txt new file mode 100644 index 0000000..d12d3c3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f47073b5a23aa6a01ae67530540b0c09.txt @@ -0,0 +1,4 @@ +0 0.34011627906976744 0.2942708333333333 0.20348837209302326 0.15625 +0 0.8226744186046512 0.27604166666666663 0.20348837209302326 0.15625 +0 0.4825581395348837 0.640625 0.20348837209302326 0.15625 +0 0.1308139534883721 0.5494791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f4bf4f9315e86ffd5e351553ed86aa4e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f4bf4f9315e86ffd5e351553ed86aa4e.txt new file mode 100644 index 0000000..d96e52e --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f4bf4f9315e86ffd5e351553ed86aa4e.txt @@ -0,0 +1,4 @@ +0 0.30523255813953487 0.3177083333333333 0.20348837209302326 0.15625 +0 0.3866279069767442 0.6197916666666666 0.20348837209302326 0.15625 +0 0.8284883720930233 0.5442708333333333 0.20348837209302326 0.15625 +0 0.8023255813953488 0.13020833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f4e820989083bf0d3f6a6fa58d23cf53.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f4e820989083bf0d3f6a6fa58d23cf53.txt new file mode 100644 index 0000000..61ef3d6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f4e820989083bf0d3f6a6fa58d23cf53.txt @@ -0,0 +1,4 @@ +0 0.2180232558139535 0.28385416666666663 0.20348837209302326 0.15625 +0 0.6773255813953488 0.7838541666666666 0.20348837209302326 0.15625 +0 0.6598837209302325 0.12239583333333333 0.20348837209302326 0.15625 +0 0.8488372093023255 0.46354166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f52b92c0cccb98f292f60d035dd2ab94.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f52b92c0cccb98f292f60d035dd2ab94.txt new file mode 100644 index 0000000..20b84ae --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f52b92c0cccb98f292f60d035dd2ab94.txt @@ -0,0 +1,5 @@ +0 0.14534883720930233 0.3020833333333333 0.20348837209302326 0.15625 +0 0.311046511627907 0.6458333333333333 0.20348837209302326 0.15625 +0 0.8401162790697674 0.7552083333333333 0.20348837209302326 0.15625 +0 0.42441860465116277 0.27604166666666663 0.20348837209302326 0.15625 +0 0.747093023255814 0.09375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f5779c0b22016b22ca856f30c661d448.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f5779c0b22016b22ca856f30c661d448.txt new file mode 100644 index 0000000..4e227b4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f5779c0b22016b22ca856f30c661d448.txt @@ -0,0 +1,3 @@ +0 0.7790697674418604 0.6536458333333333 0.20348837209302326 0.15625 +0 0.8662790697674418 0.20572916666666666 0.20348837209302326 0.15625 +0 0.13372093023255813 0.7369791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f5d23fc3190f08cbef79623ebe31a3b4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f5d23fc3190f08cbef79623ebe31a3b4.txt new file mode 100644 index 0000000..0d0bcd4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f5d23fc3190f08cbef79623ebe31a3b4.txt @@ -0,0 +1,4 @@ +0 0.8284883720930233 0.6197916666666666 0.20348837209302326 0.15625 +0 0.7005813953488372 0.37760416666666663 0.20348837209302326 0.15625 +0 0.1308139534883721 0.17708333333333331 0.20348837209302326 0.15625 +0 0.561046511627907 0.09375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f5e120f536fcc39cf654f4c94db1da9a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f5e120f536fcc39cf654f4c94db1da9a.txt new file mode 100644 index 0000000..267946f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f5e120f536fcc39cf654f4c94db1da9a.txt @@ -0,0 +1,4 @@ +0 0.3953488372093023 0.4817708333333333 0.20348837209302326 0.15625 +0 0.32558139534883723 0.1015625 0.20348837209302326 0.15625 +0 0.4331395348837209 0.7864583333333333 0.20348837209302326 0.15625 +0 0.6627906976744186 0.2890625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f5e86297f0173b3e74dccbbb7056dd08.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f5e86297f0173b3e74dccbbb7056dd08.txt new file mode 100644 index 0000000..cef2329 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f5e86297f0173b3e74dccbbb7056dd08.txt @@ -0,0 +1,5 @@ +0 0.8081395348837209 0.6145833333333333 0.20348837209302326 0.15625 +0 0.125 0.7083333333333333 0.20348837209302326 0.15625 +0 0.5813953488372093 0.34375 0.20348837209302326 0.15625 +0 0.8197674418604651 0.10416666666666666 0.20348837209302326 0.15625 +0 0.5290697674418604 0.6927083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f618add20c90062744d516dd45a4bf51.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f618add20c90062744d516dd45a4bf51.txt new file mode 100644 index 0000000..0a0a876 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f618add20c90062744d516dd45a4bf51.txt @@ -0,0 +1,4 @@ +0 0.5465116279069767 0.4583333333333333 0.20348837209302326 0.15625 +0 0.18604651162790697 0.5729166666666666 0.20348837209302326 0.15625 +0 0.6046511627906976 0.1328125 0.20348837209302326 0.15625 +0 0.8372093023255813 0.4583333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f67f614434da278ba12617e415f79d26.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f67f614434da278ba12617e415f79d26.txt new file mode 100644 index 0000000..3b4920b --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f67f614434da278ba12617e415f79d26.txt @@ -0,0 +1,4 @@ +0 0.15988372093023256 0.3645833333333333 0.20348837209302326 0.15625 +0 0.14825581395348836 0.5911458333333333 0.20348837209302326 0.15625 +0 0.8343023255813954 0.3984375 0.20348837209302326 0.15625 +0 0.5465116279069767 0.22135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f693718414860f5d84e6bc44bbca149e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f693718414860f5d84e6bc44bbca149e.txt new file mode 100644 index 0000000..538d793 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f693718414860f5d84e6bc44bbca149e.txt @@ -0,0 +1,4 @@ +0 0.6744186046511628 0.16927083333333331 0.20348837209302326 0.15625 +0 0.6366279069767442 0.7057291666666666 0.20348837209302326 0.15625 +0 0.311046511627907 0.71875 0.20348837209302326 0.15625 +0 0.2703488372093023 0.26822916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f6a6397e01be24efb536c36ce04ddef3.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f6a6397e01be24efb536c36ce04ddef3.txt new file mode 100644 index 0000000..708ad10 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f6a6397e01be24efb536c36ce04ddef3.txt @@ -0,0 +1,4 @@ +0 0.6366279069767442 0.13541666666666666 0.20348837209302326 0.15625 +0 0.5668604651162791 0.4036458333333333 0.20348837209302326 0.15625 +0 0.8052325581395349 0.7734375 0.20348837209302326 0.15625 +0 0.1947674418604651 0.37760416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f6a72b786e9f7e3c1d77c7b4fc31861c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f6a72b786e9f7e3c1d77c7b4fc31861c.txt new file mode 100644 index 0000000..2c94b4d --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f6a72b786e9f7e3c1d77c7b4fc31861c.txt @@ -0,0 +1,4 @@ +0 0.1686046511627907 0.6432291666666666 0.20348837209302326 0.15625 +0 0.7180232558139534 0.6041666666666666 0.20348837209302326 0.15625 +0 0.5348837209302325 0.14583333333333331 0.20348837209302326 0.15625 +0 0.1947674418604651 0.109375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f6d95b0399ab777293f40515cab97d51.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f6d95b0399ab777293f40515cab97d51.txt new file mode 100644 index 0000000..fbbe264 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f6d95b0399ab777293f40515cab97d51.txt @@ -0,0 +1,4 @@ +0 0.622093023255814 0.3567708333333333 0.20348837209302326 0.15625 +0 0.31976744186046513 0.1015625 0.20348837209302326 0.15625 +0 0.502906976744186 0.734375 0.20348837209302326 0.15625 +0 0.29941860465116277 0.45572916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f6fd3d9a2d77bc871d1576b63eba9af0.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f6fd3d9a2d77bc871d1576b63eba9af0.txt new file mode 100644 index 0000000..17b97aa --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f6fd3d9a2d77bc871d1576b63eba9af0.txt @@ -0,0 +1,4 @@ +0 0.43023255813953487 0.6067708333333333 0.20348837209302326 0.15625 +0 0.7441860465116279 0.71875 0.20348837209302326 0.15625 +0 0.7994186046511628 0.3489583333333333 0.20348837209302326 0.15625 +0 0.37209302325581395 0.10416666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f7301422174591a9d05be1d17e656578.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f7301422174591a9d05be1d17e656578.txt new file mode 100644 index 0000000..16d6275 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f7301422174591a9d05be1d17e656578.txt @@ -0,0 +1,4 @@ +0 0.438953488372093 0.7942708333333333 0.20348837209302326 0.15625 +0 0.5290697674418604 0.25 0.20348837209302326 0.15625 +0 0.7994186046511628 0.7135416666666666 0.20348837209302326 0.15625 +0 0.4331395348837209 0.5 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f7828e14ab620601c975a14748681fa6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f7828e14ab620601c975a14748681fa6.txt new file mode 100644 index 0000000..61ed27f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f7828e14ab620601c975a14748681fa6.txt @@ -0,0 +1,4 @@ +0 0.4505813953488372 0.5078125 0.20348837209302326 0.15625 +0 0.7732558139534884 0.6901041666666666 0.20348837209302326 0.15625 +0 0.2005813953488372 0.11979166666666666 0.20348837209302326 0.15625 +0 0.686046511627907 0.11979166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f81476f1b68856abb2403f4120c4928d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f81476f1b68856abb2403f4120c4928d.txt new file mode 100644 index 0000000..5c740d3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f81476f1b68856abb2403f4120c4928d.txt @@ -0,0 +1,4 @@ +0 0.8459302325581395 0.453125 0.20348837209302326 0.15625 +0 0.5465116279069767 0.6536458333333333 0.20348837209302326 0.15625 +0 0.20348837209302326 0.6666666666666666 0.20348837209302326 0.15625 +0 0.2616279069767442 0.3567708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f874a3d818f17de0b3139cf12056551b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f874a3d818f17de0b3139cf12056551b.txt new file mode 100644 index 0000000..aefa448 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f874a3d818f17de0b3139cf12056551b.txt @@ -0,0 +1,4 @@ +0 0.5872093023255814 0.2942708333333333 0.20348837209302326 0.15625 +0 0.2616279069767442 0.4427083333333333 0.20348837209302326 0.15625 +0 0.20348837209302326 0.15885416666666666 0.20348837209302326 0.15625 +0 0.6395348837209303 0.59375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f8c4636a0c26c3cc041a83cf078aad9c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f8c4636a0c26c3cc041a83cf078aad9c.txt new file mode 100644 index 0000000..66082aa --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f8c4636a0c26c3cc041a83cf078aad9c.txt @@ -0,0 +1,4 @@ +0 0.6308139534883721 0.1171875 0.20348837209302326 0.15625 +0 0.502906976744186 0.7161458333333333 0.20348837209302326 0.15625 +0 0.2819767441860465 0.11197916666666666 0.20348837209302326 0.15625 +0 0.6627906976744186 0.4375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f96787979e2d56bb246ee62a31b5d865.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f96787979e2d56bb246ee62a31b5d865.txt new file mode 100644 index 0000000..839d1fe --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f96787979e2d56bb246ee62a31b5d865.txt @@ -0,0 +1,4 @@ +0 0.12209302325581395 0.71875 0.20348837209302326 0.15625 +0 0.6656976744186046 0.7630208333333333 0.20348837209302326 0.15625 +0 0.6686046511627907 0.421875 0.20348837209302326 0.15625 +0 0.3575581395348837 0.34635416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f9c65d47c8441b284f3e92a262f291da.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f9c65d47c8441b284f3e92a262f291da.txt new file mode 100644 index 0000000..96a38c9 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f9c65d47c8441b284f3e92a262f291da.txt @@ -0,0 +1,4 @@ +0 0.11337209302325581 0.359375 0.20348837209302326 0.15625 +0 0.48546511627906974 0.7890625 0.20348837209302326 0.15625 +0 0.8197674418604651 0.5572916666666666 0.20348837209302326 0.15625 +0 0.7761627906976744 0.31510416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f9f5ea2a009bb50623136c1c6591a903.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f9f5ea2a009bb50623136c1c6591a903.txt new file mode 100644 index 0000000..bebca88 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f9f5ea2a009bb50623136c1c6591a903.txt @@ -0,0 +1,4 @@ +0 0.5436046511627907 0.5833333333333333 0.20348837209302326 0.15625 +0 0.21511627906976744 0.5130208333333333 0.20348837209302326 0.15625 +0 0.6656976744186046 0.16927083333333331 0.20348837209302326 0.15625 +0 0.19186046511627908 0.22135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f9f89c309709d34f6bb32f1bf2f02be2.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f9f89c309709d34f6bb32f1bf2f02be2.txt new file mode 100644 index 0000000..5504995 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/f9f89c309709d34f6bb32f1bf2f02be2.txt @@ -0,0 +1,3 @@ +0 0.23546511627906977 0.7708333333333333 0.20348837209302326 0.15625 +0 0.7005813953488372 0.2708333333333333 0.20348837209302326 0.15625 +0 0.2441860465116279 0.23177083333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fa1ea8c4f4ddd462c17bb8c81aad432c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fa1ea8c4f4ddd462c17bb8c81aad432c.txt new file mode 100644 index 0000000..2300cc4 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fa1ea8c4f4ddd462c17bb8c81aad432c.txt @@ -0,0 +1,3 @@ +0 0.3226744186046512 0.515625 0.20348837209302326 0.15625 +0 0.5174418604651163 0.765625 0.20348837209302326 0.15625 +0 0.3430232558139535 0.2630208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fa7fe8108802c83205c66fe7caade124.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fa7fe8108802c83205c66fe7caade124.txt new file mode 100644 index 0000000..b4c7725 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fa7fe8108802c83205c66fe7caade124.txt @@ -0,0 +1,5 @@ +0 0.2645348837209302 0.33854166666666663 0.20348837209302326 0.15625 +0 0.8226744186046512 0.5989583333333333 0.20348837209302326 0.15625 +0 0.7441860465116279 0.23958333333333331 0.20348837209302326 0.15625 +0 0.2703488372093023 0.5703125 0.20348837209302326 0.15625 +0 0.19186046511627908 0.7864583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/face9dcebae4da2f8a8159bfe59ee8ac.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/face9dcebae4da2f8a8159bfe59ee8ac.txt new file mode 100644 index 0000000..d3c0228 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/face9dcebae4da2f8a8159bfe59ee8ac.txt @@ -0,0 +1,2 @@ +0 0.40406976744186046 0.5104166666666666 0.20348837209302326 0.15625 +0 0.8081395348837209 0.5364583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fb4b7eeaa98f0f6b6a1bdd053d5beea8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fb4b7eeaa98f0f6b6a1bdd053d5beea8.txt new file mode 100644 index 0000000..433054a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fb4b7eeaa98f0f6b6a1bdd053d5beea8.txt @@ -0,0 +1,5 @@ +0 0.5552325581395349 0.4296875 0.20348837209302326 0.15625 +0 0.3226744186046512 0.6614583333333333 0.20348837209302326 0.15625 +0 0.44476744186046513 0.17447916666666666 0.20348837209302326 0.15625 +0 0.8604651162790697 0.6901041666666666 0.20348837209302326 0.15625 +0 0.11337209302325581 0.34635416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fbacaa34a04c3c6221d1ffeed14089b4.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fbacaa34a04c3c6221d1ffeed14089b4.txt new file mode 100644 index 0000000..1e86518 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fbacaa34a04c3c6221d1ffeed14089b4.txt @@ -0,0 +1,5 @@ +0 0.6598837209302325 0.19010416666666666 0.20348837209302326 0.15625 +0 0.36046511627906974 0.5 0.20348837209302326 0.15625 +0 0.8313953488372093 0.4296875 0.20348837209302326 0.15625 +0 0.22674418604651161 0.17708333333333331 0.20348837209302326 0.15625 +0 0.436046511627907 0.7604166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fbba3c9273686ea5984366d2c4e0da6d.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fbba3c9273686ea5984366d2c4e0da6d.txt new file mode 100644 index 0000000..b2aa8f0 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fbba3c9273686ea5984366d2c4e0da6d.txt @@ -0,0 +1,2 @@ +0 0.6366279069767442 0.2734375 0.20348837209302326 0.15625 +0 0.22093023255813954 0.11458333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fc7a198e1e6c9f93147c2195b7f1594f.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fc7a198e1e6c9f93147c2195b7f1594f.txt new file mode 100644 index 0000000..fab7ec6 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fc7a198e1e6c9f93147c2195b7f1594f.txt @@ -0,0 +1,4 @@ +0 0.7267441860465116 0.2708333333333333 0.20348837209302326 0.15625 +0 0.6686046511627907 0.6640625 0.20348837209302326 0.15625 +0 0.311046511627907 0.6744791666666666 0.20348837209302326 0.15625 +0 0.3808139534883721 0.40885416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fc9aba974677d91558a3f7a8165a6f97.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fc9aba974677d91558a3f7a8165a6f97.txt new file mode 100644 index 0000000..7e4c5ee --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fc9aba974677d91558a3f7a8165a6f97.txt @@ -0,0 +1,3 @@ +0 0.4331395348837209 0.14322916666666666 0.20348837209302326 0.15625 +0 0.2238372093023256 0.44010416666666663 0.20348837209302326 0.15625 +0 0.6598837209302325 0.5442708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fce59c14afae0c28214e78dc047f81c1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fce59c14afae0c28214e78dc047f81c1.txt new file mode 100644 index 0000000..e65a55c --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fce59c14afae0c28214e78dc047f81c1.txt @@ -0,0 +1,4 @@ +0 0.18604651162790697 0.6927083333333333 0.20348837209302326 0.15625 +0 0.502906976744186 0.4427083333333333 0.20348837209302326 0.15625 +0 0.7093023255813954 0.21614583333333331 0.20348837209302326 0.15625 +0 0.19767441860465115 0.29166666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fceef5e956eff358ec3b956dd9e2749e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fceef5e956eff358ec3b956dd9e2749e.txt new file mode 100644 index 0000000..55b24e5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fceef5e956eff358ec3b956dd9e2749e.txt @@ -0,0 +1,4 @@ +0 0.5872093023255814 0.09375 0.20348837209302326 0.15625 +0 0.375 0.4270833333333333 0.20348837209302326 0.15625 +0 0.6308139534883721 0.7135416666666666 0.20348837209302326 0.15625 +0 0.8023255813953488 0.3645833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fd007672b1bfdeb6ec15ec3f9c0da5ea.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fd007672b1bfdeb6ec15ec3f9c0da5ea.txt new file mode 100644 index 0000000..9d03050 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fd007672b1bfdeb6ec15ec3f9c0da5ea.txt @@ -0,0 +1,4 @@ +0 0.19186046511627908 0.10677083333333333 0.20348837209302326 0.15625 +0 0.4883720930232558 0.23958333333333331 0.20348837209302326 0.15625 +0 0.6918604651162791 0.7421875 0.20348837209302326 0.15625 +0 0.8023255813953488 0.4921875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fd83e0bab3cc6706a8dbd1902185167b.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fd83e0bab3cc6706a8dbd1902185167b.txt new file mode 100644 index 0000000..9b1871f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fd83e0bab3cc6706a8dbd1902185167b.txt @@ -0,0 +1,4 @@ +0 0.24127906976744184 0.453125 0.20348837209302326 0.15625 +0 0.311046511627907 0.140625 0.20348837209302326 0.15625 +0 0.6831395348837209 0.375 0.20348837209302326 0.15625 +0 0.436046511627907 0.671875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fdd51b44cf3ddf8dc6a77b9bfc19ca1c.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fdd51b44cf3ddf8dc6a77b9bfc19ca1c.txt new file mode 100644 index 0000000..1ee130a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fdd51b44cf3ddf8dc6a77b9bfc19ca1c.txt @@ -0,0 +1,5 @@ +0 0.8284883720930233 0.12239583333333333 0.20348837209302326 0.15625 +0 0.747093023255814 0.5078125 0.20348837209302326 0.15625 +0 0.4825581395348837 0.19791666666666666 0.20348837209302326 0.15625 +0 0.34011627906976744 0.5729166666666666 0.20348837209302326 0.15625 +0 0.4476744186046512 0.7864583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fddadb61964144436fd9980dcf8144a1.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fddadb61964144436fd9980dcf8144a1.txt new file mode 100644 index 0000000..6b10f57 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fddadb61964144436fd9980dcf8144a1.txt @@ -0,0 +1,3 @@ +0 0.18313953488372092 0.24739583333333331 0.20348837209302326 0.15625 +0 0.6598837209302325 0.3880208333333333 0.20348837209302326 0.15625 +0 0.1511627906976744 0.7005208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fde51bc25cd84efd04b7e429fdb817b6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fde51bc25cd84efd04b7e429fdb817b6.txt new file mode 100644 index 0000000..01b3b6a --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fde51bc25cd84efd04b7e429fdb817b6.txt @@ -0,0 +1,4 @@ +0 0.747093023255814 0.6901041666666666 0.20348837209302326 0.15625 +0 0.24127906976744184 0.5963541666666666 0.20348837209302326 0.15625 +0 0.4215116279069767 0.12239583333333333 0.20348837209302326 0.15625 +0 0.7209302325581395 0.3645833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe0db3048d5452a58d50970966be8fc6.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe0db3048d5452a58d50970966be8fc6.txt new file mode 100644 index 0000000..0a0fd99 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe0db3048d5452a58d50970966be8fc6.txt @@ -0,0 +1,4 @@ +0 0.4680232558139535 0.5182291666666666 0.20348837209302326 0.15625 +0 0.36046511627906974 0.15885416666666666 0.20348837209302326 0.15625 +0 0.23546511627906977 0.765625 0.20348837209302326 0.15625 +0 0.7674418604651163 0.6067708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe1d90af8cc5f60d6905a005e026b5cd.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe1d90af8cc5f60d6905a005e026b5cd.txt new file mode 100644 index 0000000..a6f7b4f --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe1d90af8cc5f60d6905a005e026b5cd.txt @@ -0,0 +1,4 @@ +0 0.7994186046511628 0.44010416666666663 0.20348837209302326 0.15625 +0 0.3633720930232558 0.4739583333333333 0.20348837209302326 0.15625 +0 0.7238372093023255 0.2109375 0.20348837209302326 0.15625 +0 0.3633720930232558 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe4697abfff8dd17fe11ca475577c38a.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe4697abfff8dd17fe11ca475577c38a.txt new file mode 100644 index 0000000..56473ce --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe4697abfff8dd17fe11ca475577c38a.txt @@ -0,0 +1,5 @@ +0 0.13372093023255813 0.2552083333333333 0.20348837209302326 0.15625 +0 0.5697674418604651 0.359375 0.20348837209302326 0.15625 +0 0.8430232558139534 0.11197916666666666 0.20348837209302326 0.15625 +0 0.7819767441860465 0.6119791666666666 0.20348837209302326 0.15625 +0 0.23255813953488372 0.6041666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe642b4b7ccf1bb853a35278c80e90a8.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe642b4b7ccf1bb853a35278c80e90a8.txt new file mode 100644 index 0000000..b0f4de5 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe642b4b7ccf1bb853a35278c80e90a8.txt @@ -0,0 +1,5 @@ +0 0.4825581395348837 0.18489583333333331 0.20348837209302326 0.15625 +0 0.5552325581395349 0.4765625 0.20348837209302326 0.15625 +0 0.15988372093023256 0.7604166666666666 0.20348837209302326 0.15625 +0 0.6337209302325582 0.734375 0.20348837209302326 0.15625 +0 0.18313953488372092 0.5208333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe64c41bfccc5883f85639a8a9009f7e.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe64c41bfccc5883f85639a8a9009f7e.txt new file mode 100644 index 0000000..ada0157 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/fe64c41bfccc5883f85639a8a9009f7e.txt @@ -0,0 +1,3 @@ +0 0.7819767441860465 0.4895833333333333 0.20348837209302326 0.15625 +0 0.3953488372093023 0.75 0.20348837209302326 0.15625 +0 0.8633720930232558 0.11197916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/feb192a0864b3d014f01adf5445cb6ae.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/feb192a0864b3d014f01adf5445cb6ae.txt new file mode 100644 index 0000000..33e4deb --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/feb192a0864b3d014f01adf5445cb6ae.txt @@ -0,0 +1,5 @@ +0 0.6656976744186046 0.13020833333333331 0.20348837209302326 0.15625 +0 0.7819767441860465 0.5182291666666666 0.20348837209302326 0.15625 +0 0.27906976744186046 0.3567708333333333 0.20348837209302326 0.15625 +0 0.16279069767441862 0.6067708333333333 0.20348837209302326 0.15625 +0 0.4563953488372093 0.6302083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ff7d2f8ab6790a3c3fa66b4eb6efa152.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ff7d2f8ab6790a3c3fa66b4eb6efa152.txt new file mode 100644 index 0000000..93c3e02 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ff7d2f8ab6790a3c3fa66b4eb6efa152.txt @@ -0,0 +1,5 @@ +0 0.4563953488372093 0.6614583333333333 0.20348837209302326 0.15625 +0 0.747093023255814 0.5833333333333333 0.20348837209302326 0.15625 +0 0.2180232558139535 0.33072916666666663 0.20348837209302326 0.15625 +0 0.6656976744186046 0.35416666666666663 0.20348837209302326 0.15625 +0 0.1511627906976744 0.6770833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ffb7b85dfd0c732e3055ea335bbaf870.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ffb7b85dfd0c732e3055ea335bbaf870.txt new file mode 100644 index 0000000..011b8a3 --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ffb7b85dfd0c732e3055ea335bbaf870.txt @@ -0,0 +1,5 @@ +0 0.5232558139534884 0.3802083333333333 0.20348837209302326 0.15625 +0 0.32558139534883723 0.7161458333333333 0.20348837209302326 0.15625 +0 0.8662790697674418 0.6276041666666666 0.20348837209302326 0.15625 +0 0.12790697674418605 0.3255208333333333 0.20348837209302326 0.15625 +0 0.8372093023255813 0.28385416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ffeb17610b24a45fbb9c9b687caa4d56.txt b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ffeb17610b24a45fbb9c9b687caa4d56.txt new file mode 100644 index 0000000..b90a1eb --- /dev/null +++ b/hanzi_detection/files/train/jiyan_train_imgs_txt_1K/ffeb17610b24a45fbb9c9b687caa4d56.txt @@ -0,0 +1,4 @@ +0 0.5436046511627907 0.5911458333333333 0.20348837209302326 0.15625 +0 0.6075581395348837 0.18229166666666666 0.20348837209302326 0.15625 +0 0.27906976744186046 0.6041666666666666 0.20348837209302326 0.15625 +0 0.19186046511627908 0.3020833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/009a7e97021d97dae6673b80f5562419.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/009a7e97021d97dae6673b80f5562419.txt new file mode 100644 index 0000000..2976697 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/009a7e97021d97dae6673b80f5562419.txt @@ -0,0 +1,4 @@ +0 0.4331395348837209 0.6640625 0.20348837209302326 0.15625 +0 0.6511627906976745 0.296875 0.20348837209302326 0.15625 +0 0.21511627906976744 0.36197916666666663 0.20348837209302326 0.15625 +0 0.8430232558139534 0.5807291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/00d85d76fffde2afbb5662ec32d4e6e3.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/00d85d76fffde2afbb5662ec32d4e6e3.txt new file mode 100644 index 0000000..fc7aabe --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/00d85d76fffde2afbb5662ec32d4e6e3.txt @@ -0,0 +1,4 @@ +0 0.2877906976744186 0.6328125 0.20348837209302326 0.15625 +0 0.31976744186046513 0.109375 0.20348837209302326 0.15625 +0 0.8401162790697674 0.37760416666666663 0.20348837209302326 0.15625 +0 0.4476744186046512 0.34375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0109defc816d4d3f9ebec520758101ed.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0109defc816d4d3f9ebec520758101ed.txt new file mode 100644 index 0000000..40b5e29 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0109defc816d4d3f9ebec520758101ed.txt @@ -0,0 +1,2 @@ +0 0.36627906976744184 0.16145833333333331 0.20348837209302326 0.15625 +0 0.36046511627906974 0.7786458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/013b4c04b2643efda758e27a68b47e8b.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/013b4c04b2643efda758e27a68b47e8b.txt new file mode 100644 index 0000000..97710a4 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/013b4c04b2643efda758e27a68b47e8b.txt @@ -0,0 +1,2 @@ +0 0.38372093023255816 0.6015625 0.20348837209302326 0.15625 +0 0.6773255813953488 0.6276041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0140db605724c01ba5142cbc218cfe25.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0140db605724c01ba5142cbc218cfe25.txt new file mode 100644 index 0000000..8697afe --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0140db605724c01ba5142cbc218cfe25.txt @@ -0,0 +1,3 @@ +0 0.2180232558139535 0.09375 0.20348837209302326 0.15625 +0 0.7936046511627907 0.2265625 0.20348837209302326 0.15625 +0 0.40988372093023256 0.7890625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/01c7ed9c137d1361d3cbc3425457119d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/01c7ed9c137d1361d3cbc3425457119d.txt new file mode 100644 index 0000000..c9cde7c --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/01c7ed9c137d1361d3cbc3425457119d.txt @@ -0,0 +1,4 @@ +0 0.28488372093023256 0.3567708333333333 0.20348837209302326 0.15625 +0 0.5319767441860465 0.6770833333333333 0.20348837209302326 0.15625 +0 0.8226744186046512 0.24479166666666666 0.20348837209302326 0.15625 +0 0.26744186046511625 0.6328125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/01e020b4086fd8ecb300e61150e66444.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/01e020b4086fd8ecb300e61150e66444.txt new file mode 100644 index 0000000..ad22658 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/01e020b4086fd8ecb300e61150e66444.txt @@ -0,0 +1,3 @@ +0 0.4418604651162791 0.5989583333333333 0.20348837209302326 0.15625 +0 0.3023255813953488 0.15625 0.20348837209302326 0.15625 +0 0.7383720930232558 0.38541666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/02f204657e32d9898613c0cb56cb5f19.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/02f204657e32d9898613c0cb56cb5f19.txt new file mode 100644 index 0000000..9125b07 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/02f204657e32d9898613c0cb56cb5f19.txt @@ -0,0 +1,4 @@ +0 0.8517441860465116 0.7161458333333333 0.20348837209302326 0.15625 +0 0.37790697674418605 0.5182291666666666 0.20348837209302326 0.15625 +0 0.8052325581395349 0.10416666666666666 0.20348837209302326 0.15625 +0 0.2703488372093023 0.19010416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0304f393f7eb69101ddab817824ce675.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0304f393f7eb69101ddab817824ce675.txt new file mode 100644 index 0000000..850f60b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0304f393f7eb69101ddab817824ce675.txt @@ -0,0 +1,4 @@ +0 0.8052325581395349 0.09375 0.20348837209302326 0.15625 +0 0.39244186046511625 0.5104166666666666 0.20348837209302326 0.15625 +0 0.2063953488372093 0.7708333333333333 0.20348837209302326 0.15625 +0 0.7994186046511628 0.35416666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/03256b23586b52f75fd89c48169c2580.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/03256b23586b52f75fd89c48169c2580.txt new file mode 100644 index 0000000..df7e601 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/03256b23586b52f75fd89c48169c2580.txt @@ -0,0 +1,4 @@ +0 0.5406976744186046 0.40885416666666663 0.20348837209302326 0.15625 +0 0.2616279069767442 0.6588541666666666 0.20348837209302326 0.15625 +0 0.5465116279069767 0.65625 0.20348837209302326 0.15625 +0 0.8546511627906976 0.7526041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/03e26365704345822c52eb7d4853e97f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/03e26365704345822c52eb7d4853e97f.txt new file mode 100644 index 0000000..9dbe5a2 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/03e26365704345822c52eb7d4853e97f.txt @@ -0,0 +1,3 @@ +0 0.2936046511627907 0.6614583333333333 0.20348837209302326 0.15625 +0 0.4563953488372093 0.1484375 0.20348837209302326 0.15625 +0 0.14244186046511628 0.33072916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/04f36d827bf62ba22575845abd2cd686.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/04f36d827bf62ba22575845abd2cd686.txt new file mode 100644 index 0000000..837e538 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/04f36d827bf62ba22575845abd2cd686.txt @@ -0,0 +1,3 @@ +0 0.49127906976744184 0.30729166666666663 0.20348837209302326 0.15625 +0 0.6308139534883721 0.5729166666666666 0.20348837209302326 0.15625 +0 0.25872093023255816 0.6354166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/04f8a5805d9b266c0d91dd062014dfaa.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/04f8a5805d9b266c0d91dd062014dfaa.txt new file mode 100644 index 0000000..ae7b3e9 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/04f8a5805d9b266c0d91dd062014dfaa.txt @@ -0,0 +1,3 @@ +0 0.2645348837209302 0.6953125 0.20348837209302326 0.15625 +0 0.6744186046511628 0.23697916666666666 0.20348837209302326 0.15625 +0 0.6598837209302325 0.5703125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0583ad55ecedb4ae888801613d288d0a.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0583ad55ecedb4ae888801613d288d0a.txt new file mode 100644 index 0000000..b3d5c27 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0583ad55ecedb4ae888801613d288d0a.txt @@ -0,0 +1,4 @@ +0 0.46511627906976744 0.7213541666666666 0.20348837209302326 0.15625 +0 0.8488372093023255 0.23958333333333331 0.20348837209302326 0.15625 +0 0.5406976744186046 0.4505208333333333 0.20348837209302326 0.15625 +0 0.2616279069767442 0.38541666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0593d6a8f09c1960815f4c3d68355d91.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0593d6a8f09c1960815f4c3d68355d91.txt new file mode 100644 index 0000000..9ec34d4 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0593d6a8f09c1960815f4c3d68355d91.txt @@ -0,0 +1,4 @@ +0 0.3633720930232558 0.703125 0.20348837209302326 0.15625 +0 0.747093023255814 0.47135416666666663 0.20348837209302326 0.15625 +0 0.4273255813953488 0.32291666666666663 0.20348837209302326 0.15625 +0 0.7994186046511628 0.1484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/05b4f87fc4740cb39374870227371ad2.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/05b4f87fc4740cb39374870227371ad2.txt new file mode 100644 index 0000000..863cc55 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/05b4f87fc4740cb39374870227371ad2.txt @@ -0,0 +1,5 @@ +0 0.19186046511627908 0.6041666666666666 0.20348837209302326 0.15625 +0 0.8372093023255813 0.421875 0.20348837209302326 0.15625 +0 0.3895348837209302 0.23697916666666666 0.20348837209302326 0.15625 +0 0.502906976744186 0.5755208333333333 0.20348837209302326 0.15625 +0 0.8197674418604651 0.1484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0757d81f2a087c727869681b09734a65.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0757d81f2a087c727869681b09734a65.txt new file mode 100644 index 0000000..dff8492 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0757d81f2a087c727869681b09734a65.txt @@ -0,0 +1,5 @@ +0 0.2180232558139535 0.6458333333333333 0.20348837209302326 0.15625 +0 0.7383720930232558 0.5208333333333333 0.20348837209302326 0.15625 +0 0.2238372093023256 0.12239583333333333 0.20348837209302326 0.15625 +0 0.7994186046511628 0.265625 0.20348837209302326 0.15625 +0 0.4563953488372093 0.4296875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/07e1e3b1060912328e34746e13ee19ae.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/07e1e3b1060912328e34746e13ee19ae.txt new file mode 100644 index 0000000..7f3536b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/07e1e3b1060912328e34746e13ee19ae.txt @@ -0,0 +1,4 @@ +0 0.8517441860465116 0.2864583333333333 0.20348837209302326 0.15625 +0 0.5145348837209303 0.5104166666666666 0.20348837209302326 0.15625 +0 0.18604651162790697 0.5130208333333333 0.20348837209302326 0.15625 +0 0.16569767441860464 0.09635416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/080ba59085ef88048ec8415d3eaf742a.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/080ba59085ef88048ec8415d3eaf742a.txt new file mode 100644 index 0000000..bda29e1 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/080ba59085ef88048ec8415d3eaf742a.txt @@ -0,0 +1,4 @@ +0 0.8197674418604651 0.23697916666666666 0.20348837209302326 0.15625 +0 0.6133720930232558 0.5494791666666666 0.20348837209302326 0.15625 +0 0.19767441860465115 0.5416666666666666 0.20348837209302326 0.15625 +0 0.5959302325581395 0.7838541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/08220ca8d594cf17da36c9d4b9c57195.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/08220ca8d594cf17da36c9d4b9c57195.txt new file mode 100644 index 0000000..7259126 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/08220ca8d594cf17da36c9d4b9c57195.txt @@ -0,0 +1,4 @@ +0 0.7441860465116279 0.28385416666666663 0.20348837209302326 0.15625 +0 0.20348837209302326 0.375 0.20348837209302326 0.15625 +0 0.42441860465116277 0.7760416666666666 0.20348837209302326 0.15625 +0 0.13662790697674418 0.09895833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/08b29d17e97ff3a1adb8787b7f969578.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/08b29d17e97ff3a1adb8787b7f969578.txt new file mode 100644 index 0000000..5b2b854 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/08b29d17e97ff3a1adb8787b7f969578.txt @@ -0,0 +1,4 @@ +0 0.46511627906976744 0.48697916666666663 0.20348837209302326 0.15625 +0 0.561046511627907 0.1015625 0.20348837209302326 0.15625 +0 0.8401162790697674 0.27604166666666663 0.20348837209302326 0.15625 +0 0.3081395348837209 0.7604166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/094846640c380b7e9c6ad297e4c2672a.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/094846640c380b7e9c6ad297e4c2672a.txt new file mode 100644 index 0000000..78184e0 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/094846640c380b7e9c6ad297e4c2672a.txt @@ -0,0 +1,4 @@ +0 0.5523255813953488 0.7447916666666666 0.20348837209302326 0.15625 +0 0.20930232558139533 0.1484375 0.20348837209302326 0.15625 +0 0.6511627906976745 0.16145833333333331 0.20348837209302326 0.15625 +0 0.18604651162790697 0.7890625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0a80281bab3eb2e167666b34d9167b4a.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0a80281bab3eb2e167666b34d9167b4a.txt new file mode 100644 index 0000000..57455d8 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0a80281bab3eb2e167666b34d9167b4a.txt @@ -0,0 +1,2 @@ +0 0.19186046511627908 0.2265625 0.20348837209302326 0.15625 +0 0.15988372093023256 0.6119791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0a9ae1aa5c8309bc02f169f6c7652822.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0a9ae1aa5c8309bc02f169f6c7652822.txt new file mode 100644 index 0000000..970c540 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0a9ae1aa5c8309bc02f169f6c7652822.txt @@ -0,0 +1,4 @@ +0 0.5959302325581395 0.3333333333333333 0.20348837209302326 0.15625 +0 0.10755813953488372 0.14322916666666666 0.20348837209302326 0.15625 +0 0.3226744186046512 0.5104166666666666 0.20348837209302326 0.15625 +0 0.8255813953488372 0.609375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0a9bff5ea913ac5e5d9206bc34dbf4a9.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0a9bff5ea913ac5e5d9206bc34dbf4a9.txt new file mode 100644 index 0000000..6cb16c0 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0a9bff5ea913ac5e5d9206bc34dbf4a9.txt @@ -0,0 +1,4 @@ +0 0.29069767441860467 0.6432291666666666 0.20348837209302326 0.15625 +0 0.15406976744186046 0.390625 0.20348837209302326 0.15625 +0 0.7383720930232558 0.7864583333333333 0.20348837209302326 0.15625 +0 0.45930232558139533 0.22135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0af1caa776bdf673e904082cc2f76edf.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0af1caa776bdf673e904082cc2f76edf.txt new file mode 100644 index 0000000..3d7904d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0af1caa776bdf673e904082cc2f76edf.txt @@ -0,0 +1,5 @@ +0 0.41860465116279066 0.2265625 0.20348837209302326 0.15625 +0 0.3488372093023256 0.6510416666666666 0.20348837209302326 0.15625 +0 0.6656976744186046 0.6432291666666666 0.20348837209302326 0.15625 +0 0.14534883720930233 0.33854166666666663 0.20348837209302326 0.15625 +0 0.8401162790697674 0.3880208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0b3240f52d3ec0f6246e64049a3c5444.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0b3240f52d3ec0f6246e64049a3c5444.txt new file mode 100644 index 0000000..bdad8df --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0b3240f52d3ec0f6246e64049a3c5444.txt @@ -0,0 +1,3 @@ +0 0.17151162790697674 0.4270833333333333 0.20348837209302326 0.15625 +0 0.6744186046511628 0.484375 0.20348837209302326 0.15625 +0 0.18895348837209303 0.6484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0be40c85ed6abac7dc600b8164aef739.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0be40c85ed6abac7dc600b8164aef739.txt new file mode 100644 index 0000000..e7379f2 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0be40c85ed6abac7dc600b8164aef739.txt @@ -0,0 +1,4 @@ +0 0.5843023255813954 0.3359375 0.20348837209302326 0.15625 +0 0.6511627906976745 0.6171875 0.20348837209302326 0.15625 +0 0.19186046511627908 0.390625 0.20348837209302326 0.15625 +0 0.311046511627907 0.11197916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0c0198c6bff66812263b06f14ef07b57.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0c0198c6bff66812263b06f14ef07b57.txt new file mode 100644 index 0000000..7b79d2f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0c0198c6bff66812263b06f14ef07b57.txt @@ -0,0 +1,4 @@ +0 0.5523255813953488 0.6796875 0.20348837209302326 0.15625 +0 0.4883720930232558 0.1171875 0.20348837209302326 0.15625 +0 0.18895348837209303 0.6302083333333333 0.20348837209302326 0.15625 +0 0.6017441860465116 0.4375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0c95c0d94a267ee41e471a9c73baff54.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0c95c0d94a267ee41e471a9c73baff54.txt new file mode 100644 index 0000000..9d7574d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0c95c0d94a267ee41e471a9c73baff54.txt @@ -0,0 +1,2 @@ +0 0.3808139534883721 0.6276041666666666 0.20348837209302326 0.15625 +0 0.688953488372093 0.5625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0cffb0162877dd7032367bfa0592c83e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0cffb0162877dd7032367bfa0592c83e.txt new file mode 100644 index 0000000..133da98 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0cffb0162877dd7032367bfa0592c83e.txt @@ -0,0 +1,4 @@ +0 0.22965116279069767 0.2630208333333333 0.20348837209302326 0.15625 +0 0.7180232558139534 0.6640625 0.20348837209302326 0.15625 +0 0.5290697674418604 0.3255208333333333 0.20348837209302326 0.15625 +0 0.13372093023255813 0.6171875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0dcbc4d598c387ca212731a3d17d4130.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0dcbc4d598c387ca212731a3d17d4130.txt new file mode 100644 index 0000000..c0c2f1d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0dcbc4d598c387ca212731a3d17d4130.txt @@ -0,0 +1,4 @@ +0 0.752906976744186 0.22916666666666666 0.20348837209302326 0.15625 +0 0.2441860465116279 0.37760416666666663 0.20348837209302326 0.15625 +0 0.47674418604651164 0.6796875 0.20348837209302326 0.15625 +0 0.8052325581395349 0.4583333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0de73b31c3c38c538bbc0d055991d1f3.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0de73b31c3c38c538bbc0d055991d1f3.txt new file mode 100644 index 0000000..b173358 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0de73b31c3c38c538bbc0d055991d1f3.txt @@ -0,0 +1,4 @@ +0 0.4622093023255814 0.6067708333333333 0.20348837209302326 0.15625 +0 0.7587209302325582 0.6458333333333333 0.20348837209302326 0.15625 +0 0.2063953488372093 0.359375 0.20348837209302326 0.15625 +0 0.6191860465116279 0.3203125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0e1ceb1fd5e14e57733032d9070e5ce1.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0e1ceb1fd5e14e57733032d9070e5ce1.txt new file mode 100644 index 0000000..a2d3a8c --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0e1ceb1fd5e14e57733032d9070e5ce1.txt @@ -0,0 +1,4 @@ +0 0.7412790697674418 0.14322916666666666 0.20348837209302326 0.15625 +0 0.2965116279069767 0.40104166666666663 0.20348837209302326 0.15625 +0 0.7906976744186046 0.6197916666666666 0.20348837209302326 0.15625 +0 0.3226744186046512 0.15885416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0eeafcecb06a43e3f8f9b5b38973992e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0eeafcecb06a43e3f8f9b5b38973992e.txt new file mode 100644 index 0000000..e02546f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0eeafcecb06a43e3f8f9b5b38973992e.txt @@ -0,0 +1,4 @@ +0 0.37209302325581395 0.1484375 0.20348837209302326 0.15625 +0 0.30523255813953487 0.4921875 0.20348837209302326 0.15625 +0 0.5290697674418604 0.7291666666666666 0.20348837209302326 0.15625 +0 0.8459302325581395 0.2942708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0ef2825d91407a5a7ce4904c3f626804.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0ef2825d91407a5a7ce4904c3f626804.txt new file mode 100644 index 0000000..5c678f9 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0ef2825d91407a5a7ce4904c3f626804.txt @@ -0,0 +1,3 @@ +0 0.6424418604651163 0.5364583333333333 0.20348837209302326 0.15625 +0 0.2761627906976744 0.31510416666666663 0.20348837209302326 0.15625 +0 0.3633720930232558 0.5729166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0f0438743b8c051059471f36ee9ceae6.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0f0438743b8c051059471f36ee9ceae6.txt new file mode 100644 index 0000000..f76465c --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/0f0438743b8c051059471f36ee9ceae6.txt @@ -0,0 +1,5 @@ +0 0.20348837209302326 0.171875 0.20348837209302326 0.15625 +0 0.6453488372093024 0.3203125 0.20348837209302326 0.15625 +0 0.7732558139534884 0.71875 0.20348837209302326 0.15625 +0 0.3546511627906977 0.390625 0.20348837209302326 0.15625 +0 0.38372093023255816 0.6354166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1043e72a8a78acad7fcd3464fd6c0edc.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1043e72a8a78acad7fcd3464fd6c0edc.txt new file mode 100644 index 0000000..5f0d05a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1043e72a8a78acad7fcd3464fd6c0edc.txt @@ -0,0 +1,4 @@ +0 0.7209302325581395 0.16666666666666666 0.20348837209302326 0.15625 +0 0.3953488372093023 0.19270833333333331 0.20348837209302326 0.15625 +0 0.5 0.6145833333333333 0.20348837209302326 0.15625 +0 0.13372093023255813 0.7291666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1057a07b83ba65107342a7356ee335ee.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1057a07b83ba65107342a7356ee335ee.txt new file mode 100644 index 0000000..1af5028 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1057a07b83ba65107342a7356ee335ee.txt @@ -0,0 +1,4 @@ +0 0.38372093023255816 0.6875 0.20348837209302326 0.15625 +0 0.36627906976744184 0.14583333333333331 0.20348837209302326 0.15625 +0 0.8488372093023255 0.18229166666666666 0.20348837209302326 0.15625 +0 0.7790697674418604 0.7682291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/106c76e80c18785eb6b754a42cc3676f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/106c76e80c18785eb6b754a42cc3676f.txt new file mode 100644 index 0000000..9269058 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/106c76e80c18785eb6b754a42cc3676f.txt @@ -0,0 +1,4 @@ +0 0.4127906976744186 0.6145833333333333 0.20348837209302326 0.15625 +0 0.7151162790697674 0.6432291666666666 0.20348837209302326 0.15625 +0 0.19767441860465115 0.21875 0.20348837209302326 0.15625 +0 0.686046511627907 0.21354166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/10ffa78896d3ab41de3dd9989818aa8f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/10ffa78896d3ab41de3dd9989818aa8f.txt new file mode 100644 index 0000000..d45b7f6 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/10ffa78896d3ab41de3dd9989818aa8f.txt @@ -0,0 +1,4 @@ +0 0.125 0.5520833333333333 0.20348837209302326 0.15625 +0 0.7267441860465116 0.12239583333333333 0.20348837209302326 0.15625 +0 0.7994186046511628 0.6614583333333333 0.20348837209302326 0.15625 +0 0.6802325581395349 0.3880208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/110ec995a4af1159da4ec4699016a91d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/110ec995a4af1159da4ec4699016a91d.txt new file mode 100644 index 0000000..7379d85 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/110ec995a4af1159da4ec4699016a91d.txt @@ -0,0 +1,4 @@ +0 0.688953488372093 0.7604166666666666 0.20348837209302326 0.15625 +0 0.36627906976744184 0.59375 0.20348837209302326 0.15625 +0 0.6395348837209303 0.15364583333333331 0.20348837209302326 0.15625 +0 0.3081395348837209 0.30729166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/11170c3c4b77a5b0ecccc3584722e9b3.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/11170c3c4b77a5b0ecccc3584722e9b3.txt new file mode 100644 index 0000000..6e05243 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/11170c3c4b77a5b0ecccc3584722e9b3.txt @@ -0,0 +1,3 @@ +0 0.627906976744186 0.734375 0.20348837209302326 0.15625 +0 0.3023255813953488 0.71875 0.20348837209302326 0.15625 +0 0.48546511627906974 0.5 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1129caac17eabf0f916b52f2b14b53c7.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1129caac17eabf0f916b52f2b14b53c7.txt new file mode 100644 index 0000000..3aa9277 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1129caac17eabf0f916b52f2b14b53c7.txt @@ -0,0 +1,5 @@ +0 0.7645348837209303 0.4192708333333333 0.20348837209302326 0.15625 +0 0.14534883720930233 0.703125 0.20348837209302326 0.15625 +0 0.6598837209302325 0.734375 0.20348837209302326 0.15625 +0 0.13953488372093023 0.16666666666666666 0.20348837209302326 0.15625 +0 0.22674418604651161 0.4375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/116b3097928f2d0b478adcaa88f52631.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/116b3097928f2d0b478adcaa88f52631.txt new file mode 100644 index 0000000..520098b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/116b3097928f2d0b478adcaa88f52631.txt @@ -0,0 +1,4 @@ +0 0.15406976744186046 0.2578125 0.20348837209302326 0.15625 +0 0.8604651162790697 0.3411458333333333 0.20348837209302326 0.15625 +0 0.5581395348837209 0.20052083333333331 0.20348837209302326 0.15625 +0 0.15406976744186046 0.5182291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/11ccd14f27f1fcae1803e6a1a787e7c7.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/11ccd14f27f1fcae1803e6a1a787e7c7.txt new file mode 100644 index 0000000..4193b7f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/11ccd14f27f1fcae1803e6a1a787e7c7.txt @@ -0,0 +1,5 @@ +0 0.75 0.609375 0.20348837209302326 0.15625 +0 0.3633720930232558 0.7916666666666666 0.20348837209302326 0.15625 +0 0.5232558139534884 0.375 0.20348837209302326 0.15625 +0 0.311046511627907 0.13541666666666666 0.20348837209302326 0.15625 +0 0.6482558139534884 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/11e1ca8c81c5e711df3b8ae8a5fc6bc3.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/11e1ca8c81c5e711df3b8ae8a5fc6bc3.txt new file mode 100644 index 0000000..35e9b25 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/11e1ca8c81c5e711df3b8ae8a5fc6bc3.txt @@ -0,0 +1,5 @@ +0 0.622093023255814 0.3203125 0.20348837209302326 0.15625 +0 0.5813953488372093 0.7864583333333333 0.20348837209302326 0.15625 +0 0.2936046511627907 0.21875 0.20348837209302326 0.15625 +0 0.5784883720930233 0.546875 0.20348837209302326 0.15625 +0 0.18604651162790697 0.6041666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/13652dcb732f6b94b12e2c54ce09046a.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/13652dcb732f6b94b12e2c54ce09046a.txt new file mode 100644 index 0000000..eea6be0 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/13652dcb732f6b94b12e2c54ce09046a.txt @@ -0,0 +1,2 @@ +0 0.4563953488372093 0.5 0.20348837209302326 0.15625 +0 0.33430232558139533 0.265625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/13b97793eec1064db7bf89855d732bab.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/13b97793eec1064db7bf89855d732bab.txt new file mode 100644 index 0000000..a366a76 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/13b97793eec1064db7bf89855d732bab.txt @@ -0,0 +1,5 @@ +0 0.36627906976744184 0.171875 0.20348837209302326 0.15625 +0 0.21511627906976744 0.7057291666666666 0.20348837209302326 0.15625 +0 0.2645348837209302 0.4661458333333333 0.20348837209302326 0.15625 +0 0.7180232558139534 0.4375 0.20348837209302326 0.15625 +0 0.7819767441860465 0.765625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1485fe3b91a98e108dac134fefc3ce1e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1485fe3b91a98e108dac134fefc3ce1e.txt new file mode 100644 index 0000000..fab7f5e --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1485fe3b91a98e108dac134fefc3ce1e.txt @@ -0,0 +1,4 @@ +0 0.7005813953488372 0.0859375 0.20348837209302326 0.15625 +0 0.18023255813953487 0.15104166666666666 0.20348837209302326 0.15625 +0 0.6104651162790697 0.40885416666666663 0.20348837209302326 0.15625 +0 0.18895348837209303 0.5078125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/155034b20152b8ee2b713117a6dc3fff.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/155034b20152b8ee2b713117a6dc3fff.txt new file mode 100644 index 0000000..42a85bf --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/155034b20152b8ee2b713117a6dc3fff.txt @@ -0,0 +1,4 @@ +0 0.14534883720930233 0.7864583333333333 0.20348837209302326 0.15625 +0 0.11918604651162791 0.12760416666666666 0.20348837209302326 0.15625 +0 0.7674418604651163 0.4661458333333333 0.20348837209302326 0.15625 +0 0.2005813953488372 0.5260416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/15701bebf45106e5aa9c44510d2690a0.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/15701bebf45106e5aa9c44510d2690a0.txt new file mode 100644 index 0000000..5697a97 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/15701bebf45106e5aa9c44510d2690a0.txt @@ -0,0 +1,5 @@ +0 0.8313953488372093 0.5755208333333333 0.20348837209302326 0.15625 +0 0.15988372093023256 0.6692708333333333 0.20348837209302326 0.15625 +0 0.44476744186046513 0.36979166666666663 0.20348837209302326 0.15625 +0 0.5261627906976745 0.703125 0.20348837209302326 0.15625 +0 0.17151162790697674 0.140625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/16be8ffe5ef1fc75e49f0b4c0dc7b333.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/16be8ffe5ef1fc75e49f0b4c0dc7b333.txt new file mode 100644 index 0000000..e4e4149 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/16be8ffe5ef1fc75e49f0b4c0dc7b333.txt @@ -0,0 +1,4 @@ +0 0.752906976744186 0.6067708333333333 0.20348837209302326 0.15625 +0 0.5813953488372093 0.2864583333333333 0.20348837209302326 0.15625 +0 0.4215116279069767 0.5338541666666666 0.20348837209302326 0.15625 +0 0.25 0.12760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/17af4c22377adbd21b47956d4dc6868a.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/17af4c22377adbd21b47956d4dc6868a.txt new file mode 100644 index 0000000..058e72e --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/17af4c22377adbd21b47956d4dc6868a.txt @@ -0,0 +1,4 @@ +0 0.38372093023255816 0.3828125 0.20348837209302326 0.15625 +0 0.5 0.11979166666666666 0.20348837209302326 0.15625 +0 0.7034883720930233 0.4192708333333333 0.20348837209302326 0.15625 +0 0.5988372093023255 0.6432291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/17f1fa3d015121a35a61284d754b908e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/17f1fa3d015121a35a61284d754b908e.txt new file mode 100644 index 0000000..0193995 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/17f1fa3d015121a35a61284d754b908e.txt @@ -0,0 +1,5 @@ +0 0.5465116279069767 0.47135416666666663 0.20348837209302326 0.15625 +0 0.6511627906976745 0.7630208333333333 0.20348837209302326 0.15625 +0 0.46511627906976744 0.14322916666666666 0.20348837209302326 0.15625 +0 0.14825581395348836 0.46875 0.20348837209302326 0.15625 +0 0.311046511627907 0.7265625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/192491b35377b986c5c8650b16eedf43.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/192491b35377b986c5c8650b16eedf43.txt new file mode 100644 index 0000000..4d81383 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/192491b35377b986c5c8650b16eedf43.txt @@ -0,0 +1,4 @@ +0 0.7906976744186046 0.3489583333333333 0.20348837209302326 0.15625 +0 0.22965116279069767 0.171875 0.20348837209302326 0.15625 +0 0.6627906976744186 0.7213541666666666 0.20348837209302326 0.15625 +0 0.7877906976744186 0.13020833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/19726a130475df782a8f306ecfb53baa.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/19726a130475df782a8f306ecfb53baa.txt new file mode 100644 index 0000000..f797a91 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/19726a130475df782a8f306ecfb53baa.txt @@ -0,0 +1,4 @@ +0 0.43023255813953487 0.7682291666666666 0.20348837209302326 0.15625 +0 0.8168604651162791 0.7265625 0.20348837209302326 0.15625 +0 0.8226744186046512 0.3333333333333333 0.20348837209302326 0.15625 +0 0.2005813953488372 0.09375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/19caba426117594cc403fb8ff86547b6.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/19caba426117594cc403fb8ff86547b6.txt new file mode 100644 index 0000000..aed06a1 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/19caba426117594cc403fb8ff86547b6.txt @@ -0,0 +1,2 @@ +0 0.34593023255813954 0.53125 0.20348837209302326 0.15625 +0 0.8255813953488372 0.4817708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1a62cf7a7b99e7cf533835e6d1188983.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1a62cf7a7b99e7cf533835e6d1188983.txt new file mode 100644 index 0000000..e29defb --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1a62cf7a7b99e7cf533835e6d1188983.txt @@ -0,0 +1,4 @@ +0 0.5 0.15885416666666666 0.20348837209302326 0.15625 +0 0.14244186046511628 0.7447916666666666 0.20348837209302326 0.15625 +0 0.27906976744186046 0.4895833333333333 0.20348837209302326 0.15625 +0 0.8343023255813954 0.5208333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1b4194d1d60be754fde2ac79965eed27.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1b4194d1d60be754fde2ac79965eed27.txt new file mode 100644 index 0000000..39b7e7a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1b4194d1d60be754fde2ac79965eed27.txt @@ -0,0 +1,4 @@ +0 0.4680232558139535 0.3177083333333333 0.20348837209302326 0.15625 +0 0.8401162790697674 0.10677083333333333 0.20348837209302326 0.15625 +0 0.7965116279069767 0.46354166666666663 0.20348837209302326 0.15625 +0 0.1511627906976744 0.12239583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1b42a7028ce6b0a4f197366472285b92.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1b42a7028ce6b0a4f197366472285b92.txt new file mode 100644 index 0000000..e926ee8 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1b42a7028ce6b0a4f197366472285b92.txt @@ -0,0 +1,4 @@ +0 0.6656976744186046 0.6901041666666666 0.20348837209302326 0.15625 +0 0.22674418604651161 0.1875 0.20348837209302326 0.15625 +0 0.7819767441860465 0.3203125 0.20348837209302326 0.15625 +0 0.27325581395348836 0.5572916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1b88bcdc113af9db3b348edd481787bf.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1b88bcdc113af9db3b348edd481787bf.txt new file mode 100644 index 0000000..ca5d664 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1b88bcdc113af9db3b348edd481787bf.txt @@ -0,0 +1,4 @@ +0 0.29941860465116277 0.2708333333333333 0.20348837209302326 0.15625 +0 0.43023255813953487 0.5364583333333333 0.20348837209302326 0.15625 +0 0.6366279069767442 0.29947916666666663 0.20348837209302326 0.15625 +0 0.8517441860465116 0.7708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1bab06733afd529dc3df158780fa2f9c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1bab06733afd529dc3df158780fa2f9c.txt new file mode 100644 index 0000000..cc1e74b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1bab06733afd529dc3df158780fa2f9c.txt @@ -0,0 +1,4 @@ +0 0.2761627906976744 0.4192708333333333 0.20348837209302326 0.15625 +0 0.2645348837209302 0.7291666666666666 0.20348837209302326 0.15625 +0 0.7325581395348837 0.16666666666666666 0.20348837209302326 0.15625 +0 0.2877906976744186 0.1328125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1c33794f2acbbb2bae3dc99af1493819.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1c33794f2acbbb2bae3dc99af1493819.txt new file mode 100644 index 0000000..55617f8 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1c33794f2acbbb2bae3dc99af1493819.txt @@ -0,0 +1,2 @@ +0 0.622093023255814 0.453125 0.20348837209302326 0.15625 +0 0.8575581395348837 0.203125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1c91cc97ad65688cf3ff8dbd3efa13b6.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1c91cc97ad65688cf3ff8dbd3efa13b6.txt new file mode 100644 index 0000000..3b78446 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1c91cc97ad65688cf3ff8dbd3efa13b6.txt @@ -0,0 +1,4 @@ +0 0.2441860465116279 0.15885416666666666 0.20348837209302326 0.15625 +0 0.5930232558139534 0.6901041666666666 0.20348837209302326 0.15625 +0 0.6686046511627907 0.22395833333333331 0.20348837209302326 0.15625 +0 0.15988372093023256 0.6744791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1d30e913f0d6c62c32a8f38c9c131399.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1d30e913f0d6c62c32a8f38c9c131399.txt new file mode 100644 index 0000000..d39d272 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1d30e913f0d6c62c32a8f38c9c131399.txt @@ -0,0 +1,5 @@ +0 0.4825581395348837 0.6484375 0.20348837209302326 0.15625 +0 0.877906976744186 0.1328125 0.20348837209302326 0.15625 +0 0.7848837209302325 0.6276041666666666 0.20348837209302326 0.15625 +0 0.18895348837209303 0.3125 0.20348837209302326 0.15625 +0 0.1744186046511628 0.59375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1d7ecb23dd0021c6d0afbddbf3d5c877.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1d7ecb23dd0021c6d0afbddbf3d5c877.txt new file mode 100644 index 0000000..9e6a7fa --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1d7ecb23dd0021c6d0afbddbf3d5c877.txt @@ -0,0 +1,4 @@ +0 0.5348837209302325 0.5859375 0.20348837209302326 0.15625 +0 0.5087209302325582 0.29947916666666663 0.20348837209302326 0.15625 +0 0.12790697674418605 0.3098958333333333 0.20348837209302326 0.15625 +0 0.8459302325581395 0.31510416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1dee58bfcfe52bca44b0520df4f94f3f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1dee58bfcfe52bca44b0520df4f94f3f.txt new file mode 100644 index 0000000..de393c1 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1dee58bfcfe52bca44b0520df4f94f3f.txt @@ -0,0 +1,5 @@ +0 0.2616279069767442 0.703125 0.20348837209302326 0.15625 +0 0.37209302325581395 0.16145833333333331 0.20348837209302326 0.15625 +0 0.811046511627907 0.2864583333333333 0.20348837209302326 0.15625 +0 0.7877906976744186 0.7083333333333333 0.20348837209302326 0.15625 +0 0.40988372093023256 0.45572916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1ea40a218bfff8bcc4e41a87fde1bba7.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1ea40a218bfff8bcc4e41a87fde1bba7.txt new file mode 100644 index 0000000..6657ffe --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1ea40a218bfff8bcc4e41a87fde1bba7.txt @@ -0,0 +1,4 @@ +0 0.22674418604651161 0.6197916666666666 0.20348837209302326 0.15625 +0 0.7034883720930233 0.5703125 0.20348837209302326 0.15625 +0 0.16569767441860464 0.22916666666666666 0.20348837209302326 0.15625 +0 0.46511627906976744 0.15364583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1f2f9f7d868a3703647f73a5ea8e57c8.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1f2f9f7d868a3703647f73a5ea8e57c8.txt new file mode 100644 index 0000000..c4c7c0a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1f2f9f7d868a3703647f73a5ea8e57c8.txt @@ -0,0 +1,4 @@ +0 0.17151162790697674 0.37760416666666663 0.20348837209302326 0.15625 +0 0.7877906976744186 0.5 0.20348837209302326 0.15625 +0 0.21511627906976744 0.6979166666666666 0.20348837209302326 0.15625 +0 0.7005813953488372 0.71875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1f375507c30e04a415fe1430a2e348d3.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1f375507c30e04a415fe1430a2e348d3.txt new file mode 100644 index 0000000..4ff13fd --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1f375507c30e04a415fe1430a2e348d3.txt @@ -0,0 +1,4 @@ +0 0.7441860465116279 0.5026041666666666 0.20348837209302326 0.15625 +0 0.6947674418604651 0.7760416666666666 0.20348837209302326 0.15625 +0 0.24127906976744184 0.5364583333333333 0.20348837209302326 0.15625 +0 0.6453488372093024 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1f8518a3b4eb317c3a094594994c918e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1f8518a3b4eb317c3a094594994c918e.txt new file mode 100644 index 0000000..5af0f17 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/1f8518a3b4eb317c3a094594994c918e.txt @@ -0,0 +1,4 @@ +0 0.5901162790697674 0.734375 0.20348837209302326 0.15625 +0 0.24127906976744184 0.24479166666666666 0.20348837209302326 0.15625 +0 0.5581395348837209 0.359375 0.20348837209302326 0.15625 +0 0.21511627906976744 0.6354166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/204262c758c2e399c7a7f668cb035c32.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/204262c758c2e399c7a7f668cb035c32.txt new file mode 100644 index 0000000..10fc522 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/204262c758c2e399c7a7f668cb035c32.txt @@ -0,0 +1,5 @@ +0 0.6569767441860465 0.6953125 0.20348837209302326 0.15625 +0 0.313953488372093 0.6197916666666666 0.20348837209302326 0.15625 +0 0.5087209302325582 0.15364583333333331 0.20348837209302326 0.15625 +0 0.8604651162790697 0.3567708333333333 0.20348837209302326 0.15625 +0 0.17151162790697674 0.28385416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/20bd48cc59aee5f57a37c3e19ccc5b81.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/20bd48cc59aee5f57a37c3e19ccc5b81.txt new file mode 100644 index 0000000..39ea8c5 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/20bd48cc59aee5f57a37c3e19ccc5b81.txt @@ -0,0 +1,5 @@ +0 0.2877906976744186 0.18489583333333331 0.20348837209302326 0.15625 +0 0.5116279069767442 0.703125 0.20348837209302326 0.15625 +0 0.8226744186046512 0.140625 0.20348837209302326 0.15625 +0 0.5406976744186046 0.5 0.20348837209302326 0.15625 +0 0.1511627906976744 0.4583333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2132427f941a8eaf80e639731b26f8cd.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2132427f941a8eaf80e639731b26f8cd.txt new file mode 100644 index 0000000..1364bf4 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2132427f941a8eaf80e639731b26f8cd.txt @@ -0,0 +1,4 @@ +0 0.622093023255814 0.5859375 0.20348837209302326 0.15625 +0 0.7848837209302325 0.1015625 0.20348837209302326 0.15625 +0 0.32848837209302323 0.2864583333333333 0.20348837209302326 0.15625 +0 0.22093023255813954 0.7760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/22107b73864219371dddf73da066786c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/22107b73864219371dddf73da066786c.txt new file mode 100644 index 0000000..896b768 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/22107b73864219371dddf73da066786c.txt @@ -0,0 +1,4 @@ +0 0.16279069767441862 0.171875 0.20348837209302326 0.15625 +0 0.47674418604651164 0.22395833333333331 0.20348837209302326 0.15625 +0 0.5436046511627907 0.6484375 0.20348837209302326 0.15625 +0 0.7645348837209303 0.359375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/222b581b22a76b737eb4070d7bd7cfca.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/222b581b22a76b737eb4070d7bd7cfca.txt new file mode 100644 index 0000000..be47741 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/222b581b22a76b737eb4070d7bd7cfca.txt @@ -0,0 +1,4 @@ +0 0.7180232558139534 0.4270833333333333 0.20348837209302326 0.15625 +0 0.31976744186046513 0.515625 0.20348837209302326 0.15625 +0 0.3081395348837209 0.2552083333333333 0.20348837209302326 0.15625 +0 0.8372093023255813 0.125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/23532d65439430cbd36a4951c0c7af05.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/23532d65439430cbd36a4951c0c7af05.txt new file mode 100644 index 0000000..c964bde --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/23532d65439430cbd36a4951c0c7af05.txt @@ -0,0 +1,4 @@ +0 0.747093023255814 0.34375 0.20348837209302326 0.15625 +0 0.4215116279069767 0.31510416666666663 0.20348837209302326 0.15625 +0 0.5959302325581395 0.7057291666666666 0.20348837209302326 0.15625 +0 0.10174418604651163 0.6276041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/25863f08d537a978fca92941aa8542a3.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/25863f08d537a978fca92941aa8542a3.txt new file mode 100644 index 0000000..d5ad733 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/25863f08d537a978fca92941aa8542a3.txt @@ -0,0 +1,4 @@ +0 0.5348837209302325 0.75 0.20348837209302326 0.15625 +0 0.6366279069767442 0.19791666666666666 0.20348837209302326 0.15625 +0 0.16569767441860464 0.7057291666666666 0.20348837209302326 0.15625 +0 0.3023255813953488 0.3046875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/26e77bc14f38e95bd86bee67a44da43e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/26e77bc14f38e95bd86bee67a44da43e.txt new file mode 100644 index 0000000..f764843 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/26e77bc14f38e95bd86bee67a44da43e.txt @@ -0,0 +1 @@ +0 0.2645348837209302 0.2708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2761ffab840875beea0673738df78bf6.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2761ffab840875beea0673738df78bf6.txt new file mode 100644 index 0000000..1cc0d5f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2761ffab840875beea0673738df78bf6.txt @@ -0,0 +1,4 @@ +0 0.6046511627906976 0.5651041666666666 0.20348837209302326 0.15625 +0 0.5726744186046512 0.12239583333333333 0.20348837209302326 0.15625 +0 0.13662790697674418 0.6328125 0.20348837209302326 0.15625 +0 0.23546511627906977 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/27b663a9111e3ab540465370e6ec1e6f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/27b663a9111e3ab540465370e6ec1e6f.txt new file mode 100644 index 0000000..2ab6a5a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/27b663a9111e3ab540465370e6ec1e6f.txt @@ -0,0 +1,3 @@ +0 0.5261627906976745 0.59375 0.20348837209302326 0.15625 +0 0.24709302325581395 0.3046875 0.20348837209302326 0.15625 +0 0.5319767441860465 0.140625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/27edc29c28067e0c199215b30c046517.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/27edc29c28067e0c199215b30c046517.txt new file mode 100644 index 0000000..d7c1cb6 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/27edc29c28067e0c199215b30c046517.txt @@ -0,0 +1,4 @@ +0 0.8575581395348837 0.6692708333333333 0.20348837209302326 0.15625 +0 0.14244186046511628 0.14583333333333331 0.20348837209302326 0.15625 +0 0.4883720930232558 0.3567708333333333 0.20348837209302326 0.15625 +0 0.8255813953488372 0.28385416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/29a82a5f398c44c717e5963b8aa18ce0.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/29a82a5f398c44c717e5963b8aa18ce0.txt new file mode 100644 index 0000000..ed4b1c5 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/29a82a5f398c44c717e5963b8aa18ce0.txt @@ -0,0 +1,3 @@ +0 0.8546511627906976 0.12239583333333333 0.20348837209302326 0.15625 +0 0.5377906976744186 0.43229166666666663 0.20348837209302326 0.15625 +0 0.5406976744186046 0.7265625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2a27d33108c135b78005316e25b7344b.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2a27d33108c135b78005316e25b7344b.txt new file mode 100644 index 0000000..f76252e --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2a27d33108c135b78005316e25b7344b.txt @@ -0,0 +1,3 @@ +0 0.7209302325581395 0.18229166666666666 0.20348837209302326 0.15625 +0 0.622093023255814 0.4427083333333333 0.20348837209302326 0.15625 +0 0.2441860465116279 0.7838541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2a37dff08e425c14579ca4ecb232122b.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2a37dff08e425c14579ca4ecb232122b.txt new file mode 100644 index 0000000..38e92bd --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2a37dff08e425c14579ca4ecb232122b.txt @@ -0,0 +1,5 @@ +0 0.561046511627907 0.3333333333333333 0.20348837209302326 0.15625 +0 0.5813953488372093 0.10677083333333333 0.20348837209302326 0.15625 +0 0.7703488372093024 0.7005208333333333 0.20348837209302326 0.15625 +0 0.16569767441860464 0.5755208333333333 0.20348837209302326 0.15625 +0 0.23255813953488372 0.34375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2bc4c2dc4a0f69a21ff2381dd4e4dee3.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2bc4c2dc4a0f69a21ff2381dd4e4dee3.txt new file mode 100644 index 0000000..75f0764 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2bc4c2dc4a0f69a21ff2381dd4e4dee3.txt @@ -0,0 +1,5 @@ +0 0.3546511627906977 0.6588541666666666 0.20348837209302326 0.15625 +0 0.3546511627906977 0.4036458333333333 0.20348837209302326 0.15625 +0 0.8023255813953488 0.5338541666666666 0.20348837209302326 0.15625 +0 0.4011627906976744 0.15364583333333331 0.20348837209302326 0.15625 +0 0.8488372093023255 0.22916666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2cbf8c9e27871c5350b480fdc251e005.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2cbf8c9e27871c5350b480fdc251e005.txt new file mode 100644 index 0000000..1072295 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2cbf8c9e27871c5350b480fdc251e005.txt @@ -0,0 +1,3 @@ +0 0.5784883720930233 0.578125 0.20348837209302326 0.15625 +0 0.15988372093023256 0.7135416666666666 0.20348837209302326 0.15625 +0 0.8401162790697674 0.25260416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2cd54245fbc81730d1697b2224ba4795.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2cd54245fbc81730d1697b2224ba4795.txt new file mode 100644 index 0000000..6a44967 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2cd54245fbc81730d1697b2224ba4795.txt @@ -0,0 +1,5 @@ +0 0.19767441860465115 0.7447916666666666 0.20348837209302326 0.15625 +0 0.7819767441860465 0.2864583333333333 0.20348837209302326 0.15625 +0 0.40988372093023256 0.4765625 0.20348837209302326 0.15625 +0 0.27906976744186046 0.18489583333333331 0.20348837209302326 0.15625 +0 0.7587209302325582 0.7239583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2da14cd8670dac91bb5671c7bf40b327.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2da14cd8670dac91bb5671c7bf40b327.txt new file mode 100644 index 0000000..118e4f8 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2da14cd8670dac91bb5671c7bf40b327.txt @@ -0,0 +1,4 @@ +0 0.40406976744186046 0.5729166666666666 0.20348837209302326 0.15625 +0 0.7063953488372093 0.5755208333333333 0.20348837209302326 0.15625 +0 0.6598837209302325 0.29947916666666663 0.20348837209302326 0.15625 +0 0.34011627906976744 0.2942708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2e32a0ee0daab5ee5194a2f8b5e0f586.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2e32a0ee0daab5ee5194a2f8b5e0f586.txt new file mode 100644 index 0000000..3ac9c39 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2e32a0ee0daab5ee5194a2f8b5e0f586.txt @@ -0,0 +1,3 @@ +0 0.2616279069767442 0.5104166666666666 0.20348837209302326 0.15625 +0 0.4011627906976744 0.0859375 0.20348837209302326 0.15625 +0 0.3226744186046512 0.7604166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2e677532d5e6379d7bb9227c73c10208.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2e677532d5e6379d7bb9227c73c10208.txt new file mode 100644 index 0000000..734eb58 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2e677532d5e6379d7bb9227c73c10208.txt @@ -0,0 +1,4 @@ +0 0.7325581395348837 0.17447916666666666 0.20348837209302326 0.15625 +0 0.4796511627906977 0.7760416666666666 0.20348837209302326 0.15625 +0 0.7005813953488372 0.5234375 0.20348837209302326 0.15625 +0 0.13662790697674418 0.23958333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2ee752feb40dded57dfb417a49803f5e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2ee752feb40dded57dfb417a49803f5e.txt new file mode 100644 index 0000000..5e256fb --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2ee752feb40dded57dfb417a49803f5e.txt @@ -0,0 +1,4 @@ +0 0.43023255813953487 0.6640625 0.20348837209302326 0.15625 +0 0.16569767441860464 0.3645833333333333 0.20348837209302326 0.15625 +0 0.12790697674418605 0.7682291666666666 0.20348837209302326 0.15625 +0 0.6656976744186046 0.28385416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2f63ed89bae4f75af1bf58e85899a462.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2f63ed89bae4f75af1bf58e85899a462.txt new file mode 100644 index 0000000..d3ee446 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2f63ed89bae4f75af1bf58e85899a462.txt @@ -0,0 +1,4 @@ +0 0.6831395348837209 0.234375 0.20348837209302326 0.15625 +0 0.7209302325581395 0.6927083333333333 0.20348837209302326 0.15625 +0 0.18313953488372092 0.09114583333333333 0.20348837209302326 0.15625 +0 0.2180232558139535 0.4036458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2fc6afecda457b5e083b8395cf7e37a4.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2fc6afecda457b5e083b8395cf7e37a4.txt new file mode 100644 index 0000000..4419ece --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/2fc6afecda457b5e083b8395cf7e37a4.txt @@ -0,0 +1,4 @@ +0 0.21511627906976744 0.7760416666666666 0.20348837209302326 0.15625 +0 0.5494186046511628 0.14322916666666666 0.20348837209302326 0.15625 +0 0.5552325581395349 0.44010416666666663 0.20348837209302326 0.15625 +0 0.15988372093023256 0.4921875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3036daac7bf852527515fd961c83485a.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3036daac7bf852527515fd961c83485a.txt new file mode 100644 index 0000000..33b20a8 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3036daac7bf852527515fd961c83485a.txt @@ -0,0 +1,4 @@ +0 0.46511627906976744 0.609375 0.20348837209302326 0.15625 +0 0.622093023255814 0.3125 0.20348837209302326 0.15625 +0 0.7674418604651163 0.5963541666666666 0.20348837209302326 0.15625 +0 0.13662790697674418 0.4505208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/30550bcc40a53e823571bf5843f595f7.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/30550bcc40a53e823571bf5843f595f7.txt new file mode 100644 index 0000000..cc399d9 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/30550bcc40a53e823571bf5843f595f7.txt @@ -0,0 +1,4 @@ +0 0.18895348837209303 0.47135416666666663 0.20348837209302326 0.15625 +0 0.6511627906976745 0.46875 0.20348837209302326 0.15625 +0 0.36046511627906974 0.7213541666666666 0.20348837209302326 0.15625 +0 0.16279069767441862 0.1875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3159c888bb0b70dd182433f7b1d04909.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3159c888bb0b70dd182433f7b1d04909.txt new file mode 100644 index 0000000..e643927 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3159c888bb0b70dd182433f7b1d04909.txt @@ -0,0 +1,4 @@ +0 0.3430232558139535 0.11197916666666666 0.20348837209302326 0.15625 +0 0.36046511627906974 0.5729166666666666 0.20348837209302326 0.15625 +0 0.7587209302325582 0.11197916666666666 0.20348837209302326 0.15625 +0 0.12209302325581395 0.3411458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3186f4ce35b012e3b3fe8b8db2671c83.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3186f4ce35b012e3b3fe8b8db2671c83.txt new file mode 100644 index 0000000..d401848 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3186f4ce35b012e3b3fe8b8db2671c83.txt @@ -0,0 +1,3 @@ +0 0.13662790697674418 0.3489583333333333 0.20348837209302326 0.15625 +0 0.4331395348837209 0.46354166666666663 0.20348837209302326 0.15625 +0 0.6395348837209303 0.1015625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/318d149ff875c24ba2d4066346d1e9d6.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/318d149ff875c24ba2d4066346d1e9d6.txt new file mode 100644 index 0000000..cd9be71 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/318d149ff875c24ba2d4066346d1e9d6.txt @@ -0,0 +1,2 @@ +0 0.13953488372093023 0.37760416666666663 0.20348837209302326 0.15625 +0 0.5523255813953488 0.09114583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/31b28e3fd6a231d6382367606843f088.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/31b28e3fd6a231d6382367606843f088.txt new file mode 100644 index 0000000..3780cc9 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/31b28e3fd6a231d6382367606843f088.txt @@ -0,0 +1,4 @@ +0 0.11918604651162791 0.359375 0.20348837209302326 0.15625 +0 0.4622093023255814 0.359375 0.20348837209302326 0.15625 +0 0.17151162790697674 0.7760416666666666 0.20348837209302326 0.15625 +0 0.6162790697674418 0.6484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/31ccc43eebe23e65879dea87292277ff.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/31ccc43eebe23e65879dea87292277ff.txt new file mode 100644 index 0000000..265d474 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/31ccc43eebe23e65879dea87292277ff.txt @@ -0,0 +1,4 @@ +0 0.5319767441860465 0.7291666666666666 0.20348837209302326 0.15625 +0 0.24709302325581395 0.6223958333333333 0.20348837209302326 0.15625 +0 0.10755813953488372 0.2864583333333333 0.20348837209302326 0.15625 +0 0.4796511627906977 0.2708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/320727f387d0c70e30d0ef6650212794.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/320727f387d0c70e30d0ef6650212794.txt new file mode 100644 index 0000000..26250ef --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/320727f387d0c70e30d0ef6650212794.txt @@ -0,0 +1,4 @@ +0 0.4680232558139535 0.3177083333333333 0.20348837209302326 0.15625 +0 0.5203488372093024 0.6380208333333333 0.20348837209302326 0.15625 +0 0.18895348837209303 0.10416666666666666 0.20348837209302326 0.15625 +0 0.7819767441860465 0.24479166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/326dc5fc5b0a058a96c3690141849192.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/326dc5fc5b0a058a96c3690141849192.txt new file mode 100644 index 0000000..ac91caf --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/326dc5fc5b0a058a96c3690141849192.txt @@ -0,0 +1,3 @@ +0 0.3953488372093023 0.4036458333333333 0.20348837209302326 0.15625 +0 0.7441860465116279 0.22916666666666666 0.20348837209302326 0.15625 +0 0.5726744186046512 0.6640625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3332c0fc81c718ed96a430da7b4dae82.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3332c0fc81c718ed96a430da7b4dae82.txt new file mode 100644 index 0000000..a230552 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3332c0fc81c718ed96a430da7b4dae82.txt @@ -0,0 +1,3 @@ +0 0.13953488372093023 0.2734375 0.20348837209302326 0.15625 +0 0.24127906976744184 0.6171875 0.20348837209302326 0.15625 +0 0.5 0.34635416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/33c311c9a9458c5791bc58d1462bdc93.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/33c311c9a9458c5791bc58d1462bdc93.txt new file mode 100644 index 0000000..1841529 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/33c311c9a9458c5791bc58d1462bdc93.txt @@ -0,0 +1,4 @@ +0 0.8343023255813954 0.13802083333333331 0.20348837209302326 0.15625 +0 0.33430232558139533 0.33854166666666663 0.20348837209302326 0.15625 +0 0.3023255813953488 0.7604166666666666 0.20348837209302326 0.15625 +0 0.686046511627907 0.421875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/33e44da886008ccf1812715a8b3ae157.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/33e44da886008ccf1812715a8b3ae157.txt new file mode 100644 index 0000000..e03e3a4 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/33e44da886008ccf1812715a8b3ae157.txt @@ -0,0 +1,5 @@ +0 0.2238372093023256 0.44791666666666663 0.20348837209302326 0.15625 +0 0.5058139534883721 0.2109375 0.20348837209302326 0.15625 +0 0.6482558139534884 0.5026041666666666 0.20348837209302326 0.15625 +0 0.8226744186046512 0.265625 0.20348837209302326 0.15625 +0 0.15988372093023256 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/346710c046ca0d5e1dee497c8b08997d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/346710c046ca0d5e1dee497c8b08997d.txt new file mode 100644 index 0000000..3c2d3f4 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/346710c046ca0d5e1dee497c8b08997d.txt @@ -0,0 +1,4 @@ +0 0.5465116279069767 0.30729166666666663 0.20348837209302326 0.15625 +0 0.37790697674418605 0.6432291666666666 0.20348837209302326 0.15625 +0 0.8023255813953488 0.6666666666666666 0.20348837209302326 0.15625 +0 0.18895348837209303 0.27604166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/34df9e42fb083ffc5411e73eba66d43a.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/34df9e42fb083ffc5411e73eba66d43a.txt new file mode 100644 index 0000000..b4fbe08 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/34df9e42fb083ffc5411e73eba66d43a.txt @@ -0,0 +1,3 @@ +0 0.6627906976744186 0.5 0.20348837209302326 0.15625 +0 0.625 0.7578125 0.20348837209302326 0.15625 +0 0.22674418604651161 0.265625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/362fcc1a70d9c315b94c6a3317111b25.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/362fcc1a70d9c315b94c6a3317111b25.txt new file mode 100644 index 0000000..2354989 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/362fcc1a70d9c315b94c6a3317111b25.txt @@ -0,0 +1,3 @@ +0 0.622093023255814 0.44791666666666663 0.20348837209302326 0.15625 +0 0.4738372093023256 0.15885416666666666 0.20348837209302326 0.15625 +0 0.7122093023255814 0.6744791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/36bf6e670468410177de50c83fac4b0c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/36bf6e670468410177de50c83fac4b0c.txt new file mode 100644 index 0000000..820b940 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/36bf6e670468410177de50c83fac4b0c.txt @@ -0,0 +1,5 @@ +0 0.1947674418604651 0.71875 0.20348837209302326 0.15625 +0 0.6918604651162791 0.33072916666666663 0.20348837209302326 0.15625 +0 0.8546511627906976 0.5703125 0.20348837209302326 0.15625 +0 0.3808139534883721 0.3333333333333333 0.20348837209302326 0.15625 +0 0.1686046511627907 0.11197916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/36bfb1e4d19d7a1325a7d1cd647175a1.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/36bfb1e4d19d7a1325a7d1cd647175a1.txt new file mode 100644 index 0000000..d6373fe --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/36bfb1e4d19d7a1325a7d1cd647175a1.txt @@ -0,0 +1,4 @@ +0 0.5930232558139534 0.32291666666666663 0.20348837209302326 0.15625 +0 0.5901162790697674 0.5833333333333333 0.20348837209302326 0.15625 +0 0.19767441860465115 0.1015625 0.20348837209302326 0.15625 +0 0.1569767441860465 0.7005208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/36eb0c3c00ce21d912db08b872ecfe85.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/36eb0c3c00ce21d912db08b872ecfe85.txt new file mode 100644 index 0000000..9e6ba3d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/36eb0c3c00ce21d912db08b872ecfe85.txt @@ -0,0 +1,4 @@ +0 0.3081395348837209 0.2552083333333333 0.20348837209302326 0.15625 +0 0.563953488372093 0.5104166666666666 0.20348837209302326 0.15625 +0 0.6802325581395349 0.7395833333333333 0.20348837209302326 0.15625 +0 0.1686046511627907 0.7161458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/37431dd17168d3278269a68997c1e2a9.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/37431dd17168d3278269a68997c1e2a9.txt new file mode 100644 index 0000000..bc12503 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/37431dd17168d3278269a68997c1e2a9.txt @@ -0,0 +1,2 @@ +0 0.7063953488372093 0.484375 0.20348837209302326 0.15625 +0 0.3488372093023256 0.265625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/37481c1fd1e3f459ff50847dbbeb5a93.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/37481c1fd1e3f459ff50847dbbeb5a93.txt new file mode 100644 index 0000000..dd6afee --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/37481c1fd1e3f459ff50847dbbeb5a93.txt @@ -0,0 +1,4 @@ +0 0.5203488372093024 0.45572916666666663 0.20348837209302326 0.15625 +0 0.7906976744186046 0.7760416666666666 0.20348837209302326 0.15625 +0 0.18313953488372092 0.7604166666666666 0.20348837209302326 0.15625 +0 0.49127906976744184 0.7317708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3795bbc85df7841dc04e3e14edfd21f4.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3795bbc85df7841dc04e3e14edfd21f4.txt new file mode 100644 index 0000000..ce301cf --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3795bbc85df7841dc04e3e14edfd21f4.txt @@ -0,0 +1,4 @@ +0 0.40988372093023256 0.5494791666666666 0.20348837209302326 0.15625 +0 0.7848837209302325 0.7838541666666666 0.20348837209302326 0.15625 +0 0.8313953488372093 0.4895833333333333 0.20348837209302326 0.15625 +0 0.18604651162790697 0.14583333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/37ed57c07862e4dc18c7ef83e5a3ec3d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/37ed57c07862e4dc18c7ef83e5a3ec3d.txt new file mode 100644 index 0000000..12c7157 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/37ed57c07862e4dc18c7ef83e5a3ec3d.txt @@ -0,0 +1,4 @@ +0 0.5406976744186046 0.7916666666666666 0.20348837209302326 0.15625 +0 0.813953488372093 0.6171875 0.20348837209302326 0.15625 +0 0.5 0.22135416666666666 0.20348837209302326 0.15625 +0 0.34011627906976744 0.5208333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/38aa35b99729041734924db15ae6523b.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/38aa35b99729041734924db15ae6523b.txt new file mode 100644 index 0000000..7d5de61 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/38aa35b99729041734924db15ae6523b.txt @@ -0,0 +1,4 @@ +0 0.22093023255813954 0.13541666666666666 0.20348837209302326 0.15625 +0 0.8226744186046512 0.3333333333333333 0.20348837209302326 0.15625 +0 0.5 0.4609375 0.20348837209302326 0.15625 +0 0.5784883720930233 0.1015625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/398550e0c7483b15fc97f5e17b33fe94.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/398550e0c7483b15fc97f5e17b33fe94.txt new file mode 100644 index 0000000..7fec5e5 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/398550e0c7483b15fc97f5e17b33fe94.txt @@ -0,0 +1,5 @@ +0 0.44476744186046513 0.4973958333333333 0.20348837209302326 0.15625 +0 0.4563953488372093 0.7317708333333333 0.20348837209302326 0.15625 +0 0.12209302325581395 0.17447916666666666 0.20348837209302326 0.15625 +0 0.14534883720930233 0.7161458333333333 0.20348837209302326 0.15625 +0 0.6715116279069767 0.10677083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/39ef765bae2d2f3118f369de7317fb76.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/39ef765bae2d2f3118f369de7317fb76.txt new file mode 100644 index 0000000..b369302 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/39ef765bae2d2f3118f369de7317fb76.txt @@ -0,0 +1,4 @@ +0 0.5784883720930233 0.15104166666666666 0.20348837209302326 0.15625 +0 0.6482558139534884 0.5859375 0.20348837209302326 0.15625 +0 0.14244186046511628 0.2890625 0.20348837209302326 0.15625 +0 0.3546511627906977 0.6614583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3ac0f390b8a881b74e55f2af3f29250a.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3ac0f390b8a881b74e55f2af3f29250a.txt new file mode 100644 index 0000000..2e94a13 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3ac0f390b8a881b74e55f2af3f29250a.txt @@ -0,0 +1,5 @@ +0 0.6482558139534884 0.453125 0.20348837209302326 0.15625 +0 0.27906976744186046 0.26822916666666663 0.20348837209302326 0.15625 +0 0.35174418604651164 0.6927083333333333 0.20348837209302326 0.15625 +0 0.7994186046511628 0.1640625 0.20348837209302326 0.15625 +0 0.6656976744186046 0.7708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3b134cad77abf272edd7323c9be89787.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3b134cad77abf272edd7323c9be89787.txt new file mode 100644 index 0000000..6ecb9c4 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3b134cad77abf272edd7323c9be89787.txt @@ -0,0 +1,4 @@ +0 0.31976744186046513 0.609375 0.20348837209302326 0.15625 +0 0.6191860465116279 0.515625 0.20348837209302326 0.15625 +0 0.4215116279069767 0.13020833333333331 0.20348837209302326 0.15625 +0 0.7936046511627907 0.15625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3be2b5d228ad9dcba2ad0a01d24ea9af.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3be2b5d228ad9dcba2ad0a01d24ea9af.txt new file mode 100644 index 0000000..a98050d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3be2b5d228ad9dcba2ad0a01d24ea9af.txt @@ -0,0 +1,4 @@ +0 0.6366279069767442 0.33072916666666663 0.20348837209302326 0.15625 +0 0.5436046511627907 0.6015625 0.20348837209302326 0.15625 +0 0.15988372093023256 0.33072916666666663 0.20348837209302326 0.15625 +0 0.16279069767441862 0.5885416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3c34b3c035744a0f64d8d979ca867511.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3c34b3c035744a0f64d8d979ca867511.txt new file mode 100644 index 0000000..9b45a95 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3c34b3c035744a0f64d8d979ca867511.txt @@ -0,0 +1,4 @@ +0 0.5813953488372093 0.5286458333333333 0.20348837209302326 0.15625 +0 0.25290697674418605 0.40885416666666663 0.20348837209302326 0.15625 +0 0.6715116279069767 0.7786458333333333 0.20348837209302326 0.15625 +0 0.23837209302325582 0.7135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3c6aaefa8a430d08eb1de57e64b1e32d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3c6aaefa8a430d08eb1de57e64b1e32d.txt new file mode 100644 index 0000000..de0addd --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3c6aaefa8a430d08eb1de57e64b1e32d.txt @@ -0,0 +1,4 @@ +0 0.21220930232558138 0.1484375 0.20348837209302326 0.15625 +0 0.14534883720930233 0.3984375 0.20348837209302326 0.15625 +0 0.6598837209302325 0.6171875 0.20348837209302326 0.15625 +0 0.6686046511627907 0.3958333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3c7d7f3fd805b7c10784a2252f0e62f5.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3c7d7f3fd805b7c10784a2252f0e62f5.txt new file mode 100644 index 0000000..82a61d3 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3c7d7f3fd805b7c10784a2252f0e62f5.txt @@ -0,0 +1,4 @@ +0 0.18604651162790697 0.1015625 0.20348837209302326 0.15625 +0 0.7906976744186046 0.5182291666666666 0.20348837209302326 0.15625 +0 0.2441860465116279 0.5208333333333333 0.20348837209302326 0.15625 +0 0.12790697674418605 0.7760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3d22bd6dcce2054b85e54e23df329bea.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3d22bd6dcce2054b85e54e23df329bea.txt new file mode 100644 index 0000000..0552e6d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3d22bd6dcce2054b85e54e23df329bea.txt @@ -0,0 +1,3 @@ +0 0.14534883720930233 0.23958333333333331 0.20348837209302326 0.15625 +0 0.5872093023255814 0.4348958333333333 0.20348837209302326 0.15625 +0 0.627906976744186 0.12239583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3f23c2473ab75911807d6e2a69933e0d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3f23c2473ab75911807d6e2a69933e0d.txt new file mode 100644 index 0000000..76bd160 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3f23c2473ab75911807d6e2a69933e0d.txt @@ -0,0 +1,4 @@ +0 0.5552325581395349 0.41666666666666663 0.20348837209302326 0.15625 +0 0.7936046511627907 0.7552083333333333 0.20348837209302326 0.15625 +0 0.2063953488372093 0.3984375 0.20348837209302326 0.15625 +0 0.6976744186046512 0.16927083333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3f433eb056df56a8d69c6a1ea563e74c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3f433eb056df56a8d69c6a1ea563e74c.txt new file mode 100644 index 0000000..ad34f7b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3f433eb056df56a8d69c6a1ea563e74c.txt @@ -0,0 +1,4 @@ +0 0.35174418604651164 0.18489583333333331 0.20348837209302326 0.15625 +0 0.7819767441860465 0.5182291666666666 0.20348837209302326 0.15625 +0 0.3168604651162791 0.5390625 0.20348837209302326 0.15625 +0 0.7325581395348837 0.203125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3f78208475b9dc4d9a8fc8d011888f02.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3f78208475b9dc4d9a8fc8d011888f02.txt new file mode 100644 index 0000000..f03e20c --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/3f78208475b9dc4d9a8fc8d011888f02.txt @@ -0,0 +1,4 @@ +0 0.14534883720930233 0.7682291666666666 0.20348837209302326 0.15625 +0 0.4331395348837209 0.7526041666666666 0.20348837209302326 0.15625 +0 0.13953488372093023 0.40625 0.20348837209302326 0.15625 +0 0.3866279069767442 0.13020833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/400195dc9a918704861ca9b3533fdb48.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/400195dc9a918704861ca9b3533fdb48.txt new file mode 100644 index 0000000..3756ba6 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/400195dc9a918704861ca9b3533fdb48.txt @@ -0,0 +1,4 @@ +0 0.8546511627906976 0.3177083333333333 0.20348837209302326 0.15625 +0 0.5116279069767442 0.16145833333333331 0.20348837209302326 0.15625 +0 0.7645348837209303 0.6692708333333333 0.20348837209302326 0.15625 +0 0.36046511627906974 0.5052083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/401a6529b756023fafddc0ecc08f3a34.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/401a6529b756023fafddc0ecc08f3a34.txt new file mode 100644 index 0000000..0ddbbdf --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/401a6529b756023fafddc0ecc08f3a34.txt @@ -0,0 +1,5 @@ +0 0.6715116279069767 0.20572916666666666 0.20348837209302326 0.15625 +0 0.31976744186046513 0.2708333333333333 0.20348837209302326 0.15625 +0 0.7906976744186046 0.578125 0.20348837209302326 0.15625 +0 0.2877906976744186 0.7265625 0.20348837209302326 0.15625 +0 0.2703488372093023 0.5052083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/410035421e5bbf571c52cf42f0bc283e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/410035421e5bbf571c52cf42f0bc283e.txt new file mode 100644 index 0000000..5699593 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/410035421e5bbf571c52cf42f0bc283e.txt @@ -0,0 +1,3 @@ +0 0.8459302325581395 0.5546875 0.20348837209302326 0.15625 +0 0.5348837209302325 0.6484375 0.20348837209302326 0.15625 +0 0.5843023255813954 0.29947916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4195841bf1ecb3b7f09a4b97b6225f80.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4195841bf1ecb3b7f09a4b97b6225f80.txt new file mode 100644 index 0000000..9a78848 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4195841bf1ecb3b7f09a4b97b6225f80.txt @@ -0,0 +1,4 @@ +0 0.38372093023255816 0.6796875 0.20348837209302326 0.15625 +0 0.3226744186046512 0.38541666666666663 0.20348837209302326 0.15625 +0 0.3081395348837209 0.14322916666666666 0.20348837209302326 0.15625 +0 0.8255813953488372 0.4348958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/42770b7520259afe70390e59e0af99a0.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/42770b7520259afe70390e59e0af99a0.txt new file mode 100644 index 0000000..6b1215f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/42770b7520259afe70390e59e0af99a0.txt @@ -0,0 +1,4 @@ +0 0.4331395348837209 0.5338541666666666 0.20348837209302326 0.15625 +0 0.8168604651162791 0.6614583333333333 0.20348837209302326 0.15625 +0 0.4273255813953488 0.7864583333333333 0.20348837209302326 0.15625 +0 0.4622093023255814 0.26041666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/42bd385aa6a3f544f17bfa3a2efbd533.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/42bd385aa6a3f544f17bfa3a2efbd533.txt new file mode 100644 index 0000000..8e27063 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/42bd385aa6a3f544f17bfa3a2efbd533.txt @@ -0,0 +1,4 @@ +0 0.3895348837209302 0.39322916666666663 0.20348837209302326 0.15625 +0 0.8023255813953488 0.3958333333333333 0.20348837209302326 0.15625 +0 0.7965116279069767 0.640625 0.20348837209302326 0.15625 +0 0.14825581395348836 0.7682291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/43519d83899d5c69878f9c444f8120a2.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/43519d83899d5c69878f9c444f8120a2.txt new file mode 100644 index 0000000..6f08540 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/43519d83899d5c69878f9c444f8120a2.txt @@ -0,0 +1,4 @@ +0 0.39244186046511625 0.6302083333333333 0.20348837209302326 0.15625 +0 0.32558139534883723 0.11979166666666666 0.20348837209302326 0.15625 +0 0.6715116279069767 0.2708333333333333 0.20348837209302326 0.15625 +0 0.8488372093023255 0.6223958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/43605a2b412d6ac6f4449a0ed60ae30d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/43605a2b412d6ac6f4449a0ed60ae30d.txt new file mode 100644 index 0000000..3cfe8b0 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/43605a2b412d6ac6f4449a0ed60ae30d.txt @@ -0,0 +1,2 @@ +0 0.18895348837209303 0.46875 0.20348837209302326 0.15625 +0 0.5145348837209303 0.6614583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/44dbfd2e1b8d827e74a8c26c0dba82b0.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/44dbfd2e1b8d827e74a8c26c0dba82b0.txt new file mode 100644 index 0000000..99e9a95 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/44dbfd2e1b8d827e74a8c26c0dba82b0.txt @@ -0,0 +1,4 @@ +0 0.5843023255813954 0.265625 0.20348837209302326 0.15625 +0 0.8808139534883721 0.5364583333333333 0.20348837209302326 0.15625 +0 0.18313953488372092 0.625 0.20348837209302326 0.15625 +0 0.23255813953488372 0.13541666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4510f763fc87557edeff52dc63c4362b.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4510f763fc87557edeff52dc63c4362b.txt new file mode 100644 index 0000000..a379d3c --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4510f763fc87557edeff52dc63c4362b.txt @@ -0,0 +1,4 @@ +0 0.8284883720930233 0.71875 0.20348837209302326 0.15625 +0 0.5901162790697674 0.22916666666666666 0.20348837209302326 0.15625 +0 0.19186046511627908 0.3567708333333333 0.20348837209302326 0.15625 +0 0.5145348837209303 0.6041666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/452b4d9454ab5efa7e588537759b8b65.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/452b4d9454ab5efa7e588537759b8b65.txt new file mode 100644 index 0000000..79080d5 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/452b4d9454ab5efa7e588537759b8b65.txt @@ -0,0 +1,4 @@ +0 0.40406976744186046 0.19791666666666666 0.20348837209302326 0.15625 +0 0.7994186046511628 0.71875 0.20348837209302326 0.15625 +0 0.12790697674418605 0.7864583333333333 0.20348837209302326 0.15625 +0 0.438953488372093 0.5 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/45d878d88d345bdf47b96c54fb19020d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/45d878d88d345bdf47b96c54fb19020d.txt new file mode 100644 index 0000000..c58e746 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/45d878d88d345bdf47b96c54fb19020d.txt @@ -0,0 +1,4 @@ +0 0.2180232558139535 0.7447916666666666 0.20348837209302326 0.15625 +0 0.5843023255813954 0.5338541666666666 0.20348837209302326 0.15625 +0 0.7994186046511628 0.1171875 0.20348837209302326 0.15625 +0 0.3953488372093023 0.1796875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/46bf4c6370fd7a5038a576775cf047a7.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/46bf4c6370fd7a5038a576775cf047a7.txt new file mode 100644 index 0000000..f7d9414 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/46bf4c6370fd7a5038a576775cf047a7.txt @@ -0,0 +1,3 @@ +0 0.5348837209302325 0.625 0.20348837209302326 0.15625 +0 0.24709302325581395 0.71875 0.20348837209302326 0.15625 +0 0.502906976744186 0.2890625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/48588868e9e505c3ad9ed0fc1f38e7fc.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/48588868e9e505c3ad9ed0fc1f38e7fc.txt new file mode 100644 index 0000000..f3545f8 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/48588868e9e505c3ad9ed0fc1f38e7fc.txt @@ -0,0 +1,4 @@ +0 0.47674418604651164 0.36197916666666663 0.20348837209302326 0.15625 +0 0.5290697674418604 0.6484375 0.20348837209302326 0.15625 +0 0.8430232558139534 0.23697916666666666 0.20348837209302326 0.15625 +0 0.19767441860465115 0.7005208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4999032b48901dc30550c8b43a0528a0.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4999032b48901dc30550c8b43a0528a0.txt new file mode 100644 index 0000000..119fcc3 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4999032b48901dc30550c8b43a0528a0.txt @@ -0,0 +1,4 @@ +0 0.30523255813953487 0.515625 0.20348837209302326 0.15625 +0 0.5232558139534884 0.3020833333333333 0.20348837209302326 0.15625 +0 0.2180232558139535 0.20052083333333331 0.20348837209302326 0.15625 +0 0.872093023255814 0.2630208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4a4bc20da64e111c69659c49efb6a99b.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4a4bc20da64e111c69659c49efb6a99b.txt new file mode 100644 index 0000000..f423f0d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4a4bc20da64e111c69659c49efb6a99b.txt @@ -0,0 +1,4 @@ +0 0.8343023255813954 0.2890625 0.20348837209302326 0.15625 +0 0.7732558139534884 0.546875 0.20348837209302326 0.15625 +0 0.3691860465116279 0.7682291666666666 0.20348837209302326 0.15625 +0 0.3575581395348837 0.43229166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4a7ecc87a26e0406d0261d9d0c51af1b.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4a7ecc87a26e0406d0261d9d0c51af1b.txt new file mode 100644 index 0000000..505822c --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4a7ecc87a26e0406d0261d9d0c51af1b.txt @@ -0,0 +1,5 @@ +0 0.24709302325581395 0.171875 0.20348837209302326 0.15625 +0 0.75 0.14322916666666666 0.20348837209302326 0.15625 +0 0.25290697674418605 0.4270833333333333 0.20348837209302326 0.15625 +0 0.622093023255814 0.7005208333333333 0.20348837209302326 0.15625 +0 0.15988372093023256 0.7734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4c3b7d90e3c48ccbdc3dd899920427ab.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4c3b7d90e3c48ccbdc3dd899920427ab.txt new file mode 100644 index 0000000..c9b71fe --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4c3b7d90e3c48ccbdc3dd899920427ab.txt @@ -0,0 +1,4 @@ +0 0.5406976744186046 0.34635416666666663 0.20348837209302326 0.15625 +0 0.49127906976744184 0.703125 0.20348837209302326 0.15625 +0 0.21220930232558138 0.33854166666666663 0.20348837209302326 0.15625 +0 0.3575581395348837 0.10416666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4c91928e0d18fb9f935323e21a7a377f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4c91928e0d18fb9f935323e21a7a377f.txt new file mode 100644 index 0000000..7ee1483 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4c91928e0d18fb9f935323e21a7a377f.txt @@ -0,0 +1,5 @@ +0 0.7587209302325582 0.27604166666666663 0.20348837209302326 0.15625 +0 0.5581395348837209 0.53125 0.20348837209302326 0.15625 +0 0.14825581395348836 0.328125 0.20348837209302326 0.15625 +0 0.3546511627906977 0.7786458333333333 0.20348837209302326 0.15625 +0 0.7238372093023255 0.7864583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4dc3e2b518cff881958a0d8023d04323.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4dc3e2b518cff881958a0d8023d04323.txt new file mode 100644 index 0000000..b874872 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4dc3e2b518cff881958a0d8023d04323.txt @@ -0,0 +1,4 @@ +0 0.7122093023255814 0.16666666666666666 0.20348837209302326 0.15625 +0 0.2645348837209302 0.6927083333333333 0.20348837209302326 0.15625 +0 0.7906976744186046 0.4375 0.20348837209302326 0.15625 +0 0.7063953488372093 0.765625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4e4e945cf266b758ca86165a7d8d2b9c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4e4e945cf266b758ca86165a7d8d2b9c.txt new file mode 100644 index 0000000..a175ad3 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4e4e945cf266b758ca86165a7d8d2b9c.txt @@ -0,0 +1,5 @@ +0 0.6715116279069767 0.14583333333333331 0.20348837209302326 0.15625 +0 0.313953488372093 0.6276041666666666 0.20348837209302326 0.15625 +0 0.32558139534883723 0.3098958333333333 0.20348837209302326 0.15625 +0 0.6308139534883721 0.6666666666666666 0.20348837209302326 0.15625 +0 0.6686046511627907 0.4270833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4e92d0b632411dfd1f034e6841285b63.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4e92d0b632411dfd1f034e6841285b63.txt new file mode 100644 index 0000000..6c0810c --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4e92d0b632411dfd1f034e6841285b63.txt @@ -0,0 +1,4 @@ +0 0.6017441860465116 0.20572916666666666 0.20348837209302326 0.15625 +0 0.30523255813953487 0.21354166666666666 0.20348837209302326 0.15625 +0 0.4215116279069767 0.6640625 0.20348837209302326 0.15625 +0 0.14244186046511628 0.6614583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4ee71c6c6465bcd633e17a88bb66e6b6.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4ee71c6c6465bcd633e17a88bb66e6b6.txt new file mode 100644 index 0000000..b109f5c --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4ee71c6c6465bcd633e17a88bb66e6b6.txt @@ -0,0 +1,3 @@ +0 0.561046511627907 0.5729166666666666 0.20348837209302326 0.15625 +0 0.7063953488372093 0.22135416666666666 0.20348837209302326 0.15625 +0 0.3168604651162791 0.22916666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4f2e3ae76b23aa8f37e5c1f6a6764cbb.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4f2e3ae76b23aa8f37e5c1f6a6764cbb.txt new file mode 100644 index 0000000..925313f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/4f2e3ae76b23aa8f37e5c1f6a6764cbb.txt @@ -0,0 +1,4 @@ +0 0.4331395348837209 0.3671875 0.20348837209302326 0.15625 +0 0.7936046511627907 0.4427083333333333 0.20348837209302326 0.15625 +0 0.5058139534883721 0.7447916666666666 0.20348837209302326 0.15625 +0 0.18023255813953487 0.6302083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5019576f93e20855db14485bbef2c955.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5019576f93e20855db14485bbef2c955.txt new file mode 100644 index 0000000..c7c2d74 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5019576f93e20855db14485bbef2c955.txt @@ -0,0 +1,4 @@ +0 0.13953488372093023 0.140625 0.20348837209302326 0.15625 +0 0.8052325581395349 0.09635416666666666 0.20348837209302326 0.15625 +0 0.3488372093023256 0.7135416666666666 0.20348837209302326 0.15625 +0 0.8575581395348837 0.7239583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/51334487bb9b1a0c74d8fa63e934cb13.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/51334487bb9b1a0c74d8fa63e934cb13.txt new file mode 100644 index 0000000..66e1da4 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/51334487bb9b1a0c74d8fa63e934cb13.txt @@ -0,0 +1,4 @@ +0 0.5261627906976745 0.7760416666666666 0.20348837209302326 0.15625 +0 0.2761627906976744 0.34375 0.20348837209302326 0.15625 +0 0.5348837209302325 0.1171875 0.20348837209302326 0.15625 +0 0.2616279069767442 0.6484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/519ca1605ca2e29195f432ca7c6b9cee.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/519ca1605ca2e29195f432ca7c6b9cee.txt new file mode 100644 index 0000000..8a580f6 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/519ca1605ca2e29195f432ca7c6b9cee.txt @@ -0,0 +1,4 @@ +0 0.7034883720930233 0.671875 0.20348837209302326 0.15625 +0 0.4738372093023256 0.15104166666666666 0.20348837209302326 0.15625 +0 0.3081395348837209 0.6432291666666666 0.20348837209302326 0.15625 +0 0.32558139534883723 0.38541666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/51b36552854c5e2fdcb505e67309fbf8.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/51b36552854c5e2fdcb505e67309fbf8.txt new file mode 100644 index 0000000..221c835 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/51b36552854c5e2fdcb505e67309fbf8.txt @@ -0,0 +1,3 @@ +0 0.1686046511627907 0.7265625 0.20348837209302326 0.15625 +0 0.6598837209302325 0.6119791666666666 0.20348837209302326 0.15625 +0 0.5872093023255814 0.15625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/520d7c9f42181d562be5fa94b7af12db.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/520d7c9f42181d562be5fa94b7af12db.txt new file mode 100644 index 0000000..c80652e --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/520d7c9f42181d562be5fa94b7af12db.txt @@ -0,0 +1,3 @@ +0 0.21511627906976744 0.4505208333333333 0.20348837209302326 0.15625 +0 0.5988372093023255 0.43229166666666663 0.20348837209302326 0.15625 +0 0.8081395348837209 0.7552083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/529628f3551401356c3071efc858c265.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/529628f3551401356c3071efc858c265.txt new file mode 100644 index 0000000..eea9f2d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/529628f3551401356c3071efc858c265.txt @@ -0,0 +1,3 @@ +0 0.5523255813953488 0.1328125 0.20348837209302326 0.15625 +0 0.18895348837209303 0.4036458333333333 0.20348837209302326 0.15625 +0 0.7965116279069767 0.7395833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/52a3837bf459d37710dd704419e496de.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/52a3837bf459d37710dd704419e496de.txt new file mode 100644 index 0000000..bda9d6a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/52a3837bf459d37710dd704419e496de.txt @@ -0,0 +1,3 @@ +0 0.8255813953488372 0.5494791666666666 0.20348837209302326 0.15625 +0 0.30523255813953487 0.6197916666666666 0.20348837209302326 0.15625 +0 0.15406976744186046 0.3333333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5349d602f9deb7dd510eea3bb4695bce.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5349d602f9deb7dd510eea3bb4695bce.txt new file mode 100644 index 0000000..16a9800 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5349d602f9deb7dd510eea3bb4695bce.txt @@ -0,0 +1,5 @@ +0 0.7645348837209303 0.5390625 0.20348837209302326 0.15625 +0 0.37790697674418605 0.09895833333333333 0.20348837209302326 0.15625 +0 0.7412790697674418 0.2734375 0.20348837209302326 0.15625 +0 0.2180232558139535 0.6119791666666666 0.20348837209302326 0.15625 +0 0.5348837209302325 0.7942708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/541444acfa5eaf5382767dced1c34dba.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/541444acfa5eaf5382767dced1c34dba.txt new file mode 100644 index 0000000..8b34d7a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/541444acfa5eaf5382767dced1c34dba.txt @@ -0,0 +1,4 @@ +0 0.5319767441860465 0.3046875 0.20348837209302326 0.15625 +0 0.5377906976744186 0.7734375 0.20348837209302326 0.15625 +0 0.15406976744186046 0.18489583333333331 0.20348837209302326 0.15625 +0 0.4215116279069767 0.5364583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/54582ae38ee9947c1926d8193c1ae8b7.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/54582ae38ee9947c1926d8193c1ae8b7.txt new file mode 100644 index 0000000..e4f7d57 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/54582ae38ee9947c1926d8193c1ae8b7.txt @@ -0,0 +1,3 @@ +0 0.5813953488372093 0.4973958333333333 0.20348837209302326 0.15625 +0 0.438953488372093 0.16666666666666666 0.20348837209302326 0.15625 +0 0.16569767441860464 0.32291666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/54a2e506d9f0dc65308355b141269ef6.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/54a2e506d9f0dc65308355b141269ef6.txt new file mode 100644 index 0000000..465c13f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/54a2e506d9f0dc65308355b141269ef6.txt @@ -0,0 +1,4 @@ +0 0.7034883720930233 0.5729166666666666 0.20348837209302326 0.15625 +0 0.8226744186046512 0.125 0.20348837209302326 0.15625 +0 0.2005813953488372 0.39322916666666663 0.20348837209302326 0.15625 +0 0.5 0.21354166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/54b7c5bf429eb9e20ed7db62ac737bb2.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/54b7c5bf429eb9e20ed7db62ac737bb2.txt new file mode 100644 index 0000000..3a17e9a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/54b7c5bf429eb9e20ed7db62ac737bb2.txt @@ -0,0 +1,4 @@ +0 0.8052325581395349 0.6848958333333333 0.20348837209302326 0.15625 +0 0.29069767441860467 0.22916666666666666 0.20348837209302326 0.15625 +0 0.7732558139534884 0.2864583333333333 0.20348837209302326 0.15625 +0 0.18895348837209303 0.5729166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5580c1dd0df32648b5ce98510507abd5.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5580c1dd0df32648b5ce98510507abd5.txt new file mode 100644 index 0000000..b1713c6 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5580c1dd0df32648b5ce98510507abd5.txt @@ -0,0 +1,5 @@ +0 0.7267441860465116 0.4192708333333333 0.20348837209302326 0.15625 +0 0.1744186046511628 0.7213541666666666 0.20348837209302326 0.15625 +0 0.7848837209302325 0.7786458333333333 0.20348837209302326 0.15625 +0 0.31976744186046513 0.22916666666666666 0.20348837209302326 0.15625 +0 0.7819767441860465 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/558b1b333ddd1542bc561f02706c1fc4.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/558b1b333ddd1542bc561f02706c1fc4.txt new file mode 100644 index 0000000..1b67111 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/558b1b333ddd1542bc561f02706c1fc4.txt @@ -0,0 +1,4 @@ +0 0.1686046511627907 0.47916666666666663 0.20348837209302326 0.15625 +0 0.4796511627906977 0.4973958333333333 0.20348837209302326 0.15625 +0 0.811046511627907 0.4739583333333333 0.20348837209302326 0.15625 +0 0.5813953488372093 0.19270833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/561e31e4b8f46b9687a8378710ac3b02.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/561e31e4b8f46b9687a8378710ac3b02.txt new file mode 100644 index 0000000..367d9e7 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/561e31e4b8f46b9687a8378710ac3b02.txt @@ -0,0 +1,3 @@ +0 0.4883720930232558 0.734375 0.20348837209302326 0.15625 +0 0.2616279069767442 0.46875 0.20348837209302326 0.15625 +0 0.8226744186046512 0.5026041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/582729139f879d1590ca60422deb8841.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/582729139f879d1590ca60422deb8841.txt new file mode 100644 index 0000000..3e3bd4f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/582729139f879d1590ca60422deb8841.txt @@ -0,0 +1,5 @@ +0 0.563953488372093 0.5416666666666666 0.20348837209302326 0.15625 +0 0.4505813953488372 0.28385416666666663 0.20348837209302326 0.15625 +0 0.2616279069767442 0.6822916666666666 0.20348837209302326 0.15625 +0 0.7790697674418604 0.3125 0.20348837209302326 0.15625 +0 0.8459302325581395 0.59375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/58b6749ecb2db5b30fe90aafdd7e2598.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/58b6749ecb2db5b30fe90aafdd7e2598.txt new file mode 100644 index 0000000..29bbca5 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/58b6749ecb2db5b30fe90aafdd7e2598.txt @@ -0,0 +1,3 @@ +0 0.1511627906976744 0.609375 0.20348837209302326 0.15625 +0 0.2441860465116279 0.1796875 0.20348837209302326 0.15625 +0 0.5872093023255814 0.11197916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/58fb78f5d92833e1570d0fb23857fd6d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/58fb78f5d92833e1570d0fb23857fd6d.txt new file mode 100644 index 0000000..adf386f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/58fb78f5d92833e1570d0fb23857fd6d.txt @@ -0,0 +1,5 @@ +0 0.24709302325581395 0.7630208333333333 0.20348837209302326 0.15625 +0 0.5348837209302325 0.6197916666666666 0.20348837209302326 0.15625 +0 0.16569767441860464 0.3723958333333333 0.20348837209302326 0.15625 +0 0.8401162790697674 0.5 0.20348837209302326 0.15625 +0 0.7877906976744186 0.265625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/59e7550ded1e0f6bd251635be74f1dfe.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/59e7550ded1e0f6bd251635be74f1dfe.txt new file mode 100644 index 0000000..d29f494 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/59e7550ded1e0f6bd251635be74f1dfe.txt @@ -0,0 +1,3 @@ +0 0.38372093023255816 0.19270833333333331 0.20348837209302326 0.15625 +0 0.8430232558139534 0.7890625 0.20348837209302326 0.15625 +0 0.30523255813953487 0.6354166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5b3153f226bd5c74cd48f228b8f7bd8c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5b3153f226bd5c74cd48f228b8f7bd8c.txt new file mode 100644 index 0000000..028e434 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5b3153f226bd5c74cd48f228b8f7bd8c.txt @@ -0,0 +1,3 @@ +0 0.42441860465116277 0.7552083333333333 0.20348837209302326 0.15625 +0 0.10755813953488372 0.6119791666666666 0.20348837209302326 0.15625 +0 0.16279069767441862 0.20052083333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5bd31a05874d191357a938ab4f43099a.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5bd31a05874d191357a938ab4f43099a.txt new file mode 100644 index 0000000..f65ab20 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5bd31a05874d191357a938ab4f43099a.txt @@ -0,0 +1,5 @@ +0 0.6511627906976745 0.4296875 0.20348837209302326 0.15625 +0 0.2441860465116279 0.59375 0.20348837209302326 0.15625 +0 0.8284883720930233 0.7265625 0.20348837209302326 0.15625 +0 0.8284883720930233 0.19010416666666666 0.20348837209302326 0.15625 +0 0.36627906976744184 0.16666666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5d4c6046a844ac9ba956624e854d274e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5d4c6046a844ac9ba956624e854d274e.txt new file mode 100644 index 0000000..e4a230b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5d4c6046a844ac9ba956624e854d274e.txt @@ -0,0 +1,3 @@ +0 0.49127906976744184 0.7317708333333333 0.20348837209302326 0.15625 +0 0.5523255813953488 0.14322916666666666 0.20348837209302326 0.15625 +0 0.22674418604651161 0.24479166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5d85a738255bca6f79ff36cef8c21c8e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5d85a738255bca6f79ff36cef8c21c8e.txt new file mode 100644 index 0000000..258cb4a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5d85a738255bca6f79ff36cef8c21c8e.txt @@ -0,0 +1,3 @@ +0 0.8430232558139534 0.6432291666666666 0.20348837209302326 0.15625 +0 0.7267441860465116 0.15625 0.20348837209302326 0.15625 +0 0.27325581395348836 0.5416666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5d9e5e18e9c5f3acfcd85709d30e3300.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5d9e5e18e9c5f3acfcd85709d30e3300.txt new file mode 100644 index 0000000..234d4d5 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5d9e5e18e9c5f3acfcd85709d30e3300.txt @@ -0,0 +1,4 @@ +0 0.8023255813953488 0.6979166666666666 0.20348837209302326 0.15625 +0 0.5465116279069767 0.14583333333333331 0.20348837209302326 0.15625 +0 0.4069767441860465 0.65625 0.20348837209302326 0.15625 +0 0.625 0.421875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5de94b7c29c8ca911b9f04f08cbbe52a.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5de94b7c29c8ca911b9f04f08cbbe52a.txt new file mode 100644 index 0000000..c0787e1 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5de94b7c29c8ca911b9f04f08cbbe52a.txt @@ -0,0 +1,5 @@ +0 0.7063953488372093 0.5286458333333333 0.20348837209302326 0.15625 +0 0.3633720930232558 0.7630208333333333 0.20348837209302326 0.15625 +0 0.14825581395348836 0.4505208333333333 0.20348837209302326 0.15625 +0 0.8459302325581395 0.28385416666666663 0.20348837209302326 0.15625 +0 0.5436046511627907 0.1484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5e0950103792f0632853c84a6ebb1387.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5e0950103792f0632853c84a6ebb1387.txt new file mode 100644 index 0000000..41271d4 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/5e0950103792f0632853c84a6ebb1387.txt @@ -0,0 +1,4 @@ +0 0.45930232558139533 0.625 0.20348837209302326 0.15625 +0 0.7616279069767442 0.19270833333333331 0.20348837209302326 0.15625 +0 0.7848837209302325 0.5208333333333333 0.20348837209302326 0.15625 +0 0.2645348837209302 0.39322916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/600a72d948d2e5c49beb1ba99f757bd9.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/600a72d948d2e5c49beb1ba99f757bd9.txt new file mode 100644 index 0000000..e2b814c --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/600a72d948d2e5c49beb1ba99f757bd9.txt @@ -0,0 +1,4 @@ +0 0.8197674418604651 0.6484375 0.20348837209302326 0.15625 +0 0.24127906976744184 0.22135416666666666 0.20348837209302326 0.15625 +0 0.6191860465116279 0.26041666666666663 0.20348837209302326 0.15625 +0 0.4331395348837209 0.5572916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/60462687400894cd6b98dc383092eb1e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/60462687400894cd6b98dc383092eb1e.txt new file mode 100644 index 0000000..3a9363a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/60462687400894cd6b98dc383092eb1e.txt @@ -0,0 +1,3 @@ +0 0.8197674418604651 0.5651041666666666 0.20348837209302326 0.15625 +0 0.18313953488372092 0.47135416666666663 0.20348837209302326 0.15625 +0 0.28488372093023256 0.7135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/61533beb53948314aa6f92a4750a509f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/61533beb53948314aa6f92a4750a509f.txt new file mode 100644 index 0000000..017422d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/61533beb53948314aa6f92a4750a509f.txt @@ -0,0 +1,4 @@ +0 0.4127906976744186 0.2864583333333333 0.20348837209302326 0.15625 +0 0.19767441860465115 0.6067708333333333 0.20348837209302326 0.15625 +0 0.8459302325581395 0.47135416666666663 0.20348837209302326 0.15625 +0 0.8488372093023255 0.7760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/62619e202ab8cf792019f56950399e2d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/62619e202ab8cf792019f56950399e2d.txt new file mode 100644 index 0000000..2d32542 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/62619e202ab8cf792019f56950399e2d.txt @@ -0,0 +1,4 @@ +0 0.6569767441860465 0.6666666666666666 0.20348837209302326 0.15625 +0 0.18313953488372092 0.3255208333333333 0.20348837209302326 0.15625 +0 0.28488372093023256 0.6953125 0.20348837209302326 0.15625 +0 0.4825581395348837 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/626f38915c39a337b0ba32d7979026af.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/626f38915c39a337b0ba32d7979026af.txt new file mode 100644 index 0000000..8c0487e --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/626f38915c39a337b0ba32d7979026af.txt @@ -0,0 +1,5 @@ +0 0.5843023255813954 0.45572916666666663 0.20348837209302326 0.15625 +0 0.7412790697674418 0.12239583333333333 0.20348837209302326 0.15625 +0 0.33430232558139533 0.11458333333333333 0.20348837209302326 0.15625 +0 0.25290697674418605 0.40625 0.20348837209302326 0.15625 +0 0.3488372093023256 0.7135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/639bd3499a527300d3963cee02c78d4c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/639bd3499a527300d3963cee02c78d4c.txt new file mode 100644 index 0000000..a62f988 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/639bd3499a527300d3963cee02c78d4c.txt @@ -0,0 +1,4 @@ +0 0.8517441860465116 0.12239583333333333 0.20348837209302326 0.15625 +0 0.41860465116279066 0.2734375 0.20348837209302326 0.15625 +0 0.7005813953488372 0.37760416666666663 0.20348837209302326 0.15625 +0 0.7819767441860465 0.765625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/63a9362a0fcce0e2c7aeb26f0ba700bd.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/63a9362a0fcce0e2c7aeb26f0ba700bd.txt new file mode 100644 index 0000000..cdf77ce --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/63a9362a0fcce0e2c7aeb26f0ba700bd.txt @@ -0,0 +1,4 @@ +0 0.45930232558139533 0.6979166666666666 0.20348837209302326 0.15625 +0 0.22674418604651161 0.234375 0.20348837209302326 0.15625 +0 0.6191860465116279 0.19270833333333331 0.20348837209302326 0.15625 +0 0.7645348837209303 0.53125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6472a94afc8804218f79747af43089d0.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6472a94afc8804218f79747af43089d0.txt new file mode 100644 index 0000000..90c0a41 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6472a94afc8804218f79747af43089d0.txt @@ -0,0 +1,3 @@ +0 0.24709302325581395 0.4817708333333333 0.20348837209302326 0.15625 +0 0.7441860465116279 0.4296875 0.20348837209302326 0.15625 +0 0.16569767441860464 0.13541666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/647cb7c0cd83579bde57dc4ad34c9cd9.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/647cb7c0cd83579bde57dc4ad34c9cd9.txt new file mode 100644 index 0000000..abcbb7e --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/647cb7c0cd83579bde57dc4ad34c9cd9.txt @@ -0,0 +1,3 @@ +0 0.1686046511627907 0.4296875 0.20348837209302326 0.15625 +0 0.6773255813953488 0.6354166666666666 0.20348837209302326 0.15625 +0 0.7209302325581395 0.21875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/648480a86f42c3d28e66eafcb09710b9.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/648480a86f42c3d28e66eafcb09710b9.txt new file mode 100644 index 0000000..5f799cb --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/648480a86f42c3d28e66eafcb09710b9.txt @@ -0,0 +1,4 @@ +0 0.39244186046511625 0.1953125 0.20348837209302326 0.15625 +0 0.37209302325581395 0.6953125 0.20348837209302326 0.15625 +0 0.7732558139534884 0.21614583333333331 0.20348837209302326 0.15625 +0 0.7412790697674418 0.7317708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/65a965e01e4533ef2c33088a096a1dc7.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/65a965e01e4533ef2c33088a096a1dc7.txt new file mode 100644 index 0000000..dbbed2f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/65a965e01e4533ef2c33088a096a1dc7.txt @@ -0,0 +1,4 @@ +0 0.38372093023255816 0.7213541666666666 0.20348837209302326 0.15625 +0 0.7209302325581395 0.23177083333333331 0.20348837209302326 0.15625 +0 0.1686046511627907 0.4921875 0.20348837209302326 0.15625 +0 0.4418604651162791 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6618fc3a903127e48b2c4fa624b0dd65.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6618fc3a903127e48b2c4fa624b0dd65.txt new file mode 100644 index 0000000..502135e --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6618fc3a903127e48b2c4fa624b0dd65.txt @@ -0,0 +1,5 @@ +0 0.6511627906976745 0.6875 0.20348837209302326 0.15625 +0 0.6133720930232558 0.4296875 0.20348837209302326 0.15625 +0 0.1308139534883721 0.359375 0.20348837209302326 0.15625 +0 0.7703488372093024 0.1015625 0.20348837209302326 0.15625 +0 0.2616279069767442 0.6927083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/66608aa57990aa2b8bd49ae3994569da.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/66608aa57990aa2b8bd49ae3994569da.txt new file mode 100644 index 0000000..7973625 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/66608aa57990aa2b8bd49ae3994569da.txt @@ -0,0 +1,4 @@ +0 0.4331395348837209 0.296875 0.20348837209302326 0.15625 +0 0.752906976744186 0.5546875 0.20348837209302326 0.15625 +0 0.18023255813953487 0.7864583333333333 0.20348837209302326 0.15625 +0 0.12790697674418605 0.5104166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/66fa72d54f8e560209ad9464de945c18.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/66fa72d54f8e560209ad9464de945c18.txt new file mode 100644 index 0000000..e4d01b1 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/66fa72d54f8e560209ad9464de945c18.txt @@ -0,0 +1,4 @@ +0 0.7994186046511628 0.296875 0.20348837209302326 0.15625 +0 0.36627906976744184 0.6770833333333333 0.20348837209302326 0.15625 +0 0.5058139534883721 0.2421875 0.20348837209302326 0.15625 +0 0.627906976744186 0.5390625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/678696f9eb5b903bbadad15d696328a2.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/678696f9eb5b903bbadad15d696328a2.txt new file mode 100644 index 0000000..6df0b2d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/678696f9eb5b903bbadad15d696328a2.txt @@ -0,0 +1,5 @@ +0 0.4680232558139535 0.484375 0.20348837209302326 0.15625 +0 0.8401162790697674 0.5104166666666666 0.20348837209302326 0.15625 +0 0.7616279069767442 0.15625 0.20348837209302326 0.15625 +0 0.4796511627906977 0.7708333333333333 0.20348837209302326 0.15625 +0 0.1511627906976744 0.5052083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/67d8686a17ab038abad3201430c57d22.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/67d8686a17ab038abad3201430c57d22.txt new file mode 100644 index 0000000..82c1b74 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/67d8686a17ab038abad3201430c57d22.txt @@ -0,0 +1,4 @@ +0 0.6976744186046512 0.5286458333333333 0.20348837209302326 0.15625 +0 0.5697674418604651 0.29166666666666663 0.20348837209302326 0.15625 +0 0.1686046511627907 0.2552083333333333 0.20348837209302326 0.15625 +0 0.16569767441860464 0.6145833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6a229e209beb7637e4ce5292d568798d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6a229e209beb7637e4ce5292d568798d.txt new file mode 100644 index 0000000..e1e1a53 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6a229e209beb7637e4ce5292d568798d.txt @@ -0,0 +1,4 @@ +0 0.7063953488372093 0.2421875 0.20348837209302326 0.15625 +0 0.3488372093023256 0.65625 0.20348837209302326 0.15625 +0 0.18604651162790697 0.18229166666666666 0.20348837209302326 0.15625 +0 0.6773255813953488 0.7630208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6ae61d876c63fa6cf47263c7a2ae7691.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6ae61d876c63fa6cf47263c7a2ae7691.txt new file mode 100644 index 0000000..d034527 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6ae61d876c63fa6cf47263c7a2ae7691.txt @@ -0,0 +1,4 @@ +0 0.8197674418604651 0.5859375 0.20348837209302326 0.15625 +0 0.44476744186046513 0.7057291666666666 0.20348837209302326 0.15625 +0 0.438953488372093 0.18229166666666666 0.20348837209302326 0.15625 +0 0.14534883720930233 0.5755208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6b1be0537a54d118a8763eafe746e904.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6b1be0537a54d118a8763eafe746e904.txt new file mode 100644 index 0000000..1e2146a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6b1be0537a54d118a8763eafe746e904.txt @@ -0,0 +1,4 @@ +0 0.7761627906976744 0.4140625 0.20348837209302326 0.15625 +0 0.7674418604651163 0.6666666666666666 0.20348837209302326 0.15625 +0 0.35174418604651164 0.5078125 0.20348837209302326 0.15625 +0 0.4680232558139535 0.27604166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6b2d3f4f96511774eb3bae27e3af06ad.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6b2d3f4f96511774eb3bae27e3af06ad.txt new file mode 100644 index 0000000..a9d1ed7 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6b2d3f4f96511774eb3bae27e3af06ad.txt @@ -0,0 +1,5 @@ +0 0.688953488372093 0.7369791666666666 0.20348837209302326 0.15625 +0 0.11918604651162791 0.453125 0.20348837209302326 0.15625 +0 0.5436046511627907 0.44010416666666663 0.20348837209302326 0.15625 +0 0.34011627906976744 0.125 0.20348837209302326 0.15625 +0 0.3866279069767442 0.7864583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6cb874c40ca65ceea675a7373018cfc4.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6cb874c40ca65ceea675a7373018cfc4.txt new file mode 100644 index 0000000..822bc07 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6cb874c40ca65ceea675a7373018cfc4.txt @@ -0,0 +1,4 @@ +0 0.3808139534883721 0.29947916666666663 0.20348837209302326 0.15625 +0 0.8255813953488372 0.4348958333333333 0.20348837209302326 0.15625 +0 0.6482558139534884 0.7526041666666666 0.20348837209302326 0.15625 +0 0.16279069767441862 0.7526041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6d13c490f207acee9e98881e13adb0f1.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6d13c490f207acee9e98881e13adb0f1.txt new file mode 100644 index 0000000..319e639 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6d13c490f207acee9e98881e13adb0f1.txt @@ -0,0 +1,4 @@ +0 0.3691860465116279 0.4505208333333333 0.20348837209302326 0.15625 +0 0.75 0.17708333333333331 0.20348837209302326 0.15625 +0 0.6569767441860465 0.4661458333333333 0.20348837209302326 0.15625 +0 0.19186046511627908 0.171875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6d5befea960e46a5c3274d0afc41ed1c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6d5befea960e46a5c3274d0afc41ed1c.txt new file mode 100644 index 0000000..c6f2167 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6d5befea960e46a5c3274d0afc41ed1c.txt @@ -0,0 +1,4 @@ +0 0.436046511627907 0.6848958333333333 0.20348837209302326 0.15625 +0 0.7994186046511628 0.5364583333333333 0.20348837209302326 0.15625 +0 0.5 0.3880208333333333 0.20348837209302326 0.15625 +0 0.19767441860465115 0.36979166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6e0f25e1a76ff1cbc9d0180969d3b54d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6e0f25e1a76ff1cbc9d0180969d3b54d.txt new file mode 100644 index 0000000..d7d4a8e --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6e0f25e1a76ff1cbc9d0180969d3b54d.txt @@ -0,0 +1,3 @@ +0 0.7296511627906976 0.4817708333333333 0.20348837209302326 0.15625 +0 0.42441860465116277 0.7395833333333333 0.20348837209302326 0.15625 +0 0.3546511627906977 0.2890625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6ea4be782fe8a5e54d5bb9070c47f71a.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6ea4be782fe8a5e54d5bb9070c47f71a.txt new file mode 100644 index 0000000..88c94d6 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6ea4be782fe8a5e54d5bb9070c47f71a.txt @@ -0,0 +1,4 @@ +0 0.5843023255813954 0.3828125 0.20348837209302326 0.15625 +0 0.17151162790697674 0.14583333333333331 0.20348837209302326 0.15625 +0 0.438953488372093 0.6640625 0.20348837209302326 0.15625 +0 0.11918604651162791 0.6432291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6ee961549759ead4213dbaf056bf62ae.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6ee961549759ead4213dbaf056bf62ae.txt new file mode 100644 index 0000000..2376903 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6ee961549759ead4213dbaf056bf62ae.txt @@ -0,0 +1,4 @@ +0 0.5087209302325582 0.25 0.20348837209302326 0.15625 +0 0.42441860465116277 0.5807291666666666 0.20348837209302326 0.15625 +0 0.1686046511627907 0.28385416666666663 0.20348837209302326 0.15625 +0 0.09302325581395349 0.734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6f7612493d34d1f1b8ec804747165c32.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6f7612493d34d1f1b8ec804747165c32.txt new file mode 100644 index 0000000..16fcbe7 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6f7612493d34d1f1b8ec804747165c32.txt @@ -0,0 +1,3 @@ +0 0.41860465116279066 0.5755208333333333 0.20348837209302326 0.15625 +0 0.8052325581395349 0.3333333333333333 0.20348837209302326 0.15625 +0 0.75 0.578125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6fa30962d8f9c30116e466965179387f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6fa30962d8f9c30116e466965179387f.txt new file mode 100644 index 0000000..175d982 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6fa30962d8f9c30116e466965179387f.txt @@ -0,0 +1,4 @@ +0 0.20348837209302326 0.3359375 0.20348837209302326 0.15625 +0 0.8168604651162791 0.3333333333333333 0.20348837209302326 0.15625 +0 0.502906976744186 0.15364583333333331 0.20348837209302326 0.15625 +0 0.4738372093023256 0.6197916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6fc67db2d6f8d0c0f40fe81faa04faa4.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6fc67db2d6f8d0c0f40fe81faa04faa4.txt new file mode 100644 index 0000000..0d9b0a6 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/6fc67db2d6f8d0c0f40fe81faa04faa4.txt @@ -0,0 +1,5 @@ +0 0.313953488372093 0.40885416666666663 0.20348837209302326 0.15625 +0 0.627906976744186 0.5 0.20348837209302326 0.15625 +0 0.11627906976744186 0.75 0.20348837209302326 0.15625 +0 0.747093023255814 0.18489583333333331 0.20348837209302326 0.15625 +0 0.6656976744186046 0.7239583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7009b0450486cf01ddb3deae2baded34.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7009b0450486cf01ddb3deae2baded34.txt new file mode 100644 index 0000000..825a923 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7009b0450486cf01ddb3deae2baded34.txt @@ -0,0 +1,5 @@ +0 0.42441860465116277 0.6875 0.20348837209302326 0.15625 +0 0.7965116279069767 0.6875 0.20348837209302326 0.15625 +0 0.7180232558139534 0.4453125 0.20348837209302326 0.15625 +0 0.26744186046511625 0.3671875 0.20348837209302326 0.15625 +0 0.3081395348837209 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/70bffc035ae5d0fd2bd314782cf69620.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/70bffc035ae5d0fd2bd314782cf69620.txt new file mode 100644 index 0000000..98b9a31 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/70bffc035ae5d0fd2bd314782cf69620.txt @@ -0,0 +1,3 @@ +0 0.7936046511627907 0.4765625 0.20348837209302326 0.15625 +0 0.2005813953488372 0.45572916666666663 0.20348837209302326 0.15625 +0 0.34011627906976744 0.71875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/710087f718f927c0d21c5f43b25bc85f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/710087f718f927c0d21c5f43b25bc85f.txt new file mode 100644 index 0000000..33f220d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/710087f718f927c0d21c5f43b25bc85f.txt @@ -0,0 +1,5 @@ +0 0.4331395348837209 0.36197916666666663 0.20348837209302326 0.15625 +0 0.7441860465116279 0.328125 0.20348837209302326 0.15625 +0 0.7819767441860465 0.7760416666666666 0.20348837209302326 0.15625 +0 0.4069767441860465 0.15364583333333331 0.20348837209302326 0.15625 +0 0.5058139534883721 0.6848958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/71c8e9c164e8bfccecc6b0d0c711a8ac.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/71c8e9c164e8bfccecc6b0d0c711a8ac.txt new file mode 100644 index 0000000..f9beed1 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/71c8e9c164e8bfccecc6b0d0c711a8ac.txt @@ -0,0 +1,4 @@ +0 0.5174418604651163 0.34375 0.20348837209302326 0.15625 +0 0.4622093023255814 0.6666666666666666 0.20348837209302326 0.15625 +0 0.8023255813953488 0.5963541666666666 0.20348837209302326 0.15625 +0 0.18895348837209303 0.36197916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/720436e9c276a5dd5159849e1d09e8ea.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/720436e9c276a5dd5159849e1d09e8ea.txt new file mode 100644 index 0000000..6272b29 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/720436e9c276a5dd5159849e1d09e8ea.txt @@ -0,0 +1,4 @@ +0 0.6831395348837209 0.3671875 0.20348837209302326 0.15625 +0 0.622093023255814 0.6223958333333333 0.20348837209302326 0.15625 +0 0.2965116279069767 0.10416666666666666 0.20348837209302326 0.15625 +0 0.37790697674418605 0.3411458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/726f8f3511fe3b8356332c19aa3ac299.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/726f8f3511fe3b8356332c19aa3ac299.txt new file mode 100644 index 0000000..035bfd0 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/726f8f3511fe3b8356332c19aa3ac299.txt @@ -0,0 +1,5 @@ +0 0.5348837209302325 0.7161458333333333 0.20348837209302326 0.15625 +0 0.41860465116279066 0.4036458333333333 0.20348837209302326 0.15625 +0 0.12209302325581395 0.21614583333333331 0.20348837209302326 0.15625 +0 0.8023255813953488 0.4921875 0.20348837209302326 0.15625 +0 0.13953488372093023 0.703125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/72cee0ff27d1c35768c2afdcfdc1183c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/72cee0ff27d1c35768c2afdcfdc1183c.txt new file mode 100644 index 0000000..eeff2e2 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/72cee0ff27d1c35768c2afdcfdc1183c.txt @@ -0,0 +1,4 @@ +0 0.125 0.5364583333333333 0.20348837209302326 0.15625 +0 0.39244186046511625 0.2421875 0.20348837209302326 0.15625 +0 0.8546511627906976 0.1171875 0.20348837209302326 0.15625 +0 0.8488372093023255 0.59375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/741bd5c4d3a2342122b3bcbab4f733ea.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/741bd5c4d3a2342122b3bcbab4f733ea.txt new file mode 100644 index 0000000..1d32740 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/741bd5c4d3a2342122b3bcbab4f733ea.txt @@ -0,0 +1,4 @@ +0 0.6686046511627907 0.21354166666666666 0.20348837209302326 0.15625 +0 0.14825581395348836 0.2864583333333333 0.20348837209302326 0.15625 +0 0.75 0.6979166666666666 0.20348837209302326 0.15625 +0 0.313953488372093 0.6927083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/745ed065275224ee96b082e6423970e7.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/745ed065275224ee96b082e6423970e7.txt new file mode 100644 index 0000000..29293d0 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/745ed065275224ee96b082e6423970e7.txt @@ -0,0 +1,5 @@ +0 0.5 0.4375 0.20348837209302326 0.15625 +0 0.13662790697674418 0.19270833333333331 0.20348837209302326 0.15625 +0 0.7994186046511628 0.22135416666666666 0.20348837209302326 0.15625 +0 0.2877906976744186 0.7682291666666666 0.20348837209302326 0.15625 +0 0.8284883720930233 0.6067708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7471731c4266eead2be85bc3b3bf45dc.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7471731c4266eead2be85bc3b3bf45dc.txt new file mode 100644 index 0000000..5cfefb5 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7471731c4266eead2be85bc3b3bf45dc.txt @@ -0,0 +1,4 @@ +0 0.5872093023255814 0.7708333333333333 0.20348837209302326 0.15625 +0 0.6482558139534884 0.09375 0.20348837209302326 0.15625 +0 0.4011627906976744 0.46875 0.20348837209302326 0.15625 +0 0.1569767441860465 0.13020833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7534b599139ea12d7b44e2495fe05157.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7534b599139ea12d7b44e2495fe05157.txt new file mode 100644 index 0000000..50e95ee --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7534b599139ea12d7b44e2495fe05157.txt @@ -0,0 +1,4 @@ +0 0.14825581395348836 0.29947916666666663 0.20348837209302326 0.15625 +0 0.4273255813953488 0.7005208333333333 0.20348837209302326 0.15625 +0 0.75 0.6588541666666666 0.20348837209302326 0.15625 +0 0.5174418604651163 0.3489583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/75670a9f70f9d0bfd32204a4eab7d470.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/75670a9f70f9d0bfd32204a4eab7d470.txt new file mode 100644 index 0000000..934d568 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/75670a9f70f9d0bfd32204a4eab7d470.txt @@ -0,0 +1,4 @@ +0 0.1308139534883721 0.26822916666666663 0.20348837209302326 0.15625 +0 0.627906976744186 0.2864583333333333 0.20348837209302326 0.15625 +0 0.20930232558139533 0.6328125 0.20348837209302326 0.15625 +0 0.7587209302325582 0.5989583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/76788b4474b560ecc99133113185a49b.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/76788b4474b560ecc99133113185a49b.txt new file mode 100644 index 0000000..9c45fa0 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/76788b4474b560ecc99133113185a49b.txt @@ -0,0 +1,4 @@ +0 0.20930232558139533 0.3489583333333333 0.20348837209302326 0.15625 +0 0.25872093023255816 0.6432291666666666 0.20348837209302326 0.15625 +0 0.5843023255813954 0.453125 0.20348837209302326 0.15625 +0 0.7819767441860465 0.7578125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7726cef279d193502f5cb83b9a88e83e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7726cef279d193502f5cb83b9a88e83e.txt new file mode 100644 index 0000000..1f2d2ec --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7726cef279d193502f5cb83b9a88e83e.txt @@ -0,0 +1,4 @@ +0 0.313953488372093 0.6119791666666666 0.20348837209302326 0.15625 +0 0.5581395348837209 0.2578125 0.20348837209302326 0.15625 +0 0.7732558139534884 0.53125 0.20348837209302326 0.15625 +0 0.14534883720930233 0.296875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/77312c07675c04d4b9267f93043a40ca.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/77312c07675c04d4b9267f93043a40ca.txt new file mode 100644 index 0000000..41b72cf --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/77312c07675c04d4b9267f93043a40ca.txt @@ -0,0 +1,4 @@ +0 0.5784883720930233 0.3802083333333333 0.20348837209302326 0.15625 +0 0.11918604651162791 0.2578125 0.20348837209302326 0.15625 +0 0.4622093023255814 0.6067708333333333 0.20348837209302326 0.15625 +0 0.1569767441860465 0.7760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/775446ae1ae0487f41edf9102969aede.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/775446ae1ae0487f41edf9102969aede.txt new file mode 100644 index 0000000..7884f2a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/775446ae1ae0487f41edf9102969aede.txt @@ -0,0 +1,4 @@ +0 0.3488372093023256 0.5130208333333333 0.20348837209302326 0.15625 +0 0.6308139534883721 0.15104166666666666 0.20348837209302326 0.15625 +0 0.6598837209302325 0.6145833333333333 0.20348837209302326 0.15625 +0 0.16569767441860464 0.2734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/77a7f5beb4fc4841f8a801f8cae29808.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/77a7f5beb4fc4841f8a801f8cae29808.txt new file mode 100644 index 0000000..ea85481 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/77a7f5beb4fc4841f8a801f8cae29808.txt @@ -0,0 +1,5 @@ +0 0.8313953488372093 0.1796875 0.20348837209302326 0.15625 +0 0.8488372093023255 0.48697916666666663 0.20348837209302326 0.15625 +0 0.5523255813953488 0.3177083333333333 0.20348837209302326 0.15625 +0 0.18313953488372092 0.15364583333333331 0.20348837209302326 0.15625 +0 0.3953488372093023 0.7135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/77c4275bce0c9cd186cd53ccb9a706b2.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/77c4275bce0c9cd186cd53ccb9a706b2.txt new file mode 100644 index 0000000..e79405b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/77c4275bce0c9cd186cd53ccb9a706b2.txt @@ -0,0 +1,4 @@ +0 0.40406976744186046 0.7526041666666666 0.20348837209302326 0.15625 +0 0.7819767441860465 0.12760416666666666 0.20348837209302326 0.15625 +0 0.3313953488372093 0.2890625 0.20348837209302326 0.15625 +0 0.7877906976744186 0.7135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/77eb813a40cdecdadc882c57f6b2cc4c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/77eb813a40cdecdadc882c57f6b2cc4c.txt new file mode 100644 index 0000000..5cb6502 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/77eb813a40cdecdadc882c57f6b2cc4c.txt @@ -0,0 +1,4 @@ +0 0.8488372093023255 0.18229166666666666 0.20348837209302326 0.15625 +0 0.48546511627906974 0.3723958333333333 0.20348837209302326 0.15625 +0 0.627906976744186 0.7369791666666666 0.20348837209302326 0.15625 +0 0.16279069767441862 0.29166666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/785da55d2c7de97aeb6ad1bd19119d6f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/785da55d2c7de97aeb6ad1bd19119d6f.txt new file mode 100644 index 0000000..720c72f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/785da55d2c7de97aeb6ad1bd19119d6f.txt @@ -0,0 +1,5 @@ +0 0.6511627906976745 0.3098958333333333 0.20348837209302326 0.15625 +0 0.29941860465116277 0.40885416666666663 0.20348837209302326 0.15625 +0 0.36627906976744184 0.6692708333333333 0.20348837209302326 0.15625 +0 0.6744186046511628 0.5260416666666666 0.20348837209302326 0.15625 +0 0.3081395348837209 0.16145833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/786d49911281c71f99e0d553c06ce3df.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/786d49911281c71f99e0d553c06ce3df.txt new file mode 100644 index 0000000..ca2927f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/786d49911281c71f99e0d553c06ce3df.txt @@ -0,0 +1,4 @@ +0 0.5959302325581395 0.28385416666666663 0.20348837209302326 0.15625 +0 0.2005813953488372 0.5494791666666666 0.20348837209302326 0.15625 +0 0.19186046511627908 0.29947916666666663 0.20348837209302326 0.15625 +0 0.11046511627906977 0.7708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7894d90a7e9e64d27d0d85c4c49555f3.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7894d90a7e9e64d27d0d85c4c49555f3.txt new file mode 100644 index 0000000..a8526ee --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7894d90a7e9e64d27d0d85c4c49555f3.txt @@ -0,0 +1,4 @@ +0 0.688953488372093 0.625 0.20348837209302326 0.15625 +0 0.5436046511627907 0.30729166666666663 0.20348837209302326 0.15625 +0 0.15406976744186046 0.23177083333333331 0.20348837209302326 0.15625 +0 0.22093023255813954 0.6744791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/78ad4d9929b9f076963d726d53a6e940.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/78ad4d9929b9f076963d726d53a6e940.txt new file mode 100644 index 0000000..c64eab1 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/78ad4d9929b9f076963d726d53a6e940.txt @@ -0,0 +1,2 @@ +0 0.7383720930232558 0.6953125 0.20348837209302326 0.15625 +0 0.27906976744186046 0.13541666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/794ccd0649ea0e8be29589734058a57d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/794ccd0649ea0e8be29589734058a57d.txt new file mode 100644 index 0000000..a685975 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/794ccd0649ea0e8be29589734058a57d.txt @@ -0,0 +1,3 @@ +0 0.3866279069767442 0.6041666666666666 0.20348837209302326 0.15625 +0 0.14825581395348836 0.13541666666666666 0.20348837209302326 0.15625 +0 0.8401162790697674 0.11197916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/79aa3d276582994734323d24cdb5ed01.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/79aa3d276582994734323d24cdb5ed01.txt new file mode 100644 index 0000000..ed7e2b3 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/79aa3d276582994734323d24cdb5ed01.txt @@ -0,0 +1,4 @@ +0 0.5959302325581395 0.5807291666666666 0.20348837209302326 0.15625 +0 0.3081395348837209 0.37760416666666663 0.20348837209302326 0.15625 +0 0.5930232558139534 0.16666666666666666 0.20348837209302326 0.15625 +0 0.18604651162790697 0.7057291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7a395e5c9d1fe6c75d862b922d77187c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7a395e5c9d1fe6c75d862b922d77187c.txt new file mode 100644 index 0000000..bb4bddf --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7a395e5c9d1fe6c75d862b922d77187c.txt @@ -0,0 +1,5 @@ +0 0.8343023255813954 0.47135416666666663 0.20348837209302326 0.15625 +0 0.3023255813953488 0.3984375 0.20348837209302326 0.15625 +0 0.7412790697674418 0.7630208333333333 0.20348837209302326 0.15625 +0 0.3168604651162791 0.6145833333333333 0.20348837209302326 0.15625 +0 0.7616279069767442 0.21875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7baff76c5fb6c08564fa34fd83939453.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7baff76c5fb6c08564fa34fd83939453.txt new file mode 100644 index 0000000..51b609b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7baff76c5fb6c08564fa34fd83939453.txt @@ -0,0 +1,5 @@ +0 0.6569767441860465 0.26822916666666663 0.20348837209302326 0.15625 +0 0.2936046511627907 0.5911458333333333 0.20348837209302326 0.15625 +0 0.5784883720930233 0.7239583333333333 0.20348837209302326 0.15625 +0 0.2616279069767442 0.22135416666666666 0.20348837209302326 0.15625 +0 0.8517441860465116 0.5078125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7c41d612128cd5e3b6e408883c934c95.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7c41d612128cd5e3b6e408883c934c95.txt new file mode 100644 index 0000000..4c4f3a3 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7c41d612128cd5e3b6e408883c934c95.txt @@ -0,0 +1,4 @@ +0 0.686046511627907 0.2552083333333333 0.20348837209302326 0.15625 +0 0.40988372093023256 0.4192708333333333 0.20348837209302326 0.15625 +0 0.6424418604651163 0.7552083333333333 0.20348837209302326 0.15625 +0 0.4069767441860465 0.1171875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7cbff942d1478e98084353d0f7f62e31.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7cbff942d1478e98084353d0f7f62e31.txt new file mode 100644 index 0000000..70c3fe7 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7cbff942d1478e98084353d0f7f62e31.txt @@ -0,0 +1,4 @@ +0 0.375 0.44791666666666663 0.20348837209302326 0.15625 +0 0.8023255813953488 0.21875 0.20348837209302326 0.15625 +0 0.7209302325581395 0.6822916666666666 0.20348837209302326 0.15625 +0 0.30523255813953487 0.6875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7d5348dd3b542499bbf02aed8bd36785.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7d5348dd3b542499bbf02aed8bd36785.txt new file mode 100644 index 0000000..98784d5 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7d5348dd3b542499bbf02aed8bd36785.txt @@ -0,0 +1,5 @@ +0 0.25872093023255816 0.3828125 0.20348837209302326 0.15625 +0 0.5988372093023255 0.4114583333333333 0.20348837209302326 0.15625 +0 0.3023255813953488 0.6588541666666666 0.20348837209302326 0.15625 +0 0.627906976744186 0.140625 0.20348837209302326 0.15625 +0 0.7267441860465116 0.7369791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7d93ad334d08b8c98c4284c1f8d2c4ec.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7d93ad334d08b8c98c4284c1f8d2c4ec.txt new file mode 100644 index 0000000..9fad6b6 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7d93ad334d08b8c98c4284c1f8d2c4ec.txt @@ -0,0 +1,5 @@ +0 0.32848837209302323 0.6953125 0.20348837209302326 0.15625 +0 0.44476744186046513 0.4895833333333333 0.20348837209302326 0.15625 +0 0.6918604651162791 0.15625 0.20348837209302326 0.15625 +0 0.8459302325581395 0.3880208333333333 0.20348837209302326 0.15625 +0 0.7703488372093024 0.671875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7d9c7bd57e89e7740ec07ecf8a048151.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7d9c7bd57e89e7740ec07ecf8a048151.txt new file mode 100644 index 0000000..5747d10 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7d9c7bd57e89e7740ec07ecf8a048151.txt @@ -0,0 +1,3 @@ +0 0.24127906976744184 0.4348958333333333 0.20348837209302326 0.15625 +0 0.3430232558139535 0.15885416666666666 0.20348837209302326 0.15625 +0 0.8372093023255813 0.6744791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7db7aae1e2bca2ca5235b8057009b0ac.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7db7aae1e2bca2ca5235b8057009b0ac.txt new file mode 100644 index 0000000..53e8891 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7db7aae1e2bca2ca5235b8057009b0ac.txt @@ -0,0 +1,5 @@ +0 0.8081395348837209 0.2552083333333333 0.20348837209302326 0.15625 +0 0.34593023255813954 0.6770833333333333 0.20348837209302326 0.15625 +0 0.6656976744186046 0.6979166666666666 0.20348837209302326 0.15625 +0 0.1511627906976744 0.09895833333333333 0.20348837209302326 0.15625 +0 0.5087209302325582 0.4140625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7e1f67b67402c4df5e1e2a44d25f51fa.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7e1f67b67402c4df5e1e2a44d25f51fa.txt new file mode 100644 index 0000000..cbf4851 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7e1f67b67402c4df5e1e2a44d25f51fa.txt @@ -0,0 +1,4 @@ +0 0.2063953488372093 0.5390625 0.20348837209302326 0.15625 +0 0.6104651162790697 0.6588541666666666 0.20348837209302326 0.15625 +0 0.8284883720930233 0.203125 0.20348837209302326 0.15625 +0 0.47093023255813954 0.32291666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7f11e6e09918113dcddf6d681e13ea71.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7f11e6e09918113dcddf6d681e13ea71.txt new file mode 100644 index 0000000..f31119b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7f11e6e09918113dcddf6d681e13ea71.txt @@ -0,0 +1,4 @@ +0 0.16279069767441862 0.7552083333333333 0.20348837209302326 0.15625 +0 0.7151162790697674 0.22916666666666666 0.20348837209302326 0.15625 +0 0.5872093023255814 0.671875 0.20348837209302326 0.15625 +0 0.34593023255813954 0.3203125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7f5f376b86a286024c83c26ffb49cb8c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7f5f376b86a286024c83c26ffb49cb8c.txt new file mode 100644 index 0000000..c42a2c3 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7f5f376b86a286024c83c26ffb49cb8c.txt @@ -0,0 +1,4 @@ +0 0.8401162790697674 0.7395833333333333 0.20348837209302326 0.15625 +0 0.3023255813953488 0.41666666666666663 0.20348837209302326 0.15625 +0 0.7761627906976744 0.4973958333333333 0.20348837209302326 0.15625 +0 0.5436046511627907 0.19270833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7fbf8b0bbec82e061a8d3eea8f0a71d1.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7fbf8b0bbec82e061a8d3eea8f0a71d1.txt new file mode 100644 index 0000000..0048467 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/7fbf8b0bbec82e061a8d3eea8f0a71d1.txt @@ -0,0 +1,4 @@ +0 0.37790697674418605 0.39322916666666663 0.20348837209302326 0.15625 +0 0.313953488372093 0.7760416666666666 0.20348837209302326 0.15625 +0 0.7616279069767442 0.16666666666666666 0.20348837209302326 0.15625 +0 0.7325581395348837 0.6302083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8213f4a18007036d5f4065f5376ff774.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8213f4a18007036d5f4065f5376ff774.txt new file mode 100644 index 0000000..ea71eea --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8213f4a18007036d5f4065f5376ff774.txt @@ -0,0 +1,4 @@ +0 0.8459302325581395 0.33072916666666663 0.20348837209302326 0.15625 +0 0.36046511627906974 0.734375 0.20348837209302326 0.15625 +0 0.2936046511627907 0.375 0.20348837209302326 0.15625 +0 0.5552325581395349 0.09114583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/824a6558348b36207e550fec790c5722.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/824a6558348b36207e550fec790c5722.txt new file mode 100644 index 0000000..b7a953a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/824a6558348b36207e550fec790c5722.txt @@ -0,0 +1,4 @@ +0 0.7674418604651163 0.625 0.20348837209302326 0.15625 +0 0.2761627906976744 0.15104166666666666 0.20348837209302326 0.15625 +0 0.8372093023255813 0.29947916666666663 0.20348837209302326 0.15625 +0 0.3168604651162791 0.5078125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/825a7b148796df2377293f52d740e817.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/825a7b148796df2377293f52d740e817.txt new file mode 100644 index 0000000..fa32dfc --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/825a7b148796df2377293f52d740e817.txt @@ -0,0 +1,4 @@ +0 0.6046511627906976 0.203125 0.20348837209302326 0.15625 +0 0.5552325581395349 0.7057291666666666 0.20348837209302326 0.15625 +0 0.2441860465116279 0.5286458333333333 0.20348837209302326 0.15625 +0 0.25290697674418605 0.765625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/82a1fd80d6a43cf0496ed6110c2f8e02.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/82a1fd80d6a43cf0496ed6110c2f8e02.txt new file mode 100644 index 0000000..9a1ce50 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/82a1fd80d6a43cf0496ed6110c2f8e02.txt @@ -0,0 +1,4 @@ +0 0.7674418604651163 0.40104166666666663 0.20348837209302326 0.15625 +0 0.7063953488372093 0.15104166666666666 0.20348837209302326 0.15625 +0 0.7732558139534884 0.6302083333333333 0.20348837209302326 0.15625 +0 0.20930232558139533 0.16145833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/841f372e79296ea98dd109364f81c59d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/841f372e79296ea98dd109364f81c59d.txt new file mode 100644 index 0000000..3dda015 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/841f372e79296ea98dd109364f81c59d.txt @@ -0,0 +1,4 @@ +0 0.5058139534883721 0.4348958333333333 0.20348837209302326 0.15625 +0 0.2819767441860465 0.7395833333333333 0.20348837209302326 0.15625 +0 0.6976744186046512 0.1640625 0.20348837209302326 0.15625 +0 0.14825581395348836 0.2890625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/851459f4199292ed1a7577162d013e9d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/851459f4199292ed1a7577162d013e9d.txt new file mode 100644 index 0000000..d447c74 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/851459f4199292ed1a7577162d013e9d.txt @@ -0,0 +1,5 @@ +0 0.36627906976744184 0.5494791666666666 0.20348837209302326 0.15625 +0 0.6598837209302325 0.22135416666666666 0.20348837209302326 0.15625 +0 0.29069767441860467 0.7890625 0.20348837209302326 0.15625 +0 0.7209302325581395 0.546875 0.20348837209302326 0.15625 +0 0.34011627906976744 0.21614583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8559d83fb3386d14f3f864903dfec0c8.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8559d83fb3386d14f3f864903dfec0c8.txt new file mode 100644 index 0000000..7498fc2 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8559d83fb3386d14f3f864903dfec0c8.txt @@ -0,0 +1,4 @@ +0 0.35174418604651164 0.4270833333333333 0.20348837209302326 0.15625 +0 0.4563953488372093 0.6458333333333333 0.20348837209302326 0.15625 +0 0.27325581395348836 0.14583333333333331 0.20348837209302326 0.15625 +0 0.7093023255813954 0.22395833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/857d3626683a302ff9b570090741ca51.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/857d3626683a302ff9b570090741ca51.txt new file mode 100644 index 0000000..95b4dcd --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/857d3626683a302ff9b570090741ca51.txt @@ -0,0 +1,3 @@ +0 0.7005813953488372 0.46875 0.20348837209302326 0.15625 +0 0.13662790697674418 0.2630208333333333 0.20348837209302326 0.15625 +0 0.7209302325581395 0.125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/85f5c5779d8989d9d671ea60e397690b.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/85f5c5779d8989d9d671ea60e397690b.txt new file mode 100644 index 0000000..ca8fb29 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/85f5c5779d8989d9d671ea60e397690b.txt @@ -0,0 +1,4 @@ +0 0.40988372093023256 0.21614583333333331 0.20348837209302326 0.15625 +0 0.6918604651162791 0.6223958333333333 0.20348837209302326 0.15625 +0 0.16569767441860464 0.5078125 0.20348837209302326 0.15625 +0 0.752906976744186 0.265625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/873baa02e1555c2c849ea326132b03c1.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/873baa02e1555c2c849ea326132b03c1.txt new file mode 100644 index 0000000..ae8af82 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/873baa02e1555c2c849ea326132b03c1.txt @@ -0,0 +1,4 @@ +0 0.5145348837209303 0.7395833333333333 0.20348837209302326 0.15625 +0 0.8313953488372093 0.734375 0.20348837209302326 0.15625 +0 0.2616279069767442 0.4192708333333333 0.20348837209302326 0.15625 +0 0.6511627906976745 0.28385416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/87955b65b77f2f86b3c9331d4a14bbb6.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/87955b65b77f2f86b3c9331d4a14bbb6.txt new file mode 100644 index 0000000..232944b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/87955b65b77f2f86b3c9331d4a14bbb6.txt @@ -0,0 +1,5 @@ +0 0.6773255813953488 0.671875 0.20348837209302326 0.15625 +0 0.12209302325581395 0.44010416666666663 0.20348837209302326 0.15625 +0 0.6802325581395349 0.23958333333333331 0.20348837209302326 0.15625 +0 0.14534883720930233 0.7265625 0.20348837209302326 0.15625 +0 0.2645348837209302 0.21875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8825bb1799574d04b9d15cdd52cf748d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8825bb1799574d04b9d15cdd52cf748d.txt new file mode 100644 index 0000000..d70385c --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8825bb1799574d04b9d15cdd52cf748d.txt @@ -0,0 +1,4 @@ +0 0.6424418604651163 0.2864583333333333 0.20348837209302326 0.15625 +0 0.3168604651162791 0.3723958333333333 0.20348837209302326 0.15625 +0 0.5465116279069767 0.671875 0.20348837209302326 0.15625 +0 0.18604651162790697 0.7916666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/89d87730899049f97ef3fb1c709cadd7.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/89d87730899049f97ef3fb1c709cadd7.txt new file mode 100644 index 0000000..a05ee4a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/89d87730899049f97ef3fb1c709cadd7.txt @@ -0,0 +1,4 @@ +0 0.5668604651162791 0.33072916666666663 0.20348837209302326 0.15625 +0 0.31976744186046513 0.6328125 0.20348837209302326 0.15625 +0 0.5901162790697674 0.5989583333333333 0.20348837209302326 0.15625 +0 0.18023255813953487 0.3333333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8a15e934825b7cb2d3e5b613144cd910.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8a15e934825b7cb2d3e5b613144cd910.txt new file mode 100644 index 0000000..b7498bf --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8a15e934825b7cb2d3e5b613144cd910.txt @@ -0,0 +1,3 @@ +0 0.43023255813953487 0.7734375 0.20348837209302326 0.15625 +0 0.5523255813953488 0.39322916666666663 0.20348837209302326 0.15625 +0 0.12790697674418605 0.14583333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8b0d95e91c085a2685ffb3d8269d7077.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8b0d95e91c085a2685ffb3d8269d7077.txt new file mode 100644 index 0000000..57ffa9f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8b0d95e91c085a2685ffb3d8269d7077.txt @@ -0,0 +1,5 @@ +0 0.4796511627906977 0.32291666666666663 0.20348837209302326 0.15625 +0 0.12790697674418605 0.37760416666666663 0.20348837209302326 0.15625 +0 0.8226744186046512 0.7708333333333333 0.20348837209302326 0.15625 +0 0.5290697674418604 0.09895833333333333 0.20348837209302326 0.15625 +0 0.5465116279069767 0.7708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8d9a1d62882c4212fff968c6ce25430e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8d9a1d62882c4212fff968c6ce25430e.txt new file mode 100644 index 0000000..b38e132 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8d9a1d62882c4212fff968c6ce25430e.txt @@ -0,0 +1,2 @@ +0 0.2180232558139535 0.4895833333333333 0.20348837209302326 0.15625 +0 0.5872093023255814 0.7291666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8ec09b3461d580500e27199617e3bd9c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8ec09b3461d580500e27199617e3bd9c.txt new file mode 100644 index 0000000..818424d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8ec09b3461d580500e27199617e3bd9c.txt @@ -0,0 +1,3 @@ +0 0.11337209302325581 0.7265625 0.20348837209302326 0.15625 +0 0.438953488372093 0.3411458333333333 0.20348837209302326 0.15625 +0 0.4273255813953488 0.703125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8ec1c1e12dac2fa8d13e32f4e140be33.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8ec1c1e12dac2fa8d13e32f4e140be33.txt new file mode 100644 index 0000000..bd2378e --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8ec1c1e12dac2fa8d13e32f4e140be33.txt @@ -0,0 +1,4 @@ +0 0.2703488372093023 0.359375 0.20348837209302326 0.15625 +0 0.7761627906976744 0.7552083333333333 0.20348837209302326 0.15625 +0 0.18895348837209303 0.6432291666666666 0.20348837209302326 0.15625 +0 0.7906976744186046 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8edd016df31d5637ec523779cac20961.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8edd016df31d5637ec523779cac20961.txt new file mode 100644 index 0000000..3d61021 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8edd016df31d5637ec523779cac20961.txt @@ -0,0 +1,2 @@ +0 0.747093023255814 0.7421875 0.20348837209302326 0.15625 +0 0.18023255813953487 0.2708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8eeb9ee66982325b11dd44ce2e765cee.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8eeb9ee66982325b11dd44ce2e765cee.txt new file mode 100644 index 0000000..97bbf04 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8eeb9ee66982325b11dd44ce2e765cee.txt @@ -0,0 +1,4 @@ +0 0.1511627906976744 0.6223958333333333 0.20348837209302326 0.15625 +0 0.36046511627906974 0.328125 0.20348837209302326 0.15625 +0 0.752906976744186 0.5208333333333333 0.20348837209302326 0.15625 +0 0.622093023255814 0.19270833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8f714f97e08d772374b551cc9f3e3580.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8f714f97e08d772374b551cc9f3e3580.txt new file mode 100644 index 0000000..50ce5bf --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8f714f97e08d772374b551cc9f3e3580.txt @@ -0,0 +1,4 @@ +0 0.8401162790697674 0.125 0.20348837209302326 0.15625 +0 0.2965116279069767 0.3671875 0.20348837209302326 0.15625 +0 0.6598837209302325 0.4817708333333333 0.20348837209302326 0.15625 +0 0.4273255813953488 0.10677083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8fb7ce565187d7ce5e53bdd4e8be8565.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8fb7ce565187d7ce5e53bdd4e8be8565.txt new file mode 100644 index 0000000..2f946ea --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/8fb7ce565187d7ce5e53bdd4e8be8565.txt @@ -0,0 +1,4 @@ +0 0.18604651162790697 0.5260416666666666 0.20348837209302326 0.15625 +0 0.47093023255813954 0.23958333333333331 0.20348837209302326 0.15625 +0 0.8313953488372093 0.4375 0.20348837209302326 0.15625 +0 0.7877906976744186 0.11458333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9097f94db10c3a77e4dcce0f9d873e28.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9097f94db10c3a77e4dcce0f9d873e28.txt new file mode 100644 index 0000000..459d3b6 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9097f94db10c3a77e4dcce0f9d873e28.txt @@ -0,0 +1,4 @@ +0 0.1686046511627907 0.4296875 0.20348837209302326 0.15625 +0 0.29941860465116277 0.7421875 0.20348837209302326 0.15625 +0 0.8662790697674418 0.14322916666666666 0.20348837209302326 0.15625 +0 0.1686046511627907 0.14583333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/910ea301c783d2a6b264eae9672f23e6.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/910ea301c783d2a6b264eae9672f23e6.txt new file mode 100644 index 0000000..7d0a419 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/910ea301c783d2a6b264eae9672f23e6.txt @@ -0,0 +1,2 @@ +0 0.4622093023255814 0.5 0.20348837209302326 0.15625 +0 0.17151162790697674 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9142fa8d89b3e0b6f5eb1de4c092098a.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9142fa8d89b3e0b6f5eb1de4c092098a.txt new file mode 100644 index 0000000..ff97213 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9142fa8d89b3e0b6f5eb1de4c092098a.txt @@ -0,0 +1,4 @@ +0 0.3691860465116279 0.4661458333333333 0.20348837209302326 0.15625 +0 0.627906976744186 0.7734375 0.20348837209302326 0.15625 +0 0.3313953488372093 0.18489583333333331 0.20348837209302326 0.15625 +0 0.3168604651162791 0.7135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/916ddce272ccfb0276d8af323e28e455.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/916ddce272ccfb0276d8af323e28e455.txt new file mode 100644 index 0000000..31589fb --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/916ddce272ccfb0276d8af323e28e455.txt @@ -0,0 +1,4 @@ +0 0.2761627906976744 0.765625 0.20348837209302326 0.15625 +0 0.563953488372093 0.1015625 0.20348837209302326 0.15625 +0 0.8459302325581395 0.4453125 0.20348837209302326 0.15625 +0 0.18604651162790697 0.2421875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/91c65204b18c6fb96943baf908ea12c9.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/91c65204b18c6fb96943baf908ea12c9.txt new file mode 100644 index 0000000..0b08180 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/91c65204b18c6fb96943baf908ea12c9.txt @@ -0,0 +1,4 @@ +0 0.4418604651162791 0.15364583333333331 0.20348837209302326 0.15625 +0 0.8052325581395349 0.4427083333333333 0.20348837209302326 0.15625 +0 0.24709302325581395 0.39322916666666663 0.20348837209302326 0.15625 +0 0.14825581395348836 0.6302083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9275e527c729636774d24889914a0008.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9275e527c729636774d24889914a0008.txt new file mode 100644 index 0000000..ef0f755 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9275e527c729636774d24889914a0008.txt @@ -0,0 +1,4 @@ +0 0.29941860465116277 0.5963541666666666 0.20348837209302326 0.15625 +0 0.3430232558139535 0.12239583333333333 0.20348837209302326 0.15625 +0 0.6686046511627907 0.15104166666666666 0.20348837209302326 0.15625 +0 0.752906976744186 0.4895833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/92de2815fa1300896a5caa248ddd3b27.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/92de2815fa1300896a5caa248ddd3b27.txt new file mode 100644 index 0000000..136ea24 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/92de2815fa1300896a5caa248ddd3b27.txt @@ -0,0 +1,3 @@ +0 0.18895348837209303 0.4296875 0.20348837209302326 0.15625 +0 0.8255813953488372 0.4817708333333333 0.20348837209302326 0.15625 +0 0.5087209302325582 0.734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9331d444eb4022d9156c2981285761cb.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9331d444eb4022d9156c2981285761cb.txt new file mode 100644 index 0000000..867bb5f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9331d444eb4022d9156c2981285761cb.txt @@ -0,0 +1,5 @@ +0 0.7906976744186046 0.49479166666666663 0.20348837209302326 0.15625 +0 0.19767441860465115 0.3411458333333333 0.20348837209302326 0.15625 +0 0.7761627906976744 0.23177083333333331 0.20348837209302326 0.15625 +0 0.311046511627907 0.5703125 0.20348837209302326 0.15625 +0 0.13953488372093023 0.11458333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/933a534cef0c2e5093597e01e1a48729.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/933a534cef0c2e5093597e01e1a48729.txt new file mode 100644 index 0000000..c666d2e --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/933a534cef0c2e5093597e01e1a48729.txt @@ -0,0 +1,3 @@ +0 0.7906976744186046 0.15364583333333331 0.20348837209302326 0.15625 +0 0.5988372093023255 0.7369791666666666 0.20348837209302326 0.15625 +0 0.23546511627906977 0.7473958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/935db938e9eda7ba1ee4a3b5991b9c57.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/935db938e9eda7ba1ee4a3b5991b9c57.txt new file mode 100644 index 0000000..a28cffa --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/935db938e9eda7ba1ee4a3b5991b9c57.txt @@ -0,0 +1,3 @@ +0 0.5436046511627907 0.6223958333333333 0.20348837209302326 0.15625 +0 0.502906976744186 0.21354166666666666 0.20348837209302326 0.15625 +0 0.811046511627907 0.3802083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/93d0fc7d138988945a0099da59269745.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/93d0fc7d138988945a0099da59269745.txt new file mode 100644 index 0000000..e9e8ebb --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/93d0fc7d138988945a0099da59269745.txt @@ -0,0 +1,2 @@ +0 0.5726744186046512 0.6979166666666666 0.20348837209302326 0.15625 +0 0.44476744186046513 0.3411458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/941a7cd0eb00bba884869e751d00ae2c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/941a7cd0eb00bba884869e751d00ae2c.txt new file mode 100644 index 0000000..fe6e5a9 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/941a7cd0eb00bba884869e751d00ae2c.txt @@ -0,0 +1,3 @@ +0 0.5726744186046512 0.19270833333333331 0.20348837209302326 0.15625 +0 0.313953488372093 0.578125 0.20348837209302326 0.15625 +0 0.7412790697674418 0.5885416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/943a90030ea11eefa19af682ce7cc28e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/943a90030ea11eefa19af682ce7cc28e.txt new file mode 100644 index 0000000..a447c42 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/943a90030ea11eefa19af682ce7cc28e.txt @@ -0,0 +1,4 @@ +0 0.7093023255813954 0.1015625 0.20348837209302326 0.15625 +0 0.18895348837209303 0.765625 0.20348837209302326 0.15625 +0 0.4215116279069767 0.2890625 0.20348837209302326 0.15625 +0 0.8313953488372093 0.6536458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9449bc93017476ec283925e21bd8f1c9.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9449bc93017476ec283925e21bd8f1c9.txt new file mode 100644 index 0000000..e957b3b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9449bc93017476ec283925e21bd8f1c9.txt @@ -0,0 +1,4 @@ +0 0.5348837209302325 0.12760416666666666 0.20348837209302326 0.15625 +0 0.7122093023255814 0.5651041666666666 0.20348837209302326 0.15625 +0 0.2441860465116279 0.44010416666666663 0.20348837209302326 0.15625 +0 0.1308139534883721 0.15364583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/94f3d16d1488a8b7690542b6aaccb056.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/94f3d16d1488a8b7690542b6aaccb056.txt new file mode 100644 index 0000000..18c58c7 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/94f3d16d1488a8b7690542b6aaccb056.txt @@ -0,0 +1,4 @@ +0 0.43023255813953487 0.515625 0.20348837209302326 0.15625 +0 0.7151162790697674 0.37760416666666663 0.20348837209302326 0.15625 +0 0.14244186046511628 0.4427083333333333 0.20348837209302326 0.15625 +0 0.7325581395348837 0.11979166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/952bdbcd285b419a773b8be327bf2edd.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/952bdbcd285b419a773b8be327bf2edd.txt new file mode 100644 index 0000000..8ed11d5 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/952bdbcd285b419a773b8be327bf2edd.txt @@ -0,0 +1,4 @@ +0 0.7645348837209303 0.2265625 0.20348837209302326 0.15625 +0 0.8459302325581395 0.5729166666666666 0.20348837209302326 0.15625 +0 0.2180232558139535 0.4270833333333333 0.20348837209302326 0.15625 +0 0.20348837209302326 0.12760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/95540a87f0439f94844fa8a078efa55e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/95540a87f0439f94844fa8a078efa55e.txt new file mode 100644 index 0000000..01105d5 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/95540a87f0439f94844fa8a078efa55e.txt @@ -0,0 +1,5 @@ +0 0.8255813953488372 0.12760416666666666 0.20348837209302326 0.15625 +0 0.35174418604651164 0.14322916666666666 0.20348837209302326 0.15625 +0 0.561046511627907 0.7994791666666666 0.20348837209302326 0.15625 +0 0.10755813953488372 0.6067708333333333 0.20348837209302326 0.15625 +0 0.4476744186046512 0.484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/95c690c6734de26d8308b061d74081ae.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/95c690c6734de26d8308b061d74081ae.txt new file mode 100644 index 0000000..109fb08 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/95c690c6734de26d8308b061d74081ae.txt @@ -0,0 +1,4 @@ +0 0.5145348837209303 0.7786458333333333 0.20348837209302326 0.15625 +0 0.41860465116279066 0.30729166666666663 0.20348837209302326 0.15625 +0 0.7412790697674418 0.1484375 0.20348837209302326 0.15625 +0 0.8052325581395349 0.6432291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/95e4b8a979c82909d89ef9b0fa3c1fda.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/95e4b8a979c82909d89ef9b0fa3c1fda.txt new file mode 100644 index 0000000..8cfa587 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/95e4b8a979c82909d89ef9b0fa3c1fda.txt @@ -0,0 +1,4 @@ +0 0.4418604651162791 0.734375 0.20348837209302326 0.15625 +0 0.2877906976744186 0.30729166666666663 0.20348837209302326 0.15625 +0 0.7383720930232558 0.5130208333333333 0.20348837209302326 0.15625 +0 0.752906976744186 0.12760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/960e1a7f4b929bf85f024050639201c9.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/960e1a7f4b929bf85f024050639201c9.txt new file mode 100644 index 0000000..0672a85 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/960e1a7f4b929bf85f024050639201c9.txt @@ -0,0 +1,5 @@ +0 0.7906976744186046 0.14322916666666666 0.20348837209302326 0.15625 +0 0.47674418604651164 0.24739583333333331 0.20348837209302326 0.15625 +0 0.18895348837209303 0.10677083333333333 0.20348837209302326 0.15625 +0 0.23546511627906977 0.5338541666666666 0.20348837209302326 0.15625 +0 0.7383720930232558 0.7291666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/961c2a792a5e1966cc7360da94d557c9.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/961c2a792a5e1966cc7360da94d557c9.txt new file mode 100644 index 0000000..75afb82 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/961c2a792a5e1966cc7360da94d557c9.txt @@ -0,0 +1,4 @@ +0 0.502906976744186 0.6276041666666666 0.20348837209302326 0.15625 +0 0.6947674418604651 0.3645833333333333 0.20348837209302326 0.15625 +0 0.8343023255813954 0.14322916666666666 0.20348837209302326 0.15625 +0 0.22674418604651161 0.34375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/96be01144f9c5cf1cbfea9e1bc15c27c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/96be01144f9c5cf1cbfea9e1bc15c27c.txt new file mode 100644 index 0000000..6711d2d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/96be01144f9c5cf1cbfea9e1bc15c27c.txt @@ -0,0 +1,3 @@ +0 0.502906976744186 0.4609375 0.20348837209302326 0.15625 +0 0.8430232558139534 0.5807291666666666 0.20348837209302326 0.15625 +0 0.3866279069767442 0.140625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/96c0be811cbc2ba0144c31a967854e6a.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/96c0be811cbc2ba0144c31a967854e6a.txt new file mode 100644 index 0000000..71ff6c2 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/96c0be811cbc2ba0144c31a967854e6a.txt @@ -0,0 +1,4 @@ +0 0.4215116279069767 0.2630208333333333 0.20348837209302326 0.15625 +0 0.747093023255814 0.09895833333333333 0.20348837209302326 0.15625 +0 0.7238372093023255 0.6328125 0.20348837209302326 0.15625 +0 0.13662790697674418 0.5755208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/97e1ec9b22357b23ea61236d43b6c4a5.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/97e1ec9b22357b23ea61236d43b6c4a5.txt new file mode 100644 index 0000000..ecbc05d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/97e1ec9b22357b23ea61236d43b6c4a5.txt @@ -0,0 +1,5 @@ +0 0.34011627906976744 0.5625 0.20348837209302326 0.15625 +0 0.8372093023255813 0.7317708333333333 0.20348837209302326 0.15625 +0 0.7558139534883721 0.2265625 0.20348837209302326 0.15625 +0 0.4069767441860465 0.3020833333333333 0.20348837209302326 0.15625 +0 0.5523255813953488 0.7890625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/99098dc4e3250e6b858211bf756805bd.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/99098dc4e3250e6b858211bf756805bd.txt new file mode 100644 index 0000000..d1fb11e --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/99098dc4e3250e6b858211bf756805bd.txt @@ -0,0 +1,5 @@ +0 0.7238372093023255 0.7369791666666666 0.20348837209302326 0.15625 +0 0.7732558139534884 0.2864583333333333 0.20348837209302326 0.15625 +0 0.18313953488372092 0.40885416666666663 0.20348837209302326 0.15625 +0 0.1569767441860465 0.7239583333333333 0.20348837209302326 0.15625 +0 0.563953488372093 0.5286458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9937c9a1cd35f0a189489e1ba3e1ee6e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9937c9a1cd35f0a189489e1ba3e1ee6e.txt new file mode 100644 index 0000000..b7e320a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9937c9a1cd35f0a189489e1ba3e1ee6e.txt @@ -0,0 +1,5 @@ +0 0.7441860465116279 0.7213541666666666 0.20348837209302326 0.15625 +0 0.8401162790697674 0.296875 0.20348837209302326 0.15625 +0 0.29941860465116277 0.31510416666666663 0.20348837209302326 0.15625 +0 0.2819767441860465 0.6302083333333333 0.20348837209302326 0.15625 +0 0.18604651162790697 0.09895833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/996ea9758e9184460656293299f4fc5f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/996ea9758e9184460656293299f4fc5f.txt new file mode 100644 index 0000000..e5fc1dd --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/996ea9758e9184460656293299f4fc5f.txt @@ -0,0 +1,3 @@ +0 0.5348837209302325 0.71875 0.20348837209302326 0.15625 +0 0.4215116279069767 0.26041666666666663 0.20348837209302326 0.15625 +0 0.40988372093023256 0.4765625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/99b3a193d98cedc339cf03ed0c89ed4e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/99b3a193d98cedc339cf03ed0c89ed4e.txt new file mode 100644 index 0000000..8be9507 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/99b3a193d98cedc339cf03ed0c89ed4e.txt @@ -0,0 +1,4 @@ +0 0.811046511627907 0.1484375 0.20348837209302326 0.15625 +0 0.43023255813953487 0.4296875 0.20348837209302326 0.15625 +0 0.502906976744186 0.7395833333333333 0.20348837209302326 0.15625 +0 0.8255813953488372 0.5807291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9a17dca9a159b52f6058c4b8b3758263.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9a17dca9a159b52f6058c4b8b3758263.txt new file mode 100644 index 0000000..25663d5 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9a17dca9a159b52f6058c4b8b3758263.txt @@ -0,0 +1,3 @@ +0 0.8284883720930233 0.16145833333333331 0.20348837209302326 0.15625 +0 0.26744186046511625 0.12760416666666666 0.20348837209302326 0.15625 +0 0.6395348837209303 0.7942708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9ade086496ac44efdbdbdf3345995b0d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9ade086496ac44efdbdbdf3345995b0d.txt new file mode 100644 index 0000000..91c8a24 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9ade086496ac44efdbdbdf3345995b0d.txt @@ -0,0 +1,3 @@ +0 0.26744186046511625 0.30729166666666663 0.20348837209302326 0.15625 +0 0.5581395348837209 0.15625 0.20348837209302326 0.15625 +0 0.18023255813953487 0.765625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9af82de23dc4be3c15423a1f3c3a4468.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9af82de23dc4be3c15423a1f3c3a4468.txt new file mode 100644 index 0000000..4c43453 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9af82de23dc4be3c15423a1f3c3a4468.txt @@ -0,0 +1,4 @@ +0 0.561046511627907 0.31510416666666663 0.20348837209302326 0.15625 +0 0.8662790697674418 0.53125 0.20348837209302326 0.15625 +0 0.3895348837209302 0.578125 0.20348837209302326 0.15625 +0 0.125 0.21354166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b09d046433f03f50defda54e17a33ec.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b09d046433f03f50defda54e17a33ec.txt new file mode 100644 index 0000000..9f583e2 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b09d046433f03f50defda54e17a33ec.txt @@ -0,0 +1,4 @@ +0 0.7093023255813954 0.14322916666666666 0.20348837209302326 0.15625 +0 0.7906976744186046 0.5286458333333333 0.20348837209302326 0.15625 +0 0.3953488372093023 0.3255208333333333 0.20348837209302326 0.15625 +0 0.11627906976744186 0.765625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b5ace4527677b30a2ee7fe026991945.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b5ace4527677b30a2ee7fe026991945.txt new file mode 100644 index 0000000..7b6ecd6 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b5ace4527677b30a2ee7fe026991945.txt @@ -0,0 +1,4 @@ +0 0.2063953488372093 0.44791666666666663 0.20348837209302326 0.15625 +0 0.7936046511627907 0.3671875 0.20348837209302326 0.15625 +0 0.5901162790697674 0.7708333333333333 0.20348837209302326 0.15625 +0 0.2645348837209302 0.18489583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b716ca22bf76c39ca2102792f0614e9.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b716ca22bf76c39ca2102792f0614e9.txt new file mode 100644 index 0000000..d216976 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b716ca22bf76c39ca2102792f0614e9.txt @@ -0,0 +1,3 @@ +0 0.6569767441860465 0.296875 0.20348837209302326 0.15625 +0 0.8372093023255813 0.6640625 0.20348837209302326 0.15625 +0 0.5203488372093024 0.703125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b9428a20c87ccf17df3d1751b820344.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b9428a20c87ccf17df3d1751b820344.txt new file mode 100644 index 0000000..5ee11e1 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b9428a20c87ccf17df3d1751b820344.txt @@ -0,0 +1,4 @@ +0 0.311046511627907 0.5416666666666666 0.20348837209302326 0.15625 +0 0.6191860465116279 0.6875 0.20348837209302326 0.15625 +0 0.7906976744186046 0.1640625 0.20348837209302326 0.15625 +0 0.3866279069767442 0.17447916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b9e6a1b9082f4f9a7d5c745f84f497d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b9e6a1b9082f4f9a7d5c745f84f497d.txt new file mode 100644 index 0000000..670b7df --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9b9e6a1b9082f4f9a7d5c745f84f497d.txt @@ -0,0 +1,3 @@ +0 0.752906976744186 0.15364583333333331 0.20348837209302326 0.15625 +0 0.313953488372093 0.5963541666666666 0.20348837209302326 0.15625 +0 0.42441860465116277 0.3645833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9ba634bd945795ed8a76acdecfde49a4.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9ba634bd945795ed8a76acdecfde49a4.txt new file mode 100644 index 0000000..e8d7618 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9ba634bd945795ed8a76acdecfde49a4.txt @@ -0,0 +1,4 @@ +0 0.4622093023255814 0.4270833333333333 0.20348837209302326 0.15625 +0 0.18604651162790697 0.7552083333333333 0.20348837209302326 0.15625 +0 0.7674418604651163 0.41666666666666663 0.20348837209302326 0.15625 +0 0.30523255813953487 0.15104166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9c0f0a0ce42d8287c9f48a6cc7c71c1e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9c0f0a0ce42d8287c9f48a6cc7c71c1e.txt new file mode 100644 index 0000000..a03e2fc --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9c0f0a0ce42d8287c9f48a6cc7c71c1e.txt @@ -0,0 +1,4 @@ +0 0.7441860465116279 0.140625 0.20348837209302326 0.15625 +0 0.12790697674418605 0.5364583333333333 0.20348837209302326 0.15625 +0 0.4331395348837209 0.296875 0.20348837209302326 0.15625 +0 0.6453488372093024 0.6328125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9c5fbc59328f51d035932d0d1f542487.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9c5fbc59328f51d035932d0d1f542487.txt new file mode 100644 index 0000000..e2a0c4e --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9c5fbc59328f51d035932d0d1f542487.txt @@ -0,0 +1,4 @@ +0 0.6424418604651163 0.6744791666666666 0.20348837209302326 0.15625 +0 0.7936046511627907 0.11197916666666666 0.20348837209302326 0.15625 +0 0.34011627906976744 0.6067708333333333 0.20348837209302326 0.15625 +0 0.5261627906976745 0.14583333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9c9e4e374863bf04076ae1b6eaa5eac2.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9c9e4e374863bf04076ae1b6eaa5eac2.txt new file mode 100644 index 0000000..c3f2257 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9c9e4e374863bf04076ae1b6eaa5eac2.txt @@ -0,0 +1,4 @@ +0 0.25 0.5729166666666666 0.20348837209302326 0.15625 +0 0.38372093023255816 0.2942708333333333 0.20348837209302326 0.15625 +0 0.8546511627906976 0.19010416666666666 0.20348837209302326 0.15625 +0 0.7994186046511628 0.6744791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9d11ef7100b8416d96188e22f5171adf.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9d11ef7100b8416d96188e22f5171adf.txt new file mode 100644 index 0000000..6f1db47 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9d11ef7100b8416d96188e22f5171adf.txt @@ -0,0 +1,3 @@ +0 0.627906976744186 0.5729166666666666 0.20348837209302326 0.15625 +0 0.6453488372093024 0.2890625 0.20348837209302326 0.15625 +0 0.17732558139534885 0.375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9debdbee212d6c3067cf2cdaf270e3b3.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9debdbee212d6c3067cf2cdaf270e3b3.txt new file mode 100644 index 0000000..276ea60 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9debdbee212d6c3067cf2cdaf270e3b3.txt @@ -0,0 +1,4 @@ +0 0.311046511627907 0.7786458333333333 0.20348837209302326 0.15625 +0 0.8255813953488372 0.140625 0.20348837209302326 0.15625 +0 0.17151162790697674 0.5026041666666666 0.20348837209302326 0.15625 +0 0.6773255813953488 0.4140625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9e1e456a238764f55631e71db54e9e9e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9e1e456a238764f55631e71db54e9e9e.txt new file mode 100644 index 0000000..c42bab7 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9e1e456a238764f55631e71db54e9e9e.txt @@ -0,0 +1,4 @@ +0 0.8633720930232558 0.796875 0.20348837209302326 0.15625 +0 0.561046511627907 0.375 0.20348837209302326 0.15625 +0 0.8546511627906976 0.1953125 0.20348837209302326 0.15625 +0 0.8575581395348837 0.5703125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9eec1c737984af1556c71586c071121d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9eec1c737984af1556c71586c071121d.txt new file mode 100644 index 0000000..a5d7514 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9eec1c737984af1556c71586c071121d.txt @@ -0,0 +1,4 @@ +0 0.18313953488372092 0.6302083333333333 0.20348837209302326 0.15625 +0 0.8546511627906976 0.703125 0.20348837209302326 0.15625 +0 0.502906976744186 0.15885416666666666 0.20348837209302326 0.15625 +0 0.7122093023255814 0.44010416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9f6629f1db673de2d304b3fcc2c48ea2.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9f6629f1db673de2d304b3fcc2c48ea2.txt new file mode 100644 index 0000000..46fa5ba --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9f6629f1db673de2d304b3fcc2c48ea2.txt @@ -0,0 +1,4 @@ +0 0.438953488372093 0.671875 0.20348837209302326 0.15625 +0 0.6831395348837209 0.2109375 0.20348837209302326 0.15625 +0 0.2063953488372093 0.33854166666666663 0.20348837209302326 0.15625 +0 0.8081395348837209 0.5078125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9fcc16f1a59fc5dc8061be9211d1406f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9fcc16f1a59fc5dc8061be9211d1406f.txt new file mode 100644 index 0000000..7908b9c --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/9fcc16f1a59fc5dc8061be9211d1406f.txt @@ -0,0 +1,3 @@ +0 0.14825581395348836 0.5338541666666666 0.20348837209302326 0.15625 +0 0.5261627906976745 0.234375 0.20348837209302326 0.15625 +0 0.7936046511627907 0.6484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a11fd151b48136b97839d38f924a2341.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a11fd151b48136b97839d38f924a2341.txt new file mode 100644 index 0000000..3fc3f80 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a11fd151b48136b97839d38f924a2341.txt @@ -0,0 +1,4 @@ +0 0.5087209302325582 0.6953125 0.20348837209302326 0.15625 +0 0.16279069767441862 0.7578125 0.20348837209302326 0.15625 +0 0.3633720930232558 0.4348958333333333 0.20348837209302326 0.15625 +0 0.8459302325581395 0.09635416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a1f23934299c5079c5733105072d1f93.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a1f23934299c5079c5733105072d1f93.txt new file mode 100644 index 0000000..1017d85 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a1f23934299c5079c5733105072d1f93.txt @@ -0,0 +1,3 @@ +0 0.5174418604651163 0.7265625 0.20348837209302326 0.15625 +0 0.7936046511627907 0.3020833333333333 0.20348837209302326 0.15625 +0 0.11337209302325581 0.2708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a2b7e80c538e0511d89273aeed25a92f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a2b7e80c538e0511d89273aeed25a92f.txt new file mode 100644 index 0000000..d9b01c0 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a2b7e80c538e0511d89273aeed25a92f.txt @@ -0,0 +1,5 @@ +0 0.5436046511627907 0.140625 0.20348837209302326 0.15625 +0 0.7645348837209303 0.7708333333333333 0.20348837209302326 0.15625 +0 0.7587209302325582 0.4427083333333333 0.20348837209302326 0.15625 +0 0.20348837209302326 0.53125 0.20348837209302326 0.15625 +0 0.2703488372093023 0.7760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a2cc250a546ae544fb4695e2b8077ad1.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a2cc250a546ae544fb4695e2b8077ad1.txt new file mode 100644 index 0000000..e2f285c --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a2cc250a546ae544fb4695e2b8077ad1.txt @@ -0,0 +1,3 @@ +0 0.688953488372093 0.20833333333333331 0.20348837209302326 0.15625 +0 0.5784883720930233 0.5390625 0.20348837209302326 0.15625 +0 0.5406976744186046 0.7578125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a2f87d16679f59a1686cd8eeeb1ca63f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a2f87d16679f59a1686cd8eeeb1ca63f.txt new file mode 100644 index 0000000..c7a29f2 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a2f87d16679f59a1686cd8eeeb1ca63f.txt @@ -0,0 +1,4 @@ +0 0.1308139534883721 0.59375 0.20348837209302326 0.15625 +0 0.5116279069767442 0.3255208333333333 0.20348837209302326 0.15625 +0 0.7093023255813954 0.7421875 0.20348837209302326 0.15625 +0 0.3168604651162791 0.09895833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a3b3fcd204c9ef0ce797fe25747b85d3.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a3b3fcd204c9ef0ce797fe25747b85d3.txt new file mode 100644 index 0000000..9c200eb --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a3b3fcd204c9ef0ce797fe25747b85d3.txt @@ -0,0 +1,4 @@ +0 0.4563953488372093 0.2552083333333333 0.20348837209302326 0.15625 +0 0.8575581395348837 0.5 0.20348837209302326 0.15625 +0 0.1511627906976744 0.3723958333333333 0.20348837209302326 0.15625 +0 0.48546511627906974 0.734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a3f1af91c9902e7bf1ff0648f38652be.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a3f1af91c9902e7bf1ff0648f38652be.txt new file mode 100644 index 0000000..69aff37 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a3f1af91c9902e7bf1ff0648f38652be.txt @@ -0,0 +1,4 @@ +0 0.6802325581395349 0.265625 0.20348837209302326 0.15625 +0 0.32558139534883723 0.7213541666666666 0.20348837209302326 0.15625 +0 0.7063953488372093 0.7864583333333333 0.20348837209302326 0.15625 +0 0.18895348837209303 0.34635416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a42c96155f0b834b4d6e1a3eee789390.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a42c96155f0b834b4d6e1a3eee789390.txt new file mode 100644 index 0000000..24a8522 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a42c96155f0b834b4d6e1a3eee789390.txt @@ -0,0 +1,3 @@ +0 0.4476744186046512 0.6145833333333333 0.20348837209302326 0.15625 +0 0.8052325581395349 0.796875 0.20348837209302326 0.15625 +0 0.5872093023255814 0.3203125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a45c95d0bade2be240feeae148f17274.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a45c95d0bade2be240feeae148f17274.txt new file mode 100644 index 0000000..89e7f69 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a45c95d0bade2be240feeae148f17274.txt @@ -0,0 +1,5 @@ +0 0.2180232558139535 0.5598958333333333 0.20348837209302326 0.15625 +0 0.4331395348837209 0.1796875 0.20348837209302326 0.15625 +0 0.5843023255813954 0.5963541666666666 0.20348837209302326 0.15625 +0 0.747093023255814 0.26041666666666663 0.20348837209302326 0.15625 +0 0.15988372093023256 0.23697916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a49f45d1fd6b6586eb46970b989c4dc7.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a49f45d1fd6b6586eb46970b989c4dc7.txt new file mode 100644 index 0000000..f9965ed --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a49f45d1fd6b6586eb46970b989c4dc7.txt @@ -0,0 +1,3 @@ +0 0.5319767441860465 0.6640625 0.20348837209302326 0.15625 +0 0.14534883720930233 0.53125 0.20348837209302326 0.15625 +0 0.7790697674418604 0.234375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a4c1525c8db3dddd50e0092dc36862ac.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a4c1525c8db3dddd50e0092dc36862ac.txt new file mode 100644 index 0000000..260231d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a4c1525c8db3dddd50e0092dc36862ac.txt @@ -0,0 +1,4 @@ +0 0.5843023255813954 0.4765625 0.20348837209302326 0.15625 +0 0.16279069767441862 0.5546875 0.20348837209302326 0.15625 +0 0.3895348837209302 0.19791666666666666 0.20348837209302326 0.15625 +0 0.7965116279069767 0.19791666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a4cbaa33dc42283d5371c48b6eb17cf5.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a4cbaa33dc42283d5371c48b6eb17cf5.txt new file mode 100644 index 0000000..e0ccfb2 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a4cbaa33dc42283d5371c48b6eb17cf5.txt @@ -0,0 +1,4 @@ +0 0.3633720930232558 0.7395833333333333 0.20348837209302326 0.15625 +0 0.5348837209302325 0.140625 0.20348837209302326 0.15625 +0 0.8430232558139534 0.29166666666666663 0.20348837209302326 0.15625 +0 0.4796511627906977 0.453125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a4f4330957dfac60def39e08d8c69ca9.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a4f4330957dfac60def39e08d8c69ca9.txt new file mode 100644 index 0000000..3bdf6dc --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a4f4330957dfac60def39e08d8c69ca9.txt @@ -0,0 +1,5 @@ +0 0.1511627906976744 0.6223958333333333 0.20348837209302326 0.15625 +0 0.7267441860465116 0.27604166666666663 0.20348837209302326 0.15625 +0 0.8081395348837209 0.5651041666666666 0.20348837209302326 0.15625 +0 0.12790697674418605 0.15364583333333331 0.20348837209302326 0.15625 +0 0.26744186046511625 0.3828125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a52f23dc0c83fd6f1b9e7ed7279bb9e3.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a52f23dc0c83fd6f1b9e7ed7279bb9e3.txt new file mode 100644 index 0000000..882bb2d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a52f23dc0c83fd6f1b9e7ed7279bb9e3.txt @@ -0,0 +1,4 @@ +0 0.8662790697674418 0.12239583333333333 0.20348837209302326 0.15625 +0 0.5465116279069767 0.3255208333333333 0.20348837209302326 0.15625 +0 0.8168604651162791 0.7916666666666666 0.20348837209302326 0.15625 +0 0.5058139534883721 0.7526041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a584494c3ac50081b2f9574b18ba42fb.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a584494c3ac50081b2f9574b18ba42fb.txt new file mode 100644 index 0000000..bbcbead --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a584494c3ac50081b2f9574b18ba42fb.txt @@ -0,0 +1,4 @@ +0 0.6627906976744186 0.375 0.20348837209302326 0.15625 +0 0.7877906976744186 0.6666666666666666 0.20348837209302326 0.15625 +0 0.8197674418604651 0.11458333333333333 0.20348837209302326 0.15625 +0 0.46511627906976744 0.5989583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a59cf66b62ea8d403f095bae377a1e82.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a59cf66b62ea8d403f095bae377a1e82.txt new file mode 100644 index 0000000..d96d4b0 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a59cf66b62ea8d403f095bae377a1e82.txt @@ -0,0 +1,5 @@ +0 0.7994186046511628 0.7708333333333333 0.20348837209302326 0.15625 +0 0.32558139534883723 0.7682291666666666 0.20348837209302326 0.15625 +0 0.17732558139534885 0.4114583333333333 0.20348837209302326 0.15625 +0 0.5232558139534884 0.40625 0.20348837209302326 0.15625 +0 0.46511627906976744 0.1171875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a5cfeb3eaa805540f31726104d5037c9.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a5cfeb3eaa805540f31726104d5037c9.txt new file mode 100644 index 0000000..01077f4 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a5cfeb3eaa805540f31726104d5037c9.txt @@ -0,0 +1,4 @@ +0 0.23255813953488372 0.609375 0.20348837209302326 0.15625 +0 0.6046511627906976 0.3020833333333333 0.20348837209302326 0.15625 +0 0.7441860465116279 0.6015625 0.20348837209302326 0.15625 +0 0.1947674418604651 0.10416666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a8a56b91eea0f9a8c480f81e0960a9f0.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a8a56b91eea0f9a8c480f81e0960a9f0.txt new file mode 100644 index 0000000..2baa73b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a8a56b91eea0f9a8c480f81e0960a9f0.txt @@ -0,0 +1,4 @@ +0 0.747093023255814 0.5026041666666666 0.20348837209302326 0.15625 +0 0.34011627906976744 0.21614583333333331 0.20348837209302326 0.15625 +0 0.3023255813953488 0.44791666666666663 0.20348837209302326 0.15625 +0 0.6831395348837209 0.7526041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a917d45a781de755ce4c7f727ecb663a.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a917d45a781de755ce4c7f727ecb663a.txt new file mode 100644 index 0000000..86871e7 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a917d45a781de755ce4c7f727ecb663a.txt @@ -0,0 +1,4 @@ +0 0.6627906976744186 0.15885416666666666 0.20348837209302326 0.15625 +0 0.20930232558139533 0.15104166666666666 0.20348837209302326 0.15625 +0 0.2877906976744186 0.5963541666666666 0.20348837209302326 0.15625 +0 0.747093023255814 0.6901041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a925e5a0d4a2ad37c36a0cdeae5f4a05.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a925e5a0d4a2ad37c36a0cdeae5f4a05.txt new file mode 100644 index 0000000..514e6ba --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a925e5a0d4a2ad37c36a0cdeae5f4a05.txt @@ -0,0 +1,4 @@ +0 0.7238372093023255 0.23958333333333331 0.20348837209302326 0.15625 +0 0.686046511627907 0.6041666666666666 0.20348837209302326 0.15625 +0 0.25 0.7395833333333333 0.20348837209302326 0.15625 +0 0.36627906976744184 0.10677083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a93bc75d3f60badf7765a69654aea189.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a93bc75d3f60badf7765a69654aea189.txt new file mode 100644 index 0000000..7741aa6 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a93bc75d3f60badf7765a69654aea189.txt @@ -0,0 +1,3 @@ +0 0.2936046511627907 0.6770833333333333 0.20348837209302326 0.15625 +0 0.7412790697674418 0.6770833333333333 0.20348837209302326 0.15625 +0 0.6395348837209303 0.15885416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a955a755f40b0cda7492c7aa4fff2b52.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a955a755f40b0cda7492c7aa4fff2b52.txt new file mode 100644 index 0000000..bc9d4b1 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/a955a755f40b0cda7492c7aa4fff2b52.txt @@ -0,0 +1,4 @@ +0 0.4825581395348837 0.5286458333333333 0.20348837209302326 0.15625 +0 0.19186046511627908 0.37760416666666663 0.20348837209302326 0.15625 +0 0.6104651162790697 0.2265625 0.20348837209302326 0.15625 +0 0.8052325581395349 0.53125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/aaaf334aeff84ea148a1469d42c6fc82.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/aaaf334aeff84ea148a1469d42c6fc82.txt new file mode 100644 index 0000000..8cbc8fc --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/aaaf334aeff84ea148a1469d42c6fc82.txt @@ -0,0 +1,3 @@ +0 0.6104651162790697 0.6067708333333333 0.20348837209302326 0.15625 +0 0.4273255813953488 0.359375 0.20348837209302326 0.15625 +0 0.17151162790697674 0.5963541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ab3afd0a8254672d351f549a76f83c98.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ab3afd0a8254672d351f549a76f83c98.txt new file mode 100644 index 0000000..7fe2193 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ab3afd0a8254672d351f549a76f83c98.txt @@ -0,0 +1,4 @@ +0 0.5813953488372093 0.3645833333333333 0.20348837209302326 0.15625 +0 0.4796511627906977 0.7786458333333333 0.20348837209302326 0.15625 +0 0.14244186046511628 0.32291666666666663 0.20348837209302326 0.15625 +0 0.6627906976744186 0.12760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/acecd72ff9410fb27b05718d047d24dc.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/acecd72ff9410fb27b05718d047d24dc.txt new file mode 100644 index 0000000..c9739a1 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/acecd72ff9410fb27b05718d047d24dc.txt @@ -0,0 +1,4 @@ +0 0.26744186046511625 0.5 0.20348837209302326 0.15625 +0 0.7965116279069767 0.3567708333333333 0.20348837209302326 0.15625 +0 0.4331395348837209 0.7864583333333333 0.20348837209302326 0.15625 +0 0.14244186046511628 0.1484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ad54ac1ce876f93cf5c813ec262845e2.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ad54ac1ce876f93cf5c813ec262845e2.txt new file mode 100644 index 0000000..e636067 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ad54ac1ce876f93cf5c813ec262845e2.txt @@ -0,0 +1,4 @@ +0 0.7790697674418604 0.18489583333333331 0.20348837209302326 0.15625 +0 0.7296511627906976 0.5755208333333333 0.20348837209302326 0.15625 +0 0.43023255813953487 0.40885416666666663 0.20348837209302326 0.15625 +0 0.11918604651162791 0.4348958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ad67a4d7d31da7c7e823b4c05d64270f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ad67a4d7d31da7c7e823b4c05d64270f.txt new file mode 100644 index 0000000..037c653 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ad67a4d7d31da7c7e823b4c05d64270f.txt @@ -0,0 +1,3 @@ +0 0.12790697674418605 0.26041666666666663 0.20348837209302326 0.15625 +0 0.7703488372093024 0.4765625 0.20348837209302326 0.15625 +0 0.7383720930232558 0.12239583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/add3c7e8571233b17df92912514e36ad.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/add3c7e8571233b17df92912514e36ad.txt new file mode 100644 index 0000000..ca72c3b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/add3c7e8571233b17df92912514e36ad.txt @@ -0,0 +1,4 @@ +0 0.7848837209302325 0.6770833333333333 0.20348837209302326 0.15625 +0 0.3633720930232558 0.4348958333333333 0.20348837209302326 0.15625 +0 0.747093023255814 0.3567708333333333 0.20348837209302326 0.15625 +0 0.5523255813953488 0.1015625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ae5b492f03929fd6b81ebee9b2733e2a.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ae5b492f03929fd6b81ebee9b2733e2a.txt new file mode 100644 index 0000000..9c42be4 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ae5b492f03929fd6b81ebee9b2733e2a.txt @@ -0,0 +1,4 @@ +0 0.5058139534883721 0.6041666666666666 0.20348837209302326 0.15625 +0 0.5872093023255814 0.3828125 0.20348837209302326 0.15625 +0 0.2063953488372093 0.5885416666666666 0.20348837209302326 0.15625 +0 0.23255813953488372 0.3489583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ae99c7c82d9ac7a6355323ae7a0a95c0.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ae99c7c82d9ac7a6355323ae7a0a95c0.txt new file mode 100644 index 0000000..7df09b6 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ae99c7c82d9ac7a6355323ae7a0a95c0.txt @@ -0,0 +1,3 @@ +0 0.5901162790697674 0.09895833333333333 0.20348837209302326 0.15625 +0 0.5465116279069767 0.5651041666666666 0.20348837209302326 0.15625 +0 0.2616279069767442 0.6328125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/aeb0dab30ccf763d9999214f196e1bed.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/aeb0dab30ccf763d9999214f196e1bed.txt new file mode 100644 index 0000000..435e60b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/aeb0dab30ccf763d9999214f196e1bed.txt @@ -0,0 +1,5 @@ +0 0.3575581395348837 0.6588541666666666 0.20348837209302326 0.15625 +0 0.811046511627907 0.29166666666666663 0.20348837209302326 0.15625 +0 0.13662790697674418 0.21875 0.20348837209302326 0.15625 +0 0.44476744186046513 0.10677083333333333 0.20348837209302326 0.15625 +0 0.6715116279069767 0.6901041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/aef6711358ed63fb79fccd99e71fb50e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/aef6711358ed63fb79fccd99e71fb50e.txt new file mode 100644 index 0000000..a35de95 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/aef6711358ed63fb79fccd99e71fb50e.txt @@ -0,0 +1,5 @@ +0 0.7616279069767442 0.14322916666666666 0.20348837209302326 0.15625 +0 0.41860465116279066 0.6171875 0.20348837209302326 0.15625 +0 0.4127906976744186 0.17708333333333331 0.20348837209302326 0.15625 +0 0.14825581395348836 0.34375 0.20348837209302326 0.15625 +0 0.7645348837209303 0.6302083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af0b4beba3b6b475e18f735799b52cb3.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af0b4beba3b6b475e18f735799b52cb3.txt new file mode 100644 index 0000000..e4a9df9 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af0b4beba3b6b475e18f735799b52cb3.txt @@ -0,0 +1,5 @@ +0 0.23837209302325582 0.41666666666666663 0.20348837209302326 0.15625 +0 0.7209302325581395 0.29166666666666663 0.20348837209302326 0.15625 +0 0.6337209302325582 0.7447916666666666 0.20348837209302326 0.15625 +0 0.19186046511627908 0.7005208333333333 0.20348837209302326 0.15625 +0 0.8052325581395349 0.5078125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af214b3b06b5463cc90434a96bbafd51.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af214b3b06b5463cc90434a96bbafd51.txt new file mode 100644 index 0000000..bada9f2 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af214b3b06b5463cc90434a96bbafd51.txt @@ -0,0 +1,4 @@ +0 0.7063953488372093 0.1640625 0.20348837209302326 0.15625 +0 0.6424418604651163 0.5859375 0.20348837209302326 0.15625 +0 0.2645348837209302 0.3255208333333333 0.20348837209302326 0.15625 +0 0.2965116279069767 0.6822916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af38ad387f7dc992568a3fcb44a072e3.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af38ad387f7dc992568a3fcb44a072e3.txt new file mode 100644 index 0000000..14feb40 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af38ad387f7dc992568a3fcb44a072e3.txt @@ -0,0 +1,4 @@ +0 0.4215116279069767 0.6067708333333333 0.20348837209302326 0.15625 +0 0.4622093023255814 0.21875 0.20348837209302326 0.15625 +0 0.7674418604651163 0.3489583333333333 0.20348837209302326 0.15625 +0 0.14534883720930233 0.3880208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af52415030cfdb1e111f787bb8cb99e2.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af52415030cfdb1e111f787bb8cb99e2.txt new file mode 100644 index 0000000..f230464 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af52415030cfdb1e111f787bb8cb99e2.txt @@ -0,0 +1,3 @@ +0 0.2616279069767442 0.234375 0.20348837209302326 0.15625 +0 0.8226744186046512 0.6953125 0.20348837209302326 0.15625 +0 0.18023255813953487 0.7708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af85198787c82b979daf1a9fdf9596cf.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af85198787c82b979daf1a9fdf9596cf.txt new file mode 100644 index 0000000..cd5bfdf --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/af85198787c82b979daf1a9fdf9596cf.txt @@ -0,0 +1,4 @@ +0 0.47674418604651164 0.7213541666666666 0.20348837209302326 0.15625 +0 0.29941860465116277 0.25260416666666663 0.20348837209302326 0.15625 +0 0.8023255813953488 0.5026041666666666 0.20348837209302326 0.15625 +0 0.11627906976744186 0.5026041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b019882b412128a36502c22a00be37b6.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b019882b412128a36502c22a00be37b6.txt new file mode 100644 index 0000000..e0f7336 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b019882b412128a36502c22a00be37b6.txt @@ -0,0 +1,4 @@ +0 0.5930232558139534 0.6484375 0.20348837209302326 0.15625 +0 0.23546511627906977 0.44791666666666663 0.20348837209302326 0.15625 +0 0.20348837209302326 0.11458333333333333 0.20348837209302326 0.15625 +0 0.14244186046511628 0.7473958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b02782fbd52d87eab17fe5c24b326e92.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b02782fbd52d87eab17fe5c24b326e92.txt new file mode 100644 index 0000000..081f50f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b02782fbd52d87eab17fe5c24b326e92.txt @@ -0,0 +1,4 @@ +0 0.125 0.6953125 0.20348837209302326 0.15625 +0 0.8284883720930233 0.40625 0.20348837209302326 0.15625 +0 0.16279069767441862 0.2708333333333333 0.20348837209302326 0.15625 +0 0.5406976744186046 0.6796875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b0414baa9b45f1df4a49b0ba95ad0678.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b0414baa9b45f1df4a49b0ba95ad0678.txt new file mode 100644 index 0000000..b81f3a3 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b0414baa9b45f1df4a49b0ba95ad0678.txt @@ -0,0 +1,5 @@ +0 0.7674418604651163 0.734375 0.20348837209302326 0.15625 +0 0.2819767441860465 0.5755208333333333 0.20348837209302326 0.15625 +0 0.8517441860465116 0.109375 0.20348837209302326 0.15625 +0 0.747093023255814 0.5 0.20348837209302326 0.15625 +0 0.3808139534883721 0.30729166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b0d353a2cd82f830c13b5258a584fda2.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b0d353a2cd82f830c13b5258a584fda2.txt new file mode 100644 index 0000000..1c726e8 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b0d353a2cd82f830c13b5258a584fda2.txt @@ -0,0 +1,5 @@ +0 0.8488372093023255 0.14322916666666666 0.20348837209302326 0.15625 +0 0.11918604651162791 0.3098958333333333 0.20348837209302326 0.15625 +0 0.5668604651162791 0.16145833333333331 0.20348837209302326 0.15625 +0 0.1308139534883721 0.5234375 0.20348837209302326 0.15625 +0 0.8372093023255813 0.6302083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b1b1c0fb595245aca359befbc1f13d65.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b1b1c0fb595245aca359befbc1f13d65.txt new file mode 100644 index 0000000..0735ba9 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b1b1c0fb595245aca359befbc1f13d65.txt @@ -0,0 +1,4 @@ +0 0.1744186046511628 0.5729166666666666 0.20348837209302326 0.15625 +0 0.622093023255814 0.3333333333333333 0.20348837209302326 0.15625 +0 0.25 0.27604166666666663 0.20348837209302326 0.15625 +0 0.5290697674418604 0.65625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b438e477a38a97ceb0d5901bf567c5cb.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b438e477a38a97ceb0d5901bf567c5cb.txt new file mode 100644 index 0000000..bfbc899 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b438e477a38a97ceb0d5901bf567c5cb.txt @@ -0,0 +1,4 @@ +0 0.8255813953488372 0.671875 0.20348837209302326 0.15625 +0 0.22965116279069767 0.47916666666666663 0.20348837209302326 0.15625 +0 0.5436046511627907 0.2734375 0.20348837209302326 0.15625 +0 0.33430232558139533 0.71875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b46052dfeffd46059f763fc055048757.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b46052dfeffd46059f763fc055048757.txt new file mode 100644 index 0000000..6f6539c --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b46052dfeffd46059f763fc055048757.txt @@ -0,0 +1,5 @@ +0 0.5668604651162791 0.23177083333333331 0.20348837209302326 0.15625 +0 0.747093023255814 0.4817708333333333 0.20348837209302326 0.15625 +0 0.16279069767441862 0.4114583333333333 0.20348837209302326 0.15625 +0 0.48546511627906974 0.46875 0.20348837209302326 0.15625 +0 0.7558139534883721 0.7473958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b4a91875a7d91bb5712fdc7ab460356e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b4a91875a7d91bb5712fdc7ab460356e.txt new file mode 100644 index 0000000..9d05437 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b4a91875a7d91bb5712fdc7ab460356e.txt @@ -0,0 +1,5 @@ +0 0.42441860465116277 0.33854166666666663 0.20348837209302326 0.15625 +0 0.29069767441860467 0.6640625 0.20348837209302326 0.15625 +0 0.7877906976744186 0.6067708333333333 0.20348837209302326 0.15625 +0 0.8604651162790697 0.14322916666666666 0.20348837209302326 0.15625 +0 0.4011627906976744 0.09635416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b4b7a065dc0d46c8524f44134b43df90.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b4b7a065dc0d46c8524f44134b43df90.txt new file mode 100644 index 0000000..96e360a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b4b7a065dc0d46c8524f44134b43df90.txt @@ -0,0 +1,5 @@ +0 0.2005813953488372 0.28385416666666663 0.20348837209302326 0.15625 +0 0.5843023255813954 0.125 0.20348837209302326 0.15625 +0 0.6162790697674418 0.4296875 0.20348837209302326 0.15625 +0 0.7238372093023255 0.7630208333333333 0.20348837209302326 0.15625 +0 0.14534883720930233 0.671875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b61570abaf72fc4e5b81089f5b08ccdf.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b61570abaf72fc4e5b81089f5b08ccdf.txt new file mode 100644 index 0000000..cd892d1 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b61570abaf72fc4e5b81089f5b08ccdf.txt @@ -0,0 +1,3 @@ +0 0.3081395348837209 0.5078125 0.20348837209302326 0.15625 +0 0.4505813953488372 0.15104166666666666 0.20348837209302326 0.15625 +0 0.3575581395348837 0.7291666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b6fa0e82f5ddf3937f7741872d5aab29.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b6fa0e82f5ddf3937f7741872d5aab29.txt new file mode 100644 index 0000000..49388d2 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b6fa0e82f5ddf3937f7741872d5aab29.txt @@ -0,0 +1,5 @@ +0 0.5843023255813954 0.13020833333333331 0.20348837209302326 0.15625 +0 0.19186046511627908 0.4192708333333333 0.20348837209302326 0.15625 +0 0.6366279069767442 0.7213541666666666 0.20348837209302326 0.15625 +0 0.47674418604651164 0.3958333333333333 0.20348837209302326 0.15625 +0 0.16569767441860464 0.6588541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b74470dc7d33f0c5ded118dcd72408dd.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b74470dc7d33f0c5ded118dcd72408dd.txt new file mode 100644 index 0000000..d210510 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b74470dc7d33f0c5ded118dcd72408dd.txt @@ -0,0 +1,2 @@ +0 0.28488372093023256 0.5625 0.20348837209302326 0.15625 +0 0.8226744186046512 0.7161458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b8116e2cc4e7e2a740cc06ed5b3eb64b.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b8116e2cc4e7e2a740cc06ed5b3eb64b.txt new file mode 100644 index 0000000..7bbcec0 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b8116e2cc4e7e2a740cc06ed5b3eb64b.txt @@ -0,0 +1,4 @@ +0 0.8313953488372093 0.5807291666666666 0.20348837209302326 0.15625 +0 0.3953488372093023 0.6432291666666666 0.20348837209302326 0.15625 +0 0.20930232558139533 0.4192708333333333 0.20348837209302326 0.15625 +0 0.5784883720930233 0.17447916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b84dc59a29d1cb0bd465bc7ac9c21963.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b84dc59a29d1cb0bd465bc7ac9c21963.txt new file mode 100644 index 0000000..9d174c5 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b84dc59a29d1cb0bd465bc7ac9c21963.txt @@ -0,0 +1,4 @@ +0 0.47093023255813954 0.10416666666666666 0.20348837209302326 0.15625 +0 0.5813953488372093 0.5729166666666666 0.20348837209302326 0.15625 +0 0.7732558139534884 0.19791666666666666 0.20348837209302326 0.15625 +0 0.4069767441860465 0.3333333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b8d4fc353441b833014d5dfb7360acaa.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b8d4fc353441b833014d5dfb7360acaa.txt new file mode 100644 index 0000000..6f064b2 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b8d4fc353441b833014d5dfb7360acaa.txt @@ -0,0 +1,4 @@ +0 0.7122093023255814 0.453125 0.20348837209302326 0.15625 +0 0.2819767441860465 0.20572916666666666 0.20348837209302326 0.15625 +0 0.21511627906976744 0.5755208333333333 0.20348837209302326 0.15625 +0 0.7732558139534884 0.15625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b932ad094993c20c7907ca8ce19afa68.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b932ad094993c20c7907ca8ce19afa68.txt new file mode 100644 index 0000000..6610d0b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b932ad094993c20c7907ca8ce19afa68.txt @@ -0,0 +1,4 @@ +0 0.8081395348837209 0.5026041666666666 0.20348837209302326 0.15625 +0 0.3430232558139535 0.31510416666666663 0.20348837209302326 0.15625 +0 0.37209302325581395 0.5963541666666666 0.20348837209302326 0.15625 +0 0.688953488372093 0.7916666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b9ab386866cdc3fe74d767f3aecdab33.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b9ab386866cdc3fe74d767f3aecdab33.txt new file mode 100644 index 0000000..c11eb47 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/b9ab386866cdc3fe74d767f3aecdab33.txt @@ -0,0 +1,4 @@ +0 0.41860465116279066 0.6458333333333333 0.20348837209302326 0.15625 +0 0.3226744186046512 0.11458333333333333 0.20348837209302326 0.15625 +0 0.375 0.359375 0.20348837209302326 0.15625 +0 0.7587209302325582 0.6171875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/baf7fffc1651230f1ba31a474abac0e8.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/baf7fffc1651230f1ba31a474abac0e8.txt new file mode 100644 index 0000000..f2c427a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/baf7fffc1651230f1ba31a474abac0e8.txt @@ -0,0 +1,4 @@ +0 0.5494186046511628 0.7864583333333333 0.20348837209302326 0.15625 +0 0.1744186046511628 0.75 0.20348837209302326 0.15625 +0 0.32558139534883723 0.23958333333333331 0.20348837209302326 0.15625 +0 0.7645348837209303 0.4661458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bb86c627bbe6120f82a39eeac0a210c7.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bb86c627bbe6120f82a39eeac0a210c7.txt new file mode 100644 index 0000000..2c9c88f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bb86c627bbe6120f82a39eeac0a210c7.txt @@ -0,0 +1,4 @@ +0 0.47093023255813954 0.47135416666666663 0.20348837209302326 0.15625 +0 0.24709302325581395 0.0859375 0.20348837209302326 0.15625 +0 0.5406976744186046 0.7552083333333333 0.20348837209302326 0.15625 +0 0.5406976744186046 0.19010416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bbca5c142aacd33545651d72c90e4d16.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bbca5c142aacd33545651d72c90e4d16.txt new file mode 100644 index 0000000..3a7a961 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bbca5c142aacd33545651d72c90e4d16.txt @@ -0,0 +1,4 @@ +0 0.5552325581395349 0.375 0.20348837209302326 0.15625 +0 0.7296511627906976 0.6041666666666666 0.20348837209302326 0.15625 +0 0.3430232558139535 0.1328125 0.20348837209302326 0.15625 +0 0.7877906976744186 0.10677083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bc42a65657fbbcab9abf3bbf7c253fb1.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bc42a65657fbbcab9abf3bbf7c253fb1.txt new file mode 100644 index 0000000..eddb57b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bc42a65657fbbcab9abf3bbf7c253fb1.txt @@ -0,0 +1,3 @@ +0 0.4796511627906977 0.078125 0.20348837209302326 0.15625 +0 0.4796511627906977 0.7395833333333333 0.20348837209302326 0.15625 +0 0.28488372093023256 0.4270833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bcb4a9a964f638055196c65f6da6f103.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bcb4a9a964f638055196c65f6da6f103.txt new file mode 100644 index 0000000..916affe --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bcb4a9a964f638055196c65f6da6f103.txt @@ -0,0 +1,2 @@ +0 0.44476744186046513 0.1875 0.20348837209302326 0.15625 +0 0.7703488372093024 0.6458333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bcc20ed95de63717b59927435fbb91b9.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bcc20ed95de63717b59927435fbb91b9.txt new file mode 100644 index 0000000..c68c9bb --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bcc20ed95de63717b59927435fbb91b9.txt @@ -0,0 +1,3 @@ +0 0.311046511627907 0.2265625 0.20348837209302326 0.15625 +0 0.8517441860465116 0.45572916666666663 0.20348837209302326 0.15625 +0 0.34593023255813954 0.5963541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bcde2471baeecec6694f8208c3d97279.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bcde2471baeecec6694f8208c3d97279.txt new file mode 100644 index 0000000..a7def8d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bcde2471baeecec6694f8208c3d97279.txt @@ -0,0 +1,3 @@ +0 0.5843023255813954 0.14322916666666666 0.20348837209302326 0.15625 +0 0.7034883720930233 0.6432291666666666 0.20348837209302326 0.15625 +0 0.13662790697674418 0.5182291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bce80bfebb680584076dcae61a8265af.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bce80bfebb680584076dcae61a8265af.txt new file mode 100644 index 0000000..490a667 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bce80bfebb680584076dcae61a8265af.txt @@ -0,0 +1,5 @@ +0 0.6918604651162791 0.3567708333333333 0.20348837209302326 0.15625 +0 0.24709302325581395 0.375 0.20348837209302326 0.15625 +0 0.7965116279069767 0.09375 0.20348837209302326 0.15625 +0 0.7267441860465116 0.5911458333333333 0.20348837209302326 0.15625 +0 0.40988372093023256 0.5963541666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bd006d9d9227499468866ba030554c13.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bd006d9d9227499468866ba030554c13.txt new file mode 100644 index 0000000..e496aa0 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bd006d9d9227499468866ba030554c13.txt @@ -0,0 +1,4 @@ +0 0.36627906976744184 0.29166666666666663 0.20348837209302326 0.15625 +0 0.15406976744186046 0.7864583333333333 0.20348837209302326 0.15625 +0 0.811046511627907 0.5520833333333333 0.20348837209302326 0.15625 +0 0.5145348837209303 0.65625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bd621187dafd6846d11d7f2fb2459fa2.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bd621187dafd6846d11d7f2fb2459fa2.txt new file mode 100644 index 0000000..74cf58c --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bd621187dafd6846d11d7f2fb2459fa2.txt @@ -0,0 +1,4 @@ +0 0.6918604651162791 0.33854166666666663 0.20348837209302326 0.15625 +0 0.3430232558139535 0.09114583333333333 0.20348837209302326 0.15625 +0 0.2238372093023256 0.5234375 0.20348837209302326 0.15625 +0 0.8343023255813954 0.75 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/be204f58ecb1f7aa29209167d8da5d70.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/be204f58ecb1f7aa29209167d8da5d70.txt new file mode 100644 index 0000000..ac0e981 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/be204f58ecb1f7aa29209167d8da5d70.txt @@ -0,0 +1,5 @@ +0 0.502906976744186 0.53125 0.20348837209302326 0.15625 +0 0.5523255813953488 0.7760416666666666 0.20348837209302326 0.15625 +0 0.14825581395348836 0.5598958333333333 0.20348837209302326 0.15625 +0 0.6395348837209303 0.23958333333333331 0.20348837209302326 0.15625 +0 0.8284883720930233 0.7630208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/be3a11101c7b3e19e67219d5ffdba17b.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/be3a11101c7b3e19e67219d5ffdba17b.txt new file mode 100644 index 0000000..5aaab1b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/be3a11101c7b3e19e67219d5ffdba17b.txt @@ -0,0 +1,4 @@ +0 0.4127906976744186 0.5390625 0.20348837209302326 0.15625 +0 0.7819767441860465 0.5989583333333333 0.20348837209302326 0.15625 +0 0.23837209302325582 0.2942708333333333 0.20348837209302326 0.15625 +0 0.7645348837209303 0.38541666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bfb153ecb1e3b7552b673f2f7be1ccf6.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bfb153ecb1e3b7552b673f2f7be1ccf6.txt new file mode 100644 index 0000000..c591dd7 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/bfb153ecb1e3b7552b673f2f7be1ccf6.txt @@ -0,0 +1,5 @@ +0 0.8284883720930233 0.4895833333333333 0.20348837209302326 0.15625 +0 0.3081395348837209 0.16666666666666666 0.20348837209302326 0.15625 +0 0.46511627906976744 0.4114583333333333 0.20348837209302326 0.15625 +0 0.40406976744186046 0.7213541666666666 0.20348837209302326 0.15625 +0 0.8052325581395349 0.2552083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c0448396a66b6a9a343c8d4f6c6c3eb0.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c0448396a66b6a9a343c8d4f6c6c3eb0.txt new file mode 100644 index 0000000..925d431 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c0448396a66b6a9a343c8d4f6c6c3eb0.txt @@ -0,0 +1,5 @@ +0 0.7383720930232558 0.16145833333333331 0.20348837209302326 0.15625 +0 0.7848837209302325 0.7734375 0.20348837209302326 0.15625 +0 0.6482558139534884 0.453125 0.20348837209302326 0.15625 +0 0.30523255813953487 0.6822916666666666 0.20348837209302326 0.15625 +0 0.24709302325581395 0.21354166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c1a0a37f454b2d5aaca369f6412bd0d3.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c1a0a37f454b2d5aaca369f6412bd0d3.txt new file mode 100644 index 0000000..02c81b0 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c1a0a37f454b2d5aaca369f6412bd0d3.txt @@ -0,0 +1,4 @@ +0 0.688953488372093 0.6432291666666666 0.20348837209302326 0.15625 +0 0.5668604651162791 0.26822916666666663 0.20348837209302326 0.15625 +0 0.16569767441860464 0.671875 0.20348837209302326 0.15625 +0 0.16569767441860464 0.3958333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2095599aaf0586f25f6c9a117d4fc0c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2095599aaf0586f25f6c9a117d4fc0c.txt new file mode 100644 index 0000000..01c6ce1 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2095599aaf0586f25f6c9a117d4fc0c.txt @@ -0,0 +1,4 @@ +0 0.7965116279069767 0.23958333333333331 0.20348837209302326 0.15625 +0 0.2877906976744186 0.2864583333333333 0.20348837209302326 0.15625 +0 0.7122093023255814 0.7552083333333333 0.20348837209302326 0.15625 +0 0.19186046511627908 0.5260416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2602bfcc5527d69fbf66e5ba431c133.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2602bfcc5527d69fbf66e5ba431c133.txt new file mode 100644 index 0000000..236ddfc --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2602bfcc5527d69fbf66e5ba431c133.txt @@ -0,0 +1,4 @@ +0 0.3575581395348837 0.6796875 0.20348837209302326 0.15625 +0 0.5552325581395349 0.1875 0.20348837209302326 0.15625 +0 0.8633720930232558 0.5026041666666666 0.20348837209302326 0.15625 +0 0.14825581395348836 0.32291666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2983bce2fb62663ef1c1bb3dfa5a353.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2983bce2fb62663ef1c1bb3dfa5a353.txt new file mode 100644 index 0000000..90be06c --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2983bce2fb62663ef1c1bb3dfa5a353.txt @@ -0,0 +1,5 @@ +0 0.5 0.14583333333333331 0.20348837209302326 0.15625 +0 0.6715116279069767 0.5963541666666666 0.20348837209302326 0.15625 +0 0.7703488372093024 0.09114583333333333 0.20348837209302326 0.15625 +0 0.13662790697674418 0.5286458333333333 0.20348837209302326 0.15625 +0 0.10755813953488372 0.203125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2bec2fae37fe4502cb53ecff9be1b6b.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2bec2fae37fe4502cb53ecff9be1b6b.txt new file mode 100644 index 0000000..92db1d5 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2bec2fae37fe4502cb53ecff9be1b6b.txt @@ -0,0 +1,4 @@ +0 0.625 0.7447916666666666 0.20348837209302326 0.15625 +0 0.5494186046511628 0.3177083333333333 0.20348837209302326 0.15625 +0 0.14825581395348836 0.3046875 0.20348837209302326 0.15625 +0 0.18023255813953487 0.5598958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2d9f3757c2dad99ec8f45240d125369.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2d9f3757c2dad99ec8f45240d125369.txt new file mode 100644 index 0000000..bb75794 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c2d9f3757c2dad99ec8f45240d125369.txt @@ -0,0 +1,5 @@ +0 0.36627906976744184 0.7734375 0.20348837209302326 0.15625 +0 0.31976744186046513 0.13020833333333331 0.20348837209302326 0.15625 +0 0.752906976744186 0.7552083333333333 0.20348837209302326 0.15625 +0 0.3226744186046512 0.3802083333333333 0.20348837209302326 0.15625 +0 0.7674418604651163 0.3645833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c3960b5c98ffe2f6f5b9f3f30bbd679e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c3960b5c98ffe2f6f5b9f3f30bbd679e.txt new file mode 100644 index 0000000..b3c51e5 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c3960b5c98ffe2f6f5b9f3f30bbd679e.txt @@ -0,0 +1,3 @@ +0 0.7936046511627907 0.6666666666666666 0.20348837209302326 0.15625 +0 0.5813953488372093 0.32291666666666663 0.20348837209302326 0.15625 +0 0.14534883720930233 0.7395833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c3ae2001bc948489f52dea7ca6e95fc9.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c3ae2001bc948489f52dea7ca6e95fc9.txt new file mode 100644 index 0000000..a7f12b0 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c3ae2001bc948489f52dea7ca6e95fc9.txt @@ -0,0 +1,4 @@ +0 0.19767441860465115 0.11197916666666666 0.20348837209302326 0.15625 +0 0.7093023255813954 0.140625 0.20348837209302326 0.15625 +0 0.7209302325581395 0.5130208333333333 0.20348837209302326 0.15625 +0 0.12790697674418605 0.6302083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c3fba3e40a39a345fc1a32d2c0e586c4.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c3fba3e40a39a345fc1a32d2c0e586c4.txt new file mode 100644 index 0000000..341014b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c3fba3e40a39a345fc1a32d2c0e586c4.txt @@ -0,0 +1,2 @@ +0 0.6831395348837209 0.31510416666666663 0.20348837209302326 0.15625 +0 0.5261627906976745 0.7630208333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c47e0ee821c908eb775487c485a1f011.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c47e0ee821c908eb775487c485a1f011.txt new file mode 100644 index 0000000..294b3ee --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c47e0ee821c908eb775487c485a1f011.txt @@ -0,0 +1,3 @@ +0 0.747093023255814 0.10677083333333333 0.20348837209302326 0.15625 +0 0.2936046511627907 0.421875 0.20348837209302326 0.15625 +0 0.688953488372093 0.6119791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c4dee3d62365554783e3696baa67fe81.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c4dee3d62365554783e3696baa67fe81.txt new file mode 100644 index 0000000..c236517 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c4dee3d62365554783e3696baa67fe81.txt @@ -0,0 +1,4 @@ +0 0.5813953488372093 0.16145833333333331 0.20348837209302326 0.15625 +0 0.6598837209302325 0.7786458333333333 0.20348837209302326 0.15625 +0 0.7848837209302325 0.5234375 0.20348837209302326 0.15625 +0 0.13662790697674418 0.23958333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c52724e65a186042b9991d546ca8353e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c52724e65a186042b9991d546ca8353e.txt new file mode 100644 index 0000000..9ebb409 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c52724e65a186042b9991d546ca8353e.txt @@ -0,0 +1,4 @@ +0 0.32558139534883723 0.6692708333333333 0.20348837209302326 0.15625 +0 0.8226744186046512 0.23177083333333331 0.20348837209302326 0.15625 +0 0.622093023255814 0.53125 0.20348837209302326 0.15625 +0 0.30523255813953487 0.13541666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c528c8c781aabb8841188b6c6870ef60.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c528c8c781aabb8841188b6c6870ef60.txt new file mode 100644 index 0000000..d9feb82 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c528c8c781aabb8841188b6c6870ef60.txt @@ -0,0 +1,2 @@ +0 0.5465116279069767 0.5286458333333333 0.20348837209302326 0.15625 +0 0.3633720930232558 0.09635416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c5383a5b4f6737d8a8aab45b34d75c85.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c5383a5b4f6737d8a8aab45b34d75c85.txt new file mode 100644 index 0000000..c6ac5e4 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c5383a5b4f6737d8a8aab45b34d75c85.txt @@ -0,0 +1,4 @@ +0 0.5552325581395349 0.34635416666666663 0.20348837209302326 0.15625 +0 0.2877906976744186 0.7421875 0.20348837209302326 0.15625 +0 0.8372093023255813 0.1171875 0.20348837209302326 0.15625 +0 0.2761627906976744 0.515625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c6d8f37a44040738b00b6329975739f1.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c6d8f37a44040738b00b6329975739f1.txt new file mode 100644 index 0000000..f94bd47 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c6d8f37a44040738b00b6329975739f1.txt @@ -0,0 +1,4 @@ +0 0.36627906976744184 0.4583333333333333 0.20348837209302326 0.15625 +0 0.7151162790697674 0.22135416666666666 0.20348837209302326 0.15625 +0 0.6744186046511628 0.5 0.20348837209302326 0.15625 +0 0.38372093023255816 0.1328125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c741348f69f3d93bca532c04d013d2ff.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c741348f69f3d93bca532c04d013d2ff.txt new file mode 100644 index 0000000..f21fe18 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c741348f69f3d93bca532c04d013d2ff.txt @@ -0,0 +1,3 @@ +0 0.19767441860465115 0.5546875 0.20348837209302326 0.15625 +0 0.752906976744186 0.6796875 0.20348837209302326 0.15625 +0 0.7587209302325582 0.1640625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c799e2d03ce8c169db17c2764eb15649.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c799e2d03ce8c169db17c2764eb15649.txt new file mode 100644 index 0000000..b483d28 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c799e2d03ce8c169db17c2764eb15649.txt @@ -0,0 +1,4 @@ +0 0.19186046511627908 0.47135416666666663 0.20348837209302326 0.15625 +0 0.5901162790697674 0.2708333333333333 0.20348837209302326 0.15625 +0 0.2616279069767442 0.1875 0.20348837209302326 0.15625 +0 0.7034883720930233 0.6640625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c7c7760b123788dfc300c00f550c0c8b.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c7c7760b123788dfc300c00f550c0c8b.txt new file mode 100644 index 0000000..b4a3216 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c7c7760b123788dfc300c00f550c0c8b.txt @@ -0,0 +1,5 @@ +0 0.7063953488372093 0.7630208333333333 0.20348837209302326 0.15625 +0 0.44476744186046513 0.5052083333333333 0.20348837209302326 0.15625 +0 0.12209302325581395 0.28385416666666663 0.20348837209302326 0.15625 +0 0.11337209302325581 0.7421875 0.20348837209302326 0.15625 +0 0.4069767441860465 0.7734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c81c448c1a4c106d2c0c65af9d171e84.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c81c448c1a4c106d2c0c65af9d171e84.txt new file mode 100644 index 0000000..aa3fb7b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/c81c448c1a4c106d2c0c65af9d171e84.txt @@ -0,0 +1,4 @@ +0 0.7848837209302325 0.4270833333333333 0.20348837209302326 0.15625 +0 0.3895348837209302 0.11197916666666666 0.20348837209302326 0.15625 +0 0.2616279069767442 0.375 0.20348837209302326 0.15625 +0 0.36046511627906974 0.7682291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ca310ecb2347058231a4f39abe2a4b37.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ca310ecb2347058231a4f39abe2a4b37.txt new file mode 100644 index 0000000..2586c37 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ca310ecb2347058231a4f39abe2a4b37.txt @@ -0,0 +1,3 @@ +0 0.5465116279069767 0.14322916666666666 0.20348837209302326 0.15625 +0 0.7238372093023255 0.4453125 0.20348837209302326 0.15625 +0 0.18313953488372092 0.24739583333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cb3d6d429e9939b00f70b6b93f75e13c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cb3d6d429e9939b00f70b6b93f75e13c.txt new file mode 100644 index 0000000..8a63e5d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cb3d6d429e9939b00f70b6b93f75e13c.txt @@ -0,0 +1,4 @@ +0 0.5377906976744186 0.3333333333333333 0.20348837209302326 0.15625 +0 0.7267441860465116 0.7161458333333333 0.20348837209302326 0.15625 +0 0.16569767441860464 0.7005208333333333 0.20348837209302326 0.15625 +0 0.125 0.109375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cbb3af2be8d11a04174cb3108ab47fd6.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cbb3af2be8d11a04174cb3108ab47fd6.txt new file mode 100644 index 0000000..fb9e755 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cbb3af2be8d11a04174cb3108ab47fd6.txt @@ -0,0 +1,3 @@ +0 0.18313953488372092 0.14583333333333331 0.20348837209302326 0.15625 +0 0.6918604651162791 0.5364583333333333 0.20348837209302326 0.15625 +0 0.3575581395348837 0.6953125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cc6d83459819b0a75b6adc146f1bb21c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cc6d83459819b0a75b6adc146f1bb21c.txt new file mode 100644 index 0000000..d0260aa --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cc6d83459819b0a75b6adc146f1bb21c.txt @@ -0,0 +1,4 @@ +0 0.14534883720930233 0.6302083333333333 0.20348837209302326 0.15625 +0 0.7674418604651163 0.7239583333333333 0.20348837209302326 0.15625 +0 0.46511627906976744 0.6067708333333333 0.20348837209302326 0.15625 +0 0.6627906976744186 0.11458333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ccd349028db6c236ae4dc2f72467013d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ccd349028db6c236ae4dc2f72467013d.txt new file mode 100644 index 0000000..425df3a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ccd349028db6c236ae4dc2f72467013d.txt @@ -0,0 +1,5 @@ +0 0.7238372093023255 0.40625 0.20348837209302326 0.15625 +0 0.21511627906976744 0.3958333333333333 0.20348837209302326 0.15625 +0 0.3691860465116279 0.6692708333333333 0.20348837209302326 0.15625 +0 0.7412790697674418 0.16927083333333331 0.20348837209302326 0.15625 +0 0.3691860465116279 0.13020833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cd5d962cad7da958ea255fb19a3dd930.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cd5d962cad7da958ea255fb19a3dd930.txt new file mode 100644 index 0000000..a081408 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cd5d962cad7da958ea255fb19a3dd930.txt @@ -0,0 +1,4 @@ +0 0.5465116279069767 0.5755208333333333 0.20348837209302326 0.15625 +0 0.34593023255813954 0.2864583333333333 0.20348837209302326 0.15625 +0 0.34011627906976744 0.7864583333333333 0.20348837209302326 0.15625 +0 0.8488372093023255 0.33072916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cda3322118354a1e2b32b97b8529e414.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cda3322118354a1e2b32b97b8529e414.txt new file mode 100644 index 0000000..d6139e5 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cda3322118354a1e2b32b97b8529e414.txt @@ -0,0 +1,4 @@ +0 0.19767441860465115 0.6588541666666666 0.20348837209302326 0.15625 +0 0.627906976744186 0.18229166666666666 0.20348837209302326 0.15625 +0 0.12209302325581395 0.25 0.20348837209302326 0.15625 +0 0.5930232558139534 0.7369791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ce0847f5942db97d0f8685af8167e89f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ce0847f5942db97d0f8685af8167e89f.txt new file mode 100644 index 0000000..6cc8892 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ce0847f5942db97d0f8685af8167e89f.txt @@ -0,0 +1,3 @@ +0 0.5436046511627907 0.7135416666666666 0.20348837209302326 0.15625 +0 0.8284883720930233 0.6223958333333333 0.20348837209302326 0.15625 +0 0.39244186046511625 0.4296875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cf4cb3db4ccc0a7ab9e9a2c4da9329a3.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cf4cb3db4ccc0a7ab9e9a2c4da9329a3.txt new file mode 100644 index 0000000..b606ec7 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cf4cb3db4ccc0a7ab9e9a2c4da9329a3.txt @@ -0,0 +1,4 @@ +0 0.6773255813953488 0.17708333333333331 0.20348837209302326 0.15625 +0 0.7412790697674418 0.6458333333333333 0.20348837209302326 0.15625 +0 0.34011627906976744 0.29947916666666663 0.20348837209302326 0.15625 +0 0.7267441860465116 0.4270833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cf5bffdcae03e2026d162acd7dbb567f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cf5bffdcae03e2026d162acd7dbb567f.txt new file mode 100644 index 0000000..f035c50 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cf5bffdcae03e2026d162acd7dbb567f.txt @@ -0,0 +1,4 @@ +0 0.6686046511627907 0.6458333333333333 0.20348837209302326 0.15625 +0 0.2761627906976744 0.4140625 0.20348837209302326 0.15625 +0 0.22965116279069767 0.109375 0.20348837209302326 0.15625 +0 0.7441860465116279 0.4192708333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cf8ebd04bf14d8ab3c4567c7e5fbb2af.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cf8ebd04bf14d8ab3c4567c7e5fbb2af.txt new file mode 100644 index 0000000..d7d2d39 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cf8ebd04bf14d8ab3c4567c7e5fbb2af.txt @@ -0,0 +1,5 @@ +0 0.35174418604651164 0.24739583333333331 0.20348837209302326 0.15625 +0 0.31976744186046513 0.5703125 0.20348837209302326 0.15625 +0 0.8604651162790697 0.3671875 0.20348837209302326 0.15625 +0 0.7616279069767442 0.6432291666666666 0.20348837209302326 0.15625 +0 0.11918604651162791 0.7760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cfa7a42afb19842fef8d76b41f20758f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cfa7a42afb19842fef8d76b41f20758f.txt new file mode 100644 index 0000000..3e49438 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/cfa7a42afb19842fef8d76b41f20758f.txt @@ -0,0 +1,5 @@ +0 0.563953488372093 0.45572916666666663 0.20348837209302326 0.15625 +0 0.45348837209302323 0.6848958333333333 0.20348837209302326 0.15625 +0 0.1569767441860465 0.7161458333333333 0.20348837209302326 0.15625 +0 0.5203488372093024 0.23177083333333331 0.20348837209302326 0.15625 +0 0.11046511627906977 0.15885416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d0208bea6e7dbf8ac017d394d06a6d97.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d0208bea6e7dbf8ac017d394d06a6d97.txt new file mode 100644 index 0000000..8bc9379 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d0208bea6e7dbf8ac017d394d06a6d97.txt @@ -0,0 +1,5 @@ +0 0.502906976744186 0.2734375 0.20348837209302326 0.15625 +0 0.8284883720930233 0.328125 0.20348837209302326 0.15625 +0 0.5930232558139534 0.5703125 0.20348837209302326 0.15625 +0 0.19186046511627908 0.5208333333333333 0.20348837209302326 0.15625 +0 0.15406976744186046 0.203125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d0f201925be9f4efbaafe8620119875d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d0f201925be9f4efbaafe8620119875d.txt new file mode 100644 index 0000000..62b48ff --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d0f201925be9f4efbaafe8620119875d.txt @@ -0,0 +1,4 @@ +0 0.438953488372093 0.21614583333333331 0.20348837209302326 0.15625 +0 0.6191860465116279 0.5442708333333333 0.20348837209302326 0.15625 +0 0.7906976744186046 0.1328125 0.20348837209302326 0.15625 +0 0.36627906976744184 0.5416666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d12354801e2a2689afabfaf237796d6f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d12354801e2a2689afabfaf237796d6f.txt new file mode 100644 index 0000000..f4c8030 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d12354801e2a2689afabfaf237796d6f.txt @@ -0,0 +1,3 @@ +0 0.7790697674418604 0.45572916666666663 0.20348837209302326 0.15625 +0 0.5668604651162791 0.109375 0.20348837209302326 0.15625 +0 0.1744186046511628 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d123dc82eefece187055aba6869b95cd.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d123dc82eefece187055aba6869b95cd.txt new file mode 100644 index 0000000..7b4c493 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d123dc82eefece187055aba6869b95cd.txt @@ -0,0 +1,5 @@ +0 0.6104651162790697 0.7265625 0.20348837209302326 0.15625 +0 0.8430232558139534 0.2630208333333333 0.20348837209302326 0.15625 +0 0.313953488372093 0.28125 0.20348837209302326 0.15625 +0 0.2645348837209302 0.59375 0.20348837209302326 0.15625 +0 0.7761627906976744 0.484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d1b7b384daafd2472881aed64e1468a7.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d1b7b384daafd2472881aed64e1468a7.txt new file mode 100644 index 0000000..c947a8f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d1b7b384daafd2472881aed64e1468a7.txt @@ -0,0 +1,4 @@ +0 0.5813953488372093 0.14583333333333331 0.20348837209302326 0.15625 +0 0.2936046511627907 0.359375 0.20348837209302326 0.15625 +0 0.5552325581395349 0.6822916666666666 0.20348837209302326 0.15625 +0 0.11337209302325581 0.71875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d22deb4dece26c8ed02e8a3f05dd0395.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d22deb4dece26c8ed02e8a3f05dd0395.txt new file mode 100644 index 0000000..05a1782 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d22deb4dece26c8ed02e8a3f05dd0395.txt @@ -0,0 +1,4 @@ +0 0.38372093023255816 0.484375 0.20348837209302326 0.15625 +0 0.8313953488372093 0.6354166666666666 0.20348837209302326 0.15625 +0 0.7180232558139534 0.36979166666666663 0.20348837209302326 0.15625 +0 0.7848837209302325 0.1171875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d275671cecfe7df4e5219cd774826825.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d275671cecfe7df4e5219cd774826825.txt new file mode 100644 index 0000000..d35b94d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d275671cecfe7df4e5219cd774826825.txt @@ -0,0 +1,4 @@ +0 0.15988372093023256 0.24739583333333331 0.20348837209302326 0.15625 +0 0.6802325581395349 0.7265625 0.20348837209302326 0.15625 +0 0.7848837209302325 0.13541666666666666 0.20348837209302326 0.15625 +0 0.6598837209302325 0.5026041666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d27a33ed1a6bf7de764fdb8b12440665.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d27a33ed1a6bf7de764fdb8b12440665.txt new file mode 100644 index 0000000..5512241 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d27a33ed1a6bf7de764fdb8b12440665.txt @@ -0,0 +1,4 @@ +0 0.7063953488372093 0.6458333333333333 0.20348837209302326 0.15625 +0 0.3168604651162791 0.40104166666666663 0.20348837209302326 0.15625 +0 0.7441860465116279 0.4192708333333333 0.20348837209302326 0.15625 +0 0.4331395348837209 0.15885416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d2bc4f474885b48501283f19d2a2dd80.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d2bc4f474885b48501283f19d2a2dd80.txt new file mode 100644 index 0000000..b867ace --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d2bc4f474885b48501283f19d2a2dd80.txt @@ -0,0 +1,2 @@ +0 0.3691860465116279 0.5052083333333333 0.20348837209302326 0.15625 +0 0.7848837209302325 0.09375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d3feb187cabf2b68f42d72c5f2c6d115.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d3feb187cabf2b68f42d72c5f2c6d115.txt new file mode 100644 index 0000000..7bdfa8e --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d3feb187cabf2b68f42d72c5f2c6d115.txt @@ -0,0 +1,3 @@ +0 0.6656976744186046 0.4114583333333333 0.20348837209302326 0.15625 +0 0.3546511627906977 0.4973958333333333 0.20348837209302326 0.15625 +0 0.7093023255813954 0.7421875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d430ed3650c4c82c2a452f3ffc7690a9.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d430ed3650c4c82c2a452f3ffc7690a9.txt new file mode 100644 index 0000000..bb29b11 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d430ed3650c4c82c2a452f3ffc7690a9.txt @@ -0,0 +1,3 @@ +0 0.7761627906976744 0.7135416666666666 0.20348837209302326 0.15625 +0 0.6598837209302325 0.2864583333333333 0.20348837209302326 0.15625 +0 0.37790697674418605 0.578125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d48510fe6ec84c879f68b9f9385f5e14.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d48510fe6ec84c879f68b9f9385f5e14.txt new file mode 100644 index 0000000..c37d86d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d48510fe6ec84c879f68b9f9385f5e14.txt @@ -0,0 +1,5 @@ +0 0.4331395348837209 0.5078125 0.20348837209302326 0.15625 +0 0.47674418604651164 0.14583333333333331 0.20348837209302326 0.15625 +0 0.8168604651162791 0.171875 0.20348837209302326 0.15625 +0 0.35174418604651164 0.7552083333333333 0.20348837209302326 0.15625 +0 0.8459302325581395 0.4348958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d49f32b48a997565aed8380dd447ef91.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d49f32b48a997565aed8380dd447ef91.txt new file mode 100644 index 0000000..64d50a3 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d49f32b48a997565aed8380dd447ef91.txt @@ -0,0 +1,3 @@ +0 0.6308139534883721 0.11458333333333333 0.20348837209302326 0.15625 +0 0.2703488372093023 0.29947916666666663 0.20348837209302326 0.15625 +0 0.39825581395348836 0.6484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d4ed6e5c29a19cace6f9c3a81ac3c961.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d4ed6e5c29a19cace6f9c3a81ac3c961.txt new file mode 100644 index 0000000..c3b2e5e --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d4ed6e5c29a19cace6f9c3a81ac3c961.txt @@ -0,0 +1,4 @@ +0 0.19186046511627908 0.421875 0.20348837209302326 0.15625 +0 0.6337209302325582 0.45572916666666663 0.20348837209302326 0.15625 +0 0.7558139534883721 0.7734375 0.20348837209302326 0.15625 +0 0.36046511627906974 0.17708333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d59bd1237fe3ec57bec775cefe34fc59.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d59bd1237fe3ec57bec775cefe34fc59.txt new file mode 100644 index 0000000..311a9ac --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d59bd1237fe3ec57bec775cefe34fc59.txt @@ -0,0 +1,4 @@ +0 0.5436046511627907 0.2942708333333333 0.20348837209302326 0.15625 +0 0.8052325581395349 0.5963541666666666 0.20348837209302326 0.15625 +0 0.23255813953488372 0.7161458333333333 0.20348837209302326 0.15625 +0 0.2761627906976744 0.4661458333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d6880efc983939a8bc39133bee849242.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d6880efc983939a8bc39133bee849242.txt new file mode 100644 index 0000000..67a233a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d6880efc983939a8bc39133bee849242.txt @@ -0,0 +1,4 @@ +0 0.6947674418604651 0.6588541666666666 0.20348837209302326 0.15625 +0 0.3488372093023256 0.1640625 0.20348837209302326 0.15625 +0 0.313953488372093 0.4817708333333333 0.20348837209302326 0.15625 +0 0.7732558139534884 0.4140625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d6efc173b527acd06565cce8947c68ed.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d6efc173b527acd06565cce8947c68ed.txt new file mode 100644 index 0000000..52b0248 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d6efc173b527acd06565cce8947c68ed.txt @@ -0,0 +1,5 @@ +0 0.7761627906976744 0.6015625 0.20348837209302326 0.15625 +0 0.48546511627906974 0.3880208333333333 0.20348837209302326 0.15625 +0 0.14534883720930233 0.265625 0.20348837209302326 0.15625 +0 0.7819767441860465 0.1875 0.20348837209302326 0.15625 +0 0.4215116279069767 0.6979166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d712db479ec92c0b37b0801161820366.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d712db479ec92c0b37b0801161820366.txt new file mode 100644 index 0000000..fa099dd --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d712db479ec92c0b37b0801161820366.txt @@ -0,0 +1,5 @@ +0 0.7238372093023255 0.7473958333333333 0.20348837209302326 0.15625 +0 0.2877906976744186 0.10677083333333333 0.20348837209302326 0.15625 +0 0.5901162790697674 0.1015625 0.20348837209302326 0.15625 +0 0.8575581395348837 0.5078125 0.20348837209302326 0.15625 +0 0.4127906976744186 0.5260416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d83e9ba661aaa1233102de0409b6832b.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d83e9ba661aaa1233102de0409b6832b.txt new file mode 100644 index 0000000..483c7a5 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d83e9ba661aaa1233102de0409b6832b.txt @@ -0,0 +1,4 @@ +0 0.7819767441860465 0.40885416666666663 0.20348837209302326 0.15625 +0 0.18313953488372092 0.15885416666666666 0.20348837209302326 0.15625 +0 0.25290697674418605 0.6458333333333333 0.20348837209302326 0.15625 +0 0.6686046511627907 0.1015625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d8526b86e748354547ff3c210e2c177b.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d8526b86e748354547ff3c210e2c177b.txt new file mode 100644 index 0000000..8158de2 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d8526b86e748354547ff3c210e2c177b.txt @@ -0,0 +1,4 @@ +0 0.6656976744186046 0.46354166666666663 0.20348837209302326 0.15625 +0 0.14534883720930233 0.5911458333333333 0.20348837209302326 0.15625 +0 0.2645348837209302 0.13020833333333331 0.20348837209302326 0.15625 +0 0.6976744186046512 0.12239583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d8a4b88ac006bf17f9d46ff487f4e481.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d8a4b88ac006bf17f9d46ff487f4e481.txt new file mode 100644 index 0000000..a6068a8 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d8a4b88ac006bf17f9d46ff487f4e481.txt @@ -0,0 +1,4 @@ +0 0.1511627906976744 0.7604166666666666 0.20348837209302326 0.15625 +0 0.4883720930232558 0.5625 0.20348837209302326 0.15625 +0 0.8023255813953488 0.6796875 0.20348837209302326 0.15625 +0 0.3168604651162791 0.27604166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d9e1da1b60affbc48272520117bf47d9.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d9e1da1b60affbc48272520117bf47d9.txt new file mode 100644 index 0000000..4e5fdb2 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/d9e1da1b60affbc48272520117bf47d9.txt @@ -0,0 +1,4 @@ +0 0.6366279069767442 0.765625 0.20348837209302326 0.15625 +0 0.2005813953488372 0.4583333333333333 0.20348837209302326 0.15625 +0 0.2441860465116279 0.7057291666666666 0.20348837209302326 0.15625 +0 0.7761627906976744 0.3203125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/da612470ecad5530274e30a0c519c26c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/da612470ecad5530274e30a0c519c26c.txt new file mode 100644 index 0000000..25037b5 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/da612470ecad5530274e30a0c519c26c.txt @@ -0,0 +1,4 @@ +0 0.5 0.390625 0.20348837209302326 0.15625 +0 0.8081395348837209 0.26041666666666663 0.20348837209302326 0.15625 +0 0.15988372093023256 0.484375 0.20348837209302326 0.15625 +0 0.32558139534883723 0.13020833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dab87e721f5a1e8410af38bc09db6112.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dab87e721f5a1e8410af38bc09db6112.txt new file mode 100644 index 0000000..d3d0f30 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dab87e721f5a1e8410af38bc09db6112.txt @@ -0,0 +1,4 @@ +0 0.8052325581395349 0.11458333333333333 0.20348837209302326 0.15625 +0 0.7296511627906976 0.3671875 0.20348837209302326 0.15625 +0 0.2645348837209302 0.3125 0.20348837209302326 0.15625 +0 0.6337209302325582 0.7135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/db0b23b7c4b284e1901ac146f62345c8.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/db0b23b7c4b284e1901ac146f62345c8.txt new file mode 100644 index 0000000..b8c17b5 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/db0b23b7c4b284e1901ac146f62345c8.txt @@ -0,0 +1,3 @@ +0 0.7936046511627907 0.6197916666666666 0.20348837209302326 0.15625 +0 0.29069767441860467 0.6354166666666666 0.20348837209302326 0.15625 +0 0.34011627906976744 0.35416666666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dbbe55447ad34d282c50beefa138cdfb.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dbbe55447ad34d282c50beefa138cdfb.txt new file mode 100644 index 0000000..c8287e4 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dbbe55447ad34d282c50beefa138cdfb.txt @@ -0,0 +1,5 @@ +0 0.7441860465116279 0.5026041666666666 0.20348837209302326 0.15625 +0 0.19767441860465115 0.22395833333333331 0.20348837209302326 0.15625 +0 0.4215116279069767 0.6432291666666666 0.20348837209302326 0.15625 +0 0.6627906976744186 0.2708333333333333 0.20348837209302326 0.15625 +0 0.13662790697674418 0.6302083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dbc7066a0923685debf5925f6e9cb980.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dbc7066a0923685debf5925f6e9cb980.txt new file mode 100644 index 0000000..0b8ee67 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dbc7066a0923685debf5925f6e9cb980.txt @@ -0,0 +1,4 @@ +0 0.3226744186046512 0.41666666666666663 0.20348837209302326 0.15625 +0 0.7441860465116279 0.4140625 0.20348837209302326 0.15625 +0 0.311046511627907 0.7291666666666666 0.20348837209302326 0.15625 +0 0.2441860465116279 0.09895833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dcfedaf9eddb9ce0a3c98d5fb29e9072.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dcfedaf9eddb9ce0a3c98d5fb29e9072.txt new file mode 100644 index 0000000..c0da0f6 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dcfedaf9eddb9ce0a3c98d5fb29e9072.txt @@ -0,0 +1,4 @@ +0 0.752906976744186 0.7786458333333333 0.20348837209302326 0.15625 +0 0.3546511627906977 0.4765625 0.20348837209302326 0.15625 +0 0.6627906976744186 0.4296875 0.20348837209302326 0.15625 +0 0.5058139534883721 0.10416666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dd730346a8a66e841d06223364ab66df.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dd730346a8a66e841d06223364ab66df.txt new file mode 100644 index 0000000..218201c --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dd730346a8a66e841d06223364ab66df.txt @@ -0,0 +1,4 @@ +0 0.40988372093023256 0.6875 0.20348837209302326 0.15625 +0 0.36046511627906974 0.3645833333333333 0.20348837209302326 0.15625 +0 0.2238372093023256 0.14583333333333331 0.20348837209302326 0.15625 +0 0.7761627906976744 0.14322916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ddd7b5b5ac9bba4014a6decf60e4bb66.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ddd7b5b5ac9bba4014a6decf60e4bb66.txt new file mode 100644 index 0000000..2850a4b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ddd7b5b5ac9bba4014a6decf60e4bb66.txt @@ -0,0 +1,4 @@ +0 0.5552325581395349 0.11979166666666666 0.20348837209302326 0.15625 +0 0.7587209302325582 0.36197916666666663 0.20348837209302326 0.15625 +0 0.40406976744186046 0.7395833333333333 0.20348837209302326 0.15625 +0 0.7238372093023255 0.7760416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/de23b7a87cd2a4fe477bebf589ebf278.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/de23b7a87cd2a4fe477bebf589ebf278.txt new file mode 100644 index 0000000..4696081 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/de23b7a87cd2a4fe477bebf589ebf278.txt @@ -0,0 +1,4 @@ +0 0.5959302325581395 0.16666666666666666 0.20348837209302326 0.15625 +0 0.2616279069767442 0.17708333333333331 0.20348837209302326 0.15625 +0 0.4069767441860465 0.703125 0.20348837209302326 0.15625 +0 0.16569767441860464 0.45572916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/deffd3c1c8784398a62c8d1ebfb3e436.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/deffd3c1c8784398a62c8d1ebfb3e436.txt new file mode 100644 index 0000000..10c73c4 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/deffd3c1c8784398a62c8d1ebfb3e436.txt @@ -0,0 +1,4 @@ +0 0.8575581395348837 0.46875 0.20348837209302326 0.15625 +0 0.4680232558139535 0.1953125 0.20348837209302326 0.15625 +0 0.16279069767441862 0.296875 0.20348837209302326 0.15625 +0 0.31976744186046513 0.765625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/df6c4c7dc3c069d53125e9b5014d1396.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/df6c4c7dc3c069d53125e9b5014d1396.txt new file mode 100644 index 0000000..ccbf99e --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/df6c4c7dc3c069d53125e9b5014d1396.txt @@ -0,0 +1,5 @@ +0 0.5523255813953488 0.1171875 0.20348837209302326 0.15625 +0 0.8604651162790697 0.7734375 0.20348837209302326 0.15625 +0 0.24127906976744184 0.5911458333333333 0.20348837209302326 0.15625 +0 0.563953488372093 0.578125 0.20348837209302326 0.15625 +0 0.8488372093023255 0.40104166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dfc1aea91a1471e2a59c7e7d113ba6e1.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dfc1aea91a1471e2a59c7e7d113ba6e1.txt new file mode 100644 index 0000000..dea974a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/dfc1aea91a1471e2a59c7e7d113ba6e1.txt @@ -0,0 +1,5 @@ +0 0.16279069767441862 0.2864583333333333 0.20348837209302326 0.15625 +0 0.125 0.5989583333333333 0.20348837209302326 0.15625 +0 0.6744186046511628 0.1171875 0.20348837209302326 0.15625 +0 0.7732558139534884 0.4609375 0.20348837209302326 0.15625 +0 0.4680232558139535 0.3828125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e05a5fbc31da900cdb2586cc9fcecd67.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e05a5fbc31da900cdb2586cc9fcecd67.txt new file mode 100644 index 0000000..d52ae07 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e05a5fbc31da900cdb2586cc9fcecd67.txt @@ -0,0 +1,4 @@ +0 0.75 0.4973958333333333 0.20348837209302326 0.15625 +0 0.3488372093023256 0.7447916666666666 0.20348837209302326 0.15625 +0 0.3081395348837209 0.08854166666666666 0.20348837209302326 0.15625 +0 0.6802325581395349 0.1015625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e09bc7551899dbca3d98b3fa38790fea.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e09bc7551899dbca3d98b3fa38790fea.txt new file mode 100644 index 0000000..9585326 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e09bc7551899dbca3d98b3fa38790fea.txt @@ -0,0 +1,4 @@ +0 0.5930232558139534 0.59375 0.20348837209302326 0.15625 +0 0.5494186046511628 0.3046875 0.20348837209302326 0.15625 +0 0.125 0.46875 0.20348837209302326 0.15625 +0 0.19767441860465115 0.1796875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e10ab369a27acb2093e56d5ea4e9029a.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e10ab369a27acb2093e56d5ea4e9029a.txt new file mode 100644 index 0000000..67f69fa --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e10ab369a27acb2093e56d5ea4e9029a.txt @@ -0,0 +1,4 @@ +0 0.42441860465116277 0.48697916666666663 0.20348837209302326 0.15625 +0 0.5988372093023255 0.7291666666666666 0.20348837209302326 0.15625 +0 0.2005813953488372 0.7578125 0.20348837209302326 0.15625 +0 0.5784883720930233 0.22395833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e133e335b9e34caa8297e7aa4e7baacc.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e133e335b9e34caa8297e7aa4e7baacc.txt new file mode 100644 index 0000000..454246d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e133e335b9e34caa8297e7aa4e7baacc.txt @@ -0,0 +1,4 @@ +0 0.14534883720930233 0.640625 0.20348837209302326 0.15625 +0 0.8691860465116279 0.359375 0.20348837209302326 0.15625 +0 0.6104651162790697 0.671875 0.20348837209302326 0.15625 +0 0.2965116279069767 0.30729166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e20f844b4406d5935f605a65f589635d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e20f844b4406d5935f605a65f589635d.txt new file mode 100644 index 0000000..88fd2b0 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e20f844b4406d5935f605a65f589635d.txt @@ -0,0 +1,5 @@ +0 0.5 0.2630208333333333 0.20348837209302326 0.15625 +0 0.3488372093023256 0.7291666666666666 0.20348837209302326 0.15625 +0 0.7906976744186046 0.4270833333333333 0.20348837209302326 0.15625 +0 0.19767441860465115 0.12760416666666666 0.20348837209302326 0.15625 +0 0.7848837209302325 0.15625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e26188d532509f649c96e984c95cf7aa.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e26188d532509f649c96e984c95cf7aa.txt new file mode 100644 index 0000000..1c9976c --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e26188d532509f649c96e984c95cf7aa.txt @@ -0,0 +1,3 @@ +0 0.8517441860465116 0.4661458333333333 0.20348837209302326 0.15625 +0 0.3895348837209302 0.3567708333333333 0.20348837209302326 0.15625 +0 0.4796511627906977 0.6458333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e39a86e6070757a12ffe8b4970e94eb9.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e39a86e6070757a12ffe8b4970e94eb9.txt new file mode 100644 index 0000000..7c16ad2 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e39a86e6070757a12ffe8b4970e94eb9.txt @@ -0,0 +1,4 @@ +0 0.5 0.6822916666666666 0.20348837209302326 0.15625 +0 0.5988372093023255 0.44791666666666663 0.20348837209302326 0.15625 +0 0.7034883720930233 0.20052083333333331 0.20348837209302326 0.15625 +0 0.8546511627906976 0.7682291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e49863c40c18b9049601ae9dcd6511f7.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e49863c40c18b9049601ae9dcd6511f7.txt new file mode 100644 index 0000000..2f015f7 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e49863c40c18b9049601ae9dcd6511f7.txt @@ -0,0 +1,5 @@ +0 0.26744186046511625 0.25260416666666663 0.20348837209302326 0.15625 +0 0.6075581395348837 0.140625 0.20348837209302326 0.15625 +0 0.6482558139534884 0.609375 0.20348837209302326 0.15625 +0 0.14825581395348836 0.5338541666666666 0.20348837209302326 0.15625 +0 0.14534883720930233 0.7578125 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e4df16396ed7363d7f748680fb379f4c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e4df16396ed7363d7f748680fb379f4c.txt new file mode 100644 index 0000000..d072661 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e4df16396ed7363d7f748680fb379f4c.txt @@ -0,0 +1,5 @@ +0 0.6744186046511628 0.6510416666666666 0.20348837209302326 0.15625 +0 0.8575581395348837 0.12760416666666666 0.20348837209302326 0.15625 +0 0.25 0.359375 0.20348837209302326 0.15625 +0 0.7412790697674418 0.33854166666666663 0.20348837209302326 0.15625 +0 0.25 0.7473958333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e55ec704a3a5c728d28ddbca60f7392e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e55ec704a3a5c728d28ddbca60f7392e.txt new file mode 100644 index 0000000..8e4d323 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e55ec704a3a5c728d28ddbca60f7392e.txt @@ -0,0 +1,4 @@ +0 0.7238372093023255 0.5755208333333333 0.20348837209302326 0.15625 +0 0.752906976744186 0.3567708333333333 0.20348837209302326 0.15625 +0 0.7441860465116279 0.10416666666666666 0.20348837209302326 0.15625 +0 0.3023255813953488 0.22135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e65cf91b00d1eabe632cb6065fc58f1f.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e65cf91b00d1eabe632cb6065fc58f1f.txt new file mode 100644 index 0000000..6293292 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e65cf91b00d1eabe632cb6065fc58f1f.txt @@ -0,0 +1,3 @@ +0 0.7906976744186046 0.2786458333333333 0.20348837209302326 0.15625 +0 0.375 0.2864583333333333 0.20348837209302326 0.15625 +0 0.4476744186046512 0.5729166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e6cef5e7cdcd2ba2370e8ff7b2df9351.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e6cef5e7cdcd2ba2370e8ff7b2df9351.txt new file mode 100644 index 0000000..d53780a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e6cef5e7cdcd2ba2370e8ff7b2df9351.txt @@ -0,0 +1,4 @@ +0 0.3895348837209302 0.21614583333333331 0.20348837209302326 0.15625 +0 0.7732558139534884 0.71875 0.20348837209302326 0.15625 +0 0.13953488372093023 0.6354166666666666 0.20348837209302326 0.15625 +0 0.8226744186046512 0.34375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e725d377ec830c8b0daa5e02261ceae0.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e725d377ec830c8b0daa5e02261ceae0.txt new file mode 100644 index 0000000..c282f3b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e725d377ec830c8b0daa5e02261ceae0.txt @@ -0,0 +1,5 @@ +0 0.5697674418604651 0.28385416666666663 0.20348837209302326 0.15625 +0 0.3575581395348837 0.5729166666666666 0.20348837209302326 0.15625 +0 0.6453488372093024 0.7135416666666666 0.20348837209302326 0.15625 +0 0.23255813953488372 0.109375 0.20348837209302326 0.15625 +0 0.8488372093023255 0.390625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e74893a8e18678fb991bf242688ee2d5.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e74893a8e18678fb991bf242688ee2d5.txt new file mode 100644 index 0000000..8c43d2f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e74893a8e18678fb991bf242688ee2d5.txt @@ -0,0 +1,4 @@ +0 0.7848837209302325 0.5234375 0.20348837209302326 0.15625 +0 0.6627906976744186 0.14322916666666666 0.20348837209302326 0.15625 +0 0.3866279069767442 0.3984375 0.20348837209302326 0.15625 +0 0.4273255813953488 0.625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e83de5862e651226e954f206a8bfe2a1.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e83de5862e651226e954f206a8bfe2a1.txt new file mode 100644 index 0000000..0959d79 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e83de5862e651226e954f206a8bfe2a1.txt @@ -0,0 +1,5 @@ +0 0.6453488372093024 0.3645833333333333 0.20348837209302326 0.15625 +0 0.31976744186046513 0.5729166666666666 0.20348837209302326 0.15625 +0 0.32558139534883723 0.3359375 0.20348837209302326 0.15625 +0 0.7558139534883721 0.5859375 0.20348837209302326 0.15625 +0 0.4825581395348837 0.10416666666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e887607248f7391b080c7a50af22d464.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e887607248f7391b080c7a50af22d464.txt new file mode 100644 index 0000000..f6f4f8f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e887607248f7391b080c7a50af22d464.txt @@ -0,0 +1,3 @@ +0 0.8517441860465116 0.36197916666666663 0.20348837209302326 0.15625 +0 0.2965116279069767 0.5052083333333333 0.20348837209302326 0.15625 +0 0.375 0.20052083333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e8a154d6c301c9ff032879f86d2f9b89.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e8a154d6c301c9ff032879f86d2f9b89.txt new file mode 100644 index 0000000..46e7d87 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/e8a154d6c301c9ff032879f86d2f9b89.txt @@ -0,0 +1,4 @@ +0 0.7877906976744186 0.14322916666666666 0.20348837209302326 0.15625 +0 0.13953488372093023 0.3828125 0.20348837209302326 0.15625 +0 0.7412790697674418 0.7552083333333333 0.20348837209302326 0.15625 +0 0.44476744186046513 0.09635416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ea1cb7d34fe49bbbb6e9251b16657918.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ea1cb7d34fe49bbbb6e9251b16657918.txt new file mode 100644 index 0000000..7691824 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ea1cb7d34fe49bbbb6e9251b16657918.txt @@ -0,0 +1,3 @@ +0 0.5901162790697674 0.6119791666666666 0.20348837209302326 0.15625 +0 0.2441860465116279 0.6953125 0.20348837209302326 0.15625 +0 0.4622093023255814 0.36197916666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/eabc94c7e737d3fdcb4b737f73f23db8.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/eabc94c7e737d3fdcb4b737f73f23db8.txt new file mode 100644 index 0000000..9d99e65 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/eabc94c7e737d3fdcb4b737f73f23db8.txt @@ -0,0 +1,5 @@ +0 0.8197674418604651 0.18229166666666666 0.20348837209302326 0.15625 +0 0.6337209302325582 0.5833333333333333 0.20348837209302326 0.15625 +0 0.5348837209302325 0.17447916666666666 0.20348837209302326 0.15625 +0 0.2441860465116279 0.640625 0.20348837209302326 0.15625 +0 0.21220930232558138 0.3046875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/eb14edc170ff105fde8cdcd83dd942c6.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/eb14edc170ff105fde8cdcd83dd942c6.txt new file mode 100644 index 0000000..defc207 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/eb14edc170ff105fde8cdcd83dd942c6.txt @@ -0,0 +1,4 @@ +0 0.5087209302325582 0.5 0.20348837209302326 0.15625 +0 0.8662790697674418 0.7265625 0.20348837209302326 0.15625 +0 0.19186046511627908 0.2942708333333333 0.20348837209302326 0.15625 +0 0.8372093023255813 0.3802083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/eb4ea9d5d92a8c02c079ce4518e0e608.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/eb4ea9d5d92a8c02c079ce4518e0e608.txt new file mode 100644 index 0000000..4f8f24a --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/eb4ea9d5d92a8c02c079ce4518e0e608.txt @@ -0,0 +1,4 @@ +0 0.5784883720930233 0.7057291666666666 0.20348837209302326 0.15625 +0 0.25 0.20572916666666666 0.20348837209302326 0.15625 +0 0.2558139534883721 0.6223958333333333 0.20348837209302326 0.15625 +0 0.6133720930232558 0.31510416666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ecf9efb8308a694a32d3fa64933e1752.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ecf9efb8308a694a32d3fa64933e1752.txt new file mode 100644 index 0000000..c593855 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ecf9efb8308a694a32d3fa64933e1752.txt @@ -0,0 +1,5 @@ +0 0.5523255813953488 0.421875 0.20348837209302326 0.15625 +0 0.5930232558139534 0.7317708333333333 0.20348837209302326 0.15625 +0 0.24127906976744184 0.33854166666666663 0.20348837209302326 0.15625 +0 0.1569767441860465 0.5546875 0.20348837209302326 0.15625 +0 0.5755813953488372 0.1796875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/edfa08514ee31d005331d683ac0cbe5e.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/edfa08514ee31d005331d683ac0cbe5e.txt new file mode 100644 index 0000000..a4307c3 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/edfa08514ee31d005331d683ac0cbe5e.txt @@ -0,0 +1,4 @@ +0 0.16279069767441862 0.3984375 0.20348837209302326 0.15625 +0 0.6075581395348837 0.4739583333333333 0.20348837209302326 0.15625 +0 0.23546511627906977 0.11197916666666666 0.20348837209302326 0.15625 +0 0.6715116279069767 0.15885416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ef0bab363420f2105bef4a4c30d823b4.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ef0bab363420f2105bef4a4c30d823b4.txt new file mode 100644 index 0000000..92cc9ec --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ef0bab363420f2105bef4a4c30d823b4.txt @@ -0,0 +1,4 @@ +0 0.688953488372093 0.2786458333333333 0.20348837209302326 0.15625 +0 0.627906976744186 0.6119791666666666 0.20348837209302326 0.15625 +0 0.22965116279069767 0.5989583333333333 0.20348837209302326 0.15625 +0 0.39244186046511625 0.11979166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f005ad99e1ae30a0a5d4fd0b3dad7770.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f005ad99e1ae30a0a5d4fd0b3dad7770.txt new file mode 100644 index 0000000..ae0f782 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f005ad99e1ae30a0a5d4fd0b3dad7770.txt @@ -0,0 +1,5 @@ +0 0.35174418604651164 0.5729166666666666 0.20348837209302326 0.15625 +0 0.7994186046511628 0.5729166666666666 0.20348837209302326 0.15625 +0 0.3633720930232558 0.328125 0.20348837209302326 0.15625 +0 0.752906976744186 0.2864583333333333 0.20348837209302326 0.15625 +0 0.34593023255813954 0.09895833333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f0749b18aa0747b73ac74d36c9ac5317.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f0749b18aa0747b73ac74d36c9ac5317.txt new file mode 100644 index 0000000..1556c6b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f0749b18aa0747b73ac74d36c9ac5317.txt @@ -0,0 +1,4 @@ +0 0.5959302325581395 0.31510416666666663 0.20348837209302326 0.15625 +0 0.29941860465116277 0.546875 0.20348837209302326 0.15625 +0 0.8052325581395349 0.5755208333333333 0.20348837209302326 0.15625 +0 0.5581395348837209 0.7890625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f0b35ba8adfa960168421e0d7e2291d1.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f0b35ba8adfa960168421e0d7e2291d1.txt new file mode 100644 index 0000000..ab225c4 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f0b35ba8adfa960168421e0d7e2291d1.txt @@ -0,0 +1,5 @@ +0 0.7790697674418604 0.6796875 0.20348837209302326 0.15625 +0 0.436046511627907 0.6276041666666666 0.20348837209302326 0.15625 +0 0.34593023255813954 0.22916666666666666 0.20348837209302326 0.15625 +0 0.15988372093023256 0.7630208333333333 0.20348837209302326 0.15625 +0 0.7063953488372093 0.359375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f0d088d42bc11b780b4307eead291fd4.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f0d088d42bc11b780b4307eead291fd4.txt new file mode 100644 index 0000000..0ba209e --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f0d088d42bc11b780b4307eead291fd4.txt @@ -0,0 +1,5 @@ +0 0.3575581395348837 0.1171875 0.20348837209302326 0.15625 +0 0.5872093023255814 0.4609375 0.20348837209302326 0.15625 +0 0.811046511627907 0.10677083333333333 0.20348837209302326 0.15625 +0 0.29069767441860467 0.7265625 0.20348837209302326 0.15625 +0 0.6337209302325582 0.7057291666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f101f8745b2fc2a1dfd62faf74a5c53a.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f101f8745b2fc2a1dfd62faf74a5c53a.txt new file mode 100644 index 0000000..c3423f4 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f101f8745b2fc2a1dfd62faf74a5c53a.txt @@ -0,0 +1,4 @@ +0 0.747093023255814 0.17708333333333331 0.20348837209302326 0.15625 +0 0.3633720930232558 0.515625 0.20348837209302326 0.15625 +0 0.8343023255813954 0.7265625 0.20348837209302326 0.15625 +0 0.5174418604651163 0.765625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f128bc5093ce92f6948a3846c2cdaa23.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f128bc5093ce92f6948a3846c2cdaa23.txt new file mode 100644 index 0000000..3a2dc38 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f128bc5093ce92f6948a3846c2cdaa23.txt @@ -0,0 +1,4 @@ +0 0.26744186046511625 0.5364583333333333 0.20348837209302326 0.15625 +0 0.7936046511627907 0.17447916666666666 0.20348837209302326 0.15625 +0 0.31976744186046513 0.24479166666666666 0.20348837209302326 0.15625 +0 0.8691860465116279 0.609375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f1370c1c58c5249c336abda28de9c58b.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f1370c1c58c5249c336abda28de9c58b.txt new file mode 100644 index 0000000..6724269 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f1370c1c58c5249c336abda28de9c58b.txt @@ -0,0 +1,4 @@ +0 0.2703488372093023 0.4270833333333333 0.20348837209302326 0.15625 +0 0.4011627906976744 0.125 0.20348837209302326 0.15625 +0 0.34593023255813954 0.7447916666666666 0.20348837209302326 0.15625 +0 0.8662790697674418 0.5729166666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f1df5ec7fc32fd167fe5e2bba70b5e90.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f1df5ec7fc32fd167fe5e2bba70b5e90.txt new file mode 100644 index 0000000..be98add --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f1df5ec7fc32fd167fe5e2bba70b5e90.txt @@ -0,0 +1,4 @@ +0 0.6424418604651163 0.7473958333333333 0.20348837209302326 0.15625 +0 0.5494186046511628 0.17447916666666666 0.20348837209302326 0.15625 +0 0.1947674418604651 0.6171875 0.20348837209302326 0.15625 +0 0.8430232558139534 0.25 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f2e0a2a2ba5b631b50364e9424d8a399.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f2e0a2a2ba5b631b50364e9424d8a399.txt new file mode 100644 index 0000000..75384f8 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f2e0a2a2ba5b631b50364e9424d8a399.txt @@ -0,0 +1,4 @@ +0 0.8488372093023255 0.546875 0.20348837209302326 0.15625 +0 0.7238372093023255 0.1484375 0.20348837209302326 0.15625 +0 0.20348837209302326 0.17708333333333331 0.20348837209302326 0.15625 +0 0.25 0.625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f44189b1241a054fd74f1416e50ef578.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f44189b1241a054fd74f1416e50ef578.txt new file mode 100644 index 0000000..efe807f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f44189b1241a054fd74f1416e50ef578.txt @@ -0,0 +1,5 @@ +0 0.42441860465116277 0.49479166666666663 0.20348837209302326 0.15625 +0 0.75 0.3828125 0.20348837209302326 0.15625 +0 0.4622093023255814 0.1484375 0.20348837209302326 0.15625 +0 0.8081395348837209 0.15625 0.20348837209302326 0.15625 +0 0.23255813953488372 0.7864583333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f4e820989083bf0d3f6a6fa58d23cf53.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f4e820989083bf0d3f6a6fa58d23cf53.txt new file mode 100644 index 0000000..61ef3d6 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f4e820989083bf0d3f6a6fa58d23cf53.txt @@ -0,0 +1,4 @@ +0 0.2180232558139535 0.28385416666666663 0.20348837209302326 0.15625 +0 0.6773255813953488 0.7838541666666666 0.20348837209302326 0.15625 +0 0.6598837209302325 0.12239583333333333 0.20348837209302326 0.15625 +0 0.8488372093023255 0.46354166666666663 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f5552b84d08a383e183a2d4380cf3904.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f5552b84d08a383e183a2d4380cf3904.txt new file mode 100644 index 0000000..b9e3b65 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f5552b84d08a383e183a2d4380cf3904.txt @@ -0,0 +1,5 @@ +0 0.7674418604651163 0.5885416666666666 0.20348837209302326 0.15625 +0 0.7180232558139534 0.28385416666666663 0.20348837209302326 0.15625 +0 0.2936046511627907 0.5286458333333333 0.20348837209302326 0.15625 +0 0.13662790697674418 0.109375 0.20348837209302326 0.15625 +0 0.3808139534883721 0.7734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f5d23fc3190f08cbef79623ebe31a3b4.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f5d23fc3190f08cbef79623ebe31a3b4.txt new file mode 100644 index 0000000..0d0bcd4 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f5d23fc3190f08cbef79623ebe31a3b4.txt @@ -0,0 +1,4 @@ +0 0.8284883720930233 0.6197916666666666 0.20348837209302326 0.15625 +0 0.7005813953488372 0.37760416666666663 0.20348837209302326 0.15625 +0 0.1308139534883721 0.17708333333333331 0.20348837209302326 0.15625 +0 0.561046511627907 0.09375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f6c0a1a8e44fbce047d5ee1ce4b7d563.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f6c0a1a8e44fbce047d5ee1ce4b7d563.txt new file mode 100644 index 0000000..3346fd5 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f6c0a1a8e44fbce047d5ee1ce4b7d563.txt @@ -0,0 +1,4 @@ +0 0.5494186046511628 0.7213541666666666 0.20348837209302326 0.15625 +0 0.8575581395348837 0.546875 0.20348837209302326 0.15625 +0 0.2703488372093023 0.17708333333333331 0.20348837209302326 0.15625 +0 0.8633720930232558 0.1484375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f6ec1b24e1a5cb0b3b5db121d901498d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f6ec1b24e1a5cb0b3b5db121d901498d.txt new file mode 100644 index 0000000..e522b1d --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f6ec1b24e1a5cb0b3b5db121d901498d.txt @@ -0,0 +1,3 @@ +0 0.32848837209302323 0.4817708333333333 0.20348837209302326 0.15625 +0 0.5726744186046512 0.22135416666666666 0.20348837209302326 0.15625 +0 0.16279069767441862 0.19270833333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f7617b0afb68d73f7e004ee314352d91.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f7617b0afb68d73f7e004ee314352d91.txt new file mode 100644 index 0000000..889293f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f7617b0afb68d73f7e004ee314352d91.txt @@ -0,0 +1,4 @@ +0 0.622093023255814 0.5260416666666666 0.20348837209302326 0.15625 +0 0.16569767441860464 0.7161458333333333 0.20348837209302326 0.15625 +0 0.3895348837209302 0.13541666666666666 0.20348837209302326 0.15625 +0 0.7587209302325582 0.11197916666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f7903039de6b51cd3953fbdfc8bae34c.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f7903039de6b51cd3953fbdfc8bae34c.txt new file mode 100644 index 0000000..3fc9e50 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f7903039de6b51cd3953fbdfc8bae34c.txt @@ -0,0 +1,4 @@ +0 0.7412790697674418 0.6848958333333333 0.20348837209302326 0.15625 +0 0.7383720930232558 0.14583333333333331 0.20348837209302326 0.15625 +0 0.4563953488372093 0.10416666666666666 0.20348837209302326 0.15625 +0 0.34011627906976744 0.734375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f7b3ea98396a0dd9549f4b4196cdb067.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f7b3ea98396a0dd9549f4b4196cdb067.txt new file mode 100644 index 0000000..1674062 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f7b3ea98396a0dd9549f4b4196cdb067.txt @@ -0,0 +1,5 @@ +0 0.5058139534883721 0.4140625 0.20348837209302326 0.15625 +0 0.5348837209302325 0.6796875 0.20348837209302326 0.15625 +0 0.14825581395348836 0.5390625 0.20348837209302326 0.15625 +0 0.7616279069767442 0.12760416666666666 0.20348837209302326 0.15625 +0 0.2441860465116279 0.7708333333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f7da67a66d65dbe721d9359a064ab5cc.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f7da67a66d65dbe721d9359a064ab5cc.txt new file mode 100644 index 0000000..60bb2bf --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f7da67a66d65dbe721d9359a064ab5cc.txt @@ -0,0 +1,4 @@ +0 0.7994186046511628 0.1171875 0.20348837209302326 0.15625 +0 0.3488372093023256 0.6901041666666666 0.20348837209302326 0.15625 +0 0.15406976744186046 0.1875 0.20348837209302326 0.15625 +0 0.8023255813953488 0.359375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f9f64c7eedcd4ade9c06ee23b326cb96.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f9f64c7eedcd4ade9c06ee23b326cb96.txt new file mode 100644 index 0000000..2a7f912 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/f9f64c7eedcd4ade9c06ee23b326cb96.txt @@ -0,0 +1,4 @@ +0 0.5174418604651163 0.421875 0.20348837209302326 0.15625 +0 0.19186046511627908 0.7604166666666666 0.20348837209302326 0.15625 +0 0.32848837209302323 0.15364583333333331 0.20348837209302326 0.15625 +0 0.5465116279069767 0.6744791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fa4ff538d0763758fdcdf91ee0cc5ec1.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fa4ff538d0763758fdcdf91ee0cc5ec1.txt new file mode 100644 index 0000000..a191957 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fa4ff538d0763758fdcdf91ee0cc5ec1.txt @@ -0,0 +1,4 @@ +0 0.3633720930232558 0.7369791666666666 0.20348837209302326 0.15625 +0 0.5784883720930233 0.44010416666666663 0.20348837209302326 0.15625 +0 0.4011627906976744 0.09114583333333333 0.20348837209302326 0.15625 +0 0.20930232558139533 0.3359375 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fa6c79a0fff4fdb246aa7dcdebaa7173.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fa6c79a0fff4fdb246aa7dcdebaa7173.txt new file mode 100644 index 0000000..96a0b0b --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fa6c79a0fff4fdb246aa7dcdebaa7173.txt @@ -0,0 +1,4 @@ +0 0.45930232558139533 0.3098958333333333 0.20348837209302326 0.15625 +0 0.19186046511627908 0.5755208333333333 0.20348837209302326 0.15625 +0 0.5901162790697674 0.6171875 0.20348837209302326 0.15625 +0 0.15988372093023256 0.20833333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fb162b8848d3b4d814ebeeef4e055cb7.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fb162b8848d3b4d814ebeeef4e055cb7.txt new file mode 100644 index 0000000..c020061 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fb162b8848d3b4d814ebeeef4e055cb7.txt @@ -0,0 +1,4 @@ +0 0.7761627906976744 0.6041666666666666 0.20348837209302326 0.15625 +0 0.33430232558139533 0.11197916666666666 0.20348837209302326 0.15625 +0 0.2965116279069767 0.4765625 0.20348837209302326 0.15625 +0 0.4883720930232558 0.7135416666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fb9c3337c7bb67f82c60e95e883e49fa.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fb9c3337c7bb67f82c60e95e883e49fa.txt new file mode 100644 index 0000000..0ccfcea --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fb9c3337c7bb67f82c60e95e883e49fa.txt @@ -0,0 +1,5 @@ +0 0.45930232558139533 0.203125 0.20348837209302326 0.15625 +0 0.7238372093023255 0.4921875 0.20348837209302326 0.15625 +0 0.2063953488372093 0.7604166666666666 0.20348837209302326 0.15625 +0 0.19186046511627908 0.22135416666666666 0.20348837209302326 0.15625 +0 0.8662790697674418 0.7421875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fc687339c6964908a927657374dc0f0d.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fc687339c6964908a927657374dc0f0d.txt new file mode 100644 index 0000000..a5e32c9 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fc687339c6964908a927657374dc0f0d.txt @@ -0,0 +1,4 @@ +0 0.5523255813953488 0.7578125 0.20348837209302326 0.15625 +0 0.5058139534883721 0.45572916666666663 0.20348837209302326 0.15625 +0 0.22093023255813954 0.21614583333333331 0.20348837209302326 0.15625 +0 0.1308139534883721 0.7552083333333333 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fd2e892a2768cf93c57af72355073882.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fd2e892a2768cf93c57af72355073882.txt new file mode 100644 index 0000000..335de1c --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fd2e892a2768cf93c57af72355073882.txt @@ -0,0 +1,5 @@ +0 0.6191860465116279 0.09895833333333333 0.20348837209302326 0.15625 +0 0.3633720930232558 0.40104166666666663 0.20348837209302326 0.15625 +0 0.32848837209302323 0.14583333333333331 0.20348837209302326 0.15625 +0 0.6308139534883721 0.6354166666666666 0.20348837209302326 0.15625 +0 0.2936046511627907 0.671875 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fd5d72dcfdee2a36615a11ad69077808.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fd5d72dcfdee2a36615a11ad69077808.txt new file mode 100644 index 0000000..a5a0c7e --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/fd5d72dcfdee2a36615a11ad69077808.txt @@ -0,0 +1,4 @@ +0 0.8546511627906976 0.671875 0.20348837209302326 0.15625 +0 0.2441860465116279 0.27604166666666663 0.20348837209302326 0.15625 +0 0.5552325581395349 0.5625 0.20348837209302326 0.15625 +0 0.5901162790697674 0.17708333333333331 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ff0817df5eb677c91d4dda6c1d4074dc.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ff0817df5eb677c91d4dda6c1d4074dc.txt new file mode 100644 index 0000000..7e760c0 --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ff0817df5eb677c91d4dda6c1d4074dc.txt @@ -0,0 +1,4 @@ +0 0.6947674418604651 0.14583333333333331 0.20348837209302326 0.15625 +0 0.3633720930232558 0.7057291666666666 0.20348837209302326 0.15625 +0 0.3226744186046512 0.38541666666666663 0.20348837209302326 0.15625 +0 0.6831395348837209 0.7994791666666666 0.20348837209302326 0.15625 diff --git a/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ff9f936e5f3dd45ab09465d39d379763.txt b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ff9f936e5f3dd45ab09465d39d379763.txt new file mode 100644 index 0000000..934648f --- /dev/null +++ b/hanzi_detection/files/valid/jiyan_valid_imgs_txt_500/ff9f936e5f3dd45ab09465d39d379763.txt @@ -0,0 +1,4 @@ +0 0.6075581395348837 0.765625 0.20348837209302326 0.15625 +0 0.6686046511627907 0.40625 0.20348837209302326 0.15625 +0 0.15406976744186046 0.4114583333333333 0.20348837209302326 0.15625 +0 0.21511627906976744 0.65625 0.20348837209302326 0.15625 diff --git a/hanzi_detection/include/darknet.h b/hanzi_detection/include/darknet.h new file mode 100755 index 0000000..4390c61 --- /dev/null +++ b/hanzi_detection/include/darknet.h @@ -0,0 +1,805 @@ +#ifndef DARKNET_API +#define DARKNET_API +#include +#include +#include +#include + +#ifdef GPU + #define BLOCK 512 + + #include "cuda_runtime.h" + #include "curand.h" + #include "cublas_v2.h" + + #ifdef CUDNN + #include "cudnn.h" + #endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define SECRET_NUM -1234 +extern int gpu_index; + +typedef struct{ + int classes; + char **names; +} metadata; + +metadata get_metadata(char *file); + +typedef struct{ + int *leaf; + int n; + int *parent; + int *child; + int *group; + char **name; + + int groups; + int *group_size; + int *group_offset; +} tree; +tree *read_tree(char *filename); + +typedef enum{ + LOGISTIC, RELU, RELIE, LINEAR, RAMP, TANH, PLSE, LEAKY, ELU, LOGGY, STAIR, HARDTAN, LHTAN, SELU +} ACTIVATION; + +typedef enum{ + PNG, BMP, TGA, JPG +} IMTYPE; + +typedef enum{ + MULT, ADD, SUB, DIV +} BINARY_ACTIVATION; + +typedef enum { + CONVOLUTIONAL, + DECONVOLUTIONAL, + CONNECTED, + MAXPOOL, + SOFTMAX, + DETECTION, + DROPOUT, + CROP, + ROUTE, + COST, + NORMALIZATION, + AVGPOOL, + LOCAL, + SHORTCUT, + ACTIVE, + RNN, + GRU, + LSTM, + CRNN, + BATCHNORM, + NETWORK, + XNOR, + REGION, + YOLO, + ISEG, + REORG, + UPSAMPLE, + LOGXENT, + L2NORM, + BLANK +} LAYER_TYPE; + +typedef enum{ + SSE, MASKED, L1, SEG, SMOOTH,WGAN +} COST_TYPE; + +typedef struct{ + int batch; + float learning_rate; + float momentum; + float decay; + int adam; + float B1; + float B2; + float eps; + int t; +} update_args; + +struct network; +typedef struct network network; + +struct layer; +typedef struct layer layer; + +struct layer{ + LAYER_TYPE type; + ACTIVATION activation; + COST_TYPE cost_type; + void (*forward) (struct layer, struct network); + void (*backward) (struct layer, struct network); + void (*update) (struct layer, update_args); + void (*forward_gpu) (struct layer, struct network); + void (*backward_gpu) (struct layer, struct network); + void (*update_gpu) (struct layer, update_args); + int batch_normalize; + int shortcut; + int batch; + int forced; + int flipped; + int inputs; + int outputs; + int nweights; + int nbiases; + int extra; + int truths; + int h,w,c; + int out_h, out_w, out_c; + int n; + int max_boxes; + int groups; + int size; + int side; + int stride; + int reverse; + int flatten; + int spatial; + int pad; + int sqrt; + int flip; + int index; + int binary; + int xnor; + int steps; + int hidden; + int truth; + float smooth; + float dot; + float angle; + float jitter; + float saturation; + float exposure; + float shift; + float ratio; + float learning_rate_scale; + float clip; + int noloss; + int softmax; + int classes; + int coords; + int background; + int rescore; + int objectness; + int joint; + int noadjust; + int reorg; + int log; + int tanh; + int *mask; + int total; + + float alpha; + float beta; + float kappa; + + float coord_scale; + float object_scale; + float noobject_scale; + float mask_scale; + float class_scale; + int bias_match; + int random; + float ignore_thresh; + float truth_thresh; + float thresh; + float focus; + int classfix; + int absolute; + + int onlyforward; + int stopbackward; + int dontload; + int dontsave; + int dontloadscales; + int numload; + + float temperature; + float probability; + float scale; + + char * cweights; + int * indexes; + int * input_layers; + int * input_sizes; + int * map; + int * counts; + float ** sums; + float * rand; + float * cost; + float * state; + float * prev_state; + float * forgot_state; + float * forgot_delta; + float * state_delta; + float * combine_cpu; + float * combine_delta_cpu; + + float * concat; + float * concat_delta; + + float * binary_weights; + + float * biases; + float * bias_updates; + + float * scales; + float * scale_updates; + + float * weights; + float * weight_updates; + + float * delta; + float * output; + float * loss; + float * squared; + float * norms; + + float * spatial_mean; + float * mean; + float * variance; + + float * mean_delta; + float * variance_delta; + + float * rolling_mean; + float * rolling_variance; + + float * x; + float * x_norm; + + float * m; + float * v; + + float * bias_m; + float * bias_v; + float * scale_m; + float * scale_v; + + + float *z_cpu; + float *r_cpu; + float *h_cpu; + float * prev_state_cpu; + + float *temp_cpu; + float *temp2_cpu; + float *temp3_cpu; + + float *dh_cpu; + float *hh_cpu; + float *prev_cell_cpu; + float *cell_cpu; + float *f_cpu; + float *i_cpu; + float *g_cpu; + float *o_cpu; + float *c_cpu; + float *dc_cpu; + + float * binary_input; + + struct layer *input_layer; + struct layer *self_layer; + struct layer *output_layer; + + struct layer *reset_layer; + struct layer *update_layer; + struct layer *state_layer; + + struct layer *input_gate_layer; + struct layer *state_gate_layer; + struct layer *input_save_layer; + struct layer *state_save_layer; + struct layer *input_state_layer; + struct layer *state_state_layer; + + struct layer *input_z_layer; + struct layer *state_z_layer; + + struct layer *input_r_layer; + struct layer *state_r_layer; + + struct layer *input_h_layer; + struct layer *state_h_layer; + + struct layer *wz; + struct layer *uz; + struct layer *wr; + struct layer *ur; + struct layer *wh; + struct layer *uh; + struct layer *uo; + struct layer *wo; + struct layer *uf; + struct layer *wf; + struct layer *ui; + struct layer *wi; + struct layer *ug; + struct layer *wg; + + tree *softmax_tree; + + size_t workspace_size; + +#ifdef GPU + int *indexes_gpu; + + float *z_gpu; + float *r_gpu; + float *h_gpu; + + float *temp_gpu; + float *temp2_gpu; + float *temp3_gpu; + + float *dh_gpu; + float *hh_gpu; + float *prev_cell_gpu; + float *cell_gpu; + float *f_gpu; + float *i_gpu; + float *g_gpu; + float *o_gpu; + float *c_gpu; + float *dc_gpu; + + float *m_gpu; + float *v_gpu; + float *bias_m_gpu; + float *scale_m_gpu; + float *bias_v_gpu; + float *scale_v_gpu; + + float * combine_gpu; + float * combine_delta_gpu; + + float * prev_state_gpu; + float * forgot_state_gpu; + float * forgot_delta_gpu; + float * state_gpu; + float * state_delta_gpu; + float * gate_gpu; + float * gate_delta_gpu; + float * save_gpu; + float * save_delta_gpu; + float * concat_gpu; + float * concat_delta_gpu; + + float * binary_input_gpu; + float * binary_weights_gpu; + + float * mean_gpu; + float * variance_gpu; + + float * rolling_mean_gpu; + float * rolling_variance_gpu; + + float * variance_delta_gpu; + float * mean_delta_gpu; + + float * x_gpu; + float * x_norm_gpu; + float * weights_gpu; + float * weight_updates_gpu; + float * weight_change_gpu; + + float * biases_gpu; + float * bias_updates_gpu; + float * bias_change_gpu; + + float * scales_gpu; + float * scale_updates_gpu; + float * scale_change_gpu; + + float * output_gpu; + float * loss_gpu; + float * delta_gpu; + float * rand_gpu; + float * squared_gpu; + float * norms_gpu; +#ifdef CUDNN + cudnnTensorDescriptor_t srcTensorDesc, dstTensorDesc; + cudnnTensorDescriptor_t dsrcTensorDesc, ddstTensorDesc; + cudnnTensorDescriptor_t normTensorDesc; + cudnnFilterDescriptor_t weightDesc; + cudnnFilterDescriptor_t dweightDesc; + cudnnConvolutionDescriptor_t convDesc; + cudnnConvolutionFwdAlgo_t fw_algo; + cudnnConvolutionBwdDataAlgo_t bd_algo; + cudnnConvolutionBwdFilterAlgo_t bf_algo; +#endif +#endif +}; + +void free_layer(layer); + +typedef enum { + CONSTANT, STEP, EXP, POLY, STEPS, SIG, RANDOM +} learning_rate_policy; + +typedef struct network{ + int n; + int batch; + size_t *seen; + int *t; + float epoch; + int subdivisions; + layer *layers; + float *output; + learning_rate_policy policy; + + float learning_rate; + float momentum; + float decay; + float gamma; + float scale; + float power; + int time_steps; + int step; + int max_batches; + float *scales; + int *steps; + int num_steps; + int burn_in; + + int adam; + float B1; + float B2; + float eps; + + int inputs; + int outputs; + int truths; + int notruth; + int h, w, c; + int max_crop; + int min_crop; + float max_ratio; + float min_ratio; + int center; + float angle; + float aspect; + float exposure; + float saturation; + float hue; + int random; + + int gpu_index; + tree *hierarchy; + + float *input; + float *truth; + float *delta; + float *workspace; + int train; + int index; + float *cost; + float clip; + +#ifdef GPU + float *input_gpu; + float *truth_gpu; + float *delta_gpu; + float *output_gpu; +#endif + +} network; + +typedef struct { + int w; + int h; + float scale; + float rad; + float dx; + float dy; + float aspect; +} augment_args; + +typedef struct { + int w; + int h; + int c; + float *data; +} image; + +typedef struct{ + float x, y, w, h; +} box; + +typedef struct detection{ + box bbox; + int classes; + float *prob; + float *mask; + float objectness; + int sort_class; +} detection; + +typedef struct matrix{ + int rows, cols; + float **vals; +} matrix; + + +typedef struct{ + int w, h; + matrix X; + matrix y; + int shallow; + int *num_boxes; + box **boxes; +} data; + +typedef enum { + CLASSIFICATION_DATA, DETECTION_DATA, CAPTCHA_DATA, REGION_DATA, IMAGE_DATA, COMPARE_DATA, WRITING_DATA, SWAG_DATA, TAG_DATA, OLD_CLASSIFICATION_DATA, STUDY_DATA, DET_DATA, SUPER_DATA, LETTERBOX_DATA, REGRESSION_DATA, SEGMENTATION_DATA, INSTANCE_DATA, ISEG_DATA +} data_type; + +typedef struct load_args{ + int threads; + char **paths; + char *path; + int n; + int m; + char **labels; + int h; + int w; + int out_w; + int out_h; + int nh; + int nw; + int num_boxes; + int min, max, size; + int classes; + int background; + int scale; + int center; + int coords; + float jitter; + float angle; + float aspect; + float saturation; + float exposure; + float hue; + data *d; + image *im; + image *resized; + data_type type; + tree *hierarchy; +} load_args; + +typedef struct{ + int id; + float x,y,w,h; + float left, right, top, bottom; +} box_label; + + +network *load_network(char *cfg, char *weights, int clear); +load_args get_base_args(network *net); + +void free_data(data d); + +typedef struct node{ + void *val; + struct node *next; + struct node *prev; +} node; + +typedef struct list{ + int size; + node *front; + node *back; +} list; + +pthread_t load_data(load_args args); +list *read_data_cfg(char *filename); +list *read_cfg(char *filename); +unsigned char *read_file(char *filename); +data resize_data(data orig, int w, int h); +data *tile_data(data orig, int divs, int size); +data select_data(data *orig, int *inds); + +void forward_network(network *net); +void backward_network(network *net); +void update_network(network *net); + + +float dot_cpu(int N, float *X, int INCX, float *Y, int INCY); +void axpy_cpu(int N, float ALPHA, float *X, int INCX, float *Y, int INCY); +void copy_cpu(int N, float *X, int INCX, float *Y, int INCY); +void scal_cpu(int N, float ALPHA, float *X, int INCX); +void fill_cpu(int N, float ALPHA, float * X, int INCX); +void normalize_cpu(float *x, float *mean, float *variance, int batch, int filters, int spatial); +void softmax(float *input, int n, float temp, int stride, float *output); + +int best_3d_shift_r(image a, image b, int min, int max); +#ifdef GPU +void axpy_gpu(int N, float ALPHA, float * X, int INCX, float * Y, int INCY); +void fill_gpu(int N, float ALPHA, float * X, int INCX); +void scal_gpu(int N, float ALPHA, float * X, int INCX); +void copy_gpu(int N, float * X, int INCX, float * Y, int INCY); + +void cuda_set_device(int n); +void cuda_free(float *x_gpu); +float *cuda_make_array(float *x, size_t n); +void cuda_pull_array(float *x_gpu, float *x, size_t n); +float cuda_mag_array(float *x_gpu, size_t n); +void cuda_push_array(float *x_gpu, float *x, size_t n); + +void forward_network_gpu(network *net); +void backward_network_gpu(network *net); +void update_network_gpu(network *net); + +float train_networks(network **nets, int n, data d, int interval); +void sync_nets(network **nets, int n, int interval); +void harmless_update_network_gpu(network *net); +#endif +image get_label(image **characters, char *string, int size); +void draw_label(image a, int r, int c, image label, const float *rgb); +void save_image(image im, const char *name); +void save_image_options(image im, const char *name, IMTYPE f, int quality); +void get_next_batch(data d, int n, int offset, float *X, float *y); +void grayscale_image_3c(image im); +void normalize_image(image p); +void matrix_to_csv(matrix m); +float train_network_sgd(network *net, data d, int n); +void rgbgr_image(image im); +data copy_data(data d); +data concat_data(data d1, data d2); +data load_cifar10_data(char *filename); +float matrix_topk_accuracy(matrix truth, matrix guess, int k); +void matrix_add_matrix(matrix from, matrix to); +void scale_matrix(matrix m, float scale); +matrix csv_to_matrix(char *filename); +float *network_accuracies(network *net, data d, int n); +float train_network_datum(network *net); +image make_random_image(int w, int h, int c); + +void denormalize_connected_layer(layer l); +void denormalize_convolutional_layer(layer l); +void statistics_connected_layer(layer l); +void rescale_weights(layer l, float scale, float trans); +void rgbgr_weights(layer l); +image *get_weights(layer l); + +void demo(char *cfgfile, char *weightfile, float thresh, int cam_index, const char *filename, char **names, int classes, int frame_skip, char *prefix, int avg, float hier_thresh, int w, int h, int fps, int fullscreen); +void get_detection_detections(layer l, int w, int h, float thresh, detection *dets); + +char *option_find_str(list *l, char *key, char *def); +int option_find_int(list *l, char *key, int def); +int option_find_int_quiet(list *l, char *key, int def); + +network *parse_network_cfg(char *filename); +void save_weights(network *net, char *filename); +void load_weights(network *net, char *filename); +void save_weights_upto(network *net, char *filename, int cutoff); +void load_weights_upto(network *net, char *filename, int start, int cutoff); + +void zero_objectness(layer l); +void get_region_detections(layer l, int w, int h, int netw, int neth, float thresh, int *map, float tree_thresh, int relative, detection *dets); +int get_yolo_detections(layer l, int w, int h, int netw, int neth, float thresh, int *map, int relative, detection *dets); +void free_network(network *net); +void set_batch_network(network *net, int b); +void set_temp_network(network *net, float t); +image load_image(char *filename, int w, int h, int c); +image load_image_color(char *filename, int w, int h); +image make_image(int w, int h, int c); +image resize_image(image im, int w, int h); +void censor_image(image im, int dx, int dy, int w, int h); +image letterbox_image(image im, int w, int h); +image crop_image(image im, int dx, int dy, int w, int h); +image center_crop_image(image im, int w, int h); +image resize_min(image im, int min); +image resize_max(image im, int max); +image threshold_image(image im, float thresh); +image mask_to_rgb(image mask); +int resize_network(network *net, int w, int h); +void free_matrix(matrix m); +void test_resize(char *filename); +int show_image(image p, const char *name, int ms); +image copy_image(image p); +void draw_box_width(image a, int x1, int y1, int x2, int y2, int w, float r, float g, float b); +float get_current_rate(network *net); +void composite_3d(char *f1, char *f2, char *out, int delta); +data load_data_old(char **paths, int n, int m, char **labels, int k, int w, int h); +size_t get_current_batch(network *net); +void constrain_image(image im); +image get_network_image_layer(network *net, int i); +layer get_network_output_layer(network *net); +void top_predictions(network *net, int n, int *index); +void flip_image(image a); +image float_to_image(int w, int h, int c, float *data); +void ghost_image(image source, image dest, int dx, int dy); +float network_accuracy(network *net, data d); +void random_distort_image(image im, float hue, float saturation, float exposure); +void fill_image(image m, float s); +image grayscale_image(image im); +void rotate_image_cw(image im, int times); +double what_time_is_it_now(); +image rotate_image(image m, float rad); +void visualize_network(network *net); +float box_iou(box a, box b); +data load_all_cifar10(); +box_label *read_boxes(char *filename, int *n); +box float_to_box(float *f, int stride); +void draw_detections(image im, detection *dets, int num, float thresh, char **names, image **alphabet, int classes); + +matrix network_predict_data(network *net, data test); +image **load_alphabet(); +image get_network_image(network *net); +float *network_predict(network *net, float *input); + +int network_width(network *net); +int network_height(network *net); +float *network_predict_image(network *net, image im); +void network_detect(network *net, image im, float thresh, float hier_thresh, float nms, detection *dets); +detection *get_network_boxes(network *net, int w, int h, float thresh, float hier, int *map, int relative, int *num); +void free_detections(detection *dets, int n); + +void reset_network_state(network *net, int b); + +char **get_labels(char *filename); +void do_nms_obj(detection *dets, int total, int classes, float thresh); +void do_nms_sort(detection *dets, int total, int classes, float thresh); + +matrix make_matrix(int rows, int cols); + +#ifdef OPENCV +void *open_video_stream(const char *f, int c, int w, int h, int fps); +image get_image_from_stream(void *p); +void make_window(char *name, int w, int h, int fullscreen); +#endif + +void free_image(image m); +float train_network(network *net, data d); +pthread_t load_data_in_thread(load_args args); +void load_data_blocking(load_args args); +list *get_paths(char *filename); +void hierarchy_predictions(float *predictions, int n, tree *hier, int only_leaves, int stride); +void change_leaves(tree *t, char *leaf_list); + +int find_int_arg(int argc, char **argv, char *arg, int def); +float find_float_arg(int argc, char **argv, char *arg, float def); +int find_arg(int argc, char* argv[], char *arg); +char *find_char_arg(int argc, char **argv, char *arg, char *def); +char *basecfg(char *cfgfile); +void find_replace(char *str, char *orig, char *rep, char *output); +void free_ptrs(void **ptrs, int n); +char *fgetl(FILE *fp); +void strip(char *s); +float sec(clock_t clocks); +void **list_to_array(list *l); +void top_k(float *a, int n, int k, int *index); +int *read_map(char *filename); +void error(const char *s); +int max_index(float *a, int n); +int max_int_index(int *a, int n); +int sample_array(float *a, int n); +int *random_index_order(int min, int max); +void free_list(list *l); +float mse_array(float *a, int n); +float variance_array(float *a, int n); +float mag_array(float *a, int n); +void scale_array(float *a, int n, float s); +float mean_array(float *a, int n); +float sum_array(float *a, int n); +void normalize_array(float *a, int n); +int *read_intlist(char *s, int *n, int d); +size_t rand_size_t(); +float rand_normal(); +float rand_uniform(float min, float max); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/hanzi_detection/libdarknet.so b/hanzi_detection/libdarknet.so new file mode 100755 index 0000000000000000000000000000000000000000..e9ad8777591199e492c7faefd5221eb934e922b7 GIT binary patch literal 538900 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

X7iTNo) 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 literal 0 HcmV?d00001 diff --git a/hanzi_detection/model/jiyan_classify.cfg b/hanzi_detection/model/jiyan_classify.cfg new file mode 100755 index 0000000..05c8d09 --- /dev/null +++ b/hanzi_detection/model/jiyan_classify.cfg @@ -0,0 +1,83 @@ +[net] +#batch=128 +batch=64 +subdivisions=1 +height=64 +width=64 +channels=3 +max_crop=64 +min_crop=64 +angle=7 +hue=.1 +saturation=.75 +exposure=.75 + +learning_rate=0.1 +policy=poly +power=4 +max_batches = 85000 +momentum=0.9 +decay=0.0005 + + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[maxpool] +size=2 +stride=2 + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[maxpool] +size=2 +stride=2 + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[maxpool] +size=2 +stride=2 + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + + +[convolutional] +filters=1238 +size=1 +stride=1 +pad=1 +activation=leaky + +[avgpool] + +[softmax] +groups=1 + +[cost] +type=sse + + diff --git a/hanzi_detection/model/jiyan_yolov3.cfg b/hanzi_detection/model/jiyan_yolov3.cfg new file mode 100755 index 0000000..c0e0e90 --- /dev/null +++ b/hanzi_detection/model/jiyan_yolov3.cfg @@ -0,0 +1,789 @@ +[net] +# Testing +# batch=1 +# subdivisions=1 +# Training +batch=64 +subdivisions=64 +width=608 +height=608 +channels=3 +momentum=0.9 +decay=0.0005 +angle=0 +saturation = 1.5 +exposure = 1.5 +hue=.1 + +learning_rate=0.001 +burn_in=1000 +max_batches = 1500 +policy=steps +steps=400000,450000 +scales=.1,.1 + +[convolutional] +batch_normalize=1 +filters=32 +size=3 +stride=1 +pad=1 +activation=leaky + +# Downsample + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=32 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +# Downsample + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +[shortcut] +from=-3 +activation=linear + +###################### + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=18 +activation=linear + + +[yolo] +mask = 6,7,8 +anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 +classes=1 +num=9 +jitter=.3 +ignore_thresh = .7 +truth_thresh = 1 +random=1 + + +[route] +layers = -4 + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = -1, 61 + + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=18 +activation=linear + + +[yolo] +mask = 3,4,5 +anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 +classes=1 +num=9 +jitter=.3 +ignore_thresh = .7 +truth_thresh = 1 +random=1 + + + +[route] +layers = -4 + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = -1, 36 + + + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=18 +activation=linear + + +[yolo] +mask = 0,1,2 +anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 +classes=1 +num=9 +jitter=.3 +ignore_thresh = .7 +truth_thresh = 1 +random=1 + diff --git a/hanzi_detection/python/darknet.py b/hanzi_detection/python/darknet.py new file mode 100755 index 0000000..d5f8ad9 --- /dev/null +++ b/hanzi_detection/python/darknet.py @@ -0,0 +1,156 @@ +from ctypes import * +import math +import random + +def sample(probs): + s = sum(probs) + probs = [a/s for a in probs] + r = random.uniform(0, 1) + for i in range(len(probs)): + r = r - probs[i] + if r <= 0: + return i + return len(probs)-1 + +def c_array(ctype, values): + arr = (ctype*len(values))() + arr[:] = values + return arr + +class BOX(Structure): + _fields_ = [("x", c_float), + ("y", c_float), + ("w", c_float), + ("h", c_float)] + +class DETECTION(Structure): + _fields_ = [("bbox", BOX), + ("classes", c_int), + ("prob", POINTER(c_float)), + ("mask", POINTER(c_float)), + ("objectness", c_float), + ("sort_class", c_int)] + + +class IMAGE(Structure): + _fields_ = [("w", c_int), + ("h", c_int), + ("c", c_int), + ("data", POINTER(c_float))] + +class METADATA(Structure): + _fields_ = [("classes", c_int), + ("names", POINTER(c_char_p))] + + + +#lib = CDLL("/home/pjreddie/documents/darknet/libdarknet.so", RTLD_GLOBAL) +lib = CDLL("libdarknet.so", RTLD_GLOBAL) +lib.network_width.argtypes = [c_void_p] +lib.network_width.restype = c_int +lib.network_height.argtypes = [c_void_p] +lib.network_height.restype = c_int + +predict = lib.network_predict +predict.argtypes = [c_void_p, POINTER(c_float)] +predict.restype = POINTER(c_float) + +set_gpu = lib.cuda_set_device +set_gpu.argtypes = [c_int] + +make_image = lib.make_image +make_image.argtypes = [c_int, c_int, c_int] +make_image.restype = IMAGE + +get_network_boxes = lib.get_network_boxes +get_network_boxes.argtypes = [c_void_p, c_int, c_int, c_float, c_float, POINTER(c_int), c_int, POINTER(c_int)] +get_network_boxes.restype = POINTER(DETECTION) + +make_network_boxes = lib.make_network_boxes +make_network_boxes.argtypes = [c_void_p] +make_network_boxes.restype = POINTER(DETECTION) + +free_detections = lib.free_detections +free_detections.argtypes = [POINTER(DETECTION), c_int] + +free_ptrs = lib.free_ptrs +free_ptrs.argtypes = [POINTER(c_void_p), c_int] + +network_predict = lib.network_predict +network_predict.argtypes = [c_void_p, POINTER(c_float)] + +reset_rnn = lib.reset_rnn +reset_rnn.argtypes = [c_void_p] + +load_net = lib.load_network +load_net.argtypes = [c_char_p, c_char_p, c_int] +load_net.restype = c_void_p + +do_nms_obj = lib.do_nms_obj +do_nms_obj.argtypes = [POINTER(DETECTION), c_int, c_int, c_float] + +do_nms_sort = lib.do_nms_sort +do_nms_sort.argtypes = [POINTER(DETECTION), c_int, c_int, c_float] + +free_image = lib.free_image +free_image.argtypes = [IMAGE] + +letterbox_image = lib.letterbox_image +letterbox_image.argtypes = [IMAGE, c_int, c_int] +letterbox_image.restype = IMAGE + +load_meta = lib.get_metadata +lib.get_metadata.argtypes = [c_char_p] +lib.get_metadata.restype = METADATA + +load_image = lib.load_image_color +load_image.argtypes = [c_char_p, c_int, c_int] +load_image.restype = IMAGE + +rgbgr_image = lib.rgbgr_image +rgbgr_image.argtypes = [IMAGE] + +predict_image = lib.network_predict_image +predict_image.argtypes = [c_void_p, IMAGE] +predict_image.restype = POINTER(c_float) + +def classify(net, meta, im): + out = predict_image(net, im) + res = [] + for i in range(meta.classes): + res.append((meta.names[i], out[i])) + res = sorted(res, key=lambda x: -x[1]) + return res + +def detect(net, meta, image, thresh=.5, hier_thresh=.5, nms=.45): + im = load_image(image, 0, 0) + num = c_int(0) + pnum = pointer(num) + predict_image(net, im) + dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, None, 0, pnum) + num = pnum[0] + if (nms): do_nms_obj(dets, num, meta.classes, nms); + + res = [] + for j in range(num): + for i in range(meta.classes): + if dets[j].prob[i] > 0: + b = dets[j].bbox + res.append((meta.names[i], dets[j].prob[i], (b.x, b.y, b.w, b.h))) + res = sorted(res, key=lambda x: -x[1]) + free_image(im) + free_detections(dets, num) + return res + +def run(): + net = load_net("cfg/tiny-yolo.cfg", "tiny-yolo.weights", 0) + meta = load_meta("cfg/coco.data") + r = detect(net, meta, "data/dog.jpg") + print(r) + +if __name__ == "__main__": + run() + + + + diff --git a/hanzi_detection/python/proverbot.py b/hanzi_detection/python/proverbot.py new file mode 100755 index 0000000..3a977d0 --- /dev/null +++ b/hanzi_detection/python/proverbot.py @@ -0,0 +1,37 @@ +from nine import * + +def predict_tactic(net, s): + prob = 0 + d = c_array(c_float, [0.0]*256) + tac = '' + if not len(s): + s = '\n' + for c in s[:-1]: + d[ord(c)] = 1 + pred = predict(net, d) + d[ord(c)] = 0 + c = s[-1] + while 1: + d[ord(c)] = 1 + pred = predict(net, d) + d[ord(c)] = 0 + pred = [pred[i] for i in range(256)] + ind = sample(pred) + c = chr(ind) + prob += math.log(pred[ind]) + if len(tac) and tac[-1] == '.': + break + tac = tac + c + return (tac, prob) + +def predict_tactics(net, s, n): + tacs = [] + for i in range(n): + reset_rnn(net) + tacs.append(predict_tactic(net, s)) + tacs = sorted(tacs, key=lambda x: -x[1]) + return tacs + +net = load_net("cfg/coq.test.cfg", "/home/pjreddie/backup/coq.backup", 0) +t = predict_tactics(net, "+++++\n", 10) +print t diff --git a/hanzi_detection/readme_classify.md b/hanzi_detection/readme_classify.md new file mode 100644 index 0000000..36a54ca --- /dev/null +++ b/hanzi_detection/readme_classify.md @@ -0,0 +1,20 @@ +## 汉字分类识别模型文档 + +和检测模型一样使用yolo算法,同样在检测模型项目下进行。 + +提示:backup/ 文件夹下缺少权重文件,不是我不想传,是大于100M的文件Git传不了。如果需要,微信跟我要吧。 + +### 使用方法 + +预测:`./darknet classify predict data/jiyan_classify.data model/jiyan_classify.cfg backup/jiyan_classify_final.weights` + + + +![classify_test](./classify_test.jpg) + + + +```shell +[('池', 0.8325800895690918), ('施', 0.027770591899752617)] +``` + diff --git a/hanzi_detection/scripts/dice_label.sh b/hanzi_detection/scripts/dice_label.sh new file mode 100755 index 0000000..f19f8a4 --- /dev/null +++ b/hanzi_detection/scripts/dice_label.sh @@ -0,0 +1,20 @@ +mkdir -p images +mkdir -p images/orig +mkdir -p images/train +mkdir -p images/val + +ffmpeg -i Face1.mp4 images/orig/face1_%6d.jpg +ffmpeg -i Face2.mp4 images/orig/face2_%6d.jpg +ffmpeg -i Face3.mp4 images/orig/face3_%6d.jpg +ffmpeg -i Face4.mp4 images/orig/face4_%6d.jpg +ffmpeg -i Face5.mp4 images/orig/face5_%6d.jpg +ffmpeg -i Face6.mp4 images/orig/face6_%6d.jpg + +mogrify -resize 100x100^ -gravity center -crop 100x100+0+0 +repage images/orig/* + +ls images/orig/* | shuf | head -n 1000 | xargs mv -t images/val +mv images/orig/* images/train + +find `pwd`/images/train > dice.train.list -name \*.jpg +find `pwd`/images/val > dice.val.list -name \*.jpg + diff --git a/hanzi_detection/scripts/gen_tactic.sh b/hanzi_detection/scripts/gen_tactic.sh new file mode 100755 index 0000000..ffa30d2 --- /dev/null +++ b/hanzi_detection/scripts/gen_tactic.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# Usage: +# wget http://pjreddie.com/media/files/peek.weights +# scripts/gen_tactic.sh < data/goal.txt +./darknet rnn generatetactic cfg/gru.cfg peek.weights 2>/dev/null diff --git a/hanzi_detection/scripts/get_coco_dataset.sh b/hanzi_detection/scripts/get_coco_dataset.sh new file mode 100755 index 0000000..2846301 --- /dev/null +++ b/hanzi_detection/scripts/get_coco_dataset.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Clone COCO API +git clone https://github.com/pdollar/coco +cd coco + +mkdir images +cd images + +# Download Images +wget -c https://pjreddie.com/media/files/train2014.zip +wget -c https://pjreddie.com/media/files/val2014.zip + +# Unzip +unzip -q train2014.zip +unzip -q val2014.zip + +cd .. + +# Download COCO Metadata +wget -c https://pjreddie.com/media/files/instances_train-val2014.zip +wget -c https://pjreddie.com/media/files/coco/5k.part +wget -c https://pjreddie.com/media/files/coco/trainvalno5k.part +wget -c https://pjreddie.com/media/files/coco/labels.tgz +tar xzf labels.tgz +unzip -q instances_train-val2014.zip + +# Set Up Image Lists +paste <(awk "{print \"$PWD\"}" <5k.part) 5k.part | tr -d '\t' > 5k.txt +paste <(awk "{print \"$PWD\"}" trainvalno5k.txt + diff --git a/hanzi_detection/scripts/imagenet_label.sh b/hanzi_detection/scripts/imagenet_label.sh new file mode 100755 index 0000000..01e4306 --- /dev/null +++ b/hanzi_detection/scripts/imagenet_label.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +mkdir -p labelled +wd=`pwd` + +for f in val/*.xml; +do +label=`grep -m1 "" $f | grep -oP '\K[^<]*'` +im=`echo $f | sed 's/val/imgs/; s/xml/JPEG/'` +out=`echo $im | sed 's/JPEG/'${label}'.JPEG/; s/imgs/labelled/'` +ln -s ${wd}/$im ${wd}/$out +done + +find ${wd}/labelled -name \*.JPEG > inet.val.list + diff --git a/hanzi_detection/scripts/voc_label.py b/hanzi_detection/scripts/voc_label.py new file mode 100755 index 0000000..679fc36 --- /dev/null +++ b/hanzi_detection/scripts/voc_label.py @@ -0,0 +1,59 @@ +import xml.etree.ElementTree as ET +import pickle +import os +from os import listdir, getcwd +from os.path import join + +sets=[('2012', 'train'), ('2012', 'val'), ('2007', 'train'), ('2007', 'val'), ('2007', 'test')] + +classes = ["aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"] + + +def convert(size, box): + dw = 1./(size[0]) + dh = 1./(size[1]) + x = (box[0] + box[1])/2.0 - 1 + y = (box[2] + box[3])/2.0 - 1 + w = box[1] - box[0] + h = box[3] - box[2] + x = x*dw + w = w*dw + y = y*dh + h = h*dh + return (x,y,w,h) + +def convert_annotation(year, image_id): + in_file = open('VOCdevkit/VOC%s/Annotations/%s.xml'%(year, image_id)) + out_file = open('VOCdevkit/VOC%s/labels/%s.txt'%(year, image_id), 'w') + tree=ET.parse(in_file) + root = tree.getroot() + size = root.find('size') + w = int(size.find('width').text) + h = int(size.find('height').text) + + for obj in root.iter('object'): + difficult = obj.find('difficult').text + cls = obj.find('name').text + if cls not in classes or int(difficult)==1: + continue + cls_id = classes.index(cls) + xmlbox = obj.find('bndbox') + b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text)) + bb = convert((w,h), b) + out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n') + +wd = getcwd() + +for year, image_set in sets: + if not os.path.exists('VOCdevkit/VOC%s/labels/'%(year)): + os.makedirs('VOCdevkit/VOC%s/labels/'%(year)) + image_ids = open('VOCdevkit/VOC%s/ImageSets/Main/%s.txt'%(year, image_set)).read().strip().split() + list_file = open('%s_%s.txt'%(year, image_set), 'w') + for image_id in image_ids: + list_file.write('%s/VOCdevkit/VOC%s/JPEGImages/%s.jpg\n'%(wd, year, image_id)) + convert_annotation(year, image_id) + list_file.close() + +os.system("cat 2007_train.txt 2007_val.txt 2012_train.txt 2012_val.txt > train.txt") +os.system("cat 2007_train.txt 2007_val.txt 2007_test.txt 2012_train.txt 2012_val.txt > train.all.txt") + diff --git a/hanzi_detection/src/activation_kernels.cu b/hanzi_detection/src/activation_kernels.cu new file mode 100755 index 0000000..4dc5804 --- /dev/null +++ b/hanzi_detection/src/activation_kernels.cu @@ -0,0 +1,206 @@ +#include "cuda_runtime.h" +#include "curand.h" +#include "cublas_v2.h" + +extern "C" { +#include "activations.h" +#include "cuda.h" +} + + +__device__ float lhtan_activate_kernel(float x) +{ + if(x < 0) return .001f*x; + if(x > 1) return .001f*(x-1.f) + 1.f; + return x; +} +__device__ float lhtan_gradient_kernel(float x) +{ + if(x > 0 && x < 1) return 1; + return .001; +} + +__device__ float hardtan_activate_kernel(float x) +{ + if (x < -1) return -1; + if (x > 1) return 1; + return x; +} +__device__ float linear_activate_kernel(float x){return x;} +__device__ float logistic_activate_kernel(float x){return 1.f/(1.f + expf(-x));} +__device__ float loggy_activate_kernel(float x){return 2.f/(1.f + expf(-x)) - 1;} +__device__ float relu_activate_kernel(float x){return x*(x>0);} +__device__ float elu_activate_kernel(float x){return (x >= 0)*x + (x < 0)*(expf(x)-1);} +__device__ float selu_activate_kernel(float x){return (x >= 0)*1.0507f*x + (x < 0)*1.0507f*1.6732f*(expf(x)-1);} +__device__ float relie_activate_kernel(float x){return (x>0) ? x : .01f*x;} +__device__ float ramp_activate_kernel(float x){return x*(x>0)+.1f*x;} +__device__ float leaky_activate_kernel(float x){return (x>0) ? x : .1f*x;} +__device__ float tanh_activate_kernel(float x){return (2.f/(1 + expf(-2*x)) - 1);} +__device__ float plse_activate_kernel(float x) +{ + if(x < -4) return .01f * (x + 4); + if(x > 4) return .01f * (x - 4) + 1; + return .125f*x + .5f; +} +__device__ float stair_activate_kernel(float x) +{ + int n = floorf(x); + if (n%2 == 0) return floorf(x/2); + else return (x - n) + floorf(x/2); +} + + +__device__ float hardtan_gradient_kernel(float x) +{ + if (x > -1 && x < 1) return 1; + return 0; +} +__device__ float linear_gradient_kernel(float x){return 1;} +__device__ float logistic_gradient_kernel(float x){return (1-x)*x;} +__device__ float loggy_gradient_kernel(float x) +{ + float y = (x+1)/2; + return 2*(1-y)*y; +} +__device__ float relu_gradient_kernel(float x){return (x>0);} +__device__ float elu_gradient_kernel(float x){return (x >= 0) + (x < 0)*(x + 1);} +__device__ float selu_gradient_kernel(float x){return (x >= 0)*1.0507 + (x < 0)*(x + 1.0507*1.6732);} +__device__ float relie_gradient_kernel(float x){return (x>0) ? 1 : .01f;} +__device__ float ramp_gradient_kernel(float x){return (x>0)+.1f;} +__device__ float leaky_gradient_kernel(float x){return (x>0) ? 1 : .1f;} +__device__ float tanh_gradient_kernel(float x){return 1-x*x;} +__device__ float plse_gradient_kernel(float x){return (x < 0 || x > 1) ? .01f : .125f;} +__device__ float stair_gradient_kernel(float x) +{ + if (floorf(x) == x) return 0; + return 1; +} + +__device__ float activate_kernel(float x, ACTIVATION a) +{ + switch(a){ + case LINEAR: + return linear_activate_kernel(x); + case LOGISTIC: + return logistic_activate_kernel(x); + case LOGGY: + return loggy_activate_kernel(x); + case RELU: + return relu_activate_kernel(x); + case ELU: + return elu_activate_kernel(x); + case SELU: + return selu_activate_kernel(x); + case RELIE: + return relie_activate_kernel(x); + case RAMP: + return ramp_activate_kernel(x); + case LEAKY: + return leaky_activate_kernel(x); + case TANH: + return tanh_activate_kernel(x); + case PLSE: + return plse_activate_kernel(x); + case STAIR: + return stair_activate_kernel(x); + case HARDTAN: + return hardtan_activate_kernel(x); + case LHTAN: + return lhtan_activate_kernel(x); + } + return 0; +} + +__device__ float gradient_kernel(float x, ACTIVATION a) +{ + switch(a){ + case LINEAR: + return linear_gradient_kernel(x); + case LOGISTIC: + return logistic_gradient_kernel(x); + case LOGGY: + return loggy_gradient_kernel(x); + case RELU: + return relu_gradient_kernel(x); + case ELU: + return elu_gradient_kernel(x); + case SELU: + return selu_gradient_kernel(x); + case RELIE: + return relie_gradient_kernel(x); + case RAMP: + return ramp_gradient_kernel(x); + case LEAKY: + return leaky_gradient_kernel(x); + case TANH: + return tanh_gradient_kernel(x); + case PLSE: + return plse_gradient_kernel(x); + case STAIR: + return stair_gradient_kernel(x); + case HARDTAN: + return hardtan_gradient_kernel(x); + case LHTAN: + return lhtan_gradient_kernel(x); + } + return 0; +} + +__global__ void binary_gradient_array_kernel(float *x, float *dy, int n, int s, BINARY_ACTIVATION a, float *dx) +{ + int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + int i = id % s; + int b = id / s; + float x1 = x[b*s + i]; + float x2 = x[b*s + s/2 + i]; + if(id < n) { + float de = dy[id]; + dx[b*s + i] = x2*de; + dx[b*s + s/2 + i] = x1*de; + } +} + +extern "C" void binary_gradient_array_gpu(float *x, float *dx, int n, int size, BINARY_ACTIVATION a, float *y) +{ + binary_gradient_array_kernel<<>>(x, dx, n/2, size, a, y); + check_error(cudaPeekAtLastError()); +} +__global__ void binary_activate_array_kernel(float *x, int n, int s, BINARY_ACTIVATION a, float *y) +{ + int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + int i = id % s; + int b = id / s; + float x1 = x[b*s + i]; + float x2 = x[b*s + s/2 + i]; + if(id < n) y[id] = x1*x2; +} + +extern "C" void binary_activate_array_gpu(float *x, int n, int size, BINARY_ACTIVATION a, float *y) +{ + binary_activate_array_kernel<<>>(x, n/2, size, a, y); + check_error(cudaPeekAtLastError()); +} + +__global__ void activate_array_kernel(float *x, int n, ACTIVATION a) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < n) x[i] = activate_kernel(x[i], a); +} + +__global__ void gradient_array_kernel(float *x, int n, ACTIVATION a, float *delta) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < n) delta[i] *= gradient_kernel(x[i], a); +} + +extern "C" void activate_array_gpu(float *x, int n, ACTIVATION a) +{ + activate_array_kernel<<>>(x, n, a); + check_error(cudaPeekAtLastError()); +} + +extern "C" void gradient_array_gpu(float *x, int n, ACTIVATION a, float *delta) +{ + gradient_array_kernel<<>>(x, n, a, delta); + check_error(cudaPeekAtLastError()); +} diff --git a/hanzi_detection/src/activation_layer.c b/hanzi_detection/src/activation_layer.c new file mode 100755 index 0000000..b4ba953 --- /dev/null +++ b/hanzi_detection/src/activation_layer.c @@ -0,0 +1,63 @@ +#include "activation_layer.h" +#include "utils.h" +#include "cuda.h" +#include "blas.h" +#include "gemm.h" + +#include +#include +#include +#include + +layer make_activation_layer(int batch, int inputs, ACTIVATION activation) +{ + layer l = {0}; + l.type = ACTIVE; + + l.inputs = inputs; + l.outputs = inputs; + l.batch=batch; + + l.output = calloc(batch*inputs, sizeof(float*)); + l.delta = calloc(batch*inputs, sizeof(float*)); + + l.forward = forward_activation_layer; + l.backward = backward_activation_layer; +#ifdef GPU + l.forward_gpu = forward_activation_layer_gpu; + l.backward_gpu = backward_activation_layer_gpu; + + l.output_gpu = cuda_make_array(l.output, inputs*batch); + l.delta_gpu = cuda_make_array(l.delta, inputs*batch); +#endif + l.activation = activation; + fprintf(stderr, "Activation Layer: %d inputs\n", inputs); + return l; +} + +void forward_activation_layer(layer l, network net) +{ + copy_cpu(l.outputs*l.batch, net.input, 1, l.output, 1); + activate_array(l.output, l.outputs*l.batch, l.activation); +} + +void backward_activation_layer(layer l, network net) +{ + gradient_array(l.output, l.outputs*l.batch, l.activation, l.delta); + copy_cpu(l.outputs*l.batch, l.delta, 1, net.delta, 1); +} + +#ifdef GPU + +void forward_activation_layer_gpu(layer l, network net) +{ + copy_gpu(l.outputs*l.batch, net.input_gpu, 1, l.output_gpu, 1); + activate_array_gpu(l.output_gpu, l.outputs*l.batch, l.activation); +} + +void backward_activation_layer_gpu(layer l, network net) +{ + gradient_array_gpu(l.output_gpu, l.outputs*l.batch, l.activation, l.delta_gpu); + copy_gpu(l.outputs*l.batch, l.delta_gpu, 1, net.delta_gpu, 1); +} +#endif diff --git a/hanzi_detection/src/activation_layer.h b/hanzi_detection/src/activation_layer.h new file mode 100755 index 0000000..42118a8 --- /dev/null +++ b/hanzi_detection/src/activation_layer.h @@ -0,0 +1,19 @@ +#ifndef ACTIVATION_LAYER_H +#define ACTIVATION_LAYER_H + +#include "activations.h" +#include "layer.h" +#include "network.h" + +layer make_activation_layer(int batch, int inputs, ACTIVATION activation); + +void forward_activation_layer(layer l, network net); +void backward_activation_layer(layer l, network net); + +#ifdef GPU +void forward_activation_layer_gpu(layer l, network net); +void backward_activation_layer_gpu(layer l, network net); +#endif + +#endif + diff --git a/hanzi_detection/src/activations.c b/hanzi_detection/src/activations.c new file mode 100755 index 0000000..da1a17a --- /dev/null +++ b/hanzi_detection/src/activations.c @@ -0,0 +1,150 @@ +#include "activations.h" + +#include +#include +#include +#include + +char *get_activation_string(ACTIVATION a) +{ + switch(a){ + case LOGISTIC: + return "logistic"; + case LOGGY: + return "loggy"; + case RELU: + return "relu"; + case ELU: + return "elu"; + case SELU: + return "selu"; + case RELIE: + return "relie"; + case RAMP: + return "ramp"; + case LINEAR: + return "linear"; + case TANH: + return "tanh"; + case PLSE: + return "plse"; + case LEAKY: + return "leaky"; + case STAIR: + return "stair"; + case HARDTAN: + return "hardtan"; + case LHTAN: + return "lhtan"; + default: + break; + } + return "relu"; +} + +ACTIVATION get_activation(char *s) +{ + if (strcmp(s, "logistic")==0) return LOGISTIC; + if (strcmp(s, "loggy")==0) return LOGGY; + if (strcmp(s, "relu")==0) return RELU; + if (strcmp(s, "elu")==0) return ELU; + if (strcmp(s, "selu")==0) return SELU; + if (strcmp(s, "relie")==0) return RELIE; + if (strcmp(s, "plse")==0) return PLSE; + if (strcmp(s, "hardtan")==0) return HARDTAN; + if (strcmp(s, "lhtan")==0) return LHTAN; + if (strcmp(s, "linear")==0) return LINEAR; + if (strcmp(s, "ramp")==0) return RAMP; + if (strcmp(s, "leaky")==0) return LEAKY; + if (strcmp(s, "tanh")==0) return TANH; + if (strcmp(s, "stair")==0) return STAIR; + fprintf(stderr, "Couldn't find activation function %s, going with ReLU\n", s); + return RELU; +} + +float activate(float x, ACTIVATION a) +{ + switch(a){ + case LINEAR: + return linear_activate(x); + case LOGISTIC: + return logistic_activate(x); + case LOGGY: + return loggy_activate(x); + case RELU: + return relu_activate(x); + case ELU: + return elu_activate(x); + case SELU: + return selu_activate(x); + case RELIE: + return relie_activate(x); + case RAMP: + return ramp_activate(x); + case LEAKY: + return leaky_activate(x); + case TANH: + return tanh_activate(x); + case PLSE: + return plse_activate(x); + case STAIR: + return stair_activate(x); + case HARDTAN: + return hardtan_activate(x); + case LHTAN: + return lhtan_activate(x); + } + return 0; +} + +void activate_array(float *x, const int n, const ACTIVATION a) +{ + int i; + for(i = 0; i < n; ++i){ + x[i] = activate(x[i], a); + } +} + +float gradient(float x, ACTIVATION a) +{ + switch(a){ + case LINEAR: + return linear_gradient(x); + case LOGISTIC: + return logistic_gradient(x); + case LOGGY: + return loggy_gradient(x); + case RELU: + return relu_gradient(x); + case ELU: + return elu_gradient(x); + case SELU: + return selu_gradient(x); + case RELIE: + return relie_gradient(x); + case RAMP: + return ramp_gradient(x); + case LEAKY: + return leaky_gradient(x); + case TANH: + return tanh_gradient(x); + case PLSE: + return plse_gradient(x); + case STAIR: + return stair_gradient(x); + case HARDTAN: + return hardtan_gradient(x); + case LHTAN: + return lhtan_gradient(x); + } + return 0; +} + +void gradient_array(const float *x, const int n, const ACTIVATION a, float *delta) +{ + int i; + for(i = 0; i < n; ++i){ + delta[i] *= gradient(x[i], a); + } +} + diff --git a/hanzi_detection/src/activations.h b/hanzi_detection/src/activations.h new file mode 100755 index 0000000..9780d2c --- /dev/null +++ b/hanzi_detection/src/activations.h @@ -0,0 +1,87 @@ +#ifndef ACTIVATIONS_H +#define ACTIVATIONS_H +#include "darknet.h" +#include "cuda.h" +#include "math.h" + +ACTIVATION get_activation(char *s); + +char *get_activation_string(ACTIVATION a); +float activate(float x, ACTIVATION a); +float gradient(float x, ACTIVATION a); +void gradient_array(const float *x, const int n, const ACTIVATION a, float *delta); +void activate_array(float *x, const int n, const ACTIVATION a); +#ifdef GPU +void activate_array_gpu(float *x, int n, ACTIVATION a); +void gradient_array_gpu(float *x, int n, ACTIVATION a, float *delta); +#endif + +static inline float stair_activate(float x) +{ + int n = floor(x); + if (n%2 == 0) return floor(x/2.); + else return (x - n) + floor(x/2.); +} +static inline float hardtan_activate(float x) +{ + if (x < -1) return -1; + if (x > 1) return 1; + return x; +} +static inline float linear_activate(float x){return x;} +static inline float logistic_activate(float x){return 1./(1. + exp(-x));} +static inline float loggy_activate(float x){return 2./(1. + exp(-x)) - 1;} +static inline float relu_activate(float x){return x*(x>0);} +static inline float elu_activate(float x){return (x >= 0)*x + (x < 0)*(exp(x)-1);} +static inline float selu_activate(float x){return (x >= 0)*1.0507*x + (x < 0)*1.0507*1.6732*(exp(x)-1);} +static inline float relie_activate(float x){return (x>0) ? x : .01*x;} +static inline float ramp_activate(float x){return x*(x>0)+.1*x;} +static inline float leaky_activate(float x){return (x>0) ? x : .1*x;} +static inline float tanh_activate(float x){return (exp(2*x)-1)/(exp(2*x)+1);} +static inline float plse_activate(float x) +{ + if(x < -4) return .01 * (x + 4); + if(x > 4) return .01 * (x - 4) + 1; + return .125*x + .5; +} + +static inline float lhtan_activate(float x) +{ + if(x < 0) return .001*x; + if(x > 1) return .001*(x-1) + 1; + return x; +} +static inline float lhtan_gradient(float x) +{ + if(x > 0 && x < 1) return 1; + return .001; +} + +static inline float hardtan_gradient(float x) +{ + if (x > -1 && x < 1) return 1; + return 0; +} +static inline float linear_gradient(float x){return 1;} +static inline float logistic_gradient(float x){return (1-x)*x;} +static inline float loggy_gradient(float x) +{ + float y = (x+1.)/2.; + return 2*(1-y)*y; +} +static inline float stair_gradient(float x) +{ + if (floor(x) == x) return 0; + return 1; +} +static inline float relu_gradient(float x){return (x>0);} +static inline float elu_gradient(float x){return (x >= 0) + (x < 0)*(x + 1);} +static inline float selu_gradient(float x){return (x >= 0)*1.0507 + (x < 0)*(x + 1.0507*1.6732);} +static inline float relie_gradient(float x){return (x>0) ? 1 : .01;} +static inline float ramp_gradient(float x){return (x>0)+.1;} +static inline float leaky_gradient(float x){return (x>0) ? 1 : .1;} +static inline float tanh_gradient(float x){return 1-x*x;} +static inline float plse_gradient(float x){return (x < 0 || x > 1) ? .01 : .125;} + +#endif + diff --git a/hanzi_detection/src/avgpool_layer.c b/hanzi_detection/src/avgpool_layer.c new file mode 100755 index 0000000..83034db --- /dev/null +++ b/hanzi_detection/src/avgpool_layer.c @@ -0,0 +1,71 @@ +#include "avgpool_layer.h" +#include "cuda.h" +#include + +avgpool_layer make_avgpool_layer(int batch, int w, int h, int c) +{ + fprintf(stderr, "avg %4d x%4d x%4d -> %4d\n", w, h, c, c); + avgpool_layer l = {0}; + l.type = AVGPOOL; + l.batch = batch; + l.h = h; + l.w = w; + l.c = c; + l.out_w = 1; + l.out_h = 1; + l.out_c = c; + l.outputs = l.out_c; + l.inputs = h*w*c; + int output_size = l.outputs * batch; + l.output = calloc(output_size, sizeof(float)); + l.delta = calloc(output_size, sizeof(float)); + l.forward = forward_avgpool_layer; + l.backward = backward_avgpool_layer; + #ifdef GPU + l.forward_gpu = forward_avgpool_layer_gpu; + l.backward_gpu = backward_avgpool_layer_gpu; + l.output_gpu = cuda_make_array(l.output, output_size); + l.delta_gpu = cuda_make_array(l.delta, output_size); + #endif + return l; +} + +void resize_avgpool_layer(avgpool_layer *l, int w, int h) +{ + l->w = w; + l->h = h; + l->inputs = h*w*l->c; +} + +void forward_avgpool_layer(const avgpool_layer l, network net) +{ + int b,i,k; + + for(b = 0; b < l.batch; ++b){ + for(k = 0; k < l.c; ++k){ + int out_index = k + b*l.c; + l.output[out_index] = 0; + for(i = 0; i < l.h*l.w; ++i){ + int in_index = i + l.h*l.w*(k + b*l.c); + l.output[out_index] += net.input[in_index]; + } + l.output[out_index] /= l.h*l.w; + } + } +} + +void backward_avgpool_layer(const avgpool_layer l, network net) +{ + int b,i,k; + + for(b = 0; b < l.batch; ++b){ + for(k = 0; k < l.c; ++k){ + int out_index = k + b*l.c; + for(i = 0; i < l.h*l.w; ++i){ + int in_index = i + l.h*l.w*(k + b*l.c); + net.delta[in_index] += l.delta[out_index] / (l.h*l.w); + } + } + } +} + diff --git a/hanzi_detection/src/avgpool_layer.h b/hanzi_detection/src/avgpool_layer.h new file mode 100755 index 0000000..3bd356c --- /dev/null +++ b/hanzi_detection/src/avgpool_layer.h @@ -0,0 +1,23 @@ +#ifndef AVGPOOL_LAYER_H +#define AVGPOOL_LAYER_H + +#include "image.h" +#include "cuda.h" +#include "layer.h" +#include "network.h" + +typedef layer avgpool_layer; + +image get_avgpool_image(avgpool_layer l); +avgpool_layer make_avgpool_layer(int batch, int w, int h, int c); +void resize_avgpool_layer(avgpool_layer *l, int w, int h); +void forward_avgpool_layer(const avgpool_layer l, network net); +void backward_avgpool_layer(const avgpool_layer l, network net); + +#ifdef GPU +void forward_avgpool_layer_gpu(avgpool_layer l, network net); +void backward_avgpool_layer_gpu(avgpool_layer l, network net); +#endif + +#endif + diff --git a/hanzi_detection/src/avgpool_layer_kernels.cu b/hanzi_detection/src/avgpool_layer_kernels.cu new file mode 100755 index 0000000..a7eca3a --- /dev/null +++ b/hanzi_detection/src/avgpool_layer_kernels.cu @@ -0,0 +1,61 @@ +#include "cuda_runtime.h" +#include "curand.h" +#include "cublas_v2.h" + +extern "C" { +#include "avgpool_layer.h" +#include "cuda.h" +} + +__global__ void forward_avgpool_layer_kernel(int n, int w, int h, int c, float *input, float *output) +{ + int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(id >= n) return; + + int k = id % c; + id /= c; + int b = id; + + int i; + int out_index = (k + c*b); + output[out_index] = 0; + for(i = 0; i < w*h; ++i){ + int in_index = i + h*w*(k + b*c); + output[out_index] += input[in_index]; + } + output[out_index] /= w*h; +} + +__global__ void backward_avgpool_layer_kernel(int n, int w, int h, int c, float *in_delta, float *out_delta) +{ + int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(id >= n) return; + + int k = id % c; + id /= c; + int b = id; + + int i; + int out_index = (k + c*b); + for(i = 0; i < w*h; ++i){ + int in_index = i + h*w*(k + b*c); + in_delta[in_index] += out_delta[out_index] / (w*h); + } +} + +extern "C" void forward_avgpool_layer_gpu(avgpool_layer layer, network net) +{ + size_t n = layer.c*layer.batch; + + forward_avgpool_layer_kernel<<>>(n, layer.w, layer.h, layer.c, net.input_gpu, layer.output_gpu); + check_error(cudaPeekAtLastError()); +} + +extern "C" void backward_avgpool_layer_gpu(avgpool_layer layer, network net) +{ + size_t n = layer.c*layer.batch; + + backward_avgpool_layer_kernel<<>>(n, layer.w, layer.h, layer.c, net.delta_gpu, layer.delta_gpu); + check_error(cudaPeekAtLastError()); +} + diff --git a/hanzi_detection/src/batchnorm_layer.c b/hanzi_detection/src/batchnorm_layer.c new file mode 100755 index 0000000..ebff387 --- /dev/null +++ b/hanzi_detection/src/batchnorm_layer.c @@ -0,0 +1,279 @@ +#include "convolutional_layer.h" +#include "batchnorm_layer.h" +#include "blas.h" +#include + +layer make_batchnorm_layer(int batch, int w, int h, int c) +{ + fprintf(stderr, "Batch Normalization Layer: %d x %d x %d image\n", w,h,c); + layer l = {0}; + l.type = BATCHNORM; + l.batch = batch; + l.h = l.out_h = h; + l.w = l.out_w = w; + l.c = l.out_c = c; + l.output = calloc(h * w * c * batch, sizeof(float)); + l.delta = calloc(h * w * c * batch, sizeof(float)); + l.inputs = w*h*c; + l.outputs = l.inputs; + + l.scales = calloc(c, sizeof(float)); + l.scale_updates = calloc(c, sizeof(float)); + l.biases = calloc(c, sizeof(float)); + l.bias_updates = calloc(c, sizeof(float)); + int i; + for(i = 0; i < c; ++i){ + l.scales[i] = 1; + } + + l.mean = calloc(c, sizeof(float)); + l.variance = calloc(c, sizeof(float)); + + l.rolling_mean = calloc(c, sizeof(float)); + l.rolling_variance = calloc(c, sizeof(float)); + + l.forward = forward_batchnorm_layer; + l.backward = backward_batchnorm_layer; +#ifdef GPU + l.forward_gpu = forward_batchnorm_layer_gpu; + l.backward_gpu = backward_batchnorm_layer_gpu; + + l.output_gpu = cuda_make_array(l.output, h * w * c * batch); + l.delta_gpu = cuda_make_array(l.delta, h * w * c * batch); + + l.biases_gpu = cuda_make_array(l.biases, c); + l.bias_updates_gpu = cuda_make_array(l.bias_updates, c); + + l.scales_gpu = cuda_make_array(l.scales, c); + l.scale_updates_gpu = cuda_make_array(l.scale_updates, c); + + l.mean_gpu = cuda_make_array(l.mean, c); + l.variance_gpu = cuda_make_array(l.variance, c); + + l.rolling_mean_gpu = cuda_make_array(l.mean, c); + l.rolling_variance_gpu = cuda_make_array(l.variance, c); + + l.mean_delta_gpu = cuda_make_array(l.mean, c); + l.variance_delta_gpu = cuda_make_array(l.variance, c); + + l.x_gpu = cuda_make_array(l.output, l.batch*l.outputs); + l.x_norm_gpu = cuda_make_array(l.output, l.batch*l.outputs); + #ifdef CUDNN + cudnnCreateTensorDescriptor(&l.normTensorDesc); + cudnnCreateTensorDescriptor(&l.dstTensorDesc); + cudnnSetTensor4dDescriptor(l.dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, l.batch, l.out_c, l.out_h, l.out_w); + cudnnSetTensor4dDescriptor(l.normTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, 1, l.out_c, 1, 1); + + #endif +#endif + return l; +} + +void backward_scale_cpu(float *x_norm, float *delta, int batch, int n, int size, float *scale_updates) +{ + int i,b,f; + for(f = 0; f < n; ++f){ + float sum = 0; + for(b = 0; b < batch; ++b){ + for(i = 0; i < size; ++i){ + int index = i + size*(f + n*b); + sum += delta[index] * x_norm[index]; + } + } + scale_updates[f] += sum; + } +} + +void mean_delta_cpu(float *delta, float *variance, int batch, int filters, int spatial, float *mean_delta) +{ + + int i,j,k; + for(i = 0; i < filters; ++i){ + mean_delta[i] = 0; + for (j = 0; j < batch; ++j) { + for (k = 0; k < spatial; ++k) { + int index = j*filters*spatial + i*spatial + k; + mean_delta[i] += delta[index]; + } + } + mean_delta[i] *= (-1./sqrt(variance[i] + .00001f)); + } +} +void variance_delta_cpu(float *x, float *delta, float *mean, float *variance, int batch, int filters, int spatial, float *variance_delta) +{ + + int i,j,k; + for(i = 0; i < filters; ++i){ + variance_delta[i] = 0; + for(j = 0; j < batch; ++j){ + for(k = 0; k < spatial; ++k){ + int index = j*filters*spatial + i*spatial + k; + variance_delta[i] += delta[index]*(x[index] - mean[i]); + } + } + variance_delta[i] *= -.5 * pow(variance[i] + .00001f, (float)(-3./2.)); + } +} +void normalize_delta_cpu(float *x, float *mean, float *variance, float *mean_delta, float *variance_delta, int batch, int filters, int spatial, float *delta) +{ + int f, j, k; + for(j = 0; j < batch; ++j){ + for(f = 0; f < filters; ++f){ + for(k = 0; k < spatial; ++k){ + int index = j*filters*spatial + f*spatial + k; + delta[index] = delta[index] * 1./(sqrt(variance[f] + .00001f)) + variance_delta[f] * 2. * (x[index] - mean[f]) / (spatial * batch) + mean_delta[f]/(spatial*batch); + } + } + } +} + +void resize_batchnorm_layer(layer *layer, int w, int h) +{ + fprintf(stderr, "Not implemented\n"); +} + +void forward_batchnorm_layer(layer l, network net) +{ + if(l.type == BATCHNORM) copy_cpu(l.outputs*l.batch, net.input, 1, l.output, 1); + copy_cpu(l.outputs*l.batch, l.output, 1, l.x, 1); + if(net.train){ + mean_cpu(l.output, l.batch, l.out_c, l.out_h*l.out_w, l.mean); + variance_cpu(l.output, l.mean, l.batch, l.out_c, l.out_h*l.out_w, l.variance); + + scal_cpu(l.out_c, .99, l.rolling_mean, 1); + axpy_cpu(l.out_c, .01, l.mean, 1, l.rolling_mean, 1); + scal_cpu(l.out_c, .99, l.rolling_variance, 1); + axpy_cpu(l.out_c, .01, l.variance, 1, l.rolling_variance, 1); + + normalize_cpu(l.output, l.mean, l.variance, l.batch, l.out_c, l.out_h*l.out_w); + copy_cpu(l.outputs*l.batch, l.output, 1, l.x_norm, 1); + } else { + normalize_cpu(l.output, l.rolling_mean, l.rolling_variance, l.batch, l.out_c, l.out_h*l.out_w); + } + scale_bias(l.output, l.scales, l.batch, l.out_c, l.out_h*l.out_w); + add_bias(l.output, l.biases, l.batch, l.out_c, l.out_h*l.out_w); +} + +void backward_batchnorm_layer(layer l, network net) +{ + if(!net.train){ + l.mean = l.rolling_mean; + l.variance = l.rolling_variance; + } + backward_bias(l.bias_updates, l.delta, l.batch, l.out_c, l.out_w*l.out_h); + backward_scale_cpu(l.x_norm, l.delta, l.batch, l.out_c, l.out_w*l.out_h, l.scale_updates); + + scale_bias(l.delta, l.scales, l.batch, l.out_c, l.out_h*l.out_w); + + mean_delta_cpu(l.delta, l.variance, l.batch, l.out_c, l.out_w*l.out_h, l.mean_delta); + variance_delta_cpu(l.x, l.delta, l.mean, l.variance, l.batch, l.out_c, l.out_w*l.out_h, l.variance_delta); + normalize_delta_cpu(l.x, l.mean, l.variance, l.mean_delta, l.variance_delta, l.batch, l.out_c, l.out_w*l.out_h, l.delta); + if(l.type == BATCHNORM) copy_cpu(l.outputs*l.batch, l.delta, 1, net.delta, 1); +} + +#ifdef GPU + +void pull_batchnorm_layer(layer l) +{ + cuda_pull_array(l.scales_gpu, l.scales, l.c); + cuda_pull_array(l.rolling_mean_gpu, l.rolling_mean, l.c); + cuda_pull_array(l.rolling_variance_gpu, l.rolling_variance, l.c); +} +void push_batchnorm_layer(layer l) +{ + cuda_push_array(l.scales_gpu, l.scales, l.c); + cuda_push_array(l.rolling_mean_gpu, l.rolling_mean, l.c); + cuda_push_array(l.rolling_variance_gpu, l.rolling_variance, l.c); +} + +void forward_batchnorm_layer_gpu(layer l, network net) +{ + if(l.type == BATCHNORM) copy_gpu(l.outputs*l.batch, net.input_gpu, 1, l.output_gpu, 1); + copy_gpu(l.outputs*l.batch, l.output_gpu, 1, l.x_gpu, 1); + if (net.train) { +#ifdef CUDNN + float one = 1; + float zero = 0; + cudnnBatchNormalizationForwardTraining(cudnn_handle(), + CUDNN_BATCHNORM_SPATIAL, + &one, + &zero, + l.dstTensorDesc, + l.x_gpu, + l.dstTensorDesc, + l.output_gpu, + l.normTensorDesc, + l.scales_gpu, + l.biases_gpu, + .01, + l.rolling_mean_gpu, + l.rolling_variance_gpu, + .00001, + l.mean_gpu, + l.variance_gpu); +#else + fast_mean_gpu(l.output_gpu, l.batch, l.out_c, l.out_h*l.out_w, l.mean_gpu); + fast_variance_gpu(l.output_gpu, l.mean_gpu, l.batch, l.out_c, l.out_h*l.out_w, l.variance_gpu); + + scal_gpu(l.out_c, .99, l.rolling_mean_gpu, 1); + axpy_gpu(l.out_c, .01, l.mean_gpu, 1, l.rolling_mean_gpu, 1); + scal_gpu(l.out_c, .99, l.rolling_variance_gpu, 1); + axpy_gpu(l.out_c, .01, l.variance_gpu, 1, l.rolling_variance_gpu, 1); + + copy_gpu(l.outputs*l.batch, l.output_gpu, 1, l.x_gpu, 1); + normalize_gpu(l.output_gpu, l.mean_gpu, l.variance_gpu, l.batch, l.out_c, l.out_h*l.out_w); + copy_gpu(l.outputs*l.batch, l.output_gpu, 1, l.x_norm_gpu, 1); + + scale_bias_gpu(l.output_gpu, l.scales_gpu, l.batch, l.out_c, l.out_h*l.out_w); + add_bias_gpu(l.output_gpu, l.biases_gpu, l.batch, l.out_c, l.out_w*l.out_h); +#endif + } else { + normalize_gpu(l.output_gpu, l.rolling_mean_gpu, l.rolling_variance_gpu, l.batch, l.out_c, l.out_h*l.out_w); + scale_bias_gpu(l.output_gpu, l.scales_gpu, l.batch, l.out_c, l.out_h*l.out_w); + add_bias_gpu(l.output_gpu, l.biases_gpu, l.batch, l.out_c, l.out_w*l.out_h); + } + +} + +void backward_batchnorm_layer_gpu(layer l, network net) +{ + if(!net.train){ + l.mean_gpu = l.rolling_mean_gpu; + l.variance_gpu = l.rolling_variance_gpu; + } +#ifdef CUDNN + float one = 1; + float zero = 0; + cudnnBatchNormalizationBackward(cudnn_handle(), + CUDNN_BATCHNORM_SPATIAL, + &one, + &zero, + &one, + &one, + l.dstTensorDesc, + l.x_gpu, + l.dstTensorDesc, + l.delta_gpu, + l.dstTensorDesc, + l.x_norm_gpu, + l.normTensorDesc, + l.scales_gpu, + l.scale_updates_gpu, + l.bias_updates_gpu, + .00001, + l.mean_gpu, + l.variance_gpu); + copy_gpu(l.outputs*l.batch, l.x_norm_gpu, 1, l.delta_gpu, 1); +#else + backward_bias_gpu(l.bias_updates_gpu, l.delta_gpu, l.batch, l.out_c, l.out_w*l.out_h); + backward_scale_gpu(l.x_norm_gpu, l.delta_gpu, l.batch, l.out_c, l.out_w*l.out_h, l.scale_updates_gpu); + + scale_bias_gpu(l.delta_gpu, l.scales_gpu, l.batch, l.out_c, l.out_h*l.out_w); + + fast_mean_delta_gpu(l.delta_gpu, l.variance_gpu, l.batch, l.out_c, l.out_w*l.out_h, l.mean_delta_gpu); + fast_variance_delta_gpu(l.x_gpu, l.delta_gpu, l.mean_gpu, l.variance_gpu, l.batch, l.out_c, l.out_w*l.out_h, l.variance_delta_gpu); + normalize_delta_gpu(l.x_gpu, l.mean_gpu, l.variance_gpu, l.mean_delta_gpu, l.variance_delta_gpu, l.batch, l.out_c, l.out_w*l.out_h, l.delta_gpu); +#endif + if(l.type == BATCHNORM) copy_gpu(l.outputs*l.batch, l.delta_gpu, 1, net.delta_gpu, 1); +} +#endif diff --git a/hanzi_detection/src/batchnorm_layer.h b/hanzi_detection/src/batchnorm_layer.h new file mode 100755 index 0000000..25a18a3 --- /dev/null +++ b/hanzi_detection/src/batchnorm_layer.h @@ -0,0 +1,19 @@ +#ifndef BATCHNORM_LAYER_H +#define BATCHNORM_LAYER_H + +#include "image.h" +#include "layer.h" +#include "network.h" + +layer make_batchnorm_layer(int batch, int w, int h, int c); +void forward_batchnorm_layer(layer l, network net); +void backward_batchnorm_layer(layer l, network net); + +#ifdef GPU +void forward_batchnorm_layer_gpu(layer l, network net); +void backward_batchnorm_layer_gpu(layer l, network net); +void pull_batchnorm_layer(layer l); +void push_batchnorm_layer(layer l); +#endif + +#endif diff --git a/hanzi_detection/src/blas.c b/hanzi_detection/src/blas.c new file mode 100755 index 0000000..9e16044 --- /dev/null +++ b/hanzi_detection/src/blas.c @@ -0,0 +1,351 @@ +#include "blas.h" + +#include +#include +#include +#include +#include +#include +void reorg_cpu(float *x, int w, int h, int c, int batch, int stride, int forward, float *out) +{ + int b,i,j,k; + int out_c = c/(stride*stride); + + for(b = 0; b < batch; ++b){ + for(k = 0; k < c; ++k){ + for(j = 0; j < h; ++j){ + for(i = 0; i < w; ++i){ + int in_index = i + w*(j + h*(k + c*b)); + int c2 = k % out_c; + int offset = k / out_c; + int w2 = i*stride + offset % stride; + int h2 = j*stride + offset / stride; + int out_index = w2 + w*stride*(h2 + h*stride*(c2 + out_c*b)); + if(forward) out[out_index] = x[in_index]; + else out[in_index] = x[out_index]; + } + } + } + } +} + +void flatten(float *x, int size, int layers, int batch, int forward) +{ + float *swap = calloc(size*layers*batch, sizeof(float)); + int i,c,b; + for(b = 0; b < batch; ++b){ + for(c = 0; c < layers; ++c){ + for(i = 0; i < size; ++i){ + int i1 = b*layers*size + c*size + i; + int i2 = b*layers*size + i*layers + c; + if (forward) swap[i2] = x[i1]; + else swap[i1] = x[i2]; + } + } + } + memcpy(x, swap, size*layers*batch*sizeof(float)); + free(swap); +} + +void weighted_sum_cpu(float *a, float *b, float *s, int n, float *c) +{ + int i; + for(i = 0; i < n; ++i){ + c[i] = s[i]*a[i] + (1-s[i])*(b ? b[i] : 0); + } +} + +void weighted_delta_cpu(float *a, float *b, float *s, float *da, float *db, float *ds, int n, float *dc) +{ + int i; + for(i = 0; i < n; ++i){ + if(da) da[i] += dc[i] * s[i]; + if(db) db[i] += dc[i] * (1-s[i]); + ds[i] += dc[i] * (a[i] - b[i]); + } +} + +void shortcut_cpu(int batch, int w1, int h1, int c1, float *add, int w2, int h2, int c2, float s1, float s2, float *out) +{ + int stride = w1/w2; + int sample = w2/w1; + assert(stride == h1/h2); + assert(sample == h2/h1); + if(stride < 1) stride = 1; + if(sample < 1) sample = 1; + int minw = (w1 < w2) ? w1 : w2; + int minh = (h1 < h2) ? h1 : h2; + int minc = (c1 < c2) ? c1 : c2; + + int i,j,k,b; + for(b = 0; b < batch; ++b){ + for(k = 0; k < minc; ++k){ + for(j = 0; j < minh; ++j){ + for(i = 0; i < minw; ++i){ + int out_index = i*sample + w2*(j*sample + h2*(k + c2*b)); + int add_index = i*stride + w1*(j*stride + h1*(k + c1*b)); + out[out_index] = s1*out[out_index] + s2*add[add_index]; + } + } + } + } +} + +void mean_cpu(float *x, int batch, int filters, int spatial, float *mean) +{ + float scale = 1./(batch * spatial); + int i,j,k; + for(i = 0; i < filters; ++i){ + mean[i] = 0; + for(j = 0; j < batch; ++j){ + for(k = 0; k < spatial; ++k){ + int index = j*filters*spatial + i*spatial + k; + mean[i] += x[index]; + } + } + mean[i] *= scale; + } +} + +void variance_cpu(float *x, float *mean, int batch, int filters, int spatial, float *variance) +{ + float scale = 1./(batch * spatial - 1); + int i,j,k; + for(i = 0; i < filters; ++i){ + variance[i] = 0; + for(j = 0; j < batch; ++j){ + for(k = 0; k < spatial; ++k){ + int index = j*filters*spatial + i*spatial + k; + variance[i] += pow((x[index] - mean[i]), 2); + } + } + variance[i] *= scale; + } +} + +void l2normalize_cpu(float *x, float *dx, int batch, int filters, int spatial) +{ + int b,f,i; + for(b = 0; b < batch; ++b){ + for(i = 0; i < spatial; ++i){ + float sum = 0; + for(f = 0; f < filters; ++f){ + int index = b*filters*spatial + f*spatial + i; + sum += powf(x[index], 2); + } + sum = sqrtf(sum); + for(f = 0; f < filters; ++f){ + int index = b*filters*spatial + f*spatial + i; + x[index] /= sum; + dx[index] = (1 - x[index]) / sum; + } + } + } +} + + +void normalize_cpu(float *x, float *mean, float *variance, int batch, int filters, int spatial) +{ + int b, f, i; + for(b = 0; b < batch; ++b){ + for(f = 0; f < filters; ++f){ + for(i = 0; i < spatial; ++i){ + int index = b*filters*spatial + f*spatial + i; + x[index] = (x[index] - mean[f])/(sqrt(variance[f]) + .000001f); + } + } + } +} + +void const_cpu(int N, float ALPHA, float *X, int INCX) +{ + int i; + for(i = 0; i < N; ++i) X[i*INCX] = ALPHA; +} + +void mul_cpu(int N, float *X, int INCX, float *Y, int INCY) +{ + int i; + for(i = 0; i < N; ++i) Y[i*INCY] *= X[i*INCX]; +} + +void pow_cpu(int N, float ALPHA, float *X, int INCX, float *Y, int INCY) +{ + int i; + for(i = 0; i < N; ++i) Y[i*INCY] = pow(X[i*INCX], ALPHA); +} + +void axpy_cpu(int N, float ALPHA, float *X, int INCX, float *Y, int INCY) +{ + int i; + for(i = 0; i < N; ++i) Y[i*INCY] += ALPHA*X[i*INCX]; +} + +void scal_cpu(int N, float ALPHA, float *X, int INCX) +{ + int i; + for(i = 0; i < N; ++i) X[i*INCX] *= ALPHA; +} + +void fill_cpu(int N, float ALPHA, float *X, int INCX) +{ + int i; + for(i = 0; i < N; ++i) X[i*INCX] = ALPHA; +} + +void deinter_cpu(int NX, float *X, int NY, float *Y, int B, float *OUT) +{ + int i, j; + int index = 0; + for(j = 0; j < B; ++j) { + for(i = 0; i < NX; ++i){ + if(X) X[j*NX + i] += OUT[index]; + ++index; + } + for(i = 0; i < NY; ++i){ + if(Y) Y[j*NY + i] += OUT[index]; + ++index; + } + } +} + +void inter_cpu(int NX, float *X, int NY, float *Y, int B, float *OUT) +{ + int i, j; + int index = 0; + for(j = 0; j < B; ++j) { + for(i = 0; i < NX; ++i){ + OUT[index++] = X[j*NX + i]; + } + for(i = 0; i < NY; ++i){ + OUT[index++] = Y[j*NY + i]; + } + } +} + +void copy_cpu(int N, float *X, int INCX, float *Y, int INCY) +{ + int i; + for(i = 0; i < N; ++i) Y[i*INCY] = X[i*INCX]; +} + +void mult_add_into_cpu(int N, float *X, float *Y, float *Z) +{ + int i; + for(i = 0; i < N; ++i) Z[i] += X[i]*Y[i]; +} + +void smooth_l1_cpu(int n, float *pred, float *truth, float *delta, float *error) +{ + int i; + for(i = 0; i < n; ++i){ + float diff = truth[i] - pred[i]; + float abs_val = fabs(diff); + if(abs_val < 1) { + error[i] = diff * diff; + delta[i] = diff; + } + else { + error[i] = 2*abs_val - 1; + delta[i] = (diff < 0) ? 1 : -1; + } + } +} + +void l1_cpu(int n, float *pred, float *truth, float *delta, float *error) +{ + int i; + for(i = 0; i < n; ++i){ + float diff = truth[i] - pred[i]; + error[i] = fabs(diff); + delta[i] = diff > 0 ? 1 : -1; + } +} + +void softmax_x_ent_cpu(int n, float *pred, float *truth, float *delta, float *error) +{ + int i; + for(i = 0; i < n; ++i){ + float t = truth[i]; + float p = pred[i]; + error[i] = (t) ? -log(p) : 0; + delta[i] = t-p; + } +} + +void logistic_x_ent_cpu(int n, float *pred, float *truth, float *delta, float *error) +{ + int i; + for(i = 0; i < n; ++i){ + float t = truth[i]; + float p = pred[i]; + error[i] = -t*log(p) - (1-t)*log(1-p); + delta[i] = t-p; + } +} + +void l2_cpu(int n, float *pred, float *truth, float *delta, float *error) +{ + int i; + for(i = 0; i < n; ++i){ + float diff = truth[i] - pred[i]; + error[i] = diff * diff; + delta[i] = diff; + } +} + +float dot_cpu(int N, float *X, int INCX, float *Y, int INCY) +{ + int i; + float dot = 0; + for(i = 0; i < N; ++i) dot += X[i*INCX] * Y[i*INCY]; + return dot; +} + +void softmax(float *input, int n, float temp, int stride, float *output) +{ + int i; + float sum = 0; + float largest = -FLT_MAX; + for(i = 0; i < n; ++i){ + if(input[i*stride] > largest) largest = input[i*stride]; + } + for(i = 0; i < n; ++i){ + float e = exp(input[i*stride]/temp - largest/temp); + sum += e; + output[i*stride] = e; + } + for(i = 0; i < n; ++i){ + output[i*stride] /= sum; + } +} + + +void softmax_cpu(float *input, int n, int batch, int batch_offset, int groups, int group_offset, int stride, float temp, float *output) +{ + int g, b; + for(b = 0; b < batch; ++b){ + for(g = 0; g < groups; ++g){ + softmax(input + b*batch_offset + g*group_offset, n, temp, stride, output + b*batch_offset + g*group_offset); + } + } +} + +void upsample_cpu(float *in, int w, int h, int c, int batch, int stride, int forward, float scale, float *out) +{ + int i, j, k, b; + for(b = 0; b < batch; ++b){ + for(k = 0; k < c; ++k){ + for(j = 0; j < h*stride; ++j){ + for(i = 0; i < w*stride; ++i){ + int in_index = b*w*h*c + k*w*h + (j/stride)*w + i/stride; + int out_index = b*w*h*c*stride*stride + k*w*h*stride*stride + j*w*stride + i; + if(forward) out[out_index] = scale*in[in_index]; + else in[in_index] += scale*out[out_index]; + } + } + } + } +} + + diff --git a/hanzi_detection/src/blas.h b/hanzi_detection/src/blas.h new file mode 100755 index 0000000..707291d --- /dev/null +++ b/hanzi_detection/src/blas.h @@ -0,0 +1,105 @@ +#ifndef BLAS_H +#define BLAS_H +#include "darknet.h" + +void flatten(float *x, int size, int layers, int batch, int forward); +void pm(int M, int N, float *A); +float *random_matrix(int rows, int cols); +void time_random_matrix(int TA, int TB, int m, int k, int n); +void reorg_cpu(float *x, int w, int h, int c, int batch, int stride, int forward, float *out); + +void test_blas(); + +void inter_cpu(int NX, float *X, int NY, float *Y, int B, float *OUT); +void deinter_cpu(int NX, float *X, int NY, float *Y, int B, float *OUT); +void mult_add_into_cpu(int N, float *X, float *Y, float *Z); + +void const_cpu(int N, float ALPHA, float *X, int INCX); +void constrain_gpu(int N, float ALPHA, float * X, int INCX); +void pow_cpu(int N, float ALPHA, float *X, int INCX, float *Y, int INCY); +void mul_cpu(int N, float *X, int INCX, float *Y, int INCY); + +int test_gpu_blas(); +void shortcut_cpu(int batch, int w1, int h1, int c1, float *add, int w2, int h2, int c2, float s1, float s2, float *out); + +void mean_cpu(float *x, int batch, int filters, int spatial, float *mean); +void variance_cpu(float *x, float *mean, int batch, int filters, int spatial, float *variance); + +void scale_bias(float *output, float *scales, int batch, int n, int size); +void backward_scale_cpu(float *x_norm, float *delta, int batch, int n, int size, float *scale_updates); +void mean_delta_cpu(float *delta, float *variance, int batch, int filters, int spatial, float *mean_delta); +void variance_delta_cpu(float *x, float *delta, float *mean, float *variance, int batch, int filters, int spatial, float *variance_delta); +void normalize_delta_cpu(float *x, float *mean, float *variance, float *mean_delta, float *variance_delta, int batch, int filters, int spatial, float *delta); +void l2normalize_cpu(float *x, float *dx, int batch, int filters, int spatial); + +void smooth_l1_cpu(int n, float *pred, float *truth, float *delta, float *error); +void l2_cpu(int n, float *pred, float *truth, float *delta, float *error); +void l1_cpu(int n, float *pred, float *truth, float *delta, float *error); +void logistic_x_ent_cpu(int n, float *pred, float *truth, float *delta, float *error); +void softmax_x_ent_cpu(int n, float *pred, float *truth, float *delta, float *error); +void weighted_sum_cpu(float *a, float *b, float *s, int num, float *c); +void weighted_delta_cpu(float *a, float *b, float *s, float *da, float *db, float *ds, int n, float *dc); + +void softmax(float *input, int n, float temp, int stride, float *output); +void softmax_cpu(float *input, int n, int batch, int batch_offset, int groups, int group_offset, int stride, float temp, float *output); +void upsample_cpu(float *in, int w, int h, int c, int batch, int stride, int forward, float scale, float *out); + +#ifdef GPU +#include "cuda.h" +#include "tree.h" + +void axpy_gpu(int N, float ALPHA, float * X, int INCX, float * Y, int INCY); +void axpy_gpu_offset(int N, float ALPHA, float * X, int OFFX, int INCX, float * Y, int OFFY, int INCY); +void copy_gpu(int N, float * X, int INCX, float * Y, int INCY); +void copy_gpu_offset(int N, float * X, int OFFX, int INCX, float * Y, int OFFY, int INCY); +void add_gpu(int N, float ALPHA, float * X, int INCX); +void supp_gpu(int N, float ALPHA, float * X, int INCX); +void mask_gpu(int N, float * X, float mask_num, float * mask, float val); +void scale_mask_gpu(int N, float * X, float mask_num, float * mask, float scale); +void const_gpu(int N, float ALPHA, float *X, int INCX); +void pow_gpu(int N, float ALPHA, float *X, int INCX, float *Y, int INCY); +void mul_gpu(int N, float *X, int INCX, float *Y, int INCY); + +void mean_gpu(float *x, int batch, int filters, int spatial, float *mean); +void variance_gpu(float *x, float *mean, int batch, int filters, int spatial, float *variance); +void normalize_gpu(float *x, float *mean, float *variance, int batch, int filters, int spatial); +void l2normalize_gpu(float *x, float *dx, int batch, int filters, int spatial); + +void normalize_delta_gpu(float *x, float *mean, float *variance, float *mean_delta, float *variance_delta, int batch, int filters, int spatial, float *delta); + +void fast_mean_delta_gpu(float *delta, float *variance, int batch, int filters, int spatial, float *mean_delta); +void fast_variance_delta_gpu(float *x, float *delta, float *mean, float *variance, int batch, int filters, int spatial, float *variance_delta); + +void fast_variance_gpu(float *x, float *mean, int batch, int filters, int spatial, float *variance); +void fast_mean_gpu(float *x, int batch, int filters, int spatial, float *mean); +void shortcut_gpu(int batch, int w1, int h1, int c1, float *add, int w2, int h2, int c2, float s1, float s2, float *out); +void scale_bias_gpu(float *output, float *biases, int batch, int n, int size); +void backward_scale_gpu(float *x_norm, float *delta, int batch, int n, int size, float *scale_updates); +void scale_bias_gpu(float *output, float *biases, int batch, int n, int size); +void add_bias_gpu(float *output, float *biases, int batch, int n, int size); +void backward_bias_gpu(float *bias_updates, float *delta, int batch, int n, int size); + +void logistic_x_ent_gpu(int n, float *pred, float *truth, float *delta, float *error); +void softmax_x_ent_gpu(int n, float *pred, float *truth, float *delta, float *error); +void smooth_l1_gpu(int n, float *pred, float *truth, float *delta, float *error); +void l2_gpu(int n, float *pred, float *truth, float *delta, float *error); +void l1_gpu(int n, float *pred, float *truth, float *delta, float *error); +void wgan_gpu(int n, float *pred, float *truth, float *delta, float *error); +void weighted_delta_gpu(float *a, float *b, float *s, float *da, float *db, float *ds, int num, float *dc); +void weighted_sum_gpu(float *a, float *b, float *s, int num, float *c); +void mult_add_into_gpu(int num, float *a, float *b, float *c); +void inter_gpu(int NX, float *X, int NY, float *Y, int B, float *OUT); +void deinter_gpu(int NX, float *X, int NY, float *Y, int B, float *OUT); + +void reorg_gpu(float *x, int w, int h, int c, int batch, int stride, int forward, float *out); + +void softmax_gpu(float *input, int n, int batch, int batch_offset, int groups, int group_offset, int stride, float temp, float *output); +void adam_update_gpu(float *w, float *d, float *m, float *v, float B1, float B2, float eps, float decay, float rate, int n, int batch, int t); +void adam_gpu(int n, float *x, float *m, float *v, float B1, float B2, float rate, float eps, int t); + +void flatten_gpu(float *x, int spatial, int layers, int batch, int forward, float *out); +void softmax_tree(float *input, int spatial, int batch, int stride, float temp, float *output, tree hier); +void upsample_gpu(float *in, int w, int h, int c, int batch, int stride, int forward, float scale, float *out); + +#endif +#endif diff --git a/hanzi_detection/src/blas_kernels.cu b/hanzi_detection/src/blas_kernels.cu new file mode 100755 index 0000000..47e8217 --- /dev/null +++ b/hanzi_detection/src/blas_kernels.cu @@ -0,0 +1,1035 @@ +#include "cuda_runtime.h" +#include "curand.h" +#include "cublas_v2.h" +#include + +extern "C" { +#include "blas.h" +#include "cuda.h" +#include "utils.h" +} + +__global__ void scale_bias_kernel(float *output, float *biases, int n, int size) +{ + int offset = blockIdx.x * blockDim.x + threadIdx.x; + int filter = blockIdx.y; + int batch = blockIdx.z; + + if(offset < size) output[(batch*n+filter)*size + offset] *= biases[filter]; +} + +void scale_bias_gpu(float *output, float *biases, int batch, int n, int size) +{ + dim3 dimGrid((size-1)/BLOCK + 1, n, batch); + dim3 dimBlock(BLOCK, 1, 1); + + scale_bias_kernel<<>>(output, biases, n, size); + check_error(cudaPeekAtLastError()); +} + +__global__ void backward_scale_kernel(float *x_norm, float *delta, int batch, int n, int size, float *scale_updates) +{ + __shared__ float part[BLOCK]; + int i,b; + int filter = blockIdx.x; + int p = threadIdx.x; + float sum = 0; + for(b = 0; b < batch; ++b){ + for(i = 0; i < size; i += BLOCK){ + int index = p + i + size*(filter + n*b); + sum += (p+i < size) ? delta[index]*x_norm[index] : 0; + } + } + part[p] = sum; + __syncthreads(); + if (p == 0) { + for(i = 0; i < BLOCK; ++i) scale_updates[filter] += part[i]; + } +} + +void backward_scale_gpu(float *x_norm, float *delta, int batch, int n, int size, float *scale_updates) +{ + backward_scale_kernel<<>>(x_norm, delta, batch, n, size, scale_updates); + check_error(cudaPeekAtLastError()); +} + +__global__ void add_bias_kernel(float *output, float *biases, int batch, int n, int size) +{ + int index = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if (index >= n*size*batch) return; + int i = index % size; + index /= size; + int j = index % n; + index /= n; + int k = index; + + output[(k*n+j)*size + i] += biases[j]; +} + +void add_bias_gpu(float *output, float *biases, int batch, int n, int size) +{ + int num = n*size*batch; + + add_bias_kernel<<>>(output, biases, batch, n, size); + check_error(cudaPeekAtLastError()); +} + +__global__ void backward_bias_conn_kernel(float *bias_updates, float *delta, int batch, int n) +{ + int index = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if (index >= n) return; + int b; + float sum = 0; + for(b = 0; b < batch; ++b){ + int i = b*n + index; + sum += delta[i]; + } + bias_updates[index] += sum; +} + +__global__ void backward_bias_kernel(float *bias_updates, float *delta, int batch, int n, int size) +{ + __shared__ float part[BLOCK]; + int i,b; + int filter = blockIdx.x; + int p = threadIdx.x; + float sum = 0; + for(b = 0; b < batch; ++b){ + for(i = 0; i < size; i += BLOCK){ + int index = p + i + size*(filter + n*b); + sum += (p+i < size) ? delta[index] : 0; + } + } + part[p] = sum; + __syncthreads(); + if (p == 0) { + for(i = 0; i < BLOCK; ++i) bias_updates[filter] += part[i]; + } +} + +void backward_bias_gpu(float *bias_updates, float *delta, int batch, int n, int size) +{ + if(size == 1){ + backward_bias_conn_kernel<<>>(bias_updates, delta, batch, n); + }else{ + backward_bias_kernel<<>>(bias_updates, delta, batch, n, size); + } + check_error(cudaPeekAtLastError()); +} + +/* +__global__ void dot_kernel(float *output, float scale, int batch, int n, int size, float *delta) +{ + int index = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + int f1 = index / n; + int f2 = index % n; + if (f2 <= f1) return; + + float sum = 0; + float norm1 = 0; + float norm2 = 0; + int b, i; + for(b = 0; b < batch; ++b){ + for(i = 0; i < size; ++i){ + int i1 = b * size * n + f1 * size + i; + int i2 = b * size * n + f2 * size + i; + sum += output[i1] * output[i2]; + norm1 += output[i1] * output[i1]; + norm2 += output[i2] * output[i2]; + } + } + norm1 = sqrt(norm1); + norm2 = sqrt(norm2); + float norm = norm1 * norm2; + sum = sum / norm; + for(b = 0; b < batch; ++b){ + for(i = 0; i < size; ++i){ + int i1 = b * size * n + f1 * size + i; + int i2 = b * size * n + f2 * size + i; + delta[i1] += - scale * sum * output[i2] / norm; + delta[i2] += - scale * sum * output[i1] / norm; + } + } +} + +void dot_error_gpu(layer l) +{ + dot_kernel<<>>(l.output_gpu, l.dot, l.batch, l.n, l.out_w * l.out_h, l.delta_gpu); + check_error(cudaPeekAtLastError()); +} +*/ + + +__global__ void adam_kernel(int N, float *x, float *m, float *v, float B1, float B2, float rate, float eps, int t) +{ + int index = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if (index >= N) return; + + float mhat = m[index] / (1.f - powf(B1, t)); + float vhat = v[index] / (1.f - powf(B2, t)); + + x[index] = x[index] + rate * mhat / (sqrtf(vhat) + eps); +} + +extern "C" void adam_gpu(int n, float *x, float *m, float *v, float B1, float B2, float rate, float eps, int t) +{ + adam_kernel<<>>(n, x, m, v, B1, B2, rate, eps, t); + check_error(cudaPeekAtLastError()); +} + +extern "C" void adam_update_gpu(float *w, float *d, float *m, float *v, float B1, float B2, float eps, float decay, float rate, int n, int batch, int t) +{ + scal_gpu(n, B1, m, 1); + scal_gpu(n, B2, v, 1); + axpy_gpu(n, -decay*batch, w, 1, d, 1); + + axpy_gpu(n, (1-B1), d, 1, m, 1); + mul_gpu(n, d, 1, d, 1); + axpy_gpu(n, (1-B2), d, 1, v, 1); + + adam_gpu(n, w, m, v, B1, B2, rate, eps, t); + fill_gpu(n, 0, d, 1); +} + +__global__ void normalize_kernel(int N, float *x, float *mean, float *variance, int batch, int filters, int spatial) +{ + int index = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if (index >= N) return; + int f = (index/spatial)%filters; + + x[index] = (x[index] - mean[f])/(sqrtf(variance[f] + .00001f)); +} + +__global__ void normalize_delta_kernel(int N, float *x, float *mean, float *variance, float *mean_delta, float *variance_delta, int batch, int filters, int spatial, float *delta) +{ + int index = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if (index >= N) return; + int f = (index/spatial)%filters; + + delta[index] = delta[index] * 1.f/(sqrtf(variance[f] + .00001f)) + variance_delta[f] * 2.f * (x[index] - mean[f]) / (spatial * batch) + mean_delta[f]/(spatial*batch); +} + +extern "C" void normalize_delta_gpu(float *x, float *mean, float *variance, float *mean_delta, float *variance_delta, int batch, int filters, int spatial, float *delta) +{ + size_t N = batch*filters*spatial; + normalize_delta_kernel<<>>(N, x, mean, variance, mean_delta, variance_delta, batch, filters, spatial, delta); + check_error(cudaPeekAtLastError()); +} + +__global__ void variance_delta_kernel(float *x, float *delta, float *mean, float *variance, int batch, int filters, int spatial, float *variance_delta) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if (i >= filters) return; + int j,k; + variance_delta[i] = 0; + for(j = 0; j < batch; ++j){ + for(k = 0; k < spatial; ++k){ + int index = j*filters*spatial + i*spatial + k; + variance_delta[i] += delta[index]*(x[index] - mean[i]); + } + } + variance_delta[i] *= -.5f * powf(variance[i] + .00001f, (float)(-3.f/2.f)); +} + +__global__ void accumulate_kernel(float *x, int n, int groups, float *sum) +{ + int k; + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if (i >= groups) return; + sum[i] = 0; + for(k = 0; k < n; ++k){ + sum[i] += x[k*groups + i]; + } +} + +__global__ void fast_mean_delta_kernel(float *delta, float *variance, int batch, int filters, int spatial, float *mean_delta) +{ + const int threads = BLOCK; + __shared__ float local[threads]; + + int id = threadIdx.x; + local[id] = 0; + + int filter = blockIdx.x; + + int i, j; + for(j = 0; j < batch; ++j){ + for(i = 0; i < spatial; i += threads){ + int index = j*spatial*filters + filter*spatial + i + id; + local[id] += (i+id < spatial) ? delta[index] : 0; + } + } + + __syncthreads(); + + if(id == 0){ + mean_delta[filter] = 0; + for(i = 0; i < threads; ++i){ + mean_delta[filter] += local[i]; + } + mean_delta[filter] *= (-1.f/sqrtf(variance[filter] + .00001f)); + } +} + +__global__ void fast_variance_delta_kernel(float *x, float *delta, float *mean, float *variance, int batch, int filters, int spatial, float *variance_delta) +{ + const int threads = BLOCK; + __shared__ float local[threads]; + + int id = threadIdx.x; + local[id] = 0; + + int filter = blockIdx.x; + + int i, j; + for(j = 0; j < batch; ++j){ + for(i = 0; i < spatial; i += threads){ + int index = j*spatial*filters + filter*spatial + i + id; + + local[id] += (i+id < spatial) ? delta[index]*(x[index] - mean[filter]) : 0; + } + } + + __syncthreads(); + + if(id == 0){ + variance_delta[filter] = 0; + for(i = 0; i < threads; ++i){ + variance_delta[filter] += local[i]; + } + variance_delta[filter] *= -.5f * powf(variance[filter] + .00001f, (float)(-3.f/2.f)); + } +} + + +__global__ void mean_delta_kernel(float *delta, float *variance, int batch, int filters, int spatial, float *mean_delta) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if (i >= filters) return; + int j,k; + mean_delta[i] = 0; + for (j = 0; j < batch; ++j) { + for (k = 0; k < spatial; ++k) { + int index = j*filters*spatial + i*spatial + k; + mean_delta[i] += delta[index]; + } + } + mean_delta[i] *= (-1.f/sqrtf(variance[i] + .00001f)); +} + +extern "C" void mean_delta_gpu(float *delta, float *variance, int batch, int filters, int spatial, float *mean_delta) +{ + mean_delta_kernel<<>>(delta, variance, batch, filters, spatial, mean_delta); + check_error(cudaPeekAtLastError()); +} + +extern "C" void fast_mean_delta_gpu(float *delta, float *variance, int batch, int filters, int spatial, float *mean_delta) +{ + fast_mean_delta_kernel<<>>(delta, variance, batch, filters, spatial, mean_delta); + check_error(cudaPeekAtLastError()); +} + +extern "C" void fast_variance_delta_gpu(float *x, float *delta, float *mean, float *variance, int batch, int filters, int spatial, float *variance_delta) +{ + fast_variance_delta_kernel<<>>(x, delta, mean, variance, batch, filters, spatial, variance_delta); + check_error(cudaPeekAtLastError()); +} + +__global__ void mean_kernel(float *x, int batch, int filters, int spatial, float *mean) +{ + float scale = 1.f/(batch * spatial); + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if (i >= filters) return; + int j,k; + mean[i] = 0; + for(j = 0; j < batch; ++j){ + for(k = 0; k < spatial; ++k){ + int index = j*filters*spatial + i*spatial + k; + mean[i] += x[index]; + } + } + mean[i] *= scale; +} + +__global__ void variance_kernel(float *x, float *mean, int batch, int filters, int spatial, float *variance) +{ + float scale = 1.f/(batch * spatial - 1); + int j,k; + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if (i >= filters) return; + variance[i] = 0; + for(j = 0; j < batch; ++j){ + for(k = 0; k < spatial; ++k){ + int index = j*filters*spatial + i*spatial + k; + variance[i] += powf((x[index] - mean[i]), 2); + } + } + variance[i] *= scale; +} + +__global__ void reorg_kernel(int N, float *x, int w, int h, int c, int batch, int stride, int forward, float *out) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i >= N) return; + int in_index = i; + int in_w = i%w; + i = i/w; + int in_h = i%h; + i = i/h; + int in_c = i%c; + i = i/c; + int b = i%batch; + + int out_c = c/(stride*stride); + + int c2 = in_c % out_c; + int offset = in_c / out_c; + int w2 = in_w*stride + offset % stride; + int h2 = in_h*stride + offset / stride; + //printf("%d\n", offset); + int out_index = w2 + w*stride*(h2 + h*stride*(c2 + out_c*b)); + + // printf("%d %d %d\n", w2, h2, c2); + //printf("%d %d\n", in_index, out_index); + //if(out_index >= N || out_index < 0) printf("bad bad bad \n"); + + if(forward) out[out_index] = x[in_index]; + else out[in_index] = x[out_index]; + //if(forward) out[1] = x[1]; + //else out[0] = x[0]; +} + +__global__ void axpy_kernel(int N, float ALPHA, float *X, int OFFX, int INCX, float *Y, int OFFY, int INCY) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < N) Y[OFFY+i*INCY] += ALPHA*X[OFFX+i*INCX]; +} + +__global__ void pow_kernel(int N, float ALPHA, float *X, int INCX, float *Y, int INCY) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < N) Y[i*INCY] = pow(X[i*INCX], ALPHA); +} + +__global__ void const_kernel(int N, float ALPHA, float *X, int INCX) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < N) X[i*INCX] = ALPHA; +} + +__global__ void constrain_kernel(int N, float ALPHA, float *X, int INCX) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < N) X[i*INCX] = fminf(ALPHA, fmaxf(-ALPHA, X[i*INCX])); +} + +__global__ void supp_kernel(int N, float ALPHA, float *X, int INCX) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < N) { + if((X[i*INCX] * X[i*INCX]) < (ALPHA * ALPHA)) X[i*INCX] = 0; + } +} + +__global__ void add_kernel(int N, float ALPHA, float *X, int INCX) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < N) X[i*INCX] += ALPHA; +} + +__global__ void scal_kernel(int N, float ALPHA, float *X, int INCX) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < N) X[i*INCX] *= ALPHA; +} + +__global__ void fill_kernel(int N, float ALPHA, float *X, int INCX) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < N) X[i*INCX] = ALPHA; +} + +__global__ void copy_kernel(int N, float *X, int OFFX, int INCX, float *Y, int OFFY, int INCY) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < N) Y[i*INCY + OFFY] = X[i*INCX + OFFX]; +} + +__global__ void mul_kernel(int N, float *X, int INCX, float *Y, int INCY) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < N) Y[i*INCY] *= X[i*INCX]; +} + + +extern "C" void normalize_gpu(float *x, float *mean, float *variance, int batch, int filters, int spatial) +{ + size_t N = batch*filters*spatial; + normalize_kernel<<>>(N, x, mean, variance, batch, filters, spatial); + check_error(cudaPeekAtLastError()); +} + +__global__ void l2norm_kernel(int N, float *x, float *dx, int batch, int filters, int spatial) +{ + int index = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if (index >= N) return; + int b = index / spatial; + int i = index % spatial; + int f; + float sum = 0; + for(f = 0; f < filters; ++f){ + int index = b*filters*spatial + f*spatial + i; + sum += powf(x[index], 2); + } + sum = sqrtf(sum); + if(sum == 0) sum = 1; + //printf("%f\n", sum); + for(f = 0; f < filters; ++f){ + int index = b*filters*spatial + f*spatial + i; + x[index] /= sum; + dx[index] = (1 - x[index]) / sum; + } +} + +extern "C" void l2normalize_gpu(float *x, float *dx, int batch, int filters, int spatial) +{ + size_t N = batch*spatial; + l2norm_kernel<<>>(N, x, dx, batch, filters, spatial); + check_error(cudaPeekAtLastError()); +} + +__global__ void fast_mean_kernel(float *x, int batch, int filters, int spatial, float *mean) +{ + const int threads = BLOCK; + __shared__ float local[threads]; + + int id = threadIdx.x; + local[id] = 0; + + int filter = blockIdx.x; + + int i, j; + for(j = 0; j < batch; ++j){ + for(i = 0; i < spatial; i += threads){ + int index = j*spatial*filters + filter*spatial + i + id; + local[id] += (i+id < spatial) ? x[index] : 0; + } + } + + __syncthreads(); + + if(id == 0){ + mean[filter] = 0; + for(i = 0; i < threads; ++i){ + mean[filter] += local[i]; + } + mean[filter] /= spatial * batch; + } +} + +__global__ void fast_variance_kernel(float *x, float *mean, int batch, int filters, int spatial, float *variance) +{ + const int threads = BLOCK; + __shared__ float local[threads]; + + int id = threadIdx.x; + local[id] = 0; + + int filter = blockIdx.x; + + int i, j; + for(j = 0; j < batch; ++j){ + for(i = 0; i < spatial; i += threads){ + int index = j*spatial*filters + filter*spatial + i + id; + + local[id] += (i+id < spatial) ? powf((x[index] - mean[filter]), 2) : 0; + } + } + + __syncthreads(); + + if(id == 0){ + variance[filter] = 0; + for(i = 0; i < threads; ++i){ + variance[filter] += local[i]; + } + variance[filter] /= (spatial * batch - 1); + } +} + +extern "C" void fast_mean_gpu(float *x, int batch, int filters, int spatial, float *mean) +{ + fast_mean_kernel<<>>(x, batch, filters, spatial, mean); + check_error(cudaPeekAtLastError()); +} + +extern "C" void fast_variance_gpu(float *x, float *mean, int batch, int filters, int spatial, float *variance) +{ + fast_variance_kernel<<>>(x, mean, batch, filters, spatial, variance); + check_error(cudaPeekAtLastError()); +} + + +extern "C" void mean_gpu(float *x, int batch, int filters, int spatial, float *mean) +{ + mean_kernel<<>>(x, batch, filters, spatial, mean); + check_error(cudaPeekAtLastError()); +} + +extern "C" void variance_gpu(float *x, float *mean, int batch, int filters, int spatial, float *variance) +{ + variance_kernel<<>>(x, mean, batch, filters, spatial, variance); + check_error(cudaPeekAtLastError()); +} + +extern "C" void axpy_gpu(int N, float ALPHA, float * X, int INCX, float * Y, int INCY) +{ + axpy_gpu_offset(N, ALPHA, X, 0, INCX, Y, 0, INCY); +} + +extern "C" void pow_gpu(int N, float ALPHA, float * X, int INCX, float * Y, int INCY) +{ + pow_kernel<<>>(N, ALPHA, X, INCX, Y, INCY); + check_error(cudaPeekAtLastError()); +} + +extern "C" void axpy_gpu_offset(int N, float ALPHA, float * X, int OFFX, int INCX, float * Y, int OFFY, int INCY) +{ + axpy_kernel<<>>(N, ALPHA, X, OFFX, INCX, Y, OFFY, INCY); + check_error(cudaPeekAtLastError()); +} + +extern "C" void copy_gpu(int N, float * X, int INCX, float * Y, int INCY) +{ + copy_gpu_offset(N, X, 0, INCX, Y, 0, INCY); +} + +extern "C" void mul_gpu(int N, float * X, int INCX, float * Y, int INCY) +{ + mul_kernel<<>>(N, X, INCX, Y, INCY); + check_error(cudaPeekAtLastError()); +} + +extern "C" void copy_gpu_offset(int N, float * X, int OFFX, int INCX, float * Y, int OFFY, int INCY) +{ + copy_kernel<<>>(N, X, OFFX, INCX, Y, OFFY, INCY); + check_error(cudaPeekAtLastError()); +} + +__global__ void flatten_kernel(int N, float *x, int spatial, int layers, int batch, int forward, float *out) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i >= N) return; + int in_s = i%spatial; + i = i/spatial; + int in_c = i%layers; + i = i/layers; + int b = i; + + int i1 = b*layers*spatial + in_c*spatial + in_s; + int i2 = b*layers*spatial + in_s*layers + in_c; + + if (forward) out[i2] = x[i1]; + else out[i1] = x[i2]; +} + +extern "C" void flatten_gpu(float *x, int spatial, int layers, int batch, int forward, float *out) +{ + int size = spatial*batch*layers; + flatten_kernel<<>>(size, x, spatial, layers, batch, forward, out); + check_error(cudaPeekAtLastError()); +} + +extern "C" void reorg_gpu(float *x, int w, int h, int c, int batch, int stride, int forward, float *out) +{ + int size = w*h*c*batch; + reorg_kernel<<>>(size, x, w, h, c, batch, stride, forward, out); + check_error(cudaPeekAtLastError()); +} + +__global__ void mask_kernel(int n, float *x, float mask_num, float *mask, float val) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < n && mask[i] == mask_num) x[i] = val; +} + +extern "C" void mask_gpu(int N, float * X, float mask_num, float * mask, float val) +{ + mask_kernel<<>>(N, X, mask_num, mask, val); + check_error(cudaPeekAtLastError()); +} + +__global__ void scale_mask_kernel(int n, float *x, float mask_num, float *mask, float scale) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < n && mask[i] == mask_num) x[i] *= scale; +} + +extern "C" void scale_mask_gpu(int N, float * X, float mask_num, float * mask, float scale) +{ + scale_mask_kernel<<>>(N, X, mask_num, mask, scale); + check_error(cudaPeekAtLastError()); +} + +extern "C" void const_gpu(int N, float ALPHA, float * X, int INCX) +{ + const_kernel<<>>(N, ALPHA, X, INCX); + check_error(cudaPeekAtLastError()); +} + +extern "C" void constrain_gpu(int N, float ALPHA, float * X, int INCX) +{ + constrain_kernel<<>>(N, ALPHA, X, INCX); + check_error(cudaPeekAtLastError()); +} + + +extern "C" void add_gpu(int N, float ALPHA, float * X, int INCX) +{ + add_kernel<<>>(N, ALPHA, X, INCX); + check_error(cudaPeekAtLastError()); +} + +extern "C" void scal_gpu(int N, float ALPHA, float * X, int INCX) +{ + scal_kernel<<>>(N, ALPHA, X, INCX); + check_error(cudaPeekAtLastError()); +} + +extern "C" void supp_gpu(int N, float ALPHA, float * X, int INCX) +{ + supp_kernel<<>>(N, ALPHA, X, INCX); + check_error(cudaPeekAtLastError()); +} + +extern "C" void fill_gpu(int N, float ALPHA, float * X, int INCX) +{ + fill_kernel<<>>(N, ALPHA, X, INCX); + check_error(cudaPeekAtLastError()); +} + +__global__ void shortcut_kernel(int size, int minw, int minh, int minc, int stride, int sample, int batch, int w1, int h1, int c1, float *add, int w2, int h2, int c2, float s1, float s2, float *out) +{ + int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if (id >= size) return; + int i = id % minw; + id /= minw; + int j = id % minh; + id /= minh; + int k = id % minc; + id /= minc; + int b = id % batch; + + int out_index = i*sample + w2*(j*sample + h2*(k + c2*b)); + int add_index = i*stride + w1*(j*stride + h1*(k + c1*b)); + out[out_index] = s1*out[out_index] + s2*add[add_index]; + //out[out_index] += add[add_index]; +} + +extern "C" void shortcut_gpu(int batch, int w1, int h1, int c1, float *add, int w2, int h2, int c2, float s1, float s2, float *out) +{ + int minw = (w1 < w2) ? w1 : w2; + int minh = (h1 < h2) ? h1 : h2; + int minc = (c1 < c2) ? c1 : c2; + + int stride = w1/w2; + int sample = w2/w1; + assert(stride == h1/h2); + assert(sample == h2/h1); + if(stride < 1) stride = 1; + if(sample < 1) sample = 1; + + int size = batch * minw * minh * minc; + shortcut_kernel<<>>(size, minw, minh, minc, stride, sample, batch, w1, h1, c1, add, w2, h2, c2, s1, s2, out); + check_error(cudaPeekAtLastError()); +} + +__global__ void smooth_l1_kernel(int n, float *pred, float *truth, float *delta, float *error) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < n){ + float diff = truth[i] - pred[i]; + float abs_val = fabsf(diff); + if(abs_val < 1) { + error[i] = diff * diff; + delta[i] = diff; + } + else { + error[i] = 2*abs_val - 1; + delta[i] = (diff > 0) ? 1 : -1; + } + } +} + +extern "C" void smooth_l1_gpu(int n, float *pred, float *truth, float *delta, float *error) +{ + smooth_l1_kernel<<>>(n, pred, truth, delta, error); + check_error(cudaPeekAtLastError()); +} + +__global__ void softmax_x_ent_kernel(int n, float *pred, float *truth, float *delta, float *error) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < n){ + float t = truth[i]; + float p = pred[i]; + error[i] = (t) ? -log(p) : 0; + delta[i] = t-p; + } +} + +extern "C" void softmax_x_ent_gpu(int n, float *pred, float *truth, float *delta, float *error) +{ + softmax_x_ent_kernel<<>>(n, pred, truth, delta, error); + check_error(cudaPeekAtLastError()); +} + +__global__ void logistic_x_ent_kernel(int n, float *pred, float *truth, float *delta, float *error) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < n){ + float t = truth[i]; + float p = pred[i]; + error[i] = -t*log(p+.0000001) - (1-t)*log(1-p+.0000001); + delta[i] = t-p; + } +} + +extern "C" void logistic_x_ent_gpu(int n, float *pred, float *truth, float *delta, float *error) +{ + logistic_x_ent_kernel<<>>(n, pred, truth, delta, error); + check_error(cudaPeekAtLastError()); +} + +__global__ void l2_kernel(int n, float *pred, float *truth, float *delta, float *error) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < n){ + float diff = truth[i] - pred[i]; + error[i] = diff * diff; //I know this is technically wrong, deal with it. + delta[i] = diff; + } +} + +extern "C" void l2_gpu(int n, float *pred, float *truth, float *delta, float *error) +{ + l2_kernel<<>>(n, pred, truth, delta, error); + check_error(cudaPeekAtLastError()); +} + +__global__ void l1_kernel(int n, float *pred, float *truth, float *delta, float *error) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < n){ + float diff = truth[i] - pred[i]; + error[i] = abs(diff); + delta[i] = (diff > 0) ? 1 : -1; + } +} + +extern "C" void l1_gpu(int n, float *pred, float *truth, float *delta, float *error) +{ + l1_kernel<<>>(n, pred, truth, delta, error); + check_error(cudaPeekAtLastError()); +} + +__global__ void wgan_kernel(int n, float *pred, float *truth, float *delta, float *error) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < n){ + error[i] = truth[i] ? -pred[i] : pred[i]; + delta[i] = (truth[i] > 0) ? 1 : -1; + } +} + +extern "C" void wgan_gpu(int n, float *pred, float *truth, float *delta, float *error) +{ + wgan_kernel<<>>(n, pred, truth, delta, error); + check_error(cudaPeekAtLastError()); +} + + + + +__global__ void weighted_sum_kernel(int n, float *a, float *b, float *s, float *c) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < n){ + c[i] = s[i]*a[i] + (1-s[i])*(b ? b[i] : 0); + } +} + +__global__ void deinter_kernel(int NX, float *X, int NY, float *Y, int B, float *OUT) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < (NX+NY)*B){ + int b = i / (NX+NY); + int j = i % (NX+NY); + if (j < NX){ + if(X) X[b*NX + j] += OUT[i]; + } else { + if(Y) Y[b*NY + j - NX] += OUT[i]; + } + } +} + +extern "C" void deinter_gpu(int NX, float *X, int NY, float *Y, int B, float *OUT) +{ + deinter_kernel<<>>(NX, X, NY, Y, B, OUT); + check_error(cudaPeekAtLastError()); +} + +__global__ void inter_kernel(int NX, float *X, int NY, float *Y, int B, float *OUT) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < (NX+NY)*B){ + int b = i / (NX+NY); + int j = i % (NX+NY); + if (j < NX){ + OUT[i] = X[b*NX + j]; + } else { + OUT[i] = Y[b*NY + j - NX]; + } + } +} + +extern "C" void inter_gpu(int NX, float *X, int NY, float *Y, int B, float *OUT) +{ + inter_kernel<<>>(NX, X, NY, Y, B, OUT); + check_error(cudaPeekAtLastError()); +} + +extern "C" void weighted_sum_gpu(float *a, float *b, float *s, int num, float *c) +{ + weighted_sum_kernel<<>>(num, a, b, s, c); + check_error(cudaPeekAtLastError()); +} + +__global__ void weighted_delta_kernel(int n, float *a, float *b, float *s, float *da, float *db, float *ds, float *dc) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < n){ + if(da) da[i] += dc[i] * s[i]; + if(db) db[i] += dc[i] * (1-s[i]); + ds[i] += dc[i] * (a[i] - b[i]); + } +} + +extern "C" void weighted_delta_gpu(float *a, float *b, float *s, float *da, float *db, float *ds, int num, float *dc) +{ + weighted_delta_kernel<<>>(num, a, b, s, da, db, ds, dc); + check_error(cudaPeekAtLastError()); +} + +__global__ void mult_add_into_kernel(int n, float *a, float *b, float *c) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i < n){ + c[i] += a[i]*b[i]; + } +} + +extern "C" void mult_add_into_gpu(int num, float *a, float *b, float *c) +{ + mult_add_into_kernel<<>>(num, a, b, c); + check_error(cudaPeekAtLastError()); +} + + +__device__ void softmax_device(float *input, int n, float temp, int stride, float *output) +{ + int i; + float sum = 0; + float largest = -INFINITY; + for(i = 0; i < n; ++i){ + int val = input[i*stride]; + largest = (val>largest) ? val : largest; + } + for(i = 0; i < n; ++i){ + float e = expf(input[i*stride]/temp - largest/temp); + sum += e; + output[i*stride] = e; + } + for(i = 0; i < n; ++i){ + output[i*stride] /= sum; + } +} + + +__global__ void softmax_tree_kernel(float *input, int spatial, int batch, int stride, float temp, float *output, int groups, int *group_size, int *group_offset) +{ + int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if (id >= spatial*batch*groups) return; + int s = id % spatial; + id = id / spatial; + int g = id % groups; + int b = id / groups; + int goff = group_offset[g]*spatial; + int boff = b*stride; + softmax_device(input + goff + boff + s, group_size[g], temp, spatial, output + goff + boff + s); +} + +extern "C" void softmax_tree(float *input, int spatial, int batch, int stride, float temp, float *output, tree hier) +{ + int *tree_groups_size = cuda_make_int_array(hier.group_size, hier.groups); + int *tree_groups_offset = cuda_make_int_array(hier.group_offset, hier.groups); + /* + static int *tree_groups_size = 0; + static int *tree_groups_offset = 0; + if(!tree_groups_size){ + tree_groups_size = cuda_make_int_array(hier.group_size, hier.groups); + tree_groups_offset = cuda_make_int_array(hier.group_offset, hier.groups); + } + */ + int num = spatial*batch*hier.groups; + softmax_tree_kernel<<>>(input, spatial, batch, stride, temp, output, hier.groups, tree_groups_size, tree_groups_offset); + check_error(cudaPeekAtLastError()); + cuda_free((float *)tree_groups_size); + cuda_free((float *)tree_groups_offset); +} + +__global__ void softmax_kernel(float *input, int n, int batch, int batch_offset, int groups, int group_offset, int stride, float temp, float *output) +{ + int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if (id >= batch*groups) return; + int b = id / groups; + int g = id % groups; + softmax_device(input + b*batch_offset + g*group_offset, n, temp, stride, output + b*batch_offset + g*group_offset); +} + +extern "C" void softmax_gpu(float *input, int n, int batch, int batch_offset, int groups, int group_offset, int stride, float temp, float *output) +{ + softmax_kernel<<>>(input, n, batch, batch_offset, groups, group_offset, stride, temp, output); + check_error(cudaPeekAtLastError()); +} + + +__global__ void upsample_kernel(size_t N, float *x, int w, int h, int c, int batch, int stride, int forward, float scale, float *out) +{ + size_t i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i >= N) return; + int out_index = i; + int out_w = i%(w*stride); + i = i/(w*stride); + int out_h = i%(h*stride); + i = i/(h*stride); + int out_c = i%c; + i = i/c; + int b = i%batch; + + int in_w = out_w / stride; + int in_h = out_h / stride; + int in_c = out_c; + + int in_index = b*w*h*c + in_c*w*h + in_h*w + in_w; + + + if(forward) out[out_index] += scale * x[in_index]; + else atomicAdd(x+in_index, scale * out[out_index]); +} +extern "C" void upsample_gpu(float *in, int w, int h, int c, int batch, int stride, int forward, float scale, float *out) +{ + size_t size = w*h*c*batch*stride*stride; + upsample_kernel<<>>(size, in, w, h, c, batch, stride, forward, scale, out); + check_error(cudaPeekAtLastError()); +} diff --git a/hanzi_detection/src/box.c b/hanzi_detection/src/box.c new file mode 100755 index 0000000..8a1772c --- /dev/null +++ b/hanzi_detection/src/box.c @@ -0,0 +1,357 @@ +#include "box.h" +#include +#include +#include + +int nms_comparator(const void *pa, const void *pb) +{ + detection a = *(detection *)pa; + detection b = *(detection *)pb; + float diff = 0; + if(b.sort_class >= 0){ + diff = a.prob[b.sort_class] - b.prob[b.sort_class]; + } else { + diff = a.objectness - b.objectness; + } + if(diff < 0) return 1; + else if(diff > 0) return -1; + return 0; +} + +void do_nms_obj(detection *dets, int total, int classes, float thresh) +{ + int i, j, k; + k = total-1; + for(i = 0; i <= k; ++i){ + if(dets[i].objectness == 0){ + detection swap = dets[i]; + dets[i] = dets[k]; + dets[k] = swap; + --k; + --i; + } + } + total = k+1; + + for(i = 0; i < total; ++i){ + dets[i].sort_class = -1; + } + + qsort(dets, total, sizeof(detection), nms_comparator); + for(i = 0; i < total; ++i){ + if(dets[i].objectness == 0) continue; + box a = dets[i].bbox; + for(j = i+1; j < total; ++j){ + if(dets[j].objectness == 0) continue; + box b = dets[j].bbox; + if (box_iou(a, b) > thresh){ + dets[j].objectness = 0; + for(k = 0; k < classes; ++k){ + dets[j].prob[k] = 0; + } + } + } + } +} + + +void do_nms_sort(detection *dets, int total, int classes, float thresh) +{ + int i, j, k; + k = total-1; + for(i = 0; i <= k; ++i){ + if(dets[i].objectness == 0){ + detection swap = dets[i]; + dets[i] = dets[k]; + dets[k] = swap; + --k; + --i; + } + } + total = k+1; + + for(k = 0; k < classes; ++k){ + for(i = 0; i < total; ++i){ + dets[i].sort_class = k; + } + qsort(dets, total, sizeof(detection), nms_comparator); + for(i = 0; i < total; ++i){ + if(dets[i].prob[k] == 0) continue; + box a = dets[i].bbox; + for(j = i+1; j < total; ++j){ + box b = dets[j].bbox; + if (box_iou(a, b) > thresh){ + dets[j].prob[k] = 0; + } + } + } + } +} + +box float_to_box(float *f, int stride) +{ + box b = {0}; + b.x = f[0]; + b.y = f[1*stride]; + b.w = f[2*stride]; + b.h = f[3*stride]; + return b; +} + +dbox derivative(box a, box b) +{ + dbox d; + d.dx = 0; + d.dw = 0; + float l1 = a.x - a.w/2; + float l2 = b.x - b.w/2; + if (l1 > l2){ + d.dx -= 1; + d.dw += .5; + } + float r1 = a.x + a.w/2; + float r2 = b.x + b.w/2; + if(r1 < r2){ + d.dx += 1; + d.dw += .5; + } + if (l1 > r2) { + d.dx = -1; + d.dw = 0; + } + if (r1 < l2){ + d.dx = 1; + d.dw = 0; + } + + d.dy = 0; + d.dh = 0; + float t1 = a.y - a.h/2; + float t2 = b.y - b.h/2; + if (t1 > t2){ + d.dy -= 1; + d.dh += .5; + } + float b1 = a.y + a.h/2; + float b2 = b.y + b.h/2; + if(b1 < b2){ + d.dy += 1; + d.dh += .5; + } + if (t1 > b2) { + d.dy = -1; + d.dh = 0; + } + if (b1 < t2){ + d.dy = 1; + d.dh = 0; + } + return d; +} + +float overlap(float x1, float w1, float x2, float w2) +{ + float l1 = x1 - w1/2; + float l2 = x2 - w2/2; + float left = l1 > l2 ? l1 : l2; + float r1 = x1 + w1/2; + float r2 = x2 + w2/2; + float right = r1 < r2 ? r1 : r2; + return right - left; +} + +float box_intersection(box a, box b) +{ + float w = overlap(a.x, a.w, b.x, b.w); + float h = overlap(a.y, a.h, b.y, b.h); + if(w < 0 || h < 0) return 0; + float area = w*h; + return area; +} + +float box_union(box a, box b) +{ + float i = box_intersection(a, b); + float u = a.w*a.h + b.w*b.h - i; + return u; +} + +float box_iou(box a, box b) +{ + return box_intersection(a, b)/box_union(a, b); +} + +float box_rmse(box a, box b) +{ + return sqrt(pow(a.x-b.x, 2) + + pow(a.y-b.y, 2) + + pow(a.w-b.w, 2) + + pow(a.h-b.h, 2)); +} + +dbox dintersect(box a, box b) +{ + float w = overlap(a.x, a.w, b.x, b.w); + float h = overlap(a.y, a.h, b.y, b.h); + dbox dover = derivative(a, b); + dbox di; + + di.dw = dover.dw*h; + di.dx = dover.dx*h; + di.dh = dover.dh*w; + di.dy = dover.dy*w; + + return di; +} + +dbox dunion(box a, box b) +{ + dbox du; + + dbox di = dintersect(a, b); + du.dw = a.h - di.dw; + du.dh = a.w - di.dh; + du.dx = -di.dx; + du.dy = -di.dy; + + return du; +} + + +void test_dunion() +{ + box a = {0, 0, 1, 1}; + box dxa= {0+.0001, 0, 1, 1}; + box dya= {0, 0+.0001, 1, 1}; + box dwa= {0, 0, 1+.0001, 1}; + box dha= {0, 0, 1, 1+.0001}; + + box b = {.5, .5, .2, .2}; + dbox di = dunion(a,b); + printf("Union: %f %f %f %f\n", di.dx, di.dy, di.dw, di.dh); + float inter = box_union(a, b); + float xinter = box_union(dxa, b); + float yinter = box_union(dya, b); + float winter = box_union(dwa, b); + float hinter = box_union(dha, b); + xinter = (xinter - inter)/(.0001); + yinter = (yinter - inter)/(.0001); + winter = (winter - inter)/(.0001); + hinter = (hinter - inter)/(.0001); + printf("Union Manual %f %f %f %f\n", xinter, yinter, winter, hinter); +} +void test_dintersect() +{ + box a = {0, 0, 1, 1}; + box dxa= {0+.0001, 0, 1, 1}; + box dya= {0, 0+.0001, 1, 1}; + box dwa= {0, 0, 1+.0001, 1}; + box dha= {0, 0, 1, 1+.0001}; + + box b = {.5, .5, .2, .2}; + dbox di = dintersect(a,b); + printf("Inter: %f %f %f %f\n", di.dx, di.dy, di.dw, di.dh); + float inter = box_intersection(a, b); + float xinter = box_intersection(dxa, b); + float yinter = box_intersection(dya, b); + float winter = box_intersection(dwa, b); + float hinter = box_intersection(dha, b); + xinter = (xinter - inter)/(.0001); + yinter = (yinter - inter)/(.0001); + winter = (winter - inter)/(.0001); + hinter = (hinter - inter)/(.0001); + printf("Inter Manual %f %f %f %f\n", xinter, yinter, winter, hinter); +} + +void test_box() +{ + test_dintersect(); + test_dunion(); + box a = {0, 0, 1, 1}; + box dxa= {0+.00001, 0, 1, 1}; + box dya= {0, 0+.00001, 1, 1}; + box dwa= {0, 0, 1+.00001, 1}; + box dha= {0, 0, 1, 1+.00001}; + + box b = {.5, 0, .2, .2}; + + float iou = box_iou(a,b); + iou = (1-iou)*(1-iou); + printf("%f\n", iou); + dbox d = diou(a, b); + printf("%f %f %f %f\n", d.dx, d.dy, d.dw, d.dh); + + float xiou = box_iou(dxa, b); + float yiou = box_iou(dya, b); + float wiou = box_iou(dwa, b); + float hiou = box_iou(dha, b); + xiou = ((1-xiou)*(1-xiou) - iou)/(.00001); + yiou = ((1-yiou)*(1-yiou) - iou)/(.00001); + wiou = ((1-wiou)*(1-wiou) - iou)/(.00001); + hiou = ((1-hiou)*(1-hiou) - iou)/(.00001); + printf("manual %f %f %f %f\n", xiou, yiou, wiou, hiou); +} + +dbox diou(box a, box b) +{ + float u = box_union(a,b); + float i = box_intersection(a,b); + dbox di = dintersect(a,b); + dbox du = dunion(a,b); + dbox dd = {0,0,0,0}; + + if(i <= 0 || 1) { + dd.dx = b.x - a.x; + dd.dy = b.y - a.y; + dd.dw = b.w - a.w; + dd.dh = b.h - a.h; + return dd; + } + + dd.dx = 2*pow((1-(i/u)),1)*(di.dx*u - du.dx*i)/(u*u); + dd.dy = 2*pow((1-(i/u)),1)*(di.dy*u - du.dy*i)/(u*u); + dd.dw = 2*pow((1-(i/u)),1)*(di.dw*u - du.dw*i)/(u*u); + dd.dh = 2*pow((1-(i/u)),1)*(di.dh*u - du.dh*i)/(u*u); + return dd; +} + + +void do_nms(box *boxes, float **probs, int total, int classes, float thresh) +{ + int i, j, k; + for(i = 0; i < total; ++i){ + int any = 0; + for(k = 0; k < classes; ++k) any = any || (probs[i][k] > 0); + if(!any) { + continue; + } + for(j = i+1; j < total; ++j){ + if (box_iou(boxes[i], boxes[j]) > thresh){ + for(k = 0; k < classes; ++k){ + if (probs[i][k] < probs[j][k]) probs[i][k] = 0; + else probs[j][k] = 0; + } + } + } + } +} + +box encode_box(box b, box anchor) +{ + box encode; + encode.x = (b.x - anchor.x) / anchor.w; + encode.y = (b.y - anchor.y) / anchor.h; + encode.w = log2(b.w / anchor.w); + encode.h = log2(b.h / anchor.h); + return encode; +} + +box decode_box(box b, box anchor) +{ + box decode; + decode.x = b.x * anchor.w + anchor.x; + decode.y = b.y * anchor.h + anchor.y; + decode.w = pow(2., b.w) * anchor.w; + decode.h = pow(2., b.h) * anchor.h; + return decode; +} diff --git a/hanzi_detection/src/box.h b/hanzi_detection/src/box.h new file mode 100755 index 0000000..dda3e59 --- /dev/null +++ b/hanzi_detection/src/box.h @@ -0,0 +1,14 @@ +#ifndef BOX_H +#define BOX_H +#include "darknet.h" + +typedef struct{ + float dx, dy, dw, dh; +} dbox; + +float box_rmse(box a, box b); +dbox diou(box a, box b); +box decode_box(box b, box anchor); +box encode_box(box b, box anchor); + +#endif diff --git a/hanzi_detection/src/classifier.h b/hanzi_detection/src/classifier.h new file mode 100755 index 0000000..8b13789 --- /dev/null +++ b/hanzi_detection/src/classifier.h @@ -0,0 +1 @@ + diff --git a/hanzi_detection/src/col2im.c b/hanzi_detection/src/col2im.c new file mode 100755 index 0000000..5c4605e --- /dev/null +++ b/hanzi_detection/src/col2im.c @@ -0,0 +1,39 @@ +#include +#include +void col2im_add_pixel(float *im, int height, int width, int channels, + int row, int col, int channel, int pad, float val) +{ + row -= pad; + col -= pad; + + if (row < 0 || col < 0 || + row >= height || col >= width) return; + im[col + width*(row + height*channel)] += val; +} +//This one might be too, can't remember. +void col2im_cpu(float* data_col, + int channels, int height, int width, + int ksize, int stride, int pad, float* data_im) +{ + int c,h,w; + int height_col = (height + 2*pad - ksize) / stride + 1; + int width_col = (width + 2*pad - ksize) / stride + 1; + + int channels_col = channels * ksize * ksize; + for (c = 0; c < channels_col; ++c) { + int w_offset = c % ksize; + int h_offset = (c / ksize) % ksize; + int c_im = c / ksize / ksize; + for (h = 0; h < height_col; ++h) { + for (w = 0; w < width_col; ++w) { + int im_row = h_offset + h * stride; + int im_col = w_offset + w * stride; + int col_index = (c * height_col + h) * width_col + w; + double val = data_col[col_index]; + col2im_add_pixel(data_im, height, width, channels, + im_row, im_col, c_im, pad, val); + } + } + } +} + diff --git a/hanzi_detection/src/col2im.h b/hanzi_detection/src/col2im.h new file mode 100755 index 0000000..3fbe053 --- /dev/null +++ b/hanzi_detection/src/col2im.h @@ -0,0 +1,13 @@ +#ifndef COL2IM_H +#define COL2IM_H + +void col2im_cpu(float* data_col, + int channels, int height, int width, + int ksize, int stride, int pad, float* data_im); + +#ifdef GPU +void col2im_gpu(float *data_col, + int channels, int height, int width, + int ksize, int stride, int pad, float *data_im); +#endif +#endif diff --git a/hanzi_detection/src/col2im_kernels.cu b/hanzi_detection/src/col2im_kernels.cu new file mode 100755 index 0000000..ba45e0f --- /dev/null +++ b/hanzi_detection/src/col2im_kernels.cu @@ -0,0 +1,58 @@ +#include "cuda_runtime.h" +#include "curand.h" +#include "cublas_v2.h" + +extern "C" { +#include "col2im.h" +#include "cuda.h" +} + +// src: https://github.com/BVLC/caffe/blob/master/src/caffe/util/im2col.cu +// You may also want to read: https://github.com/BVLC/caffe/blob/master/LICENSE + +__global__ void col2im_gpu_kernel(const int n, const float* data_col, + const int height, const int width, const int ksize, + const int pad, + const int stride, + const int height_col, const int width_col, + float *data_im) { + int index = blockIdx.x*blockDim.x+threadIdx.x; + for(; index < n; index += blockDim.x*gridDim.x){ + float val = 0; + int w = index % width + pad; + int h = (index / width) % height + pad; + int c = index / (width * height); + // compute the start and end of the output + int w_col_start = (w < ksize) ? 0 : (w - ksize) / stride + 1; + int w_col_end = min(w / stride + 1, width_col); + int h_col_start = (h < ksize) ? 0 : (h - ksize) / stride + 1; + int h_col_end = min(h / stride + 1, height_col); + // equivalent implementation + int offset = + (c * ksize * ksize + h * ksize + w) * height_col * width_col; + int coeff_h_col = (1 - stride * ksize * height_col) * width_col; + int coeff_w_col = (1 - stride * height_col * width_col); + for (int h_col = h_col_start; h_col < h_col_end; ++h_col) { + for (int w_col = w_col_start; w_col < w_col_end; ++w_col) { + val += data_col[offset + h_col * coeff_h_col + w_col * coeff_w_col]; + } + } + data_im[index] += val; + } +} + +void col2im_gpu(float *data_col, + int channels, int height, int width, + int ksize, int stride, int pad, float *data_im){ + // We are going to launch channels * height_col * width_col kernels, each + // kernel responsible for copying a single-channel grid. + int height_col = (height + 2 * pad - ksize) / stride + 1; + int width_col = (width + 2 * pad - ksize) / stride + 1; + int num_kernels = channels * height * width; + col2im_gpu_kernel<<<(num_kernels+BLOCK-1)/BLOCK, + BLOCK>>>( + num_kernels, data_col, height, width, ksize, pad, + stride, height_col, + width_col, data_im); +} + diff --git a/hanzi_detection/src/compare.c b/hanzi_detection/src/compare.c new file mode 100755 index 0000000..d2d2b3b --- /dev/null +++ b/hanzi_detection/src/compare.c @@ -0,0 +1,352 @@ +#include + +#include "network.h" +#include "detection_layer.h" +#include "cost_layer.h" +#include "utils.h" +#include "parser.h" +#include "box.h" + +void train_compare(char *cfgfile, char *weightfile) +{ + srand(time(0)); + float avg_loss = -1; + char *base = basecfg(cfgfile); + char *backup_directory = "/home/pjreddie/backup/"; + printf("%s\n", base); + network net = parse_network_cfg(cfgfile); + if(weightfile){ + load_weights(&net, weightfile); + } + printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net.learning_rate, net.momentum, net.decay); + int imgs = 1024; + list *plist = get_paths("data/compare.train.list"); + char **paths = (char **)list_to_array(plist); + int N = plist->size; + printf("%d\n", N); + clock_t time; + pthread_t load_thread; + data train; + data buffer; + + load_args args = {0}; + args.w = net.w; + args.h = net.h; + args.paths = paths; + args.classes = 20; + args.n = imgs; + args.m = N; + args.d = &buffer; + args.type = COMPARE_DATA; + + load_thread = load_data_in_thread(args); + int epoch = *net.seen/N; + int i = 0; + while(1){ + ++i; + time=clock(); + pthread_join(load_thread, 0); + train = buffer; + + load_thread = load_data_in_thread(args); + printf("Loaded: %lf seconds\n", sec(clock()-time)); + time=clock(); + float loss = train_network(net, train); + if(avg_loss == -1) avg_loss = loss; + avg_loss = avg_loss*.9 + loss*.1; + printf("%.3f: %f, %f avg, %lf seconds, %ld images\n", (float)*net.seen/N, loss, avg_loss, sec(clock()-time), *net.seen); + free_data(train); + if(i%100 == 0){ + char buff[256]; + sprintf(buff, "%s/%s_%d_minor_%d.weights",backup_directory,base, epoch, i); + save_weights(net, buff); + } + if(*net.seen/N > epoch){ + epoch = *net.seen/N; + i = 0; + char buff[256]; + sprintf(buff, "%s/%s_%d.weights",backup_directory,base, epoch); + save_weights(net, buff); + if(epoch%22 == 0) net.learning_rate *= .1; + } + } + pthread_join(load_thread, 0); + free_data(buffer); + free_network(net); + free_ptrs((void**)paths, plist->size); + free_list(plist); + free(base); +} + +void validate_compare(char *filename, char *weightfile) +{ + int i = 0; + network net = parse_network_cfg(filename); + if(weightfile){ + load_weights(&net, weightfile); + } + srand(time(0)); + + list *plist = get_paths("data/compare.val.list"); + //list *plist = get_paths("data/compare.val.old"); + char **paths = (char **)list_to_array(plist); + int N = plist->size/2; + free_list(plist); + + clock_t time; + int correct = 0; + int total = 0; + int splits = 10; + int num = (i+1)*N/splits - i*N/splits; + + data val, buffer; + + load_args args = {0}; + args.w = net.w; + args.h = net.h; + args.paths = paths; + args.classes = 20; + args.n = num; + args.m = 0; + args.d = &buffer; + args.type = COMPARE_DATA; + + pthread_t load_thread = load_data_in_thread(args); + for(i = 1; i <= splits; ++i){ + time=clock(); + + pthread_join(load_thread, 0); + val = buffer; + + num = (i+1)*N/splits - i*N/splits; + char **part = paths+(i*N/splits); + if(i != splits){ + args.paths = part; + load_thread = load_data_in_thread(args); + } + printf("Loaded: %d images in %lf seconds\n", val.X.rows, sec(clock()-time)); + + time=clock(); + matrix pred = network_predict_data(net, val); + int j,k; + for(j = 0; j < val.y.rows; ++j){ + for(k = 0; k < 20; ++k){ + if(val.y.vals[j][k*2] != val.y.vals[j][k*2+1]){ + ++total; + if((val.y.vals[j][k*2] < val.y.vals[j][k*2+1]) == (pred.vals[j][k*2] < pred.vals[j][k*2+1])){ + ++correct; + } + } + } + } + free_matrix(pred); + printf("%d: Acc: %f, %lf seconds, %d images\n", i, (float)correct/total, sec(clock()-time), val.X.rows); + free_data(val); + } +} + +typedef struct { + network net; + char *filename; + int class; + int classes; + float elo; + float *elos; +} sortable_bbox; + +int total_compares = 0; +int current_class = 0; + +int elo_comparator(const void*a, const void *b) +{ + sortable_bbox box1 = *(sortable_bbox*)a; + sortable_bbox box2 = *(sortable_bbox*)b; + if(box1.elos[current_class] == box2.elos[current_class]) return 0; + if(box1.elos[current_class] > box2.elos[current_class]) return -1; + return 1; +} + +int bbox_comparator(const void *a, const void *b) +{ + ++total_compares; + sortable_bbox box1 = *(sortable_bbox*)a; + sortable_bbox box2 = *(sortable_bbox*)b; + network net = box1.net; + int class = box1.class; + + image im1 = load_image_color(box1.filename, net.w, net.h); + image im2 = load_image_color(box2.filename, net.w, net.h); + float *X = calloc(net.w*net.h*net.c, sizeof(float)); + memcpy(X, im1.data, im1.w*im1.h*im1.c*sizeof(float)); + memcpy(X+im1.w*im1.h*im1.c, im2.data, im2.w*im2.h*im2.c*sizeof(float)); + float *predictions = network_predict(net, X); + + free_image(im1); + free_image(im2); + free(X); + if (predictions[class*2] > predictions[class*2+1]){ + return 1; + } + return -1; +} + +void bbox_update(sortable_bbox *a, sortable_bbox *b, int class, int result) +{ + int k = 32; + float EA = 1./(1+pow(10, (b->elos[class] - a->elos[class])/400.)); + float EB = 1./(1+pow(10, (a->elos[class] - b->elos[class])/400.)); + float SA = result ? 1 : 0; + float SB = result ? 0 : 1; + a->elos[class] += k*(SA - EA); + b->elos[class] += k*(SB - EB); +} + +void bbox_fight(network net, sortable_bbox *a, sortable_bbox *b, int classes, int class) +{ + image im1 = load_image_color(a->filename, net.w, net.h); + image im2 = load_image_color(b->filename, net.w, net.h); + float *X = calloc(net.w*net.h*net.c, sizeof(float)); + memcpy(X, im1.data, im1.w*im1.h*im1.c*sizeof(float)); + memcpy(X+im1.w*im1.h*im1.c, im2.data, im2.w*im2.h*im2.c*sizeof(float)); + float *predictions = network_predict(net, X); + ++total_compares; + + int i; + for(i = 0; i < classes; ++i){ + if(class < 0 || class == i){ + int result = predictions[i*2] > predictions[i*2+1]; + bbox_update(a, b, i, result); + } + } + + free_image(im1); + free_image(im2); + free(X); +} + +void SortMaster3000(char *filename, char *weightfile) +{ + int i = 0; + network net = parse_network_cfg(filename); + if(weightfile){ + load_weights(&net, weightfile); + } + srand(time(0)); + set_batch_network(&net, 1); + + list *plist = get_paths("data/compare.sort.list"); + //list *plist = get_paths("data/compare.val.old"); + char **paths = (char **)list_to_array(plist); + int N = plist->size; + free_list(plist); + sortable_bbox *boxes = calloc(N, sizeof(sortable_bbox)); + printf("Sorting %d boxes...\n", N); + for(i = 0; i < N; ++i){ + boxes[i].filename = paths[i]; + boxes[i].net = net; + boxes[i].class = 7; + boxes[i].elo = 1500; + } + clock_t time=clock(); + qsort(boxes, N, sizeof(sortable_bbox), bbox_comparator); + for(i = 0; i < N; ++i){ + printf("%s\n", boxes[i].filename); + } + printf("Sorted in %d compares, %f secs\n", total_compares, sec(clock()-time)); +} + +void BattleRoyaleWithCheese(char *filename, char *weightfile) +{ + int classes = 20; + int i,j; + network net = parse_network_cfg(filename); + if(weightfile){ + load_weights(&net, weightfile); + } + srand(time(0)); + set_batch_network(&net, 1); + + list *plist = get_paths("data/compare.sort.list"); + //list *plist = get_paths("data/compare.small.list"); + //list *plist = get_paths("data/compare.cat.list"); + //list *plist = get_paths("data/compare.val.old"); + char **paths = (char **)list_to_array(plist); + int N = plist->size; + int total = N; + free_list(plist); + sortable_bbox *boxes = calloc(N, sizeof(sortable_bbox)); + printf("Battling %d boxes...\n", N); + for(i = 0; i < N; ++i){ + boxes[i].filename = paths[i]; + boxes[i].net = net; + boxes[i].classes = classes; + boxes[i].elos = calloc(classes, sizeof(float));; + for(j = 0; j < classes; ++j){ + boxes[i].elos[j] = 1500; + } + } + int round; + clock_t time=clock(); + for(round = 1; round <= 4; ++round){ + clock_t round_time=clock(); + printf("Round: %d\n", round); + shuffle(boxes, N, sizeof(sortable_bbox)); + for(i = 0; i < N/2; ++i){ + bbox_fight(net, boxes+i*2, boxes+i*2+1, classes, -1); + } + printf("Round: %f secs, %d remaining\n", sec(clock()-round_time), N); + } + + int class; + + for (class = 0; class < classes; ++class){ + + N = total; + current_class = class; + qsort(boxes, N, sizeof(sortable_bbox), elo_comparator); + N /= 2; + + for(round = 1; round <= 100; ++round){ + clock_t round_time=clock(); + printf("Round: %d\n", round); + + sorta_shuffle(boxes, N, sizeof(sortable_bbox), 10); + for(i = 0; i < N/2; ++i){ + bbox_fight(net, boxes+i*2, boxes+i*2+1, classes, class); + } + qsort(boxes, N, sizeof(sortable_bbox), elo_comparator); + if(round <= 20) N = (N*9/10)/2*2; + + printf("Round: %f secs, %d remaining\n", sec(clock()-round_time), N); + } + char buff[256]; + sprintf(buff, "results/battle_%d.log", class); + FILE *outfp = fopen(buff, "w"); + for(i = 0; i < N; ++i){ + fprintf(outfp, "%s %f\n", boxes[i].filename, boxes[i].elos[class]); + } + fclose(outfp); + } + printf("Tournament in %d compares, %f secs\n", total_compares, sec(clock()-time)); +} + +void run_compare(int argc, char **argv) +{ + if(argc < 4){ + fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]); + return; + } + + char *cfg = argv[3]; + char *weights = (argc > 4) ? argv[4] : 0; + //char *filename = (argc > 5) ? argv[5]: 0; + if(0==strcmp(argv[2], "train")) train_compare(cfg, weights); + else if(0==strcmp(argv[2], "valid")) validate_compare(cfg, weights); + else if(0==strcmp(argv[2], "sort")) SortMaster3000(cfg, weights); + else if(0==strcmp(argv[2], "battle")) BattleRoyaleWithCheese(cfg, weights); + /* + else if(0==strcmp(argv[2], "train")) train_coco(cfg, weights); + else if(0==strcmp(argv[2], "extract")) extract_boxes(cfg, weights); + else if(0==strcmp(argv[2], "valid")) validate_recall(cfg, weights); + */ +} diff --git a/hanzi_detection/src/connected_layer.c b/hanzi_detection/src/connected_layer.c new file mode 100755 index 0000000..353f4e5 --- /dev/null +++ b/hanzi_detection/src/connected_layer.c @@ -0,0 +1,336 @@ +#include "connected_layer.h" +#include "convolutional_layer.h" +#include "batchnorm_layer.h" +#include "utils.h" +#include "cuda.h" +#include "blas.h" +#include "gemm.h" + +#include +#include +#include +#include + +layer make_connected_layer(int batch, int inputs, int outputs, ACTIVATION activation, int batch_normalize, int adam) +{ + int i; + layer l = {0}; + l.learning_rate_scale = 1; + l.type = CONNECTED; + + l.inputs = inputs; + l.outputs = outputs; + l.batch=batch; + l.batch_normalize = batch_normalize; + l.h = 1; + l.w = 1; + l.c = inputs; + l.out_h = 1; + l.out_w = 1; + l.out_c = outputs; + + l.output = calloc(batch*outputs, sizeof(float)); + l.delta = calloc(batch*outputs, sizeof(float)); + + l.weight_updates = calloc(inputs*outputs, sizeof(float)); + l.bias_updates = calloc(outputs, sizeof(float)); + + l.weights = calloc(outputs*inputs, sizeof(float)); + l.biases = calloc(outputs, sizeof(float)); + + l.forward = forward_connected_layer; + l.backward = backward_connected_layer; + l.update = update_connected_layer; + + //float scale = 1./sqrt(inputs); + float scale = sqrt(2./inputs); + for(i = 0; i < outputs*inputs; ++i){ + l.weights[i] = scale*rand_uniform(-1, 1); + } + + for(i = 0; i < outputs; ++i){ + l.biases[i] = 0; + } + + if(adam){ + l.m = calloc(l.inputs*l.outputs, sizeof(float)); + l.v = calloc(l.inputs*l.outputs, sizeof(float)); + l.bias_m = calloc(l.outputs, sizeof(float)); + l.scale_m = calloc(l.outputs, sizeof(float)); + l.bias_v = calloc(l.outputs, sizeof(float)); + l.scale_v = calloc(l.outputs, sizeof(float)); + } + if(batch_normalize){ + l.scales = calloc(outputs, sizeof(float)); + l.scale_updates = calloc(outputs, sizeof(float)); + for(i = 0; i < outputs; ++i){ + l.scales[i] = 1; + } + + l.mean = calloc(outputs, sizeof(float)); + l.mean_delta = calloc(outputs, sizeof(float)); + l.variance = calloc(outputs, sizeof(float)); + l.variance_delta = calloc(outputs, sizeof(float)); + + l.rolling_mean = calloc(outputs, sizeof(float)); + l.rolling_variance = calloc(outputs, sizeof(float)); + + l.x = calloc(batch*outputs, sizeof(float)); + l.x_norm = calloc(batch*outputs, sizeof(float)); + } + +#ifdef GPU + l.forward_gpu = forward_connected_layer_gpu; + l.backward_gpu = backward_connected_layer_gpu; + l.update_gpu = update_connected_layer_gpu; + + l.weights_gpu = cuda_make_array(l.weights, outputs*inputs); + l.biases_gpu = cuda_make_array(l.biases, outputs); + + l.weight_updates_gpu = cuda_make_array(l.weight_updates, outputs*inputs); + l.bias_updates_gpu = cuda_make_array(l.bias_updates, outputs); + + l.output_gpu = cuda_make_array(l.output, outputs*batch); + l.delta_gpu = cuda_make_array(l.delta, outputs*batch); + if (adam) { + l.m_gpu = cuda_make_array(0, inputs*outputs); + l.v_gpu = cuda_make_array(0, inputs*outputs); + l.bias_m_gpu = cuda_make_array(0, outputs); + l.bias_v_gpu = cuda_make_array(0, outputs); + l.scale_m_gpu = cuda_make_array(0, outputs); + l.scale_v_gpu = cuda_make_array(0, outputs); + } + + if(batch_normalize){ + l.mean_gpu = cuda_make_array(l.mean, outputs); + l.variance_gpu = cuda_make_array(l.variance, outputs); + + l.rolling_mean_gpu = cuda_make_array(l.mean, outputs); + l.rolling_variance_gpu = cuda_make_array(l.variance, outputs); + + l.mean_delta_gpu = cuda_make_array(l.mean, outputs); + l.variance_delta_gpu = cuda_make_array(l.variance, outputs); + + l.scales_gpu = cuda_make_array(l.scales, outputs); + l.scale_updates_gpu = cuda_make_array(l.scale_updates, outputs); + + l.x_gpu = cuda_make_array(l.output, l.batch*outputs); + l.x_norm_gpu = cuda_make_array(l.output, l.batch*outputs); +#ifdef CUDNN + cudnnCreateTensorDescriptor(&l.normTensorDesc); + cudnnCreateTensorDescriptor(&l.dstTensorDesc); + cudnnSetTensor4dDescriptor(l.dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, l.batch, l.out_c, l.out_h, l.out_w); + cudnnSetTensor4dDescriptor(l.normTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, 1, l.out_c, 1, 1); +#endif + } +#endif + l.activation = activation; + fprintf(stderr, "connected %4d -> %4d\n", inputs, outputs); + return l; +} + +void update_connected_layer(layer l, update_args a) +{ + float learning_rate = a.learning_rate*l.learning_rate_scale; + float momentum = a.momentum; + float decay = a.decay; + int batch = a.batch; + axpy_cpu(l.outputs, learning_rate/batch, l.bias_updates, 1, l.biases, 1); + scal_cpu(l.outputs, momentum, l.bias_updates, 1); + + if(l.batch_normalize){ + axpy_cpu(l.outputs, learning_rate/batch, l.scale_updates, 1, l.scales, 1); + scal_cpu(l.outputs, momentum, l.scale_updates, 1); + } + + axpy_cpu(l.inputs*l.outputs, -decay*batch, l.weights, 1, l.weight_updates, 1); + axpy_cpu(l.inputs*l.outputs, learning_rate/batch, l.weight_updates, 1, l.weights, 1); + scal_cpu(l.inputs*l.outputs, momentum, l.weight_updates, 1); +} + +void forward_connected_layer(layer l, network net) +{ + fill_cpu(l.outputs*l.batch, 0, l.output, 1); + int m = l.batch; + int k = l.inputs; + int n = l.outputs; + float *a = net.input; + float *b = l.weights; + float *c = l.output; + gemm(0,1,m,n,k,1,a,k,b,k,1,c,n); + if(l.batch_normalize){ + forward_batchnorm_layer(l, net); + } else { + add_bias(l.output, l.biases, l.batch, l.outputs, 1); + } + activate_array(l.output, l.outputs*l.batch, l.activation); +} + +void backward_connected_layer(layer l, network net) +{ + gradient_array(l.output, l.outputs*l.batch, l.activation, l.delta); + + if(l.batch_normalize){ + backward_batchnorm_layer(l, net); + } else { + backward_bias(l.bias_updates, l.delta, l.batch, l.outputs, 1); + } + + int m = l.outputs; + int k = l.batch; + int n = l.inputs; + float *a = l.delta; + float *b = net.input; + float *c = l.weight_updates; + gemm(1,0,m,n,k,1,a,m,b,n,1,c,n); + + m = l.batch; + k = l.outputs; + n = l.inputs; + + a = l.delta; + b = l.weights; + c = net.delta; + + if(c) gemm(0,0,m,n,k,1,a,k,b,n,1,c,n); +} + + +void denormalize_connected_layer(layer l) +{ + int i, j; + for(i = 0; i < l.outputs; ++i){ + float scale = l.scales[i]/sqrt(l.rolling_variance[i] + .000001); + for(j = 0; j < l.inputs; ++j){ + l.weights[i*l.inputs + j] *= scale; + } + l.biases[i] -= l.rolling_mean[i] * scale; + l.scales[i] = 1; + l.rolling_mean[i] = 0; + l.rolling_variance[i] = 1; + } +} + + +void statistics_connected_layer(layer l) +{ + if(l.batch_normalize){ + printf("Scales "); + print_statistics(l.scales, l.outputs); + /* + printf("Rolling Mean "); + print_statistics(l.rolling_mean, l.outputs); + printf("Rolling Variance "); + print_statistics(l.rolling_variance, l.outputs); + */ + } + printf("Biases "); + print_statistics(l.biases, l.outputs); + printf("Weights "); + print_statistics(l.weights, l.outputs); +} + +#ifdef GPU + +void pull_connected_layer(layer l) +{ + cuda_pull_array(l.weights_gpu, l.weights, l.inputs*l.outputs); + cuda_pull_array(l.biases_gpu, l.biases, l.outputs); + cuda_pull_array(l.weight_updates_gpu, l.weight_updates, l.inputs*l.outputs); + cuda_pull_array(l.bias_updates_gpu, l.bias_updates, l.outputs); + if (l.batch_normalize){ + cuda_pull_array(l.scales_gpu, l.scales, l.outputs); + cuda_pull_array(l.rolling_mean_gpu, l.rolling_mean, l.outputs); + cuda_pull_array(l.rolling_variance_gpu, l.rolling_variance, l.outputs); + } +} + +void push_connected_layer(layer l) +{ + cuda_push_array(l.weights_gpu, l.weights, l.inputs*l.outputs); + cuda_push_array(l.biases_gpu, l.biases, l.outputs); + cuda_push_array(l.weight_updates_gpu, l.weight_updates, l.inputs*l.outputs); + cuda_push_array(l.bias_updates_gpu, l.bias_updates, l.outputs); + if (l.batch_normalize){ + cuda_push_array(l.scales_gpu, l.scales, l.outputs); + cuda_push_array(l.rolling_mean_gpu, l.rolling_mean, l.outputs); + cuda_push_array(l.rolling_variance_gpu, l.rolling_variance, l.outputs); + } +} + +void update_connected_layer_gpu(layer l, update_args a) +{ + float learning_rate = a.learning_rate*l.learning_rate_scale; + float momentum = a.momentum; + float decay = a.decay; + int batch = a.batch; + if(a.adam){ + adam_update_gpu(l.weights_gpu, l.weight_updates_gpu, l.m_gpu, l.v_gpu, a.B1, a.B2, a.eps, decay, learning_rate, l.inputs*l.outputs, batch, a.t); + adam_update_gpu(l.biases_gpu, l.bias_updates_gpu, l.bias_m_gpu, l.bias_v_gpu, a.B1, a.B2, a.eps, decay, learning_rate, l.outputs, batch, a.t); + if(l.scales_gpu){ + adam_update_gpu(l.scales_gpu, l.scale_updates_gpu, l.scale_m_gpu, l.scale_v_gpu, a.B1, a.B2, a.eps, decay, learning_rate, l.outputs, batch, a.t); + } + }else{ + axpy_gpu(l.outputs, learning_rate/batch, l.bias_updates_gpu, 1, l.biases_gpu, 1); + scal_gpu(l.outputs, momentum, l.bias_updates_gpu, 1); + + if(l.batch_normalize){ + axpy_gpu(l.outputs, learning_rate/batch, l.scale_updates_gpu, 1, l.scales_gpu, 1); + scal_gpu(l.outputs, momentum, l.scale_updates_gpu, 1); + } + + axpy_gpu(l.inputs*l.outputs, -decay*batch, l.weights_gpu, 1, l.weight_updates_gpu, 1); + axpy_gpu(l.inputs*l.outputs, learning_rate/batch, l.weight_updates_gpu, 1, l.weights_gpu, 1); + scal_gpu(l.inputs*l.outputs, momentum, l.weight_updates_gpu, 1); + } +} + +void forward_connected_layer_gpu(layer l, network net) +{ + fill_gpu(l.outputs*l.batch, 0, l.output_gpu, 1); + + int m = l.batch; + int k = l.inputs; + int n = l.outputs; + float * a = net.input_gpu; + float * b = l.weights_gpu; + float * c = l.output_gpu; + gemm_gpu(0,1,m,n,k,1,a,k,b,k,1,c,n); + + if (l.batch_normalize) { + forward_batchnorm_layer_gpu(l, net); + } else { + add_bias_gpu(l.output_gpu, l.biases_gpu, l.batch, l.outputs, 1); + } + activate_array_gpu(l.output_gpu, l.outputs*l.batch, l.activation); +} + +void backward_connected_layer_gpu(layer l, network net) +{ + constrain_gpu(l.outputs*l.batch, 1, l.delta_gpu, 1); + gradient_array_gpu(l.output_gpu, l.outputs*l.batch, l.activation, l.delta_gpu); + if(l.batch_normalize){ + backward_batchnorm_layer_gpu(l, net); + } else { + backward_bias_gpu(l.bias_updates_gpu, l.delta_gpu, l.batch, l.outputs, 1); + } + + int m = l.outputs; + int k = l.batch; + int n = l.inputs; + float * a = l.delta_gpu; + float * b = net.input_gpu; + float * c = l.weight_updates_gpu; + gemm_gpu(1,0,m,n,k,1,a,m,b,n,1,c,n); + + m = l.batch; + k = l.outputs; + n = l.inputs; + + a = l.delta_gpu; + b = l.weights_gpu; + c = net.delta_gpu; + + if(c) gemm_gpu(0,0,m,n,k,1,a,k,b,n,1,c,n); +} +#endif diff --git a/hanzi_detection/src/connected_layer.h b/hanzi_detection/src/connected_layer.h new file mode 100755 index 0000000..6727a96 --- /dev/null +++ b/hanzi_detection/src/connected_layer.h @@ -0,0 +1,23 @@ +#ifndef CONNECTED_LAYER_H +#define CONNECTED_LAYER_H + +#include "activations.h" +#include "layer.h" +#include "network.h" + +layer make_connected_layer(int batch, int inputs, int outputs, ACTIVATION activation, int batch_normalize, int adam); + +void forward_connected_layer(layer l, network net); +void backward_connected_layer(layer l, network net); +void update_connected_layer(layer l, update_args a); + +#ifdef GPU +void forward_connected_layer_gpu(layer l, network net); +void backward_connected_layer_gpu(layer l, network net); +void update_connected_layer_gpu(layer l, update_args a); +void push_connected_layer(layer l); +void pull_connected_layer(layer l); +#endif + +#endif + diff --git a/hanzi_detection/src/convolutional_kernels.cu b/hanzi_detection/src/convolutional_kernels.cu new file mode 100755 index 0000000..4a1047b --- /dev/null +++ b/hanzi_detection/src/convolutional_kernels.cu @@ -0,0 +1,330 @@ +#include "cuda_runtime.h" +#include "curand.h" +#include "cublas_v2.h" + +extern "C" { +#include "convolutional_layer.h" +#include "batchnorm_layer.h" +#include "gemm.h" +#include "blas.h" +#include "im2col.h" +#include "col2im.h" +#include "utils.h" +#include "cuda.h" +} + +__global__ void binarize_kernel(float *x, int n, float *binary) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if (i >= n) return; + binary[i] = (x[i] >= 0) ? 1 : -1; +} + +void binarize_gpu(float *x, int n, float *binary) +{ + binarize_kernel<<>>(x, n, binary); + check_error(cudaPeekAtLastError()); +} + +__global__ void binarize_input_kernel(float *input, int n, int size, float *binary) +{ + int s = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if (s >= size) return; + int i = 0; + float mean = 0; + for(i = 0; i < n; ++i){ + mean += fabsf(input[i*size + s]); + } + mean = mean / n; + for(i = 0; i < n; ++i){ + binary[i*size + s] = (input[i*size + s] > 0) ? mean : -mean; + } +} + +void binarize_input_gpu(float *input, int n, int size, float *binary) +{ + binarize_input_kernel<<>>(input, n, size, binary); + check_error(cudaPeekAtLastError()); +} + + +__global__ void binarize_weights_kernel(float *weights, int n, int size, float *binary) +{ + int f = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if (f >= n) return; + int i = 0; + float mean = 0; + for(i = 0; i < size; ++i){ + mean += fabsf(weights[f*size + i]); + } + mean = mean / size; + for(i = 0; i < size; ++i){ + binary[f*size + i] = (weights[f*size + i] > 0) ? mean : -mean; + //binary[f*size + i] = weights[f*size + i]; + } +} + +void binarize_weights_gpu(float *weights, int n, int size, float *binary) +{ + binarize_weights_kernel<<>>(weights, n, size, binary); + check_error(cudaPeekAtLastError()); +} + +void forward_convolutional_layer_gpu(convolutional_layer l, network net) +{ + fill_gpu(l.outputs*l.batch, 0, l.output_gpu, 1); + if(l.binary){ + binarize_weights_gpu(l.weights_gpu, l.n, l.c/l.groups*l.size*l.size, l.binary_weights_gpu); + swap_binary(&l); + } + + if(l.xnor){ + binarize_weights_gpu(l.weights_gpu, l.n, l.c/l.groups*l.size*l.size, l.binary_weights_gpu); + swap_binary(&l); + binarize_gpu(net.input_gpu, l.c*l.h*l.w*l.batch, l.binary_input_gpu); + net.input_gpu = l.binary_input_gpu; + } + +#ifdef CUDNN + float one = 1; + cudnnConvolutionForward(cudnn_handle(), + &one, + l.srcTensorDesc, + net.input_gpu, + l.weightDesc, + l.weights_gpu, + l.convDesc, + l.fw_algo, + net.workspace, + l.workspace_size, + &one, + l.dstTensorDesc, + l.output_gpu); + +#else + int i, j; + int m = l.n/l.groups; + int k = l.size*l.size*l.c/l.groups; + int n = l.out_w*l.out_h; + for(i = 0; i < l.batch; ++i){ + for(j = 0; j < l.groups; ++j){ + float *a = l.weights_gpu + j*l.nweights/l.groups; + float *b = net.workspace; + float *c = l.output_gpu + (i*l.groups + j)*n*m; + float *im = net.input_gpu + (i*l.groups + j)*l.c/l.groups*l.h*l.w; + + if (l.size == 1){ + b = im; + } else { + im2col_gpu(im, l.c/l.groups, l.h, l.w, l.size, l.stride, l.pad, b); + } + gemm_gpu(0,0,m,n,k,1,a,k,b,n,1,c,n); + } + } +#endif + + if (l.batch_normalize) { + forward_batchnorm_layer_gpu(l, net); + } else { + add_bias_gpu(l.output_gpu, l.biases_gpu, l.batch, l.n, l.out_w*l.out_h); + } + + activate_array_gpu(l.output_gpu, l.outputs*l.batch, l.activation); + //if(l.dot > 0) dot_error_gpu(l); + if(l.binary || l.xnor) swap_binary(&l); +} + +__global__ void smooth_kernel(float *x, int n, int w, int h, int c, int size, float rate, float *delta) +{ + int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(id >= n) return; + + int j = id % w; + id /= w; + int i = id % h; + id /= h; + int k = id % c; + id /= c; + int b = id; + + int w_offset = -(size/2.f); + int h_offset = -(size/2.f); + + int out_index = j + w*(i + h*(k + c*b)); + int l, m; + for(l = 0; l < size; ++l){ + for(m = 0; m < size; ++m){ + int cur_h = h_offset + i + l; + int cur_w = w_offset + j + m; + int index = cur_w + w*(cur_h + h*(k + b*c)); + int valid = (cur_h >= 0 && cur_h < h && + cur_w >= 0 && cur_w < w); + delta[out_index] += valid ? rate*(x[index] - x[out_index]) : 0; + } + } +} + +extern "C" void smooth_layer(layer l, int size, float rate) +{ + int h = l.out_h; + int w = l.out_w; + int c = l.out_c; + + size_t n = h*w*c*l.batch; + + smooth_kernel<<>>(l.output_gpu, n, l.w, l.h, l.c, size, rate, l.delta_gpu); + check_error(cudaPeekAtLastError()); +} + +void backward_convolutional_layer_gpu(convolutional_layer l, network net) +{ + if(l.smooth){ + smooth_layer(l, 5, l.smooth); + } + //constrain_gpu(l.outputs*l.batch, 1, l.delta_gpu, 1); + gradient_array_gpu(l.output_gpu, l.outputs*l.batch, l.activation, l.delta_gpu); + + + if(l.batch_normalize){ + backward_batchnorm_layer_gpu(l, net); + } else { + backward_bias_gpu(l.bias_updates_gpu, l.delta_gpu, l.batch, l.n, l.out_w*l.out_h); + } + float *original_input = net.input_gpu; + + if(l.xnor) net.input_gpu = l.binary_input_gpu; +#ifdef CUDNN + float one = 1; + cudnnConvolutionBackwardFilter(cudnn_handle(), + &one, + l.srcTensorDesc, + net.input_gpu, + l.ddstTensorDesc, + l.delta_gpu, + l.convDesc, + l.bf_algo, + net.workspace, + l.workspace_size, + &one, + l.dweightDesc, + l.weight_updates_gpu); + + if(net.delta_gpu){ + if(l.binary || l.xnor) swap_binary(&l); + cudnnConvolutionBackwardData(cudnn_handle(), + &one, + l.weightDesc, + l.weights_gpu, + l.ddstTensorDesc, + l.delta_gpu, + l.convDesc, + l.bd_algo, + net.workspace, + l.workspace_size, + &one, + l.dsrcTensorDesc, + net.delta_gpu); + if(l.binary || l.xnor) swap_binary(&l); + if(l.xnor) gradient_array_gpu(original_input, l.batch*l.c*l.h*l.w, HARDTAN, net.delta_gpu); + } + +#else + int m = l.n/l.groups; + int n = l.size*l.size*l.c/l.groups; + int k = l.out_w*l.out_h; + + int i, j; + for(i = 0; i < l.batch; ++i){ + for(j = 0; j < l.groups; ++j){ + float *a = l.delta_gpu + (i*l.groups + j)*m*k; + float *b = net.workspace; + float *c = l.weight_updates_gpu + j*l.nweights/l.groups; + + float *im = net.input_gpu+(i*l.groups + j)*l.c/l.groups*l.h*l.w; + float *imd = net.delta_gpu+(i*l.groups + j)*l.c/l.groups*l.h*l.w; + + im2col_gpu(im, l.c/l.groups, l.h, l.w, l.size, l.stride, l.pad, b); + gemm_gpu(0,1,m,n,k,1,a,k,b,k,1,c,n); + + if (net.delta_gpu) { + if (l.binary || l.xnor) swap_binary(&l); + a = l.weights_gpu + j*l.nweights/l.groups; + b = l.delta_gpu + (i*l.groups + j)*m*k; + c = net.workspace; + if (l.size == 1) { + c = imd; + } + + gemm_gpu(1,0,n,k,m,1,a,n,b,k,0,c,k); + + if (l.size != 1) { + col2im_gpu(net.workspace, l.c/l.groups, l.h, l.w, l.size, l.stride, l.pad, imd); + } + if(l.binary || l.xnor) { + swap_binary(&l); + } + } + if(l.xnor) gradient_array_gpu(original_input + i*l.c*l.h*l.w, l.c*l.h*l.w, HARDTAN, net.delta_gpu + i*l.c*l.h*l.w); + } + } +#endif +} + +void pull_convolutional_layer(layer l) +{ + cuda_pull_array(l.weights_gpu, l.weights, l.nweights); + cuda_pull_array(l.biases_gpu, l.biases, l.n); + cuda_pull_array(l.weight_updates_gpu, l.weight_updates, l.nweights); + cuda_pull_array(l.bias_updates_gpu, l.bias_updates, l.n); + if (l.batch_normalize){ + cuda_pull_array(l.scales_gpu, l.scales, l.n); + cuda_pull_array(l.rolling_mean_gpu, l.rolling_mean, l.n); + cuda_pull_array(l.rolling_variance_gpu, l.rolling_variance, l.n); + } +} + +void push_convolutional_layer(layer l) +{ + cuda_push_array(l.weights_gpu, l.weights, l.nweights); + cuda_push_array(l.biases_gpu, l.biases, l.n); + cuda_push_array(l.weight_updates_gpu, l.weight_updates, l.nweights); + cuda_push_array(l.bias_updates_gpu, l.bias_updates, l.n); + if (l.batch_normalize){ + cuda_push_array(l.scales_gpu, l.scales, l.n); + cuda_push_array(l.rolling_mean_gpu, l.rolling_mean, l.n); + cuda_push_array(l.rolling_variance_gpu, l.rolling_variance, l.n); + } +} + +void update_convolutional_layer_gpu(layer l, update_args a) +{ + float learning_rate = a.learning_rate*l.learning_rate_scale; + float momentum = a.momentum; + float decay = a.decay; + int batch = a.batch; + + if(a.adam){ + adam_update_gpu(l.weights_gpu, l.weight_updates_gpu, l.m_gpu, l.v_gpu, a.B1, a.B2, a.eps, decay, learning_rate, l.nweights, batch, a.t); + adam_update_gpu(l.biases_gpu, l.bias_updates_gpu, l.bias_m_gpu, l.bias_v_gpu, a.B1, a.B2, a.eps, decay, learning_rate, l.n, batch, a.t); + if(l.scales_gpu){ + adam_update_gpu(l.scales_gpu, l.scale_updates_gpu, l.scale_m_gpu, l.scale_v_gpu, a.B1, a.B2, a.eps, decay, learning_rate, l.n, batch, a.t); + } + }else{ + axpy_gpu(l.nweights, -decay*batch, l.weights_gpu, 1, l.weight_updates_gpu, 1); + axpy_gpu(l.nweights, learning_rate/batch, l.weight_updates_gpu, 1, l.weights_gpu, 1); + scal_gpu(l.nweights, momentum, l.weight_updates_gpu, 1); + + axpy_gpu(l.n, learning_rate/batch, l.bias_updates_gpu, 1, l.biases_gpu, 1); + scal_gpu(l.n, momentum, l.bias_updates_gpu, 1); + + if(l.scales_gpu){ + axpy_gpu(l.n, learning_rate/batch, l.scale_updates_gpu, 1, l.scales_gpu, 1); + scal_gpu(l.n, momentum, l.scale_updates_gpu, 1); + } + } + if(l.clip){ + constrain_gpu(l.nweights, l.clip, l.weights_gpu, 1); + } +} + + diff --git a/hanzi_detection/src/convolutional_layer.c b/hanzi_detection/src/convolutional_layer.c new file mode 100755 index 0000000..1fb58b0 --- /dev/null +++ b/hanzi_detection/src/convolutional_layer.c @@ -0,0 +1,622 @@ +#include "convolutional_layer.h" +#include "utils.h" +#include "batchnorm_layer.h" +#include "im2col.h" +#include "col2im.h" +#include "blas.h" +#include "gemm.h" +#include +#include + +#ifdef AI2 +#include "xnor_layer.h" +#endif + +void swap_binary(convolutional_layer *l) +{ + float *swap = l->weights; + l->weights = l->binary_weights; + l->binary_weights = swap; + +#ifdef GPU + swap = l->weights_gpu; + l->weights_gpu = l->binary_weights_gpu; + l->binary_weights_gpu = swap; +#endif +} + +void binarize_weights(float *weights, int n, int size, float *binary) +{ + int i, f; + for(f = 0; f < n; ++f){ + float mean = 0; + for(i = 0; i < size; ++i){ + mean += fabs(weights[f*size + i]); + } + mean = mean / size; + for(i = 0; i < size; ++i){ + binary[f*size + i] = (weights[f*size + i] > 0) ? mean : -mean; + } + } +} + +void binarize_cpu(float *input, int n, float *binary) +{ + int i; + for(i = 0; i < n; ++i){ + binary[i] = (input[i] > 0) ? 1 : -1; + } +} + +void binarize_input(float *input, int n, int size, float *binary) +{ + int i, s; + for(s = 0; s < size; ++s){ + float mean = 0; + for(i = 0; i < n; ++i){ + mean += fabs(input[i*size + s]); + } + mean = mean / n; + for(i = 0; i < n; ++i){ + binary[i*size + s] = (input[i*size + s] > 0) ? mean : -mean; + } + } +} + +int convolutional_out_height(convolutional_layer l) +{ + return (l.h + 2*l.pad - l.size) / l.stride + 1; +} + +int convolutional_out_width(convolutional_layer l) +{ + return (l.w + 2*l.pad - l.size) / l.stride + 1; +} + +image get_convolutional_image(convolutional_layer l) +{ + return float_to_image(l.out_w,l.out_h,l.out_c,l.output); +} + +image get_convolutional_delta(convolutional_layer l) +{ + return float_to_image(l.out_w,l.out_h,l.out_c,l.delta); +} + +static size_t get_workspace_size(layer l){ +#ifdef CUDNN + if(gpu_index >= 0){ + size_t most = 0; + size_t s = 0; + cudnnGetConvolutionForwardWorkspaceSize(cudnn_handle(), + l.srcTensorDesc, + l.weightDesc, + l.convDesc, + l.dstTensorDesc, + l.fw_algo, + &s); + if (s > most) most = s; + cudnnGetConvolutionBackwardFilterWorkspaceSize(cudnn_handle(), + l.srcTensorDesc, + l.ddstTensorDesc, + l.convDesc, + l.dweightDesc, + l.bf_algo, + &s); + if (s > most) most = s; + cudnnGetConvolutionBackwardDataWorkspaceSize(cudnn_handle(), + l.weightDesc, + l.ddstTensorDesc, + l.convDesc, + l.dsrcTensorDesc, + l.bd_algo, + &s); + if (s > most) most = s; + return most; + } +#endif + return (size_t)l.out_h*l.out_w*l.size*l.size*l.c/l.groups*sizeof(float); +} + +#ifdef GPU +#ifdef CUDNN +void cudnn_convolutional_setup(layer *l) +{ + cudnnSetTensor4dDescriptor(l->dsrcTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, l->batch, l->c, l->h, l->w); + cudnnSetTensor4dDescriptor(l->ddstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, l->batch, l->out_c, l->out_h, l->out_w); + + cudnnSetTensor4dDescriptor(l->srcTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, l->batch, l->c, l->h, l->w); + cudnnSetTensor4dDescriptor(l->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, l->batch, l->out_c, l->out_h, l->out_w); + cudnnSetTensor4dDescriptor(l->normTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, 1, l->out_c, 1, 1); + + cudnnSetFilter4dDescriptor(l->dweightDesc, CUDNN_DATA_FLOAT, CUDNN_TENSOR_NCHW, l->n, l->c/l->groups, l->size, l->size); + cudnnSetFilter4dDescriptor(l->weightDesc, CUDNN_DATA_FLOAT, CUDNN_TENSOR_NCHW, l->n, l->c/l->groups, l->size, l->size); + #if CUDNN_MAJOR >= 6 + cudnnSetConvolution2dDescriptor(l->convDesc, l->pad, l->pad, l->stride, l->stride, 1, 1, CUDNN_CROSS_CORRELATION, CUDNN_DATA_FLOAT); + #else + cudnnSetConvolution2dDescriptor(l->convDesc, l->pad, l->pad, l->stride, l->stride, 1, 1, CUDNN_CROSS_CORRELATION); + #endif + + #if CUDNN_MAJOR >= 7 + cudnnSetConvolutionGroupCount(l->convDesc, l->groups); + #else + if(l->groups > 1){ + error("CUDNN < 7 doesn't support groups, please upgrade!"); + } + #endif + + cudnnGetConvolutionForwardAlgorithm(cudnn_handle(), + l->srcTensorDesc, + l->weightDesc, + l->convDesc, + l->dstTensorDesc, + CUDNN_CONVOLUTION_FWD_SPECIFY_WORKSPACE_LIMIT, + 2000000000, + &l->fw_algo); + cudnnGetConvolutionBackwardDataAlgorithm(cudnn_handle(), + l->weightDesc, + l->ddstTensorDesc, + l->convDesc, + l->dsrcTensorDesc, + CUDNN_CONVOLUTION_BWD_DATA_SPECIFY_WORKSPACE_LIMIT, + 2000000000, + &l->bd_algo); + cudnnGetConvolutionBackwardFilterAlgorithm(cudnn_handle(), + l->srcTensorDesc, + l->ddstTensorDesc, + l->convDesc, + l->dweightDesc, + CUDNN_CONVOLUTION_BWD_FILTER_SPECIFY_WORKSPACE_LIMIT, + 2000000000, + &l->bf_algo); +} +#endif +#endif + +convolutional_layer make_convolutional_layer(int batch, int h, int w, int c, int n, int groups, int size, int stride, int padding, ACTIVATION activation, int batch_normalize, int binary, int xnor, int adam) +{ + int i; + convolutional_layer l = {0}; + l.type = CONVOLUTIONAL; + + l.groups = groups; + l.h = h; + l.w = w; + l.c = c; + l.n = n; + l.binary = binary; + l.xnor = xnor; + l.batch = batch; + l.stride = stride; + l.size = size; + l.pad = padding; + l.batch_normalize = batch_normalize; + + l.weights = calloc(c/groups*n*size*size, sizeof(float)); + l.weight_updates = calloc(c/groups*n*size*size, sizeof(float)); + + l.biases = calloc(n, sizeof(float)); + l.bias_updates = calloc(n, sizeof(float)); + + l.nweights = c/groups*n*size*size; + l.nbiases = n; + + // float scale = 1./sqrt(size*size*c); + float scale = sqrt(2./(size*size*c/l.groups)); + //printf("convscale %f\n", scale); + //scale = .02; + //for(i = 0; i < c*n*size*size; ++i) l.weights[i] = scale*rand_uniform(-1, 1); + for(i = 0; i < l.nweights; ++i) l.weights[i] = scale*rand_normal(); + int out_w = convolutional_out_width(l); + int out_h = convolutional_out_height(l); + l.out_h = out_h; + l.out_w = out_w; + l.out_c = n; + l.outputs = l.out_h * l.out_w * l.out_c; + l.inputs = l.w * l.h * l.c; + + l.output = calloc(l.batch*l.outputs, sizeof(float)); + l.delta = calloc(l.batch*l.outputs, sizeof(float)); + + l.forward = forward_convolutional_layer; + l.backward = backward_convolutional_layer; + l.update = update_convolutional_layer; + if(binary){ + l.binary_weights = calloc(l.nweights, sizeof(float)); + l.cweights = calloc(l.nweights, sizeof(char)); + l.scales = calloc(n, sizeof(float)); + } + if(xnor){ + l.binary_weights = calloc(l.nweights, sizeof(float)); + l.binary_input = calloc(l.inputs*l.batch, sizeof(float)); + } + + if(batch_normalize){ + l.scales = calloc(n, sizeof(float)); + l.scale_updates = calloc(n, sizeof(float)); + for(i = 0; i < n; ++i){ + l.scales[i] = 1; + } + + l.mean = calloc(n, sizeof(float)); + l.variance = calloc(n, sizeof(float)); + + l.mean_delta = calloc(n, sizeof(float)); + l.variance_delta = calloc(n, sizeof(float)); + + l.rolling_mean = calloc(n, sizeof(float)); + l.rolling_variance = calloc(n, sizeof(float)); + l.x = calloc(l.batch*l.outputs, sizeof(float)); + l.x_norm = calloc(l.batch*l.outputs, sizeof(float)); + } + if(adam){ + l.m = calloc(l.nweights, sizeof(float)); + l.v = calloc(l.nweights, sizeof(float)); + l.bias_m = calloc(n, sizeof(float)); + l.scale_m = calloc(n, sizeof(float)); + l.bias_v = calloc(n, sizeof(float)); + l.scale_v = calloc(n, sizeof(float)); + } + +#ifdef GPU + l.forward_gpu = forward_convolutional_layer_gpu; + l.backward_gpu = backward_convolutional_layer_gpu; + l.update_gpu = update_convolutional_layer_gpu; + + if(gpu_index >= 0){ + if (adam) { + l.m_gpu = cuda_make_array(l.m, l.nweights); + l.v_gpu = cuda_make_array(l.v, l.nweights); + l.bias_m_gpu = cuda_make_array(l.bias_m, n); + l.bias_v_gpu = cuda_make_array(l.bias_v, n); + l.scale_m_gpu = cuda_make_array(l.scale_m, n); + l.scale_v_gpu = cuda_make_array(l.scale_v, n); + } + + l.weights_gpu = cuda_make_array(l.weights, l.nweights); + l.weight_updates_gpu = cuda_make_array(l.weight_updates, l.nweights); + + l.biases_gpu = cuda_make_array(l.biases, n); + l.bias_updates_gpu = cuda_make_array(l.bias_updates, n); + + l.delta_gpu = cuda_make_array(l.delta, l.batch*out_h*out_w*n); + l.output_gpu = cuda_make_array(l.output, l.batch*out_h*out_w*n); + + if(binary){ + l.binary_weights_gpu = cuda_make_array(l.weights, l.nweights); + } + if(xnor){ + l.binary_weights_gpu = cuda_make_array(l.weights, l.nweights); + l.binary_input_gpu = cuda_make_array(0, l.inputs*l.batch); + } + + if(batch_normalize){ + l.mean_gpu = cuda_make_array(l.mean, n); + l.variance_gpu = cuda_make_array(l.variance, n); + + l.rolling_mean_gpu = cuda_make_array(l.mean, n); + l.rolling_variance_gpu = cuda_make_array(l.variance, n); + + l.mean_delta_gpu = cuda_make_array(l.mean, n); + l.variance_delta_gpu = cuda_make_array(l.variance, n); + + l.scales_gpu = cuda_make_array(l.scales, n); + l.scale_updates_gpu = cuda_make_array(l.scale_updates, n); + + l.x_gpu = cuda_make_array(l.output, l.batch*out_h*out_w*n); + l.x_norm_gpu = cuda_make_array(l.output, l.batch*out_h*out_w*n); + } +#ifdef CUDNN + cudnnCreateTensorDescriptor(&l.normTensorDesc); + cudnnCreateTensorDescriptor(&l.srcTensorDesc); + cudnnCreateTensorDescriptor(&l.dstTensorDesc); + cudnnCreateFilterDescriptor(&l.weightDesc); + cudnnCreateTensorDescriptor(&l.dsrcTensorDesc); + cudnnCreateTensorDescriptor(&l.ddstTensorDesc); + cudnnCreateFilterDescriptor(&l.dweightDesc); + cudnnCreateConvolutionDescriptor(&l.convDesc); + cudnn_convolutional_setup(&l); +#endif + } +#endif + l.workspace_size = get_workspace_size(l); + l.activation = activation; + + fprintf(stderr, "conv %5d %2d x%2d /%2d %4d x%4d x%4d -> %4d x%4d x%4d %5.3f BFLOPs\n", n, size, size, stride, w, h, c, l.out_w, l.out_h, l.out_c, (2.0 * l.n * l.size*l.size*l.c/l.groups * l.out_h*l.out_w)/1000000000.); + + return l; +} + +void denormalize_convolutional_layer(convolutional_layer l) +{ + int i, j; + for(i = 0; i < l.n; ++i){ + float scale = l.scales[i]/sqrt(l.rolling_variance[i] + .00001); + for(j = 0; j < l.c/l.groups*l.size*l.size; ++j){ + l.weights[i*l.c/l.groups*l.size*l.size + j] *= scale; + } + l.biases[i] -= l.rolling_mean[i] * scale; + l.scales[i] = 1; + l.rolling_mean[i] = 0; + l.rolling_variance[i] = 1; + } +} + +/* +void test_convolutional_layer() +{ + convolutional_layer l = make_convolutional_layer(1, 5, 5, 3, 2, 5, 2, 1, LEAKY, 1, 0, 0, 0); + l.batch_normalize = 1; + float data[] = {1,1,1,1,1, + 1,1,1,1,1, + 1,1,1,1,1, + 1,1,1,1,1, + 1,1,1,1,1, + 2,2,2,2,2, + 2,2,2,2,2, + 2,2,2,2,2, + 2,2,2,2,2, + 2,2,2,2,2, + 3,3,3,3,3, + 3,3,3,3,3, + 3,3,3,3,3, + 3,3,3,3,3, + 3,3,3,3,3}; + //net.input = data; + //forward_convolutional_layer(l); +} +*/ + +void resize_convolutional_layer(convolutional_layer *l, int w, int h) +{ + l->w = w; + l->h = h; + int out_w = convolutional_out_width(*l); + int out_h = convolutional_out_height(*l); + + l->out_w = out_w; + l->out_h = out_h; + + l->outputs = l->out_h * l->out_w * l->out_c; + l->inputs = l->w * l->h * l->c; + + l->output = realloc(l->output, l->batch*l->outputs*sizeof(float)); + l->delta = realloc(l->delta, l->batch*l->outputs*sizeof(float)); + if(l->batch_normalize){ + l->x = realloc(l->x, l->batch*l->outputs*sizeof(float)); + l->x_norm = realloc(l->x_norm, l->batch*l->outputs*sizeof(float)); + } + +#ifdef GPU + cuda_free(l->delta_gpu); + cuda_free(l->output_gpu); + + l->delta_gpu = cuda_make_array(l->delta, l->batch*l->outputs); + l->output_gpu = cuda_make_array(l->output, l->batch*l->outputs); + + if(l->batch_normalize){ + cuda_free(l->x_gpu); + cuda_free(l->x_norm_gpu); + + l->x_gpu = cuda_make_array(l->output, l->batch*l->outputs); + l->x_norm_gpu = cuda_make_array(l->output, l->batch*l->outputs); + } +#ifdef CUDNN + cudnn_convolutional_setup(l); +#endif +#endif + l->workspace_size = get_workspace_size(*l); +} + +void add_bias(float *output, float *biases, int batch, int n, int size) +{ + int i,j,b; + for(b = 0; b < batch; ++b){ + for(i = 0; i < n; ++i){ + for(j = 0; j < size; ++j){ + output[(b*n + i)*size + j] += biases[i]; + } + } + } +} + +void scale_bias(float *output, float *scales, int batch, int n, int size) +{ + int i,j,b; + for(b = 0; b < batch; ++b){ + for(i = 0; i < n; ++i){ + for(j = 0; j < size; ++j){ + output[(b*n + i)*size + j] *= scales[i]; + } + } + } +} + +void backward_bias(float *bias_updates, float *delta, int batch, int n, int size) +{ + int i,b; + for(b = 0; b < batch; ++b){ + for(i = 0; i < n; ++i){ + bias_updates[i] += sum_array(delta+size*(i+b*n), size); + } + } +} + +void forward_convolutional_layer(convolutional_layer l, network net) +{ + int i, j; + + fill_cpu(l.outputs*l.batch, 0, l.output, 1); + + if(l.xnor){ + binarize_weights(l.weights, l.n, l.c/l.groups*l.size*l.size, l.binary_weights); + swap_binary(&l); + binarize_cpu(net.input, l.c*l.h*l.w*l.batch, l.binary_input); + net.input = l.binary_input; + } + + int m = l.n/l.groups; + int k = l.size*l.size*l.c/l.groups; + int n = l.out_w*l.out_h; + for(i = 0; i < l.batch; ++i){ + for(j = 0; j < l.groups; ++j){ + float *a = l.weights + j*l.nweights/l.groups; + float *b = net.workspace; + float *c = l.output + (i*l.groups + j)*n*m; + float *im = net.input + (i*l.groups + j)*l.c/l.groups*l.h*l.w; + + if (l.size == 1) { + b = im; + } else { + im2col_cpu(im, l.c/l.groups, l.h, l.w, l.size, l.stride, l.pad, b); + } + gemm(0,0,m,n,k,1,a,k,b,n,1,c,n); + } + } + + if(l.batch_normalize){ + forward_batchnorm_layer(l, net); + } else { + add_bias(l.output, l.biases, l.batch, l.n, l.out_h*l.out_w); + } + + activate_array(l.output, l.outputs*l.batch, l.activation); + if(l.binary || l.xnor) swap_binary(&l); +} + +void backward_convolutional_layer(convolutional_layer l, network net) +{ + int i, j; + int m = l.n/l.groups; + int n = l.size*l.size*l.c/l.groups; + int k = l.out_w*l.out_h; + + gradient_array(l.output, l.outputs*l.batch, l.activation, l.delta); + + if(l.batch_normalize){ + backward_batchnorm_layer(l, net); + } else { + backward_bias(l.bias_updates, l.delta, l.batch, l.n, k); + } + + for(i = 0; i < l.batch; ++i){ + for(j = 0; j < l.groups; ++j){ + float *a = l.delta + (i*l.groups + j)*m*k; + float *b = net.workspace; + float *c = l.weight_updates + j*l.nweights/l.groups; + + float *im = net.input + (i*l.groups + j)*l.c/l.groups*l.h*l.w; + float *imd = net.delta + (i*l.groups + j)*l.c/l.groups*l.h*l.w; + + if(l.size == 1){ + b = im; + } else { + im2col_cpu(im, l.c/l.groups, l.h, l.w, + l.size, l.stride, l.pad, b); + } + + gemm(0,1,m,n,k,1,a,k,b,k,1,c,n); + + if (net.delta) { + a = l.weights + j*l.nweights/l.groups; + b = l.delta + (i*l.groups + j)*m*k; + c = net.workspace; + if (l.size == 1) { + c = imd; + } + + gemm(1,0,n,k,m,1,a,n,b,k,0,c,k); + + if (l.size != 1) { + col2im_cpu(net.workspace, l.c/l.groups, l.h, l.w, l.size, l.stride, l.pad, imd); + } + } + } + } +} + +void update_convolutional_layer(convolutional_layer l, update_args a) +{ + float learning_rate = a.learning_rate*l.learning_rate_scale; + float momentum = a.momentum; + float decay = a.decay; + int batch = a.batch; + + axpy_cpu(l.n, learning_rate/batch, l.bias_updates, 1, l.biases, 1); + scal_cpu(l.n, momentum, l.bias_updates, 1); + + if(l.scales){ + axpy_cpu(l.n, learning_rate/batch, l.scale_updates, 1, l.scales, 1); + scal_cpu(l.n, momentum, l.scale_updates, 1); + } + + axpy_cpu(l.nweights, -decay*batch, l.weights, 1, l.weight_updates, 1); + axpy_cpu(l.nweights, learning_rate/batch, l.weight_updates, 1, l.weights, 1); + scal_cpu(l.nweights, momentum, l.weight_updates, 1); +} + + +image get_convolutional_weight(convolutional_layer l, int i) +{ + int h = l.size; + int w = l.size; + int c = l.c/l.groups; + return float_to_image(w,h,c,l.weights+i*h*w*c); +} + +void rgbgr_weights(convolutional_layer l) +{ + int i; + for(i = 0; i < l.n; ++i){ + image im = get_convolutional_weight(l, i); + if (im.c == 3) { + rgbgr_image(im); + } + } +} + +void rescale_weights(convolutional_layer l, float scale, float trans) +{ + int i; + for(i = 0; i < l.n; ++i){ + image im = get_convolutional_weight(l, i); + if (im.c == 3) { + scale_image(im, scale); + float sum = sum_array(im.data, im.w*im.h*im.c); + l.biases[i] += sum*trans; + } + } +} + +image *get_weights(convolutional_layer l) +{ + image *weights = calloc(l.n, sizeof(image)); + int i; + for(i = 0; i < l.n; ++i){ + weights[i] = copy_image(get_convolutional_weight(l, i)); + normalize_image(weights[i]); + /* + char buff[256]; + sprintf(buff, "filter%d", i); + save_image(weights[i], buff); + */ + } + //error("hey"); + return weights; +} + +image *visualize_convolutional_layer(convolutional_layer l, char *window, image *prev_weights) +{ + image *single_weights = get_weights(l); + show_images(single_weights, l.n, window); + + image delta = get_convolutional_image(l); + image dc = collapse_image_layers(delta, 1); + char buff[256]; + sprintf(buff, "%s: Output", window); + //show_image(dc, buff); + //save_image(dc, buff); + free_image(dc); + return single_weights; +} + diff --git a/hanzi_detection/src/convolutional_layer.h b/hanzi_detection/src/convolutional_layer.h new file mode 100755 index 0000000..6c261f5 --- /dev/null +++ b/hanzi_detection/src/convolutional_layer.h @@ -0,0 +1,50 @@ +#ifndef CONVOLUTIONAL_LAYER_H +#define CONVOLUTIONAL_LAYER_H + +#include "cuda.h" +#include "image.h" +#include "activations.h" +#include "layer.h" +#include "network.h" + +typedef layer convolutional_layer; + +#ifdef GPU +void forward_convolutional_layer_gpu(convolutional_layer layer, network net); +void backward_convolutional_layer_gpu(convolutional_layer layer, network net); +void update_convolutional_layer_gpu(convolutional_layer layer, update_args a); + +void push_convolutional_layer(convolutional_layer layer); +void pull_convolutional_layer(convolutional_layer layer); + +void add_bias_gpu(float *output, float *biases, int batch, int n, int size); +void backward_bias_gpu(float *bias_updates, float *delta, int batch, int n, int size); +void adam_update_gpu(float *w, float *d, float *m, float *v, float B1, float B2, float eps, float decay, float rate, int n, int batch, int t); +#ifdef CUDNN +void cudnn_convolutional_setup(layer *l); +#endif +#endif + +convolutional_layer make_convolutional_layer(int batch, int h, int w, int c, int n, int groups, int size, int stride, int padding, ACTIVATION activation, int batch_normalize, int binary, int xnor, int adam); +void resize_convolutional_layer(convolutional_layer *layer, int w, int h); +void forward_convolutional_layer(const convolutional_layer layer, network net); +void update_convolutional_layer(convolutional_layer layer, update_args a); +image *visualize_convolutional_layer(convolutional_layer layer, char *window, image *prev_weights); +void binarize_weights(float *weights, int n, int size, float *binary); +void swap_binary(convolutional_layer *l); +void binarize_weights2(float *weights, int n, int size, char *binary, float *scales); + +void backward_convolutional_layer(convolutional_layer layer, network net); + +void add_bias(float *output, float *biases, int batch, int n, int size); +void backward_bias(float *bias_updates, float *delta, int batch, int n, int size); + +image get_convolutional_image(convolutional_layer layer); +image get_convolutional_delta(convolutional_layer layer); +image get_convolutional_weight(convolutional_layer layer, int i); + +int convolutional_out_height(convolutional_layer layer); +int convolutional_out_width(convolutional_layer layer); + +#endif + diff --git a/hanzi_detection/src/cost_layer.c b/hanzi_detection/src/cost_layer.c new file mode 100755 index 0000000..2138ff2 --- /dev/null +++ b/hanzi_detection/src/cost_layer.c @@ -0,0 +1,176 @@ +#include "cost_layer.h" +#include "utils.h" +#include "cuda.h" +#include "blas.h" +#include +#include +#include +#include + +COST_TYPE get_cost_type(char *s) +{ + if (strcmp(s, "seg")==0) return SEG; + if (strcmp(s, "sse")==0) return SSE; + if (strcmp(s, "masked")==0) return MASKED; + if (strcmp(s, "smooth")==0) return SMOOTH; + if (strcmp(s, "L1")==0) return L1; + if (strcmp(s, "wgan")==0) return WGAN; + fprintf(stderr, "Couldn't find cost type %s, going with SSE\n", s); + return SSE; +} + +char *get_cost_string(COST_TYPE a) +{ + switch(a){ + case SEG: + return "seg"; + case SSE: + return "sse"; + case MASKED: + return "masked"; + case SMOOTH: + return "smooth"; + case L1: + return "L1"; + case WGAN: + return "wgan"; + } + return "sse"; +} + +cost_layer make_cost_layer(int batch, int inputs, COST_TYPE cost_type, float scale) +{ + fprintf(stderr, "cost %4d\n", inputs); + cost_layer l = {0}; + l.type = COST; + + l.scale = scale; + l.batch = batch; + l.inputs = inputs; + l.outputs = inputs; + l.cost_type = cost_type; + l.delta = calloc(inputs*batch, sizeof(float)); + l.output = calloc(inputs*batch, sizeof(float)); + l.cost = calloc(1, sizeof(float)); + + l.forward = forward_cost_layer; + l.backward = backward_cost_layer; + #ifdef GPU + l.forward_gpu = forward_cost_layer_gpu; + l.backward_gpu = backward_cost_layer_gpu; + + l.delta_gpu = cuda_make_array(l.output, inputs*batch); + l.output_gpu = cuda_make_array(l.delta, inputs*batch); + #endif + return l; +} + +void resize_cost_layer(cost_layer *l, int inputs) +{ + l->inputs = inputs; + l->outputs = inputs; + l->delta = realloc(l->delta, inputs*l->batch*sizeof(float)); + l->output = realloc(l->output, inputs*l->batch*sizeof(float)); +#ifdef GPU + cuda_free(l->delta_gpu); + cuda_free(l->output_gpu); + l->delta_gpu = cuda_make_array(l->delta, inputs*l->batch); + l->output_gpu = cuda_make_array(l->output, inputs*l->batch); +#endif +} + +void forward_cost_layer(cost_layer l, network net) +{ + if (!net.truth) return; + if(l.cost_type == MASKED){ + int i; + for(i = 0; i < l.batch*l.inputs; ++i){ + if(net.truth[i] == SECRET_NUM) net.input[i] = SECRET_NUM; + } + } + if(l.cost_type == SMOOTH){ + smooth_l1_cpu(l.batch*l.inputs, net.input, net.truth, l.delta, l.output); + }else if(l.cost_type == L1){ + l1_cpu(l.batch*l.inputs, net.input, net.truth, l.delta, l.output); + } else { + l2_cpu(l.batch*l.inputs, net.input, net.truth, l.delta, l.output); + } + l.cost[0] = sum_array(l.output, l.batch*l.inputs); +} + +void backward_cost_layer(const cost_layer l, network net) +{ + axpy_cpu(l.batch*l.inputs, l.scale, l.delta, 1, net.delta, 1); +} + +#ifdef GPU + +void pull_cost_layer(cost_layer l) +{ + cuda_pull_array(l.delta_gpu, l.delta, l.batch*l.inputs); +} + +void push_cost_layer(cost_layer l) +{ + cuda_push_array(l.delta_gpu, l.delta, l.batch*l.inputs); +} + +int float_abs_compare (const void * a, const void * b) +{ + float fa = *(const float*) a; + if(fa < 0) fa = -fa; + float fb = *(const float*) b; + if(fb < 0) fb = -fb; + return (fa > fb) - (fa < fb); +} + +void forward_cost_layer_gpu(cost_layer l, network net) +{ + if (!net.truth) return; + if(l.smooth){ + scal_gpu(l.batch*l.inputs, (1-l.smooth), net.truth_gpu, 1); + add_gpu(l.batch*l.inputs, l.smooth * 1./l.inputs, net.truth_gpu, 1); + } + + if(l.cost_type == SMOOTH){ + smooth_l1_gpu(l.batch*l.inputs, net.input_gpu, net.truth_gpu, l.delta_gpu, l.output_gpu); + } else if (l.cost_type == L1){ + l1_gpu(l.batch*l.inputs, net.input_gpu, net.truth_gpu, l.delta_gpu, l.output_gpu); + } else if (l.cost_type == WGAN){ + wgan_gpu(l.batch*l.inputs, net.input_gpu, net.truth_gpu, l.delta_gpu, l.output_gpu); + } else { + l2_gpu(l.batch*l.inputs, net.input_gpu, net.truth_gpu, l.delta_gpu, l.output_gpu); + } + + if (l.cost_type == SEG && l.noobject_scale != 1) { + scale_mask_gpu(l.batch*l.inputs, l.delta_gpu, 0, net.truth_gpu, l.noobject_scale); + scale_mask_gpu(l.batch*l.inputs, l.output_gpu, 0, net.truth_gpu, l.noobject_scale); + } + if (l.cost_type == MASKED) { + mask_gpu(l.batch*l.inputs, net.delta_gpu, SECRET_NUM, net.truth_gpu, 0); + } + + if(l.ratio){ + cuda_pull_array(l.delta_gpu, l.delta, l.batch*l.inputs); + qsort(l.delta, l.batch*l.inputs, sizeof(float), float_abs_compare); + int n = (1-l.ratio) * l.batch*l.inputs; + float thresh = l.delta[n]; + thresh = 0; + printf("%f\n", thresh); + supp_gpu(l.batch*l.inputs, thresh, l.delta_gpu, 1); + } + + if(l.thresh){ + supp_gpu(l.batch*l.inputs, l.thresh*1./l.inputs, l.delta_gpu, 1); + } + + cuda_pull_array(l.output_gpu, l.output, l.batch*l.inputs); + l.cost[0] = sum_array(l.output, l.batch*l.inputs); +} + +void backward_cost_layer_gpu(const cost_layer l, network net) +{ + axpy_gpu(l.batch*l.inputs, l.scale, l.delta_gpu, 1, net.delta_gpu, 1); +} +#endif + diff --git a/hanzi_detection/src/cost_layer.h b/hanzi_detection/src/cost_layer.h new file mode 100755 index 0000000..ceb64de --- /dev/null +++ b/hanzi_detection/src/cost_layer.h @@ -0,0 +1,20 @@ +#ifndef COST_LAYER_H +#define COST_LAYER_H +#include "layer.h" +#include "network.h" + +typedef layer cost_layer; + +COST_TYPE get_cost_type(char *s); +char *get_cost_string(COST_TYPE a); +cost_layer make_cost_layer(int batch, int inputs, COST_TYPE type, float scale); +void forward_cost_layer(const cost_layer l, network net); +void backward_cost_layer(const cost_layer l, network net); +void resize_cost_layer(cost_layer *l, int inputs); + +#ifdef GPU +void forward_cost_layer_gpu(cost_layer l, network net); +void backward_cost_layer_gpu(const cost_layer l, network net); +#endif + +#endif diff --git a/hanzi_detection/src/crnn_layer.c b/hanzi_detection/src/crnn_layer.c new file mode 100755 index 0000000..7dd29f6 --- /dev/null +++ b/hanzi_detection/src/crnn_layer.c @@ -0,0 +1,283 @@ +#include "crnn_layer.h" +#include "convolutional_layer.h" +#include "utils.h" +#include "cuda.h" +#include "blas.h" +#include "gemm.h" + +#include +#include +#include +#include + +static void increment_layer(layer *l, int steps) +{ + int num = l->outputs*l->batch*steps; + l->output += num; + l->delta += num; + l->x += num; + l->x_norm += num; + +#ifdef GPU + l->output_gpu += num; + l->delta_gpu += num; + l->x_gpu += num; + l->x_norm_gpu += num; +#endif +} + +layer make_crnn_layer(int batch, int h, int w, int c, int hidden_filters, int output_filters, int steps, ACTIVATION activation, int batch_normalize) +{ + fprintf(stderr, "CRNN Layer: %d x %d x %d image, %d filters\n", h,w,c,output_filters); + batch = batch / steps; + layer l = {0}; + l.batch = batch; + l.type = CRNN; + l.steps = steps; + l.h = h; + l.w = w; + l.c = c; + l.out_h = h; + l.out_w = w; + l.out_c = output_filters; + l.inputs = h*w*c; + l.hidden = h * w * hidden_filters; + l.outputs = l.out_h * l.out_w * l.out_c; + + l.state = calloc(l.hidden*batch*(steps+1), sizeof(float)); + + l.input_layer = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.input_layer) = make_convolutional_layer(batch*steps, h, w, c, hidden_filters, 1, 3, 1, 1, activation, batch_normalize, 0, 0, 0); + l.input_layer->batch = batch; + + l.self_layer = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.self_layer) = make_convolutional_layer(batch*steps, h, w, hidden_filters, hidden_filters, 1, 3, 1, 1, activation, batch_normalize, 0, 0, 0); + l.self_layer->batch = batch; + + l.output_layer = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.output_layer) = make_convolutional_layer(batch*steps, h, w, hidden_filters, output_filters, 1, 3, 1, 1, activation, batch_normalize, 0, 0, 0); + l.output_layer->batch = batch; + + l.output = l.output_layer->output; + l.delta = l.output_layer->delta; + + l.forward = forward_crnn_layer; + l.backward = backward_crnn_layer; + l.update = update_crnn_layer; + +#ifdef GPU + l.forward_gpu = forward_crnn_layer_gpu; + l.backward_gpu = backward_crnn_layer_gpu; + l.update_gpu = update_crnn_layer_gpu; + + l.state_gpu = cuda_make_array(l.state, l.hidden*batch*(steps+1)); + l.output_gpu = l.output_layer->output_gpu; + l.delta_gpu = l.output_layer->delta_gpu; +#endif + + return l; +} + +void update_crnn_layer(layer l, update_args a) +{ + update_convolutional_layer(*(l.input_layer), a); + update_convolutional_layer(*(l.self_layer), a); + update_convolutional_layer(*(l.output_layer), a); +} + +void forward_crnn_layer(layer l, network net) +{ + network s = net; + s.train = net.train; + int i; + layer input_layer = *(l.input_layer); + layer self_layer = *(l.self_layer); + layer output_layer = *(l.output_layer); + + fill_cpu(l.outputs * l.batch * l.steps, 0, output_layer.delta, 1); + fill_cpu(l.hidden * l.batch * l.steps, 0, self_layer.delta, 1); + fill_cpu(l.hidden * l.batch * l.steps, 0, input_layer.delta, 1); + if(net.train) fill_cpu(l.hidden * l.batch, 0, l.state, 1); + + for (i = 0; i < l.steps; ++i) { + s.input = net.input; + forward_convolutional_layer(input_layer, s); + + s.input = l.state; + forward_convolutional_layer(self_layer, s); + + float *old_state = l.state; + if(net.train) l.state += l.hidden*l.batch; + if(l.shortcut){ + copy_cpu(l.hidden * l.batch, old_state, 1, l.state, 1); + }else{ + fill_cpu(l.hidden * l.batch, 0, l.state, 1); + } + axpy_cpu(l.hidden * l.batch, 1, input_layer.output, 1, l.state, 1); + axpy_cpu(l.hidden * l.batch, 1, self_layer.output, 1, l.state, 1); + + s.input = l.state; + forward_convolutional_layer(output_layer, s); + + net.input += l.inputs*l.batch; + increment_layer(&input_layer, 1); + increment_layer(&self_layer, 1); + increment_layer(&output_layer, 1); + } +} + +void backward_crnn_layer(layer l, network net) +{ + network s = net; + int i; + layer input_layer = *(l.input_layer); + layer self_layer = *(l.self_layer); + layer output_layer = *(l.output_layer); + + increment_layer(&input_layer, l.steps-1); + increment_layer(&self_layer, l.steps-1); + increment_layer(&output_layer, l.steps-1); + + l.state += l.hidden*l.batch*l.steps; + for (i = l.steps-1; i >= 0; --i) { + copy_cpu(l.hidden * l.batch, input_layer.output, 1, l.state, 1); + axpy_cpu(l.hidden * l.batch, 1, self_layer.output, 1, l.state, 1); + + s.input = l.state; + s.delta = self_layer.delta; + backward_convolutional_layer(output_layer, s); + + l.state -= l.hidden*l.batch; + /* + if(i > 0){ + copy_cpu(l.hidden * l.batch, input_layer.output - l.hidden*l.batch, 1, l.state, 1); + axpy_cpu(l.hidden * l.batch, 1, self_layer.output - l.hidden*l.batch, 1, l.state, 1); + }else{ + fill_cpu(l.hidden * l.batch, 0, l.state, 1); + } + */ + + s.input = l.state; + s.delta = self_layer.delta - l.hidden*l.batch; + if (i == 0) s.delta = 0; + backward_convolutional_layer(self_layer, s); + + copy_cpu(l.hidden*l.batch, self_layer.delta, 1, input_layer.delta, 1); + if (i > 0 && l.shortcut) axpy_cpu(l.hidden*l.batch, 1, self_layer.delta, 1, self_layer.delta - l.hidden*l.batch, 1); + s.input = net.input + i*l.inputs*l.batch; + if(net.delta) s.delta = net.delta + i*l.inputs*l.batch; + else s.delta = 0; + backward_convolutional_layer(input_layer, s); + + increment_layer(&input_layer, -1); + increment_layer(&self_layer, -1); + increment_layer(&output_layer, -1); + } +} + +#ifdef GPU + +void pull_crnn_layer(layer l) +{ + pull_convolutional_layer(*(l.input_layer)); + pull_convolutional_layer(*(l.self_layer)); + pull_convolutional_layer(*(l.output_layer)); +} + +void push_crnn_layer(layer l) +{ + push_convolutional_layer(*(l.input_layer)); + push_convolutional_layer(*(l.self_layer)); + push_convolutional_layer(*(l.output_layer)); +} + +void update_crnn_layer_gpu(layer l, update_args a) +{ + update_convolutional_layer_gpu(*(l.input_layer), a); + update_convolutional_layer_gpu(*(l.self_layer), a); + update_convolutional_layer_gpu(*(l.output_layer), a); +} + +void forward_crnn_layer_gpu(layer l, network net) +{ + network s = net; + int i; + layer input_layer = *(l.input_layer); + layer self_layer = *(l.self_layer); + layer output_layer = *(l.output_layer); + + fill_gpu(l.outputs * l.batch * l.steps, 0, output_layer.delta_gpu, 1); + fill_gpu(l.hidden * l.batch * l.steps, 0, self_layer.delta_gpu, 1); + fill_gpu(l.hidden * l.batch * l.steps, 0, input_layer.delta_gpu, 1); + if(net.train) fill_gpu(l.hidden * l.batch, 0, l.state_gpu, 1); + + for (i = 0; i < l.steps; ++i) { + s.input_gpu = net.input_gpu; + forward_convolutional_layer_gpu(input_layer, s); + + s.input_gpu = l.state_gpu; + forward_convolutional_layer_gpu(self_layer, s); + + float *old_state = l.state_gpu; + if(net.train) l.state_gpu += l.hidden*l.batch; + if(l.shortcut){ + copy_gpu(l.hidden * l.batch, old_state, 1, l.state_gpu, 1); + }else{ + fill_gpu(l.hidden * l.batch, 0, l.state_gpu, 1); + } + axpy_gpu(l.hidden * l.batch, 1, input_layer.output_gpu, 1, l.state_gpu, 1); + axpy_gpu(l.hidden * l.batch, 1, self_layer.output_gpu, 1, l.state_gpu, 1); + + s.input_gpu = l.state_gpu; + forward_convolutional_layer_gpu(output_layer, s); + + net.input_gpu += l.inputs*l.batch; + increment_layer(&input_layer, 1); + increment_layer(&self_layer, 1); + increment_layer(&output_layer, 1); + } +} + +void backward_crnn_layer_gpu(layer l, network net) +{ + network s = net; + s.train = net.train; + int i; + layer input_layer = *(l.input_layer); + layer self_layer = *(l.self_layer); + layer output_layer = *(l.output_layer); + increment_layer(&input_layer, l.steps - 1); + increment_layer(&self_layer, l.steps - 1); + increment_layer(&output_layer, l.steps - 1); + l.state_gpu += l.hidden*l.batch*l.steps; + for (i = l.steps-1; i >= 0; --i) { + copy_gpu(l.hidden * l.batch, input_layer.output_gpu, 1, l.state_gpu, 1); + axpy_gpu(l.hidden * l.batch, 1, self_layer.output_gpu, 1, l.state_gpu, 1); + + s.input_gpu = l.state_gpu; + s.delta_gpu = self_layer.delta_gpu; + backward_convolutional_layer_gpu(output_layer, s); + + l.state_gpu -= l.hidden*l.batch; + + s.input_gpu = l.state_gpu; + s.delta_gpu = self_layer.delta_gpu - l.hidden*l.batch; + if (i == 0) s.delta_gpu = 0; + backward_convolutional_layer_gpu(self_layer, s); + + copy_gpu(l.hidden*l.batch, self_layer.delta_gpu, 1, input_layer.delta_gpu, 1); + if (i > 0 && l.shortcut) axpy_gpu(l.hidden*l.batch, 1, self_layer.delta_gpu, 1, self_layer.delta_gpu - l.hidden*l.batch, 1); + s.input_gpu = net.input_gpu + i*l.inputs*l.batch; + if(net.delta_gpu) s.delta_gpu = net.delta_gpu + i*l.inputs*l.batch; + else s.delta_gpu = 0; + backward_convolutional_layer_gpu(input_layer, s); + + increment_layer(&input_layer, -1); + increment_layer(&self_layer, -1); + increment_layer(&output_layer, -1); + } +} +#endif diff --git a/hanzi_detection/src/crnn_layer.h b/hanzi_detection/src/crnn_layer.h new file mode 100755 index 0000000..515f378 --- /dev/null +++ b/hanzi_detection/src/crnn_layer.h @@ -0,0 +1,24 @@ + +#ifndef CRNN_LAYER_H +#define CRNN_LAYER_H + +#include "activations.h" +#include "layer.h" +#include "network.h" + +layer make_crnn_layer(int batch, int h, int w, int c, int hidden_filters, int output_filters, int steps, ACTIVATION activation, int batch_normalize); + +void forward_crnn_layer(layer l, network net); +void backward_crnn_layer(layer l, network net); +void update_crnn_layer(layer l, update_args a); + +#ifdef GPU +void forward_crnn_layer_gpu(layer l, network net); +void backward_crnn_layer_gpu(layer l, network net); +void update_crnn_layer_gpu(layer l, update_args a); +void push_crnn_layer(layer l); +void pull_crnn_layer(layer l); +#endif + +#endif + diff --git a/hanzi_detection/src/crop_layer.c b/hanzi_detection/src/crop_layer.c new file mode 100755 index 0000000..3b91852 --- /dev/null +++ b/hanzi_detection/src/crop_layer.c @@ -0,0 +1,103 @@ +#include "crop_layer.h" +#include "cuda.h" +#include + +image get_crop_image(crop_layer l) +{ + int h = l.out_h; + int w = l.out_w; + int c = l.out_c; + return float_to_image(w,h,c,l.output); +} + +void backward_crop_layer(const crop_layer l, network net){} +void backward_crop_layer_gpu(const crop_layer l, network net){} + +crop_layer make_crop_layer(int batch, int h, int w, int c, int crop_height, int crop_width, int flip, float angle, float saturation, float exposure) +{ + fprintf(stderr, "Crop Layer: %d x %d -> %d x %d x %d image\n", h,w,crop_height,crop_width,c); + crop_layer l = {0}; + l.type = CROP; + l.batch = batch; + l.h = h; + l.w = w; + l.c = c; + l.scale = (float)crop_height / h; + l.flip = flip; + l.angle = angle; + l.saturation = saturation; + l.exposure = exposure; + l.out_w = crop_width; + l.out_h = crop_height; + l.out_c = c; + l.inputs = l.w * l.h * l.c; + l.outputs = l.out_w * l.out_h * l.out_c; + l.output = calloc(l.outputs*batch, sizeof(float)); + l.forward = forward_crop_layer; + l.backward = backward_crop_layer; + + #ifdef GPU + l.forward_gpu = forward_crop_layer_gpu; + l.backward_gpu = backward_crop_layer_gpu; + l.output_gpu = cuda_make_array(l.output, l.outputs*batch); + l.rand_gpu = cuda_make_array(0, l.batch*8); + #endif + return l; +} + +void resize_crop_layer(layer *l, int w, int h) +{ + l->w = w; + l->h = h; + + l->out_w = l->scale*w; + l->out_h = l->scale*h; + + l->inputs = l->w * l->h * l->c; + l->outputs = l->out_h * l->out_w * l->out_c; + + l->output = realloc(l->output, l->batch*l->outputs*sizeof(float)); + #ifdef GPU + cuda_free(l->output_gpu); + l->output_gpu = cuda_make_array(l->output, l->outputs*l->batch); + #endif +} + + +void forward_crop_layer(const crop_layer l, network net) +{ + int i,j,c,b,row,col; + int index; + int count = 0; + int flip = (l.flip && rand()%2); + int dh = rand()%(l.h - l.out_h + 1); + int dw = rand()%(l.w - l.out_w + 1); + float scale = 2; + float trans = -1; + if(l.noadjust){ + scale = 1; + trans = 0; + } + if(!net.train){ + flip = 0; + dh = (l.h - l.out_h)/2; + dw = (l.w - l.out_w)/2; + } + for(b = 0; b < l.batch; ++b){ + for(c = 0; c < l.c; ++c){ + for(i = 0; i < l.out_h; ++i){ + for(j = 0; j < l.out_w; ++j){ + if(flip){ + col = l.w - dw - j - 1; + }else{ + col = j + dw; + } + row = i + dh; + index = col+l.w*(row+l.h*(c + l.c*b)); + l.output[count++] = net.input[index]*scale + trans; + } + } + } + } +} + diff --git a/hanzi_detection/src/crop_layer.h b/hanzi_detection/src/crop_layer.h new file mode 100755 index 0000000..3b5883c --- /dev/null +++ b/hanzi_detection/src/crop_layer.h @@ -0,0 +1,20 @@ +#ifndef CROP_LAYER_H +#define CROP_LAYER_H + +#include "image.h" +#include "layer.h" +#include "network.h" + +typedef layer crop_layer; + +image get_crop_image(crop_layer l); +crop_layer make_crop_layer(int batch, int h, int w, int c, int crop_height, int crop_width, int flip, float angle, float saturation, float exposure); +void forward_crop_layer(const crop_layer l, network net); +void resize_crop_layer(layer *l, int w, int h); + +#ifdef GPU +void forward_crop_layer_gpu(crop_layer l, network net); +#endif + +#endif + diff --git a/hanzi_detection/src/crop_layer_kernels.cu b/hanzi_detection/src/crop_layer_kernels.cu new file mode 100755 index 0000000..b5b9f55 --- /dev/null +++ b/hanzi_detection/src/crop_layer_kernels.cu @@ -0,0 +1,225 @@ +#include "cuda_runtime.h" +#include "curand.h" +#include "cublas_v2.h" + +extern "C" { +#include "crop_layer.h" +#include "utils.h" +#include "cuda.h" +#include "image.h" +} + +__device__ float get_pixel_kernel(float *image, int w, int h, int x, int y, int c) +{ + if(x < 0 || x >= w || y < 0 || y >= h) return 0; + return image[x + w*(y + c*h)]; +} + +__device__ float3 rgb_to_hsv_kernel(float3 rgb) +{ + float r = rgb.x; + float g = rgb.y; + float b = rgb.z; + + float h, s, v; + float max = (r > g) ? ( (r > b) ? r : b) : ( (g > b) ? g : b); + float min = (r < g) ? ( (r < b) ? r : b) : ( (g < b) ? g : b); + float delta = max - min; + v = max; + if(max == 0){ + s = 0; + h = -1; + }else{ + s = delta/max; + if(r == max){ + h = (g - b) / delta; + } else if (g == max) { + h = 2 + (b - r) / delta; + } else { + h = 4 + (r - g) / delta; + } + if (h < 0) h += 6; + } + return make_float3(h, s, v); +} + +__device__ float3 hsv_to_rgb_kernel(float3 hsv) +{ + float h = hsv.x; + float s = hsv.y; + float v = hsv.z; + + float r, g, b; + float f, p, q, t; + + if (s == 0) { + r = g = b = v; + } else { + int index = (int) floorf(h); + f = h - index; + p = v*(1-s); + q = v*(1-s*f); + t = v*(1-s*(1-f)); + if(index == 0){ + r = v; g = t; b = p; + } else if(index == 1){ + r = q; g = v; b = p; + } else if(index == 2){ + r = p; g = v; b = t; + } else if(index == 3){ + r = p; g = q; b = v; + } else if(index == 4){ + r = t; g = p; b = v; + } else { + r = v; g = p; b = q; + } + } + r = (r < 0) ? 0 : ((r > 1) ? 1 : r); + g = (g < 0) ? 0 : ((g > 1) ? 1 : g); + b = (b < 0) ? 0 : ((b > 1) ? 1 : b); + return make_float3(r, g, b); +} + +__device__ float bilinear_interpolate_kernel(float *image, int w, int h, float x, float y, int c) +{ + int ix = (int) floorf(x); + int iy = (int) floorf(y); + + float dx = x - ix; + float dy = y - iy; + + float val = (1-dy) * (1-dx) * get_pixel_kernel(image, w, h, ix, iy, c) + + dy * (1-dx) * get_pixel_kernel(image, w, h, ix, iy+1, c) + + (1-dy) * dx * get_pixel_kernel(image, w, h, ix+1, iy, c) + + dy * dx * get_pixel_kernel(image, w, h, ix+1, iy+1, c); + return val; +} + +__global__ void levels_image_kernel(float *image, float *rand, int batch, int w, int h, int train, float saturation, float exposure, float translate, float scale, float shift) +{ + int size = batch * w * h; + int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(id >= size) return; + int x = id % w; + id /= w; + int y = id % h; + id /= h; + float rshift = rand[0]; + float gshift = rand[1]; + float bshift = rand[2]; + float r0 = rand[8*id + 0]; + float r1 = rand[8*id + 1]; + float r2 = rand[8*id + 2]; + float r3 = rand[8*id + 3]; + + saturation = r0*(saturation - 1) + 1; + saturation = (r1 > .5f) ? 1.f/saturation : saturation; + exposure = r2*(exposure - 1) + 1; + exposure = (r3 > .5f) ? 1.f/exposure : exposure; + + size_t offset = id * h * w * 3; + image += offset; + float r = image[x + w*(y + h*0)]; + float g = image[x + w*(y + h*1)]; + float b = image[x + w*(y + h*2)]; + float3 rgb = make_float3(r,g,b); + if(train){ + float3 hsv = rgb_to_hsv_kernel(rgb); + hsv.y *= saturation; + hsv.z *= exposure; + rgb = hsv_to_rgb_kernel(hsv); + } else { + shift = 0; + } + image[x + w*(y + h*0)] = rgb.x*scale + translate + (rshift - .5f)*shift; + image[x + w*(y + h*1)] = rgb.y*scale + translate + (gshift - .5f)*shift; + image[x + w*(y + h*2)] = rgb.z*scale + translate + (bshift - .5f)*shift; +} + +__global__ void forward_crop_layer_kernel(float *input, float *rand, int size, int c, int h, int w, int crop_height, int crop_width, int train, int flip, float angle, float *output) +{ + int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(id >= size) return; + + float cx = w/2.f; + float cy = h/2.f; + + int count = id; + int j = id % crop_width; + id /= crop_width; + int i = id % crop_height; + id /= crop_height; + int k = id % c; + id /= c; + int b = id; + + float r4 = rand[8*b + 4]; + float r5 = rand[8*b + 5]; + float r6 = rand[8*b + 6]; + float r7 = rand[8*b + 7]; + + float dw = (w - crop_width)*r4; + float dh = (h - crop_height)*r5; + flip = (flip && (r6 > .5f)); + angle = 2*angle*r7 - angle; + if(!train){ + dw = (w - crop_width)/2.f; + dh = (h - crop_height)/2.f; + flip = 0; + angle = 0; + } + + input += w*h*c*b; + + float x = (flip) ? w - dw - j - 1 : j + dw; + float y = i + dh; + + float rx = cosf(angle)*(x-cx) - sinf(angle)*(y-cy) + cx; + float ry = sinf(angle)*(x-cx) + cosf(angle)*(y-cy) + cy; + + output[count] = bilinear_interpolate_kernel(input, w, h, rx, ry, k); +} + +extern "C" void forward_crop_layer_gpu(crop_layer layer, network net) +{ + cuda_random(layer.rand_gpu, layer.batch*8); + + float radians = layer.angle*3.14159265f/180.f; + + float scale = 2; + float translate = -1; + if(layer.noadjust){ + scale = 1; + translate = 0; + } + + int size = layer.batch * layer.w * layer.h; + + levels_image_kernel<<>>(net.input_gpu, layer.rand_gpu, layer.batch, layer.w, layer.h, net.train, layer.saturation, layer.exposure, translate, scale, layer.shift); + check_error(cudaPeekAtLastError()); + + size = layer.batch*layer.c*layer.out_w*layer.out_h; + + forward_crop_layer_kernel<<>>(net.input_gpu, layer.rand_gpu, size, layer.c, layer.h, layer.w, layer.out_h, layer.out_w, net.train, layer.flip, radians, layer.output_gpu); + check_error(cudaPeekAtLastError()); + +/* + cuda_pull_array(layer.output_gpu, layer.output, size); + image im = float_to_image(layer.crop_width, layer.crop_height, layer.c, layer.output + 0*(size/layer.batch)); + image im2 = float_to_image(layer.crop_width, layer.crop_height, layer.c, layer.output + 1*(size/layer.batch)); + image im3 = float_to_image(layer.crop_width, layer.crop_height, layer.c, layer.output + 2*(size/layer.batch)); + + translate_image(im, -translate); + scale_image(im, 1/scale); + translate_image(im2, -translate); + scale_image(im2, 1/scale); + translate_image(im3, -translate); + scale_image(im3, 1/scale); + + show_image(im, "cropped"); + show_image(im2, "cropped2"); + show_image(im3, "cropped3"); + cvWaitKey(0); + */ +} + diff --git a/hanzi_detection/src/cuda.c b/hanzi_detection/src/cuda.c new file mode 100755 index 0000000..48aba6e --- /dev/null +++ b/hanzi_detection/src/cuda.c @@ -0,0 +1,178 @@ +int gpu_index = 0; + +#ifdef GPU + +#include "cuda.h" +#include "utils.h" +#include "blas.h" +#include +#include +#include + +void cuda_set_device(int n) +{ + gpu_index = n; + cudaError_t status = cudaSetDevice(n); + check_error(status); +} + +int cuda_get_device() +{ + int n = 0; + cudaError_t status = cudaGetDevice(&n); + check_error(status); + return n; +} + +void check_error(cudaError_t status) +{ + //cudaDeviceSynchronize(); + cudaError_t status2 = cudaGetLastError(); + if (status != cudaSuccess) + { + const char *s = cudaGetErrorString(status); + char buffer[256]; + printf("CUDA Error: %s\n", s); + assert(0); + snprintf(buffer, 256, "CUDA Error: %s", s); + error(buffer); + } + if (status2 != cudaSuccess) + { + const char *s = cudaGetErrorString(status); + char buffer[256]; + printf("CUDA Error Prev: %s\n", s); + assert(0); + snprintf(buffer, 256, "CUDA Error Prev: %s", s); + error(buffer); + } +} + +dim3 cuda_gridsize(size_t n){ + size_t k = (n-1) / BLOCK + 1; + size_t x = k; + size_t y = 1; + if(x > 65535){ + x = ceil(sqrt(k)); + y = (n-1)/(x*BLOCK) + 1; + } + dim3 d = {x, y, 1}; + //printf("%ld %ld %ld %ld\n", n, x, y, x*y*BLOCK); + return d; +} + +#ifdef CUDNN +cudnnHandle_t cudnn_handle() +{ + static int init[16] = {0}; + static cudnnHandle_t handle[16]; + int i = cuda_get_device(); + if(!init[i]) { + cudnnCreate(&handle[i]); + init[i] = 1; + } + return handle[i]; +} +#endif + +cublasHandle_t blas_handle() +{ + static int init[16] = {0}; + static cublasHandle_t handle[16]; + int i = cuda_get_device(); + if(!init[i]) { + cublasCreate(&handle[i]); + init[i] = 1; + } + return handle[i]; +} + +float *cuda_make_array(float *x, size_t n) +{ + float *x_gpu; + size_t size = sizeof(float)*n; + cudaError_t status = cudaMalloc((void **)&x_gpu, size); + check_error(status); + if(x){ + status = cudaMemcpy(x_gpu, x, size, cudaMemcpyHostToDevice); + check_error(status); + } else { + fill_gpu(n, 0, x_gpu, 1); + } + if(!x_gpu) error("Cuda malloc failed\n"); + return x_gpu; +} + +void cuda_random(float *x_gpu, size_t n) +{ + static curandGenerator_t gen[16]; + static int init[16] = {0}; + int i = cuda_get_device(); + if(!init[i]){ + curandCreateGenerator(&gen[i], CURAND_RNG_PSEUDO_DEFAULT); + curandSetPseudoRandomGeneratorSeed(gen[i], time(0)); + init[i] = 1; + } + curandGenerateUniform(gen[i], x_gpu, n); + check_error(cudaPeekAtLastError()); +} + +float cuda_compare(float *x_gpu, float *x, size_t n, char *s) +{ + float *tmp = calloc(n, sizeof(float)); + cuda_pull_array(x_gpu, tmp, n); + //int i; + //for(i = 0; i < n; ++i) printf("%f %f\n", tmp[i], x[i]); + axpy_cpu(n, -1, x, 1, tmp, 1); + float err = dot_cpu(n, tmp, 1, tmp, 1); + printf("Error %s: %f\n", s, sqrt(err/n)); + free(tmp); + return err; +} + +int *cuda_make_int_array(int *x, size_t n) +{ + int *x_gpu; + size_t size = sizeof(int)*n; + cudaError_t status = cudaMalloc((void **)&x_gpu, size); + check_error(status); + if(x){ + status = cudaMemcpy(x_gpu, x, size, cudaMemcpyHostToDevice); + check_error(status); + } + if(!x_gpu) error("Cuda malloc failed\n"); + return x_gpu; +} + +void cuda_free(float *x_gpu) +{ + cudaError_t status = cudaFree(x_gpu); + check_error(status); +} + +void cuda_push_array(float *x_gpu, float *x, size_t n) +{ + size_t size = sizeof(float)*n; + cudaError_t status = cudaMemcpy(x_gpu, x, size, cudaMemcpyHostToDevice); + check_error(status); +} + +void cuda_pull_array(float *x_gpu, float *x, size_t n) +{ + size_t size = sizeof(float)*n; + cudaError_t status = cudaMemcpy(x, x_gpu, size, cudaMemcpyDeviceToHost); + check_error(status); +} + +float cuda_mag_array(float *x_gpu, size_t n) +{ + float *temp = calloc(n, sizeof(float)); + cuda_pull_array(x_gpu, temp, n); + float m = mag_array(temp, n); + free(temp); + return m; +} +#else +void cuda_set_device(int n){} + +#endif diff --git a/hanzi_detection/src/cuda.h b/hanzi_detection/src/cuda.h new file mode 100755 index 0000000..a1bc216 --- /dev/null +++ b/hanzi_detection/src/cuda.h @@ -0,0 +1,20 @@ +#ifndef CUDA_H +#define CUDA_H + +#include "darknet.h" + +#ifdef GPU + +void check_error(cudaError_t status); +cublasHandle_t blas_handle(); +int *cuda_make_int_array(int *x, size_t n); +void cuda_random(float *x_gpu, size_t n); +float cuda_compare(float *x_gpu, float *x, size_t n, char *s); +dim3 cuda_gridsize(size_t n); + +#ifdef CUDNN +cudnnHandle_t cudnn_handle(); +#endif + +#endif +#endif diff --git a/hanzi_detection/src/data.c b/hanzi_detection/src/data.c new file mode 100755 index 0000000..59051b4 --- /dev/null +++ b/hanzi_detection/src/data.c @@ -0,0 +1,1685 @@ +#include "data.h" +#include "utils.h" +#include "image.h" +#include "cuda.h" + +#include +#include +#include + +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +list *get_paths(char *filename) +{ + char *path; + FILE *file = fopen(filename, "r"); + if(!file) file_error(filename); + list *lines = make_list(); + while((path=fgetl(file))){ + list_insert(lines, path); + } + fclose(file); + return lines; +} + +/* +char **get_random_paths_indexes(char **paths, int n, int m, int *indexes) +{ + char **random_paths = calloc(n, sizeof(char*)); + int i; + pthread_mutex_lock(&mutex); + for(i = 0; i < n; ++i){ + int index = rand()%m; + indexes[i] = index; + random_paths[i] = paths[index]; + if(i == 0) printf("%s\n", paths[index]); + } + pthread_mutex_unlock(&mutex); + return random_paths; +} +*/ + +char **get_random_paths(char **paths, int n, int m) +{ + char **random_paths = calloc(n, sizeof(char*)); + int i; + pthread_mutex_lock(&mutex); + for(i = 0; i < n; ++i){ + int index = rand()%m; + random_paths[i] = paths[index]; + //if(i == 0) printf("%s\n", paths[index]); + } + pthread_mutex_unlock(&mutex); + return random_paths; +} + +char **find_replace_paths(char **paths, int n, char *find, char *replace) +{ + char **replace_paths = calloc(n, sizeof(char*)); + int i; + for(i = 0; i < n; ++i){ + char replaced[4096]; + find_replace(paths[i], find, replace, replaced); + replace_paths[i] = copy_string(replaced); + } + return replace_paths; +} + +matrix load_image_paths_gray(char **paths, int n, int w, int h) +{ + int i; + matrix X; + X.rows = n; + X.vals = calloc(X.rows, sizeof(float*)); + X.cols = 0; + + for(i = 0; i < n; ++i){ + image im = load_image(paths[i], w, h, 3); + + image gray = grayscale_image(im); + free_image(im); + im = gray; + + X.vals[i] = im.data; + X.cols = im.h*im.w*im.c; + } + return X; +} + +matrix load_image_paths(char **paths, int n, int w, int h) +{ + int i; + matrix X; + X.rows = n; + X.vals = calloc(X.rows, sizeof(float*)); + X.cols = 0; + + for(i = 0; i < n; ++i){ + image im = load_image_color(paths[i], w, h); + X.vals[i] = im.data; + X.cols = im.h*im.w*im.c; + } + return X; +} + +matrix load_image_augment_paths(char **paths, int n, int min, int max, int size, float angle, float aspect, float hue, float saturation, float exposure, int center) +{ + int i; + matrix X; + X.rows = n; + X.vals = calloc(X.rows, sizeof(float*)); + X.cols = 0; + + for(i = 0; i < n; ++i){ + image im = load_image_color(paths[i], 0, 0); + image crop; + if(center){ + crop = center_crop_image(im, size, size); + } else { + crop = random_augment_image(im, angle, aspect, min, max, size, size); + } + int flip = rand()%2; + if (flip) flip_image(crop); + random_distort_image(crop, hue, saturation, exposure); + + /* + show_image(im, "orig"); + show_image(crop, "crop"); + cvWaitKey(0); + */ + //grayscale_image_3c(crop); + free_image(im); + X.vals[i] = crop.data; + X.cols = crop.h*crop.w*crop.c; + } + return X; +} + + +box_label *read_boxes(char *filename, int *n) +{ + FILE *file = fopen(filename, "r"); + if(!file) file_error(filename); + float x, y, h, w; + int id; + int count = 0; + int size = 64; + box_label *boxes = calloc(size, sizeof(box_label)); + while(fscanf(file, "%d %f %f %f %f", &id, &x, &y, &w, &h) == 5){ + if(count == size) { + size = size * 2; + boxes = realloc(boxes, size*sizeof(box_label)); + } + boxes[count].id = id; + boxes[count].x = x; + boxes[count].y = y; + boxes[count].h = h; + boxes[count].w = w; + boxes[count].left = x - w/2; + boxes[count].right = x + w/2; + boxes[count].top = y - h/2; + boxes[count].bottom = y + h/2; + ++count; + } + fclose(file); + *n = count; + return boxes; +} + +void randomize_boxes(box_label *b, int n) +{ + int i; + for(i = 0; i < n; ++i){ + box_label swap = b[i]; + int index = rand()%n; + b[i] = b[index]; + b[index] = swap; + } +} + +void correct_boxes(box_label *boxes, int n, float dx, float dy, float sx, float sy, int flip) +{ + int i; + for(i = 0; i < n; ++i){ + if(boxes[i].x == 0 && boxes[i].y == 0) { + boxes[i].x = 999999; + boxes[i].y = 999999; + boxes[i].w = 999999; + boxes[i].h = 999999; + continue; + } + boxes[i].left = boxes[i].left * sx - dx; + boxes[i].right = boxes[i].right * sx - dx; + boxes[i].top = boxes[i].top * sy - dy; + boxes[i].bottom = boxes[i].bottom* sy - dy; + + if(flip){ + float swap = boxes[i].left; + boxes[i].left = 1. - boxes[i].right; + boxes[i].right = 1. - swap; + } + + boxes[i].left = constrain(0, 1, boxes[i].left); + boxes[i].right = constrain(0, 1, boxes[i].right); + boxes[i].top = constrain(0, 1, boxes[i].top); + boxes[i].bottom = constrain(0, 1, boxes[i].bottom); + + boxes[i].x = (boxes[i].left+boxes[i].right)/2; + boxes[i].y = (boxes[i].top+boxes[i].bottom)/2; + boxes[i].w = (boxes[i].right - boxes[i].left); + boxes[i].h = (boxes[i].bottom - boxes[i].top); + + boxes[i].w = constrain(0, 1, boxes[i].w); + boxes[i].h = constrain(0, 1, boxes[i].h); + } +} + +void fill_truth_swag(char *path, float *truth, int classes, int flip, float dx, float dy, float sx, float sy) +{ + char labelpath[4096]; + find_replace(path, "images", "labels", labelpath); + find_replace(labelpath, "JPEGImages", "labels", labelpath); + find_replace(labelpath, ".jpg", ".txt", labelpath); + find_replace(labelpath, ".JPG", ".txt", labelpath); + find_replace(labelpath, ".JPEG", ".txt", labelpath); + + int count = 0; + box_label *boxes = read_boxes(labelpath, &count); + randomize_boxes(boxes, count); + correct_boxes(boxes, count, dx, dy, sx, sy, flip); + float x,y,w,h; + int id; + int i; + + for (i = 0; i < count && i < 90; ++i) { + x = boxes[i].x; + y = boxes[i].y; + w = boxes[i].w; + h = boxes[i].h; + id = boxes[i].id; + + if (w < .0 || h < .0) continue; + + int index = (4+classes) * i; + + truth[index++] = x; + truth[index++] = y; + truth[index++] = w; + truth[index++] = h; + + if (id < classes) truth[index+id] = 1; + } + free(boxes); +} + +void fill_truth_region(char *path, float *truth, int classes, int num_boxes, int flip, float dx, float dy, float sx, float sy) +{ + char labelpath[4096]; + find_replace(path, "images", "labels", labelpath); + find_replace(labelpath, "JPEGImages", "labels", labelpath); + + find_replace(labelpath, ".jpg", ".txt", labelpath); + find_replace(labelpath, ".png", ".txt", labelpath); + find_replace(labelpath, ".JPG", ".txt", labelpath); + find_replace(labelpath, ".JPEG", ".txt", labelpath); + int count = 0; + box_label *boxes = read_boxes(labelpath, &count); + randomize_boxes(boxes, count); + correct_boxes(boxes, count, dx, dy, sx, sy, flip); + float x,y,w,h; + int id; + int i; + + for (i = 0; i < count; ++i) { + x = boxes[i].x; + y = boxes[i].y; + w = boxes[i].w; + h = boxes[i].h; + id = boxes[i].id; + + if (w < .005 || h < .005) continue; + + int col = (int)(x*num_boxes); + int row = (int)(y*num_boxes); + + x = x*num_boxes - col; + y = y*num_boxes - row; + + int index = (col+row*num_boxes)*(5+classes); + if (truth[index]) continue; + truth[index++] = 1; + + if (id < classes) truth[index+id] = 1; + index += classes; + + truth[index++] = x; + truth[index++] = y; + truth[index++] = w; + truth[index++] = h; + } + free(boxes); +} + +void load_rle(image im, int *rle, int n) +{ + int count = 0; + int curr = 0; + int i,j; + for(i = 0; i < n; ++i){ + for(j = 0; j < rle[i]; ++j){ + im.data[count++] = curr; + } + curr = 1 - curr; + } + for(; count < im.h*im.w*im.c; ++count){ + im.data[count] = curr; + } +} + +void or_image(image src, image dest, int c) +{ + int i; + for(i = 0; i < src.w*src.h; ++i){ + if(src.data[i]) dest.data[dest.w*dest.h*c + i] = 1; + } +} + +void exclusive_image(image src) +{ + int k, j, i; + int s = src.w*src.h; + for(k = 0; k < src.c-1; ++k){ + for(i = 0; i < s; ++i){ + if (src.data[k*s + i]){ + for(j = k+1; j < src.c; ++j){ + src.data[j*s + i] = 0; + } + } + } + } +} + +box bound_image(image im) +{ + int x,y; + int minx = im.w; + int miny = im.h; + int maxx = 0; + int maxy = 0; + for(y = 0; y < im.h; ++y){ + for(x = 0; x < im.w; ++x){ + if(im.data[y*im.w + x]){ + minx = (x < minx) ? x : minx; + miny = (y < miny) ? y : miny; + maxx = (x > maxx) ? x : maxx; + maxy = (y > maxy) ? y : maxy; + } + } + } + box b = {minx, miny, maxx-minx + 1, maxy-miny + 1}; + //printf("%f %f %f %f\n", b.x, b.y, b.w, b.h); + return b; +} + +void fill_truth_iseg(char *path, int num_boxes, float *truth, int classes, int w, int h, augment_args aug, int flip, int mw, int mh) +{ + char labelpath[4096]; + find_replace(path, "images", "mask", labelpath); + find_replace(labelpath, "JPEGImages", "mask", labelpath); + find_replace(labelpath, ".jpg", ".txt", labelpath); + find_replace(labelpath, ".JPG", ".txt", labelpath); + find_replace(labelpath, ".JPEG", ".txt", labelpath); + FILE *file = fopen(labelpath, "r"); + if(!file) file_error(labelpath); + char buff[32788]; + int id; + int i = 0; + int j; + image part = make_image(w, h, 1); + while((fscanf(file, "%d %s", &id, buff) == 2) && i < num_boxes){ + int n = 0; + int *rle = read_intlist(buff, &n, 0); + load_rle(part, rle, n); + image sized = rotate_crop_image(part, aug.rad, aug.scale, aug.w, aug.h, aug.dx, aug.dy, aug.aspect); + if(flip) flip_image(sized); + + image mask = resize_image(sized, mw, mh); + truth[i*(mw*mh+1)] = id; + for(j = 0; j < mw*mh; ++j){ + truth[i*(mw*mh + 1) + 1 + j] = mask.data[j]; + } + ++i; + + free_image(mask); + free_image(sized); + free(rle); + } + if(i < num_boxes) truth[i*(mw*mh+1)] = -1; + fclose(file); + free_image(part); +} + +void fill_truth_mask(char *path, int num_boxes, float *truth, int classes, int w, int h, augment_args aug, int flip, int mw, int mh) +{ + char labelpath[4096]; + find_replace(path, "images", "mask", labelpath); + find_replace(labelpath, "JPEGImages", "mask", labelpath); + find_replace(labelpath, ".jpg", ".txt", labelpath); + find_replace(labelpath, ".JPG", ".txt", labelpath); + find_replace(labelpath, ".JPEG", ".txt", labelpath); + FILE *file = fopen(labelpath, "r"); + if(!file) file_error(labelpath); + char buff[32788]; + int id; + int i = 0; + image part = make_image(w, h, 1); + while((fscanf(file, "%d %s", &id, buff) == 2) && i < num_boxes){ + int n = 0; + int *rle = read_intlist(buff, &n, 0); + load_rle(part, rle, n); + image sized = rotate_crop_image(part, aug.rad, aug.scale, aug.w, aug.h, aug.dx, aug.dy, aug.aspect); + if(flip) flip_image(sized); + box b = bound_image(sized); + if(b.w > 0){ + image crop = crop_image(sized, b.x, b.y, b.w, b.h); + image mask = resize_image(crop, mw, mh); + truth[i*(4 + mw*mh + 1) + 0] = (b.x + b.w/2.)/sized.w; + truth[i*(4 + mw*mh + 1) + 1] = (b.y + b.h/2.)/sized.h; + truth[i*(4 + mw*mh + 1) + 2] = b.w/sized.w; + truth[i*(4 + mw*mh + 1) + 3] = b.h/sized.h; + int j; + for(j = 0; j < mw*mh; ++j){ + truth[i*(4 + mw*mh + 1) + 4 + j] = mask.data[j]; + } + truth[i*(4 + mw*mh + 1) + 4 + mw*mh] = id; + free_image(crop); + free_image(mask); + ++i; + } + free_image(sized); + free(rle); + } + fclose(file); + free_image(part); +} + + +void fill_truth_detection(char *path, int num_boxes, float *truth, int classes, int flip, float dx, float dy, float sx, float sy) +{ + char labelpath[4096]; + find_replace(path, "images", "labels", labelpath); + find_replace(labelpath, "JPEGImages", "labels", labelpath); + + find_replace(labelpath, "raw", "labels", labelpath); + find_replace(labelpath, ".jpg", ".txt", labelpath); + find_replace(labelpath, ".png", ".txt", labelpath); + find_replace(labelpath, ".JPG", ".txt", labelpath); + find_replace(labelpath, ".JPEG", ".txt", labelpath); + int count = 0; + box_label *boxes = read_boxes(labelpath, &count); + randomize_boxes(boxes, count); + correct_boxes(boxes, count, dx, dy, sx, sy, flip); + if(count > num_boxes) count = num_boxes; + float x,y,w,h; + int id; + int i; + int sub = 0; + + for (i = 0; i < count; ++i) { + x = boxes[i].x; + y = boxes[i].y; + w = boxes[i].w; + h = boxes[i].h; + id = boxes[i].id; + + if ((w < .001 || h < .001)) { + ++sub; + continue; + } + + truth[(i-sub)*5+0] = x; + truth[(i-sub)*5+1] = y; + truth[(i-sub)*5+2] = w; + truth[(i-sub)*5+3] = h; + truth[(i-sub)*5+4] = id; + } + free(boxes); +} + +#define NUMCHARS 37 + +void print_letters(float *pred, int n) +{ + int i; + for(i = 0; i < n; ++i){ + int index = max_index(pred+i*NUMCHARS, NUMCHARS); + printf("%c", int_to_alphanum(index)); + } + printf("\n"); +} + +void fill_truth_captcha(char *path, int n, float *truth) +{ + char *begin = strrchr(path, '/'); + ++begin; + int i; + for(i = 0; i < strlen(begin) && i < n && begin[i] != '.'; ++i){ + int index = alphanum_to_int(begin[i]); + if(index > 35) printf("Bad %c\n", begin[i]); + truth[i*NUMCHARS+index] = 1; + } + for(;i < n; ++i){ + truth[i*NUMCHARS + NUMCHARS-1] = 1; + } +} + +data load_data_captcha(char **paths, int n, int m, int k, int w, int h) +{ + if(m) paths = get_random_paths(paths, n, m); + data d = {0}; + d.shallow = 0; + d.X = load_image_paths(paths, n, w, h); + d.y = make_matrix(n, k*NUMCHARS); + int i; + for(i = 0; i < n; ++i){ + fill_truth_captcha(paths[i], k, d.y.vals[i]); + } + if(m) free(paths); + return d; +} + +data load_data_captcha_encode(char **paths, int n, int m, int w, int h) +{ + if(m) paths = get_random_paths(paths, n, m); + data d = {0}; + d.shallow = 0; + d.X = load_image_paths(paths, n, w, h); + d.X.cols = 17100; + d.y = d.X; + if(m) free(paths); + return d; +} + +void fill_truth(char *path, char **labels, int k, float *truth) +{ + int i; + memset(truth, 0, k*sizeof(float)); + int count = 0; + for(i = 0; i < k; ++i){ + if(strstr(path, labels[i])){ + truth[i] = 1; + ++count; + //printf("%s %s %d\n", path, labels[i], i); + } + } + if(count != 1 && (k != 1 || count != 0)) printf("Too many or too few labels: %d, %s\n", count, path); +} + +void fill_hierarchy(float *truth, int k, tree *hierarchy) +{ + int j; + for(j = 0; j < k; ++j){ + if(truth[j]){ + int parent = hierarchy->parent[j]; + while(parent >= 0){ + truth[parent] = 1; + parent = hierarchy->parent[parent]; + } + } + } + int i; + int count = 0; + for(j = 0; j < hierarchy->groups; ++j){ + //printf("%d\n", count); + int mask = 1; + for(i = 0; i < hierarchy->group_size[j]; ++i){ + if(truth[count + i]){ + mask = 0; + break; + } + } + if (mask) { + for(i = 0; i < hierarchy->group_size[j]; ++i){ + truth[count + i] = SECRET_NUM; + } + } + count += hierarchy->group_size[j]; + } +} + +matrix load_regression_labels_paths(char **paths, int n, int k) +{ + matrix y = make_matrix(n, k); + int i,j; + for(i = 0; i < n; ++i){ + char labelpath[4096]; + find_replace(paths[i], "images", "labels", labelpath); + find_replace(labelpath, "JPEGImages", "labels", labelpath); + find_replace(labelpath, ".BMP", ".txt", labelpath); + find_replace(labelpath, ".JPEG", ".txt", labelpath); + find_replace(labelpath, ".JPG", ".txt", labelpath); + find_replace(labelpath, ".JPeG", ".txt", labelpath); + find_replace(labelpath, ".Jpeg", ".txt", labelpath); + find_replace(labelpath, ".PNG", ".txt", labelpath); + find_replace(labelpath, ".TIF", ".txt", labelpath); + find_replace(labelpath, ".bmp", ".txt", labelpath); + find_replace(labelpath, ".jpeg", ".txt", labelpath); + find_replace(labelpath, ".jpg", ".txt", labelpath); + find_replace(labelpath, ".png", ".txt", labelpath); + find_replace(labelpath, ".tif", ".txt", labelpath); + + FILE *file = fopen(labelpath, "r"); + for(j = 0; j < k; ++j){ + fscanf(file, "%f", &(y.vals[i][j])); + } + fclose(file); + } + return y; +} + +matrix load_labels_paths(char **paths, int n, char **labels, int k, tree *hierarchy) +{ + matrix y = make_matrix(n, k); + int i; + for(i = 0; i < n && labels; ++i){ + fill_truth(paths[i], labels, k, y.vals[i]); + if(hierarchy){ + fill_hierarchy(y.vals[i], k, hierarchy); + } + } + return y; +} + +matrix load_tags_paths(char **paths, int n, int k) +{ + matrix y = make_matrix(n, k); + int i; + //int count = 0; + for(i = 0; i < n; ++i){ + char label[4096]; + find_replace(paths[i], "images", "labels", label); + find_replace(label, ".jpg", ".txt", label); + FILE *file = fopen(label, "r"); + if (!file) continue; + //++count; + int tag; + while(fscanf(file, "%d", &tag) == 1){ + if(tag < k){ + y.vals[i][tag] = 1; + } + } + fclose(file); + } + //printf("%d/%d\n", count, n); + return y; +} + +char **get_labels(char *filename) +{ + list *plist = get_paths(filename); + char **labels = (char **)list_to_array(plist); + free_list(plist); + return labels; +} + +void free_data(data d) +{ + if(!d.shallow){ + free_matrix(d.X); + free_matrix(d.y); + }else{ + free(d.X.vals); + free(d.y.vals); + } +} + +image get_segmentation_image(char *path, int w, int h, int classes) +{ + char labelpath[4096]; + find_replace(path, "images", "mask", labelpath); + find_replace(labelpath, "JPEGImages", "mask", labelpath); + find_replace(labelpath, ".jpg", ".txt", labelpath); + find_replace(labelpath, ".JPG", ".txt", labelpath); + find_replace(labelpath, ".JPEG", ".txt", labelpath); + image mask = make_image(w, h, classes); + FILE *file = fopen(labelpath, "r"); + if(!file) file_error(labelpath); + char buff[32788]; + int id; + image part = make_image(w, h, 1); + while(fscanf(file, "%d %s", &id, buff) == 2){ + int n = 0; + int *rle = read_intlist(buff, &n, 0); + load_rle(part, rle, n); + or_image(part, mask, id); + free(rle); + } + //exclusive_image(mask); + fclose(file); + free_image(part); + return mask; +} + +image get_segmentation_image2(char *path, int w, int h, int classes) +{ + char labelpath[4096]; + find_replace(path, "images", "mask", labelpath); + find_replace(labelpath, "JPEGImages", "mask", labelpath); + find_replace(labelpath, ".jpg", ".txt", labelpath); + find_replace(labelpath, ".JPG", ".txt", labelpath); + find_replace(labelpath, ".JPEG", ".txt", labelpath); + image mask = make_image(w, h, classes+1); + int i; + for(i = 0; i < w*h; ++i){ + mask.data[w*h*classes + i] = 1; + } + FILE *file = fopen(labelpath, "r"); + if(!file) file_error(labelpath); + char buff[32788]; + int id; + image part = make_image(w, h, 1); + while(fscanf(file, "%d %s", &id, buff) == 2){ + int n = 0; + int *rle = read_intlist(buff, &n, 0); + load_rle(part, rle, n); + or_image(part, mask, id); + for(i = 0; i < w*h; ++i){ + if(part.data[i]) mask.data[w*h*classes + i] = 0; + } + free(rle); + } + //exclusive_image(mask); + fclose(file); + free_image(part); + return mask; +} + +data load_data_seg(int n, char **paths, int m, int w, int h, int classes, int min, int max, float angle, float aspect, float hue, float saturation, float exposure, int div) +{ + char **random_paths = get_random_paths(paths, n, m); + int i; + data d = {0}; + d.shallow = 0; + + d.X.rows = n; + d.X.vals = calloc(d.X.rows, sizeof(float*)); + d.X.cols = h*w*3; + + + d.y.rows = n; + d.y.cols = h*w*classes/div/div; + d.y.vals = calloc(d.X.rows, sizeof(float*)); + + for(i = 0; i < n; ++i){ + image orig = load_image_color(random_paths[i], 0, 0); + augment_args a = random_augment_args(orig, angle, aspect, min, max, w, h); + image sized = rotate_crop_image(orig, a.rad, a.scale, a.w, a.h, a.dx, a.dy, a.aspect); + + int flip = rand()%2; + if(flip) flip_image(sized); + random_distort_image(sized, hue, saturation, exposure); + d.X.vals[i] = sized.data; + + image mask = get_segmentation_image(random_paths[i], orig.w, orig.h, classes); + //image mask = make_image(orig.w, orig.h, classes+1); + image sized_m = rotate_crop_image(mask, a.rad, a.scale/div, a.w/div, a.h/div, a.dx/div, a.dy/div, a.aspect); + + if(flip) flip_image(sized_m); + d.y.vals[i] = sized_m.data; + + free_image(orig); + free_image(mask); + + /* + image rgb = mask_to_rgb(sized_m, classes); + show_image(rgb, "part"); + show_image(sized, "orig"); + cvWaitKey(0); + free_image(rgb); + */ + } + free(random_paths); + return d; +} + +data load_data_iseg(int n, char **paths, int m, int w, int h, int classes, int boxes, int div, int min, int max, float angle, float aspect, float hue, float saturation, float exposure) +{ + char **random_paths = get_random_paths(paths, n, m); + int i; + data d = {0}; + d.shallow = 0; + + d.X.rows = n; + d.X.vals = calloc(d.X.rows, sizeof(float*)); + d.X.cols = h*w*3; + + d.y = make_matrix(n, (((w/div)*(h/div))+1)*boxes); + + for(i = 0; i < n; ++i){ + image orig = load_image_color(random_paths[i], 0, 0); + augment_args a = random_augment_args(orig, angle, aspect, min, max, w, h); + image sized = rotate_crop_image(orig, a.rad, a.scale, a.w, a.h, a.dx, a.dy, a.aspect); + + int flip = rand()%2; + if(flip) flip_image(sized); + random_distort_image(sized, hue, saturation, exposure); + d.X.vals[i] = sized.data; + //show_image(sized, "image"); + + fill_truth_iseg(random_paths[i], boxes, d.y.vals[i], classes, orig.w, orig.h, a, flip, w/div, h/div); + + free_image(orig); + + /* + image rgb = mask_to_rgb(sized_m, classes); + show_image(rgb, "part"); + show_image(sized, "orig"); + cvWaitKey(0); + free_image(rgb); + */ + } + free(random_paths); + return d; +} + +data load_data_mask(int n, char **paths, int m, int w, int h, int classes, int boxes, int coords, int min, int max, float angle, float aspect, float hue, float saturation, float exposure) +{ + char **random_paths = get_random_paths(paths, n, m); + int i; + data d = {0}; + d.shallow = 0; + + d.X.rows = n; + d.X.vals = calloc(d.X.rows, sizeof(float*)); + d.X.cols = h*w*3; + + d.y = make_matrix(n, (coords+1)*boxes); + + for(i = 0; i < n; ++i){ + image orig = load_image_color(random_paths[i], 0, 0); + augment_args a = random_augment_args(orig, angle, aspect, min, max, w, h); + image sized = rotate_crop_image(orig, a.rad, a.scale, a.w, a.h, a.dx, a.dy, a.aspect); + + int flip = rand()%2; + if(flip) flip_image(sized); + random_distort_image(sized, hue, saturation, exposure); + d.X.vals[i] = sized.data; + //show_image(sized, "image"); + + fill_truth_mask(random_paths[i], boxes, d.y.vals[i], classes, orig.w, orig.h, a, flip, 14, 14); + + free_image(orig); + + /* + image rgb = mask_to_rgb(sized_m, classes); + show_image(rgb, "part"); + show_image(sized, "orig"); + cvWaitKey(0); + free_image(rgb); + */ + } + free(random_paths); + return d; +} + +data load_data_region(int n, char **paths, int m, int w, int h, int size, int classes, float jitter, float hue, float saturation, float exposure) +{ + char **random_paths = get_random_paths(paths, n, m); + int i; + data d = {0}; + d.shallow = 0; + + d.X.rows = n; + d.X.vals = calloc(d.X.rows, sizeof(float*)); + d.X.cols = h*w*3; + + + int k = size*size*(5+classes); + d.y = make_matrix(n, k); + for(i = 0; i < n; ++i){ + image orig = load_image_color(random_paths[i], 0, 0); + + int oh = orig.h; + int ow = orig.w; + + int dw = (ow*jitter); + int dh = (oh*jitter); + + int pleft = rand_uniform(-dw, dw); + int pright = rand_uniform(-dw, dw); + int ptop = rand_uniform(-dh, dh); + int pbot = rand_uniform(-dh, dh); + + int swidth = ow - pleft - pright; + int sheight = oh - ptop - pbot; + + float sx = (float)swidth / ow; + float sy = (float)sheight / oh; + + int flip = rand()%2; + image cropped = crop_image(orig, pleft, ptop, swidth, sheight); + + float dx = ((float)pleft/ow)/sx; + float dy = ((float)ptop /oh)/sy; + + image sized = resize_image(cropped, w, h); + if(flip) flip_image(sized); + random_distort_image(sized, hue, saturation, exposure); + d.X.vals[i] = sized.data; + + fill_truth_region(random_paths[i], d.y.vals[i], classes, size, flip, dx, dy, 1./sx, 1./sy); + + free_image(orig); + free_image(cropped); + } + free(random_paths); + return d; +} + +data load_data_compare(int n, char **paths, int m, int classes, int w, int h) +{ + if(m) paths = get_random_paths(paths, 2*n, m); + int i,j; + data d = {0}; + d.shallow = 0; + + d.X.rows = n; + d.X.vals = calloc(d.X.rows, sizeof(float*)); + d.X.cols = h*w*6; + + int k = 2*(classes); + d.y = make_matrix(n, k); + for(i = 0; i < n; ++i){ + image im1 = load_image_color(paths[i*2], w, h); + image im2 = load_image_color(paths[i*2+1], w, h); + + d.X.vals[i] = calloc(d.X.cols, sizeof(float)); + memcpy(d.X.vals[i], im1.data, h*w*3*sizeof(float)); + memcpy(d.X.vals[i] + h*w*3, im2.data, h*w*3*sizeof(float)); + + int id; + float iou; + + char imlabel1[4096]; + char imlabel2[4096]; + find_replace(paths[i*2], "imgs", "labels", imlabel1); + find_replace(imlabel1, "jpg", "txt", imlabel1); + FILE *fp1 = fopen(imlabel1, "r"); + + while(fscanf(fp1, "%d %f", &id, &iou) == 2){ + if (d.y.vals[i][2*id] < iou) d.y.vals[i][2*id] = iou; + } + + find_replace(paths[i*2+1], "imgs", "labels", imlabel2); + find_replace(imlabel2, "jpg", "txt", imlabel2); + FILE *fp2 = fopen(imlabel2, "r"); + + while(fscanf(fp2, "%d %f", &id, &iou) == 2){ + if (d.y.vals[i][2*id + 1] < iou) d.y.vals[i][2*id + 1] = iou; + } + + for (j = 0; j < classes; ++j){ + if (d.y.vals[i][2*j] > .5 && d.y.vals[i][2*j+1] < .5){ + d.y.vals[i][2*j] = 1; + d.y.vals[i][2*j+1] = 0; + } else if (d.y.vals[i][2*j] < .5 && d.y.vals[i][2*j+1] > .5){ + d.y.vals[i][2*j] = 0; + d.y.vals[i][2*j+1] = 1; + } else { + d.y.vals[i][2*j] = SECRET_NUM; + d.y.vals[i][2*j+1] = SECRET_NUM; + } + } + fclose(fp1); + fclose(fp2); + + free_image(im1); + free_image(im2); + } + if(m) free(paths); + return d; +} + +data load_data_swag(char **paths, int n, int classes, float jitter) +{ + int index = rand()%n; + char *random_path = paths[index]; + + image orig = load_image_color(random_path, 0, 0); + int h = orig.h; + int w = orig.w; + + data d = {0}; + d.shallow = 0; + d.w = w; + d.h = h; + + d.X.rows = 1; + d.X.vals = calloc(d.X.rows, sizeof(float*)); + d.X.cols = h*w*3; + + int k = (4+classes)*90; + d.y = make_matrix(1, k); + + int dw = w*jitter; + int dh = h*jitter; + + int pleft = rand_uniform(-dw, dw); + int pright = rand_uniform(-dw, dw); + int ptop = rand_uniform(-dh, dh); + int pbot = rand_uniform(-dh, dh); + + int swidth = w - pleft - pright; + int sheight = h - ptop - pbot; + + float sx = (float)swidth / w; + float sy = (float)sheight / h; + + int flip = rand()%2; + image cropped = crop_image(orig, pleft, ptop, swidth, sheight); + + float dx = ((float)pleft/w)/sx; + float dy = ((float)ptop /h)/sy; + + image sized = resize_image(cropped, w, h); + if(flip) flip_image(sized); + d.X.vals[0] = sized.data; + + fill_truth_swag(random_path, d.y.vals[0], classes, flip, dx, dy, 1./sx, 1./sy); + + free_image(orig); + free_image(cropped); + + return d; +} + +data load_data_detection(int n, char **paths, int m, int w, int h, int boxes, int classes, float jitter, float hue, float saturation, float exposure) +{ + char **random_paths = get_random_paths(paths, n, m); + int i; + data d = {0}; + d.shallow = 0; + + d.X.rows = n; + d.X.vals = calloc(d.X.rows, sizeof(float*)); + d.X.cols = h*w*3; + + d.y = make_matrix(n, 5*boxes); + for(i = 0; i < n; ++i){ + image orig = load_image_color(random_paths[i], 0, 0); + image sized = make_image(w, h, orig.c); + fill_image(sized, .5); + + float dw = jitter * orig.w; + float dh = jitter * orig.h; + + float new_ar = (orig.w + rand_uniform(-dw, dw)) / (orig.h + rand_uniform(-dh, dh)); + //float scale = rand_uniform(.25, 2); + float scale = 1; + + float nw, nh; + + if(new_ar < 1){ + nh = scale * h; + nw = nh * new_ar; + } else { + nw = scale * w; + nh = nw / new_ar; + } + + float dx = rand_uniform(0, w - nw); + float dy = rand_uniform(0, h - nh); + + place_image(orig, nw, nh, dx, dy, sized); + + random_distort_image(sized, hue, saturation, exposure); + + int flip = rand()%2; + if(flip) flip_image(sized); + d.X.vals[i] = sized.data; + + + fill_truth_detection(random_paths[i], boxes, d.y.vals[i], classes, flip, -dx/w, -dy/h, nw/w, nh/h); + + free_image(orig); + } + free(random_paths); + return d; +} + +void *load_thread(void *ptr) +{ + //printf("Loading data: %d\n", rand()); + load_args a = *(struct load_args*)ptr; + if(a.exposure == 0) a.exposure = 1; + if(a.saturation == 0) a.saturation = 1; + if(a.aspect == 0) a.aspect = 1; + + if (a.type == OLD_CLASSIFICATION_DATA){ + *a.d = load_data_old(a.paths, a.n, a.m, a.labels, a.classes, a.w, a.h); + } else if (a.type == REGRESSION_DATA){ + *a.d = load_data_regression(a.paths, a.n, a.m, a.classes, a.min, a.max, a.size, a.angle, a.aspect, a.hue, a.saturation, a.exposure); + } else if (a.type == CLASSIFICATION_DATA){ + *a.d = load_data_augment(a.paths, a.n, a.m, a.labels, a.classes, a.hierarchy, a.min, a.max, a.size, a.angle, a.aspect, a.hue, a.saturation, a.exposure, a.center); + } else if (a.type == SUPER_DATA){ + *a.d = load_data_super(a.paths, a.n, a.m, a.w, a.h, a.scale); + } else if (a.type == WRITING_DATA){ + *a.d = load_data_writing(a.paths, a.n, a.m, a.w, a.h, a.out_w, a.out_h); + } else if (a.type == ISEG_DATA){ + *a.d = load_data_iseg(a.n, a.paths, a.m, a.w, a.h, a.classes, a.num_boxes, a.scale, a.min, a.max, a.angle, a.aspect, a.hue, a.saturation, a.exposure); + } else if (a.type == INSTANCE_DATA){ + *a.d = load_data_mask(a.n, a.paths, a.m, a.w, a.h, a.classes, a.num_boxes, a.coords, a.min, a.max, a.angle, a.aspect, a.hue, a.saturation, a.exposure); + } else if (a.type == SEGMENTATION_DATA){ + *a.d = load_data_seg(a.n, a.paths, a.m, a.w, a.h, a.classes, a.min, a.max, a.angle, a.aspect, a.hue, a.saturation, a.exposure, a.scale); + } else if (a.type == REGION_DATA){ + *a.d = load_data_region(a.n, a.paths, a.m, a.w, a.h, a.num_boxes, a.classes, a.jitter, a.hue, a.saturation, a.exposure); + } else if (a.type == DETECTION_DATA){ + *a.d = load_data_detection(a.n, a.paths, a.m, a.w, a.h, a.num_boxes, a.classes, a.jitter, a.hue, a.saturation, a.exposure); + } else if (a.type == SWAG_DATA){ + *a.d = load_data_swag(a.paths, a.n, a.classes, a.jitter); + } else if (a.type == COMPARE_DATA){ + *a.d = load_data_compare(a.n, a.paths, a.m, a.classes, a.w, a.h); + } else if (a.type == IMAGE_DATA){ + *(a.im) = load_image_color(a.path, 0, 0); + *(a.resized) = resize_image(*(a.im), a.w, a.h); + } else if (a.type == LETTERBOX_DATA){ + *(a.im) = load_image_color(a.path, 0, 0); + *(a.resized) = letterbox_image(*(a.im), a.w, a.h); + } else if (a.type == TAG_DATA){ + *a.d = load_data_tag(a.paths, a.n, a.m, a.classes, a.min, a.max, a.size, a.angle, a.aspect, a.hue, a.saturation, a.exposure); + } + free(ptr); + return 0; +} + +pthread_t load_data_in_thread(load_args args) +{ + pthread_t thread; + struct load_args *ptr = calloc(1, sizeof(struct load_args)); + *ptr = args; + if(pthread_create(&thread, 0, load_thread, ptr)) error("Thread creation failed"); + return thread; +} + +void *load_threads(void *ptr) +{ + int i; + load_args args = *(load_args *)ptr; + if (args.threads == 0) args.threads = 1; + data *out = args.d; + int total = args.n; + free(ptr); + data *buffers = calloc(args.threads, sizeof(data)); + pthread_t *threads = calloc(args.threads, sizeof(pthread_t)); + for(i = 0; i < args.threads; ++i){ + args.d = buffers + i; + args.n = (i+1) * total/args.threads - i * total/args.threads; + threads[i] = load_data_in_thread(args); + } + for(i = 0; i < args.threads; ++i){ + pthread_join(threads[i], 0); + } + *out = concat_datas(buffers, args.threads); + out->shallow = 0; + for(i = 0; i < args.threads; ++i){ + buffers[i].shallow = 1; + free_data(buffers[i]); + } + free(buffers); + free(threads); + return 0; +} + +void load_data_blocking(load_args args) +{ + struct load_args *ptr = calloc(1, sizeof(struct load_args)); + *ptr = args; + load_thread(ptr); +} + +pthread_t load_data(load_args args) +{ + pthread_t thread; + struct load_args *ptr = calloc(1, sizeof(struct load_args)); + *ptr = args; + if(pthread_create(&thread, 0, load_threads, ptr)) error("Thread creation failed"); + return thread; +} + +data load_data_writing(char **paths, int n, int m, int w, int h, int out_w, int out_h) +{ + if(m) paths = get_random_paths(paths, n, m); + char **replace_paths = find_replace_paths(paths, n, ".png", "-label.png"); + data d = {0}; + d.shallow = 0; + d.X = load_image_paths(paths, n, w, h); + d.y = load_image_paths_gray(replace_paths, n, out_w, out_h); + if(m) free(paths); + int i; + for(i = 0; i < n; ++i) free(replace_paths[i]); + free(replace_paths); + return d; +} + +data load_data_old(char **paths, int n, int m, char **labels, int k, int w, int h) +{ + if(m) paths = get_random_paths(paths, n, m); + data d = {0}; + d.shallow = 0; + d.X = load_image_paths(paths, n, w, h); + d.y = load_labels_paths(paths, n, labels, k, 0); + if(m) free(paths); + return d; +} + +/* + data load_data_study(char **paths, int n, int m, char **labels, int k, int min, int max, int size, float angle, float aspect, float hue, float saturation, float exposure) + { + data d = {0}; + d.indexes = calloc(n, sizeof(int)); + if(m) paths = get_random_paths_indexes(paths, n, m, d.indexes); + d.shallow = 0; + d.X = load_image_augment_paths(paths, n, min, max, size, angle, aspect, hue, saturation, exposure); + d.y = load_labels_paths(paths, n, labels, k); + if(m) free(paths); + return d; + } + */ + +data load_data_super(char **paths, int n, int m, int w, int h, int scale) +{ + if(m) paths = get_random_paths(paths, n, m); + data d = {0}; + d.shallow = 0; + + int i; + d.X.rows = n; + d.X.vals = calloc(n, sizeof(float*)); + d.X.cols = w*h*3; + + d.y.rows = n; + d.y.vals = calloc(n, sizeof(float*)); + d.y.cols = w*scale * h*scale * 3; + + for(i = 0; i < n; ++i){ + image im = load_image_color(paths[i], 0, 0); + image crop = random_crop_image(im, w*scale, h*scale); + int flip = rand()%2; + if (flip) flip_image(crop); + image resize = resize_image(crop, w, h); + d.X.vals[i] = resize.data; + d.y.vals[i] = crop.data; + free_image(im); + } + + if(m) free(paths); + return d; +} + +data load_data_regression(char **paths, int n, int m, int k, int min, int max, int size, float angle, float aspect, float hue, float saturation, float exposure) +{ + if(m) paths = get_random_paths(paths, n, m); + data d = {0}; + d.shallow = 0; + d.X = load_image_augment_paths(paths, n, min, max, size, angle, aspect, hue, saturation, exposure, 0); + d.y = load_regression_labels_paths(paths, n, k); + if(m) free(paths); + return d; +} + +data select_data(data *orig, int *inds) +{ + data d = {0}; + d.shallow = 1; + d.w = orig[0].w; + d.h = orig[0].h; + + d.X.rows = orig[0].X.rows; + d.y.rows = orig[0].X.rows; + + d.X.cols = orig[0].X.cols; + d.y.cols = orig[0].y.cols; + + d.X.vals = calloc(orig[0].X.rows, sizeof(float *)); + d.y.vals = calloc(orig[0].y.rows, sizeof(float *)); + int i; + for(i = 0; i < d.X.rows; ++i){ + d.X.vals[i] = orig[inds[i]].X.vals[i]; + d.y.vals[i] = orig[inds[i]].y.vals[i]; + } + return d; +} + +data *tile_data(data orig, int divs, int size) +{ + data *ds = calloc(divs*divs, sizeof(data)); + int i, j; +#pragma omp parallel for + for(i = 0; i < divs*divs; ++i){ + data d; + d.shallow = 0; + d.w = orig.w/divs * size; + d.h = orig.h/divs * size; + d.X.rows = orig.X.rows; + d.X.cols = d.w*d.h*3; + d.X.vals = calloc(d.X.rows, sizeof(float*)); + + d.y = copy_matrix(orig.y); +#pragma omp parallel for + for(j = 0; j < orig.X.rows; ++j){ + int x = (i%divs) * orig.w / divs - (d.w - orig.w/divs)/2; + int y = (i/divs) * orig.h / divs - (d.h - orig.h/divs)/2; + image im = float_to_image(orig.w, orig.h, 3, orig.X.vals[j]); + d.X.vals[j] = crop_image(im, x, y, d.w, d.h).data; + } + ds[i] = d; + } + return ds; +} + +data resize_data(data orig, int w, int h) +{ + data d = {0}; + d.shallow = 0; + d.w = w; + d.h = h; + int i; + d.X.rows = orig.X.rows; + d.X.cols = w*h*3; + d.X.vals = calloc(d.X.rows, sizeof(float*)); + + d.y = copy_matrix(orig.y); +#pragma omp parallel for + for(i = 0; i < orig.X.rows; ++i){ + image im = float_to_image(orig.w, orig.h, 3, orig.X.vals[i]); + d.X.vals[i] = resize_image(im, w, h).data; + } + return d; +} + +data load_data_augment(char **paths, int n, int m, char **labels, int k, tree *hierarchy, int min, int max, int size, float angle, float aspect, float hue, float saturation, float exposure, int center) +{ + if(m) paths = get_random_paths(paths, n, m); + data d = {0}; + d.shallow = 0; + d.w=size; + d.h=size; + d.X = load_image_augment_paths(paths, n, min, max, size, angle, aspect, hue, saturation, exposure, center); + d.y = load_labels_paths(paths, n, labels, k, hierarchy); + if(m) free(paths); + return d; +} + +data load_data_tag(char **paths, int n, int m, int k, int min, int max, int size, float angle, float aspect, float hue, float saturation, float exposure) +{ + if(m) paths = get_random_paths(paths, n, m); + data d = {0}; + d.w = size; + d.h = size; + d.shallow = 0; + d.X = load_image_augment_paths(paths, n, min, max, size, angle, aspect, hue, saturation, exposure, 0); + d.y = load_tags_paths(paths, n, k); + if(m) free(paths); + return d; +} + +matrix concat_matrix(matrix m1, matrix m2) +{ + int i, count = 0; + matrix m; + m.cols = m1.cols; + m.rows = m1.rows+m2.rows; + m.vals = calloc(m1.rows + m2.rows, sizeof(float*)); + for(i = 0; i < m1.rows; ++i){ + m.vals[count++] = m1.vals[i]; + } + for(i = 0; i < m2.rows; ++i){ + m.vals[count++] = m2.vals[i]; + } + return m; +} + +data concat_data(data d1, data d2) +{ + data d = {0}; + d.shallow = 1; + d.X = concat_matrix(d1.X, d2.X); + d.y = concat_matrix(d1.y, d2.y); + d.w = d1.w; + d.h = d1.h; + return d; +} + +data concat_datas(data *d, int n) +{ + int i; + data out = {0}; + for(i = 0; i < n; ++i){ + data new = concat_data(d[i], out); + free_data(out); + out = new; + } + return out; +} + +data load_categorical_data_csv(char *filename, int target, int k) +{ + data d = {0}; + d.shallow = 0; + matrix X = csv_to_matrix(filename); + float *truth_1d = pop_column(&X, target); + float **truth = one_hot_encode(truth_1d, X.rows, k); + matrix y; + y.rows = X.rows; + y.cols = k; + y.vals = truth; + d.X = X; + d.y = y; + free(truth_1d); + return d; +} + +data load_cifar10_data(char *filename) +{ + data d = {0}; + d.shallow = 0; + long i,j; + matrix X = make_matrix(10000, 3072); + matrix y = make_matrix(10000, 10); + d.X = X; + d.y = y; + + FILE *fp = fopen(filename, "rb"); + if(!fp) file_error(filename); + for(i = 0; i < 10000; ++i){ + unsigned char bytes[3073]; + fread(bytes, 1, 3073, fp); + int class = bytes[0]; + y.vals[i][class] = 1; + for(j = 0; j < X.cols; ++j){ + X.vals[i][j] = (double)bytes[j+1]; + } + } + scale_data_rows(d, 1./255); + //normalize_data_rows(d); + fclose(fp); + return d; +} + +void get_random_batch(data d, int n, float *X, float *y) +{ + int j; + for(j = 0; j < n; ++j){ + int index = rand()%d.X.rows; + memcpy(X+j*d.X.cols, d.X.vals[index], d.X.cols*sizeof(float)); + memcpy(y+j*d.y.cols, d.y.vals[index], d.y.cols*sizeof(float)); + } +} + +void get_next_batch(data d, int n, int offset, float *X, float *y) +{ + int j; + for(j = 0; j < n; ++j){ + int index = offset + j; + memcpy(X+j*d.X.cols, d.X.vals[index], d.X.cols*sizeof(float)); + if(y) memcpy(y+j*d.y.cols, d.y.vals[index], d.y.cols*sizeof(float)); + } +} + +void smooth_data(data d) +{ + int i, j; + float scale = 1. / d.y.cols; + float eps = .1; + for(i = 0; i < d.y.rows; ++i){ + for(j = 0; j < d.y.cols; ++j){ + d.y.vals[i][j] = eps * scale + (1-eps) * d.y.vals[i][j]; + } + } +} + +data load_all_cifar10() +{ + data d = {0}; + d.shallow = 0; + int i,j,b; + matrix X = make_matrix(50000, 3072); + matrix y = make_matrix(50000, 10); + d.X = X; + d.y = y; + + + for(b = 0; b < 5; ++b){ + char buff[256]; + sprintf(buff, "data/cifar/cifar-10-batches-bin/data_batch_%d.bin", b+1); + FILE *fp = fopen(buff, "rb"); + if(!fp) file_error(buff); + for(i = 0; i < 10000; ++i){ + unsigned char bytes[3073]; + fread(bytes, 1, 3073, fp); + int class = bytes[0]; + y.vals[i+b*10000][class] = 1; + for(j = 0; j < X.cols; ++j){ + X.vals[i+b*10000][j] = (double)bytes[j+1]; + } + } + fclose(fp); + } + //normalize_data_rows(d); + scale_data_rows(d, 1./255); + smooth_data(d); + return d; +} + +data load_go(char *filename) +{ + FILE *fp = fopen(filename, "rb"); + matrix X = make_matrix(3363059, 361); + matrix y = make_matrix(3363059, 361); + int row, col; + + if(!fp) file_error(filename); + char *label; + int count = 0; + while((label = fgetl(fp))){ + int i; + if(count == X.rows){ + X = resize_matrix(X, count*2); + y = resize_matrix(y, count*2); + } + sscanf(label, "%d %d", &row, &col); + char *board = fgetl(fp); + + int index = row*19 + col; + y.vals[count][index] = 1; + + for(i = 0; i < 19*19; ++i){ + float val = 0; + if(board[i] == '1') val = 1; + else if(board[i] == '2') val = -1; + X.vals[count][i] = val; + } + ++count; + free(label); + free(board); + } + X = resize_matrix(X, count); + y = resize_matrix(y, count); + + data d = {0}; + d.shallow = 0; + d.X = X; + d.y = y; + + + fclose(fp); + + return d; +} + + +void randomize_data(data d) +{ + int i; + for(i = d.X.rows-1; i > 0; --i){ + int index = rand()%i; + float *swap = d.X.vals[index]; + d.X.vals[index] = d.X.vals[i]; + d.X.vals[i] = swap; + + swap = d.y.vals[index]; + d.y.vals[index] = d.y.vals[i]; + d.y.vals[i] = swap; + } +} + +void scale_data_rows(data d, float s) +{ + int i; + for(i = 0; i < d.X.rows; ++i){ + scale_array(d.X.vals[i], d.X.cols, s); + } +} + +void translate_data_rows(data d, float s) +{ + int i; + for(i = 0; i < d.X.rows; ++i){ + translate_array(d.X.vals[i], d.X.cols, s); + } +} + +data copy_data(data d) +{ + data c = {0}; + c.w = d.w; + c.h = d.h; + c.shallow = 0; + c.num_boxes = d.num_boxes; + c.boxes = d.boxes; + c.X = copy_matrix(d.X); + c.y = copy_matrix(d.y); + return c; +} + +void normalize_data_rows(data d) +{ + int i; + for(i = 0; i < d.X.rows; ++i){ + normalize_array(d.X.vals[i], d.X.cols); + } +} + +data get_data_part(data d, int part, int total) +{ + data p = {0}; + p.shallow = 1; + p.X.rows = d.X.rows * (part + 1) / total - d.X.rows * part / total; + p.y.rows = d.y.rows * (part + 1) / total - d.y.rows * part / total; + p.X.cols = d.X.cols; + p.y.cols = d.y.cols; + p.X.vals = d.X.vals + d.X.rows * part / total; + p.y.vals = d.y.vals + d.y.rows * part / total; + return p; +} + +data get_random_data(data d, int num) +{ + data r = {0}; + r.shallow = 1; + + r.X.rows = num; + r.y.rows = num; + + r.X.cols = d.X.cols; + r.y.cols = d.y.cols; + + r.X.vals = calloc(num, sizeof(float *)); + r.y.vals = calloc(num, sizeof(float *)); + + int i; + for(i = 0; i < num; ++i){ + int index = rand()%d.X.rows; + r.X.vals[i] = d.X.vals[index]; + r.y.vals[i] = d.y.vals[index]; + } + return r; +} + +data *split_data(data d, int part, int total) +{ + data *split = calloc(2, sizeof(data)); + int i; + int start = part*d.X.rows/total; + int end = (part+1)*d.X.rows/total; + data train; + data test; + train.shallow = test.shallow = 1; + + test.X.rows = test.y.rows = end-start; + train.X.rows = train.y.rows = d.X.rows - (end-start); + train.X.cols = test.X.cols = d.X.cols; + train.y.cols = test.y.cols = d.y.cols; + + train.X.vals = calloc(train.X.rows, sizeof(float*)); + test.X.vals = calloc(test.X.rows, sizeof(float*)); + train.y.vals = calloc(train.y.rows, sizeof(float*)); + test.y.vals = calloc(test.y.rows, sizeof(float*)); + + for(i = 0; i < start; ++i){ + train.X.vals[i] = d.X.vals[i]; + train.y.vals[i] = d.y.vals[i]; + } + for(i = start; i < end; ++i){ + test.X.vals[i-start] = d.X.vals[i]; + test.y.vals[i-start] = d.y.vals[i]; + } + for(i = end; i < d.X.rows; ++i){ + train.X.vals[i-(end-start)] = d.X.vals[i]; + train.y.vals[i-(end-start)] = d.y.vals[i]; + } + split[0] = train; + split[1] = test; + return split; +} + diff --git a/hanzi_detection/src/data.h b/hanzi_detection/src/data.h new file mode 100755 index 0000000..781906f --- /dev/null +++ b/hanzi_detection/src/data.h @@ -0,0 +1,50 @@ +#ifndef DATA_H +#define DATA_H +#include + +#include "darknet.h" +#include "matrix.h" +#include "list.h" +#include "image.h" +#include "tree.h" + +static inline float distance_from_edge(int x, int max) +{ + int dx = (max/2) - x; + if (dx < 0) dx = -dx; + dx = (max/2) + 1 - dx; + dx *= 2; + float dist = (float)dx/max; + if (dist > 1) dist = 1; + return dist; +} +void load_data_blocking(load_args args); + + +void print_letters(float *pred, int n); +data load_data_captcha(char **paths, int n, int m, int k, int w, int h); +data load_data_captcha_encode(char **paths, int n, int m, int w, int h); +data load_data_detection(int n, char **paths, int m, int w, int h, int boxes, int classes, float jitter, float hue, float saturation, float exposure); +data load_data_tag(char **paths, int n, int m, int k, int min, int max, int size, float angle, float aspect, float hue, float saturation, float exposure); +matrix load_image_augment_paths(char **paths, int n, int min, int max, int size, float angle, float aspect, float hue, float saturation, float exposure, int center); +data load_data_super(char **paths, int n, int m, int w, int h, int scale); +data load_data_augment(char **paths, int n, int m, char **labels, int k, tree *hierarchy, int min, int max, int size, float angle, float aspect, float hue, float saturation, float exposure, int center); +data load_data_regression(char **paths, int n, int m, int classes, int min, int max, int size, float angle, float aspect, float hue, float saturation, float exposure); +data load_go(char *filename); + + +data load_data_writing(char **paths, int n, int m, int w, int h, int out_w, int out_h); + +void get_random_batch(data d, int n, float *X, float *y); +data get_data_part(data d, int part, int total); +data get_random_data(data d, int num); +data load_categorical_data_csv(char *filename, int target, int k); +void normalize_data_rows(data d); +void scale_data_rows(data d, float s); +void translate_data_rows(data d, float s); +void randomize_data(data d); +data *split_data(data d, int part, int total); +data concat_datas(data *d, int n); +void fill_truth(char *path, char **labels, int k, float *truth); + +#endif diff --git a/hanzi_detection/src/deconvolutional_kernels.cu b/hanzi_detection/src/deconvolutional_kernels.cu new file mode 100755 index 0000000..8267dcf --- /dev/null +++ b/hanzi_detection/src/deconvolutional_kernels.cu @@ -0,0 +1,139 @@ +#include "cuda_runtime.h" +#include "curand.h" +#include "cublas_v2.h" + +extern "C" { +#include "convolutional_layer.h" +#include "deconvolutional_layer.h" +#include "batchnorm_layer.h" +#include "gemm.h" +#include "blas.h" +#include "im2col.h" +#include "col2im.h" +#include "utils.h" +#include "cuda.h" +} + +extern "C" void forward_deconvolutional_layer_gpu(layer l, network net) +{ + int i; + + int m = l.size*l.size*l.n; + int n = l.h*l.w; + int k = l.c; + + fill_gpu(l.outputs*l.batch, 0, l.output_gpu, 1); + + for(i = 0; i < l.batch; ++i){ + float *a = l.weights_gpu; + float *b = net.input_gpu + i*l.c*l.h*l.w; + float *c = net.workspace; + + gemm_gpu(1,0,m,n,k,1,a,m,b,n,0,c,n); + + col2im_gpu(net.workspace, l.out_c, l.out_h, l.out_w, l.size, l.stride, l.pad, l.output_gpu+i*l.outputs); + } + if (l.batch_normalize) { + forward_batchnorm_layer_gpu(l, net); + } else { + add_bias_gpu(l.output_gpu, l.biases_gpu, l.batch, l.n, l.out_w*l.out_h); + } + activate_array_gpu(l.output_gpu, l.batch*l.n*l.out_w*l.out_h, l.activation); +} + +extern "C" void backward_deconvolutional_layer_gpu(layer l, network net) +{ + int i; + + //constrain_gpu(l.outputs*l.batch, 1, l.delta_gpu, 1); + gradient_array_gpu(l.output_gpu, l.outputs*l.batch, l.activation, l.delta_gpu); + + if(l.batch_normalize){ + backward_batchnorm_layer_gpu(l, net); + } else { + backward_bias_gpu(l.bias_updates_gpu, l.delta_gpu, l.batch, l.n, l.out_w*l.out_h); + } + + //if(net.delta_gpu) memset(net.delta_gpu, 0, l.batch*l.h*l.w*l.c*sizeof(float)); + + for(i = 0; i < l.batch; ++i){ + int m = l.c; + int n = l.size*l.size*l.n; + int k = l.h*l.w; + + float *a = net.input_gpu + i*m*k; + float *b = net.workspace; + float *c = l.weight_updates_gpu; + + im2col_gpu(l.delta_gpu + i*l.outputs, l.out_c, l.out_h, l.out_w, + l.size, l.stride, l.pad, b); + gemm_gpu(0,1,m,n,k,1,a,k,b,k,1,c,n); + + if(net.delta_gpu){ + int m = l.c; + int n = l.h*l.w; + int k = l.size*l.size*l.n; + + float *a = l.weights_gpu; + float *b = net.workspace; + float *c = net.delta_gpu + i*n*m; + + gemm_gpu(0,0,m,n,k,1,a,k,b,n,1,c,n); + } + } +} + +extern "C" void pull_deconvolutional_layer(layer l) +{ + cuda_pull_array(l.weights_gpu, l.weights, l.c*l.n*l.size*l.size); + cuda_pull_array(l.biases_gpu, l.biases, l.n); + cuda_pull_array(l.weight_updates_gpu, l.weight_updates, l.c*l.n*l.size*l.size); + cuda_pull_array(l.bias_updates_gpu, l.bias_updates, l.n); + if (l.batch_normalize){ + cuda_pull_array(l.scales_gpu, l.scales, l.n); + cuda_pull_array(l.rolling_mean_gpu, l.rolling_mean, l.n); + cuda_pull_array(l.rolling_variance_gpu, l.rolling_variance, l.n); + } +} + +extern "C" void push_deconvolutional_layer(layer l) +{ + cuda_push_array(l.weights_gpu, l.weights, l.c*l.n*l.size*l.size); + cuda_push_array(l.biases_gpu, l.biases, l.n); + cuda_push_array(l.weight_updates_gpu, l.weight_updates, l.c*l.n*l.size*l.size); + cuda_push_array(l.bias_updates_gpu, l.bias_updates, l.n); + if (l.batch_normalize){ + cuda_push_array(l.scales_gpu, l.scales, l.n); + cuda_push_array(l.rolling_mean_gpu, l.rolling_mean, l.n); + cuda_push_array(l.rolling_variance_gpu, l.rolling_variance, l.n); + } +} + +void update_deconvolutional_layer_gpu(layer l, update_args a) +{ + float learning_rate = a.learning_rate*l.learning_rate_scale; + float momentum = a.momentum; + float decay = a.decay; + int batch = a.batch; + + if(a.adam){ + adam_update_gpu(l.weights_gpu, l.weight_updates_gpu, l.m_gpu, l.v_gpu, a.B1, a.B2, a.eps, decay, learning_rate, l.nweights, batch, a.t); + adam_update_gpu(l.biases_gpu, l.bias_updates_gpu, l.bias_m_gpu, l.bias_v_gpu, a.B1, a.B2, a.eps, decay, learning_rate, l.n, batch, a.t); + if(l.scales_gpu){ + adam_update_gpu(l.scales_gpu, l.scale_updates_gpu, l.scale_m_gpu, l.scale_v_gpu, a.B1, a.B2, a.eps, decay, learning_rate, l.n, batch, a.t); + } + }else{ + axpy_gpu(l.nweights, -decay*batch, l.weights_gpu, 1, l.weight_updates_gpu, 1); + axpy_gpu(l.nweights, learning_rate/batch, l.weight_updates_gpu, 1, l.weights_gpu, 1); + scal_gpu(l.nweights, momentum, l.weight_updates_gpu, 1); + + axpy_gpu(l.n, learning_rate/batch, l.bias_updates_gpu, 1, l.biases_gpu, 1); + scal_gpu(l.n, momentum, l.bias_updates_gpu, 1); + + if(l.scales_gpu){ + axpy_gpu(l.n, learning_rate/batch, l.scale_updates_gpu, 1, l.scales_gpu, 1); + scal_gpu(l.n, momentum, l.scale_updates_gpu, 1); + } + } +} + diff --git a/hanzi_detection/src/deconvolutional_layer.c b/hanzi_detection/src/deconvolutional_layer.c new file mode 100755 index 0000000..00c0e85 --- /dev/null +++ b/hanzi_detection/src/deconvolutional_layer.c @@ -0,0 +1,312 @@ +#include "deconvolutional_layer.h" +#include "convolutional_layer.h" +#include "batchnorm_layer.h" +#include "utils.h" +#include "im2col.h" +#include "col2im.h" +#include "blas.h" +#include "gemm.h" + +#include +#include + + +static size_t get_workspace_size(layer l){ + return (size_t)l.h*l.w*l.size*l.size*l.n*sizeof(float); +} + +void bilinear_init(layer l) +{ + int i,j,f; + float center = (l.size-1) / 2.; + for(f = 0; f < l.n; ++f){ + for(j = 0; j < l.size; ++j){ + for(i = 0; i < l.size; ++i){ + float val = (1 - fabs(i - center)) * (1 - fabs(j - center)); + int c = f%l.c; + int ind = f*l.size*l.size*l.c + c*l.size*l.size + j*l.size + i; + l.weights[ind] = val; + } + } + } +} + + +layer make_deconvolutional_layer(int batch, int h, int w, int c, int n, int size, int stride, int padding, ACTIVATION activation, int batch_normalize, int adam) +{ + int i; + layer l = {0}; + l.type = DECONVOLUTIONAL; + + l.h = h; + l.w = w; + l.c = c; + l.n = n; + l.batch = batch; + l.stride = stride; + l.size = size; + + l.nweights = c*n*size*size; + l.nbiases = n; + + l.weights = calloc(c*n*size*size, sizeof(float)); + l.weight_updates = calloc(c*n*size*size, sizeof(float)); + + l.biases = calloc(n, sizeof(float)); + l.bias_updates = calloc(n, sizeof(float)); + //float scale = n/(size*size*c); + //printf("scale: %f\n", scale); + float scale = .02; + for(i = 0; i < c*n*size*size; ++i) l.weights[i] = scale*rand_normal(); + //bilinear_init(l); + for(i = 0; i < n; ++i){ + l.biases[i] = 0; + } + l.pad = padding; + + l.out_h = (l.h - 1) * l.stride + l.size - 2*l.pad; + l.out_w = (l.w - 1) * l.stride + l.size - 2*l.pad; + l.out_c = n; + l.outputs = l.out_w * l.out_h * l.out_c; + l.inputs = l.w * l.h * l.c; + + scal_cpu(l.nweights, (float)l.out_w*l.out_h/(l.w*l.h), l.weights, 1); + + l.output = calloc(l.batch*l.outputs, sizeof(float)); + l.delta = calloc(l.batch*l.outputs, sizeof(float)); + + l.forward = forward_deconvolutional_layer; + l.backward = backward_deconvolutional_layer; + l.update = update_deconvolutional_layer; + + l.batch_normalize = batch_normalize; + + if(batch_normalize){ + l.scales = calloc(n, sizeof(float)); + l.scale_updates = calloc(n, sizeof(float)); + for(i = 0; i < n; ++i){ + l.scales[i] = 1; + } + + l.mean = calloc(n, sizeof(float)); + l.variance = calloc(n, sizeof(float)); + + l.mean_delta = calloc(n, sizeof(float)); + l.variance_delta = calloc(n, sizeof(float)); + + l.rolling_mean = calloc(n, sizeof(float)); + l.rolling_variance = calloc(n, sizeof(float)); + l.x = calloc(l.batch*l.outputs, sizeof(float)); + l.x_norm = calloc(l.batch*l.outputs, sizeof(float)); + } + if(adam){ + l.m = calloc(c*n*size*size, sizeof(float)); + l.v = calloc(c*n*size*size, sizeof(float)); + l.bias_m = calloc(n, sizeof(float)); + l.scale_m = calloc(n, sizeof(float)); + l.bias_v = calloc(n, sizeof(float)); + l.scale_v = calloc(n, sizeof(float)); + } + +#ifdef GPU + l.forward_gpu = forward_deconvolutional_layer_gpu; + l.backward_gpu = backward_deconvolutional_layer_gpu; + l.update_gpu = update_deconvolutional_layer_gpu; + + if(gpu_index >= 0){ + + if (adam) { + l.m_gpu = cuda_make_array(l.m, c*n*size*size); + l.v_gpu = cuda_make_array(l.v, c*n*size*size); + l.bias_m_gpu = cuda_make_array(l.bias_m, n); + l.bias_v_gpu = cuda_make_array(l.bias_v, n); + l.scale_m_gpu = cuda_make_array(l.scale_m, n); + l.scale_v_gpu = cuda_make_array(l.scale_v, n); + } + l.weights_gpu = cuda_make_array(l.weights, c*n*size*size); + l.weight_updates_gpu = cuda_make_array(l.weight_updates, c*n*size*size); + + l.biases_gpu = cuda_make_array(l.biases, n); + l.bias_updates_gpu = cuda_make_array(l.bias_updates, n); + + l.delta_gpu = cuda_make_array(l.delta, l.batch*l.out_h*l.out_w*n); + l.output_gpu = cuda_make_array(l.output, l.batch*l.out_h*l.out_w*n); + + if(batch_normalize){ + l.mean_gpu = cuda_make_array(0, n); + l.variance_gpu = cuda_make_array(0, n); + + l.rolling_mean_gpu = cuda_make_array(0, n); + l.rolling_variance_gpu = cuda_make_array(0, n); + + l.mean_delta_gpu = cuda_make_array(0, n); + l.variance_delta_gpu = cuda_make_array(0, n); + + l.scales_gpu = cuda_make_array(l.scales, n); + l.scale_updates_gpu = cuda_make_array(0, n); + + l.x_gpu = cuda_make_array(0, l.batch*l.out_h*l.out_w*n); + l.x_norm_gpu = cuda_make_array(0, l.batch*l.out_h*l.out_w*n); + } + } + #ifdef CUDNN + cudnnCreateTensorDescriptor(&l.dstTensorDesc); + cudnnCreateTensorDescriptor(&l.normTensorDesc); + cudnnSetTensor4dDescriptor(l.dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, l.batch, l.out_c, l.out_h, l.out_w); + cudnnSetTensor4dDescriptor(l.normTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, 1, l.out_c, 1, 1); + #endif +#endif + + l.activation = activation; + l.workspace_size = get_workspace_size(l); + + fprintf(stderr, "deconv%5d %2d x%2d /%2d %4d x%4d x%4d -> %4d x%4d x%4d\n", n, size, size, stride, w, h, c, l.out_w, l.out_h, l.out_c); + + return l; +} + +void denormalize_deconvolutional_layer(layer l) +{ + int i, j; + for(i = 0; i < l.n; ++i){ + float scale = l.scales[i]/sqrt(l.rolling_variance[i] + .00001); + for(j = 0; j < l.c*l.size*l.size; ++j){ + l.weights[i*l.c*l.size*l.size + j] *= scale; + } + l.biases[i] -= l.rolling_mean[i] * scale; + l.scales[i] = 1; + l.rolling_mean[i] = 0; + l.rolling_variance[i] = 1; + } +} + +void resize_deconvolutional_layer(layer *l, int h, int w) +{ + l->h = h; + l->w = w; + l->out_h = (l->h - 1) * l->stride + l->size - 2*l->pad; + l->out_w = (l->w - 1) * l->stride + l->size - 2*l->pad; + + l->outputs = l->out_h * l->out_w * l->out_c; + l->inputs = l->w * l->h * l->c; + + l->output = realloc(l->output, l->batch*l->outputs*sizeof(float)); + l->delta = realloc(l->delta, l->batch*l->outputs*sizeof(float)); + if(l->batch_normalize){ + l->x = realloc(l->x, l->batch*l->outputs*sizeof(float)); + l->x_norm = realloc(l->x_norm, l->batch*l->outputs*sizeof(float)); + } + +#ifdef GPU + cuda_free(l->delta_gpu); + cuda_free(l->output_gpu); + + l->delta_gpu = cuda_make_array(l->delta, l->batch*l->outputs); + l->output_gpu = cuda_make_array(l->output, l->batch*l->outputs); + + if(l->batch_normalize){ + cuda_free(l->x_gpu); + cuda_free(l->x_norm_gpu); + + l->x_gpu = cuda_make_array(l->output, l->batch*l->outputs); + l->x_norm_gpu = cuda_make_array(l->output, l->batch*l->outputs); + } + #ifdef CUDNN + cudnnSetTensor4dDescriptor(l->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, l->batch, l->out_c, l->out_h, l->out_w); + cudnnSetTensor4dDescriptor(l->normTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, 1, l->out_c, 1, 1); + #endif +#endif + l->workspace_size = get_workspace_size(*l); +} + +void forward_deconvolutional_layer(const layer l, network net) +{ + int i; + + int m = l.size*l.size*l.n; + int n = l.h*l.w; + int k = l.c; + + fill_cpu(l.outputs*l.batch, 0, l.output, 1); + + for(i = 0; i < l.batch; ++i){ + float *a = l.weights; + float *b = net.input + i*l.c*l.h*l.w; + float *c = net.workspace; + + gemm_cpu(1,0,m,n,k,1,a,m,b,n,0,c,n); + + col2im_cpu(net.workspace, l.out_c, l.out_h, l.out_w, l.size, l.stride, l.pad, l.output+i*l.outputs); + } + if (l.batch_normalize) { + forward_batchnorm_layer(l, net); + } else { + add_bias(l.output, l.biases, l.batch, l.n, l.out_w*l.out_h); + } + activate_array(l.output, l.batch*l.n*l.out_w*l.out_h, l.activation); +} + +void backward_deconvolutional_layer(layer l, network net) +{ + int i; + + gradient_array(l.output, l.outputs*l.batch, l.activation, l.delta); + + if(l.batch_normalize){ + backward_batchnorm_layer(l, net); + } else { + backward_bias(l.bias_updates, l.delta, l.batch, l.n, l.out_w*l.out_h); + } + + //if(net.delta) memset(net.delta, 0, l.batch*l.h*l.w*l.c*sizeof(float)); + + for(i = 0; i < l.batch; ++i){ + int m = l.c; + int n = l.size*l.size*l.n; + int k = l.h*l.w; + + float *a = net.input + i*m*k; + float *b = net.workspace; + float *c = l.weight_updates; + + im2col_cpu(l.delta + i*l.outputs, l.out_c, l.out_h, l.out_w, + l.size, l.stride, l.pad, b); + gemm_cpu(0,1,m,n,k,1,a,k,b,k,1,c,n); + + if(net.delta){ + int m = l.c; + int n = l.h*l.w; + int k = l.size*l.size*l.n; + + float *a = l.weights; + float *b = net.workspace; + float *c = net.delta + i*n*m; + + gemm_cpu(0,0,m,n,k,1,a,k,b,n,1,c,n); + } + } +} + +void update_deconvolutional_layer(layer l, update_args a) +{ + float learning_rate = a.learning_rate*l.learning_rate_scale; + float momentum = a.momentum; + float decay = a.decay; + int batch = a.batch; + + int size = l.size*l.size*l.c*l.n; + axpy_cpu(l.n, learning_rate/batch, l.bias_updates, 1, l.biases, 1); + scal_cpu(l.n, momentum, l.bias_updates, 1); + + if(l.scales){ + axpy_cpu(l.n, learning_rate/batch, l.scale_updates, 1, l.scales, 1); + scal_cpu(l.n, momentum, l.scale_updates, 1); + } + + axpy_cpu(size, -decay*batch, l.weights, 1, l.weight_updates, 1); + axpy_cpu(size, learning_rate/batch, l.weight_updates, 1, l.weights, 1); + scal_cpu(size, momentum, l.weight_updates, 1); +} + + + diff --git a/hanzi_detection/src/deconvolutional_layer.h b/hanzi_detection/src/deconvolutional_layer.h new file mode 100755 index 0000000..b254fb9 --- /dev/null +++ b/hanzi_detection/src/deconvolutional_layer.h @@ -0,0 +1,25 @@ +#ifndef DECONVOLUTIONAL_LAYER_H +#define DECONVOLUTIONAL_LAYER_H + +#include "cuda.h" +#include "image.h" +#include "activations.h" +#include "layer.h" +#include "network.h" + +#ifdef GPU +void forward_deconvolutional_layer_gpu(layer l, network net); +void backward_deconvolutional_layer_gpu(layer l, network net); +void update_deconvolutional_layer_gpu(layer l, update_args a); +void push_deconvolutional_layer(layer l); +void pull_deconvolutional_layer(layer l); +#endif + +layer make_deconvolutional_layer(int batch, int h, int w, int c, int n, int size, int stride, int padding, ACTIVATION activation, int batch_normalize, int adam); +void resize_deconvolutional_layer(layer *l, int h, int w); +void forward_deconvolutional_layer(const layer l, network net); +void update_deconvolutional_layer(layer l, update_args a); +void backward_deconvolutional_layer(layer l, network net); + +#endif + diff --git a/hanzi_detection/src/demo.c b/hanzi_detection/src/demo.c new file mode 100755 index 0000000..b89efb8 --- /dev/null +++ b/hanzi_detection/src/demo.c @@ -0,0 +1,349 @@ +#include "network.h" +#include "detection_layer.h" +#include "region_layer.h" +#include "cost_layer.h" +#include "utils.h" +#include "parser.h" +#include "box.h" +#include "image.h" +#include "demo.h" +#include + +#define DEMO 1 + +#ifdef OPENCV + +static char **demo_names; +static image **demo_alphabet; +static int demo_classes; + +static network *net; +static image buff [3]; +static image buff_letter[3]; +static int buff_index = 0; +static void * cap; +static float fps = 0; +static float demo_thresh = 0; +static float demo_hier = .5; +static int running = 0; + +static int demo_frame = 3; +static int demo_index = 0; +static float **predictions; +static float *avg; +static int demo_done = 0; +static int demo_total = 0; +double demo_time; + +detection *get_network_boxes(network *net, int w, int h, float thresh, float hier, int *map, int relative, int *num); + +int size_network(network *net) +{ + int i; + int count = 0; + for(i = 0; i < net->n; ++i){ + layer l = net->layers[i]; + if(l.type == YOLO || l.type == REGION || l.type == DETECTION){ + count += l.outputs; + } + } + return count; +} + +void remember_network(network *net) +{ + int i; + int count = 0; + for(i = 0; i < net->n; ++i){ + layer l = net->layers[i]; + if(l.type == YOLO || l.type == REGION || l.type == DETECTION){ + memcpy(predictions[demo_index] + count, net->layers[i].output, sizeof(float) * l.outputs); + count += l.outputs; + } + } +} + +detection *avg_predictions(network *net, int *nboxes) +{ + int i, j; + int count = 0; + fill_cpu(demo_total, 0, avg, 1); + for(j = 0; j < demo_frame; ++j){ + axpy_cpu(demo_total, 1./demo_frame, predictions[j], 1, avg, 1); + } + for(i = 0; i < net->n; ++i){ + layer l = net->layers[i]; + if(l.type == YOLO || l.type == REGION || l.type == DETECTION){ + memcpy(l.output, avg + count, sizeof(float) * l.outputs); + count += l.outputs; + } + } + detection *dets = get_network_boxes(net, buff[0].w, buff[0].h, demo_thresh, demo_hier, 0, 1, nboxes); + return dets; +} + +void *detect_in_thread(void *ptr) +{ + running = 1; + float nms = .4; + + layer l = net->layers[net->n-1]; + float *X = buff_letter[(buff_index+2)%3].data; + network_predict(net, X); + + /* + if(l.type == DETECTION){ + get_detection_boxes(l, 1, 1, demo_thresh, probs, boxes, 0); + } else */ + remember_network(net); + detection *dets = 0; + int nboxes = 0; + dets = avg_predictions(net, &nboxes); + + + /* + int i,j; + box zero = {0}; + int classes = l.classes; + for(i = 0; i < demo_detections; ++i){ + avg[i].objectness = 0; + avg[i].bbox = zero; + memset(avg[i].prob, 0, classes*sizeof(float)); + for(j = 0; j < demo_frame; ++j){ + axpy_cpu(classes, 1./demo_frame, dets[j][i].prob, 1, avg[i].prob, 1); + avg[i].objectness += dets[j][i].objectness * 1./demo_frame; + avg[i].bbox.x += dets[j][i].bbox.x * 1./demo_frame; + avg[i].bbox.y += dets[j][i].bbox.y * 1./demo_frame; + avg[i].bbox.w += dets[j][i].bbox.w * 1./demo_frame; + avg[i].bbox.h += dets[j][i].bbox.h * 1./demo_frame; + } + //copy_cpu(classes, dets[0][i].prob, 1, avg[i].prob, 1); + //avg[i].objectness = dets[0][i].objectness; + } + */ + + if (nms > 0) do_nms_obj(dets, nboxes, l.classes, nms); + + printf("\033[2J"); + printf("\033[1;1H"); + printf("\nFPS:%.1f\n",fps); + printf("Objects:\n\n"); + image display = buff[(buff_index+2) % 3]; + draw_detections(display, dets, nboxes, demo_thresh, demo_names, demo_alphabet, demo_classes); + free_detections(dets, nboxes); + + demo_index = (demo_index + 1)%demo_frame; + running = 0; + return 0; +} + +void *fetch_in_thread(void *ptr) +{ + free_image(buff[buff_index]); + buff[buff_index] = get_image_from_stream(cap); + if(buff[buff_index].data == 0) { + demo_done = 1; + return 0; + } + letterbox_image_into(buff[buff_index], net->w, net->h, buff_letter[buff_index]); + return 0; +} + +void *display_in_thread(void *ptr) +{ + int c = show_image(buff[(buff_index + 1)%3], "Demo", 1); + if (c != -1) c = c%256; + if (c == 27) { + demo_done = 1; + return 0; + } else if (c == 82) { + demo_thresh += .02; + } else if (c == 84) { + demo_thresh -= .02; + if(demo_thresh <= .02) demo_thresh = .02; + } else if (c == 83) { + demo_hier += .02; + } else if (c == 81) { + demo_hier -= .02; + if(demo_hier <= .0) demo_hier = .0; + } + return 0; +} + +void *display_loop(void *ptr) +{ + while(1){ + display_in_thread(0); + } +} + +void *detect_loop(void *ptr) +{ + while(1){ + detect_in_thread(0); + } +} + +void demo(char *cfgfile, char *weightfile, float thresh, int cam_index, const char *filename, char **names, int classes, int delay, char *prefix, int avg_frames, float hier, int w, int h, int frames, int fullscreen) +{ + //demo_frame = avg_frames; + image **alphabet = load_alphabet(); + demo_names = names; + demo_alphabet = alphabet; + demo_classes = classes; + demo_thresh = thresh; + demo_hier = hier; + printf("Demo\n"); + net = load_network(cfgfile, weightfile, 0); + set_batch_network(net, 1); + pthread_t detect_thread; + pthread_t fetch_thread; + + srand(2222222); + + int i; + demo_total = size_network(net); + predictions = calloc(demo_frame, sizeof(float*)); + for (i = 0; i < demo_frame; ++i){ + predictions[i] = calloc(demo_total, sizeof(float)); + } + avg = calloc(demo_total, sizeof(float)); + + if(filename){ + printf("video file: %s\n", filename); + cap = open_video_stream(filename, 0, 0, 0, 0); + }else{ + cap = open_video_stream(0, cam_index, w, h, frames); + } + + if(!cap) error("Couldn't connect to webcam.\n"); + + buff[0] = get_image_from_stream(cap); + buff[1] = copy_image(buff[0]); + buff[2] = copy_image(buff[0]); + buff_letter[0] = letterbox_image(buff[0], net->w, net->h); + buff_letter[1] = letterbox_image(buff[0], net->w, net->h); + buff_letter[2] = letterbox_image(buff[0], net->w, net->h); + + int count = 0; + if(!prefix){ + make_window("Demo", 1352, 1013, fullscreen); + } + + demo_time = what_time_is_it_now(); + + while(!demo_done){ + buff_index = (buff_index + 1) %3; + if(pthread_create(&fetch_thread, 0, fetch_in_thread, 0)) error("Thread creation failed"); + if(pthread_create(&detect_thread, 0, detect_in_thread, 0)) error("Thread creation failed"); + if(!prefix){ + fps = 1./(what_time_is_it_now() - demo_time); + demo_time = what_time_is_it_now(); + display_in_thread(0); + }else{ + char name[256]; + sprintf(name, "%s_%08d", prefix, count); + save_image(buff[(buff_index + 1)%3], name); + } + pthread_join(fetch_thread, 0); + pthread_join(detect_thread, 0); + ++count; + } +} + +/* + void demo_compare(char *cfg1, char *weight1, char *cfg2, char *weight2, float thresh, int cam_index, const char *filename, char **names, int classes, int delay, char *prefix, int avg_frames, float hier, int w, int h, int frames, int fullscreen) + { + demo_frame = avg_frames; + predictions = calloc(demo_frame, sizeof(float*)); + image **alphabet = load_alphabet(); + demo_names = names; + demo_alphabet = alphabet; + demo_classes = classes; + demo_thresh = thresh; + demo_hier = hier; + printf("Demo\n"); + net = load_network(cfg1, weight1, 0); + set_batch_network(net, 1); + pthread_t detect_thread; + pthread_t fetch_thread; + + srand(2222222); + + if(filename){ + printf("video file: %s\n", filename); + cap = cvCaptureFromFile(filename); + }else{ + cap = cvCaptureFromCAM(cam_index); + + if(w){ + cvSetCaptureProperty(cap, CV_CAP_PROP_FRAME_WIDTH, w); + } + if(h){ + cvSetCaptureProperty(cap, CV_CAP_PROP_FRAME_HEIGHT, h); + } + if(frames){ + cvSetCaptureProperty(cap, CV_CAP_PROP_FPS, frames); + } + } + + if(!cap) error("Couldn't connect to webcam.\n"); + + layer l = net->layers[net->n-1]; + demo_detections = l.n*l.w*l.h; + int j; + + avg = (float *) calloc(l.outputs, sizeof(float)); + for(j = 0; j < demo_frame; ++j) predictions[j] = (float *) calloc(l.outputs, sizeof(float)); + + boxes = (box *)calloc(l.w*l.h*l.n, sizeof(box)); + probs = (float **)calloc(l.w*l.h*l.n, sizeof(float *)); + for(j = 0; j < l.w*l.h*l.n; ++j) probs[j] = (float *)calloc(l.classes+1, sizeof(float)); + + buff[0] = get_image_from_stream(cap); + buff[1] = copy_image(buff[0]); + buff[2] = copy_image(buff[0]); + buff_letter[0] = letterbox_image(buff[0], net->w, net->h); + buff_letter[1] = letterbox_image(buff[0], net->w, net->h); + buff_letter[2] = letterbox_image(buff[0], net->w, net->h); + ipl = cvCreateImage(cvSize(buff[0].w,buff[0].h), IPL_DEPTH_8U, buff[0].c); + + int count = 0; + if(!prefix){ + cvNamedWindow("Demo", CV_WINDOW_NORMAL); + if(fullscreen){ + cvSetWindowProperty("Demo", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN); + } else { + cvMoveWindow("Demo", 0, 0); + cvResizeWindow("Demo", 1352, 1013); + } + } + + demo_time = what_time_is_it_now(); + + while(!demo_done){ +buff_index = (buff_index + 1) %3; +if(pthread_create(&fetch_thread, 0, fetch_in_thread, 0)) error("Thread creation failed"); +if(pthread_create(&detect_thread, 0, detect_in_thread, 0)) error("Thread creation failed"); +if(!prefix){ + fps = 1./(what_time_is_it_now() - demo_time); + demo_time = what_time_is_it_now(); + display_in_thread(0); +}else{ + char name[256]; + sprintf(name, "%s_%08d", prefix, count); + save_image(buff[(buff_index + 1)%3], name); +} +pthread_join(fetch_thread, 0); +pthread_join(detect_thread, 0); +++count; +} +} +*/ +#else +void demo(char *cfgfile, char *weightfile, float thresh, int cam_index, const char *filename, char **names, int classes, int delay, char *prefix, int avg, float hier, int w, int h, int frames, int fullscreen) +{ + fprintf(stderr, "Demo needs OpenCV for webcam images.\n"); +} +#endif + diff --git a/hanzi_detection/src/demo.h b/hanzi_detection/src/demo.h new file mode 100755 index 0000000..86e4654 --- /dev/null +++ b/hanzi_detection/src/demo.h @@ -0,0 +1,6 @@ +#ifndef DEMO_H +#define DEMO_H + +#include "image.h" + +#endif diff --git a/hanzi_detection/src/detection_layer.c b/hanzi_detection/src/detection_layer.c new file mode 100755 index 0000000..d0e0194 --- /dev/null +++ b/hanzi_detection/src/detection_layer.c @@ -0,0 +1,275 @@ +#include "detection_layer.h" +#include "activations.h" +#include "softmax_layer.h" +#include "blas.h" +#include "box.h" +#include "cuda.h" +#include "utils.h" + +#include +#include +#include +#include + +detection_layer make_detection_layer(int batch, int inputs, int n, int side, int classes, int coords, int rescore) +{ + detection_layer l = {0}; + l.type = DETECTION; + + l.n = n; + l.batch = batch; + l.inputs = inputs; + l.classes = classes; + l.coords = coords; + l.rescore = rescore; + l.side = side; + l.w = side; + l.h = side; + assert(side*side*((1 + l.coords)*l.n + l.classes) == inputs); + l.cost = calloc(1, sizeof(float)); + l.outputs = l.inputs; + l.truths = l.side*l.side*(1+l.coords+l.classes); + l.output = calloc(batch*l.outputs, sizeof(float)); + l.delta = calloc(batch*l.outputs, sizeof(float)); + + l.forward = forward_detection_layer; + l.backward = backward_detection_layer; +#ifdef GPU + l.forward_gpu = forward_detection_layer_gpu; + l.backward_gpu = backward_detection_layer_gpu; + l.output_gpu = cuda_make_array(l.output, batch*l.outputs); + l.delta_gpu = cuda_make_array(l.delta, batch*l.outputs); +#endif + + fprintf(stderr, "Detection Layer\n"); + srand(0); + + return l; +} + +void forward_detection_layer(const detection_layer l, network net) +{ + int locations = l.side*l.side; + int i,j; + memcpy(l.output, net.input, l.outputs*l.batch*sizeof(float)); + //if(l.reorg) reorg(l.output, l.w*l.h, size*l.n, l.batch, 1); + int b; + if (l.softmax){ + for(b = 0; b < l.batch; ++b){ + int index = b*l.inputs; + for (i = 0; i < locations; ++i) { + int offset = i*l.classes; + softmax(l.output + index + offset, l.classes, 1, 1, + l.output + index + offset); + } + } + } + if(net.train){ + float avg_iou = 0; + float avg_cat = 0; + float avg_allcat = 0; + float avg_obj = 0; + float avg_anyobj = 0; + int count = 0; + *(l.cost) = 0; + int size = l.inputs * l.batch; + memset(l.delta, 0, size * sizeof(float)); + for (b = 0; b < l.batch; ++b){ + int index = b*l.inputs; + for (i = 0; i < locations; ++i) { + int truth_index = (b*locations + i)*(1+l.coords+l.classes); + int is_obj = net.truth[truth_index]; + for (j = 0; j < l.n; ++j) { + int p_index = index + locations*l.classes + i*l.n + j; + l.delta[p_index] = l.noobject_scale*(0 - l.output[p_index]); + *(l.cost) += l.noobject_scale*pow(l.output[p_index], 2); + avg_anyobj += l.output[p_index]; + } + + int best_index = -1; + float best_iou = 0; + float best_rmse = 20; + + if (!is_obj){ + continue; + } + + int class_index = index + i*l.classes; + for(j = 0; j < l.classes; ++j) { + l.delta[class_index+j] = l.class_scale * (net.truth[truth_index+1+j] - l.output[class_index+j]); + *(l.cost) += l.class_scale * pow(net.truth[truth_index+1+j] - l.output[class_index+j], 2); + if(net.truth[truth_index + 1 + j]) avg_cat += l.output[class_index+j]; + avg_allcat += l.output[class_index+j]; + } + + box truth = float_to_box(net.truth + truth_index + 1 + l.classes, 1); + truth.x /= l.side; + truth.y /= l.side; + + for(j = 0; j < l.n; ++j){ + int box_index = index + locations*(l.classes + l.n) + (i*l.n + j) * l.coords; + box out = float_to_box(l.output + box_index, 1); + out.x /= l.side; + out.y /= l.side; + + if (l.sqrt){ + out.w = out.w*out.w; + out.h = out.h*out.h; + } + + float iou = box_iou(out, truth); + //iou = 0; + float rmse = box_rmse(out, truth); + if(best_iou > 0 || iou > 0){ + if(iou > best_iou){ + best_iou = iou; + best_index = j; + } + }else{ + if(rmse < best_rmse){ + best_rmse = rmse; + best_index = j; + } + } + } + + if(l.forced){ + if(truth.w*truth.h < .1){ + best_index = 1; + }else{ + best_index = 0; + } + } + if(l.random && *(net.seen) < 64000){ + best_index = rand()%l.n; + } + + int box_index = index + locations*(l.classes + l.n) + (i*l.n + best_index) * l.coords; + int tbox_index = truth_index + 1 + l.classes; + + box out = float_to_box(l.output + box_index, 1); + out.x /= l.side; + out.y /= l.side; + if (l.sqrt) { + out.w = out.w*out.w; + out.h = out.h*out.h; + } + float iou = box_iou(out, truth); + + //printf("%d,", best_index); + int p_index = index + locations*l.classes + i*l.n + best_index; + *(l.cost) -= l.noobject_scale * pow(l.output[p_index], 2); + *(l.cost) += l.object_scale * pow(1-l.output[p_index], 2); + avg_obj += l.output[p_index]; + l.delta[p_index] = l.object_scale * (1.-l.output[p_index]); + + if(l.rescore){ + l.delta[p_index] = l.object_scale * (iou - l.output[p_index]); + } + + l.delta[box_index+0] = l.coord_scale*(net.truth[tbox_index + 0] - l.output[box_index + 0]); + l.delta[box_index+1] = l.coord_scale*(net.truth[tbox_index + 1] - l.output[box_index + 1]); + l.delta[box_index+2] = l.coord_scale*(net.truth[tbox_index + 2] - l.output[box_index + 2]); + l.delta[box_index+3] = l.coord_scale*(net.truth[tbox_index + 3] - l.output[box_index + 3]); + if(l.sqrt){ + l.delta[box_index+2] = l.coord_scale*(sqrt(net.truth[tbox_index + 2]) - l.output[box_index + 2]); + l.delta[box_index+3] = l.coord_scale*(sqrt(net.truth[tbox_index + 3]) - l.output[box_index + 3]); + } + + *(l.cost) += pow(1-iou, 2); + avg_iou += iou; + ++count; + } + } + + if(0){ + float *costs = calloc(l.batch*locations*l.n, sizeof(float)); + for (b = 0; b < l.batch; ++b) { + int index = b*l.inputs; + for (i = 0; i < locations; ++i) { + for (j = 0; j < l.n; ++j) { + int p_index = index + locations*l.classes + i*l.n + j; + costs[b*locations*l.n + i*l.n + j] = l.delta[p_index]*l.delta[p_index]; + } + } + } + int indexes[100]; + top_k(costs, l.batch*locations*l.n, 100, indexes); + float cutoff = costs[indexes[99]]; + for (b = 0; b < l.batch; ++b) { + int index = b*l.inputs; + for (i = 0; i < locations; ++i) { + for (j = 0; j < l.n; ++j) { + int p_index = index + locations*l.classes + i*l.n + j; + if (l.delta[p_index]*l.delta[p_index] < cutoff) l.delta[p_index] = 0; + } + } + } + free(costs); + } + + + *(l.cost) = pow(mag_array(l.delta, l.outputs * l.batch), 2); + + + printf("Detection Avg IOU: %f, Pos Cat: %f, All Cat: %f, Pos Obj: %f, Any Obj: %f, count: %d\n", avg_iou/count, avg_cat/count, avg_allcat/(count*l.classes), avg_obj/count, avg_anyobj/(l.batch*locations*l.n), count); + //if(l.reorg) reorg(l.delta, l.w*l.h, size*l.n, l.batch, 0); + } +} + +void backward_detection_layer(const detection_layer l, network net) +{ + axpy_cpu(l.batch*l.inputs, 1, l.delta, 1, net.delta, 1); +} + +void get_detection_detections(layer l, int w, int h, float thresh, detection *dets) +{ + int i,j,n; + float *predictions = l.output; + //int per_cell = 5*num+classes; + for (i = 0; i < l.side*l.side; ++i){ + int row = i / l.side; + int col = i % l.side; + for(n = 0; n < l.n; ++n){ + int index = i*l.n + n; + int p_index = l.side*l.side*l.classes + i*l.n + n; + float scale = predictions[p_index]; + int box_index = l.side*l.side*(l.classes + l.n) + (i*l.n + n)*4; + box b; + b.x = (predictions[box_index + 0] + col) / l.side * w; + b.y = (predictions[box_index + 1] + row) / l.side * h; + b.w = pow(predictions[box_index + 2], (l.sqrt?2:1)) * w; + b.h = pow(predictions[box_index + 3], (l.sqrt?2:1)) * h; + dets[index].bbox = b; + dets[index].objectness = scale; + for(j = 0; j < l.classes; ++j){ + int class_index = i*l.classes; + float prob = scale*predictions[class_index+j]; + dets[index].prob[j] = (prob > thresh) ? prob : 0; + } + } + } +} + +#ifdef GPU + +void forward_detection_layer_gpu(const detection_layer l, network net) +{ + if(!net.train){ + copy_gpu(l.batch*l.inputs, net.input_gpu, 1, l.output_gpu, 1); + return; + } + + cuda_pull_array(net.input_gpu, net.input, l.batch*l.inputs); + forward_detection_layer(l, net); + cuda_push_array(l.output_gpu, l.output, l.batch*l.outputs); + cuda_push_array(l.delta_gpu, l.delta, l.batch*l.inputs); +} + +void backward_detection_layer_gpu(detection_layer l, network net) +{ + axpy_gpu(l.batch*l.inputs, 1, l.delta_gpu, 1, net.delta_gpu, 1); + //copy_gpu(l.batch*l.inputs, l.delta_gpu, 1, net.delta_gpu, 1); +} +#endif + diff --git a/hanzi_detection/src/detection_layer.h b/hanzi_detection/src/detection_layer.h new file mode 100755 index 0000000..1c81853 --- /dev/null +++ b/hanzi_detection/src/detection_layer.h @@ -0,0 +1,18 @@ +#ifndef DETECTION_LAYER_H +#define DETECTION_LAYER_H + +#include "layer.h" +#include "network.h" + +typedef layer detection_layer; + +detection_layer make_detection_layer(int batch, int inputs, int n, int size, int classes, int coords, int rescore); +void forward_detection_layer(const detection_layer l, network net); +void backward_detection_layer(const detection_layer l, network net); + +#ifdef GPU +void forward_detection_layer_gpu(const detection_layer l, network net); +void backward_detection_layer_gpu(detection_layer l, network net); +#endif + +#endif diff --git a/hanzi_detection/src/dropout_layer.c b/hanzi_detection/src/dropout_layer.c new file mode 100755 index 0000000..780554f --- /dev/null +++ b/hanzi_detection/src/dropout_layer.c @@ -0,0 +1,60 @@ +#include "dropout_layer.h" +#include "utils.h" +#include "cuda.h" +#include +#include + +dropout_layer make_dropout_layer(int batch, int inputs, float probability) +{ + dropout_layer l = {0}; + l.type = DROPOUT; + l.probability = probability; + l.inputs = inputs; + l.outputs = inputs; + l.batch = batch; + l.rand = calloc(inputs*batch, sizeof(float)); + l.scale = 1./(1.-probability); + l.forward = forward_dropout_layer; + l.backward = backward_dropout_layer; + #ifdef GPU + l.forward_gpu = forward_dropout_layer_gpu; + l.backward_gpu = backward_dropout_layer_gpu; + l.rand_gpu = cuda_make_array(l.rand, inputs*batch); + #endif + fprintf(stderr, "dropout p = %.2f %4d -> %4d\n", probability, inputs, inputs); + return l; +} + +void resize_dropout_layer(dropout_layer *l, int inputs) +{ + l->rand = realloc(l->rand, l->inputs*l->batch*sizeof(float)); + #ifdef GPU + cuda_free(l->rand_gpu); + + l->rand_gpu = cuda_make_array(l->rand, inputs*l->batch); + #endif +} + +void forward_dropout_layer(dropout_layer l, network net) +{ + int i; + if (!net.train) return; + for(i = 0; i < l.batch * l.inputs; ++i){ + float r = rand_uniform(0, 1); + l.rand[i] = r; + if(r < l.probability) net.input[i] = 0; + else net.input[i] *= l.scale; + } +} + +void backward_dropout_layer(dropout_layer l, network net) +{ + int i; + if(!net.delta) return; + for(i = 0; i < l.batch * l.inputs; ++i){ + float r = l.rand[i]; + if(r < l.probability) net.delta[i] = 0; + else net.delta[i] *= l.scale; + } +} + diff --git a/hanzi_detection/src/dropout_layer.h b/hanzi_detection/src/dropout_layer.h new file mode 100755 index 0000000..01f94d4 --- /dev/null +++ b/hanzi_detection/src/dropout_layer.h @@ -0,0 +1,20 @@ +#ifndef DROPOUT_LAYER_H +#define DROPOUT_LAYER_H + +#include "layer.h" +#include "network.h" + +typedef layer dropout_layer; + +dropout_layer make_dropout_layer(int batch, int inputs, float probability); + +void forward_dropout_layer(dropout_layer l, network net); +void backward_dropout_layer(dropout_layer l, network net); +void resize_dropout_layer(dropout_layer *l, int inputs); + +#ifdef GPU +void forward_dropout_layer_gpu(dropout_layer l, network net); +void backward_dropout_layer_gpu(dropout_layer l, network net); + +#endif +#endif diff --git a/hanzi_detection/src/dropout_layer_kernels.cu b/hanzi_detection/src/dropout_layer_kernels.cu new file mode 100755 index 0000000..bd12b67 --- /dev/null +++ b/hanzi_detection/src/dropout_layer_kernels.cu @@ -0,0 +1,41 @@ +#include "cuda_runtime.h" +#include "curand.h" +#include "cublas_v2.h" + +extern "C" { +#include "dropout_layer.h" +#include "cuda.h" +#include "utils.h" +} + +__global__ void yoloswag420blazeit360noscope(float *input, int size, float *rand, float prob, float scale) +{ + int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(id < size) input[id] = (rand[id] < prob) ? 0 : input[id]*scale; +} + +void forward_dropout_layer_gpu(dropout_layer layer, network net) +{ + if (!net.train) return; + int size = layer.inputs*layer.batch; + cuda_random(layer.rand_gpu, size); + /* + int i; + for(i = 0; i < size; ++i){ + layer.rand[i] = rand_uniform(); + } + cuda_push_array(layer.rand_gpu, layer.rand, size); + */ + + yoloswag420blazeit360noscope<<>>(net.input_gpu, size, layer.rand_gpu, layer.probability, layer.scale); + check_error(cudaPeekAtLastError()); +} + +void backward_dropout_layer_gpu(dropout_layer layer, network net) +{ + if(!net.delta_gpu) return; + int size = layer.inputs*layer.batch; + + yoloswag420blazeit360noscope<<>>(net.delta_gpu, size, layer.rand_gpu, layer.probability, layer.scale); + check_error(cudaPeekAtLastError()); +} diff --git a/hanzi_detection/src/gemm.c b/hanzi_detection/src/gemm.c new file mode 100755 index 0000000..648027f --- /dev/null +++ b/hanzi_detection/src/gemm.c @@ -0,0 +1,324 @@ +#include "gemm.h" +#include "utils.h" +#include "cuda.h" +#include +#include +#include + +void gemm_bin(int M, int N, int K, float ALPHA, + char *A, int lda, + float *B, int ldb, + float *C, int ldc) +{ + int i,j,k; + for(i = 0; i < M; ++i){ + for(k = 0; k < K; ++k){ + char A_PART = A[i*lda+k]; + if(A_PART){ + for(j = 0; j < N; ++j){ + C[i*ldc+j] += B[k*ldb+j]; + } + } else { + for(j = 0; j < N; ++j){ + C[i*ldc+j] -= B[k*ldb+j]; + } + } + } + } +} + +float *random_matrix(int rows, int cols) +{ + int i; + float *m = calloc(rows*cols, sizeof(float)); + for(i = 0; i < rows*cols; ++i){ + m[i] = (float)rand()/RAND_MAX; + } + return m; +} + +void time_random_matrix(int TA, int TB, int m, int k, int n) +{ + float *a; + if(!TA) a = random_matrix(m,k); + else a = random_matrix(k,m); + int lda = (!TA)?k:m; + float *b; + if(!TB) b = random_matrix(k,n); + else b = random_matrix(n,k); + int ldb = (!TB)?n:k; + + float *c = random_matrix(m,n); + int i; + clock_t start = clock(), end; + for(i = 0; i<10; ++i){ + gemm_cpu(TA,TB,m,n,k,1,a,lda,b,ldb,1,c,n); + } + end = clock(); + printf("Matrix Multiplication %dx%d * %dx%d, TA=%d, TB=%d: %lf ms\n",m,k,k,n, TA, TB, (float)(end-start)/CLOCKS_PER_SEC); + free(a); + free(b); + free(c); +} + + +void gemm(int TA, int TB, int M, int N, int K, float ALPHA, + float *A, int lda, + float *B, int ldb, + float BETA, + float *C, int ldc) +{ + gemm_cpu( TA, TB, M, N, K, ALPHA,A,lda, B, ldb,BETA,C,ldc); +} + +void gemm_nn(int M, int N, int K, float ALPHA, + float *A, int lda, + float *B, int ldb, + float *C, int ldc) +{ + int i,j,k; + #pragma omp parallel for + for(i = 0; i < M; ++i){ + for(k = 0; k < K; ++k){ + register float A_PART = ALPHA*A[i*lda+k]; + for(j = 0; j < N; ++j){ + C[i*ldc+j] += A_PART*B[k*ldb+j]; + } + } + } +} + +void gemm_nt(int M, int N, int K, float ALPHA, + float *A, int lda, + float *B, int ldb, + float *C, int ldc) +{ + int i,j,k; + #pragma omp parallel for + for(i = 0; i < M; ++i){ + for(j = 0; j < N; ++j){ + register float sum = 0; + for(k = 0; k < K; ++k){ + sum += ALPHA*A[i*lda+k]*B[j*ldb + k]; + } + C[i*ldc+j] += sum; + } + } +} + +void gemm_tn(int M, int N, int K, float ALPHA, + float *A, int lda, + float *B, int ldb, + float *C, int ldc) +{ + int i,j,k; + #pragma omp parallel for + for(i = 0; i < M; ++i){ + for(k = 0; k < K; ++k){ + register float A_PART = ALPHA*A[k*lda+i]; + for(j = 0; j < N; ++j){ + C[i*ldc+j] += A_PART*B[k*ldb+j]; + } + } + } +} + +void gemm_tt(int M, int N, int K, float ALPHA, + float *A, int lda, + float *B, int ldb, + float *C, int ldc) +{ + int i,j,k; + #pragma omp parallel for + for(i = 0; i < M; ++i){ + for(j = 0; j < N; ++j){ + register float sum = 0; + for(k = 0; k < K; ++k){ + sum += ALPHA*A[i+k*lda]*B[k+j*ldb]; + } + C[i*ldc+j] += sum; + } + } +} + + +void gemm_cpu(int TA, int TB, int M, int N, int K, float ALPHA, + float *A, int lda, + float *B, int ldb, + float BETA, + float *C, int ldc) +{ + //printf("cpu: %d %d %d %d %d %f %d %d %f %d\n",TA, TB, M, N, K, ALPHA, lda, ldb, BETA, ldc); + int i, j; + for(i = 0; i < M; ++i){ + for(j = 0; j < N; ++j){ + C[i*ldc + j] *= BETA; + } + } + if(!TA && !TB) + gemm_nn(M, N, K, ALPHA,A,lda, B, ldb,C,ldc); + else if(TA && !TB) + gemm_tn(M, N, K, ALPHA,A,lda, B, ldb,C,ldc); + else if(!TA && TB) + gemm_nt(M, N, K, ALPHA,A,lda, B, ldb,C,ldc); + else + gemm_tt(M, N, K, ALPHA,A,lda, B, ldb,C,ldc); +} + +#ifdef GPU + +#include + +void gemm_gpu(int TA, int TB, int M, int N, int K, float ALPHA, + float *A_gpu, int lda, + float *B_gpu, int ldb, + float BETA, + float *C_gpu, int ldc) +{ + cublasHandle_t handle = blas_handle(); + cudaError_t status = cublasSgemm(handle, (TB ? CUBLAS_OP_T : CUBLAS_OP_N), + (TA ? CUBLAS_OP_T : CUBLAS_OP_N), N, M, K, &ALPHA, B_gpu, ldb, A_gpu, lda, &BETA, C_gpu, ldc); + check_error(status); +} + +#include +#include +#include +#include + +void time_gpu_random_matrix(int TA, int TB, int m, int k, int n) +{ + float *a; + if(!TA) a = random_matrix(m,k); + else a = random_matrix(k,m); + int lda = (!TA)?k:m; + float *b; + if(!TB) b = random_matrix(k,n); + else b = random_matrix(n,k); + int ldb = (!TB)?n:k; + + float *c = random_matrix(m,n); + int i; + clock_t start = clock(), end; + for(i = 0; i<32; ++i){ + gemm_gpu(TA,TB,m,n,k,1,a,lda,b,ldb,1,c,n); + } + end = clock(); + printf("Matrix Multiplication %dx%d * %dx%d, TA=%d, TB=%d: %lf s\n",m,k,k,n, TA, TB, (float)(end-start)/CLOCKS_PER_SEC); + free(a); + free(b); + free(c); +} + +void time_gpu(int TA, int TB, int m, int k, int n) +{ + int iter = 10; + float *a = random_matrix(m,k); + float *b = random_matrix(k,n); + + int lda = (!TA)?k:m; + int ldb = (!TB)?n:k; + + float *c = random_matrix(m,n); + + float *a_cl = cuda_make_array(a, m*k); + float *b_cl = cuda_make_array(b, k*n); + float *c_cl = cuda_make_array(c, m*n); + + int i; + clock_t start = clock(), end; + for(i = 0; i +#include +#include +#include + +static void increment_layer(layer *l, int steps) +{ + int num = l->outputs*l->batch*steps; + l->output += num; + l->delta += num; + l->x += num; + l->x_norm += num; + +#ifdef GPU + l->output_gpu += num; + l->delta_gpu += num; + l->x_gpu += num; + l->x_norm_gpu += num; +#endif +} + +layer make_gru_layer(int batch, int inputs, int outputs, int steps, int batch_normalize, int adam) +{ + fprintf(stderr, "GRU Layer: %d inputs, %d outputs\n", inputs, outputs); + batch = batch / steps; + layer l = {0}; + l.batch = batch; + l.type = GRU; + l.steps = steps; + l.inputs = inputs; + + l.uz = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.uz) = make_connected_layer(batch*steps, inputs, outputs, LINEAR, batch_normalize, adam); + l.uz->batch = batch; + + l.wz = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.wz) = make_connected_layer(batch*steps, outputs, outputs, LINEAR, batch_normalize, adam); + l.wz->batch = batch; + + l.ur = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.ur) = make_connected_layer(batch*steps, inputs, outputs, LINEAR, batch_normalize, adam); + l.ur->batch = batch; + + l.wr = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.wr) = make_connected_layer(batch*steps, outputs, outputs, LINEAR, batch_normalize, adam); + l.wr->batch = batch; + + + + l.uh = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.uh) = make_connected_layer(batch*steps, inputs, outputs, LINEAR, batch_normalize, adam); + l.uh->batch = batch; + + l.wh = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.wh) = make_connected_layer(batch*steps, outputs, outputs, LINEAR, batch_normalize, adam); + l.wh->batch = batch; + + l.batch_normalize = batch_normalize; + + + l.outputs = outputs; + l.output = calloc(outputs*batch*steps, sizeof(float)); + l.delta = calloc(outputs*batch*steps, sizeof(float)); + l.state = calloc(outputs*batch, sizeof(float)); + l.prev_state = calloc(outputs*batch, sizeof(float)); + l.forgot_state = calloc(outputs*batch, sizeof(float)); + l.forgot_delta = calloc(outputs*batch, sizeof(float)); + + l.r_cpu = calloc(outputs*batch, sizeof(float)); + l.z_cpu = calloc(outputs*batch, sizeof(float)); + l.h_cpu = calloc(outputs*batch, sizeof(float)); + + l.forward = forward_gru_layer; + l.backward = backward_gru_layer; + l.update = update_gru_layer; + +#ifdef GPU + l.forward_gpu = forward_gru_layer_gpu; + l.backward_gpu = backward_gru_layer_gpu; + l.update_gpu = update_gru_layer_gpu; + + l.forgot_state_gpu = cuda_make_array(0, batch*outputs); + l.forgot_delta_gpu = cuda_make_array(0, batch*outputs); + l.prev_state_gpu = cuda_make_array(0, batch*outputs); + l.state_gpu = cuda_make_array(0, batch*outputs); + l.output_gpu = cuda_make_array(0, batch*outputs*steps); + l.delta_gpu = cuda_make_array(0, batch*outputs*steps); + l.r_gpu = cuda_make_array(0, batch*outputs); + l.z_gpu = cuda_make_array(0, batch*outputs); + l.h_gpu = cuda_make_array(0, batch*outputs); + +#ifdef CUDNN + cudnnSetTensor4dDescriptor(l.uz->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, batch, l.uz->out_c, l.uz->out_h, l.uz->out_w); + cudnnSetTensor4dDescriptor(l.uh->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, batch, l.uh->out_c, l.uh->out_h, l.uh->out_w); + cudnnSetTensor4dDescriptor(l.ur->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, batch, l.ur->out_c, l.ur->out_h, l.ur->out_w); + cudnnSetTensor4dDescriptor(l.wz->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, batch, l.wz->out_c, l.wz->out_h, l.wz->out_w); + cudnnSetTensor4dDescriptor(l.wh->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, batch, l.wh->out_c, l.wh->out_h, l.wh->out_w); + cudnnSetTensor4dDescriptor(l.wr->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, batch, l.wr->out_c, l.wr->out_h, l.wr->out_w); +#endif +#endif + + return l; +} + +void update_gru_layer(layer l, update_args a) +{ + update_connected_layer(*(l.ur), a); + update_connected_layer(*(l.uz), a); + update_connected_layer(*(l.uh), a); + update_connected_layer(*(l.wr), a); + update_connected_layer(*(l.wz), a); + update_connected_layer(*(l.wh), a); +} + +void forward_gru_layer(layer l, network net) +{ + network s = net; + s.train = net.train; + int i; + layer uz = *(l.uz); + layer ur = *(l.ur); + layer uh = *(l.uh); + + layer wz = *(l.wz); + layer wr = *(l.wr); + layer wh = *(l.wh); + + fill_cpu(l.outputs * l.batch * l.steps, 0, uz.delta, 1); + fill_cpu(l.outputs * l.batch * l.steps, 0, ur.delta, 1); + fill_cpu(l.outputs * l.batch * l.steps, 0, uh.delta, 1); + + fill_cpu(l.outputs * l.batch * l.steps, 0, wz.delta, 1); + fill_cpu(l.outputs * l.batch * l.steps, 0, wr.delta, 1); + fill_cpu(l.outputs * l.batch * l.steps, 0, wh.delta, 1); + if(net.train) { + fill_cpu(l.outputs * l.batch * l.steps, 0, l.delta, 1); + copy_cpu(l.outputs*l.batch, l.state, 1, l.prev_state, 1); + } + + for (i = 0; i < l.steps; ++i) { + s.input = l.state; + forward_connected_layer(wz, s); + forward_connected_layer(wr, s); + + s.input = net.input; + forward_connected_layer(uz, s); + forward_connected_layer(ur, s); + forward_connected_layer(uh, s); + + + copy_cpu(l.outputs*l.batch, uz.output, 1, l.z_cpu, 1); + axpy_cpu(l.outputs*l.batch, 1, wz.output, 1, l.z_cpu, 1); + + copy_cpu(l.outputs*l.batch, ur.output, 1, l.r_cpu, 1); + axpy_cpu(l.outputs*l.batch, 1, wr.output, 1, l.r_cpu, 1); + + activate_array(l.z_cpu, l.outputs*l.batch, LOGISTIC); + activate_array(l.r_cpu, l.outputs*l.batch, LOGISTIC); + + copy_cpu(l.outputs*l.batch, l.state, 1, l.forgot_state, 1); + mul_cpu(l.outputs*l.batch, l.r_cpu, 1, l.forgot_state, 1); + + s.input = l.forgot_state; + forward_connected_layer(wh, s); + + copy_cpu(l.outputs*l.batch, uh.output, 1, l.h_cpu, 1); + axpy_cpu(l.outputs*l.batch, 1, wh.output, 1, l.h_cpu, 1); + + if(l.tanh){ + activate_array(l.h_cpu, l.outputs*l.batch, TANH); + } else { + activate_array(l.h_cpu, l.outputs*l.batch, LOGISTIC); + } + + weighted_sum_cpu(l.state, l.h_cpu, l.z_cpu, l.outputs*l.batch, l.output); + + copy_cpu(l.outputs*l.batch, l.output, 1, l.state, 1); + + net.input += l.inputs*l.batch; + l.output += l.outputs*l.batch; + increment_layer(&uz, 1); + increment_layer(&ur, 1); + increment_layer(&uh, 1); + + increment_layer(&wz, 1); + increment_layer(&wr, 1); + increment_layer(&wh, 1); + } +} + +void backward_gru_layer(layer l, network net) +{ +} + +#ifdef GPU + +void pull_gru_layer(layer l) +{ +} + +void push_gru_layer(layer l) +{ +} + +void update_gru_layer_gpu(layer l, update_args a) +{ + update_connected_layer_gpu(*(l.ur), a); + update_connected_layer_gpu(*(l.uz), a); + update_connected_layer_gpu(*(l.uh), a); + update_connected_layer_gpu(*(l.wr), a); + update_connected_layer_gpu(*(l.wz), a); + update_connected_layer_gpu(*(l.wh), a); +} + +void forward_gru_layer_gpu(layer l, network net) +{ + network s = {0}; + s.train = net.train; + int i; + layer uz = *(l.uz); + layer ur = *(l.ur); + layer uh = *(l.uh); + + layer wz = *(l.wz); + layer wr = *(l.wr); + layer wh = *(l.wh); + + fill_gpu(l.outputs * l.batch * l.steps, 0, uz.delta_gpu, 1); + fill_gpu(l.outputs * l.batch * l.steps, 0, ur.delta_gpu, 1); + fill_gpu(l.outputs * l.batch * l.steps, 0, uh.delta_gpu, 1); + + fill_gpu(l.outputs * l.batch * l.steps, 0, wz.delta_gpu, 1); + fill_gpu(l.outputs * l.batch * l.steps, 0, wr.delta_gpu, 1); + fill_gpu(l.outputs * l.batch * l.steps, 0, wh.delta_gpu, 1); + if(net.train) { + fill_gpu(l.outputs * l.batch * l.steps, 0, l.delta_gpu, 1); + copy_gpu(l.outputs*l.batch, l.state_gpu, 1, l.prev_state_gpu, 1); + } + + for (i = 0; i < l.steps; ++i) { + s.input_gpu = l.state_gpu; + forward_connected_layer_gpu(wz, s); + forward_connected_layer_gpu(wr, s); + + s.input_gpu = net.input_gpu; + forward_connected_layer_gpu(uz, s); + forward_connected_layer_gpu(ur, s); + forward_connected_layer_gpu(uh, s); + + copy_gpu(l.outputs*l.batch, uz.output_gpu, 1, l.z_gpu, 1); + axpy_gpu(l.outputs*l.batch, 1, wz.output_gpu, 1, l.z_gpu, 1); + + copy_gpu(l.outputs*l.batch, ur.output_gpu, 1, l.r_gpu, 1); + axpy_gpu(l.outputs*l.batch, 1, wr.output_gpu, 1, l.r_gpu, 1); + + activate_array_gpu(l.z_gpu, l.outputs*l.batch, LOGISTIC); + activate_array_gpu(l.r_gpu, l.outputs*l.batch, LOGISTIC); + + copy_gpu(l.outputs*l.batch, l.state_gpu, 1, l.forgot_state_gpu, 1); + mul_gpu(l.outputs*l.batch, l.r_gpu, 1, l.forgot_state_gpu, 1); + + s.input_gpu = l.forgot_state_gpu; + forward_connected_layer_gpu(wh, s); + + copy_gpu(l.outputs*l.batch, uh.output_gpu, 1, l.h_gpu, 1); + axpy_gpu(l.outputs*l.batch, 1, wh.output_gpu, 1, l.h_gpu, 1); + + if(l.tanh){ + activate_array_gpu(l.h_gpu, l.outputs*l.batch, TANH); + } else { + activate_array_gpu(l.h_gpu, l.outputs*l.batch, LOGISTIC); + } + + weighted_sum_gpu(l.state_gpu, l.h_gpu, l.z_gpu, l.outputs*l.batch, l.output_gpu); + copy_gpu(l.outputs*l.batch, l.output_gpu, 1, l.state_gpu, 1); + + net.input_gpu += l.inputs*l.batch; + l.output_gpu += l.outputs*l.batch; + increment_layer(&uz, 1); + increment_layer(&ur, 1); + increment_layer(&uh, 1); + + increment_layer(&wz, 1); + increment_layer(&wr, 1); + increment_layer(&wh, 1); + } +} + +void backward_gru_layer_gpu(layer l, network net) +{ + network s = {0}; + s.train = net.train; + int i; + layer uz = *(l.uz); + layer ur = *(l.ur); + layer uh = *(l.uh); + + layer wz = *(l.wz); + layer wr = *(l.wr); + layer wh = *(l.wh); + + increment_layer(&uz, l.steps - 1); + increment_layer(&ur, l.steps - 1); + increment_layer(&uh, l.steps - 1); + + increment_layer(&wz, l.steps - 1); + increment_layer(&wr, l.steps - 1); + increment_layer(&wh, l.steps - 1); + + net.input_gpu += l.inputs*l.batch*(l.steps-1); + if(net.delta_gpu) net.delta_gpu += l.inputs*l.batch*(l.steps-1); + l.output_gpu += l.outputs*l.batch*(l.steps-1); + l.delta_gpu += l.outputs*l.batch*(l.steps-1); + float *end_state = l.output_gpu; + for (i = l.steps-1; i >= 0; --i) { + if(i != 0) copy_gpu(l.outputs*l.batch, l.output_gpu - l.outputs*l.batch, 1, l.state_gpu, 1); + else copy_gpu(l.outputs*l.batch, l.prev_state_gpu, 1, l.state_gpu, 1); + float *prev_delta_gpu = (i == 0) ? 0 : l.delta_gpu - l.outputs*l.batch; + + copy_gpu(l.outputs*l.batch, uz.output_gpu, 1, l.z_gpu, 1); + axpy_gpu(l.outputs*l.batch, 1, wz.output_gpu, 1, l.z_gpu, 1); + + copy_gpu(l.outputs*l.batch, ur.output_gpu, 1, l.r_gpu, 1); + axpy_gpu(l.outputs*l.batch, 1, wr.output_gpu, 1, l.r_gpu, 1); + + activate_array_gpu(l.z_gpu, l.outputs*l.batch, LOGISTIC); + activate_array_gpu(l.r_gpu, l.outputs*l.batch, LOGISTIC); + + copy_gpu(l.outputs*l.batch, uh.output_gpu, 1, l.h_gpu, 1); + axpy_gpu(l.outputs*l.batch, 1, wh.output_gpu, 1, l.h_gpu, 1); + + if(l.tanh){ + activate_array_gpu(l.h_gpu, l.outputs*l.batch, TANH); + } else { + activate_array_gpu(l.h_gpu, l.outputs*l.batch, LOGISTIC); + } + + weighted_delta_gpu(l.state_gpu, l.h_gpu, l.z_gpu, prev_delta_gpu, uh.delta_gpu, uz.delta_gpu, l.outputs*l.batch, l.delta_gpu); + + if(l.tanh){ + gradient_array_gpu(l.h_gpu, l.outputs*l.batch, TANH, uh.delta_gpu); + } else { + gradient_array_gpu(l.h_gpu, l.outputs*l.batch, LOGISTIC, uh.delta_gpu); + } + + copy_gpu(l.outputs*l.batch, uh.delta_gpu, 1, wh.delta_gpu, 1); + + copy_gpu(l.outputs*l.batch, l.state_gpu, 1, l.forgot_state_gpu, 1); + mul_gpu(l.outputs*l.batch, l.r_gpu, 1, l.forgot_state_gpu, 1); + fill_gpu(l.outputs*l.batch, 0, l.forgot_delta_gpu, 1); + + s.input_gpu = l.forgot_state_gpu; + s.delta_gpu = l.forgot_delta_gpu; + + backward_connected_layer_gpu(wh, s); + if(prev_delta_gpu) mult_add_into_gpu(l.outputs*l.batch, l.forgot_delta_gpu, l.r_gpu, prev_delta_gpu); + mult_add_into_gpu(l.outputs*l.batch, l.forgot_delta_gpu, l.state_gpu, ur.delta_gpu); + + gradient_array_gpu(l.r_gpu, l.outputs*l.batch, LOGISTIC, ur.delta_gpu); + copy_gpu(l.outputs*l.batch, ur.delta_gpu, 1, wr.delta_gpu, 1); + + gradient_array_gpu(l.z_gpu, l.outputs*l.batch, LOGISTIC, uz.delta_gpu); + copy_gpu(l.outputs*l.batch, uz.delta_gpu, 1, wz.delta_gpu, 1); + + s.input_gpu = l.state_gpu; + s.delta_gpu = prev_delta_gpu; + + backward_connected_layer_gpu(wr, s); + backward_connected_layer_gpu(wz, s); + + s.input_gpu = net.input_gpu; + s.delta_gpu = net.delta_gpu; + + backward_connected_layer_gpu(uh, s); + backward_connected_layer_gpu(ur, s); + backward_connected_layer_gpu(uz, s); + + + net.input_gpu -= l.inputs*l.batch; + if(net.delta_gpu) net.delta_gpu -= l.inputs*l.batch; + l.output_gpu -= l.outputs*l.batch; + l.delta_gpu -= l.outputs*l.batch; + increment_layer(&uz, -1); + increment_layer(&ur, -1); + increment_layer(&uh, -1); + + increment_layer(&wz, -1); + increment_layer(&wr, -1); + increment_layer(&wh, -1); + } + copy_gpu(l.outputs*l.batch, end_state, 1, l.state_gpu, 1); +} +#endif diff --git a/hanzi_detection/src/gru_layer.h b/hanzi_detection/src/gru_layer.h new file mode 100755 index 0000000..9067942 --- /dev/null +++ b/hanzi_detection/src/gru_layer.h @@ -0,0 +1,24 @@ + +#ifndef GRU_LAYER_H +#define GRU_LAYER_H + +#include "activations.h" +#include "layer.h" +#include "network.h" + +layer make_gru_layer(int batch, int inputs, int outputs, int steps, int batch_normalize, int adam); + +void forward_gru_layer(layer l, network state); +void backward_gru_layer(layer l, network state); +void update_gru_layer(layer l, update_args a); + +#ifdef GPU +void forward_gru_layer_gpu(layer l, network state); +void backward_gru_layer_gpu(layer l, network state); +void update_gru_layer_gpu(layer l, update_args a); +void push_gru_layer(layer l); +void pull_gru_layer(layer l); +#endif + +#endif + diff --git a/hanzi_detection/src/im2col.c b/hanzi_detection/src/im2col.c new file mode 100755 index 0000000..69ec98a --- /dev/null +++ b/hanzi_detection/src/im2col.c @@ -0,0 +1,40 @@ +#include "im2col.h" +#include +float im2col_get_pixel(float *im, int height, int width, int channels, + int row, int col, int channel, int pad) +{ + row -= pad; + col -= pad; + + if (row < 0 || col < 0 || + row >= height || col >= width) return 0; + return im[col + width*(row + height*channel)]; +} + +//From Berkeley Vision's Caffe! +//https://github.com/BVLC/caffe/blob/master/LICENSE +void im2col_cpu(float* data_im, + int channels, int height, int width, + int ksize, int stride, int pad, float* data_col) +{ + int c,h,w; + int height_col = (height + 2*pad - ksize) / stride + 1; + int width_col = (width + 2*pad - ksize) / stride + 1; + + int channels_col = channels * ksize * ksize; + for (c = 0; c < channels_col; ++c) { + int w_offset = c % ksize; + int h_offset = (c / ksize) % ksize; + int c_im = c / ksize / ksize; + for (h = 0; h < height_col; ++h) { + for (w = 0; w < width_col; ++w) { + int im_row = h_offset + h * stride; + int im_col = w_offset + w * stride; + int col_index = (c * height_col + h) * width_col + w; + data_col[col_index] = im2col_get_pixel(data_im, height, width, channels, + im_row, im_col, c_im, pad); + } + } + } +} + diff --git a/hanzi_detection/src/im2col.h b/hanzi_detection/src/im2col.h new file mode 100755 index 0000000..02c4247 --- /dev/null +++ b/hanzi_detection/src/im2col.h @@ -0,0 +1,15 @@ +#ifndef IM2COL_H +#define IM2COL_H + +void im2col_cpu(float* data_im, + int channels, int height, int width, + int ksize, int stride, int pad, float* data_col); + +#ifdef GPU + +void im2col_gpu(float *im, + int channels, int height, int width, + int ksize, int stride, int pad,float *data_col); + +#endif +#endif diff --git a/hanzi_detection/src/im2col_kernels.cu b/hanzi_detection/src/im2col_kernels.cu new file mode 100755 index 0000000..07b5e67 --- /dev/null +++ b/hanzi_detection/src/im2col_kernels.cu @@ -0,0 +1,61 @@ +#include "cuda_runtime.h" +#include "curand.h" +#include "cublas_v2.h" + +extern "C" { +#include "im2col.h" +#include "cuda.h" +} + +// src: https://github.com/BVLC/caffe/blob/master/src/caffe/util/im2col.cu +// You may also want to read: https://github.com/BVLC/caffe/blob/master/LICENSE + +__global__ void im2col_gpu_kernel(const int n, const float* data_im, + const int height, const int width, const int ksize, + const int pad, + const int stride, + const int height_col, const int width_col, + float *data_col) { + int index = blockIdx.x*blockDim.x+threadIdx.x; + for(; index < n; index += blockDim.x*gridDim.x){ + int w_out = index % width_col; + int h_index = index / width_col; + int h_out = h_index % height_col; + int channel_in = h_index / height_col; + int channel_out = channel_in * ksize * ksize; + int h_in = h_out * stride - pad; + int w_in = w_out * stride - pad; + float* data_col_ptr = data_col; + data_col_ptr += (channel_out * height_col + h_out) * width_col + w_out; + const float* data_im_ptr = data_im; + data_im_ptr += (channel_in * height + h_in) * width + w_in; + for (int i = 0; i < ksize; ++i) { + for (int j = 0; j < ksize; ++j) { + int h = h_in + i; + int w = w_in + j; + + *data_col_ptr = (h >= 0 && w >= 0 && h < height && w < width) ? + data_im_ptr[i * width + j] : 0; + + //*data_col_ptr = data_im_ptr[ii * width + jj]; + + data_col_ptr += height_col * width_col; + } + } + } +} + +void im2col_gpu(float *im, + int channels, int height, int width, + int ksize, int stride, int pad, float *data_col){ + // We are going to launch channels * height_col * width_col kernels, each + // kernel responsible for copying a single-channel grid. + int height_col = (height + 2 * pad - ksize) / stride + 1; + int width_col = (width + 2 * pad - ksize) / stride + 1; + int num_kernels = channels * height_col * width_col; + im2col_gpu_kernel<<<(num_kernels+BLOCK-1)/BLOCK, + BLOCK>>>( + num_kernels, im, height, width, ksize, pad, + stride, height_col, + width_col, data_col); +} diff --git a/hanzi_detection/src/image.c b/hanzi_detection/src/image.c new file mode 100755 index 0000000..4a2c6ba --- /dev/null +++ b/hanzi_detection/src/image.c @@ -0,0 +1,1466 @@ +#include "image.h" +#include "utils.h" +#include "blas.h" +#include "cuda.h" +#include +#include + +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" +#define STB_IMAGE_WRITE_IMPLEMENTATION +#include "stb_image_write.h" + +int windows = 0; + +float colors[6][3] = { {1,0,1}, {0,0,1},{0,1,1},{0,1,0},{1,1,0},{1,0,0} }; + +float get_color(int c, int x, int max) +{ + float ratio = ((float)x/max)*5; + int i = floor(ratio); + int j = ceil(ratio); + ratio -= i; + float r = (1-ratio) * colors[i][c] + ratio*colors[j][c]; + //printf("%f\n", r); + return r; +} + +image mask_to_rgb(image mask) +{ + int n = mask.c; + image im = make_image(mask.w, mask.h, 3); + int i, j; + for(j = 0; j < n; ++j){ + int offset = j*123457 % n; + float red = get_color(2,offset,n); + float green = get_color(1,offset,n); + float blue = get_color(0,offset,n); + for(i = 0; i < im.w*im.h; ++i){ + im.data[i + 0*im.w*im.h] += mask.data[j*im.h*im.w + i]*red; + im.data[i + 1*im.w*im.h] += mask.data[j*im.h*im.w + i]*green; + im.data[i + 2*im.w*im.h] += mask.data[j*im.h*im.w + i]*blue; + } + } + return im; +} + +static float get_pixel(image m, int x, int y, int c) +{ + assert(x < m.w && y < m.h && c < m.c); + return m.data[c*m.h*m.w + y*m.w + x]; +} +static float get_pixel_extend(image m, int x, int y, int c) +{ + if(x < 0 || x >= m.w || y < 0 || y >= m.h) return 0; + /* + if(x < 0) x = 0; + if(x >= m.w) x = m.w-1; + if(y < 0) y = 0; + if(y >= m.h) y = m.h-1; + */ + if(c < 0 || c >= m.c) return 0; + return get_pixel(m, x, y, c); +} +static void set_pixel(image m, int x, int y, int c, float val) +{ + if (x < 0 || y < 0 || c < 0 || x >= m.w || y >= m.h || c >= m.c) return; + assert(x < m.w && y < m.h && c < m.c); + m.data[c*m.h*m.w + y*m.w + x] = val; +} +static void add_pixel(image m, int x, int y, int c, float val) +{ + assert(x < m.w && y < m.h && c < m.c); + m.data[c*m.h*m.w + y*m.w + x] += val; +} + +static float bilinear_interpolate(image im, float x, float y, int c) +{ + int ix = (int) floorf(x); + int iy = (int) floorf(y); + + float dx = x - ix; + float dy = y - iy; + + float val = (1-dy) * (1-dx) * get_pixel_extend(im, ix, iy, c) + + dy * (1-dx) * get_pixel_extend(im, ix, iy+1, c) + + (1-dy) * dx * get_pixel_extend(im, ix+1, iy, c) + + dy * dx * get_pixel_extend(im, ix+1, iy+1, c); + return val; +} + + +void composite_image(image source, image dest, int dx, int dy) +{ + int x,y,k; + for(k = 0; k < source.c; ++k){ + for(y = 0; y < source.h; ++y){ + for(x = 0; x < source.w; ++x){ + float val = get_pixel(source, x, y, k); + float val2 = get_pixel_extend(dest, dx+x, dy+y, k); + set_pixel(dest, dx+x, dy+y, k, val * val2); + } + } + } +} + +image border_image(image a, int border) +{ + image b = make_image(a.w + 2*border, a.h + 2*border, a.c); + int x,y,k; + for(k = 0; k < b.c; ++k){ + for(y = 0; y < b.h; ++y){ + for(x = 0; x < b.w; ++x){ + float val = get_pixel_extend(a, x - border, y - border, k); + if(x - border < 0 || x - border >= a.w || y - border < 0 || y - border >= a.h) val = 1; + set_pixel(b, x, y, k, val); + } + } + } + return b; +} + +image tile_images(image a, image b, int dx) +{ + if(a.w == 0) return copy_image(b); + image c = make_image(a.w + b.w + dx, (a.h > b.h) ? a.h : b.h, (a.c > b.c) ? a.c : b.c); + fill_cpu(c.w*c.h*c.c, 1, c.data, 1); + embed_image(a, c, 0, 0); + composite_image(b, c, a.w + dx, 0); + return c; +} + +image get_label(image **characters, char *string, int size) +{ + size = size/10; + if(size > 7) size = 7; + image label = make_empty_image(0,0,0); + while(*string){ + image l = characters[size][(int)*string]; + image n = tile_images(label, l, -size - 1 + (size+1)/2); + free_image(label); + label = n; + ++string; + } + image b = border_image(label, label.h*.25); + free_image(label); + return b; +} + +void draw_label(image a, int r, int c, image label, const float *rgb) +{ + int w = label.w; + int h = label.h; + if (r - h >= 0) r = r - h; + + int i, j, k; + for(j = 0; j < h && j + r < a.h; ++j){ + for(i = 0; i < w && i + c < a.w; ++i){ + for(k = 0; k < label.c; ++k){ + float val = get_pixel(label, i, j, k); + set_pixel(a, i+c, j+r, k, rgb[k] * val); + } + } + } +} + +void draw_box(image a, int x1, int y1, int x2, int y2, float r, float g, float b) +{ + //normalize_image(a); + int i; + if(x1 < 0) x1 = 0; + if(x1 >= a.w) x1 = a.w-1; + if(x2 < 0) x2 = 0; + if(x2 >= a.w) x2 = a.w-1; + + if(y1 < 0) y1 = 0; + if(y1 >= a.h) y1 = a.h-1; + if(y2 < 0) y2 = 0; + if(y2 >= a.h) y2 = a.h-1; + + for(i = x1; i <= x2; ++i){ + a.data[i + y1*a.w + 0*a.w*a.h] = r; + a.data[i + y2*a.w + 0*a.w*a.h] = r; + + a.data[i + y1*a.w + 1*a.w*a.h] = g; + a.data[i + y2*a.w + 1*a.w*a.h] = g; + + a.data[i + y1*a.w + 2*a.w*a.h] = b; + a.data[i + y2*a.w + 2*a.w*a.h] = b; + } + for(i = y1; i <= y2; ++i){ + a.data[x1 + i*a.w + 0*a.w*a.h] = r; + a.data[x2 + i*a.w + 0*a.w*a.h] = r; + + a.data[x1 + i*a.w + 1*a.w*a.h] = g; + a.data[x2 + i*a.w + 1*a.w*a.h] = g; + + a.data[x1 + i*a.w + 2*a.w*a.h] = b; + a.data[x2 + i*a.w + 2*a.w*a.h] = b; + } +} + +void draw_box_width(image a, int x1, int y1, int x2, int y2, int w, float r, float g, float b) +{ + int i; + for(i = 0; i < w; ++i){ + draw_box(a, x1+i, y1+i, x2-i, y2-i, r, g, b); + } +} + +void draw_bbox(image a, box bbox, int w, float r, float g, float b) +{ + int left = (bbox.x-bbox.w/2)*a.w; + int right = (bbox.x+bbox.w/2)*a.w; + int top = (bbox.y-bbox.h/2)*a.h; + int bot = (bbox.y+bbox.h/2)*a.h; + + int i; + for(i = 0; i < w; ++i){ + draw_box(a, left+i, top+i, right-i, bot-i, r, g, b); + } +} + +image **load_alphabet() +{ + int i, j; + const int nsize = 8; + image **alphabets = calloc(nsize, sizeof(image)); + for(j = 0; j < nsize; ++j){ + alphabets[j] = calloc(128, sizeof(image)); + for(i = 32; i < 127; ++i){ + char buff[256]; + sprintf(buff, "data/labels/%d_%d.png", i, j); + alphabets[j][i] = load_image_color(buff, 0, 0); + } + } + return alphabets; +} + +void draw_detections(image im, detection *dets, int num, float thresh, char **names, image **alphabet, int classes) +{ + int i,j; + + for(i = 0; i < num; ++i){ + char labelstr[4096] = {0}; + int class = -1; + for(j = 0; j < classes; ++j){ + if (dets[i].prob[j] > thresh){ + if (class < 0) { + strcat(labelstr, names[j]); + class = j; + } else { + strcat(labelstr, ", "); + strcat(labelstr, names[j]); + } + printf("%s: %.0f%%\n", names[j], dets[i].prob[j]*100); + } + } + if(class >= 0){ + int width = im.h * .006; + + /* + if(0){ + width = pow(prob, 1./2.)*10+1; + alphabet = 0; + } + */ + + //printf("%d %s: %.0f%%\n", i, names[class], prob*100); + int offset = class*123457 % classes; + float red = get_color(2,offset,classes); + float green = get_color(1,offset,classes); + float blue = get_color(0,offset,classes); + float rgb[3]; + + //width = prob*20+2; + + rgb[0] = red; + rgb[1] = green; + rgb[2] = blue; + box b = dets[i].bbox; + //printf("%f %f %f %f\n", b.x, b.y, b.w, b.h); + + int left = (b.x-b.w/2.)*im.w; + int right = (b.x+b.w/2.)*im.w; + int top = (b.y-b.h/2.)*im.h; + int bot = (b.y+b.h/2.)*im.h; + + if(left < 0) left = 0; + if(right > im.w-1) right = im.w-1; + if(top < 0) top = 0; + if(bot > im.h-1) bot = im.h-1; + + draw_box_width(im, left, top, right, bot, width, red, green, blue); + if (alphabet) { + image label = get_label(alphabet, labelstr, (im.h*.03)); + draw_label(im, top + width, left, label, rgb); + free_image(label); + } + if (dets[i].mask){ + image mask = float_to_image(14, 14, 1, dets[i].mask); + image resized_mask = resize_image(mask, b.w*im.w, b.h*im.h); + image tmask = threshold_image(resized_mask, .5); + embed_image(tmask, im, left, top); + free_image(mask); + free_image(resized_mask); + free_image(tmask); + } + } + } +} + +void transpose_image(image im) +{ + assert(im.w == im.h); + int n, m; + int c; + for(c = 0; c < im.c; ++c){ + for(n = 0; n < im.w-1; ++n){ + for(m = n + 1; m < im.w; ++m){ + float swap = im.data[m + im.w*(n + im.h*c)]; + im.data[m + im.w*(n + im.h*c)] = im.data[n + im.w*(m + im.h*c)]; + im.data[n + im.w*(m + im.h*c)] = swap; + } + } + } +} + +void rotate_image_cw(image im, int times) +{ + assert(im.w == im.h); + times = (times + 400) % 4; + int i, x, y, c; + int n = im.w; + for(i = 0; i < times; ++i){ + for(c = 0; c < im.c; ++c){ + for(x = 0; x < n/2; ++x){ + for(y = 0; y < (n-1)/2 + 1; ++y){ + float temp = im.data[y + im.w*(x + im.h*c)]; + im.data[y + im.w*(x + im.h*c)] = im.data[n-1-x + im.w*(y + im.h*c)]; + im.data[n-1-x + im.w*(y + im.h*c)] = im.data[n-1-y + im.w*(n-1-x + im.h*c)]; + im.data[n-1-y + im.w*(n-1-x + im.h*c)] = im.data[x + im.w*(n-1-y + im.h*c)]; + im.data[x + im.w*(n-1-y + im.h*c)] = temp; + } + } + } + } +} + +void flip_image(image a) +{ + int i,j,k; + for(k = 0; k < a.c; ++k){ + for(i = 0; i < a.h; ++i){ + for(j = 0; j < a.w/2; ++j){ + int index = j + a.w*(i + a.h*(k)); + int flip = (a.w - j - 1) + a.w*(i + a.h*(k)); + float swap = a.data[flip]; + a.data[flip] = a.data[index]; + a.data[index] = swap; + } + } + } +} + +image image_distance(image a, image b) +{ + int i,j; + image dist = make_image(a.w, a.h, 1); + for(i = 0; i < a.c; ++i){ + for(j = 0; j < a.h*a.w; ++j){ + dist.data[j] += pow(a.data[i*a.h*a.w+j]-b.data[i*a.h*a.w+j],2); + } + } + for(j = 0; j < a.h*a.w; ++j){ + dist.data[j] = sqrt(dist.data[j]); + } + return dist; +} + +void ghost_image(image source, image dest, int dx, int dy) +{ + int x,y,k; + float max_dist = sqrt((-source.w/2. + .5)*(-source.w/2. + .5)); + for(k = 0; k < source.c; ++k){ + for(y = 0; y < source.h; ++y){ + for(x = 0; x < source.w; ++x){ + float dist = sqrt((x - source.w/2. + .5)*(x - source.w/2. + .5) + (y - source.h/2. + .5)*(y - source.h/2. + .5)); + float alpha = (1 - dist/max_dist); + if(alpha < 0) alpha = 0; + float v1 = get_pixel(source, x,y,k); + float v2 = get_pixel(dest, dx+x,dy+y,k); + float val = alpha*v1 + (1-alpha)*v2; + set_pixel(dest, dx+x, dy+y, k, val); + } + } + } +} + +void blocky_image(image im, int s) +{ + int i,j,k; + for(k = 0; k < im.c; ++k){ + for(j = 0; j < im.h; ++j){ + for(i = 0; i < im.w; ++i){ + im.data[i + im.w*(j + im.h*k)] = im.data[i/s*s + im.w*(j/s*s + im.h*k)]; + } + } + } +} + +void censor_image(image im, int dx, int dy, int w, int h) +{ + int i,j,k; + int s = 32; + if(dx < 0) dx = 0; + if(dy < 0) dy = 0; + + for(k = 0; k < im.c; ++k){ + for(j = dy; j < dy + h && j < im.h; ++j){ + for(i = dx; i < dx + w && i < im.w; ++i){ + im.data[i + im.w*(j + im.h*k)] = im.data[i/s*s + im.w*(j/s*s + im.h*k)]; + //im.data[i + j*im.w + k*im.w*im.h] = 0; + } + } + } +} + +void embed_image(image source, image dest, int dx, int dy) +{ + int x,y,k; + for(k = 0; k < source.c; ++k){ + for(y = 0; y < source.h; ++y){ + for(x = 0; x < source.w; ++x){ + float val = get_pixel(source, x,y,k); + set_pixel(dest, dx+x, dy+y, k, val); + } + } + } +} + +image collapse_image_layers(image source, int border) +{ + int h = source.h; + h = (h+border)*source.c - border; + image dest = make_image(source.w, h, 1); + int i; + for(i = 0; i < source.c; ++i){ + image layer = get_image_layer(source, i); + int h_offset = i*(source.h+border); + embed_image(layer, dest, 0, h_offset); + free_image(layer); + } + return dest; +} + +void constrain_image(image im) +{ + int i; + for(i = 0; i < im.w*im.h*im.c; ++i){ + if(im.data[i] < 0) im.data[i] = 0; + if(im.data[i] > 1) im.data[i] = 1; + } +} + +void normalize_image(image p) +{ + int i; + float min = 9999999; + float max = -999999; + + for(i = 0; i < p.h*p.w*p.c; ++i){ + float v = p.data[i]; + if(v < min) min = v; + if(v > max) max = v; + } + if(max - min < .000000001){ + min = 0; + max = 1; + } + for(i = 0; i < p.c*p.w*p.h; ++i){ + p.data[i] = (p.data[i] - min)/(max-min); + } +} + +void normalize_image2(image p) +{ + float *min = calloc(p.c, sizeof(float)); + float *max = calloc(p.c, sizeof(float)); + int i,j; + for(i = 0; i < p.c; ++i) min[i] = max[i] = p.data[i*p.h*p.w]; + + for(j = 0; j < p.c; ++j){ + for(i = 0; i < p.h*p.w; ++i){ + float v = p.data[i+j*p.h*p.w]; + if(v < min[j]) min[j] = v; + if(v > max[j]) max[j] = v; + } + } + for(i = 0; i < p.c; ++i){ + if(max[i] - min[i] < .000000001){ + min[i] = 0; + max[i] = 1; + } + } + for(j = 0; j < p.c; ++j){ + for(i = 0; i < p.w*p.h; ++i){ + p.data[i+j*p.h*p.w] = (p.data[i+j*p.h*p.w] - min[j])/(max[j]-min[j]); + } + } + free(min); + free(max); +} + +void copy_image_into(image src, image dest) +{ + memcpy(dest.data, src.data, src.h*src.w*src.c*sizeof(float)); +} + +image copy_image(image p) +{ + image copy = p; + copy.data = calloc(p.h*p.w*p.c, sizeof(float)); + memcpy(copy.data, p.data, p.h*p.w*p.c*sizeof(float)); + return copy; +} + +void rgbgr_image(image im) +{ + int i; + for(i = 0; i < im.w*im.h; ++i){ + float swap = im.data[i]; + im.data[i] = im.data[i+im.w*im.h*2]; + im.data[i+im.w*im.h*2] = swap; + } +} + +int show_image(image p, const char *name, int ms) +{ +#ifdef OPENCV + int c = show_image_cv(p, name, ms); + return c; +#else + fprintf(stderr, "Not compiled with OpenCV, saving to %s.png instead\n", name); + save_image(p, name); + return -1; +#endif +} + +void save_image_options(image im, const char *name, IMTYPE f, int quality) +{ + char buff[256]; + //sprintf(buff, "%s (%d)", name, windows); + if(f == PNG) sprintf(buff, "%s.png", name); + else if (f == BMP) sprintf(buff, "%s.bmp", name); + else if (f == TGA) sprintf(buff, "%s.tga", name); + else if (f == JPG) sprintf(buff, "%s.jpg", name); + else sprintf(buff, "%s.png", name); + unsigned char *data = calloc(im.w*im.h*im.c, sizeof(char)); + int i,k; + for(k = 0; k < im.c; ++k){ + for(i = 0; i < im.w*im.h; ++i){ + data[i*im.c+k] = (unsigned char) (255*im.data[i + k*im.w*im.h]); + } + } + int success = 0; + if(f == PNG) success = stbi_write_png(buff, im.w, im.h, im.c, data, im.w*im.c); + else if (f == BMP) success = stbi_write_bmp(buff, im.w, im.h, im.c, data); + else if (f == TGA) success = stbi_write_tga(buff, im.w, im.h, im.c, data); + else if (f == JPG) success = stbi_write_jpg(buff, im.w, im.h, im.c, data, quality); + free(data); + if(!success) fprintf(stderr, "Failed to write image %s\n", buff); +} + +void save_image(image im, const char *name) +{ + save_image_options(im, name, JPG, 80); +} + +void show_image_layers(image p, char *name) +{ + int i; + char buff[256]; + for(i = 0; i < p.c; ++i){ + sprintf(buff, "%s - Layer %d", name, i); + image layer = get_image_layer(p, i); + show_image(layer, buff, 1); + free_image(layer); + } +} + +void show_image_collapsed(image p, char *name) +{ + image c = collapse_image_layers(p, 1); + show_image(c, name, 1); + free_image(c); +} + +image make_empty_image(int w, int h, int c) +{ + image out; + out.data = 0; + out.h = h; + out.w = w; + out.c = c; + return out; +} + +image make_image(int w, int h, int c) +{ + image out = make_empty_image(w,h,c); + out.data = calloc(h*w*c, sizeof(float)); + return out; +} + +image make_random_image(int w, int h, int c) +{ + image out = make_empty_image(w,h,c); + out.data = calloc(h*w*c, sizeof(float)); + int i; + for(i = 0; i < w*h*c; ++i){ + out.data[i] = (rand_normal() * .25) + .5; + } + return out; +} + +image float_to_image(int w, int h, int c, float *data) +{ + image out = make_empty_image(w,h,c); + out.data = data; + return out; +} + +void place_image(image im, int w, int h, int dx, int dy, image canvas) +{ + int x, y, c; + for(c = 0; c < im.c; ++c){ + for(y = 0; y < h; ++y){ + for(x = 0; x < w; ++x){ + float rx = ((float)x / w) * im.w; + float ry = ((float)y / h) * im.h; + float val = bilinear_interpolate(im, rx, ry, c); + set_pixel(canvas, x + dx, y + dy, c, val); + } + } + } +} + +image center_crop_image(image im, int w, int h) +{ + int m = (im.w < im.h) ? im.w : im.h; + image c = crop_image(im, (im.w - m) / 2, (im.h - m)/2, m, m); + image r = resize_image(c, w, h); + free_image(c); + return r; +} + +image rotate_crop_image(image im, float rad, float s, int w, int h, float dx, float dy, float aspect) +{ + int x, y, c; + float cx = im.w/2.; + float cy = im.h/2.; + image rot = make_image(w, h, im.c); + for(c = 0; c < im.c; ++c){ + for(y = 0; y < h; ++y){ + for(x = 0; x < w; ++x){ + float rx = cos(rad)*((x - w/2.)/s*aspect + dx/s*aspect) - sin(rad)*((y - h/2.)/s + dy/s) + cx; + float ry = sin(rad)*((x - w/2.)/s*aspect + dx/s*aspect) + cos(rad)*((y - h/2.)/s + dy/s) + cy; + float val = bilinear_interpolate(im, rx, ry, c); + set_pixel(rot, x, y, c, val); + } + } + } + return rot; +} + +image rotate_image(image im, float rad) +{ + int x, y, c; + float cx = im.w/2.; + float cy = im.h/2.; + image rot = make_image(im.w, im.h, im.c); + for(c = 0; c < im.c; ++c){ + for(y = 0; y < im.h; ++y){ + for(x = 0; x < im.w; ++x){ + float rx = cos(rad)*(x-cx) - sin(rad)*(y-cy) + cx; + float ry = sin(rad)*(x-cx) + cos(rad)*(y-cy) + cy; + float val = bilinear_interpolate(im, rx, ry, c); + set_pixel(rot, x, y, c, val); + } + } + } + return rot; +} + +void fill_image(image m, float s) +{ + int i; + for(i = 0; i < m.h*m.w*m.c; ++i) m.data[i] = s; +} + +void translate_image(image m, float s) +{ + int i; + for(i = 0; i < m.h*m.w*m.c; ++i) m.data[i] += s; +} + +void scale_image(image m, float s) +{ + int i; + for(i = 0; i < m.h*m.w*m.c; ++i) m.data[i] *= s; +} + +image crop_image(image im, int dx, int dy, int w, int h) +{ + image cropped = make_image(w, h, im.c); + int i, j, k; + for(k = 0; k < im.c; ++k){ + for(j = 0; j < h; ++j){ + for(i = 0; i < w; ++i){ + int r = j + dy; + int c = i + dx; + float val = 0; + r = constrain_int(r, 0, im.h-1); + c = constrain_int(c, 0, im.w-1); + val = get_pixel(im, c, r, k); + set_pixel(cropped, i, j, k, val); + } + } + } + return cropped; +} + +int best_3d_shift_r(image a, image b, int min, int max) +{ + if(min == max) return min; + int mid = floor((min + max) / 2.); + image c1 = crop_image(b, 0, mid, b.w, b.h); + image c2 = crop_image(b, 0, mid+1, b.w, b.h); + float d1 = dist_array(c1.data, a.data, a.w*a.h*a.c, 10); + float d2 = dist_array(c2.data, a.data, a.w*a.h*a.c, 10); + free_image(c1); + free_image(c2); + if(d1 < d2) return best_3d_shift_r(a, b, min, mid); + else return best_3d_shift_r(a, b, mid+1, max); +} + +int best_3d_shift(image a, image b, int min, int max) +{ + int i; + int best = 0; + float best_distance = FLT_MAX; + for(i = min; i <= max; i += 2){ + image c = crop_image(b, 0, i, b.w, b.h); + float d = dist_array(c.data, a.data, a.w*a.h*a.c, 100); + if(d < best_distance){ + best_distance = d; + best = i; + } + printf("%d %f\n", i, d); + free_image(c); + } + return best; +} + +void composite_3d(char *f1, char *f2, char *out, int delta) +{ + if(!out) out = "out"; + image a = load_image(f1, 0,0,0); + image b = load_image(f2, 0,0,0); + int shift = best_3d_shift_r(a, b, -a.h/100, a.h/100); + + image c1 = crop_image(b, 10, shift, b.w, b.h); + float d1 = dist_array(c1.data, a.data, a.w*a.h*a.c, 100); + image c2 = crop_image(b, -10, shift, b.w, b.h); + float d2 = dist_array(c2.data, a.data, a.w*a.h*a.c, 100); + + if(d2 < d1 && 0){ + image swap = a; + a = b; + b = swap; + shift = -shift; + printf("swapped, %d\n", shift); + } + else{ + printf("%d\n", shift); + } + + image c = crop_image(b, delta, shift, a.w, a.h); + int i; + for(i = 0; i < c.w*c.h; ++i){ + c.data[i] = a.data[i]; + } + save_image(c, out); +} + +void letterbox_image_into(image im, int w, int h, image boxed) +{ + int new_w = im.w; + int new_h = im.h; + if (((float)w/im.w) < ((float)h/im.h)) { + new_w = w; + new_h = (im.h * w)/im.w; + } else { + new_h = h; + new_w = (im.w * h)/im.h; + } + image resized = resize_image(im, new_w, new_h); + embed_image(resized, boxed, (w-new_w)/2, (h-new_h)/2); + free_image(resized); +} + +image letterbox_image(image im, int w, int h) +{ + int new_w = im.w; + int new_h = im.h; + if (((float)w/im.w) < ((float)h/im.h)) { + new_w = w; + new_h = (im.h * w)/im.w; + } else { + new_h = h; + new_w = (im.w * h)/im.h; + } + image resized = resize_image(im, new_w, new_h); + image boxed = make_image(w, h, im.c); + fill_image(boxed, .5); + //int i; + //for(i = 0; i < boxed.w*boxed.h*boxed.c; ++i) boxed.data[i] = 0; + embed_image(resized, boxed, (w-new_w)/2, (h-new_h)/2); + free_image(resized); + return boxed; +} + +image resize_max(image im, int max) +{ + int w = im.w; + int h = im.h; + if(w > h){ + h = (h * max) / w; + w = max; + } else { + w = (w * max) / h; + h = max; + } + if(w == im.w && h == im.h) return im; + image resized = resize_image(im, w, h); + return resized; +} + +image resize_min(image im, int min) +{ + int w = im.w; + int h = im.h; + if(w < h){ + h = (h * min) / w; + w = min; + } else { + w = (w * min) / h; + h = min; + } + if(w == im.w && h == im.h) return im; + image resized = resize_image(im, w, h); + return resized; +} + +image random_crop_image(image im, int w, int h) +{ + int dx = rand_int(0, im.w - w); + int dy = rand_int(0, im.h - h); + image crop = crop_image(im, dx, dy, w, h); + return crop; +} + +augment_args random_augment_args(image im, float angle, float aspect, int low, int high, int w, int h) +{ + augment_args a = {0}; + aspect = rand_scale(aspect); + int r = rand_int(low, high); + int min = (im.h < im.w*aspect) ? im.h : im.w*aspect; + float scale = (float)r / min; + + float rad = rand_uniform(-angle, angle) * TWO_PI / 360.; + + float dx = (im.w*scale/aspect - w) / 2.; + float dy = (im.h*scale - w) / 2.; + //if(dx < 0) dx = 0; + //if(dy < 0) dy = 0; + dx = rand_uniform(-dx, dx); + dy = rand_uniform(-dy, dy); + + a.rad = rad; + a.scale = scale; + a.w = w; + a.h = h; + a.dx = dx; + a.dy = dy; + a.aspect = aspect; + return a; +} + +image random_augment_image(image im, float angle, float aspect, int low, int high, int w, int h) +{ + augment_args a = random_augment_args(im, angle, aspect, low, high, w, h); + image crop = rotate_crop_image(im, a.rad, a.scale, a.w, a.h, a.dx, a.dy, a.aspect); + return crop; +} + +float three_way_max(float a, float b, float c) +{ + return (a > b) ? ( (a > c) ? a : c) : ( (b > c) ? b : c) ; +} + +float three_way_min(float a, float b, float c) +{ + return (a < b) ? ( (a < c) ? a : c) : ( (b < c) ? b : c) ; +} + +void yuv_to_rgb(image im) +{ + assert(im.c == 3); + int i, j; + float r, g, b; + float y, u, v; + for(j = 0; j < im.h; ++j){ + for(i = 0; i < im.w; ++i){ + y = get_pixel(im, i , j, 0); + u = get_pixel(im, i , j, 1); + v = get_pixel(im, i , j, 2); + + r = y + 1.13983*v; + g = y + -.39465*u + -.58060*v; + b = y + 2.03211*u; + + set_pixel(im, i, j, 0, r); + set_pixel(im, i, j, 1, g); + set_pixel(im, i, j, 2, b); + } + } +} + +void rgb_to_yuv(image im) +{ + assert(im.c == 3); + int i, j; + float r, g, b; + float y, u, v; + for(j = 0; j < im.h; ++j){ + for(i = 0; i < im.w; ++i){ + r = get_pixel(im, i , j, 0); + g = get_pixel(im, i , j, 1); + b = get_pixel(im, i , j, 2); + + y = .299*r + .587*g + .114*b; + u = -.14713*r + -.28886*g + .436*b; + v = .615*r + -.51499*g + -.10001*b; + + set_pixel(im, i, j, 0, y); + set_pixel(im, i, j, 1, u); + set_pixel(im, i, j, 2, v); + } + } +} + +// http://www.cs.rit.edu/~ncs/color/t_convert.html +void rgb_to_hsv(image im) +{ + assert(im.c == 3); + int i, j; + float r, g, b; + float h, s, v; + for(j = 0; j < im.h; ++j){ + for(i = 0; i < im.w; ++i){ + r = get_pixel(im, i , j, 0); + g = get_pixel(im, i , j, 1); + b = get_pixel(im, i , j, 2); + float max = three_way_max(r,g,b); + float min = three_way_min(r,g,b); + float delta = max - min; + v = max; + if(max == 0){ + s = 0; + h = 0; + }else{ + s = delta/max; + if(r == max){ + h = (g - b) / delta; + } else if (g == max) { + h = 2 + (b - r) / delta; + } else { + h = 4 + (r - g) / delta; + } + if (h < 0) h += 6; + h = h/6.; + } + set_pixel(im, i, j, 0, h); + set_pixel(im, i, j, 1, s); + set_pixel(im, i, j, 2, v); + } + } +} + +void hsv_to_rgb(image im) +{ + assert(im.c == 3); + int i, j; + float r, g, b; + float h, s, v; + float f, p, q, t; + for(j = 0; j < im.h; ++j){ + for(i = 0; i < im.w; ++i){ + h = 6 * get_pixel(im, i , j, 0); + s = get_pixel(im, i , j, 1); + v = get_pixel(im, i , j, 2); + if (s == 0) { + r = g = b = v; + } else { + int index = floor(h); + f = h - index; + p = v*(1-s); + q = v*(1-s*f); + t = v*(1-s*(1-f)); + if(index == 0){ + r = v; g = t; b = p; + } else if(index == 1){ + r = q; g = v; b = p; + } else if(index == 2){ + r = p; g = v; b = t; + } else if(index == 3){ + r = p; g = q; b = v; + } else if(index == 4){ + r = t; g = p; b = v; + } else { + r = v; g = p; b = q; + } + } + set_pixel(im, i, j, 0, r); + set_pixel(im, i, j, 1, g); + set_pixel(im, i, j, 2, b); + } + } +} + +void grayscale_image_3c(image im) +{ + assert(im.c == 3); + int i, j, k; + float scale[] = {0.299, 0.587, 0.114}; + for(j = 0; j < im.h; ++j){ + for(i = 0; i < im.w; ++i){ + float val = 0; + for(k = 0; k < 3; ++k){ + val += scale[k]*get_pixel(im, i, j, k); + } + im.data[0*im.h*im.w + im.w*j + i] = val; + im.data[1*im.h*im.w + im.w*j + i] = val; + im.data[2*im.h*im.w + im.w*j + i] = val; + } + } +} + +image grayscale_image(image im) +{ + assert(im.c == 3); + int i, j, k; + image gray = make_image(im.w, im.h, 1); + float scale[] = {0.299, 0.587, 0.114}; + for(k = 0; k < im.c; ++k){ + for(j = 0; j < im.h; ++j){ + for(i = 0; i < im.w; ++i){ + gray.data[i+im.w*j] += scale[k]*get_pixel(im, i, j, k); + } + } + } + return gray; +} + +image threshold_image(image im, float thresh) +{ + int i; + image t = make_image(im.w, im.h, im.c); + for(i = 0; i < im.w*im.h*im.c; ++i){ + t.data[i] = im.data[i]>thresh ? 1 : 0; + } + return t; +} + +image blend_image(image fore, image back, float alpha) +{ + assert(fore.w == back.w && fore.h == back.h && fore.c == back.c); + image blend = make_image(fore.w, fore.h, fore.c); + int i, j, k; + for(k = 0; k < fore.c; ++k){ + for(j = 0; j < fore.h; ++j){ + for(i = 0; i < fore.w; ++i){ + float val = alpha * get_pixel(fore, i, j, k) + + (1 - alpha)* get_pixel(back, i, j, k); + set_pixel(blend, i, j, k, val); + } + } + } + return blend; +} + +void scale_image_channel(image im, int c, float v) +{ + int i, j; + for(j = 0; j < im.h; ++j){ + for(i = 0; i < im.w; ++i){ + float pix = get_pixel(im, i, j, c); + pix = pix*v; + set_pixel(im, i, j, c, pix); + } + } +} + +void translate_image_channel(image im, int c, float v) +{ + int i, j; + for(j = 0; j < im.h; ++j){ + for(i = 0; i < im.w; ++i){ + float pix = get_pixel(im, i, j, c); + pix = pix+v; + set_pixel(im, i, j, c, pix); + } + } +} + +image binarize_image(image im) +{ + image c = copy_image(im); + int i; + for(i = 0; i < im.w * im.h * im.c; ++i){ + if(c.data[i] > .5) c.data[i] = 1; + else c.data[i] = 0; + } + return c; +} + +void saturate_image(image im, float sat) +{ + rgb_to_hsv(im); + scale_image_channel(im, 1, sat); + hsv_to_rgb(im); + constrain_image(im); +} + +void hue_image(image im, float hue) +{ + rgb_to_hsv(im); + int i; + for(i = 0; i < im.w*im.h; ++i){ + im.data[i] = im.data[i] + hue; + if (im.data[i] > 1) im.data[i] -= 1; + if (im.data[i] < 0) im.data[i] += 1; + } + hsv_to_rgb(im); + constrain_image(im); +} + +void exposure_image(image im, float sat) +{ + rgb_to_hsv(im); + scale_image_channel(im, 2, sat); + hsv_to_rgb(im); + constrain_image(im); +} + +void distort_image(image im, float hue, float sat, float val) +{ + rgb_to_hsv(im); + scale_image_channel(im, 1, sat); + scale_image_channel(im, 2, val); + int i; + for(i = 0; i < im.w*im.h; ++i){ + im.data[i] = im.data[i] + hue; + if (im.data[i] > 1) im.data[i] -= 1; + if (im.data[i] < 0) im.data[i] += 1; + } + hsv_to_rgb(im); + constrain_image(im); +} + +void random_distort_image(image im, float hue, float saturation, float exposure) +{ + float dhue = rand_uniform(-hue, hue); + float dsat = rand_scale(saturation); + float dexp = rand_scale(exposure); + distort_image(im, dhue, dsat, dexp); +} + +void saturate_exposure_image(image im, float sat, float exposure) +{ + rgb_to_hsv(im); + scale_image_channel(im, 1, sat); + scale_image_channel(im, 2, exposure); + hsv_to_rgb(im); + constrain_image(im); +} + +image resize_image(image im, int w, int h) +{ + image resized = make_image(w, h, im.c); + image part = make_image(w, im.h, im.c); + int r, c, k; + float w_scale = (float)(im.w - 1) / (w - 1); + float h_scale = (float)(im.h - 1) / (h - 1); + for(k = 0; k < im.c; ++k){ + for(r = 0; r < im.h; ++r){ + for(c = 0; c < w; ++c){ + float val = 0; + if(c == w-1 || im.w == 1){ + val = get_pixel(im, im.w-1, r, k); + } else { + float sx = c*w_scale; + int ix = (int) sx; + float dx = sx - ix; + val = (1 - dx) * get_pixel(im, ix, r, k) + dx * get_pixel(im, ix+1, r, k); + } + set_pixel(part, c, r, k, val); + } + } + } + for(k = 0; k < im.c; ++k){ + for(r = 0; r < h; ++r){ + float sy = r*h_scale; + int iy = (int) sy; + float dy = sy - iy; + for(c = 0; c < w; ++c){ + float val = (1-dy) * get_pixel(part, c, iy, k); + set_pixel(resized, c, r, k, val); + } + if(r == h-1 || im.h == 1) continue; + for(c = 0; c < w; ++c){ + float val = dy * get_pixel(part, c, iy+1, k); + add_pixel(resized, c, r, k, val); + } + } + } + + free_image(part); + return resized; +} + + +void test_resize(char *filename) +{ + image im = load_image(filename, 0,0, 3); + float mag = mag_array(im.data, im.w*im.h*im.c); + printf("L2 Norm: %f\n", mag); + image gray = grayscale_image(im); + + image c1 = copy_image(im); + image c2 = copy_image(im); + image c3 = copy_image(im); + image c4 = copy_image(im); + distort_image(c1, .1, 1.5, 1.5); + distort_image(c2, -.1, .66666, .66666); + distort_image(c3, .1, 1.5, .66666); + distort_image(c4, .1, .66666, 1.5); + + + show_image(im, "Original", 1); + show_image(gray, "Gray", 1); + show_image(c1, "C1", 1); + show_image(c2, "C2", 1); + show_image(c3, "C3", 1); + show_image(c4, "C4", 1); +#ifdef OPENCV + while(1){ + image aug = random_augment_image(im, 0, .75, 320, 448, 320, 320); + show_image(aug, "aug", 1); + free_image(aug); + + + float exposure = 1.15; + float saturation = 1.15; + float hue = .05; + + image c = copy_image(im); + + float dexp = rand_scale(exposure); + float dsat = rand_scale(saturation); + float dhue = rand_uniform(-hue, hue); + + distort_image(c, dhue, dsat, dexp); + show_image(c, "rand", 1); + printf("%f %f %f\n", dhue, dsat, dexp); + free_image(c); + } +#endif +} + + +image load_image_stb(char *filename, int channels) +{ + int w, h, c; + unsigned char *data = stbi_load(filename, &w, &h, &c, channels); + if (!data) { + fprintf(stderr, "Cannot load image \"%s\"\nSTB Reason: %s\n", filename, stbi_failure_reason()); + exit(0); + } + if(channels) c = channels; + int i,j,k; + image im = make_image(w, h, c); + for(k = 0; k < c; ++k){ + for(j = 0; j < h; ++j){ + for(i = 0; i < w; ++i){ + int dst_index = i + w*j + w*h*k; + int src_index = k + c*i + c*w*j; + im.data[dst_index] = (float)data[src_index]/255.; + } + } + } + free(data); + return im; +} + +image load_image(char *filename, int w, int h, int c) +{ +#ifdef OPENCV + image out = load_image_cv(filename, c); +#else + image out = load_image_stb(filename, c); +#endif + + if((h && w) && (h != out.h || w != out.w)){ + image resized = resize_image(out, w, h); + free_image(out); + out = resized; + } + return out; +} + +image load_image_color(char *filename, int w, int h) +{ + return load_image(filename, w, h, 3); +} + +image get_image_layer(image m, int l) +{ + image out = make_image(m.w, m.h, 1); + int i; + for(i = 0; i < m.h*m.w; ++i){ + out.data[i] = m.data[i+l*m.h*m.w]; + } + return out; +} +void print_image(image m) +{ + int i, j, k; + for(i =0 ; i < m.c; ++i){ + for(j =0 ; j < m.h; ++j){ + for(k = 0; k < m.w; ++k){ + printf("%.2lf, ", m.data[i*m.h*m.w + j*m.w + k]); + if(k > 30) break; + } + printf("\n"); + if(j > 30) break; + } + printf("\n"); + } + printf("\n"); +} + +image collapse_images_vert(image *ims, int n) +{ + int color = 1; + int border = 1; + int h,w,c; + w = ims[0].w; + h = (ims[0].h + border) * n - border; + c = ims[0].c; + if(c != 3 || !color){ + w = (w+border)*c - border; + c = 1; + } + + image filters = make_image(w, h, c); + int i,j; + for(i = 0; i < n; ++i){ + int h_offset = i*(ims[0].h+border); + image copy = copy_image(ims[i]); + //normalize_image(copy); + if(c == 3 && color){ + embed_image(copy, filters, 0, h_offset); + } + else{ + for(j = 0; j < copy.c; ++j){ + int w_offset = j*(ims[0].w+border); + image layer = get_image_layer(copy, j); + embed_image(layer, filters, w_offset, h_offset); + free_image(layer); + } + } + free_image(copy); + } + return filters; +} + +image collapse_images_horz(image *ims, int n) +{ + int color = 1; + int border = 1; + int h,w,c; + int size = ims[0].h; + h = size; + w = (ims[0].w + border) * n - border; + c = ims[0].c; + if(c != 3 || !color){ + h = (h+border)*c - border; + c = 1; + } + + image filters = make_image(w, h, c); + int i,j; + for(i = 0; i < n; ++i){ + int w_offset = i*(size+border); + image copy = copy_image(ims[i]); + //normalize_image(copy); + if(c == 3 && color){ + embed_image(copy, filters, w_offset, 0); + } + else{ + for(j = 0; j < copy.c; ++j){ + int h_offset = j*(size+border); + image layer = get_image_layer(copy, j); + embed_image(layer, filters, w_offset, h_offset); + free_image(layer); + } + } + free_image(copy); + } + return filters; +} + +void show_image_normalized(image im, const char *name) +{ + image c = copy_image(im); + normalize_image(c); + show_image(c, name, 1); + free_image(c); +} + +void show_images(image *ims, int n, char *window) +{ + image m = collapse_images_vert(ims, n); + /* + int w = 448; + int h = ((float)m.h/m.w) * 448; + if(h > 896){ + h = 896; + w = ((float)m.w/m.h) * 896; + } + image sized = resize_image(m, w, h); + */ + normalize_image(m); + save_image(m, window); + show_image(m, window, 1); + free_image(m); +} + +void free_image(image m) +{ + if(m.data){ + free(m.data); + } +} diff --git a/hanzi_detection/src/image.h b/hanzi_detection/src/image.h new file mode 100755 index 0000000..3392bb9 --- /dev/null +++ b/hanzi_detection/src/image.h @@ -0,0 +1,69 @@ +#ifndef IMAGE_H +#define IMAGE_H + +#include +#include +#include +#include +#include +#include "box.h" +#include "darknet.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENCV +void *open_video_stream(const char *f, int c, int w, int h, int fps); +image get_image_from_stream(void *p); +image load_image_cv(char *filename, int channels); +int show_image_cv(image im, const char* name, int ms); +#endif + +float get_color(int c, int x, int max); +void draw_box(image a, int x1, int y1, int x2, int y2, float r, float g, float b); +void draw_bbox(image a, box bbox, int w, float r, float g, float b); +void write_label(image a, int r, int c, image *characters, char *string, float *rgb); +image image_distance(image a, image b); +void scale_image(image m, float s); +image rotate_crop_image(image im, float rad, float s, int w, int h, float dx, float dy, float aspect); +image random_crop_image(image im, int w, int h); +image random_augment_image(image im, float angle, float aspect, int low, int high, int w, int h); +augment_args random_augment_args(image im, float angle, float aspect, int low, int high, int w, int h); +void letterbox_image_into(image im, int w, int h, image boxed); +image resize_max(image im, int max); +void translate_image(image m, float s); +void embed_image(image source, image dest, int dx, int dy); +void place_image(image im, int w, int h, int dx, int dy, image canvas); +void saturate_image(image im, float sat); +void exposure_image(image im, float sat); +void distort_image(image im, float hue, float sat, float val); +void saturate_exposure_image(image im, float sat, float exposure); +void rgb_to_hsv(image im); +void hsv_to_rgb(image im); +void yuv_to_rgb(image im); +void rgb_to_yuv(image im); + + +image collapse_image_layers(image source, int border); +image collapse_images_horz(image *ims, int n); +image collapse_images_vert(image *ims, int n); + +void show_image_normalized(image im, const char *name); +void show_images(image *ims, int n, char *window); +void show_image_layers(image p, char *name); +void show_image_collapsed(image p, char *name); + +void print_image(image m); + +image make_empty_image(int w, int h, int c); +void copy_image_into(image src, image dest); + +image get_image_layer(image m, int l); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/hanzi_detection/src/image_opencv.cpp b/hanzi_detection/src/image_opencv.cpp new file mode 100755 index 0000000..9d9e501 --- /dev/null +++ b/hanzi_detection/src/image_opencv.cpp @@ -0,0 +1,121 @@ +#ifdef OPENCV + +#include "stdio.h" +#include "stdlib.h" +#include "opencv2/opencv.hpp" +#include "image.h" + +using namespace cv; + +extern "C" { + +Mat image_to_mat(image im) +{ + image copy = copy_image(im); + constrain_image(copy); + if(im.c == 3) rgbgr_image(copy); + + Mat m(cv::Size(im.w,im.h), CV_8UC(im.c)); + int x,y,c; + + int step = m.step; + for(y = 0; y < im.h; ++y){ + for(x = 0; x < im.w; ++x){ + for(c= 0; c < im.c; ++c){ + float val = im.data[c*im.h*im.w + y*im.w + x]; + m.data[y*step + x*im.c + c] = (unsigned char)(val*255); + } + } + } + + free_image(copy); + return m; +} + +image mat_to_image(Mat m) +{ + int h = m.rows; + int w = m.cols; + int c = m.channels(); + image im = make_image(w, h, c); + unsigned char *data = (unsigned char *)m.data; + int step = m.step; + int i, j, k; + + for(i = 0; i < h; ++i){ + for(k= 0; k < c; ++k){ + for(j = 0; j < w; ++j){ + im.data[k*w*h + i*w + j] = data[i*step + j*c + k]/255.; + } + } + } + rgbgr_image(im); + return im; +} + +void *open_video_stream(const char *f, int c, int w, int h, int fps) +{ + VideoCapture *cap; + if(f) cap = new VideoCapture(f); + else cap = new VideoCapture(c); + if(!cap->isOpened()) return 0; + if(w) cap->set(CAP_PROP_FRAME_WIDTH, w); + if(h) cap->set(CAP_PROP_FRAME_HEIGHT, w); + if(fps) cap->set(CAP_PROP_FPS, w); + return (void *) cap; +} + +image get_image_from_stream(void *p) +{ + VideoCapture *cap = (VideoCapture *)p; + Mat m; + *cap >> m; + if(m.empty()) return make_empty_image(0,0,0); + return mat_to_image(m); +} + +image load_image_cv(char *filename, int channels) +{ + int flag = -1; + if (channels == 0) flag = -1; + else if (channels == 1) flag = 0; + else if (channels == 3) flag = 1; + else { + fprintf(stderr, "OpenCV can't force load with %d channels\n", channels); + } + Mat m; + m = imread(filename, flag); + if(!m.data){ + fprintf(stderr, "Cannot load image \"%s\"\n", filename); + char buff[256]; + sprintf(buff, "echo %s >> bad.list", filename); + system(buff); + return make_image(10,10,3); + //exit(0); + } + image im = mat_to_image(m); + return im; +} + +int show_image_cv(image im, const char* name, int ms) +{ + Mat m = image_to_mat(im); + imshow(name, m); + int c = waitKey(ms); + if (c != -1) c = c%256; + return c; +} + +void make_window(char *name, int w, int h, int fullscreen) +{ + namedWindow(name, WINDOW_NORMAL); + if (fullscreen) { + setWindowProperty(name, WND_PROP_FULLSCREEN, WINDOW_FULLSCREEN); + } else { + resizeWindow(name, w, h); + if(strcmp(name, "Demo") == 0) moveWindow(name, 0, 0); + } +} + +} +#endif diff --git a/hanzi_detection/src/iseg_layer.c b/hanzi_detection/src/iseg_layer.c new file mode 100755 index 0000000..2bf03a8 --- /dev/null +++ b/hanzi_detection/src/iseg_layer.c @@ -0,0 +1,225 @@ +#include "iseg_layer.h" +#include "activations.h" +#include "blas.h" +#include "box.h" +#include "cuda.h" +#include "utils.h" + +#include +#include +#include +#include + +layer make_iseg_layer(int batch, int w, int h, int classes, int ids) +{ + layer l = {0}; + l.type = ISEG; + + l.h = h; + l.w = w; + l.c = classes + ids; + l.out_w = l.w; + l.out_h = l.h; + l.out_c = l.c; + l.classes = classes; + l.batch = batch; + l.extra = ids; + l.cost = calloc(1, sizeof(float)); + l.outputs = h*w*l.c; + l.inputs = l.outputs; + l.truths = 90*(l.w*l.h+1); + l.delta = calloc(batch*l.outputs, sizeof(float)); + l.output = calloc(batch*l.outputs, sizeof(float)); + + l.counts = calloc(90, sizeof(int)); + l.sums = calloc(90, sizeof(float*)); + if(ids){ + int i; + for(i = 0; i < 90; ++i){ + l.sums[i] = calloc(ids, sizeof(float)); + } + } + + l.forward = forward_iseg_layer; + l.backward = backward_iseg_layer; +#ifdef GPU + l.forward_gpu = forward_iseg_layer_gpu; + l.backward_gpu = backward_iseg_layer_gpu; + l.output_gpu = cuda_make_array(l.output, batch*l.outputs); + l.delta_gpu = cuda_make_array(l.delta, batch*l.outputs); +#endif + + fprintf(stderr, "iseg\n"); + srand(0); + + return l; +} + +void resize_iseg_layer(layer *l, int w, int h) +{ + l->w = w; + l->h = h; + + l->outputs = h*w*l->c; + l->inputs = l->outputs; + + l->output = realloc(l->output, l->batch*l->outputs*sizeof(float)); + l->delta = realloc(l->delta, l->batch*l->outputs*sizeof(float)); + +#ifdef GPU + cuda_free(l->delta_gpu); + cuda_free(l->output_gpu); + + l->delta_gpu = cuda_make_array(l->delta, l->batch*l->outputs); + l->output_gpu = cuda_make_array(l->output, l->batch*l->outputs); +#endif +} + +void forward_iseg_layer(const layer l, network net) +{ + + double time = what_time_is_it_now(); + int i,b,j,k; + int ids = l.extra; + memcpy(l.output, net.input, l.outputs*l.batch*sizeof(float)); + memset(l.delta, 0, l.outputs * l.batch * sizeof(float)); + +#ifndef GPU + for (b = 0; b < l.batch; ++b){ + int index = b*l.outputs; + activate_array(l.output + index, l.classes*l.w*l.h, LOGISTIC); + } +#endif + + for (b = 0; b < l.batch; ++b){ + // a priori, each pixel has no class + for(i = 0; i < l.classes; ++i){ + for(k = 0; k < l.w*l.h; ++k){ + int index = b*l.outputs + i*l.w*l.h + k; + l.delta[index] = 0 - l.output[index]; + } + } + + // a priori, embedding should be small magnitude + for(i = 0; i < ids; ++i){ + for(k = 0; k < l.w*l.h; ++k){ + int index = b*l.outputs + (i+l.classes)*l.w*l.h + k; + l.delta[index] = .1 * (0 - l.output[index]); + } + } + + + memset(l.counts, 0, 90*sizeof(int)); + for(i = 0; i < 90; ++i){ + fill_cpu(ids, 0, l.sums[i], 1); + + int c = net.truth[b*l.truths + i*(l.w*l.h+1)]; + if(c < 0) break; + // add up metric embeddings for each instance + for(k = 0; k < l.w*l.h; ++k){ + int index = b*l.outputs + c*l.w*l.h + k; + float v = net.truth[b*l.truths + i*(l.w*l.h + 1) + 1 + k]; + if(v){ + l.delta[index] = v - l.output[index]; + axpy_cpu(ids, 1, l.output + b*l.outputs + l.classes*l.w*l.h + k, l.w*l.h, l.sums[i], 1); + ++l.counts[i]; + } + } + } + + float *mse = calloc(90, sizeof(float)); + for(i = 0; i < 90; ++i){ + int c = net.truth[b*l.truths + i*(l.w*l.h+1)]; + if(c < 0) break; + for(k = 0; k < l.w*l.h; ++k){ + float v = net.truth[b*l.truths + i*(l.w*l.h + 1) + 1 + k]; + if(v){ + int z; + float sum = 0; + for(z = 0; z < ids; ++z){ + int index = b*l.outputs + (l.classes + z)*l.w*l.h + k; + sum += pow(l.sums[i][z]/l.counts[i] - l.output[index], 2); + } + mse[i] += sum; + } + } + mse[i] /= l.counts[i]; + } + + // Calculate average embedding + for(i = 0; i < 90; ++i){ + if(!l.counts[i]) continue; + scal_cpu(ids, 1.f/l.counts[i], l.sums[i], 1); + if(b == 0 && net.gpu_index == 0){ + printf("%4d, %6.3f, ", l.counts[i], mse[i]); + for(j = 0; j < ids; ++j){ + printf("%6.3f,", l.sums[i][j]); + } + printf("\n"); + } + } + free(mse); + + // Calculate embedding loss + for(i = 0; i < 90; ++i){ + if(!l.counts[i]) continue; + for(k = 0; k < l.w*l.h; ++k){ + float v = net.truth[b*l.truths + i*(l.w*l.h + 1) + 1 + k]; + if(v){ + for(j = 0; j < 90; ++j){ + if(!l.counts[j])continue; + int z; + for(z = 0; z < ids; ++z){ + int index = b*l.outputs + (l.classes + z)*l.w*l.h + k; + float diff = l.sums[j][z] - l.output[index]; + if (j == i) l.delta[index] += diff < 0? -.1 : .1; + else l.delta[index] += -(diff < 0? -.1 : .1); + } + } + } + } + } + + for(i = 0; i < ids; ++i){ + for(k = 0; k < l.w*l.h; ++k){ + int index = b*l.outputs + (i+l.classes)*l.w*l.h + k; + l.delta[index] *= .01; + } + } + } + + *(l.cost) = pow(mag_array(l.delta, l.outputs * l.batch), 2); + printf("took %lf sec\n", what_time_is_it_now() - time); +} + +void backward_iseg_layer(const layer l, network net) +{ + axpy_cpu(l.batch*l.inputs, 1, l.delta, 1, net.delta, 1); +} + +#ifdef GPU + +void forward_iseg_layer_gpu(const layer l, network net) +{ + copy_gpu(l.batch*l.inputs, net.input_gpu, 1, l.output_gpu, 1); + int b; + for (b = 0; b < l.batch; ++b){ + activate_array_gpu(l.output_gpu + b*l.outputs, l.classes*l.w*l.h, LOGISTIC); + //if(l.extra) activate_array_gpu(l.output_gpu + b*l.outputs + l.classes*l.w*l.h, l.extra*l.w*l.h, LOGISTIC); + } + + cuda_pull_array(l.output_gpu, net.input, l.batch*l.inputs); + forward_iseg_layer(l, net); + cuda_push_array(l.delta_gpu, l.delta, l.batch*l.outputs); +} + +void backward_iseg_layer_gpu(const layer l, network net) +{ + int b; + for (b = 0; b < l.batch; ++b){ + //if(l.extra) gradient_array_gpu(l.output_gpu + b*l.outputs + l.classes*l.w*l.h, l.extra*l.w*l.h, LOGISTIC, l.delta_gpu + b*l.outputs + l.classes*l.w*l.h); + } + axpy_gpu(l.batch*l.inputs, 1, l.delta_gpu, 1, net.delta_gpu, 1); +} +#endif + diff --git a/hanzi_detection/src/iseg_layer.h b/hanzi_detection/src/iseg_layer.h new file mode 100755 index 0000000..dd8e64e --- /dev/null +++ b/hanzi_detection/src/iseg_layer.h @@ -0,0 +1,19 @@ +#ifndef ISEG_LAYER_H +#define ISEG_LAYER_H + +#include "darknet.h" +#include "layer.h" +#include "network.h" + +layer make_iseg_layer(int batch, int w, int h, int classes, int ids); +void forward_iseg_layer(const layer l, network net); +void backward_iseg_layer(const layer l, network net); +void resize_iseg_layer(layer *l, int w, int h); +int iseg_num_detections(layer l, float thresh); + +#ifdef GPU +void forward_iseg_layer_gpu(const layer l, network net); +void backward_iseg_layer_gpu(layer l, network net); +#endif + +#endif diff --git a/hanzi_detection/src/l2norm_layer.c b/hanzi_detection/src/l2norm_layer.c new file mode 100755 index 0000000..d099479 --- /dev/null +++ b/hanzi_detection/src/l2norm_layer.c @@ -0,0 +1,63 @@ +#include "l2norm_layer.h" +#include "activations.h" +#include "blas.h" +#include "cuda.h" + +#include +#include +#include +#include +#include + +layer make_l2norm_layer(int batch, int inputs) +{ + fprintf(stderr, "l2norm %4d\n", inputs); + layer l = {0}; + l.type = L2NORM; + l.batch = batch; + l.inputs = inputs; + l.outputs = inputs; + l.output = calloc(inputs*batch, sizeof(float)); + l.scales = calloc(inputs*batch, sizeof(float)); + l.delta = calloc(inputs*batch, sizeof(float)); + + l.forward = forward_l2norm_layer; + l.backward = backward_l2norm_layer; + #ifdef GPU + l.forward_gpu = forward_l2norm_layer_gpu; + l.backward_gpu = backward_l2norm_layer_gpu; + + l.output_gpu = cuda_make_array(l.output, inputs*batch); + l.scales_gpu = cuda_make_array(l.output, inputs*batch); + l.delta_gpu = cuda_make_array(l.delta, inputs*batch); + #endif + return l; +} + +void forward_l2norm_layer(const layer l, network net) +{ + copy_cpu(l.outputs*l.batch, net.input, 1, l.output, 1); + l2normalize_cpu(l.output, l.scales, l.batch, l.out_c, l.out_w*l.out_h); +} + +void backward_l2norm_layer(const layer l, network net) +{ + //axpy_cpu(l.inputs*l.batch, 1, l.scales, 1, l.delta, 1); + axpy_cpu(l.inputs*l.batch, 1, l.delta, 1, net.delta, 1); +} + +#ifdef GPU + +void forward_l2norm_layer_gpu(const layer l, network net) +{ + copy_gpu(l.outputs*l.batch, net.input_gpu, 1, l.output_gpu, 1); + l2normalize_gpu(l.output_gpu, l.scales_gpu, l.batch, l.out_c, l.out_w*l.out_h); +} + +void backward_l2norm_layer_gpu(const layer l, network net) +{ + axpy_gpu(l.batch*l.inputs, 1, l.scales_gpu, 1, l.delta_gpu, 1); + axpy_gpu(l.batch*l.inputs, 1, l.delta_gpu, 1, net.delta_gpu, 1); +} + +#endif diff --git a/hanzi_detection/src/l2norm_layer.h b/hanzi_detection/src/l2norm_layer.h new file mode 100755 index 0000000..1ca6f71 --- /dev/null +++ b/hanzi_detection/src/l2norm_layer.h @@ -0,0 +1,15 @@ +#ifndef L2NORM_LAYER_H +#define L2NORM_LAYER_H +#include "layer.h" +#include "network.h" + +layer make_l2norm_layer(int batch, int inputs); +void forward_l2norm_layer(const layer l, network net); +void backward_l2norm_layer(const layer l, network net); + +#ifdef GPU +void forward_l2norm_layer_gpu(const layer l, network net); +void backward_l2norm_layer_gpu(const layer l, network net); +#endif + +#endif diff --git a/hanzi_detection/src/layer.c b/hanzi_detection/src/layer.c new file mode 100755 index 0000000..c27b477 --- /dev/null +++ b/hanzi_detection/src/layer.c @@ -0,0 +1,97 @@ +#include "layer.h" +#include "cuda.h" + +#include + +void free_layer(layer l) +{ + if(l.type == DROPOUT){ + if(l.rand) free(l.rand); +#ifdef GPU + if(l.rand_gpu) cuda_free(l.rand_gpu); +#endif + return; + } + if(l.cweights) free(l.cweights); + if(l.indexes) free(l.indexes); + if(l.input_layers) free(l.input_layers); + if(l.input_sizes) free(l.input_sizes); + if(l.map) free(l.map); + if(l.rand) free(l.rand); + if(l.cost) free(l.cost); + if(l.state) free(l.state); + if(l.prev_state) free(l.prev_state); + if(l.forgot_state) free(l.forgot_state); + if(l.forgot_delta) free(l.forgot_delta); + if(l.state_delta) free(l.state_delta); + if(l.concat) free(l.concat); + if(l.concat_delta) free(l.concat_delta); + if(l.binary_weights) free(l.binary_weights); + if(l.biases) free(l.biases); + if(l.bias_updates) free(l.bias_updates); + if(l.scales) free(l.scales); + if(l.scale_updates) free(l.scale_updates); + if(l.weights) free(l.weights); + if(l.weight_updates) free(l.weight_updates); + if(l.delta) free(l.delta); + if(l.output) free(l.output); + if(l.squared) free(l.squared); + if(l.norms) free(l.norms); + if(l.spatial_mean) free(l.spatial_mean); + if(l.mean) free(l.mean); + if(l.variance) free(l.variance); + if(l.mean_delta) free(l.mean_delta); + if(l.variance_delta) free(l.variance_delta); + if(l.rolling_mean) free(l.rolling_mean); + if(l.rolling_variance) free(l.rolling_variance); + if(l.x) free(l.x); + if(l.x_norm) free(l.x_norm); + if(l.m) free(l.m); + if(l.v) free(l.v); + if(l.z_cpu) free(l.z_cpu); + if(l.r_cpu) free(l.r_cpu); + if(l.h_cpu) free(l.h_cpu); + if(l.binary_input) free(l.binary_input); + +#ifdef GPU + if(l.indexes_gpu) cuda_free((float *)l.indexes_gpu); + + if(l.z_gpu) cuda_free(l.z_gpu); + if(l.r_gpu) cuda_free(l.r_gpu); + if(l.h_gpu) cuda_free(l.h_gpu); + if(l.m_gpu) cuda_free(l.m_gpu); + if(l.v_gpu) cuda_free(l.v_gpu); + if(l.prev_state_gpu) cuda_free(l.prev_state_gpu); + if(l.forgot_state_gpu) cuda_free(l.forgot_state_gpu); + if(l.forgot_delta_gpu) cuda_free(l.forgot_delta_gpu); + if(l.state_gpu) cuda_free(l.state_gpu); + if(l.state_delta_gpu) cuda_free(l.state_delta_gpu); + if(l.gate_gpu) cuda_free(l.gate_gpu); + if(l.gate_delta_gpu) cuda_free(l.gate_delta_gpu); + if(l.save_gpu) cuda_free(l.save_gpu); + if(l.save_delta_gpu) cuda_free(l.save_delta_gpu); + if(l.concat_gpu) cuda_free(l.concat_gpu); + if(l.concat_delta_gpu) cuda_free(l.concat_delta_gpu); + if(l.binary_input_gpu) cuda_free(l.binary_input_gpu); + if(l.binary_weights_gpu) cuda_free(l.binary_weights_gpu); + if(l.mean_gpu) cuda_free(l.mean_gpu); + if(l.variance_gpu) cuda_free(l.variance_gpu); + if(l.rolling_mean_gpu) cuda_free(l.rolling_mean_gpu); + if(l.rolling_variance_gpu) cuda_free(l.rolling_variance_gpu); + if(l.variance_delta_gpu) cuda_free(l.variance_delta_gpu); + if(l.mean_delta_gpu) cuda_free(l.mean_delta_gpu); + if(l.x_gpu) cuda_free(l.x_gpu); + if(l.x_norm_gpu) cuda_free(l.x_norm_gpu); + if(l.weights_gpu) cuda_free(l.weights_gpu); + if(l.weight_updates_gpu) cuda_free(l.weight_updates_gpu); + if(l.biases_gpu) cuda_free(l.biases_gpu); + if(l.bias_updates_gpu) cuda_free(l.bias_updates_gpu); + if(l.scales_gpu) cuda_free(l.scales_gpu); + if(l.scale_updates_gpu) cuda_free(l.scale_updates_gpu); + if(l.output_gpu) cuda_free(l.output_gpu); + if(l.delta_gpu) cuda_free(l.delta_gpu); + if(l.rand_gpu) cuda_free(l.rand_gpu); + if(l.squared_gpu) cuda_free(l.squared_gpu); + if(l.norms_gpu) cuda_free(l.norms_gpu); +#endif +} diff --git a/hanzi_detection/src/layer.h b/hanzi_detection/src/layer.h new file mode 100755 index 0000000..af6cd2a --- /dev/null +++ b/hanzi_detection/src/layer.h @@ -0,0 +1 @@ +#include "darknet.h" diff --git a/hanzi_detection/src/list.c b/hanzi_detection/src/list.c new file mode 100755 index 0000000..0e4165d --- /dev/null +++ b/hanzi_detection/src/list.c @@ -0,0 +1,92 @@ +#include +#include +#include "list.h" + +list *make_list() +{ + list *l = malloc(sizeof(list)); + l->size = 0; + l->front = 0; + l->back = 0; + return l; +} + +/* +void transfer_node(list *s, list *d, node *n) +{ + node *prev, *next; + prev = n->prev; + next = n->next; + if(prev) prev->next = next; + if(next) next->prev = prev; + --s->size; + if(s->front == n) s->front = next; + if(s->back == n) s->back = prev; +} +*/ + +void *list_pop(list *l){ + if(!l->back) return 0; + node *b = l->back; + void *val = b->val; + l->back = b->prev; + if(l->back) l->back->next = 0; + free(b); + --l->size; + + return val; +} + +void list_insert(list *l, void *val) +{ + node *new = malloc(sizeof(node)); + new->val = val; + new->next = 0; + + if(!l->back){ + l->front = new; + new->prev = 0; + }else{ + l->back->next = new; + new->prev = l->back; + } + l->back = new; + ++l->size; +} + +void free_node(node *n) +{ + node *next; + while(n) { + next = n->next; + free(n); + n = next; + } +} + +void free_list(list *l) +{ + free_node(l->front); + free(l); +} + +void free_list_contents(list *l) +{ + node *n = l->front; + while(n){ + free(n->val); + n = n->next; + } +} + +void **list_to_array(list *l) +{ + void **a = calloc(l->size, sizeof(void*)); + int count = 0; + node *n = l->front; + while(n){ + a[count++] = n->val; + n = n->next; + } + return a; +} diff --git a/hanzi_detection/src/list.h b/hanzi_detection/src/list.h new file mode 100755 index 0000000..6b445c7 --- /dev/null +++ b/hanzi_detection/src/list.h @@ -0,0 +1,13 @@ +#ifndef LIST_H +#define LIST_H +#include "darknet.h" + +list *make_list(); +int list_find(list *l, void *val); + +void list_insert(list *, void *); + + +void free_list_contents(list *l); + +#endif diff --git a/hanzi_detection/src/local_layer.c b/hanzi_detection/src/local_layer.c new file mode 100755 index 0000000..74f6910 --- /dev/null +++ b/hanzi_detection/src/local_layer.c @@ -0,0 +1,293 @@ +#include "local_layer.h" +#include "utils.h" +#include "im2col.h" +#include "col2im.h" +#include "blas.h" +#include "gemm.h" +#include +#include + +int local_out_height(local_layer l) +{ + int h = l.h; + if (!l.pad) h -= l.size; + else h -= 1; + return h/l.stride + 1; +} + +int local_out_width(local_layer l) +{ + int w = l.w; + if (!l.pad) w -= l.size; + else w -= 1; + return w/l.stride + 1; +} + +local_layer make_local_layer(int batch, int h, int w, int c, int n, int size, int stride, int pad, ACTIVATION activation) +{ + int i; + local_layer l = {0}; + l.type = LOCAL; + + l.h = h; + l.w = w; + l.c = c; + l.n = n; + l.batch = batch; + l.stride = stride; + l.size = size; + l.pad = pad; + + int out_h = local_out_height(l); + int out_w = local_out_width(l); + int locations = out_h*out_w; + l.out_h = out_h; + l.out_w = out_w; + l.out_c = n; + l.outputs = l.out_h * l.out_w * l.out_c; + l.inputs = l.w * l.h * l.c; + + l.weights = calloc(c*n*size*size*locations, sizeof(float)); + l.weight_updates = calloc(c*n*size*size*locations, sizeof(float)); + + l.biases = calloc(l.outputs, sizeof(float)); + l.bias_updates = calloc(l.outputs, sizeof(float)); + + // float scale = 1./sqrt(size*size*c); + float scale = sqrt(2./(size*size*c)); + for(i = 0; i < c*n*size*size; ++i) l.weights[i] = scale*rand_uniform(-1,1); + + l.output = calloc(l.batch*out_h * out_w * n, sizeof(float)); + l.delta = calloc(l.batch*out_h * out_w * n, sizeof(float)); + + l.workspace_size = out_h*out_w*size*size*c; + + l.forward = forward_local_layer; + l.backward = backward_local_layer; + l.update = update_local_layer; + +#ifdef GPU + l.forward_gpu = forward_local_layer_gpu; + l.backward_gpu = backward_local_layer_gpu; + l.update_gpu = update_local_layer_gpu; + + l.weights_gpu = cuda_make_array(l.weights, c*n*size*size*locations); + l.weight_updates_gpu = cuda_make_array(l.weight_updates, c*n*size*size*locations); + + l.biases_gpu = cuda_make_array(l.biases, l.outputs); + l.bias_updates_gpu = cuda_make_array(l.bias_updates, l.outputs); + + l.delta_gpu = cuda_make_array(l.delta, l.batch*out_h*out_w*n); + l.output_gpu = cuda_make_array(l.output, l.batch*out_h*out_w*n); + +#endif + l.activation = activation; + + fprintf(stderr, "Local Layer: %d x %d x %d image, %d filters -> %d x %d x %d image\n", h,w,c,n, out_h, out_w, n); + + return l; +} + +void forward_local_layer(const local_layer l, network net) +{ + int out_h = local_out_height(l); + int out_w = local_out_width(l); + int i, j; + int locations = out_h * out_w; + + for(i = 0; i < l.batch; ++i){ + copy_cpu(l.outputs, l.biases, 1, l.output + i*l.outputs, 1); + } + + for(i = 0; i < l.batch; ++i){ + float *input = net.input + i*l.w*l.h*l.c; + im2col_cpu(input, l.c, l.h, l.w, + l.size, l.stride, l.pad, net.workspace); + float *output = l.output + i*l.outputs; + for(j = 0; j < locations; ++j){ + float *a = l.weights + j*l.size*l.size*l.c*l.n; + float *b = net.workspace + j; + float *c = output + j; + + int m = l.n; + int n = 1; + int k = l.size*l.size*l.c; + + gemm(0,0,m,n,k,1,a,k,b,locations,1,c,locations); + } + } + activate_array(l.output, l.outputs*l.batch, l.activation); +} + +void backward_local_layer(local_layer l, network net) +{ + int i, j; + int locations = l.out_w*l.out_h; + + gradient_array(l.output, l.outputs*l.batch, l.activation, l.delta); + + for(i = 0; i < l.batch; ++i){ + axpy_cpu(l.outputs, 1, l.delta + i*l.outputs, 1, l.bias_updates, 1); + } + + for(i = 0; i < l.batch; ++i){ + float *input = net.input + i*l.w*l.h*l.c; + im2col_cpu(input, l.c, l.h, l.w, + l.size, l.stride, l.pad, net.workspace); + + for(j = 0; j < locations; ++j){ + float *a = l.delta + i*l.outputs + j; + float *b = net.workspace + j; + float *c = l.weight_updates + j*l.size*l.size*l.c*l.n; + int m = l.n; + int n = l.size*l.size*l.c; + int k = 1; + + gemm(0,1,m,n,k,1,a,locations,b,locations,1,c,n); + } + + if(net.delta){ + for(j = 0; j < locations; ++j){ + float *a = l.weights + j*l.size*l.size*l.c*l.n; + float *b = l.delta + i*l.outputs + j; + float *c = net.workspace + j; + + int m = l.size*l.size*l.c; + int n = 1; + int k = l.n; + + gemm(1,0,m,n,k,1,a,m,b,locations,0,c,locations); + } + + col2im_cpu(net.workspace, l.c, l.h, l.w, l.size, l.stride, l.pad, net.delta+i*l.c*l.h*l.w); + } + } +} + +void update_local_layer(local_layer l, update_args a) +{ + float learning_rate = a.learning_rate*l.learning_rate_scale; + float momentum = a.momentum; + float decay = a.decay; + int batch = a.batch; + + int locations = l.out_w*l.out_h; + int size = l.size*l.size*l.c*l.n*locations; + axpy_cpu(l.outputs, learning_rate/batch, l.bias_updates, 1, l.biases, 1); + scal_cpu(l.outputs, momentum, l.bias_updates, 1); + + axpy_cpu(size, -decay*batch, l.weights, 1, l.weight_updates, 1); + axpy_cpu(size, learning_rate/batch, l.weight_updates, 1, l.weights, 1); + scal_cpu(size, momentum, l.weight_updates, 1); +} + +#ifdef GPU + +void forward_local_layer_gpu(const local_layer l, network net) +{ + int out_h = local_out_height(l); + int out_w = local_out_width(l); + int i, j; + int locations = out_h * out_w; + + for(i = 0; i < l.batch; ++i){ + copy_gpu(l.outputs, l.biases_gpu, 1, l.output_gpu + i*l.outputs, 1); + } + + for(i = 0; i < l.batch; ++i){ + float *input = net.input_gpu + i*l.w*l.h*l.c; + im2col_gpu(input, l.c, l.h, l.w, + l.size, l.stride, l.pad, net.workspace); + float *output = l.output_gpu + i*l.outputs; + for(j = 0; j < locations; ++j){ + float *a = l.weights_gpu + j*l.size*l.size*l.c*l.n; + float *b = net.workspace + j; + float *c = output + j; + + int m = l.n; + int n = 1; + int k = l.size*l.size*l.c; + + gemm_gpu(0,0,m,n,k,1,a,k,b,locations,1,c,locations); + } + } + activate_array_gpu(l.output_gpu, l.outputs*l.batch, l.activation); +} + +void backward_local_layer_gpu(local_layer l, network net) +{ + int i, j; + int locations = l.out_w*l.out_h; + + gradient_array_gpu(l.output_gpu, l.outputs*l.batch, l.activation, l.delta_gpu); + for(i = 0; i < l.batch; ++i){ + axpy_gpu(l.outputs, 1, l.delta_gpu + i*l.outputs, 1, l.bias_updates_gpu, 1); + } + + for(i = 0; i < l.batch; ++i){ + float *input = net.input_gpu + i*l.w*l.h*l.c; + im2col_gpu(input, l.c, l.h, l.w, + l.size, l.stride, l.pad, net.workspace); + + for(j = 0; j < locations; ++j){ + float *a = l.delta_gpu + i*l.outputs + j; + float *b = net.workspace + j; + float *c = l.weight_updates_gpu + j*l.size*l.size*l.c*l.n; + int m = l.n; + int n = l.size*l.size*l.c; + int k = 1; + + gemm_gpu(0,1,m,n,k,1,a,locations,b,locations,1,c,n); + } + + if(net.delta_gpu){ + for(j = 0; j < locations; ++j){ + float *a = l.weights_gpu + j*l.size*l.size*l.c*l.n; + float *b = l.delta_gpu + i*l.outputs + j; + float *c = net.workspace + j; + + int m = l.size*l.size*l.c; + int n = 1; + int k = l.n; + + gemm_gpu(1,0,m,n,k,1,a,m,b,locations,0,c,locations); + } + + col2im_gpu(net.workspace, l.c, l.h, l.w, l.size, l.stride, l.pad, net.delta_gpu+i*l.c*l.h*l.w); + } + } +} + +void update_local_layer_gpu(local_layer l, update_args a) +{ + float learning_rate = a.learning_rate*l.learning_rate_scale; + float momentum = a.momentum; + float decay = a.decay; + int batch = a.batch; + + int locations = l.out_w*l.out_h; + int size = l.size*l.size*l.c*l.n*locations; + axpy_gpu(l.outputs, learning_rate/batch, l.bias_updates_gpu, 1, l.biases_gpu, 1); + scal_gpu(l.outputs, momentum, l.bias_updates_gpu, 1); + + axpy_gpu(size, -decay*batch, l.weights_gpu, 1, l.weight_updates_gpu, 1); + axpy_gpu(size, learning_rate/batch, l.weight_updates_gpu, 1, l.weights_gpu, 1); + scal_gpu(size, momentum, l.weight_updates_gpu, 1); +} + +void pull_local_layer(local_layer l) +{ + int locations = l.out_w*l.out_h; + int size = l.size*l.size*l.c*l.n*locations; + cuda_pull_array(l.weights_gpu, l.weights, size); + cuda_pull_array(l.biases_gpu, l.biases, l.outputs); +} + +void push_local_layer(local_layer l) +{ + int locations = l.out_w*l.out_h; + int size = l.size*l.size*l.c*l.n*locations; + cuda_push_array(l.weights_gpu, l.weights, size); + cuda_push_array(l.biases_gpu, l.biases, l.outputs); +} +#endif diff --git a/hanzi_detection/src/local_layer.h b/hanzi_detection/src/local_layer.h new file mode 100755 index 0000000..776e572 --- /dev/null +++ b/hanzi_detection/src/local_layer.h @@ -0,0 +1,31 @@ +#ifndef LOCAL_LAYER_H +#define LOCAL_LAYER_H + +#include "cuda.h" +#include "image.h" +#include "activations.h" +#include "layer.h" +#include "network.h" + +typedef layer local_layer; + +#ifdef GPU +void forward_local_layer_gpu(local_layer layer, network net); +void backward_local_layer_gpu(local_layer layer, network net); +void update_local_layer_gpu(local_layer layer, update_args a); + +void push_local_layer(local_layer layer); +void pull_local_layer(local_layer layer); +#endif + +local_layer make_local_layer(int batch, int h, int w, int c, int n, int size, int stride, int pad, ACTIVATION activation); + +void forward_local_layer(const local_layer layer, network net); +void backward_local_layer(local_layer layer, network net); +void update_local_layer(local_layer layer, update_args a); + +void bias_output(float *output, float *biases, int batch, int n, int size); +void backward_bias(float *bias_updates, float *delta, int batch, int n, int size); + +#endif + diff --git a/hanzi_detection/src/logistic_layer.c b/hanzi_detection/src/logistic_layer.c new file mode 100755 index 0000000..b2b3d6b --- /dev/null +++ b/hanzi_detection/src/logistic_layer.c @@ -0,0 +1,71 @@ +#include "logistic_layer.h" +#include "activations.h" +#include "blas.h" +#include "cuda.h" + +#include +#include +#include +#include +#include + +layer make_logistic_layer(int batch, int inputs) +{ + fprintf(stderr, "logistic x entropy %4d\n", inputs); + layer l = {0}; + l.type = LOGXENT; + l.batch = batch; + l.inputs = inputs; + l.outputs = inputs; + l.loss = calloc(inputs*batch, sizeof(float)); + l.output = calloc(inputs*batch, sizeof(float)); + l.delta = calloc(inputs*batch, sizeof(float)); + l.cost = calloc(1, sizeof(float)); + + l.forward = forward_logistic_layer; + l.backward = backward_logistic_layer; + #ifdef GPU + l.forward_gpu = forward_logistic_layer_gpu; + l.backward_gpu = backward_logistic_layer_gpu; + + l.output_gpu = cuda_make_array(l.output, inputs*batch); + l.loss_gpu = cuda_make_array(l.loss, inputs*batch); + l.delta_gpu = cuda_make_array(l.delta, inputs*batch); + #endif + return l; +} + +void forward_logistic_layer(const layer l, network net) +{ + copy_cpu(l.outputs*l.batch, net.input, 1, l.output, 1); + activate_array(l.output, l.outputs*l.batch, LOGISTIC); + if(net.truth){ + logistic_x_ent_cpu(l.batch*l.inputs, l.output, net.truth, l.delta, l.loss); + l.cost[0] = sum_array(l.loss, l.batch*l.inputs); + } +} + +void backward_logistic_layer(const layer l, network net) +{ + axpy_cpu(l.inputs*l.batch, 1, l.delta, 1, net.delta, 1); +} + +#ifdef GPU + +void forward_logistic_layer_gpu(const layer l, network net) +{ + copy_gpu(l.outputs*l.batch, net.input_gpu, 1, l.output_gpu, 1); + activate_array_gpu(l.output_gpu, l.outputs*l.batch, LOGISTIC); + if(net.truth){ + logistic_x_ent_gpu(l.batch*l.inputs, l.output_gpu, net.truth_gpu, l.delta_gpu, l.loss_gpu); + cuda_pull_array(l.loss_gpu, l.loss, l.batch*l.inputs); + l.cost[0] = sum_array(l.loss, l.batch*l.inputs); + } +} + +void backward_logistic_layer_gpu(const layer l, network net) +{ + axpy_gpu(l.batch*l.inputs, 1, l.delta_gpu, 1, net.delta_gpu, 1); +} + +#endif diff --git a/hanzi_detection/src/logistic_layer.h b/hanzi_detection/src/logistic_layer.h new file mode 100755 index 0000000..9c25bee --- /dev/null +++ b/hanzi_detection/src/logistic_layer.h @@ -0,0 +1,15 @@ +#ifndef LOGISTIC_LAYER_H +#define LOGISTIC_LAYER_H +#include "layer.h" +#include "network.h" + +layer make_logistic_layer(int batch, int inputs); +void forward_logistic_layer(const layer l, network net); +void backward_logistic_layer(const layer l, network net); + +#ifdef GPU +void forward_logistic_layer_gpu(const layer l, network net); +void backward_logistic_layer_gpu(const layer l, network net); +#endif + +#endif diff --git a/hanzi_detection/src/lstm_layer.c b/hanzi_detection/src/lstm_layer.c new file mode 100755 index 0000000..fb07de2 --- /dev/null +++ b/hanzi_detection/src/lstm_layer.c @@ -0,0 +1,626 @@ +#include "lstm_layer.h" +#include "connected_layer.h" +#include "utils.h" +#include "cuda.h" +#include "blas.h" +#include "gemm.h" + +#include +#include +#include +#include + +static void increment_layer(layer *l, int steps) +{ + int num = l->outputs*l->batch*steps; + l->output += num; + l->delta += num; + l->x += num; + l->x_norm += num; + +#ifdef GPU + l->output_gpu += num; + l->delta_gpu += num; + l->x_gpu += num; + l->x_norm_gpu += num; +#endif +} + +layer make_lstm_layer(int batch, int inputs, int outputs, int steps, int batch_normalize, int adam) +{ + fprintf(stderr, "LSTM Layer: %d inputs, %d outputs\n", inputs, outputs); + batch = batch / steps; + layer l = { 0 }; + l.batch = batch; + l.type = LSTM; + l.steps = steps; + l.inputs = inputs; + + l.uf = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.uf) = make_connected_layer(batch*steps, inputs, outputs, LINEAR, batch_normalize, adam); + l.uf->batch = batch; + + l.ui = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.ui) = make_connected_layer(batch*steps, inputs, outputs, LINEAR, batch_normalize, adam); + l.ui->batch = batch; + + l.ug = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.ug) = make_connected_layer(batch*steps, inputs, outputs, LINEAR, batch_normalize, adam); + l.ug->batch = batch; + + l.uo = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.uo) = make_connected_layer(batch*steps, inputs, outputs, LINEAR, batch_normalize, adam); + l.uo->batch = batch; + + l.wf = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.wf) = make_connected_layer(batch*steps, outputs, outputs, LINEAR, batch_normalize, adam); + l.wf->batch = batch; + + l.wi = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.wi) = make_connected_layer(batch*steps, outputs, outputs, LINEAR, batch_normalize, adam); + l.wi->batch = batch; + + l.wg = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.wg) = make_connected_layer(batch*steps, outputs, outputs, LINEAR, batch_normalize, adam); + l.wg->batch = batch; + + l.wo = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.wo) = make_connected_layer(batch*steps, outputs, outputs, LINEAR, batch_normalize, adam); + l.wo->batch = batch; + + l.batch_normalize = batch_normalize; + l.outputs = outputs; + + l.output = calloc(outputs*batch*steps, sizeof(float)); + l.state = calloc(outputs*batch, sizeof(float)); + + l.forward = forward_lstm_layer; + l.update = update_lstm_layer; + + l.prev_state_cpu = calloc(batch*outputs, sizeof(float)); + l.prev_cell_cpu = calloc(batch*outputs, sizeof(float)); + l.cell_cpu = calloc(batch*outputs*steps, sizeof(float)); + + l.f_cpu = calloc(batch*outputs, sizeof(float)); + l.i_cpu = calloc(batch*outputs, sizeof(float)); + l.g_cpu = calloc(batch*outputs, sizeof(float)); + l.o_cpu = calloc(batch*outputs, sizeof(float)); + l.c_cpu = calloc(batch*outputs, sizeof(float)); + l.h_cpu = calloc(batch*outputs, sizeof(float)); + l.temp_cpu = calloc(batch*outputs, sizeof(float)); + l.temp2_cpu = calloc(batch*outputs, sizeof(float)); + l.temp3_cpu = calloc(batch*outputs, sizeof(float)); + l.dc_cpu = calloc(batch*outputs, sizeof(float)); + l.dh_cpu = calloc(batch*outputs, sizeof(float)); + +#ifdef GPU + l.forward_gpu = forward_lstm_layer_gpu; + l.backward_gpu = backward_lstm_layer_gpu; + l.update_gpu = update_lstm_layer_gpu; + + l.output_gpu = cuda_make_array(0, batch*outputs*steps); + l.delta_gpu = cuda_make_array(0, batch*l.outputs*steps); + + l.prev_state_gpu = cuda_make_array(0, batch*outputs); + l.prev_cell_gpu = cuda_make_array(0, batch*outputs); + l.cell_gpu = cuda_make_array(0, batch*outputs*steps); + + l.f_gpu = cuda_make_array(0, batch*outputs); + l.i_gpu = cuda_make_array(0, batch*outputs); + l.g_gpu = cuda_make_array(0, batch*outputs); + l.o_gpu = cuda_make_array(0, batch*outputs); + l.c_gpu = cuda_make_array(0, batch*outputs); + l.h_gpu = cuda_make_array(0, batch*outputs); + l.temp_gpu = cuda_make_array(0, batch*outputs); + l.temp2_gpu = cuda_make_array(0, batch*outputs); + l.temp3_gpu = cuda_make_array(0, batch*outputs); + l.dc_gpu = cuda_make_array(0, batch*outputs); + l.dh_gpu = cuda_make_array(0, batch*outputs); +#ifdef CUDNN + cudnnSetTensor4dDescriptor(l.wf->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, batch, l.wf->out_c, l.wf->out_h, l.wf->out_w); + cudnnSetTensor4dDescriptor(l.wi->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, batch, l.wi->out_c, l.wi->out_h, l.wi->out_w); + cudnnSetTensor4dDescriptor(l.wg->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, batch, l.wg->out_c, l.wg->out_h, l.wg->out_w); + cudnnSetTensor4dDescriptor(l.wo->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, batch, l.wo->out_c, l.wo->out_h, l.wo->out_w); + + cudnnSetTensor4dDescriptor(l.uf->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, batch, l.uf->out_c, l.uf->out_h, l.uf->out_w); + cudnnSetTensor4dDescriptor(l.ui->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, batch, l.ui->out_c, l.ui->out_h, l.ui->out_w); + cudnnSetTensor4dDescriptor(l.ug->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, batch, l.ug->out_c, l.ug->out_h, l.ug->out_w); + cudnnSetTensor4dDescriptor(l.uo->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, batch, l.uo->out_c, l.uo->out_h, l.uo->out_w); +#endif + +#endif + + return l; +} + +void update_lstm_layer(layer l, update_args a) +{ + update_connected_layer(*(l.wf), a); + update_connected_layer(*(l.wi), a); + update_connected_layer(*(l.wg), a); + update_connected_layer(*(l.wo), a); + update_connected_layer(*(l.uf), a); + update_connected_layer(*(l.ui), a); + update_connected_layer(*(l.ug), a); + update_connected_layer(*(l.uo), a); +} + +void forward_lstm_layer(layer l, network state) +{ + network s = { 0 }; + s.train = state.train; + int i; + layer wf = *(l.wf); + layer wi = *(l.wi); + layer wg = *(l.wg); + layer wo = *(l.wo); + + layer uf = *(l.uf); + layer ui = *(l.ui); + layer ug = *(l.ug); + layer uo = *(l.uo); + + fill_cpu(l.outputs * l.batch * l.steps, 0, wf.delta, 1); + fill_cpu(l.outputs * l.batch * l.steps, 0, wi.delta, 1); + fill_cpu(l.outputs * l.batch * l.steps, 0, wg.delta, 1); + fill_cpu(l.outputs * l.batch * l.steps, 0, wo.delta, 1); + + fill_cpu(l.outputs * l.batch * l.steps, 0, uf.delta, 1); + fill_cpu(l.outputs * l.batch * l.steps, 0, ui.delta, 1); + fill_cpu(l.outputs * l.batch * l.steps, 0, ug.delta, 1); + fill_cpu(l.outputs * l.batch * l.steps, 0, uo.delta, 1); + if (state.train) { + fill_cpu(l.outputs * l.batch * l.steps, 0, l.delta, 1); + } + + for (i = 0; i < l.steps; ++i) { + s.input = l.h_cpu; + forward_connected_layer(wf, s); + forward_connected_layer(wi, s); + forward_connected_layer(wg, s); + forward_connected_layer(wo, s); + + s.input = state.input; + forward_connected_layer(uf, s); + forward_connected_layer(ui, s); + forward_connected_layer(ug, s); + forward_connected_layer(uo, s); + + copy_cpu(l.outputs*l.batch, wf.output, 1, l.f_cpu, 1); + axpy_cpu(l.outputs*l.batch, 1, uf.output, 1, l.f_cpu, 1); + + copy_cpu(l.outputs*l.batch, wi.output, 1, l.i_cpu, 1); + axpy_cpu(l.outputs*l.batch, 1, ui.output, 1, l.i_cpu, 1); + + copy_cpu(l.outputs*l.batch, wg.output, 1, l.g_cpu, 1); + axpy_cpu(l.outputs*l.batch, 1, ug.output, 1, l.g_cpu, 1); + + copy_cpu(l.outputs*l.batch, wo.output, 1, l.o_cpu, 1); + axpy_cpu(l.outputs*l.batch, 1, uo.output, 1, l.o_cpu, 1); + + activate_array(l.f_cpu, l.outputs*l.batch, LOGISTIC); + activate_array(l.i_cpu, l.outputs*l.batch, LOGISTIC); + activate_array(l.g_cpu, l.outputs*l.batch, TANH); + activate_array(l.o_cpu, l.outputs*l.batch, LOGISTIC); + + copy_cpu(l.outputs*l.batch, l.i_cpu, 1, l.temp_cpu, 1); + mul_cpu(l.outputs*l.batch, l.g_cpu, 1, l.temp_cpu, 1); + mul_cpu(l.outputs*l.batch, l.f_cpu, 1, l.c_cpu, 1); + axpy_cpu(l.outputs*l.batch, 1, l.temp_cpu, 1, l.c_cpu, 1); + + copy_cpu(l.outputs*l.batch, l.c_cpu, 1, l.h_cpu, 1); + activate_array(l.h_cpu, l.outputs*l.batch, TANH); + mul_cpu(l.outputs*l.batch, l.o_cpu, 1, l.h_cpu, 1); + + copy_cpu(l.outputs*l.batch, l.c_cpu, 1, l.cell_cpu, 1); + copy_cpu(l.outputs*l.batch, l.h_cpu, 1, l.output, 1); + + state.input += l.inputs*l.batch; + l.output += l.outputs*l.batch; + l.cell_cpu += l.outputs*l.batch; + + increment_layer(&wf, 1); + increment_layer(&wi, 1); + increment_layer(&wg, 1); + increment_layer(&wo, 1); + + increment_layer(&uf, 1); + increment_layer(&ui, 1); + increment_layer(&ug, 1); + increment_layer(&uo, 1); + } +} + +void backward_lstm_layer(layer l, network state) +{ + network s = { 0 }; + s.train = state.train; + int i; + layer wf = *(l.wf); + layer wi = *(l.wi); + layer wg = *(l.wg); + layer wo = *(l.wo); + + layer uf = *(l.uf); + layer ui = *(l.ui); + layer ug = *(l.ug); + layer uo = *(l.uo); + + increment_layer(&wf, l.steps - 1); + increment_layer(&wi, l.steps - 1); + increment_layer(&wg, l.steps - 1); + increment_layer(&wo, l.steps - 1); + + increment_layer(&uf, l.steps - 1); + increment_layer(&ui, l.steps - 1); + increment_layer(&ug, l.steps - 1); + increment_layer(&uo, l.steps - 1); + + state.input += l.inputs*l.batch*(l.steps - 1); + if (state.delta) state.delta += l.inputs*l.batch*(l.steps - 1); + + l.output += l.outputs*l.batch*(l.steps - 1); + l.cell_cpu += l.outputs*l.batch*(l.steps - 1); + l.delta += l.outputs*l.batch*(l.steps - 1); + + for (i = l.steps - 1; i >= 0; --i) { + if (i != 0) copy_cpu(l.outputs*l.batch, l.cell_cpu - l.outputs*l.batch, 1, l.prev_cell_cpu, 1); + copy_cpu(l.outputs*l.batch, l.cell_cpu, 1, l.c_cpu, 1); + if (i != 0) copy_cpu(l.outputs*l.batch, l.output - l.outputs*l.batch, 1, l.prev_state_cpu, 1); + copy_cpu(l.outputs*l.batch, l.output, 1, l.h_cpu, 1); + + l.dh_cpu = (i == 0) ? 0 : l.delta - l.outputs*l.batch; + + copy_cpu(l.outputs*l.batch, wf.output, 1, l.f_cpu, 1); + axpy_cpu(l.outputs*l.batch, 1, uf.output, 1, l.f_cpu, 1); + + copy_cpu(l.outputs*l.batch, wi.output, 1, l.i_cpu, 1); + axpy_cpu(l.outputs*l.batch, 1, ui.output, 1, l.i_cpu, 1); + + copy_cpu(l.outputs*l.batch, wg.output, 1, l.g_cpu, 1); + axpy_cpu(l.outputs*l.batch, 1, ug.output, 1, l.g_cpu, 1); + + copy_cpu(l.outputs*l.batch, wo.output, 1, l.o_cpu, 1); + axpy_cpu(l.outputs*l.batch, 1, uo.output, 1, l.o_cpu, 1); + + activate_array(l.f_cpu, l.outputs*l.batch, LOGISTIC); + activate_array(l.i_cpu, l.outputs*l.batch, LOGISTIC); + activate_array(l.g_cpu, l.outputs*l.batch, TANH); + activate_array(l.o_cpu, l.outputs*l.batch, LOGISTIC); + + copy_cpu(l.outputs*l.batch, l.delta, 1, l.temp3_cpu, 1); + + copy_cpu(l.outputs*l.batch, l.c_cpu, 1, l.temp_cpu, 1); + activate_array(l.temp_cpu, l.outputs*l.batch, TANH); + + copy_cpu(l.outputs*l.batch, l.temp3_cpu, 1, l.temp2_cpu, 1); + mul_cpu(l.outputs*l.batch, l.o_cpu, 1, l.temp2_cpu, 1); + + gradient_array(l.temp_cpu, l.outputs*l.batch, TANH, l.temp2_cpu); + axpy_cpu(l.outputs*l.batch, 1, l.dc_cpu, 1, l.temp2_cpu, 1); + + copy_cpu(l.outputs*l.batch, l.c_cpu, 1, l.temp_cpu, 1); + activate_array(l.temp_cpu, l.outputs*l.batch, TANH); + mul_cpu(l.outputs*l.batch, l.temp3_cpu, 1, l.temp_cpu, 1); + gradient_array(l.o_cpu, l.outputs*l.batch, LOGISTIC, l.temp_cpu); + copy_cpu(l.outputs*l.batch, l.temp_cpu, 1, wo.delta, 1); + s.input = l.prev_state_cpu; + s.delta = l.dh_cpu; + backward_connected_layer(wo, s); + + copy_cpu(l.outputs*l.batch, l.temp_cpu, 1, uo.delta, 1); + s.input = state.input; + s.delta = state.delta; + backward_connected_layer(uo, s); + + copy_cpu(l.outputs*l.batch, l.temp2_cpu, 1, l.temp_cpu, 1); + mul_cpu(l.outputs*l.batch, l.i_cpu, 1, l.temp_cpu, 1); + gradient_array(l.g_cpu, l.outputs*l.batch, TANH, l.temp_cpu); + copy_cpu(l.outputs*l.batch, l.temp_cpu, 1, wg.delta, 1); + s.input = l.prev_state_cpu; + s.delta = l.dh_cpu; + backward_connected_layer(wg, s); + + copy_cpu(l.outputs*l.batch, l.temp_cpu, 1, ug.delta, 1); + s.input = state.input; + s.delta = state.delta; + backward_connected_layer(ug, s); + + copy_cpu(l.outputs*l.batch, l.temp2_cpu, 1, l.temp_cpu, 1); + mul_cpu(l.outputs*l.batch, l.g_cpu, 1, l.temp_cpu, 1); + gradient_array(l.i_cpu, l.outputs*l.batch, LOGISTIC, l.temp_cpu); + copy_cpu(l.outputs*l.batch, l.temp_cpu, 1, wi.delta, 1); + s.input = l.prev_state_cpu; + s.delta = l.dh_cpu; + backward_connected_layer(wi, s); + + copy_cpu(l.outputs*l.batch, l.temp_cpu, 1, ui.delta, 1); + s.input = state.input; + s.delta = state.delta; + backward_connected_layer(ui, s); + + copy_cpu(l.outputs*l.batch, l.temp2_cpu, 1, l.temp_cpu, 1); + mul_cpu(l.outputs*l.batch, l.prev_cell_cpu, 1, l.temp_cpu, 1); + gradient_array(l.f_cpu, l.outputs*l.batch, LOGISTIC, l.temp_cpu); + copy_cpu(l.outputs*l.batch, l.temp_cpu, 1, wf.delta, 1); + s.input = l.prev_state_cpu; + s.delta = l.dh_cpu; + backward_connected_layer(wf, s); + + copy_cpu(l.outputs*l.batch, l.temp_cpu, 1, uf.delta, 1); + s.input = state.input; + s.delta = state.delta; + backward_connected_layer(uf, s); + + copy_cpu(l.outputs*l.batch, l.temp2_cpu, 1, l.temp_cpu, 1); + mul_cpu(l.outputs*l.batch, l.f_cpu, 1, l.temp_cpu, 1); + copy_cpu(l.outputs*l.batch, l.temp_cpu, 1, l.dc_cpu, 1); + + state.input -= l.inputs*l.batch; + if (state.delta) state.delta -= l.inputs*l.batch; + l.output -= l.outputs*l.batch; + l.cell_cpu -= l.outputs*l.batch; + l.delta -= l.outputs*l.batch; + + increment_layer(&wf, -1); + increment_layer(&wi, -1); + increment_layer(&wg, -1); + increment_layer(&wo, -1); + + increment_layer(&uf, -1); + increment_layer(&ui, -1); + increment_layer(&ug, -1); + increment_layer(&uo, -1); + } +} + +#ifdef GPU +void update_lstm_layer_gpu(layer l, update_args a) +{ + update_connected_layer_gpu(*(l.wf), a); + update_connected_layer_gpu(*(l.wi), a); + update_connected_layer_gpu(*(l.wg), a); + update_connected_layer_gpu(*(l.wo), a); + update_connected_layer_gpu(*(l.uf), a); + update_connected_layer_gpu(*(l.ui), a); + update_connected_layer_gpu(*(l.ug), a); + update_connected_layer_gpu(*(l.uo), a); +} + +void forward_lstm_layer_gpu(layer l, network state) +{ + network s = { 0 }; + s.train = state.train; + int i; + layer wf = *(l.wf); + layer wi = *(l.wi); + layer wg = *(l.wg); + layer wo = *(l.wo); + + layer uf = *(l.uf); + layer ui = *(l.ui); + layer ug = *(l.ug); + layer uo = *(l.uo); + + fill_gpu(l.outputs * l.batch * l.steps, 0, wf.delta_gpu, 1); + fill_gpu(l.outputs * l.batch * l.steps, 0, wi.delta_gpu, 1); + fill_gpu(l.outputs * l.batch * l.steps, 0, wg.delta_gpu, 1); + fill_gpu(l.outputs * l.batch * l.steps, 0, wo.delta_gpu, 1); + + fill_gpu(l.outputs * l.batch * l.steps, 0, uf.delta_gpu, 1); + fill_gpu(l.outputs * l.batch * l.steps, 0, ui.delta_gpu, 1); + fill_gpu(l.outputs * l.batch * l.steps, 0, ug.delta_gpu, 1); + fill_gpu(l.outputs * l.batch * l.steps, 0, uo.delta_gpu, 1); + if (state.train) { + fill_gpu(l.outputs * l.batch * l.steps, 0, l.delta_gpu, 1); + } + + for (i = 0; i < l.steps; ++i) { + s.input_gpu = l.h_gpu; + forward_connected_layer_gpu(wf, s); + forward_connected_layer_gpu(wi, s); + forward_connected_layer_gpu(wg, s); + forward_connected_layer_gpu(wo, s); + + s.input_gpu = state.input_gpu; + forward_connected_layer_gpu(uf, s); + forward_connected_layer_gpu(ui, s); + forward_connected_layer_gpu(ug, s); + forward_connected_layer_gpu(uo, s); + + copy_gpu(l.outputs*l.batch, wf.output_gpu, 1, l.f_gpu, 1); + axpy_gpu(l.outputs*l.batch, 1, uf.output_gpu, 1, l.f_gpu, 1); + + copy_gpu(l.outputs*l.batch, wi.output_gpu, 1, l.i_gpu, 1); + axpy_gpu(l.outputs*l.batch, 1, ui.output_gpu, 1, l.i_gpu, 1); + + copy_gpu(l.outputs*l.batch, wg.output_gpu, 1, l.g_gpu, 1); + axpy_gpu(l.outputs*l.batch, 1, ug.output_gpu, 1, l.g_gpu, 1); + + copy_gpu(l.outputs*l.batch, wo.output_gpu, 1, l.o_gpu, 1); + axpy_gpu(l.outputs*l.batch, 1, uo.output_gpu, 1, l.o_gpu, 1); + + activate_array_gpu(l.f_gpu, l.outputs*l.batch, LOGISTIC); + activate_array_gpu(l.i_gpu, l.outputs*l.batch, LOGISTIC); + activate_array_gpu(l.g_gpu, l.outputs*l.batch, TANH); + activate_array_gpu(l.o_gpu, l.outputs*l.batch, LOGISTIC); + + copy_gpu(l.outputs*l.batch, l.i_gpu, 1, l.temp_gpu, 1); + mul_gpu(l.outputs*l.batch, l.g_gpu, 1, l.temp_gpu, 1); + mul_gpu(l.outputs*l.batch, l.f_gpu, 1, l.c_gpu, 1); + axpy_gpu(l.outputs*l.batch, 1, l.temp_gpu, 1, l.c_gpu, 1); + + copy_gpu(l.outputs*l.batch, l.c_gpu, 1, l.h_gpu, 1); + activate_array_gpu(l.h_gpu, l.outputs*l.batch, TANH); + mul_gpu(l.outputs*l.batch, l.o_gpu, 1, l.h_gpu, 1); + + copy_gpu(l.outputs*l.batch, l.c_gpu, 1, l.cell_gpu, 1); + copy_gpu(l.outputs*l.batch, l.h_gpu, 1, l.output_gpu, 1); + + state.input_gpu += l.inputs*l.batch; + l.output_gpu += l.outputs*l.batch; + l.cell_gpu += l.outputs*l.batch; + + increment_layer(&wf, 1); + increment_layer(&wi, 1); + increment_layer(&wg, 1); + increment_layer(&wo, 1); + + increment_layer(&uf, 1); + increment_layer(&ui, 1); + increment_layer(&ug, 1); + increment_layer(&uo, 1); + } +} + +void backward_lstm_layer_gpu(layer l, network state) +{ + network s = { 0 }; + s.train = state.train; + int i; + layer wf = *(l.wf); + layer wi = *(l.wi); + layer wg = *(l.wg); + layer wo = *(l.wo); + + layer uf = *(l.uf); + layer ui = *(l.ui); + layer ug = *(l.ug); + layer uo = *(l.uo); + + increment_layer(&wf, l.steps - 1); + increment_layer(&wi, l.steps - 1); + increment_layer(&wg, l.steps - 1); + increment_layer(&wo, l.steps - 1); + + increment_layer(&uf, l.steps - 1); + increment_layer(&ui, l.steps - 1); + increment_layer(&ug, l.steps - 1); + increment_layer(&uo, l.steps - 1); + + state.input_gpu += l.inputs*l.batch*(l.steps - 1); + if (state.delta_gpu) state.delta_gpu += l.inputs*l.batch*(l.steps - 1); + + l.output_gpu += l.outputs*l.batch*(l.steps - 1); + l.cell_gpu += l.outputs*l.batch*(l.steps - 1); + l.delta_gpu += l.outputs*l.batch*(l.steps - 1); + + for (i = l.steps - 1; i >= 0; --i) { + if (i != 0) copy_gpu(l.outputs*l.batch, l.cell_gpu - l.outputs*l.batch, 1, l.prev_cell_gpu, 1); + copy_gpu(l.outputs*l.batch, l.cell_gpu, 1, l.c_gpu, 1); + if (i != 0) copy_gpu(l.outputs*l.batch, l.output_gpu - l.outputs*l.batch, 1, l.prev_state_gpu, 1); + copy_gpu(l.outputs*l.batch, l.output_gpu, 1, l.h_gpu, 1); + + l.dh_gpu = (i == 0) ? 0 : l.delta_gpu - l.outputs*l.batch; + + copy_gpu(l.outputs*l.batch, wf.output_gpu, 1, l.f_gpu, 1); + axpy_gpu(l.outputs*l.batch, 1, uf.output_gpu, 1, l.f_gpu, 1); + + copy_gpu(l.outputs*l.batch, wi.output_gpu, 1, l.i_gpu, 1); + axpy_gpu(l.outputs*l.batch, 1, ui.output_gpu, 1, l.i_gpu, 1); + + copy_gpu(l.outputs*l.batch, wg.output_gpu, 1, l.g_gpu, 1); + axpy_gpu(l.outputs*l.batch, 1, ug.output_gpu, 1, l.g_gpu, 1); + + copy_gpu(l.outputs*l.batch, wo.output_gpu, 1, l.o_gpu, 1); + axpy_gpu(l.outputs*l.batch, 1, uo.output_gpu, 1, l.o_gpu, 1); + + activate_array_gpu(l.f_gpu, l.outputs*l.batch, LOGISTIC); + activate_array_gpu(l.i_gpu, l.outputs*l.batch, LOGISTIC); + activate_array_gpu(l.g_gpu, l.outputs*l.batch, TANH); + activate_array_gpu(l.o_gpu, l.outputs*l.batch, LOGISTIC); + + copy_gpu(l.outputs*l.batch, l.delta_gpu, 1, l.temp3_gpu, 1); + + copy_gpu(l.outputs*l.batch, l.c_gpu, 1, l.temp_gpu, 1); + activate_array_gpu(l.temp_gpu, l.outputs*l.batch, TANH); + + copy_gpu(l.outputs*l.batch, l.temp3_gpu, 1, l.temp2_gpu, 1); + mul_gpu(l.outputs*l.batch, l.o_gpu, 1, l.temp2_gpu, 1); + + gradient_array_gpu(l.temp_gpu, l.outputs*l.batch, TANH, l.temp2_gpu); + axpy_gpu(l.outputs*l.batch, 1, l.dc_gpu, 1, l.temp2_gpu, 1); + + copy_gpu(l.outputs*l.batch, l.c_gpu, 1, l.temp_gpu, 1); + activate_array_gpu(l.temp_gpu, l.outputs*l.batch, TANH); + mul_gpu(l.outputs*l.batch, l.temp3_gpu, 1, l.temp_gpu, 1); + gradient_array_gpu(l.o_gpu, l.outputs*l.batch, LOGISTIC, l.temp_gpu); + copy_gpu(l.outputs*l.batch, l.temp_gpu, 1, wo.delta_gpu, 1); + s.input_gpu = l.prev_state_gpu; + s.delta_gpu = l.dh_gpu; + backward_connected_layer_gpu(wo, s); + + copy_gpu(l.outputs*l.batch, l.temp_gpu, 1, uo.delta_gpu, 1); + s.input_gpu = state.input_gpu; + s.delta_gpu = state.delta_gpu; + backward_connected_layer_gpu(uo, s); + + copy_gpu(l.outputs*l.batch, l.temp2_gpu, 1, l.temp_gpu, 1); + mul_gpu(l.outputs*l.batch, l.i_gpu, 1, l.temp_gpu, 1); + gradient_array_gpu(l.g_gpu, l.outputs*l.batch, TANH, l.temp_gpu); + copy_gpu(l.outputs*l.batch, l.temp_gpu, 1, wg.delta_gpu, 1); + s.input_gpu = l.prev_state_gpu; + s.delta_gpu = l.dh_gpu; + backward_connected_layer_gpu(wg, s); + + copy_gpu(l.outputs*l.batch, l.temp_gpu, 1, ug.delta_gpu, 1); + s.input_gpu = state.input_gpu; + s.delta_gpu = state.delta_gpu; + backward_connected_layer_gpu(ug, s); + + copy_gpu(l.outputs*l.batch, l.temp2_gpu, 1, l.temp_gpu, 1); + mul_gpu(l.outputs*l.batch, l.g_gpu, 1, l.temp_gpu, 1); + gradient_array_gpu(l.i_gpu, l.outputs*l.batch, LOGISTIC, l.temp_gpu); + copy_gpu(l.outputs*l.batch, l.temp_gpu, 1, wi.delta_gpu, 1); + s.input_gpu = l.prev_state_gpu; + s.delta_gpu = l.dh_gpu; + backward_connected_layer_gpu(wi, s); + + copy_gpu(l.outputs*l.batch, l.temp_gpu, 1, ui.delta_gpu, 1); + s.input_gpu = state.input_gpu; + s.delta_gpu = state.delta_gpu; + backward_connected_layer_gpu(ui, s); + + copy_gpu(l.outputs*l.batch, l.temp2_gpu, 1, l.temp_gpu, 1); + mul_gpu(l.outputs*l.batch, l.prev_cell_gpu, 1, l.temp_gpu, 1); + gradient_array_gpu(l.f_gpu, l.outputs*l.batch, LOGISTIC, l.temp_gpu); + copy_gpu(l.outputs*l.batch, l.temp_gpu, 1, wf.delta_gpu, 1); + s.input_gpu = l.prev_state_gpu; + s.delta_gpu = l.dh_gpu; + backward_connected_layer_gpu(wf, s); + + copy_gpu(l.outputs*l.batch, l.temp_gpu, 1, uf.delta_gpu, 1); + s.input_gpu = state.input_gpu; + s.delta_gpu = state.delta_gpu; + backward_connected_layer_gpu(uf, s); + + copy_gpu(l.outputs*l.batch, l.temp2_gpu, 1, l.temp_gpu, 1); + mul_gpu(l.outputs*l.batch, l.f_gpu, 1, l.temp_gpu, 1); + copy_gpu(l.outputs*l.batch, l.temp_gpu, 1, l.dc_gpu, 1); + + state.input_gpu -= l.inputs*l.batch; + if (state.delta_gpu) state.delta_gpu -= l.inputs*l.batch; + l.output_gpu -= l.outputs*l.batch; + l.cell_gpu -= l.outputs*l.batch; + l.delta_gpu -= l.outputs*l.batch; + + increment_layer(&wf, -1); + increment_layer(&wi, -1); + increment_layer(&wg, -1); + increment_layer(&wo, -1); + + increment_layer(&uf, -1); + increment_layer(&ui, -1); + increment_layer(&ug, -1); + increment_layer(&uo, -1); + } +} +#endif diff --git a/hanzi_detection/src/lstm_layer.h b/hanzi_detection/src/lstm_layer.h new file mode 100755 index 0000000..b9f07e6 --- /dev/null +++ b/hanzi_detection/src/lstm_layer.h @@ -0,0 +1,20 @@ +#ifndef LSTM_LAYER_H +#define LSTM_LAYER_H + +#include "activations.h" +#include "layer.h" +#include "network.h" +#define USET + +layer make_lstm_layer(int batch, int inputs, int outputs, int steps, int batch_normalize, int adam); + +void forward_lstm_layer(layer l, network net); +void update_lstm_layer(layer l, update_args a); + +#ifdef GPU +void forward_lstm_layer_gpu(layer l, network net); +void backward_lstm_layer_gpu(layer l, network net); +void update_lstm_layer_gpu(layer l, update_args a); + +#endif +#endif diff --git a/hanzi_detection/src/matrix.c b/hanzi_detection/src/matrix.c new file mode 100755 index 0000000..799916b --- /dev/null +++ b/hanzi_detection/src/matrix.c @@ -0,0 +1,196 @@ +#include "matrix.h" +#include "utils.h" +#include "blas.h" +#include +#include +#include +#include +#include + +void free_matrix(matrix m) +{ + int i; + for(i = 0; i < m.rows; ++i) free(m.vals[i]); + free(m.vals); +} + +float matrix_topk_accuracy(matrix truth, matrix guess, int k) +{ + int *indexes = calloc(k, sizeof(int)); + int n = truth.cols; + int i,j; + int correct = 0; + for(i = 0; i < truth.rows; ++i){ + top_k(guess.vals[i], n, k, indexes); + for(j = 0; j < k; ++j){ + int class = indexes[j]; + if(truth.vals[i][class]){ + ++correct; + break; + } + } + } + free(indexes); + return (float)correct/truth.rows; +} + +void scale_matrix(matrix m, float scale) +{ + int i,j; + for(i = 0; i < m.rows; ++i){ + for(j = 0; j < m.cols; ++j){ + m.vals[i][j] *= scale; + } + } +} + +matrix resize_matrix(matrix m, int size) +{ + int i; + if (m.rows == size) return m; + if (m.rows < size) { + m.vals = realloc(m.vals, size*sizeof(float*)); + for (i = m.rows; i < size; ++i) { + m.vals[i] = calloc(m.cols, sizeof(float)); + } + } else if (m.rows > size) { + for (i = size; i < m.rows; ++i) { + free(m.vals[i]); + } + m.vals = realloc(m.vals, size*sizeof(float*)); + } + m.rows = size; + return m; +} + +void matrix_add_matrix(matrix from, matrix to) +{ + assert(from.rows == to.rows && from.cols == to.cols); + int i,j; + for(i = 0; i < from.rows; ++i){ + for(j = 0; j < from.cols; ++j){ + to.vals[i][j] += from.vals[i][j]; + } + } +} + +matrix copy_matrix(matrix m) +{ + matrix c = {0}; + c.rows = m.rows; + c.cols = m.cols; + c.vals = calloc(c.rows, sizeof(float *)); + int i; + for(i = 0; i < c.rows; ++i){ + c.vals[i] = calloc(c.cols, sizeof(float)); + copy_cpu(c.cols, m.vals[i], 1, c.vals[i], 1); + } + return c; +} + +matrix make_matrix(int rows, int cols) +{ + int i; + matrix m; + m.rows = rows; + m.cols = cols; + m.vals = calloc(m.rows, sizeof(float *)); + for(i = 0; i < m.rows; ++i){ + m.vals[i] = calloc(m.cols, sizeof(float)); + } + return m; +} + +matrix hold_out_matrix(matrix *m, int n) +{ + int i; + matrix h; + h.rows = n; + h.cols = m->cols; + h.vals = calloc(h.rows, sizeof(float *)); + for(i = 0; i < n; ++i){ + int index = rand()%m->rows; + h.vals[i] = m->vals[index]; + m->vals[index] = m->vals[--(m->rows)]; + } + return h; +} + +float *pop_column(matrix *m, int c) +{ + float *col = calloc(m->rows, sizeof(float)); + int i, j; + for(i = 0; i < m->rows; ++i){ + col[i] = m->vals[i][c]; + for(j = c; j < m->cols-1; ++j){ + m->vals[i][j] = m->vals[i][j+1]; + } + } + --m->cols; + return col; +} + +matrix csv_to_matrix(char *filename) +{ + FILE *fp = fopen(filename, "r"); + if(!fp) file_error(filename); + + matrix m; + m.cols = -1; + + char *line; + + int n = 0; + int size = 1024; + m.vals = calloc(size, sizeof(float*)); + while((line = fgetl(fp))){ + if(m.cols == -1) m.cols = count_fields(line); + if(n == size){ + size *= 2; + m.vals = realloc(m.vals, size*sizeof(float*)); + } + m.vals[n] = parse_fields(line, m.cols); + free(line); + ++n; + } + m.vals = realloc(m.vals, n*sizeof(float*)); + m.rows = n; + return m; +} + +void matrix_to_csv(matrix m) +{ + int i, j; + + for(i = 0; i < m.rows; ++i){ + for(j = 0; j < m.cols; ++j){ + if(j > 0) printf(","); + printf("%.17g", m.vals[i][j]); + } + printf("\n"); + } +} + +void print_matrix(matrix m) +{ + int i, j; + printf("%d X %d Matrix:\n",m.rows, m.cols); + printf(" __"); + for(j = 0; j < 16*m.cols-1; ++j) printf(" "); + printf("__ \n"); + + printf("| "); + for(j = 0; j < 16*m.cols-1; ++j) printf(" "); + printf(" |\n"); + + for(i = 0; i < m.rows; ++i){ + printf("| "); + for(j = 0; j < m.cols; ++j){ + printf("%15.7f ", m.vals[i][j]); + } + printf(" |\n"); + } + printf("|__"); + for(j = 0; j < 16*m.cols-1; ++j) printf(" "); + printf("__|\n"); +} diff --git a/hanzi_detection/src/matrix.h b/hanzi_detection/src/matrix.h new file mode 100755 index 0000000..879acd7 --- /dev/null +++ b/hanzi_detection/src/matrix.h @@ -0,0 +1,13 @@ +#ifndef MATRIX_H +#define MATRIX_H +#include "darknet.h" + +matrix copy_matrix(matrix m); +void print_matrix(matrix m); + +matrix hold_out_matrix(matrix *m, int n); +matrix resize_matrix(matrix m, int size); + +float *pop_column(matrix *m, int c); + +#endif diff --git a/hanzi_detection/src/maxpool_layer.c b/hanzi_detection/src/maxpool_layer.c new file mode 100755 index 0000000..fb05635 --- /dev/null +++ b/hanzi_detection/src/maxpool_layer.c @@ -0,0 +1,127 @@ +#include "maxpool_layer.h" +#include "cuda.h" +#include + +image get_maxpool_image(maxpool_layer l) +{ + int h = l.out_h; + int w = l.out_w; + int c = l.c; + return float_to_image(w,h,c,l.output); +} + +image get_maxpool_delta(maxpool_layer l) +{ + int h = l.out_h; + int w = l.out_w; + int c = l.c; + return float_to_image(w,h,c,l.delta); +} + +maxpool_layer make_maxpool_layer(int batch, int h, int w, int c, int size, int stride, int padding) +{ + maxpool_layer l = {0}; + l.type = MAXPOOL; + l.batch = batch; + l.h = h; + l.w = w; + l.c = c; + l.pad = padding; + l.out_w = (w + padding - size)/stride + 1; + l.out_h = (h + padding - size)/stride + 1; + l.out_c = c; + l.outputs = l.out_h * l.out_w * l.out_c; + l.inputs = h*w*c; + l.size = size; + l.stride = stride; + int output_size = l.out_h * l.out_w * l.out_c * batch; + l.indexes = calloc(output_size, sizeof(int)); + l.output = calloc(output_size, sizeof(float)); + l.delta = calloc(output_size, sizeof(float)); + l.forward = forward_maxpool_layer; + l.backward = backward_maxpool_layer; + #ifdef GPU + l.forward_gpu = forward_maxpool_layer_gpu; + l.backward_gpu = backward_maxpool_layer_gpu; + l.indexes_gpu = cuda_make_int_array(0, output_size); + l.output_gpu = cuda_make_array(l.output, output_size); + l.delta_gpu = cuda_make_array(l.delta, output_size); + #endif + fprintf(stderr, "max %d x %d / %d %4d x%4d x%4d -> %4d x%4d x%4d\n", size, size, stride, w, h, c, l.out_w, l.out_h, l.out_c); + return l; +} + +void resize_maxpool_layer(maxpool_layer *l, int w, int h) +{ + l->h = h; + l->w = w; + l->inputs = h*w*l->c; + + l->out_w = (w + l->pad - l->size)/l->stride + 1; + l->out_h = (h + l->pad - l->size)/l->stride + 1; + l->outputs = l->out_w * l->out_h * l->c; + int output_size = l->outputs * l->batch; + + l->indexes = realloc(l->indexes, output_size * sizeof(int)); + l->output = realloc(l->output, output_size * sizeof(float)); + l->delta = realloc(l->delta, output_size * sizeof(float)); + + #ifdef GPU + cuda_free((float *)l->indexes_gpu); + cuda_free(l->output_gpu); + cuda_free(l->delta_gpu); + l->indexes_gpu = cuda_make_int_array(0, output_size); + l->output_gpu = cuda_make_array(l->output, output_size); + l->delta_gpu = cuda_make_array(l->delta, output_size); + #endif +} + +void forward_maxpool_layer(const maxpool_layer l, network net) +{ + int b,i,j,k,m,n; + int w_offset = -l.pad/2; + int h_offset = -l.pad/2; + + int h = l.out_h; + int w = l.out_w; + int c = l.c; + + for(b = 0; b < l.batch; ++b){ + for(k = 0; k < c; ++k){ + for(i = 0; i < h; ++i){ + for(j = 0; j < w; ++j){ + int out_index = j + w*(i + h*(k + c*b)); + float max = -FLT_MAX; + int max_i = -1; + for(n = 0; n < l.size; ++n){ + for(m = 0; m < l.size; ++m){ + int cur_h = h_offset + i*l.stride + n; + int cur_w = w_offset + j*l.stride + m; + int index = cur_w + l.w*(cur_h + l.h*(k + b*l.c)); + int valid = (cur_h >= 0 && cur_h < l.h && + cur_w >= 0 && cur_w < l.w); + float val = (valid != 0) ? net.input[index] : -FLT_MAX; + max_i = (val > max) ? index : max_i; + max = (val > max) ? val : max; + } + } + l.output[out_index] = max; + l.indexes[out_index] = max_i; + } + } + } + } +} + +void backward_maxpool_layer(const maxpool_layer l, network net) +{ + int i; + int h = l.out_h; + int w = l.out_w; + int c = l.c; + for(i = 0; i < h*w*c*l.batch; ++i){ + int index = l.indexes[i]; + net.delta[index] += l.delta[i]; + } +} + diff --git a/hanzi_detection/src/maxpool_layer.h b/hanzi_detection/src/maxpool_layer.h new file mode 100755 index 0000000..ceb5190 --- /dev/null +++ b/hanzi_detection/src/maxpool_layer.h @@ -0,0 +1,23 @@ +#ifndef MAXPOOL_LAYER_H +#define MAXPOOL_LAYER_H + +#include "image.h" +#include "cuda.h" +#include "layer.h" +#include "network.h" + +typedef layer maxpool_layer; + +image get_maxpool_image(maxpool_layer l); +maxpool_layer make_maxpool_layer(int batch, int h, int w, int c, int size, int stride, int padding); +void resize_maxpool_layer(maxpool_layer *l, int w, int h); +void forward_maxpool_layer(const maxpool_layer l, network net); +void backward_maxpool_layer(const maxpool_layer l, network net); + +#ifdef GPU +void forward_maxpool_layer_gpu(maxpool_layer l, network net); +void backward_maxpool_layer_gpu(maxpool_layer l, network net); +#endif + +#endif + diff --git a/hanzi_detection/src/maxpool_layer_kernels.cu b/hanzi_detection/src/maxpool_layer_kernels.cu new file mode 100755 index 0000000..869ef46 --- /dev/null +++ b/hanzi_detection/src/maxpool_layer_kernels.cu @@ -0,0 +1,106 @@ +#include "cuda_runtime.h" +#include "curand.h" +#include "cublas_v2.h" + +extern "C" { +#include "maxpool_layer.h" +#include "cuda.h" +} + +__global__ void forward_maxpool_layer_kernel(int n, int in_h, int in_w, int in_c, int stride, int size, int pad, float *input, float *output, int *indexes) +{ + int h = (in_h + pad - size)/stride + 1; + int w = (in_w + pad - size)/stride + 1; + int c = in_c; + + int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(id >= n) return; + + int j = id % w; + id /= w; + int i = id % h; + id /= h; + int k = id % c; + id /= c; + int b = id; + + int w_offset = -pad/2; + int h_offset = -pad/2; + + int out_index = j + w*(i + h*(k + c*b)); + float max = -INFINITY; + int max_i = -1; + int l, m; + for(l = 0; l < size; ++l){ + for(m = 0; m < size; ++m){ + int cur_h = h_offset + i*stride + l; + int cur_w = w_offset + j*stride + m; + int index = cur_w + in_w*(cur_h + in_h*(k + b*in_c)); + int valid = (cur_h >= 0 && cur_h < in_h && + cur_w >= 0 && cur_w < in_w); + float val = (valid != 0) ? input[index] : -INFINITY; + max_i = (val > max) ? index : max_i; + max = (val > max) ? val : max; + } + } + output[out_index] = max; + indexes[out_index] = max_i; +} + +__global__ void backward_maxpool_layer_kernel(int n, int in_h, int in_w, int in_c, int stride, int size, int pad, float *delta, float *prev_delta, int *indexes) +{ + int h = (in_h + pad - size)/stride + 1; + int w = (in_w + pad - size)/stride + 1; + int c = in_c; + int area = (size-1)/stride; + + int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(id >= n) return; + + int index = id; + int j = id % in_w; + id /= in_w; + int i = id % in_h; + id /= in_h; + int k = id % in_c; + id /= in_c; + int b = id; + + int w_offset = -pad/2; + int h_offset = -pad/2; + + float d = 0; + int l, m; + for(l = -area; l < area+1; ++l){ + for(m = -area; m < area+1; ++m){ + int out_w = (j-w_offset)/stride + m; + int out_h = (i-h_offset)/stride + l; + int out_index = out_w + w*(out_h + h*(k + c*b)); + int valid = (out_w >= 0 && out_w < w && + out_h >= 0 && out_h < h); + d += (valid && indexes[out_index] == index) ? delta[out_index] : 0; + } + } + prev_delta[index] += d; +} + +extern "C" void forward_maxpool_layer_gpu(maxpool_layer layer, network net) +{ + int h = layer.out_h; + int w = layer.out_w; + int c = layer.c; + + size_t n = h*w*c*layer.batch; + + forward_maxpool_layer_kernel<<>>(n, layer.h, layer.w, layer.c, layer.stride, layer.size, layer.pad, net.input_gpu, layer.output_gpu, layer.indexes_gpu); + check_error(cudaPeekAtLastError()); +} + +extern "C" void backward_maxpool_layer_gpu(maxpool_layer layer, network net) +{ + size_t n = layer.h*layer.w*layer.c*layer.batch; + + backward_maxpool_layer_kernel<<>>(n, layer.h, layer.w, layer.c, layer.stride, layer.size, layer.pad, layer.delta_gpu, net.delta_gpu, layer.indexes_gpu); + check_error(cudaPeekAtLastError()); +} + diff --git a/hanzi_detection/src/network.c b/hanzi_detection/src/network.c new file mode 100755 index 0000000..aaab799 --- /dev/null +++ b/hanzi_detection/src/network.c @@ -0,0 +1,1129 @@ +#include +#include +#include +#include "network.h" +#include "image.h" +#include "data.h" +#include "utils.h" +#include "blas.h" + +#include "crop_layer.h" +#include "connected_layer.h" +#include "gru_layer.h" +#include "rnn_layer.h" +#include "crnn_layer.h" +#include "local_layer.h" +#include "convolutional_layer.h" +#include "activation_layer.h" +#include "detection_layer.h" +#include "region_layer.h" +#include "yolo_layer.h" +#include "normalization_layer.h" +#include "batchnorm_layer.h" +#include "maxpool_layer.h" +#include "reorg_layer.h" +#include "avgpool_layer.h" +#include "cost_layer.h" +#include "softmax_layer.h" +#include "dropout_layer.h" +#include "route_layer.h" +#include "upsample_layer.h" +#include "shortcut_layer.h" +#include "parser.h" +#include "data.h" + +load_args get_base_args(network *net) +{ + load_args args = {0}; + args.w = net->w; + args.h = net->h; + args.size = net->w; + + args.min = net->min_crop; + args.max = net->max_crop; + args.angle = net->angle; + args.aspect = net->aspect; + args.exposure = net->exposure; + args.center = net->center; + args.saturation = net->saturation; + args.hue = net->hue; + return args; +} + +network *load_network(char *cfg, char *weights, int clear) +{ + network *net = parse_network_cfg(cfg); + if(weights && weights[0] != 0){ + load_weights(net, weights); + } + if(clear) (*net->seen) = 0; + return net; +} + +size_t get_current_batch(network *net) +{ + size_t batch_num = (*net->seen)/(net->batch*net->subdivisions); + return batch_num; +} + +void reset_network_state(network *net, int b) +{ + int i; + for (i = 0; i < net->n; ++i) { + #ifdef GPU + layer l = net->layers[i]; + if(l.state_gpu){ + fill_gpu(l.outputs, 0, l.state_gpu + l.outputs*b, 1); + } + if(l.h_gpu){ + fill_gpu(l.outputs, 0, l.h_gpu + l.outputs*b, 1); + } + #endif + } +} + +void reset_rnn(network *net) +{ + reset_network_state(net, 0); +} + +float get_current_rate(network *net) +{ + size_t batch_num = get_current_batch(net); + int i; + float rate; + if (batch_num < net->burn_in) return net->learning_rate * pow((float)batch_num / net->burn_in, net->power); + switch (net->policy) { + case CONSTANT: + return net->learning_rate; + case STEP: + return net->learning_rate * pow(net->scale, batch_num/net->step); + case STEPS: + rate = net->learning_rate; + for(i = 0; i < net->num_steps; ++i){ + if(net->steps[i] > batch_num) return rate; + rate *= net->scales[i]; + } + return rate; + case EXP: + return net->learning_rate * pow(net->gamma, batch_num); + case POLY: + return net->learning_rate * pow(1 - (float)batch_num / net->max_batches, net->power); + case RANDOM: + return net->learning_rate * pow(rand_uniform(0,1), net->power); + case SIG: + return net->learning_rate * (1./(1.+exp(net->gamma*(batch_num - net->step)))); + default: + fprintf(stderr, "Policy is weird!\n"); + return net->learning_rate; + } +} + +char *get_layer_string(LAYER_TYPE a) +{ + switch(a){ + case CONVOLUTIONAL: + return "convolutional"; + case ACTIVE: + return "activation"; + case LOCAL: + return "local"; + case DECONVOLUTIONAL: + return "deconvolutional"; + case CONNECTED: + return "connected"; + case RNN: + return "rnn"; + case GRU: + return "gru"; + case LSTM: + return "lstm"; + case CRNN: + return "crnn"; + case MAXPOOL: + return "maxpool"; + case REORG: + return "reorg"; + case AVGPOOL: + return "avgpool"; + case SOFTMAX: + return "softmax"; + case DETECTION: + return "detection"; + case REGION: + return "region"; + case YOLO: + return "yolo"; + case DROPOUT: + return "dropout"; + case CROP: + return "crop"; + case COST: + return "cost"; + case ROUTE: + return "route"; + case SHORTCUT: + return "shortcut"; + case NORMALIZATION: + return "normalization"; + case BATCHNORM: + return "batchnorm"; + default: + break; + } + return "none"; +} + +network *make_network(int n) +{ + network *net = calloc(1, sizeof(network)); + net->n = n; + net->layers = calloc(net->n, sizeof(layer)); + net->seen = calloc(1, sizeof(size_t)); + net->t = calloc(1, sizeof(int)); + net->cost = calloc(1, sizeof(float)); + return net; +} + +void forward_network(network *netp) +{ +#ifdef GPU + if(netp->gpu_index >= 0){ + forward_network_gpu(netp); + return; + } +#endif + network net = *netp; + int i; + for(i = 0; i < net.n; ++i){ + net.index = i; + layer l = net.layers[i]; + if(l.delta){ + fill_cpu(l.outputs * l.batch, 0, l.delta, 1); + } + l.forward(l, net); + net.input = l.output; + if(l.truth) { + net.truth = l.output; + } + } + calc_network_cost(netp); +} + +void update_network(network *netp) +{ +#ifdef GPU + if(netp->gpu_index >= 0){ + update_network_gpu(netp); + return; + } +#endif + network net = *netp; + int i; + update_args a = {0}; + a.batch = net.batch*net.subdivisions; + a.learning_rate = get_current_rate(netp); + a.momentum = net.momentum; + a.decay = net.decay; + a.adam = net.adam; + a.B1 = net.B1; + a.B2 = net.B2; + a.eps = net.eps; + ++*net.t; + a.t = *net.t; + + for(i = 0; i < net.n; ++i){ + layer l = net.layers[i]; + if(l.update){ + l.update(l, a); + } + } +} + +void calc_network_cost(network *netp) +{ + network net = *netp; + int i; + float sum = 0; + int count = 0; + for(i = 0; i < net.n; ++i){ + if(net.layers[i].cost){ + sum += net.layers[i].cost[0]; + ++count; + } + } + *net.cost = sum/count; +} + +int get_predicted_class_network(network *net) +{ + return max_index(net->output, net->outputs); +} + +void backward_network(network *netp) +{ +#ifdef GPU + if(netp->gpu_index >= 0){ + backward_network_gpu(netp); + return; + } +#endif + network net = *netp; + int i; + network orig = net; + for(i = net.n-1; i >= 0; --i){ + layer l = net.layers[i]; + if(l.stopbackward) break; + if(i == 0){ + net = orig; + }else{ + layer prev = net.layers[i-1]; + net.input = prev.output; + net.delta = prev.delta; + } + net.index = i; + l.backward(l, net); + } +} + +float train_network_datum(network *net) +{ + *net->seen += net->batch; + net->train = 1; + forward_network(net); + backward_network(net); + float error = *net->cost; + if(((*net->seen)/net->batch)%net->subdivisions == 0) update_network(net); + return error; +} + +float train_network_sgd(network *net, data d, int n) +{ + int batch = net->batch; + + int i; + float sum = 0; + for(i = 0; i < n; ++i){ + get_random_batch(d, batch, net->input, net->truth); + float err = train_network_datum(net); + sum += err; + } + return (float)sum/(n*batch); +} + +float train_network(network *net, data d) +{ + assert(d.X.rows % net->batch == 0); + int batch = net->batch; + int n = d.X.rows / batch; + + int i; + float sum = 0; + for(i = 0; i < n; ++i){ + get_next_batch(d, batch, i*batch, net->input, net->truth); + float err = train_network_datum(net); + sum += err; + } + return (float)sum/(n*batch); +} + +void set_temp_network(network *net, float t) +{ + int i; + for(i = 0; i < net->n; ++i){ + net->layers[i].temperature = t; + } +} + + +void set_batch_network(network *net, int b) +{ + net->batch = b; + int i; + for(i = 0; i < net->n; ++i){ + net->layers[i].batch = b; +#ifdef CUDNN + if(net->layers[i].type == CONVOLUTIONAL){ + cudnn_convolutional_setup(net->layers + i); + } + if(net->layers[i].type == DECONVOLUTIONAL){ + layer *l = net->layers + i; + cudnnSetTensor4dDescriptor(l->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, 1, l->out_c, l->out_h, l->out_w); + cudnnSetTensor4dDescriptor(l->normTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, 1, l->out_c, 1, 1); + } +#endif + } +} + +int resize_network(network *net, int w, int h) +{ +#ifdef GPU + cuda_set_device(net->gpu_index); + cuda_free(net->workspace); +#endif + int i; + //if(w == net->w && h == net->h) return 0; + net->w = w; + net->h = h; + int inputs = 0; + size_t workspace_size = 0; + //fprintf(stderr, "Resizing to %d x %d...\n", w, h); + //fflush(stderr); + for (i = 0; i < net->n; ++i){ + layer l = net->layers[i]; + if(l.type == CONVOLUTIONAL){ + resize_convolutional_layer(&l, w, h); + }else if(l.type == CROP){ + resize_crop_layer(&l, w, h); + }else if(l.type == MAXPOOL){ + resize_maxpool_layer(&l, w, h); + }else if(l.type == REGION){ + resize_region_layer(&l, w, h); + }else if(l.type == YOLO){ + resize_yolo_layer(&l, w, h); + }else if(l.type == ROUTE){ + resize_route_layer(&l, net); + }else if(l.type == SHORTCUT){ + resize_shortcut_layer(&l, w, h); + }else if(l.type == UPSAMPLE){ + resize_upsample_layer(&l, w, h); + }else if(l.type == REORG){ + resize_reorg_layer(&l, w, h); + }else if(l.type == AVGPOOL){ + resize_avgpool_layer(&l, w, h); + }else if(l.type == NORMALIZATION){ + resize_normalization_layer(&l, w, h); + }else if(l.type == COST){ + resize_cost_layer(&l, inputs); + }else{ + error("Cannot resize this type of layer"); + } + if(l.workspace_size > workspace_size) workspace_size = l.workspace_size; + if(l.workspace_size > 2000000000) assert(0); + inputs = l.outputs; + net->layers[i] = l; + w = l.out_w; + h = l.out_h; + if(l.type == AVGPOOL) break; + } + layer out = get_network_output_layer(net); + net->inputs = net->layers[0].inputs; + net->outputs = out.outputs; + net->truths = out.outputs; + if(net->layers[net->n-1].truths) net->truths = net->layers[net->n-1].truths; + net->output = out.output; + free(net->input); + free(net->truth); + net->input = calloc(net->inputs*net->batch, sizeof(float)); + net->truth = calloc(net->truths*net->batch, sizeof(float)); +#ifdef GPU + if(gpu_index >= 0){ + cuda_free(net->input_gpu); + cuda_free(net->truth_gpu); + net->input_gpu = cuda_make_array(net->input, net->inputs*net->batch); + net->truth_gpu = cuda_make_array(net->truth, net->truths*net->batch); + if(workspace_size){ + net->workspace = cuda_make_array(0, (workspace_size-1)/sizeof(float)+1); + } + }else { + free(net->workspace); + net->workspace = calloc(1, workspace_size); + } +#else + free(net->workspace); + net->workspace = calloc(1, workspace_size); +#endif + //fprintf(stderr, " Done!\n"); + return 0; +} + +layer get_network_detection_layer(network *net) +{ + int i; + for(i = 0; i < net->n; ++i){ + if(net->layers[i].type == DETECTION){ + return net->layers[i]; + } + } + fprintf(stderr, "Detection layer not found!!\n"); + layer l = {0}; + return l; +} + +image get_network_image_layer(network *net, int i) +{ + layer l = net->layers[i]; +#ifdef GPU + //cuda_pull_array(l.output_gpu, l.output, l.outputs); +#endif + if (l.out_w && l.out_h && l.out_c){ + return float_to_image(l.out_w, l.out_h, l.out_c, l.output); + } + image def = {0}; + return def; +} + +image get_network_image(network *net) +{ + int i; + for(i = net->n-1; i >= 0; --i){ + image m = get_network_image_layer(net, i); + if(m.h != 0) return m; + } + image def = {0}; + return def; +} + +void visualize_network(network *net) +{ + image *prev = 0; + int i; + char buff[256]; + for(i = 0; i < net->n; ++i){ + sprintf(buff, "Layer %d", i); + layer l = net->layers[i]; + if(l.type == CONVOLUTIONAL){ + prev = visualize_convolutional_layer(l, buff, prev); + } + } +} + +void top_predictions(network *net, int k, int *index) +{ + top_k(net->output, net->outputs, k, index); +} + + +float *network_predict(network *net, float *input) +{ + network orig = *net; + net->input = input; + net->truth = 0; + net->train = 0; + net->delta = 0; + forward_network(net); + float *out = net->output; + *net = orig; + return out; +} + +int num_detections(network *net, float thresh) +{ + int i; + int s = 0; + for(i = 0; i < net->n; ++i){ + layer l = net->layers[i]; + if(l.type == YOLO){ + s += yolo_num_detections(l, thresh); + } + if(l.type == DETECTION || l.type == REGION){ + s += l.w*l.h*l.n; + } + } + return s; +} + +detection *make_network_boxes(network *net, float thresh, int *num) +{ + layer l = net->layers[net->n - 1]; + int i; + int nboxes = num_detections(net, thresh); + if(num) *num = nboxes; + detection *dets = calloc(nboxes, sizeof(detection)); + for(i = 0; i < nboxes; ++i){ + dets[i].prob = calloc(l.classes, sizeof(float)); + if(l.coords > 4){ + dets[i].mask = calloc(l.coords-4, sizeof(float)); + } + } + return dets; +} + +void fill_network_boxes(network *net, int w, int h, float thresh, float hier, int *map, int relative, detection *dets) +{ + int j; + for(j = 0; j < net->n; ++j){ + layer l = net->layers[j]; + if(l.type == YOLO){ + int count = get_yolo_detections(l, w, h, net->w, net->h, thresh, map, relative, dets); + dets += count; + } + if(l.type == REGION){ + get_region_detections(l, w, h, net->w, net->h, thresh, map, hier, relative, dets); + dets += l.w*l.h*l.n; + } + if(l.type == DETECTION){ + get_detection_detections(l, w, h, thresh, dets); + dets += l.w*l.h*l.n; + } + } +} + +detection *get_network_boxes(network *net, int w, int h, float thresh, float hier, int *map, int relative, int *num) +{ + detection *dets = make_network_boxes(net, thresh, num); + fill_network_boxes(net, w, h, thresh, hier, map, relative, dets); + return dets; +} + +void free_detections(detection *dets, int n) +{ + int i; + for(i = 0; i < n; ++i){ + free(dets[i].prob); + if(dets[i].mask) free(dets[i].mask); + } + free(dets); +} + +float *network_predict_image(network *net, image im) +{ + image imr = letterbox_image(im, net->w, net->h); + set_batch_network(net, 1); + float *p = network_predict(net, imr.data); + free_image(imr); + return p; +} + +int network_width(network *net){return net->w;} +int network_height(network *net){return net->h;} + +matrix network_predict_data_multi(network *net, data test, int n) +{ + int i,j,b,m; + int k = net->outputs; + matrix pred = make_matrix(test.X.rows, k); + float *X = calloc(net->batch*test.X.rows, sizeof(float)); + for(i = 0; i < test.X.rows; i += net->batch){ + for(b = 0; b < net->batch; ++b){ + if(i+b == test.X.rows) break; + memcpy(X+b*test.X.cols, test.X.vals[i+b], test.X.cols*sizeof(float)); + } + for(m = 0; m < n; ++m){ + float *out = network_predict(net, X); + for(b = 0; b < net->batch; ++b){ + if(i+b == test.X.rows) break; + for(j = 0; j < k; ++j){ + pred.vals[i+b][j] += out[j+b*k]/n; + } + } + } + } + free(X); + return pred; +} + +matrix network_predict_data(network *net, data test) +{ + int i,j,b; + int k = net->outputs; + matrix pred = make_matrix(test.X.rows, k); + float *X = calloc(net->batch*test.X.cols, sizeof(float)); + for(i = 0; i < test.X.rows; i += net->batch){ + for(b = 0; b < net->batch; ++b){ + if(i+b == test.X.rows) break; + memcpy(X+b*test.X.cols, test.X.vals[i+b], test.X.cols*sizeof(float)); + } + float *out = network_predict(net, X); + for(b = 0; b < net->batch; ++b){ + if(i+b == test.X.rows) break; + for(j = 0; j < k; ++j){ + pred.vals[i+b][j] = out[j+b*k]; + } + } + } + free(X); + return pred; +} + +void print_network(network *net) +{ + int i,j; + for(i = 0; i < net->n; ++i){ + layer l = net->layers[i]; + float *output = l.output; + int n = l.outputs; + float mean = mean_array(output, n); + float vari = variance_array(output, n); + fprintf(stderr, "Layer %d - Mean: %f, Variance: %f\n",i,mean, vari); + if(n > 100) n = 100; + for(j = 0; j < n; ++j) fprintf(stderr, "%f, ", output[j]); + if(n == 100)fprintf(stderr,".....\n"); + fprintf(stderr, "\n"); + } +} + +void compare_networks(network *n1, network *n2, data test) +{ + matrix g1 = network_predict_data(n1, test); + matrix g2 = network_predict_data(n2, test); + int i; + int a,b,c,d; + a = b = c = d = 0; + for(i = 0; i < g1.rows; ++i){ + int truth = max_index(test.y.vals[i], test.y.cols); + int p1 = max_index(g1.vals[i], g1.cols); + int p2 = max_index(g2.vals[i], g2.cols); + if(p1 == truth){ + if(p2 == truth) ++d; + else ++c; + }else{ + if(p2 == truth) ++b; + else ++a; + } + } + printf("%5d %5d\n%5d %5d\n", a, b, c, d); + float num = pow((abs(b - c) - 1.), 2.); + float den = b + c; + printf("%f\n", num/den); +} + +float network_accuracy(network *net, data d) +{ + matrix guess = network_predict_data(net, d); + float acc = matrix_topk_accuracy(d.y, guess,1); + free_matrix(guess); + return acc; +} + +float *network_accuracies(network *net, data d, int n) +{ + static float acc[2]; + matrix guess = network_predict_data(net, d); + acc[0] = matrix_topk_accuracy(d.y, guess, 1); + acc[1] = matrix_topk_accuracy(d.y, guess, n); + free_matrix(guess); + return acc; +} + +layer get_network_output_layer(network *net) +{ + int i; + for(i = net->n - 1; i >= 0; --i){ + if(net->layers[i].type != COST) break; + } + return net->layers[i]; +} + +float network_accuracy_multi(network *net, data d, int n) +{ + matrix guess = network_predict_data_multi(net, d, n); + float acc = matrix_topk_accuracy(d.y, guess,1); + free_matrix(guess); + return acc; +} + +void free_network(network *net) +{ + int i; + for(i = 0; i < net->n; ++i){ + free_layer(net->layers[i]); + } + free(net->layers); + if(net->input) free(net->input); + if(net->truth) free(net->truth); +#ifdef GPU + if(net->input_gpu) cuda_free(net->input_gpu); + if(net->truth_gpu) cuda_free(net->truth_gpu); +#endif + free(net); +} + +// Some day... +// ^ What the hell is this comment for? + + +layer network_output_layer(network *net) +{ + int i; + for(i = net->n - 1; i >= 0; --i){ + if(net->layers[i].type != COST) break; + } + return net->layers[i]; +} + +int network_inputs(network *net) +{ + return net->layers[0].inputs; +} + +int network_outputs(network *net) +{ + return network_output_layer(net).outputs; +} + +float *network_output(network *net) +{ + return network_output_layer(net).output; +} + +#ifdef GPU + +void forward_network_gpu(network *netp) +{ + network net = *netp; + cuda_set_device(net.gpu_index); + cuda_push_array(net.input_gpu, net.input, net.inputs*net.batch); + if(net.truth){ + cuda_push_array(net.truth_gpu, net.truth, net.truths*net.batch); + } + + int i; + for(i = 0; i < net.n; ++i){ + net.index = i; + layer l = net.layers[i]; + if(l.delta_gpu){ + fill_gpu(l.outputs * l.batch, 0, l.delta_gpu, 1); + } + l.forward_gpu(l, net); + net.input_gpu = l.output_gpu; + net.input = l.output; + if(l.truth) { + net.truth_gpu = l.output_gpu; + net.truth = l.output; + } + } + pull_network_output(netp); + calc_network_cost(netp); +} + +void backward_network_gpu(network *netp) +{ + int i; + network net = *netp; + network orig = net; + cuda_set_device(net.gpu_index); + for(i = net.n-1; i >= 0; --i){ + layer l = net.layers[i]; + if(l.stopbackward) break; + if(i == 0){ + net = orig; + }else{ + layer prev = net.layers[i-1]; + net.input = prev.output; + net.delta = prev.delta; + net.input_gpu = prev.output_gpu; + net.delta_gpu = prev.delta_gpu; + } + net.index = i; + l.backward_gpu(l, net); + } +} + +void update_network_gpu(network *netp) +{ + network net = *netp; + cuda_set_device(net.gpu_index); + int i; + update_args a = {0}; + a.batch = net.batch*net.subdivisions; + a.learning_rate = get_current_rate(netp); + a.momentum = net.momentum; + a.decay = net.decay; + a.adam = net.adam; + a.B1 = net.B1; + a.B2 = net.B2; + a.eps = net.eps; + ++*net.t; + a.t = (*net.t); + + for(i = 0; i < net.n; ++i){ + layer l = net.layers[i]; + if(l.update_gpu){ + l.update_gpu(l, a); + } + } +} + +void harmless_update_network_gpu(network *netp) +{ + network net = *netp; + cuda_set_device(net.gpu_index); + int i; + for(i = 0; i < net.n; ++i){ + layer l = net.layers[i]; + if(l.weight_updates_gpu) fill_gpu(l.nweights, 0, l.weight_updates_gpu, 1); + if(l.bias_updates_gpu) fill_gpu(l.nbiases, 0, l.bias_updates_gpu, 1); + if(l.scale_updates_gpu) fill_gpu(l.nbiases, 0, l.scale_updates_gpu, 1); + } +} + +typedef struct { + network *net; + data d; + float *err; +} train_args; + +void *train_thread(void *ptr) +{ + train_args args = *(train_args*)ptr; + free(ptr); + cuda_set_device(args.net->gpu_index); + *args.err = train_network(args.net, args.d); + return 0; +} + +pthread_t train_network_in_thread(network *net, data d, float *err) +{ + pthread_t thread; + train_args *ptr = (train_args *)calloc(1, sizeof(train_args)); + ptr->net = net; + ptr->d = d; + ptr->err = err; + if(pthread_create(&thread, 0, train_thread, ptr)) error("Thread creation failed"); + return thread; +} + +void merge_weights(layer l, layer base) +{ + if (l.type == CONVOLUTIONAL) { + axpy_cpu(l.n, 1, l.bias_updates, 1, base.biases, 1); + axpy_cpu(l.nweights, 1, l.weight_updates, 1, base.weights, 1); + if (l.scales) { + axpy_cpu(l.n, 1, l.scale_updates, 1, base.scales, 1); + } + } else if(l.type == CONNECTED) { + axpy_cpu(l.outputs, 1, l.bias_updates, 1, base.biases, 1); + axpy_cpu(l.outputs*l.inputs, 1, l.weight_updates, 1, base.weights, 1); + } +} + +void scale_weights(layer l, float s) +{ + if (l.type == CONVOLUTIONAL) { + scal_cpu(l.n, s, l.biases, 1); + scal_cpu(l.nweights, s, l.weights, 1); + if (l.scales) { + scal_cpu(l.n, s, l.scales, 1); + } + } else if(l.type == CONNECTED) { + scal_cpu(l.outputs, s, l.biases, 1); + scal_cpu(l.outputs*l.inputs, s, l.weights, 1); + } +} + + +void pull_weights(layer l) +{ + if(l.type == CONVOLUTIONAL || l.type == DECONVOLUTIONAL){ + cuda_pull_array(l.biases_gpu, l.bias_updates, l.n); + cuda_pull_array(l.weights_gpu, l.weight_updates, l.nweights); + if(l.scales) cuda_pull_array(l.scales_gpu, l.scale_updates, l.n); + } else if(l.type == CONNECTED){ + cuda_pull_array(l.biases_gpu, l.bias_updates, l.outputs); + cuda_pull_array(l.weights_gpu, l.weight_updates, l.outputs*l.inputs); + } +} + +void push_weights(layer l) +{ + if(l.type == CONVOLUTIONAL || l.type == DECONVOLUTIONAL){ + cuda_push_array(l.biases_gpu, l.biases, l.n); + cuda_push_array(l.weights_gpu, l.weights, l.nweights); + if(l.scales) cuda_push_array(l.scales_gpu, l.scales, l.n); + } else if(l.type == CONNECTED){ + cuda_push_array(l.biases_gpu, l.biases, l.outputs); + cuda_push_array(l.weights_gpu, l.weights, l.outputs*l.inputs); + } +} + +void distribute_weights(layer l, layer base) +{ + if (l.type == CONVOLUTIONAL || l.type == DECONVOLUTIONAL) { + cuda_push_array(l.biases_gpu, base.biases, l.n); + cuda_push_array(l.weights_gpu, base.weights, l.nweights); + if (base.scales) cuda_push_array(l.scales_gpu, base.scales, l.n); + } else if (l.type == CONNECTED) { + cuda_push_array(l.biases_gpu, base.biases, l.outputs); + cuda_push_array(l.weights_gpu, base.weights, l.outputs*l.inputs); + } +} + + +/* + + void pull_updates(layer l) + { + if(l.type == CONVOLUTIONAL){ + cuda_pull_array(l.bias_updates_gpu, l.bias_updates, l.n); + cuda_pull_array(l.weight_updates_gpu, l.weight_updates, l.nweights); + if(l.scale_updates) cuda_pull_array(l.scale_updates_gpu, l.scale_updates, l.n); + } else if(l.type == CONNECTED){ + cuda_pull_array(l.bias_updates_gpu, l.bias_updates, l.outputs); + cuda_pull_array(l.weight_updates_gpu, l.weight_updates, l.outputs*l.inputs); + } + } + + void push_updates(layer l) + { + if(l.type == CONVOLUTIONAL){ + cuda_push_array(l.bias_updates_gpu, l.bias_updates, l.n); + cuda_push_array(l.weight_updates_gpu, l.weight_updates, l.nweights); + if(l.scale_updates) cuda_push_array(l.scale_updates_gpu, l.scale_updates, l.n); + } else if(l.type == CONNECTED){ + cuda_push_array(l.bias_updates_gpu, l.bias_updates, l.outputs); + cuda_push_array(l.weight_updates_gpu, l.weight_updates, l.outputs*l.inputs); + } + } + + void update_layer(layer l, network net) + { + int update_batch = net.batch*net.subdivisions; + float rate = get_current_rate(net); + l.t = get_current_batch(net); + if(l.update_gpu){ + l.update_gpu(l, update_batch, rate*l.learning_rate_scale, net.momentum, net.decay); + } + } + void merge_updates(layer l, layer base) + { + if (l.type == CONVOLUTIONAL) { + axpy_cpu(l.n, 1, l.bias_updates, 1, base.bias_updates, 1); + axpy_cpu(l.nweights, 1, l.weight_updates, 1, base.weight_updates, 1); + if (l.scale_updates) { + axpy_cpu(l.n, 1, l.scale_updates, 1, base.scale_updates, 1); + } + } else if(l.type == CONNECTED) { + axpy_cpu(l.outputs, 1, l.bias_updates, 1, base.bias_updates, 1); + axpy_cpu(l.outputs*l.inputs, 1, l.weight_updates, 1, base.weight_updates, 1); + } + } + + void distribute_updates(layer l, layer base) + { + if(l.type == CONVOLUTIONAL || l.type == DECONVOLUTIONAL){ + cuda_push_array(l.bias_updates_gpu, base.bias_updates, l.n); + cuda_push_array(l.weight_updates_gpu, base.weight_updates, l.nweights); + if(base.scale_updates) cuda_push_array(l.scale_updates_gpu, base.scale_updates, l.n); + } else if(l.type == CONNECTED){ + cuda_push_array(l.bias_updates_gpu, base.bias_updates, l.outputs); + cuda_push_array(l.weight_updates_gpu, base.weight_updates, l.outputs*l.inputs); + } + } + */ + +/* + void sync_layer(network *nets, int n, int j) + { + int i; + network net = nets[0]; + layer base = net.layers[j]; + scale_weights(base, 0); + for (i = 0; i < n; ++i) { + cuda_set_device(nets[i].gpu_index); + layer l = nets[i].layers[j]; + pull_weights(l); + merge_weights(l, base); + } + scale_weights(base, 1./n); + for (i = 0; i < n; ++i) { + cuda_set_device(nets[i].gpu_index); + layer l = nets[i].layers[j]; + distribute_weights(l, base); + } + } + */ + +void sync_layer(network **nets, int n, int j) +{ + int i; + network *net = nets[0]; + layer base = net->layers[j]; + scale_weights(base, 0); + for (i = 0; i < n; ++i) { + cuda_set_device(nets[i]->gpu_index); + layer l = nets[i]->layers[j]; + pull_weights(l); + merge_weights(l, base); + } + scale_weights(base, 1./n); + for (i = 0; i < n; ++i) { + cuda_set_device(nets[i]->gpu_index); + layer l = nets[i]->layers[j]; + distribute_weights(l, base); + } +} + +typedef struct{ + network **nets; + int n; + int j; +} sync_args; + +void *sync_layer_thread(void *ptr) +{ + sync_args args = *(sync_args*)ptr; + sync_layer(args.nets, args.n, args.j); + free(ptr); + return 0; +} + +pthread_t sync_layer_in_thread(network **nets, int n, int j) +{ + pthread_t thread; + sync_args *ptr = (sync_args *)calloc(1, sizeof(sync_args)); + ptr->nets = nets; + ptr->n = n; + ptr->j = j; + if(pthread_create(&thread, 0, sync_layer_thread, ptr)) error("Thread creation failed"); + return thread; +} + +void sync_nets(network **nets, int n, int interval) +{ + int j; + int layers = nets[0]->n; + pthread_t *threads = (pthread_t *) calloc(layers, sizeof(pthread_t)); + + *(nets[0]->seen) += interval * (n-1) * nets[0]->batch * nets[0]->subdivisions; + for (j = 0; j < n; ++j){ + *(nets[j]->seen) = *(nets[0]->seen); + } + for (j = 0; j < layers; ++j) { + threads[j] = sync_layer_in_thread(nets, n, j); + } + for (j = 0; j < layers; ++j) { + pthread_join(threads[j], 0); + } + free(threads); +} + +float train_networks(network **nets, int n, data d, int interval) +{ + int i; + int batch = nets[0]->batch; + int subdivisions = nets[0]->subdivisions; + assert(batch * subdivisions * n == d.X.rows); + pthread_t *threads = (pthread_t *) calloc(n, sizeof(pthread_t)); + float *errors = (float *) calloc(n, sizeof(float)); + + float sum = 0; + for(i = 0; i < n; ++i){ + data p = get_data_part(d, i, n); + threads[i] = train_network_in_thread(nets[i], p, errors + i); + } + for(i = 0; i < n; ++i){ + pthread_join(threads[i], 0); + //printf("%f\n", errors[i]); + sum += errors[i]; + } + //cudaDeviceSynchronize(); + if (get_current_batch(nets[0]) % interval == 0) { + printf("Syncing... "); + fflush(stdout); + sync_nets(nets, n, interval); + printf("Done!\n"); + } + //cudaDeviceSynchronize(); + free(threads); + free(errors); + return (float)sum/(n); +} + +void pull_network_output(network *net) +{ + layer l = get_network_output_layer(net); + cuda_pull_array(l.output_gpu, l.output, l.outputs*l.batch); +} + +#endif diff --git a/hanzi_detection/src/network.h b/hanzi_detection/src/network.h new file mode 100755 index 0000000..1b0dfd1 --- /dev/null +++ b/hanzi_detection/src/network.h @@ -0,0 +1,29 @@ +// Oh boy, why am I about to do this.... +#ifndef NETWORK_H +#define NETWORK_H +#include "darknet.h" + +#include "image.h" +#include "layer.h" +#include "data.h" +#include "tree.h" + + +#ifdef GPU +void pull_network_output(network *net); +#endif + +void compare_networks(network *n1, network *n2, data d); +char *get_layer_string(LAYER_TYPE a); + +network *make_network(int n); + + +float network_accuracy_multi(network *net, data d, int n); +int get_predicted_class_network(network *net); +void print_network(network *net); +int resize_network(network *net, int w, int h); +void calc_network_cost(network *net); + +#endif + diff --git a/hanzi_detection/src/normalization_layer.c b/hanzi_detection/src/normalization_layer.c new file mode 100755 index 0000000..424714f --- /dev/null +++ b/hanzi_detection/src/normalization_layer.c @@ -0,0 +1,151 @@ +#include "normalization_layer.h" +#include "blas.h" + +#include + +layer make_normalization_layer(int batch, int w, int h, int c, int size, float alpha, float beta, float kappa) +{ + fprintf(stderr, "Local Response Normalization Layer: %d x %d x %d image, %d size\n", w,h,c,size); + layer layer = {0}; + layer.type = NORMALIZATION; + layer.batch = batch; + layer.h = layer.out_h = h; + layer.w = layer.out_w = w; + layer.c = layer.out_c = c; + layer.kappa = kappa; + layer.size = size; + layer.alpha = alpha; + layer.beta = beta; + layer.output = calloc(h * w * c * batch, sizeof(float)); + layer.delta = calloc(h * w * c * batch, sizeof(float)); + layer.squared = calloc(h * w * c * batch, sizeof(float)); + layer.norms = calloc(h * w * c * batch, sizeof(float)); + layer.inputs = w*h*c; + layer.outputs = layer.inputs; + + layer.forward = forward_normalization_layer; + layer.backward = backward_normalization_layer; + #ifdef GPU + layer.forward_gpu = forward_normalization_layer_gpu; + layer.backward_gpu = backward_normalization_layer_gpu; + + layer.output_gpu = cuda_make_array(layer.output, h * w * c * batch); + layer.delta_gpu = cuda_make_array(layer.delta, h * w * c * batch); + layer.squared_gpu = cuda_make_array(layer.squared, h * w * c * batch); + layer.norms_gpu = cuda_make_array(layer.norms, h * w * c * batch); + #endif + return layer; +} + +void resize_normalization_layer(layer *layer, int w, int h) +{ + int c = layer->c; + int batch = layer->batch; + layer->h = h; + layer->w = w; + layer->out_h = h; + layer->out_w = w; + layer->inputs = w*h*c; + layer->outputs = layer->inputs; + layer->output = realloc(layer->output, h * w * c * batch * sizeof(float)); + layer->delta = realloc(layer->delta, h * w * c * batch * sizeof(float)); + layer->squared = realloc(layer->squared, h * w * c * batch * sizeof(float)); + layer->norms = realloc(layer->norms, h * w * c * batch * sizeof(float)); +#ifdef GPU + cuda_free(layer->output_gpu); + cuda_free(layer->delta_gpu); + cuda_free(layer->squared_gpu); + cuda_free(layer->norms_gpu); + layer->output_gpu = cuda_make_array(layer->output, h * w * c * batch); + layer->delta_gpu = cuda_make_array(layer->delta, h * w * c * batch); + layer->squared_gpu = cuda_make_array(layer->squared, h * w * c * batch); + layer->norms_gpu = cuda_make_array(layer->norms, h * w * c * batch); +#endif +} + +void forward_normalization_layer(const layer layer, network net) +{ + int k,b; + int w = layer.w; + int h = layer.h; + int c = layer.c; + scal_cpu(w*h*c*layer.batch, 0, layer.squared, 1); + + for(b = 0; b < layer.batch; ++b){ + float *squared = layer.squared + w*h*c*b; + float *norms = layer.norms + w*h*c*b; + float *input = net.input + w*h*c*b; + pow_cpu(w*h*c, 2, input, 1, squared, 1); + + const_cpu(w*h, layer.kappa, norms, 1); + for(k = 0; k < layer.size/2; ++k){ + axpy_cpu(w*h, layer.alpha, squared + w*h*k, 1, norms, 1); + } + + for(k = 1; k < layer.c; ++k){ + copy_cpu(w*h, norms + w*h*(k-1), 1, norms + w*h*k, 1); + int prev = k - ((layer.size-1)/2) - 1; + int next = k + (layer.size/2); + if(prev >= 0) axpy_cpu(w*h, -layer.alpha, squared + w*h*prev, 1, norms + w*h*k, 1); + if(next < layer.c) axpy_cpu(w*h, layer.alpha, squared + w*h*next, 1, norms + w*h*k, 1); + } + } + pow_cpu(w*h*c*layer.batch, -layer.beta, layer.norms, 1, layer.output, 1); + mul_cpu(w*h*c*layer.batch, net.input, 1, layer.output, 1); +} + +void backward_normalization_layer(const layer layer, network net) +{ + // TODO This is approximate ;-) + // Also this should add in to delta instead of overwritting. + + int w = layer.w; + int h = layer.h; + int c = layer.c; + pow_cpu(w*h*c*layer.batch, -layer.beta, layer.norms, 1, net.delta, 1); + mul_cpu(w*h*c*layer.batch, layer.delta, 1, net.delta, 1); +} + +#ifdef GPU +void forward_normalization_layer_gpu(const layer layer, network net) +{ + int k,b; + int w = layer.w; + int h = layer.h; + int c = layer.c; + scal_gpu(w*h*c*layer.batch, 0, layer.squared_gpu, 1); + + for(b = 0; b < layer.batch; ++b){ + float *squared = layer.squared_gpu + w*h*c*b; + float *norms = layer.norms_gpu + w*h*c*b; + float *input = net.input_gpu + w*h*c*b; + pow_gpu(w*h*c, 2, input, 1, squared, 1); + + const_gpu(w*h, layer.kappa, norms, 1); + for(k = 0; k < layer.size/2; ++k){ + axpy_gpu(w*h, layer.alpha, squared + w*h*k, 1, norms, 1); + } + + for(k = 1; k < layer.c; ++k){ + copy_gpu(w*h, norms + w*h*(k-1), 1, norms + w*h*k, 1); + int prev = k - ((layer.size-1)/2) - 1; + int next = k + (layer.size/2); + if(prev >= 0) axpy_gpu(w*h, -layer.alpha, squared + w*h*prev, 1, norms + w*h*k, 1); + if(next < layer.c) axpy_gpu(w*h, layer.alpha, squared + w*h*next, 1, norms + w*h*k, 1); + } + } + pow_gpu(w*h*c*layer.batch, -layer.beta, layer.norms_gpu, 1, layer.output_gpu, 1); + mul_gpu(w*h*c*layer.batch, net.input_gpu, 1, layer.output_gpu, 1); +} + +void backward_normalization_layer_gpu(const layer layer, network net) +{ + // TODO This is approximate ;-) + + int w = layer.w; + int h = layer.h; + int c = layer.c; + pow_gpu(w*h*c*layer.batch, -layer.beta, layer.norms_gpu, 1, net.delta_gpu, 1); + mul_gpu(w*h*c*layer.batch, layer.delta_gpu, 1, net.delta_gpu, 1); +} +#endif diff --git a/hanzi_detection/src/normalization_layer.h b/hanzi_detection/src/normalization_layer.h new file mode 100755 index 0000000..665baa5 --- /dev/null +++ b/hanzi_detection/src/normalization_layer.h @@ -0,0 +1,19 @@ +#ifndef NORMALIZATION_LAYER_H +#define NORMALIZATION_LAYER_H + +#include "image.h" +#include "layer.h" +#include "network.h" + +layer make_normalization_layer(int batch, int w, int h, int c, int size, float alpha, float beta, float kappa); +void resize_normalization_layer(layer *layer, int h, int w); +void forward_normalization_layer(const layer layer, network net); +void backward_normalization_layer(const layer layer, network net); +void visualize_normalization_layer(layer layer, char *window); + +#ifdef GPU +void forward_normalization_layer_gpu(const layer layer, network net); +void backward_normalization_layer_gpu(const layer layer, network net); +#endif + +#endif diff --git a/hanzi_detection/src/option_list.c b/hanzi_detection/src/option_list.c new file mode 100755 index 0000000..2f52781 --- /dev/null +++ b/hanzi_detection/src/option_list.c @@ -0,0 +1,140 @@ +#include +#include +#include +#include "option_list.h" +#include "utils.h" + +list *read_data_cfg(char *filename) +{ + FILE *file = fopen(filename, "r"); + if(file == 0) file_error(filename); + char *line; + int nu = 0; + list *options = make_list(); + while((line=fgetl(file)) != 0){ + ++ nu; + strip(line); + switch(line[0]){ + case '\0': + case '#': + case ';': + free(line); + break; + default: + if(!read_option(line, options)){ + fprintf(stderr, "Config file error line %d, could parse: %s\n", nu, line); + free(line); + } + break; + } + } + fclose(file); + return options; +} + +metadata get_metadata(char *file) +{ + metadata m = {0}; + list *options = read_data_cfg(file); + + char *name_list = option_find_str(options, "names", 0); + if(!name_list) name_list = option_find_str(options, "labels", 0); + if(!name_list) { + fprintf(stderr, "No names or labels found\n"); + } else { + m.names = get_labels(name_list); + } + m.classes = option_find_int(options, "classes", 2); + free_list(options); + return m; +} + +int read_option(char *s, list *options) +{ + size_t i; + size_t len = strlen(s); + char *val = 0; + for(i = 0; i < len; ++i){ + if(s[i] == '='){ + s[i] = '\0'; + val = s+i+1; + break; + } + } + if(i == len-1) return 0; + char *key = s; + option_insert(options, key, val); + return 1; +} + +void option_insert(list *l, char *key, char *val) +{ + kvp *p = malloc(sizeof(kvp)); + p->key = key; + p->val = val; + p->used = 0; + list_insert(l, p); +} + +void option_unused(list *l) +{ + node *n = l->front; + while(n){ + kvp *p = (kvp *)n->val; + if(!p->used){ + fprintf(stderr, "Unused field: '%s = %s'\n", p->key, p->val); + } + n = n->next; + } +} + +char *option_find(list *l, char *key) +{ + node *n = l->front; + while(n){ + kvp *p = (kvp *)n->val; + if(strcmp(p->key, key) == 0){ + p->used = 1; + return p->val; + } + n = n->next; + } + return 0; +} +char *option_find_str(list *l, char *key, char *def) +{ + char *v = option_find(l, key); + if(v) return v; + if(def) fprintf(stderr, "%s: Using default '%s'\n", key, def); + return def; +} + +int option_find_int(list *l, char *key, int def) +{ + char *v = option_find(l, key); + if(v) return atoi(v); + fprintf(stderr, "%s: Using default '%d'\n", key, def); + return def; +} + +int option_find_int_quiet(list *l, char *key, int def) +{ + char *v = option_find(l, key); + if(v) return atoi(v); + return def; +} + +float option_find_float_quiet(list *l, char *key, float def) +{ + char *v = option_find(l, key); + if(v) return atof(v); + return def; +} + +float option_find_float(list *l, char *key, float def) +{ + char *v = option_find(l, key); + if(v) return atof(v); + fprintf(stderr, "%s: Using default '%lf'\n", key, def); + return def; +} diff --git a/hanzi_detection/src/option_list.h b/hanzi_detection/src/option_list.h new file mode 100755 index 0000000..844bd87 --- /dev/null +++ b/hanzi_detection/src/option_list.h @@ -0,0 +1,19 @@ +#ifndef OPTION_LIST_H +#define OPTION_LIST_H +#include "list.h" + +typedef struct{ + char *key; + char *val; + int used; +} kvp; + + +int read_option(char *s, list *options); +void option_insert(list *l, char *key, char *val); +char *option_find(list *l, char *key); +float option_find_float(list *l, char *key, float def); +float option_find_float_quiet(list *l, char *key, float def); +void option_unused(list *l); + +#endif diff --git a/hanzi_detection/src/parser.c b/hanzi_detection/src/parser.c new file mode 100755 index 0000000..c8141c9 --- /dev/null +++ b/hanzi_detection/src/parser.c @@ -0,0 +1,1312 @@ +#include +#include +#include +#include + +#include "activation_layer.h" +#include "logistic_layer.h" +#include "l2norm_layer.h" +#include "activations.h" +#include "avgpool_layer.h" +#include "batchnorm_layer.h" +#include "blas.h" +#include "connected_layer.h" +#include "deconvolutional_layer.h" +#include "convolutional_layer.h" +#include "cost_layer.h" +#include "crnn_layer.h" +#include "crop_layer.h" +#include "detection_layer.h" +#include "dropout_layer.h" +#include "gru_layer.h" +#include "list.h" +#include "local_layer.h" +#include "maxpool_layer.h" +#include "normalization_layer.h" +#include "option_list.h" +#include "parser.h" +#include "region_layer.h" +#include "yolo_layer.h" +#include "iseg_layer.h" +#include "reorg_layer.h" +#include "rnn_layer.h" +#include "route_layer.h" +#include "upsample_layer.h" +#include "shortcut_layer.h" +#include "softmax_layer.h" +#include "lstm_layer.h" +#include "utils.h" + +typedef struct{ + char *type; + list *options; +}section; + +list *read_cfg(char *filename); + +LAYER_TYPE string_to_layer_type(char * type) +{ + + if (strcmp(type, "[shortcut]")==0) return SHORTCUT; + if (strcmp(type, "[crop]")==0) return CROP; + if (strcmp(type, "[cost]")==0) return COST; + if (strcmp(type, "[detection]")==0) return DETECTION; + if (strcmp(type, "[region]")==0) return REGION; + if (strcmp(type, "[yolo]")==0) return YOLO; + if (strcmp(type, "[iseg]")==0) return ISEG; + if (strcmp(type, "[local]")==0) return LOCAL; + if (strcmp(type, "[conv]")==0 + || strcmp(type, "[convolutional]")==0) return CONVOLUTIONAL; + if (strcmp(type, "[deconv]")==0 + || strcmp(type, "[deconvolutional]")==0) return DECONVOLUTIONAL; + if (strcmp(type, "[activation]")==0) return ACTIVE; + if (strcmp(type, "[logistic]")==0) return LOGXENT; + if (strcmp(type, "[l2norm]")==0) return L2NORM; + if (strcmp(type, "[net]")==0 + || strcmp(type, "[network]")==0) return NETWORK; + if (strcmp(type, "[crnn]")==0) return CRNN; + if (strcmp(type, "[gru]")==0) return GRU; + if (strcmp(type, "[lstm]") == 0) return LSTM; + if (strcmp(type, "[rnn]")==0) return RNN; + if (strcmp(type, "[conn]")==0 + || strcmp(type, "[connected]")==0) return CONNECTED; + if (strcmp(type, "[max]")==0 + || strcmp(type, "[maxpool]")==0) return MAXPOOL; + if (strcmp(type, "[reorg]")==0) return REORG; + if (strcmp(type, "[avg]")==0 + || strcmp(type, "[avgpool]")==0) return AVGPOOL; + if (strcmp(type, "[dropout]")==0) return DROPOUT; + if (strcmp(type, "[lrn]")==0 + || strcmp(type, "[normalization]")==0) return NORMALIZATION; + if (strcmp(type, "[batchnorm]")==0) return BATCHNORM; + if (strcmp(type, "[soft]")==0 + || strcmp(type, "[softmax]")==0) return SOFTMAX; + if (strcmp(type, "[route]")==0) return ROUTE; + if (strcmp(type, "[upsample]")==0) return UPSAMPLE; + return BLANK; +} + +void free_section(section *s) +{ + free(s->type); + node *n = s->options->front; + while(n){ + kvp *pair = (kvp *)n->val; + free(pair->key); + free(pair); + node *next = n->next; + free(n); + n = next; + } + free(s->options); + free(s); +} + +void parse_data(char *data, float *a, int n) +{ + int i; + if(!data) return; + char *curr = data; + char *next = data; + int done = 0; + for(i = 0; i < n && !done; ++i){ + while(*++next !='\0' && *next != ','); + if(*next == '\0') done = 1; + *next = '\0'; + sscanf(curr, "%g", &a[i]); + curr = next+1; + } +} + +typedef struct size_params{ + int batch; + int inputs; + int h; + int w; + int c; + int index; + int time_steps; + network *net; +} size_params; + +local_layer parse_local(list *options, size_params params) +{ + int n = option_find_int(options, "filters",1); + int size = option_find_int(options, "size",1); + int stride = option_find_int(options, "stride",1); + int pad = option_find_int(options, "pad",0); + char *activation_s = option_find_str(options, "activation", "logistic"); + ACTIVATION activation = get_activation(activation_s); + + int batch,h,w,c; + h = params.h; + w = params.w; + c = params.c; + batch=params.batch; + if(!(h && w && c)) error("Layer before local layer must output image."); + + local_layer layer = make_local_layer(batch,h,w,c,n,size,stride,pad,activation); + + return layer; +} + +layer parse_deconvolutional(list *options, size_params params) +{ + int n = option_find_int(options, "filters",1); + int size = option_find_int(options, "size",1); + int stride = option_find_int(options, "stride",1); + + char *activation_s = option_find_str(options, "activation", "logistic"); + ACTIVATION activation = get_activation(activation_s); + + int batch,h,w,c; + h = params.h; + w = params.w; + c = params.c; + batch=params.batch; + if(!(h && w && c)) error("Layer before deconvolutional layer must output image."); + int batch_normalize = option_find_int_quiet(options, "batch_normalize", 0); + int pad = option_find_int_quiet(options, "pad",0); + int padding = option_find_int_quiet(options, "padding",0); + if(pad) padding = size/2; + + layer l = make_deconvolutional_layer(batch,h,w,c,n,size,stride,padding, activation, batch_normalize, params.net->adam); + + return l; +} + + +convolutional_layer parse_convolutional(list *options, size_params params) +{ + int n = option_find_int(options, "filters",1); + int size = option_find_int(options, "size",1); + int stride = option_find_int(options, "stride",1); + int pad = option_find_int_quiet(options, "pad",0); + int padding = option_find_int_quiet(options, "padding",0); + int groups = option_find_int_quiet(options, "groups", 1); + if(pad) padding = size/2; + + char *activation_s = option_find_str(options, "activation", "logistic"); + ACTIVATION activation = get_activation(activation_s); + + int batch,h,w,c; + h = params.h; + w = params.w; + c = params.c; + batch=params.batch; + if(!(h && w && c)) error("Layer before convolutional layer must output image."); + int batch_normalize = option_find_int_quiet(options, "batch_normalize", 0); + int binary = option_find_int_quiet(options, "binary", 0); + int xnor = option_find_int_quiet(options, "xnor", 0); + + convolutional_layer layer = make_convolutional_layer(batch,h,w,c,n,groups,size,stride,padding,activation, batch_normalize, binary, xnor, params.net->adam); + layer.flipped = option_find_int_quiet(options, "flipped", 0); + layer.dot = option_find_float_quiet(options, "dot", 0); + + return layer; +} + +layer parse_crnn(list *options, size_params params) +{ + int output_filters = option_find_int(options, "output_filters",1); + int hidden_filters = option_find_int(options, "hidden_filters",1); + char *activation_s = option_find_str(options, "activation", "logistic"); + ACTIVATION activation = get_activation(activation_s); + int batch_normalize = option_find_int_quiet(options, "batch_normalize", 0); + + layer l = make_crnn_layer(params.batch, params.w, params.h, params.c, hidden_filters, output_filters, params.time_steps, activation, batch_normalize); + + l.shortcut = option_find_int_quiet(options, "shortcut", 0); + + return l; +} + +layer parse_rnn(list *options, size_params params) +{ + int output = option_find_int(options, "output",1); + char *activation_s = option_find_str(options, "activation", "logistic"); + ACTIVATION activation = get_activation(activation_s); + int batch_normalize = option_find_int_quiet(options, "batch_normalize", 0); + + layer l = make_rnn_layer(params.batch, params.inputs, output, params.time_steps, activation, batch_normalize, params.net->adam); + + l.shortcut = option_find_int_quiet(options, "shortcut", 0); + + return l; +} + +layer parse_gru(list *options, size_params params) +{ + int output = option_find_int(options, "output",1); + int batch_normalize = option_find_int_quiet(options, "batch_normalize", 0); + + layer l = make_gru_layer(params.batch, params.inputs, output, params.time_steps, batch_normalize, params.net->adam); + l.tanh = option_find_int_quiet(options, "tanh", 0); + + return l; +} + +layer parse_lstm(list *options, size_params params) +{ + int output = option_find_int(options, "output", 1); + int batch_normalize = option_find_int_quiet(options, "batch_normalize", 0); + + layer l = make_lstm_layer(params.batch, params.inputs, output, params.time_steps, batch_normalize, params.net->adam); + + return l; +} + +layer parse_connected(list *options, size_params params) +{ + int output = option_find_int(options, "output",1); + char *activation_s = option_find_str(options, "activation", "logistic"); + ACTIVATION activation = get_activation(activation_s); + int batch_normalize = option_find_int_quiet(options, "batch_normalize", 0); + + layer l = make_connected_layer(params.batch, params.inputs, output, activation, batch_normalize, params.net->adam); + return l; +} + +layer parse_softmax(list *options, size_params params) +{ + int groups = option_find_int_quiet(options, "groups",1); + layer l = make_softmax_layer(params.batch, params.inputs, groups); + l.temperature = option_find_float_quiet(options, "temperature", 1); + char *tree_file = option_find_str(options, "tree", 0); + if (tree_file) l.softmax_tree = read_tree(tree_file); + l.w = params.w; + l.h = params.h; + l.c = params.c; + l.spatial = option_find_float_quiet(options, "spatial", 0); + l.noloss = option_find_int_quiet(options, "noloss", 0); + return l; +} + +int *parse_yolo_mask(char *a, int *num) +{ + int *mask = 0; + if(a){ + int len = strlen(a); + int n = 1; + int i; + for(i = 0; i < len; ++i){ + if (a[i] == ',') ++n; + } + mask = calloc(n, sizeof(int)); + for(i = 0; i < n; ++i){ + int val = atoi(a); + mask[i] = val; + a = strchr(a, ',')+1; + } + *num = n; + } + return mask; +} + +layer parse_yolo(list *options, size_params params) +{ + int classes = option_find_int(options, "classes", 20); + int total = option_find_int(options, "num", 1); + int num = total; + + char *a = option_find_str(options, "mask", 0); + int *mask = parse_yolo_mask(a, &num); + layer l = make_yolo_layer(params.batch, params.w, params.h, num, total, mask, classes); + assert(l.outputs == params.inputs); + + l.max_boxes = option_find_int_quiet(options, "max",90); + l.jitter = option_find_float(options, "jitter", .2); + + l.ignore_thresh = option_find_float(options, "ignore_thresh", .5); + l.truth_thresh = option_find_float(options, "truth_thresh", 1); + l.random = option_find_int_quiet(options, "random", 0); + + char *map_file = option_find_str(options, "map", 0); + if (map_file) l.map = read_map(map_file); + + a = option_find_str(options, "anchors", 0); + if(a){ + int len = strlen(a); + int n = 1; + int i; + for(i = 0; i < len; ++i){ + if (a[i] == ',') ++n; + } + for(i = 0; i < n; ++i){ + float bias = atof(a); + l.biases[i] = bias; + a = strchr(a, ',')+1; + } + } + return l; +} + +layer parse_iseg(list *options, size_params params) +{ + int classes = option_find_int(options, "classes", 20); + int ids = option_find_int(options, "ids", 32); + layer l = make_iseg_layer(params.batch, params.w, params.h, classes, ids); + assert(l.outputs == params.inputs); + return l; +} + +layer parse_region(list *options, size_params params) +{ + int coords = option_find_int(options, "coords", 4); + int classes = option_find_int(options, "classes", 20); + int num = option_find_int(options, "num", 1); + + layer l = make_region_layer(params.batch, params.w, params.h, num, classes, coords); + assert(l.outputs == params.inputs); + + l.log = option_find_int_quiet(options, "log", 0); + l.sqrt = option_find_int_quiet(options, "sqrt", 0); + + l.softmax = option_find_int(options, "softmax", 0); + l.background = option_find_int_quiet(options, "background", 0); + l.max_boxes = option_find_int_quiet(options, "max",30); + l.jitter = option_find_float(options, "jitter", .2); + l.rescore = option_find_int_quiet(options, "rescore",0); + + l.thresh = option_find_float(options, "thresh", .5); + l.classfix = option_find_int_quiet(options, "classfix", 0); + l.absolute = option_find_int_quiet(options, "absolute", 0); + l.random = option_find_int_quiet(options, "random", 0); + + l.coord_scale = option_find_float(options, "coord_scale", 1); + l.object_scale = option_find_float(options, "object_scale", 1); + l.noobject_scale = option_find_float(options, "noobject_scale", 1); + l.mask_scale = option_find_float(options, "mask_scale", 1); + l.class_scale = option_find_float(options, "class_scale", 1); + l.bias_match = option_find_int_quiet(options, "bias_match",0); + + char *tree_file = option_find_str(options, "tree", 0); + if (tree_file) l.softmax_tree = read_tree(tree_file); + char *map_file = option_find_str(options, "map", 0); + if (map_file) l.map = read_map(map_file); + + char *a = option_find_str(options, "anchors", 0); + if(a){ + int len = strlen(a); + int n = 1; + int i; + for(i = 0; i < len; ++i){ + if (a[i] == ',') ++n; + } + for(i = 0; i < n; ++i){ + float bias = atof(a); + l.biases[i] = bias; + a = strchr(a, ',')+1; + } + } + return l; +} + +detection_layer parse_detection(list *options, size_params params) +{ + int coords = option_find_int(options, "coords", 1); + int classes = option_find_int(options, "classes", 1); + int rescore = option_find_int(options, "rescore", 0); + int num = option_find_int(options, "num", 1); + int side = option_find_int(options, "side", 7); + detection_layer layer = make_detection_layer(params.batch, params.inputs, num, side, classes, coords, rescore); + + layer.softmax = option_find_int(options, "softmax", 0); + layer.sqrt = option_find_int(options, "sqrt", 0); + + layer.max_boxes = option_find_int_quiet(options, "max",90); + layer.coord_scale = option_find_float(options, "coord_scale", 1); + layer.forced = option_find_int(options, "forced", 0); + layer.object_scale = option_find_float(options, "object_scale", 1); + layer.noobject_scale = option_find_float(options, "noobject_scale", 1); + layer.class_scale = option_find_float(options, "class_scale", 1); + layer.jitter = option_find_float(options, "jitter", .2); + layer.random = option_find_int_quiet(options, "random", 0); + layer.reorg = option_find_int_quiet(options, "reorg", 0); + return layer; +} + +cost_layer parse_cost(list *options, size_params params) +{ + char *type_s = option_find_str(options, "type", "sse"); + COST_TYPE type = get_cost_type(type_s); + float scale = option_find_float_quiet(options, "scale",1); + cost_layer layer = make_cost_layer(params.batch, params.inputs, type, scale); + layer.ratio = option_find_float_quiet(options, "ratio",0); + layer.noobject_scale = option_find_float_quiet(options, "noobj", 1); + layer.thresh = option_find_float_quiet(options, "thresh",0); + return layer; +} + +crop_layer parse_crop(list *options, size_params params) +{ + int crop_height = option_find_int(options, "crop_height",1); + int crop_width = option_find_int(options, "crop_width",1); + int flip = option_find_int(options, "flip",0); + float angle = option_find_float(options, "angle",0); + float saturation = option_find_float(options, "saturation",1); + float exposure = option_find_float(options, "exposure",1); + + int batch,h,w,c; + h = params.h; + w = params.w; + c = params.c; + batch=params.batch; + if(!(h && w && c)) error("Layer before crop layer must output image."); + + int noadjust = option_find_int_quiet(options, "noadjust",0); + + crop_layer l = make_crop_layer(batch,h,w,c,crop_height,crop_width,flip, angle, saturation, exposure); + l.shift = option_find_float(options, "shift", 0); + l.noadjust = noadjust; + return l; +} + +layer parse_reorg(list *options, size_params params) +{ + int stride = option_find_int(options, "stride",1); + int reverse = option_find_int_quiet(options, "reverse",0); + int flatten = option_find_int_quiet(options, "flatten",0); + int extra = option_find_int_quiet(options, "extra",0); + + int batch,h,w,c; + h = params.h; + w = params.w; + c = params.c; + batch=params.batch; + if(!(h && w && c)) error("Layer before reorg layer must output image."); + + layer layer = make_reorg_layer(batch,w,h,c,stride,reverse, flatten, extra); + return layer; +} + +maxpool_layer parse_maxpool(list *options, size_params params) +{ + int stride = option_find_int(options, "stride",1); + int size = option_find_int(options, "size",stride); + int padding = option_find_int_quiet(options, "padding", size-1); + + int batch,h,w,c; + h = params.h; + w = params.w; + c = params.c; + batch=params.batch; + if(!(h && w && c)) error("Layer before maxpool layer must output image."); + + maxpool_layer layer = make_maxpool_layer(batch,h,w,c,size,stride,padding); + return layer; +} + +avgpool_layer parse_avgpool(list *options, size_params params) +{ + int batch,w,h,c; + w = params.w; + h = params.h; + c = params.c; + batch=params.batch; + if(!(h && w && c)) error("Layer before avgpool layer must output image."); + + avgpool_layer layer = make_avgpool_layer(batch,w,h,c); + return layer; +} + +dropout_layer parse_dropout(list *options, size_params params) +{ + float probability = option_find_float(options, "probability", .5); + dropout_layer layer = make_dropout_layer(params.batch, params.inputs, probability); + layer.out_w = params.w; + layer.out_h = params.h; + layer.out_c = params.c; + return layer; +} + +layer parse_normalization(list *options, size_params params) +{ + float alpha = option_find_float(options, "alpha", .0001); + float beta = option_find_float(options, "beta" , .75); + float kappa = option_find_float(options, "kappa", 1); + int size = option_find_int(options, "size", 5); + layer l = make_normalization_layer(params.batch, params.w, params.h, params.c, size, alpha, beta, kappa); + return l; +} + +layer parse_batchnorm(list *options, size_params params) +{ + layer l = make_batchnorm_layer(params.batch, params.w, params.h, params.c); + return l; +} + +layer parse_shortcut(list *options, size_params params, network *net) +{ + char *l = option_find(options, "from"); + int index = atoi(l); + if(index < 0) index = params.index + index; + + int batch = params.batch; + layer from = net->layers[index]; + + layer s = make_shortcut_layer(batch, index, params.w, params.h, params.c, from.out_w, from.out_h, from.out_c); + + char *activation_s = option_find_str(options, "activation", "linear"); + ACTIVATION activation = get_activation(activation_s); + s.activation = activation; + s.alpha = option_find_float_quiet(options, "alpha", 1); + s.beta = option_find_float_quiet(options, "beta", 1); + return s; +} + + +layer parse_l2norm(list *options, size_params params) +{ + layer l = make_l2norm_layer(params.batch, params.inputs); + l.h = l.out_h = params.h; + l.w = l.out_w = params.w; + l.c = l.out_c = params.c; + return l; +} + + +layer parse_logistic(list *options, size_params params) +{ + layer l = make_logistic_layer(params.batch, params.inputs); + l.h = l.out_h = params.h; + l.w = l.out_w = params.w; + l.c = l.out_c = params.c; + return l; +} + +layer parse_activation(list *options, size_params params) +{ + char *activation_s = option_find_str(options, "activation", "linear"); + ACTIVATION activation = get_activation(activation_s); + + layer l = make_activation_layer(params.batch, params.inputs, activation); + + l.h = l.out_h = params.h; + l.w = l.out_w = params.w; + l.c = l.out_c = params.c; + + return l; +} + +layer parse_upsample(list *options, size_params params, network *net) +{ + + int stride = option_find_int(options, "stride",2); + layer l = make_upsample_layer(params.batch, params.w, params.h, params.c, stride); + l.scale = option_find_float_quiet(options, "scale", 1); + return l; +} + +route_layer parse_route(list *options, size_params params, network *net) +{ + char *l = option_find(options, "layers"); + int len = strlen(l); + if(!l) error("Route Layer must specify input layers"); + int n = 1; + int i; + for(i = 0; i < len; ++i){ + if (l[i] == ',') ++n; + } + + int *layers = calloc(n, sizeof(int)); + int *sizes = calloc(n, sizeof(int)); + for(i = 0; i < n; ++i){ + int index = atoi(l); + l = strchr(l, ',')+1; + if(index < 0) index = params.index + index; + layers[i] = index; + sizes[i] = net->layers[index].outputs; + } + int batch = params.batch; + + route_layer layer = make_route_layer(batch, n, layers, sizes); + + convolutional_layer first = net->layers[layers[0]]; + layer.out_w = first.out_w; + layer.out_h = first.out_h; + layer.out_c = first.out_c; + for(i = 1; i < n; ++i){ + int index = layers[i]; + convolutional_layer next = net->layers[index]; + if(next.out_w == first.out_w && next.out_h == first.out_h){ + layer.out_c += next.out_c; + }else{ + layer.out_h = layer.out_w = layer.out_c = 0; + } + } + + return layer; +} + +learning_rate_policy get_policy(char *s) +{ + if (strcmp(s, "random")==0) return RANDOM; + if (strcmp(s, "poly")==0) return POLY; + if (strcmp(s, "constant")==0) return CONSTANT; + if (strcmp(s, "step")==0) return STEP; + if (strcmp(s, "exp")==0) return EXP; + if (strcmp(s, "sigmoid")==0) return SIG; + if (strcmp(s, "steps")==0) return STEPS; + fprintf(stderr, "Couldn't find policy %s, going with constant\n", s); + return CONSTANT; +} + +void parse_net_options(list *options, network *net) +{ + net->batch = option_find_int(options, "batch",1); + net->learning_rate = option_find_float(options, "learning_rate", .001); + net->momentum = option_find_float(options, "momentum", .9); + net->decay = option_find_float(options, "decay", .0001); + int subdivs = option_find_int(options, "subdivisions",1); + net->time_steps = option_find_int_quiet(options, "time_steps",1); + net->notruth = option_find_int_quiet(options, "notruth",0); + net->batch /= subdivs; + net->batch *= net->time_steps; + net->subdivisions = subdivs; + net->random = option_find_int_quiet(options, "random", 0); + + net->adam = option_find_int_quiet(options, "adam", 0); + if(net->adam){ + net->B1 = option_find_float(options, "B1", .9); + net->B2 = option_find_float(options, "B2", .999); + net->eps = option_find_float(options, "eps", .0000001); + } + + net->h = option_find_int_quiet(options, "height",0); + net->w = option_find_int_quiet(options, "width",0); + net->c = option_find_int_quiet(options, "channels",0); + net->inputs = option_find_int_quiet(options, "inputs", net->h * net->w * net->c); + net->max_crop = option_find_int_quiet(options, "max_crop",net->w*2); + net->min_crop = option_find_int_quiet(options, "min_crop",net->w); + net->max_ratio = option_find_float_quiet(options, "max_ratio", (float) net->max_crop / net->w); + net->min_ratio = option_find_float_quiet(options, "min_ratio", (float) net->min_crop / net->w); + net->center = option_find_int_quiet(options, "center",0); + net->clip = option_find_float_quiet(options, "clip", 0); + + net->angle = option_find_float_quiet(options, "angle", 0); + net->aspect = option_find_float_quiet(options, "aspect", 1); + net->saturation = option_find_float_quiet(options, "saturation", 1); + net->exposure = option_find_float_quiet(options, "exposure", 1); + net->hue = option_find_float_quiet(options, "hue", 0); + + if(!net->inputs && !(net->h && net->w && net->c)) error("No input parameters supplied"); + + char *policy_s = option_find_str(options, "policy", "constant"); + net->policy = get_policy(policy_s); + net->burn_in = option_find_int_quiet(options, "burn_in", 0); + net->power = option_find_float_quiet(options, "power", 4); + if(net->policy == STEP){ + net->step = option_find_int(options, "step", 1); + net->scale = option_find_float(options, "scale", 1); + } else if (net->policy == STEPS){ + char *l = option_find(options, "steps"); + char *p = option_find(options, "scales"); + if(!l || !p) error("STEPS policy must have steps and scales in cfg file"); + + int len = strlen(l); + int n = 1; + int i; + for(i = 0; i < len; ++i){ + if (l[i] == ',') ++n; + } + int *steps = calloc(n, sizeof(int)); + float *scales = calloc(n, sizeof(float)); + for(i = 0; i < n; ++i){ + int step = atoi(l); + float scale = atof(p); + l = strchr(l, ',')+1; + p = strchr(p, ',')+1; + steps[i] = step; + scales[i] = scale; + } + net->scales = scales; + net->steps = steps; + net->num_steps = n; + } else if (net->policy == EXP){ + net->gamma = option_find_float(options, "gamma", 1); + } else if (net->policy == SIG){ + net->gamma = option_find_float(options, "gamma", 1); + net->step = option_find_int(options, "step", 1); + } else if (net->policy == POLY || net->policy == RANDOM){ + } + net->max_batches = option_find_int(options, "max_batches", 0); +} + +int is_network(section *s) +{ + return (strcmp(s->type, "[net]")==0 + || strcmp(s->type, "[network]")==0); +} + +network *parse_network_cfg(char *filename) +{ + list *sections = read_cfg(filename); + node *n = sections->front; + if(!n) error("Config file has no sections"); + network *net = make_network(sections->size - 1); + net->gpu_index = gpu_index; + size_params params; + + section *s = (section *)n->val; + list *options = s->options; + if(!is_network(s)) error("First section must be [net] or [network]"); + parse_net_options(options, net); + + params.h = net->h; + params.w = net->w; + params.c = net->c; + params.inputs = net->inputs; + params.batch = net->batch; + params.time_steps = net->time_steps; + params.net = net; + + size_t workspace_size = 0; + n = n->next; + int count = 0; + free_section(s); + fprintf(stderr, "layer filters size input output\n"); + while(n){ + params.index = count; + fprintf(stderr, "%5d ", count); + s = (section *)n->val; + options = s->options; + layer l = {0}; + LAYER_TYPE lt = string_to_layer_type(s->type); + if(lt == CONVOLUTIONAL){ + l = parse_convolutional(options, params); + }else if(lt == DECONVOLUTIONAL){ + l = parse_deconvolutional(options, params); + }else if(lt == LOCAL){ + l = parse_local(options, params); + }else if(lt == ACTIVE){ + l = parse_activation(options, params); + }else if(lt == LOGXENT){ + l = parse_logistic(options, params); + }else if(lt == L2NORM){ + l = parse_l2norm(options, params); + }else if(lt == RNN){ + l = parse_rnn(options, params); + }else if(lt == GRU){ + l = parse_gru(options, params); + }else if (lt == LSTM) { + l = parse_lstm(options, params); + }else if(lt == CRNN){ + l = parse_crnn(options, params); + }else if(lt == CONNECTED){ + l = parse_connected(options, params); + }else if(lt == CROP){ + l = parse_crop(options, params); + }else if(lt == COST){ + l = parse_cost(options, params); + }else if(lt == REGION){ + l = parse_region(options, params); + }else if(lt == YOLO){ + l = parse_yolo(options, params); + }else if(lt == ISEG){ + l = parse_iseg(options, params); + }else if(lt == DETECTION){ + l = parse_detection(options, params); + }else if(lt == SOFTMAX){ + l = parse_softmax(options, params); + net->hierarchy = l.softmax_tree; + }else if(lt == NORMALIZATION){ + l = parse_normalization(options, params); + }else if(lt == BATCHNORM){ + l = parse_batchnorm(options, params); + }else if(lt == MAXPOOL){ + l = parse_maxpool(options, params); + }else if(lt == REORG){ + l = parse_reorg(options, params); + }else if(lt == AVGPOOL){ + l = parse_avgpool(options, params); + }else if(lt == ROUTE){ + l = parse_route(options, params, net); + }else if(lt == UPSAMPLE){ + l = parse_upsample(options, params, net); + }else if(lt == SHORTCUT){ + l = parse_shortcut(options, params, net); + }else if(lt == DROPOUT){ + l = parse_dropout(options, params); + l.output = net->layers[count-1].output; + l.delta = net->layers[count-1].delta; +#ifdef GPU + l.output_gpu = net->layers[count-1].output_gpu; + l.delta_gpu = net->layers[count-1].delta_gpu; +#endif + }else{ + fprintf(stderr, "Type not recognized: %s\n", s->type); + } + l.clip = net->clip; + l.truth = option_find_int_quiet(options, "truth", 0); + l.onlyforward = option_find_int_quiet(options, "onlyforward", 0); + l.stopbackward = option_find_int_quiet(options, "stopbackward", 0); + l.dontsave = option_find_int_quiet(options, "dontsave", 0); + l.dontload = option_find_int_quiet(options, "dontload", 0); + l.numload = option_find_int_quiet(options, "numload", 0); + l.dontloadscales = option_find_int_quiet(options, "dontloadscales", 0); + l.learning_rate_scale = option_find_float_quiet(options, "learning_rate", 1); + l.smooth = option_find_float_quiet(options, "smooth", 0); + option_unused(options); + net->layers[count] = l; + if (l.workspace_size > workspace_size) workspace_size = l.workspace_size; + free_section(s); + n = n->next; + ++count; + if(n){ + params.h = l.out_h; + params.w = l.out_w; + params.c = l.out_c; + params.inputs = l.outputs; + } + } + free_list(sections); + layer out = get_network_output_layer(net); + net->outputs = out.outputs; + net->truths = out.outputs; + if(net->layers[net->n-1].truths) net->truths = net->layers[net->n-1].truths; + net->output = out.output; + net->input = calloc(net->inputs*net->batch, sizeof(float)); + net->truth = calloc(net->truths*net->batch, sizeof(float)); +#ifdef GPU + net->output_gpu = out.output_gpu; + net->input_gpu = cuda_make_array(net->input, net->inputs*net->batch); + net->truth_gpu = cuda_make_array(net->truth, net->truths*net->batch); +#endif + if(workspace_size){ + //printf("%ld\n", workspace_size); +#ifdef GPU + if(gpu_index >= 0){ + net->workspace = cuda_make_array(0, (workspace_size-1)/sizeof(float)+1); + }else { + net->workspace = calloc(1, workspace_size); + } +#else + net->workspace = calloc(1, workspace_size); +#endif + } + return net; +} + +list *read_cfg(char *filename) +{ + FILE *file = fopen(filename, "r"); + if(file == 0) file_error(filename); + char *line; + int nu = 0; + list *options = make_list(); + section *current = 0; + while((line=fgetl(file)) != 0){ + ++ nu; + strip(line); + switch(line[0]){ + case '[': + current = malloc(sizeof(section)); + list_insert(options, current); + current->options = make_list(); + current->type = line; + break; + case '\0': + case '#': + case ';': + free(line); + break; + default: + if(!read_option(line, current->options)){ + fprintf(stderr, "Config file error line %d, could parse: %s\n", nu, line); + free(line); + } + break; + } + } + fclose(file); + return options; +} + +void save_convolutional_weights_binary(layer l, FILE *fp) +{ +#ifdef GPU + if(gpu_index >= 0){ + pull_convolutional_layer(l); + } +#endif + binarize_weights(l.weights, l.n, l.c*l.size*l.size, l.binary_weights); + int size = l.c*l.size*l.size; + int i, j, k; + fwrite(l.biases, sizeof(float), l.n, fp); + if (l.batch_normalize){ + fwrite(l.scales, sizeof(float), l.n, fp); + fwrite(l.rolling_mean, sizeof(float), l.n, fp); + fwrite(l.rolling_variance, sizeof(float), l.n, fp); + } + for(i = 0; i < l.n; ++i){ + float mean = l.binary_weights[i*size]; + if(mean < 0) mean = -mean; + fwrite(&mean, sizeof(float), 1, fp); + for(j = 0; j < size/8; ++j){ + int index = i*size + j*8; + unsigned char c = 0; + for(k = 0; k < 8; ++k){ + if (j*8 + k >= size) break; + if (l.binary_weights[index + k] > 0) c = (c | 1<= 0){ + pull_convolutional_layer(l); + } +#endif + int num = l.nweights; + fwrite(l.biases, sizeof(float), l.n, fp); + if (l.batch_normalize){ + fwrite(l.scales, sizeof(float), l.n, fp); + fwrite(l.rolling_mean, sizeof(float), l.n, fp); + fwrite(l.rolling_variance, sizeof(float), l.n, fp); + } + fwrite(l.weights, sizeof(float), num, fp); +} + +void save_batchnorm_weights(layer l, FILE *fp) +{ +#ifdef GPU + if(gpu_index >= 0){ + pull_batchnorm_layer(l); + } +#endif + fwrite(l.scales, sizeof(float), l.c, fp); + fwrite(l.rolling_mean, sizeof(float), l.c, fp); + fwrite(l.rolling_variance, sizeof(float), l.c, fp); +} + +void save_connected_weights(layer l, FILE *fp) +{ +#ifdef GPU + if(gpu_index >= 0){ + pull_connected_layer(l); + } +#endif + fwrite(l.biases, sizeof(float), l.outputs, fp); + fwrite(l.weights, sizeof(float), l.outputs*l.inputs, fp); + if (l.batch_normalize){ + fwrite(l.scales, sizeof(float), l.outputs, fp); + fwrite(l.rolling_mean, sizeof(float), l.outputs, fp); + fwrite(l.rolling_variance, sizeof(float), l.outputs, fp); + } +} + +void save_weights_upto(network *net, char *filename, int cutoff) +{ +#ifdef GPU + if(net->gpu_index >= 0){ + cuda_set_device(net->gpu_index); + } +#endif + fprintf(stderr, "Saving weights to %s\n", filename); + FILE *fp = fopen(filename, "wb"); + if(!fp) file_error(filename); + + int major = 0; + int minor = 2; + int revision = 0; + fwrite(&major, sizeof(int), 1, fp); + fwrite(&minor, sizeof(int), 1, fp); + fwrite(&revision, sizeof(int), 1, fp); + fwrite(net->seen, sizeof(size_t), 1, fp); + + int i; + for(i = 0; i < net->n && i < cutoff; ++i){ + layer l = net->layers[i]; + if (l.dontsave) continue; + if(l.type == CONVOLUTIONAL || l.type == DECONVOLUTIONAL){ + save_convolutional_weights(l, fp); + } if(l.type == CONNECTED){ + save_connected_weights(l, fp); + } if(l.type == BATCHNORM){ + save_batchnorm_weights(l, fp); + } if(l.type == RNN){ + save_connected_weights(*(l.input_layer), fp); + save_connected_weights(*(l.self_layer), fp); + save_connected_weights(*(l.output_layer), fp); + } if (l.type == LSTM) { + save_connected_weights(*(l.wi), fp); + save_connected_weights(*(l.wf), fp); + save_connected_weights(*(l.wo), fp); + save_connected_weights(*(l.wg), fp); + save_connected_weights(*(l.ui), fp); + save_connected_weights(*(l.uf), fp); + save_connected_weights(*(l.uo), fp); + save_connected_weights(*(l.ug), fp); + } if (l.type == GRU) { + if(1){ + save_connected_weights(*(l.wz), fp); + save_connected_weights(*(l.wr), fp); + save_connected_weights(*(l.wh), fp); + save_connected_weights(*(l.uz), fp); + save_connected_weights(*(l.ur), fp); + save_connected_weights(*(l.uh), fp); + }else{ + save_connected_weights(*(l.reset_layer), fp); + save_connected_weights(*(l.update_layer), fp); + save_connected_weights(*(l.state_layer), fp); + } + } if(l.type == CRNN){ + save_convolutional_weights(*(l.input_layer), fp); + save_convolutional_weights(*(l.self_layer), fp); + save_convolutional_weights(*(l.output_layer), fp); + } if(l.type == LOCAL){ +#ifdef GPU + if(gpu_index >= 0){ + pull_local_layer(l); + } +#endif + int locations = l.out_w*l.out_h; + int size = l.size*l.size*l.c*l.n*locations; + fwrite(l.biases, sizeof(float), l.outputs, fp); + fwrite(l.weights, sizeof(float), size, fp); + } + } + fclose(fp); +} +void save_weights(network *net, char *filename) +{ + save_weights_upto(net, filename, net->n); +} + +void transpose_matrix(float *a, int rows, int cols) +{ + float *transpose = calloc(rows*cols, sizeof(float)); + int x, y; + for(x = 0; x < rows; ++x){ + for(y = 0; y < cols; ++y){ + transpose[y*rows + x] = a[x*cols + y]; + } + } + memcpy(a, transpose, rows*cols*sizeof(float)); + free(transpose); +} + +void load_connected_weights(layer l, FILE *fp, int transpose) +{ + fread(l.biases, sizeof(float), l.outputs, fp); + fread(l.weights, sizeof(float), l.outputs*l.inputs, fp); + if(transpose){ + transpose_matrix(l.weights, l.inputs, l.outputs); + } + //printf("Biases: %f mean %f variance\n", mean_array(l.biases, l.outputs), variance_array(l.biases, l.outputs)); + //printf("Weights: %f mean %f variance\n", mean_array(l.weights, l.outputs*l.inputs), variance_array(l.weights, l.outputs*l.inputs)); + if (l.batch_normalize && (!l.dontloadscales)){ + fread(l.scales, sizeof(float), l.outputs, fp); + fread(l.rolling_mean, sizeof(float), l.outputs, fp); + fread(l.rolling_variance, sizeof(float), l.outputs, fp); + //printf("Scales: %f mean %f variance\n", mean_array(l.scales, l.outputs), variance_array(l.scales, l.outputs)); + //printf("rolling_mean: %f mean %f variance\n", mean_array(l.rolling_mean, l.outputs), variance_array(l.rolling_mean, l.outputs)); + //printf("rolling_variance: %f mean %f variance\n", mean_array(l.rolling_variance, l.outputs), variance_array(l.rolling_variance, l.outputs)); + } +#ifdef GPU + if(gpu_index >= 0){ + push_connected_layer(l); + } +#endif +} + +void load_batchnorm_weights(layer l, FILE *fp) +{ + fread(l.scales, sizeof(float), l.c, fp); + fread(l.rolling_mean, sizeof(float), l.c, fp); + fread(l.rolling_variance, sizeof(float), l.c, fp); +#ifdef GPU + if(gpu_index >= 0){ + push_batchnorm_layer(l); + } +#endif +} + +void load_convolutional_weights_binary(layer l, FILE *fp) +{ + fread(l.biases, sizeof(float), l.n, fp); + if (l.batch_normalize && (!l.dontloadscales)){ + fread(l.scales, sizeof(float), l.n, fp); + fread(l.rolling_mean, sizeof(float), l.n, fp); + fread(l.rolling_variance, sizeof(float), l.n, fp); + } + int size = l.c*l.size*l.size; + int i, j, k; + for(i = 0; i < l.n; ++i){ + float mean = 0; + fread(&mean, sizeof(float), 1, fp); + for(j = 0; j < size/8; ++j){ + int index = i*size + j*8; + unsigned char c = 0; + fread(&c, sizeof(char), 1, fp); + for(k = 0; k < 8; ++k){ + if (j*8 + k >= size) break; + l.weights[index + k] = (c & 1<= 0){ + push_convolutional_layer(l); + } +#endif +} + +void load_convolutional_weights(layer l, FILE *fp) +{ + if(l.binary){ + //load_convolutional_weights_binary(l, fp); + //return; + } + if(l.numload) l.n = l.numload; + int num = l.c/l.groups*l.n*l.size*l.size; + fread(l.biases, sizeof(float), l.n, fp); + if (l.batch_normalize && (!l.dontloadscales)){ + fread(l.scales, sizeof(float), l.n, fp); + fread(l.rolling_mean, sizeof(float), l.n, fp); + fread(l.rolling_variance, sizeof(float), l.n, fp); + if(0){ + int i; + for(i = 0; i < l.n; ++i){ + printf("%g, ", l.rolling_mean[i]); + } + printf("\n"); + for(i = 0; i < l.n; ++i){ + printf("%g, ", l.rolling_variance[i]); + } + printf("\n"); + } + if(0){ + fill_cpu(l.n, 0, l.rolling_mean, 1); + fill_cpu(l.n, 0, l.rolling_variance, 1); + } + if(0){ + int i; + for(i = 0; i < l.n; ++i){ + printf("%g, ", l.rolling_mean[i]); + } + printf("\n"); + for(i = 0; i < l.n; ++i){ + printf("%g, ", l.rolling_variance[i]); + } + printf("\n"); + } + } + fread(l.weights, sizeof(float), num, fp); + //if(l.c == 3) scal_cpu(num, 1./256, l.weights, 1); + if (l.flipped) { + transpose_matrix(l.weights, l.c*l.size*l.size, l.n); + } + //if (l.binary) binarize_weights(l.weights, l.n, l.c*l.size*l.size, l.weights); +#ifdef GPU + if(gpu_index >= 0){ + push_convolutional_layer(l); + } +#endif +} + + +void load_weights_upto(network *net, char *filename, int start, int cutoff) +{ +#ifdef GPU + if(net->gpu_index >= 0){ + cuda_set_device(net->gpu_index); + } +#endif + fprintf(stderr, "Loading weights from %s...", filename); + fflush(stdout); + FILE *fp = fopen(filename, "rb"); + if(!fp) file_error(filename); + + int major; + int minor; + int revision; + fread(&major, sizeof(int), 1, fp); + fread(&minor, sizeof(int), 1, fp); + fread(&revision, sizeof(int), 1, fp); + if ((major*10 + minor) >= 2 && major < 1000 && minor < 1000){ + fread(net->seen, sizeof(size_t), 1, fp); + } else { + int iseen = 0; + fread(&iseen, sizeof(int), 1, fp); + *net->seen = iseen; + } + int transpose = (major > 1000) || (minor > 1000); + + int i; + for(i = start; i < net->n && i < cutoff; ++i){ + layer l = net->layers[i]; + if (l.dontload) continue; + if(l.type == CONVOLUTIONAL || l.type == DECONVOLUTIONAL){ + load_convolutional_weights(l, fp); + } + if(l.type == CONNECTED){ + load_connected_weights(l, fp, transpose); + } + if(l.type == BATCHNORM){ + load_batchnorm_weights(l, fp); + } + if(l.type == CRNN){ + load_convolutional_weights(*(l.input_layer), fp); + load_convolutional_weights(*(l.self_layer), fp); + load_convolutional_weights(*(l.output_layer), fp); + } + if(l.type == RNN){ + load_connected_weights(*(l.input_layer), fp, transpose); + load_connected_weights(*(l.self_layer), fp, transpose); + load_connected_weights(*(l.output_layer), fp, transpose); + } + if (l.type == LSTM) { + load_connected_weights(*(l.wi), fp, transpose); + load_connected_weights(*(l.wf), fp, transpose); + load_connected_weights(*(l.wo), fp, transpose); + load_connected_weights(*(l.wg), fp, transpose); + load_connected_weights(*(l.ui), fp, transpose); + load_connected_weights(*(l.uf), fp, transpose); + load_connected_weights(*(l.uo), fp, transpose); + load_connected_weights(*(l.ug), fp, transpose); + } + if (l.type == GRU) { + if(1){ + load_connected_weights(*(l.wz), fp, transpose); + load_connected_weights(*(l.wr), fp, transpose); + load_connected_weights(*(l.wh), fp, transpose); + load_connected_weights(*(l.uz), fp, transpose); + load_connected_weights(*(l.ur), fp, transpose); + load_connected_weights(*(l.uh), fp, transpose); + }else{ + load_connected_weights(*(l.reset_layer), fp, transpose); + load_connected_weights(*(l.update_layer), fp, transpose); + load_connected_weights(*(l.state_layer), fp, transpose); + } + } + if(l.type == LOCAL){ + int locations = l.out_w*l.out_h; + int size = l.size*l.size*l.c*l.n*locations; + fread(l.biases, sizeof(float), l.outputs, fp); + fread(l.weights, sizeof(float), size, fp); +#ifdef GPU + if(gpu_index >= 0){ + push_local_layer(l); + } +#endif + } + } + fprintf(stderr, "Done!\n"); + fclose(fp); +} + +void load_weights(network *net, char *filename) +{ + load_weights_upto(net, filename, 0, net->n); +} + diff --git a/hanzi_detection/src/parser.h b/hanzi_detection/src/parser.h new file mode 100755 index 0000000..81aef2c --- /dev/null +++ b/hanzi_detection/src/parser.h @@ -0,0 +1,9 @@ +#ifndef PARSER_H +#define PARSER_H +#include "darknet.h" +#include "network.h" + +void save_network(network net, char *filename); +void save_weights_double(network net, char *filename); + +#endif diff --git a/hanzi_detection/src/region_layer.c b/hanzi_detection/src/region_layer.c new file mode 100755 index 0000000..179f5e3 --- /dev/null +++ b/hanzi_detection/src/region_layer.c @@ -0,0 +1,507 @@ +#include "region_layer.h" +#include "activations.h" +#include "blas.h" +#include "box.h" +#include "cuda.h" +#include "utils.h" + +#include +#include +#include +#include + +layer make_region_layer(int batch, int w, int h, int n, int classes, int coords) +{ + layer l = {0}; + l.type = REGION; + + l.n = n; + l.batch = batch; + l.h = h; + l.w = w; + l.c = n*(classes + coords + 1); + l.out_w = l.w; + l.out_h = l.h; + l.out_c = l.c; + l.classes = classes; + l.coords = coords; + l.cost = calloc(1, sizeof(float)); + l.biases = calloc(n*2, sizeof(float)); + l.bias_updates = calloc(n*2, sizeof(float)); + l.outputs = h*w*n*(classes + coords + 1); + l.inputs = l.outputs; + l.truths = 30*(l.coords + 1); + l.delta = calloc(batch*l.outputs, sizeof(float)); + l.output = calloc(batch*l.outputs, sizeof(float)); + int i; + for(i = 0; i < n*2; ++i){ + l.biases[i] = .5; + } + + l.forward = forward_region_layer; + l.backward = backward_region_layer; +#ifdef GPU + l.forward_gpu = forward_region_layer_gpu; + l.backward_gpu = backward_region_layer_gpu; + l.output_gpu = cuda_make_array(l.output, batch*l.outputs); + l.delta_gpu = cuda_make_array(l.delta, batch*l.outputs); +#endif + + fprintf(stderr, "detection\n"); + srand(0); + + return l; +} + +void resize_region_layer(layer *l, int w, int h) +{ + l->w = w; + l->h = h; + + l->outputs = h*w*l->n*(l->classes + l->coords + 1); + l->inputs = l->outputs; + + l->output = realloc(l->output, l->batch*l->outputs*sizeof(float)); + l->delta = realloc(l->delta, l->batch*l->outputs*sizeof(float)); + +#ifdef GPU + cuda_free(l->delta_gpu); + cuda_free(l->output_gpu); + + l->delta_gpu = cuda_make_array(l->delta, l->batch*l->outputs); + l->output_gpu = cuda_make_array(l->output, l->batch*l->outputs); +#endif +} + +box get_region_box(float *x, float *biases, int n, int index, int i, int j, int w, int h, int stride) +{ + box b; + b.x = (i + x[index + 0*stride]) / w; + b.y = (j + x[index + 1*stride]) / h; + b.w = exp(x[index + 2*stride]) * biases[2*n] / w; + b.h = exp(x[index + 3*stride]) * biases[2*n+1] / h; + return b; +} + +float delta_region_box(box truth, float *x, float *biases, int n, int index, int i, int j, int w, int h, float *delta, float scale, int stride) +{ + box pred = get_region_box(x, biases, n, index, i, j, w, h, stride); + float iou = box_iou(pred, truth); + + float tx = (truth.x*w - i); + float ty = (truth.y*h - j); + float tw = log(truth.w*w / biases[2*n]); + float th = log(truth.h*h / biases[2*n + 1]); + + delta[index + 0*stride] = scale * (tx - x[index + 0*stride]); + delta[index + 1*stride] = scale * (ty - x[index + 1*stride]); + delta[index + 2*stride] = scale * (tw - x[index + 2*stride]); + delta[index + 3*stride] = scale * (th - x[index + 3*stride]); + return iou; +} + +void delta_region_mask(float *truth, float *x, int n, int index, float *delta, int stride, int scale) +{ + int i; + for(i = 0; i < n; ++i){ + delta[index + i*stride] = scale*(truth[i] - x[index + i*stride]); + } +} + + +void delta_region_class(float *output, float *delta, int index, int class, int classes, tree *hier, float scale, int stride, float *avg_cat, int tag) +{ + int i, n; + if(hier){ + float pred = 1; + while(class >= 0){ + pred *= output[index + stride*class]; + int g = hier->group[class]; + int offset = hier->group_offset[g]; + for(i = 0; i < hier->group_size[g]; ++i){ + delta[index + stride*(offset + i)] = scale * (0 - output[index + stride*(offset + i)]); + } + delta[index + stride*class] = scale * (1 - output[index + stride*class]); + + class = hier->parent[class]; + } + *avg_cat += pred; + } else { + if (delta[index] && tag){ + delta[index + stride*class] = scale * (1 - output[index + stride*class]); + return; + } + for(n = 0; n < classes; ++n){ + delta[index + stride*n] = scale * (((n == class)?1 : 0) - output[index + stride*n]); + if(n == class) *avg_cat += output[index + stride*n]; + } + } +} + +float logit(float x) +{ + return log(x/(1.-x)); +} + +float tisnan(float x) +{ + return (x != x); +} + +int entry_index(layer l, int batch, int location, int entry) +{ + int n = location / (l.w*l.h); + int loc = location % (l.w*l.h); + return batch*l.outputs + n*l.w*l.h*(l.coords+l.classes+1) + entry*l.w*l.h + loc; +} + +void forward_region_layer(const layer l, network net) +{ + int i,j,b,t,n; + memcpy(l.output, net.input, l.outputs*l.batch*sizeof(float)); + +#ifndef GPU + for (b = 0; b < l.batch; ++b){ + for(n = 0; n < l.n; ++n){ + int index = entry_index(l, b, n*l.w*l.h, 0); + activate_array(l.output + index, 2*l.w*l.h, LOGISTIC); + index = entry_index(l, b, n*l.w*l.h, l.coords); + if(!l.background) activate_array(l.output + index, l.w*l.h, LOGISTIC); + index = entry_index(l, b, n*l.w*l.h, l.coords + 1); + if(!l.softmax && !l.softmax_tree) activate_array(l.output + index, l.classes*l.w*l.h, LOGISTIC); + } + } + if (l.softmax_tree){ + int i; + int count = l.coords + 1; + for (i = 0; i < l.softmax_tree->groups; ++i) { + int group_size = l.softmax_tree->group_size[i]; + softmax_cpu(net.input + count, group_size, l.batch, l.inputs, l.n*l.w*l.h, 1, l.n*l.w*l.h, l.temperature, l.output + count); + count += group_size; + } + } else if (l.softmax){ + int index = entry_index(l, 0, 0, l.coords + !l.background); + softmax_cpu(net.input + index, l.classes + l.background, l.batch*l.n, l.inputs/l.n, l.w*l.h, 1, l.w*l.h, 1, l.output + index); + } +#endif + + memset(l.delta, 0, l.outputs * l.batch * sizeof(float)); + if(!net.train) return; + float avg_iou = 0; + float recall = 0; + float avg_cat = 0; + float avg_obj = 0; + float avg_anyobj = 0; + int count = 0; + int class_count = 0; + *(l.cost) = 0; + for (b = 0; b < l.batch; ++b) { + if(l.softmax_tree){ + int onlyclass = 0; + for(t = 0; t < 30; ++t){ + box truth = float_to_box(net.truth + t*(l.coords + 1) + b*l.truths, 1); + if(!truth.x) break; + int class = net.truth[t*(l.coords + 1) + b*l.truths + l.coords]; + float maxp = 0; + int maxi = 0; + if(truth.x > 100000 && truth.y > 100000){ + for(n = 0; n < l.n*l.w*l.h; ++n){ + int class_index = entry_index(l, b, n, l.coords + 1); + int obj_index = entry_index(l, b, n, l.coords); + float scale = l.output[obj_index]; + l.delta[obj_index] = l.noobject_scale * (0 - l.output[obj_index]); + float p = scale*get_hierarchy_probability(l.output + class_index, l.softmax_tree, class, l.w*l.h); + if(p > maxp){ + maxp = p; + maxi = n; + } + } + int class_index = entry_index(l, b, maxi, l.coords + 1); + int obj_index = entry_index(l, b, maxi, l.coords); + delta_region_class(l.output, l.delta, class_index, class, l.classes, l.softmax_tree, l.class_scale, l.w*l.h, &avg_cat, !l.softmax); + if(l.output[obj_index] < .3) l.delta[obj_index] = l.object_scale * (.3 - l.output[obj_index]); + else l.delta[obj_index] = 0; + l.delta[obj_index] = 0; + ++class_count; + onlyclass = 1; + break; + } + } + if(onlyclass) continue; + } + for (j = 0; j < l.h; ++j) { + for (i = 0; i < l.w; ++i) { + for (n = 0; n < l.n; ++n) { + int box_index = entry_index(l, b, n*l.w*l.h + j*l.w + i, 0); + box pred = get_region_box(l.output, l.biases, n, box_index, i, j, l.w, l.h, l.w*l.h); + float best_iou = 0; + for(t = 0; t < 30; ++t){ + box truth = float_to_box(net.truth + t*(l.coords + 1) + b*l.truths, 1); + if(!truth.x) break; + float iou = box_iou(pred, truth); + if (iou > best_iou) { + best_iou = iou; + } + } + int obj_index = entry_index(l, b, n*l.w*l.h + j*l.w + i, l.coords); + avg_anyobj += l.output[obj_index]; + l.delta[obj_index] = l.noobject_scale * (0 - l.output[obj_index]); + if(l.background) l.delta[obj_index] = l.noobject_scale * (1 - l.output[obj_index]); + if (best_iou > l.thresh) { + l.delta[obj_index] = 0; + } + + if(*(net.seen) < 12800){ + box truth = {0}; + truth.x = (i + .5)/l.w; + truth.y = (j + .5)/l.h; + truth.w = l.biases[2*n]/l.w; + truth.h = l.biases[2*n+1]/l.h; + delta_region_box(truth, l.output, l.biases, n, box_index, i, j, l.w, l.h, l.delta, .01, l.w*l.h); + } + } + } + } + for(t = 0; t < 30; ++t){ + box truth = float_to_box(net.truth + t*(l.coords + 1) + b*l.truths, 1); + + if(!truth.x) break; + float best_iou = 0; + int best_n = 0; + i = (truth.x * l.w); + j = (truth.y * l.h); + box truth_shift = truth; + truth_shift.x = 0; + truth_shift.y = 0; + for(n = 0; n < l.n; ++n){ + int box_index = entry_index(l, b, n*l.w*l.h + j*l.w + i, 0); + box pred = get_region_box(l.output, l.biases, n, box_index, i, j, l.w, l.h, l.w*l.h); + if(l.bias_match){ + pred.w = l.biases[2*n]/l.w; + pred.h = l.biases[2*n+1]/l.h; + } + pred.x = 0; + pred.y = 0; + float iou = box_iou(pred, truth_shift); + if (iou > best_iou){ + best_iou = iou; + best_n = n; + } + } + + int box_index = entry_index(l, b, best_n*l.w*l.h + j*l.w + i, 0); + float iou = delta_region_box(truth, l.output, l.biases, best_n, box_index, i, j, l.w, l.h, l.delta, l.coord_scale * (2 - truth.w*truth.h), l.w*l.h); + if(l.coords > 4){ + int mask_index = entry_index(l, b, best_n*l.w*l.h + j*l.w + i, 4); + delta_region_mask(net.truth + t*(l.coords + 1) + b*l.truths + 5, l.output, l.coords - 4, mask_index, l.delta, l.w*l.h, l.mask_scale); + } + if(iou > .5) recall += 1; + avg_iou += iou; + + int obj_index = entry_index(l, b, best_n*l.w*l.h + j*l.w + i, l.coords); + avg_obj += l.output[obj_index]; + l.delta[obj_index] = l.object_scale * (1 - l.output[obj_index]); + if (l.rescore) { + l.delta[obj_index] = l.object_scale * (iou - l.output[obj_index]); + } + if(l.background){ + l.delta[obj_index] = l.object_scale * (0 - l.output[obj_index]); + } + + int class = net.truth[t*(l.coords + 1) + b*l.truths + l.coords]; + if (l.map) class = l.map[class]; + int class_index = entry_index(l, b, best_n*l.w*l.h + j*l.w + i, l.coords + 1); + delta_region_class(l.output, l.delta, class_index, class, l.classes, l.softmax_tree, l.class_scale, l.w*l.h, &avg_cat, !l.softmax); + ++count; + ++class_count; + } + } + *(l.cost) = pow(mag_array(l.delta, l.outputs * l.batch), 2); + printf("Region Avg IOU: %f, Class: %f, Obj: %f, No Obj: %f, Avg Recall: %f, count: %d\n", avg_iou/count, avg_cat/class_count, avg_obj/count, avg_anyobj/(l.w*l.h*l.n*l.batch), recall/count, count); +} + +void backward_region_layer(const layer l, network net) +{ + /* + int b; + int size = l.coords + l.classes + 1; + for (b = 0; b < l.batch*l.n; ++b){ + int index = (b*size + 4)*l.w*l.h; + gradient_array(l.output + index, l.w*l.h, LOGISTIC, l.delta + index); + } + axpy_cpu(l.batch*l.inputs, 1, l.delta, 1, net.delta, 1); + */ +} + +void correct_region_boxes(detection *dets, int n, int w, int h, int netw, int neth, int relative) +{ + int i; + int new_w=0; + int new_h=0; + if (((float)netw/w) < ((float)neth/h)) { + new_w = netw; + new_h = (h * netw)/w; + } else { + new_h = neth; + new_w = (w * neth)/h; + } + for (i = 0; i < n; ++i){ + box b = dets[i].bbox; + b.x = (b.x - (netw - new_w)/2./netw) / ((float)new_w/netw); + b.y = (b.y - (neth - new_h)/2./neth) / ((float)new_h/neth); + b.w *= (float)netw/new_w; + b.h *= (float)neth/new_h; + if(!relative){ + b.x *= w; + b.w *= w; + b.y *= h; + b.h *= h; + } + dets[i].bbox = b; + } +} + +void get_region_detections(layer l, int w, int h, int netw, int neth, float thresh, int *map, float tree_thresh, int relative, detection *dets) +{ + int i,j,n,z; + float *predictions = l.output; + if (l.batch == 2) { + float *flip = l.output + l.outputs; + for (j = 0; j < l.h; ++j) { + for (i = 0; i < l.w/2; ++i) { + for (n = 0; n < l.n; ++n) { + for(z = 0; z < l.classes + l.coords + 1; ++z){ + int i1 = z*l.w*l.h*l.n + n*l.w*l.h + j*l.w + i; + int i2 = z*l.w*l.h*l.n + n*l.w*l.h + j*l.w + (l.w - i - 1); + float swap = flip[i1]; + flip[i1] = flip[i2]; + flip[i2] = swap; + if(z == 0){ + flip[i1] = -flip[i1]; + flip[i2] = -flip[i2]; + } + } + } + } + } + for(i = 0; i < l.outputs; ++i){ + l.output[i] = (l.output[i] + flip[i])/2.; + } + } + for (i = 0; i < l.w*l.h; ++i){ + int row = i / l.w; + int col = i % l.w; + for(n = 0; n < l.n; ++n){ + int index = n*l.w*l.h + i; + for(j = 0; j < l.classes; ++j){ + dets[index].prob[j] = 0; + } + int obj_index = entry_index(l, 0, n*l.w*l.h + i, l.coords); + int box_index = entry_index(l, 0, n*l.w*l.h + i, 0); + int mask_index = entry_index(l, 0, n*l.w*l.h + i, 4); + float scale = l.background ? 1 : predictions[obj_index]; + dets[index].bbox = get_region_box(predictions, l.biases, n, box_index, col, row, l.w, l.h, l.w*l.h); + dets[index].objectness = scale > thresh ? scale : 0; + if(dets[index].mask){ + for(j = 0; j < l.coords - 4; ++j){ + dets[index].mask[j] = l.output[mask_index + j*l.w*l.h]; + } + } + + int class_index = entry_index(l, 0, n*l.w*l.h + i, l.coords + !l.background); + if(l.softmax_tree){ + + hierarchy_predictions(predictions + class_index, l.classes, l.softmax_tree, 0, l.w*l.h); + if(map){ + for(j = 0; j < 200; ++j){ + int class_index = entry_index(l, 0, n*l.w*l.h + i, l.coords + 1 + map[j]); + float prob = scale*predictions[class_index]; + dets[index].prob[j] = (prob > thresh) ? prob : 0; + } + } else { + int j = hierarchy_top_prediction(predictions + class_index, l.softmax_tree, tree_thresh, l.w*l.h); + dets[index].prob[j] = (scale > thresh) ? scale : 0; + } + } else { + if(dets[index].objectness){ + for(j = 0; j < l.classes; ++j){ + int class_index = entry_index(l, 0, n*l.w*l.h + i, l.coords + 1 + j); + float prob = scale*predictions[class_index]; + dets[index].prob[j] = (prob > thresh) ? prob : 0; + } + } + } + } + } + correct_region_boxes(dets, l.w*l.h*l.n, w, h, netw, neth, relative); +} + +#ifdef GPU + +void forward_region_layer_gpu(const layer l, network net) +{ + copy_gpu(l.batch*l.inputs, net.input_gpu, 1, l.output_gpu, 1); + int b, n; + for (b = 0; b < l.batch; ++b){ + for(n = 0; n < l.n; ++n){ + int index = entry_index(l, b, n*l.w*l.h, 0); + activate_array_gpu(l.output_gpu + index, 2*l.w*l.h, LOGISTIC); + if(l.coords > 4){ + index = entry_index(l, b, n*l.w*l.h, 4); + activate_array_gpu(l.output_gpu + index, (l.coords - 4)*l.w*l.h, LOGISTIC); + } + index = entry_index(l, b, n*l.w*l.h, l.coords); + if(!l.background) activate_array_gpu(l.output_gpu + index, l.w*l.h, LOGISTIC); + index = entry_index(l, b, n*l.w*l.h, l.coords + 1); + if(!l.softmax && !l.softmax_tree) activate_array_gpu(l.output_gpu + index, l.classes*l.w*l.h, LOGISTIC); + } + } + if (l.softmax_tree){ + int index = entry_index(l, 0, 0, l.coords + 1); + softmax_tree(net.input_gpu + index, l.w*l.h, l.batch*l.n, l.inputs/l.n, 1, l.output_gpu + index, *l.softmax_tree); + } else if (l.softmax) { + int index = entry_index(l, 0, 0, l.coords + !l.background); + softmax_gpu(net.input_gpu + index, l.classes + l.background, l.batch*l.n, l.inputs/l.n, l.w*l.h, 1, l.w*l.h, 1, l.output_gpu + index); + } + if(!net.train || l.onlyforward){ + cuda_pull_array(l.output_gpu, l.output, l.batch*l.outputs); + return; + } + + cuda_pull_array(l.output_gpu, net.input, l.batch*l.inputs); + forward_region_layer(l, net); + //cuda_push_array(l.output_gpu, l.output, l.batch*l.outputs); + if(!net.train) return; + cuda_push_array(l.delta_gpu, l.delta, l.batch*l.outputs); +} + +void backward_region_layer_gpu(const layer l, network net) +{ + int b, n; + for (b = 0; b < l.batch; ++b){ + for(n = 0; n < l.n; ++n){ + int index = entry_index(l, b, n*l.w*l.h, 0); + gradient_array_gpu(l.output_gpu + index, 2*l.w*l.h, LOGISTIC, l.delta_gpu + index); + if(l.coords > 4){ + index = entry_index(l, b, n*l.w*l.h, 4); + gradient_array_gpu(l.output_gpu + index, (l.coords - 4)*l.w*l.h, LOGISTIC, l.delta_gpu + index); + } + index = entry_index(l, b, n*l.w*l.h, l.coords); + if(!l.background) gradient_array_gpu(l.output_gpu + index, l.w*l.h, LOGISTIC, l.delta_gpu + index); + } + } + axpy_gpu(l.batch*l.inputs, 1, l.delta_gpu, 1, net.delta_gpu, 1); +} +#endif + +void zero_objectness(layer l) +{ + int i, n; + for (i = 0; i < l.w*l.h; ++i){ + for(n = 0; n < l.n; ++n){ + int obj_index = entry_index(l, 0, n*l.w*l.h + i, l.coords); + l.output[obj_index] = 0; + } + } +} + diff --git a/hanzi_detection/src/region_layer.h b/hanzi_detection/src/region_layer.h new file mode 100755 index 0000000..9f12fd1 --- /dev/null +++ b/hanzi_detection/src/region_layer.h @@ -0,0 +1,18 @@ +#ifndef REGION_LAYER_H +#define REGION_LAYER_H + +#include "darknet.h" +#include "layer.h" +#include "network.h" + +layer make_region_layer(int batch, int w, int h, int n, int classes, int coords); +void forward_region_layer(const layer l, network net); +void backward_region_layer(const layer l, network net); +void resize_region_layer(layer *l, int w, int h); + +#ifdef GPU +void forward_region_layer_gpu(const layer l, network net); +void backward_region_layer_gpu(layer l, network net); +#endif + +#endif diff --git a/hanzi_detection/src/reorg_layer.c b/hanzi_detection/src/reorg_layer.c new file mode 100755 index 0000000..31d6b84 --- /dev/null +++ b/hanzi_detection/src/reorg_layer.c @@ -0,0 +1,173 @@ +#include "reorg_layer.h" +#include "cuda.h" +#include "blas.h" + +#include + + +layer make_reorg_layer(int batch, int w, int h, int c, int stride, int reverse, int flatten, int extra) +{ + layer l = {0}; + l.type = REORG; + l.batch = batch; + l.stride = stride; + l.extra = extra; + l.h = h; + l.w = w; + l.c = c; + l.flatten = flatten; + if(reverse){ + l.out_w = w*stride; + l.out_h = h*stride; + l.out_c = c/(stride*stride); + }else{ + l.out_w = w/stride; + l.out_h = h/stride; + l.out_c = c*(stride*stride); + } + l.reverse = reverse; + + l.outputs = l.out_h * l.out_w * l.out_c; + l.inputs = h*w*c; + if(l.extra){ + l.out_w = l.out_h = l.out_c = 0; + l.outputs = l.inputs + l.extra; + } + + if(extra){ + fprintf(stderr, "reorg %4d -> %4d\n", l.inputs, l.outputs); + } else { + fprintf(stderr, "reorg /%2d %4d x%4d x%4d -> %4d x%4d x%4d\n", stride, w, h, c, l.out_w, l.out_h, l.out_c); + } + int output_size = l.outputs * batch; + l.output = calloc(output_size, sizeof(float)); + l.delta = calloc(output_size, sizeof(float)); + + l.forward = forward_reorg_layer; + l.backward = backward_reorg_layer; +#ifdef GPU + l.forward_gpu = forward_reorg_layer_gpu; + l.backward_gpu = backward_reorg_layer_gpu; + + l.output_gpu = cuda_make_array(l.output, output_size); + l.delta_gpu = cuda_make_array(l.delta, output_size); +#endif + return l; +} + +void resize_reorg_layer(layer *l, int w, int h) +{ + int stride = l->stride; + int c = l->c; + + l->h = h; + l->w = w; + + if(l->reverse){ + l->out_w = w*stride; + l->out_h = h*stride; + l->out_c = c/(stride*stride); + }else{ + l->out_w = w/stride; + l->out_h = h/stride; + l->out_c = c*(stride*stride); + } + + l->outputs = l->out_h * l->out_w * l->out_c; + l->inputs = l->outputs; + int output_size = l->outputs * l->batch; + + l->output = realloc(l->output, output_size * sizeof(float)); + l->delta = realloc(l->delta, output_size * sizeof(float)); + +#ifdef GPU + cuda_free(l->output_gpu); + cuda_free(l->delta_gpu); + l->output_gpu = cuda_make_array(l->output, output_size); + l->delta_gpu = cuda_make_array(l->delta, output_size); +#endif +} + +void forward_reorg_layer(const layer l, network net) +{ + int i; + if(l.flatten){ + memcpy(l.output, net.input, l.outputs*l.batch*sizeof(float)); + if(l.reverse){ + flatten(l.output, l.w*l.h, l.c, l.batch, 0); + }else{ + flatten(l.output, l.w*l.h, l.c, l.batch, 1); + } + } else if (l.extra) { + for(i = 0; i < l.batch; ++i){ + copy_cpu(l.inputs, net.input + i*l.inputs, 1, l.output + i*l.outputs, 1); + } + } else if (l.reverse){ + reorg_cpu(net.input, l.w, l.h, l.c, l.batch, l.stride, 1, l.output); + } else { + reorg_cpu(net.input, l.w, l.h, l.c, l.batch, l.stride, 0, l.output); + } +} + +void backward_reorg_layer(const layer l, network net) +{ + int i; + if(l.flatten){ + memcpy(net.delta, l.delta, l.outputs*l.batch*sizeof(float)); + if(l.reverse){ + flatten(net.delta, l.w*l.h, l.c, l.batch, 1); + }else{ + flatten(net.delta, l.w*l.h, l.c, l.batch, 0); + } + } else if(l.reverse){ + reorg_cpu(l.delta, l.w, l.h, l.c, l.batch, l.stride, 0, net.delta); + } else if (l.extra) { + for(i = 0; i < l.batch; ++i){ + copy_cpu(l.inputs, l.delta + i*l.outputs, 1, net.delta + i*l.inputs, 1); + } + }else{ + reorg_cpu(l.delta, l.w, l.h, l.c, l.batch, l.stride, 1, net.delta); + } +} + +#ifdef GPU +void forward_reorg_layer_gpu(layer l, network net) +{ + int i; + if(l.flatten){ + if(l.reverse){ + flatten_gpu(net.input_gpu, l.w*l.h, l.c, l.batch, 0, l.output_gpu); + }else{ + flatten_gpu(net.input_gpu, l.w*l.h, l.c, l.batch, 1, l.output_gpu); + } + } else if (l.extra) { + for(i = 0; i < l.batch; ++i){ + copy_gpu(l.inputs, net.input_gpu + i*l.inputs, 1, l.output_gpu + i*l.outputs, 1); + } + } else if (l.reverse) { + reorg_gpu(net.input_gpu, l.w, l.h, l.c, l.batch, l.stride, 1, l.output_gpu); + }else { + reorg_gpu(net.input_gpu, l.w, l.h, l.c, l.batch, l.stride, 0, l.output_gpu); + } +} + +void backward_reorg_layer_gpu(layer l, network net) +{ + if(l.flatten){ + if(l.reverse){ + flatten_gpu(l.delta_gpu, l.w*l.h, l.c, l.batch, 1, net.delta_gpu); + }else{ + flatten_gpu(l.delta_gpu, l.w*l.h, l.c, l.batch, 0, net.delta_gpu); + } + } else if (l.extra) { + int i; + for(i = 0; i < l.batch; ++i){ + copy_gpu(l.inputs, l.delta_gpu + i*l.outputs, 1, net.delta_gpu + i*l.inputs, 1); + } + } else if(l.reverse){ + reorg_gpu(l.delta_gpu, l.w, l.h, l.c, l.batch, l.stride, 0, net.delta_gpu); + } else { + reorg_gpu(l.delta_gpu, l.w, l.h, l.c, l.batch, l.stride, 1, net.delta_gpu); + } +} +#endif diff --git a/hanzi_detection/src/reorg_layer.h b/hanzi_detection/src/reorg_layer.h new file mode 100755 index 0000000..e6513a5 --- /dev/null +++ b/hanzi_detection/src/reorg_layer.h @@ -0,0 +1,20 @@ +#ifndef REORG_LAYER_H +#define REORG_LAYER_H + +#include "image.h" +#include "cuda.h" +#include "layer.h" +#include "network.h" + +layer make_reorg_layer(int batch, int w, int h, int c, int stride, int reverse, int flatten, int extra); +void resize_reorg_layer(layer *l, int w, int h); +void forward_reorg_layer(const layer l, network net); +void backward_reorg_layer(const layer l, network net); + +#ifdef GPU +void forward_reorg_layer_gpu(layer l, network net); +void backward_reorg_layer_gpu(layer l, network net); +#endif + +#endif + diff --git a/hanzi_detection/src/rnn_layer.c b/hanzi_detection/src/rnn_layer.c new file mode 100755 index 0000000..8c9b457 --- /dev/null +++ b/hanzi_detection/src/rnn_layer.c @@ -0,0 +1,292 @@ +#include "rnn_layer.h" +#include "connected_layer.h" +#include "utils.h" +#include "cuda.h" +#include "blas.h" +#include "gemm.h" + +#include +#include +#include +#include + +static void increment_layer(layer *l, int steps) +{ + int num = l->outputs*l->batch*steps; + l->output += num; + l->delta += num; + l->x += num; + l->x_norm += num; + +#ifdef GPU + l->output_gpu += num; + l->delta_gpu += num; + l->x_gpu += num; + l->x_norm_gpu += num; +#endif +} + +layer make_rnn_layer(int batch, int inputs, int outputs, int steps, ACTIVATION activation, int batch_normalize, int adam) +{ + fprintf(stderr, "RNN Layer: %d inputs, %d outputs\n", inputs, outputs); + batch = batch / steps; + layer l = {0}; + l.batch = batch; + l.type = RNN; + l.steps = steps; + l.inputs = inputs; + + l.state = calloc(batch*outputs, sizeof(float)); + l.prev_state = calloc(batch*outputs, sizeof(float)); + + l.input_layer = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.input_layer) = make_connected_layer(batch*steps, inputs, outputs, activation, batch_normalize, adam); + l.input_layer->batch = batch; + + l.self_layer = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.self_layer) = make_connected_layer(batch*steps, outputs, outputs, activation, batch_normalize, adam); + l.self_layer->batch = batch; + + l.output_layer = malloc(sizeof(layer)); + fprintf(stderr, "\t\t"); + *(l.output_layer) = make_connected_layer(batch*steps, outputs, outputs, activation, batch_normalize, adam); + l.output_layer->batch = batch; + + l.outputs = outputs; + l.output = l.output_layer->output; + l.delta = l.output_layer->delta; + + l.forward = forward_rnn_layer; + l.backward = backward_rnn_layer; + l.update = update_rnn_layer; +#ifdef GPU + l.forward_gpu = forward_rnn_layer_gpu; + l.backward_gpu = backward_rnn_layer_gpu; + l.update_gpu = update_rnn_layer_gpu; + l.state_gpu = cuda_make_array(0, batch*outputs); + l.prev_state_gpu = cuda_make_array(0, batch*outputs); + l.output_gpu = l.output_layer->output_gpu; + l.delta_gpu = l.output_layer->delta_gpu; +#ifdef CUDNN + cudnnSetTensor4dDescriptor(l.input_layer->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, batch, l.input_layer->out_c, l.input_layer->out_h, l.input_layer->out_w); + cudnnSetTensor4dDescriptor(l.self_layer->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, batch, l.self_layer->out_c, l.self_layer->out_h, l.self_layer->out_w); + cudnnSetTensor4dDescriptor(l.output_layer->dstTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT, batch, l.output_layer->out_c, l.output_layer->out_h, l.output_layer->out_w); +#endif +#endif + + return l; +} + +void update_rnn_layer(layer l, update_args a) +{ + update_connected_layer(*(l.input_layer), a); + update_connected_layer(*(l.self_layer), a); + update_connected_layer(*(l.output_layer), a); +} + +void forward_rnn_layer(layer l, network net) +{ + network s = net; + s.train = net.train; + int i; + layer input_layer = *(l.input_layer); + layer self_layer = *(l.self_layer); + layer output_layer = *(l.output_layer); + + fill_cpu(l.outputs * l.batch * l.steps, 0, output_layer.delta, 1); + fill_cpu(l.outputs * l.batch * l.steps, 0, self_layer.delta, 1); + fill_cpu(l.outputs * l.batch * l.steps, 0, input_layer.delta, 1); + if(net.train) fill_cpu(l.outputs * l.batch, 0, l.state, 1); + + for (i = 0; i < l.steps; ++i) { + s.input = net.input; + forward_connected_layer(input_layer, s); + + s.input = l.state; + forward_connected_layer(self_layer, s); + + float *old_state = l.state; + if(net.train) l.state += l.outputs*l.batch; + if(l.shortcut){ + copy_cpu(l.outputs * l.batch, old_state, 1, l.state, 1); + }else{ + fill_cpu(l.outputs * l.batch, 0, l.state, 1); + } + axpy_cpu(l.outputs * l.batch, 1, input_layer.output, 1, l.state, 1); + axpy_cpu(l.outputs * l.batch, 1, self_layer.output, 1, l.state, 1); + + s.input = l.state; + forward_connected_layer(output_layer, s); + + net.input += l.inputs*l.batch; + increment_layer(&input_layer, 1); + increment_layer(&self_layer, 1); + increment_layer(&output_layer, 1); + } +} + +void backward_rnn_layer(layer l, network net) +{ + network s = net; + s.train = net.train; + int i; + layer input_layer = *(l.input_layer); + layer self_layer = *(l.self_layer); + layer output_layer = *(l.output_layer); + + increment_layer(&input_layer, l.steps-1); + increment_layer(&self_layer, l.steps-1); + increment_layer(&output_layer, l.steps-1); + + l.state += l.outputs*l.batch*l.steps; + for (i = l.steps-1; i >= 0; --i) { + copy_cpu(l.outputs * l.batch, input_layer.output, 1, l.state, 1); + axpy_cpu(l.outputs * l.batch, 1, self_layer.output, 1, l.state, 1); + + s.input = l.state; + s.delta = self_layer.delta; + backward_connected_layer(output_layer, s); + + l.state -= l.outputs*l.batch; + /* + if(i > 0){ + copy_cpu(l.outputs * l.batch, input_layer.output - l.outputs*l.batch, 1, l.state, 1); + axpy_cpu(l.outputs * l.batch, 1, self_layer.output - l.outputs*l.batch, 1, l.state, 1); + }else{ + fill_cpu(l.outputs * l.batch, 0, l.state, 1); + } + */ + + s.input = l.state; + s.delta = self_layer.delta - l.outputs*l.batch; + if (i == 0) s.delta = 0; + backward_connected_layer(self_layer, s); + + copy_cpu(l.outputs*l.batch, self_layer.delta, 1, input_layer.delta, 1); + if (i > 0 && l.shortcut) axpy_cpu(l.outputs*l.batch, 1, self_layer.delta, 1, self_layer.delta - l.outputs*l.batch, 1); + s.input = net.input + i*l.inputs*l.batch; + if(net.delta) s.delta = net.delta + i*l.inputs*l.batch; + else s.delta = 0; + backward_connected_layer(input_layer, s); + + increment_layer(&input_layer, -1); + increment_layer(&self_layer, -1); + increment_layer(&output_layer, -1); + } +} + +#ifdef GPU + +void pull_rnn_layer(layer l) +{ + pull_connected_layer(*(l.input_layer)); + pull_connected_layer(*(l.self_layer)); + pull_connected_layer(*(l.output_layer)); +} + +void push_rnn_layer(layer l) +{ + push_connected_layer(*(l.input_layer)); + push_connected_layer(*(l.self_layer)); + push_connected_layer(*(l.output_layer)); +} + +void update_rnn_layer_gpu(layer l, update_args a) +{ + update_connected_layer_gpu(*(l.input_layer), a); + update_connected_layer_gpu(*(l.self_layer), a); + update_connected_layer_gpu(*(l.output_layer), a); +} + +void forward_rnn_layer_gpu(layer l, network net) +{ + network s = {0}; + s.train = net.train; + int i; + layer input_layer = *(l.input_layer); + layer self_layer = *(l.self_layer); + layer output_layer = *(l.output_layer); + + fill_gpu(l.outputs * l.batch * l.steps, 0, output_layer.delta_gpu, 1); + fill_gpu(l.outputs * l.batch * l.steps, 0, self_layer.delta_gpu, 1); + fill_gpu(l.outputs * l.batch * l.steps, 0, input_layer.delta_gpu, 1); + + if(net.train) { + fill_gpu(l.outputs * l.batch * l.steps, 0, l.delta_gpu, 1); + copy_gpu(l.outputs*l.batch, l.state_gpu, 1, l.prev_state_gpu, 1); + } + + for (i = 0; i < l.steps; ++i) { + s.input_gpu = net.input_gpu; + forward_connected_layer_gpu(input_layer, s); + + s.input_gpu = l.state_gpu; + forward_connected_layer_gpu(self_layer, s); + + fill_gpu(l.outputs * l.batch, 0, l.state_gpu, 1); + axpy_gpu(l.outputs * l.batch, 1, input_layer.output_gpu, 1, l.state_gpu, 1); + axpy_gpu(l.outputs * l.batch, 1, self_layer.output_gpu, 1, l.state_gpu, 1); + + s.input_gpu = l.state_gpu; + forward_connected_layer_gpu(output_layer, s); + + net.input_gpu += l.inputs*l.batch; + increment_layer(&input_layer, 1); + increment_layer(&self_layer, 1); + increment_layer(&output_layer, 1); + } +} + +void backward_rnn_layer_gpu(layer l, network net) +{ + network s = {0}; + s.train = net.train; + int i; + layer input_layer = *(l.input_layer); + layer self_layer = *(l.self_layer); + layer output_layer = *(l.output_layer); + increment_layer(&input_layer, l.steps - 1); + increment_layer(&self_layer, l.steps - 1); + increment_layer(&output_layer, l.steps - 1); + float *last_input = input_layer.output_gpu; + float *last_self = self_layer.output_gpu; + for (i = l.steps-1; i >= 0; --i) { + fill_gpu(l.outputs * l.batch, 0, l.state_gpu, 1); + axpy_gpu(l.outputs * l.batch, 1, input_layer.output_gpu, 1, l.state_gpu, 1); + axpy_gpu(l.outputs * l.batch, 1, self_layer.output_gpu, 1, l.state_gpu, 1); + + s.input_gpu = l.state_gpu; + s.delta_gpu = self_layer.delta_gpu; + backward_connected_layer_gpu(output_layer, s); + + if(i != 0) { + fill_gpu(l.outputs * l.batch, 0, l.state_gpu, 1); + axpy_gpu(l.outputs * l.batch, 1, input_layer.output_gpu - l.outputs*l.batch, 1, l.state_gpu, 1); + axpy_gpu(l.outputs * l.batch, 1, self_layer.output_gpu - l.outputs*l.batch, 1, l.state_gpu, 1); + }else { + copy_gpu(l.outputs*l.batch, l.prev_state_gpu, 1, l.state_gpu, 1); + } + + copy_gpu(l.outputs*l.batch, self_layer.delta_gpu, 1, input_layer.delta_gpu, 1); + + s.input_gpu = l.state_gpu; + s.delta_gpu = (i > 0) ? self_layer.delta_gpu - l.outputs*l.batch : 0; + if (i == 0) s.delta_gpu = 0; + backward_connected_layer_gpu(self_layer, s); + + s.input_gpu = net.input_gpu + i*l.inputs*l.batch; + if(net.delta_gpu) s.delta_gpu = net.delta_gpu + i*l.inputs*l.batch; + else s.delta_gpu = 0; + backward_connected_layer_gpu(input_layer, s); + + increment_layer(&input_layer, -1); + increment_layer(&self_layer, -1); + increment_layer(&output_layer, -1); + } + fill_gpu(l.outputs * l.batch, 0, l.state_gpu, 1); + axpy_gpu(l.outputs * l.batch, 1, last_input, 1, l.state_gpu, 1); + axpy_gpu(l.outputs * l.batch, 1, last_self, 1, l.state_gpu, 1); +} +#endif diff --git a/hanzi_detection/src/rnn_layer.h b/hanzi_detection/src/rnn_layer.h new file mode 100755 index 0000000..270a63f --- /dev/null +++ b/hanzi_detection/src/rnn_layer.h @@ -0,0 +1,25 @@ + +#ifndef RNN_LAYER_H +#define RNN_LAYER_H + +#include "activations.h" +#include "layer.h" +#include "network.h" +#define USET + +layer make_rnn_layer(int batch, int inputs, int outputs, int steps, ACTIVATION activation, int batch_normalize, int adam); + +void forward_rnn_layer(layer l, network net); +void backward_rnn_layer(layer l, network net); +void update_rnn_layer(layer l, update_args a); + +#ifdef GPU +void forward_rnn_layer_gpu(layer l, network net); +void backward_rnn_layer_gpu(layer l, network net); +void update_rnn_layer_gpu(layer l, update_args a); +void push_rnn_layer(layer l); +void pull_rnn_layer(layer l); +#endif + +#endif + diff --git a/hanzi_detection/src/route_layer.c b/hanzi_detection/src/route_layer.c new file mode 100755 index 0000000..a8970a4 --- /dev/null +++ b/hanzi_detection/src/route_layer.c @@ -0,0 +1,134 @@ +#include "route_layer.h" +#include "cuda.h" +#include "blas.h" + +#include + +route_layer make_route_layer(int batch, int n, int *input_layers, int *input_sizes) +{ + fprintf(stderr,"route "); + route_layer l = {0}; + l.type = ROUTE; + l.batch = batch; + l.n = n; + l.input_layers = input_layers; + l.input_sizes = input_sizes; + int i; + int outputs = 0; + for(i = 0; i < n; ++i){ + fprintf(stderr," %d", input_layers[i]); + outputs += input_sizes[i]; + } + fprintf(stderr, "\n"); + l.outputs = outputs; + l.inputs = outputs; + l.delta = calloc(outputs*batch, sizeof(float)); + l.output = calloc(outputs*batch, sizeof(float));; + + l.forward = forward_route_layer; + l.backward = backward_route_layer; + #ifdef GPU + l.forward_gpu = forward_route_layer_gpu; + l.backward_gpu = backward_route_layer_gpu; + + l.delta_gpu = cuda_make_array(l.delta, outputs*batch); + l.output_gpu = cuda_make_array(l.output, outputs*batch); + #endif + return l; +} + +void resize_route_layer(route_layer *l, network *net) +{ + int i; + layer first = net->layers[l->input_layers[0]]; + l->out_w = first.out_w; + l->out_h = first.out_h; + l->out_c = first.out_c; + l->outputs = first.outputs; + l->input_sizes[0] = first.outputs; + for(i = 1; i < l->n; ++i){ + int index = l->input_layers[i]; + layer next = net->layers[index]; + l->outputs += next.outputs; + l->input_sizes[i] = next.outputs; + if(next.out_w == first.out_w && next.out_h == first.out_h){ + l->out_c += next.out_c; + }else{ + printf("%d %d, %d %d\n", next.out_w, next.out_h, first.out_w, first.out_h); + l->out_h = l->out_w = l->out_c = 0; + } + } + l->inputs = l->outputs; + l->delta = realloc(l->delta, l->outputs*l->batch*sizeof(float)); + l->output = realloc(l->output, l->outputs*l->batch*sizeof(float)); + +#ifdef GPU + cuda_free(l->output_gpu); + cuda_free(l->delta_gpu); + l->output_gpu = cuda_make_array(l->output, l->outputs*l->batch); + l->delta_gpu = cuda_make_array(l->delta, l->outputs*l->batch); +#endif + +} + +void forward_route_layer(const route_layer l, network net) +{ + int i, j; + int offset = 0; + for(i = 0; i < l.n; ++i){ + int index = l.input_layers[i]; + float *input = net.layers[index].output; + int input_size = l.input_sizes[i]; + for(j = 0; j < l.batch; ++j){ + copy_cpu(input_size, input + j*input_size, 1, l.output + offset + j*l.outputs, 1); + } + offset += input_size; + } +} + +void backward_route_layer(const route_layer l, network net) +{ + int i, j; + int offset = 0; + for(i = 0; i < l.n; ++i){ + int index = l.input_layers[i]; + float *delta = net.layers[index].delta; + int input_size = l.input_sizes[i]; + for(j = 0; j < l.batch; ++j){ + axpy_cpu(input_size, 1, l.delta + offset + j*l.outputs, 1, delta + j*input_size, 1); + } + offset += input_size; + } +} + +#ifdef GPU +void forward_route_layer_gpu(const route_layer l, network net) +{ + int i, j; + int offset = 0; + for(i = 0; i < l.n; ++i){ + int index = l.input_layers[i]; + float *input = net.layers[index].output_gpu; + int input_size = l.input_sizes[i]; + for(j = 0; j < l.batch; ++j){ + copy_gpu(input_size, input + j*input_size, 1, l.output_gpu + offset + j*l.outputs, 1); + } + offset += input_size; + } +} + +void backward_route_layer_gpu(const route_layer l, network net) +{ + int i, j; + int offset = 0; + for(i = 0; i < l.n; ++i){ + int index = l.input_layers[i]; + float *delta = net.layers[index].delta_gpu; + int input_size = l.input_sizes[i]; + for(j = 0; j < l.batch; ++j){ + axpy_gpu(input_size, 1, l.delta_gpu + offset + j*l.outputs, 1, delta + j*input_size, 1); + } + offset += input_size; + } +} +#endif diff --git a/hanzi_detection/src/route_layer.h b/hanzi_detection/src/route_layer.h new file mode 100755 index 0000000..1d40330 --- /dev/null +++ b/hanzi_detection/src/route_layer.h @@ -0,0 +1,18 @@ +#ifndef ROUTE_LAYER_H +#define ROUTE_LAYER_H +#include "network.h" +#include "layer.h" + +typedef layer route_layer; + +route_layer make_route_layer(int batch, int n, int *input_layers, int *input_size); +void forward_route_layer(const route_layer l, network net); +void backward_route_layer(const route_layer l, network net); +void resize_route_layer(route_layer *l, network *net); + +#ifdef GPU +void forward_route_layer_gpu(const route_layer l, network net); +void backward_route_layer_gpu(const route_layer l, network net); +#endif + +#endif diff --git a/hanzi_detection/src/shortcut_layer.c b/hanzi_detection/src/shortcut_layer.c new file mode 100755 index 0000000..49d17f5 --- /dev/null +++ b/hanzi_detection/src/shortcut_layer.c @@ -0,0 +1,90 @@ +#include "shortcut_layer.h" +#include "cuda.h" +#include "blas.h" +#include "activations.h" + +#include +#include + +layer make_shortcut_layer(int batch, int index, int w, int h, int c, int w2, int h2, int c2) +{ + fprintf(stderr, "res %3d %4d x%4d x%4d -> %4d x%4d x%4d\n",index, w2,h2,c2, w,h,c); + layer l = {0}; + l.type = SHORTCUT; + l.batch = batch; + l.w = w2; + l.h = h2; + l.c = c2; + l.out_w = w; + l.out_h = h; + l.out_c = c; + l.outputs = w*h*c; + l.inputs = l.outputs; + + l.index = index; + + l.delta = calloc(l.outputs*batch, sizeof(float)); + l.output = calloc(l.outputs*batch, sizeof(float));; + + l.forward = forward_shortcut_layer; + l.backward = backward_shortcut_layer; + #ifdef GPU + l.forward_gpu = forward_shortcut_layer_gpu; + l.backward_gpu = backward_shortcut_layer_gpu; + + l.delta_gpu = cuda_make_array(l.delta, l.outputs*batch); + l.output_gpu = cuda_make_array(l.output, l.outputs*batch); + #endif + return l; +} + +void resize_shortcut_layer(layer *l, int w, int h) +{ + assert(l->w == l->out_w); + assert(l->h == l->out_h); + l->w = l->out_w = w; + l->h = l->out_h = h; + l->outputs = w*h*l->out_c; + l->inputs = l->outputs; + l->delta = realloc(l->delta, l->outputs*l->batch*sizeof(float)); + l->output = realloc(l->output, l->outputs*l->batch*sizeof(float)); + +#ifdef GPU + cuda_free(l->output_gpu); + cuda_free(l->delta_gpu); + l->output_gpu = cuda_make_array(l->output, l->outputs*l->batch); + l->delta_gpu = cuda_make_array(l->delta, l->outputs*l->batch); +#endif + +} + + +void forward_shortcut_layer(const layer l, network net) +{ + copy_cpu(l.outputs*l.batch, net.input, 1, l.output, 1); + shortcut_cpu(l.batch, l.w, l.h, l.c, net.layers[l.index].output, l.out_w, l.out_h, l.out_c, l.alpha, l.beta, l.output); + activate_array(l.output, l.outputs*l.batch, l.activation); +} + +void backward_shortcut_layer(const layer l, network net) +{ + gradient_array(l.output, l.outputs*l.batch, l.activation, l.delta); + axpy_cpu(l.outputs*l.batch, l.alpha, l.delta, 1, net.delta, 1); + shortcut_cpu(l.batch, l.out_w, l.out_h, l.out_c, l.delta, l.w, l.h, l.c, 1, l.beta, net.layers[l.index].delta); +} + +#ifdef GPU +void forward_shortcut_layer_gpu(const layer l, network net) +{ + copy_gpu(l.outputs*l.batch, net.input_gpu, 1, l.output_gpu, 1); + shortcut_gpu(l.batch, l.w, l.h, l.c, net.layers[l.index].output_gpu, l.out_w, l.out_h, l.out_c, l.alpha, l.beta, l.output_gpu); + activate_array_gpu(l.output_gpu, l.outputs*l.batch, l.activation); +} + +void backward_shortcut_layer_gpu(const layer l, network net) +{ + gradient_array_gpu(l.output_gpu, l.outputs*l.batch, l.activation, l.delta_gpu); + axpy_gpu(l.outputs*l.batch, l.alpha, l.delta_gpu, 1, net.delta_gpu, 1); + shortcut_gpu(l.batch, l.out_w, l.out_h, l.out_c, l.delta_gpu, l.w, l.h, l.c, 1, l.beta, net.layers[l.index].delta_gpu); +} +#endif diff --git a/hanzi_detection/src/shortcut_layer.h b/hanzi_detection/src/shortcut_layer.h new file mode 100755 index 0000000..5f684fc --- /dev/null +++ b/hanzi_detection/src/shortcut_layer.h @@ -0,0 +1,17 @@ +#ifndef SHORTCUT_LAYER_H +#define SHORTCUT_LAYER_H + +#include "layer.h" +#include "network.h" + +layer make_shortcut_layer(int batch, int index, int w, int h, int c, int w2, int h2, int c2); +void forward_shortcut_layer(const layer l, network net); +void backward_shortcut_layer(const layer l, network net); +void resize_shortcut_layer(layer *l, int w, int h); + +#ifdef GPU +void forward_shortcut_layer_gpu(const layer l, network net); +void backward_shortcut_layer_gpu(const layer l, network net); +#endif + +#endif diff --git a/hanzi_detection/src/softmax_layer.c b/hanzi_detection/src/softmax_layer.c new file mode 100755 index 0000000..9cbc6be --- /dev/null +++ b/hanzi_detection/src/softmax_layer.c @@ -0,0 +1,107 @@ +#include "softmax_layer.h" +#include "blas.h" +#include "cuda.h" + +#include +#include +#include +#include +#include + +softmax_layer make_softmax_layer(int batch, int inputs, int groups) +{ + assert(inputs%groups == 0); + fprintf(stderr, "softmax %4d\n", inputs); + softmax_layer l = {0}; + l.type = SOFTMAX; + l.batch = batch; + l.groups = groups; + l.inputs = inputs; + l.outputs = inputs; + l.loss = calloc(inputs*batch, sizeof(float)); + l.output = calloc(inputs*batch, sizeof(float)); + l.delta = calloc(inputs*batch, sizeof(float)); + l.cost = calloc(1, sizeof(float)); + + l.forward = forward_softmax_layer; + l.backward = backward_softmax_layer; + #ifdef GPU + l.forward_gpu = forward_softmax_layer_gpu; + l.backward_gpu = backward_softmax_layer_gpu; + + l.output_gpu = cuda_make_array(l.output, inputs*batch); + l.loss_gpu = cuda_make_array(l.loss, inputs*batch); + l.delta_gpu = cuda_make_array(l.delta, inputs*batch); + #endif + return l; +} + +void forward_softmax_layer(const softmax_layer l, network net) +{ + if(l.softmax_tree){ + int i; + int count = 0; + for (i = 0; i < l.softmax_tree->groups; ++i) { + int group_size = l.softmax_tree->group_size[i]; + softmax_cpu(net.input + count, group_size, l.batch, l.inputs, 1, 0, 1, l.temperature, l.output + count); + count += group_size; + } + } else { + softmax_cpu(net.input, l.inputs/l.groups, l.batch, l.inputs, l.groups, l.inputs/l.groups, 1, l.temperature, l.output); + } + + if(net.truth && !l.noloss){ + softmax_x_ent_cpu(l.batch*l.inputs, l.output, net.truth, l.delta, l.loss); + l.cost[0] = sum_array(l.loss, l.batch*l.inputs); + } +} + +void backward_softmax_layer(const softmax_layer l, network net) +{ + axpy_cpu(l.inputs*l.batch, 1, l.delta, 1, net.delta, 1); +} + +#ifdef GPU + +void pull_softmax_layer_output(const softmax_layer layer) +{ + cuda_pull_array(layer.output_gpu, layer.output, layer.inputs*layer.batch); +} + +void forward_softmax_layer_gpu(const softmax_layer l, network net) +{ + if(l.softmax_tree){ + softmax_tree(net.input_gpu, 1, l.batch, l.inputs, l.temperature, l.output_gpu, *l.softmax_tree); + /* + int i; + int count = 0; + for (i = 0; i < l.softmax_tree->groups; ++i) { + int group_size = l.softmax_tree->group_size[i]; + softmax_gpu(net.input_gpu + count, group_size, l.batch, l.inputs, 1, 0, 1, l.temperature, l.output_gpu + count); + count += group_size; + } + */ + } else { + if(l.spatial){ + softmax_gpu(net.input_gpu, l.c, l.batch*l.c, l.inputs/l.c, l.w*l.h, 1, l.w*l.h, 1, l.output_gpu); + }else{ + softmax_gpu(net.input_gpu, l.inputs/l.groups, l.batch, l.inputs, l.groups, l.inputs/l.groups, 1, l.temperature, l.output_gpu); + } + } + if(net.truth && !l.noloss){ + softmax_x_ent_gpu(l.batch*l.inputs, l.output_gpu, net.truth_gpu, l.delta_gpu, l.loss_gpu); + if(l.softmax_tree){ + mask_gpu(l.batch*l.inputs, l.delta_gpu, SECRET_NUM, net.truth_gpu, 0); + mask_gpu(l.batch*l.inputs, l.loss_gpu, SECRET_NUM, net.truth_gpu, 0); + } + cuda_pull_array(l.loss_gpu, l.loss, l.batch*l.inputs); + l.cost[0] = sum_array(l.loss, l.batch*l.inputs); + } +} + +void backward_softmax_layer_gpu(const softmax_layer layer, network net) +{ + axpy_gpu(layer.batch*layer.inputs, 1, layer.delta_gpu, 1, net.delta_gpu, 1); +} + +#endif diff --git a/hanzi_detection/src/softmax_layer.h b/hanzi_detection/src/softmax_layer.h new file mode 100755 index 0000000..2e3ffe0 --- /dev/null +++ b/hanzi_detection/src/softmax_layer.h @@ -0,0 +1,19 @@ +#ifndef SOFTMAX_LAYER_H +#define SOFTMAX_LAYER_H +#include "layer.h" +#include "network.h" + +typedef layer softmax_layer; + +void softmax_array(float *input, int n, float temp, float *output); +softmax_layer make_softmax_layer(int batch, int inputs, int groups); +void forward_softmax_layer(const softmax_layer l, network net); +void backward_softmax_layer(const softmax_layer l, network net); + +#ifdef GPU +void pull_softmax_layer_output(const softmax_layer l); +void forward_softmax_layer_gpu(const softmax_layer l, network net); +void backward_softmax_layer_gpu(const softmax_layer l, network net); +#endif + +#endif diff --git a/hanzi_detection/src/stb_image.h b/hanzi_detection/src/stb_image.h new file mode 100755 index 0000000..d9c21bc --- /dev/null +++ b/hanzi_detection/src/stb_image.h @@ -0,0 +1,7462 @@ +/* stb_image - v2.19 - public domain image loader - http://nothings.org/stb + no warranty implied; use at your own risk + + Do this: + #define STB_IMAGE_IMPLEMENTATION + before you include this file in *one* C or C++ file to create the implementation. + + // i.e. it should look like this: + #include ... + #include ... + #include ... + #define STB_IMAGE_IMPLEMENTATION + #include "stb_image.h" + + You can #define STBI_ASSERT(x) before the #include to avoid using assert.h. + And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free + + + QUICK NOTES: + Primarily of interest to game developers and other people who can + avoid problematic images and only need the trivial interface + + JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib) + PNG 1/2/4/8/16-bit-per-channel + + TGA (not sure what subset, if a subset) + BMP non-1bpp, non-RLE + PSD (composited view only, no extra channels, 8/16 bit-per-channel) + + GIF (*comp always reports as 4-channel) + HDR (radiance rgbE format) + PIC (Softimage PIC) + PNM (PPM and PGM binary only) + + Animated GIF still needs a proper API, but here's one way to do it: + http://gist.github.com/urraka/685d9a6340b26b830d49 + + - decode from memory or through FILE (define STBI_NO_STDIO to remove code) + - decode from arbitrary I/O callbacks + - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON) + + Full documentation under "DOCUMENTATION" below. + + +LICENSE + + See end of file for license information. + +RECENT REVISION HISTORY: + + 2.19 (2018-02-11) fix warning + 2.18 (2018-01-30) fix warnings + 2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings + 2.16 (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes + 2.15 (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC + 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs + 2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes + 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes + 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64 + RGB-format JPEG; remove white matting in PSD; + allocate large structures on the stack; + correct channel count for PNG & BMP + 2.10 (2016-01-22) avoid warning introduced in 2.09 + 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED + + See end of file for full revision history. + + + ============================ Contributors ========================= + + Image formats Extensions, features + Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info) + Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info) + Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG) + Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks) + Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG) + Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip) + Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) + github:urraka (animated gif) Junggon Kim (PNM comments) + Christopher Forseth (animated gif) Daniel Gibson (16-bit TGA) + socks-the-fox (16-bit PNG) + Jeremy Sawicki (handle all ImageNet JPGs) + Optimizations & bugfixes Mikhail Morozov (1-bit BMP) + Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query) + Arseny Kapoulkine + John-Mark Allen + + Bug & warning fixes + Marc LeBlanc David Woo Guillaume George Martins Mozeiko + Christpher Lloyd Jerry Jansson Joseph Thomson Phil Jordan + Dave Moore Roy Eltham Hayaki Saito Nathan Reed + Won Chun Luke Graham Johan Duparc Nick Verigakis + the Horde3D community Thomas Ruf Ronny Chevalier github:rlyeh + Janez Zemva John Bartholomew Michal Cichon github:romigrou + Jonathan Blow Ken Hamada Tero Hanninen github:svdijk + Laurent Gomila Cort Stratton Sergio Gonzalez github:snagar + Aruelien Pocheville Thibault Reuille Cass Everitt github:Zelex + Ryamond Barbiero Paul Du Bois Engin Manap github:grim210 + Aldo Culquicondor Philipp Wiesemann Dale Weiler github:sammyhw + Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:phprus + Julian Raschke Gregory Mullen Baldur Karlsson github:poppolopoppo + Christian Floisand Kevin Schmidt github:darealshinji + Blazej Dariusz Roszkowski github:Michaelangel007 +*/ + +#ifndef STBI_INCLUDE_STB_IMAGE_H +#define STBI_INCLUDE_STB_IMAGE_H + +// DOCUMENTATION +// +// Limitations: +// - no 12-bit-per-channel JPEG +// - no JPEGs with arithmetic coding +// - GIF always returns *comp=4 +// +// Basic usage (see HDR discussion below for HDR usage): +// int x,y,n; +// unsigned char *data = stbi_load(filename, &x, &y, &n, 0); +// // ... process data if not NULL ... +// // ... x = width, y = height, n = # 8-bit components per pixel ... +// // ... replace '0' with '1'..'4' to force that many components per pixel +// // ... but 'n' will always be the number that it would have been if you said 0 +// stbi_image_free(data) +// +// Standard parameters: +// int *x -- outputs image width in pixels +// int *y -- outputs image height in pixels +// int *channels_in_file -- outputs # of image components in image file +// int desired_channels -- if non-zero, # of image components requested in result +// +// The return value from an image loader is an 'unsigned char *' which points +// to the pixel data, or NULL on an allocation failure or if the image is +// corrupt or invalid. The pixel data consists of *y scanlines of *x pixels, +// with each pixel consisting of N interleaved 8-bit components; the first +// pixel pointed to is top-left-most in the image. There is no padding between +// image scanlines or between pixels, regardless of format. The number of +// components N is 'desired_channels' if desired_channels is non-zero, or +// *channels_in_file otherwise. If desired_channels is non-zero, +// *channels_in_file has the number of components that _would_ have been +// output otherwise. E.g. if you set desired_channels to 4, you will always +// get RGBA output, but you can check *channels_in_file to see if it's trivially +// opaque because e.g. there were only 3 channels in the source image. +// +// An output image with N components has the following components interleaved +// in this order in each pixel: +// +// N=#comp components +// 1 grey +// 2 grey, alpha +// 3 red, green, blue +// 4 red, green, blue, alpha +// +// If image loading fails for any reason, the return value will be NULL, +// and *x, *y, *channels_in_file will be unchanged. The function +// stbi_failure_reason() can be queried for an extremely brief, end-user +// unfriendly explanation of why the load failed. Define STBI_NO_FAILURE_STRINGS +// to avoid compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly +// more user-friendly ones. +// +// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. +// +// =========================================================================== +// +// Philosophy +// +// stb libraries are designed with the following priorities: +// +// 1. easy to use +// 2. easy to maintain +// 3. good performance +// +// Sometimes I let "good performance" creep up in priority over "easy to maintain", +// and for best performance I may provide less-easy-to-use APIs that give higher +// performance, in addition to the easy to use ones. Nevertheless, it's important +// to keep in mind that from the standpoint of you, a client of this library, +// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all. +// +// Some secondary priorities arise directly from the first two, some of which +// make more explicit reasons why performance can't be emphasized. +// +// - Portable ("ease of use") +// - Small source code footprint ("easy to maintain") +// - No dependencies ("ease of use") +// +// =========================================================================== +// +// I/O callbacks +// +// I/O callbacks allow you to read from arbitrary sources, like packaged +// files or some other source. Data read from callbacks are processed +// through a small internal buffer (currently 128 bytes) to try to reduce +// overhead. +// +// The three functions you must define are "read" (reads some bytes of data), +// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). +// +// =========================================================================== +// +// SIMD support +// +// The JPEG decoder will try to automatically use SIMD kernels on x86 when +// supported by the compiler. For ARM Neon support, you must explicitly +// request it. +// +// (The old do-it-yourself SIMD API is no longer supported in the current +// code.) +// +// On x86, SSE2 will automatically be used when available based on a run-time +// test; if not, the generic C versions are used as a fall-back. On ARM targets, +// the typical path is to have separate builds for NEON and non-NEON devices +// (at least this is true for iOS and Android). Therefore, the NEON support is +// toggled by a build flag: define STBI_NEON to get NEON loops. +// +// If for some reason you do not want to use any of SIMD code, or if +// you have issues compiling it, you can disable it entirely by +// defining STBI_NO_SIMD. +// +// =========================================================================== +// +// HDR image support (disable by defining STBI_NO_HDR) +// +// stb_image now supports loading HDR images in general, and currently +// the Radiance .HDR file format, although the support is provided +// generically. You can still load any file through the existing interface; +// if you attempt to load an HDR file, it will be automatically remapped to +// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; +// both of these constants can be reconfigured through this interface: +// +// stbi_hdr_to_ldr_gamma(2.2f); +// stbi_hdr_to_ldr_scale(1.0f); +// +// (note, do not use _inverse_ constants; stbi_image will invert them +// appropriately). +// +// Additionally, there is a new, parallel interface for loading files as +// (linear) floats to preserve the full dynamic range: +// +// float *data = stbi_loadf(filename, &x, &y, &n, 0); +// +// If you load LDR images through this interface, those images will +// be promoted to floating point values, run through the inverse of +// constants corresponding to the above: +// +// stbi_ldr_to_hdr_scale(1.0f); +// stbi_ldr_to_hdr_gamma(2.2f); +// +// Finally, given a filename (or an open file or memory block--see header +// file for details) containing image data, you can query for the "most +// appropriate" interface to use (that is, whether the image is HDR or +// not), using: +// +// stbi_is_hdr(char *filename); +// +// =========================================================================== +// +// iPhone PNG support: +// +// By default we convert iphone-formatted PNGs back to RGB, even though +// they are internally encoded differently. You can disable this conversion +// by by calling stbi_convert_iphone_png_to_rgb(0), in which case +// you will always just get the native iphone "format" through (which +// is BGR stored in RGB). +// +// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per +// pixel to remove any premultiplied alpha *only* if the image file explicitly +// says there's premultiplied data (currently only happens in iPhone images, +// and only if iPhone convert-to-rgb processing is on). +// +// =========================================================================== +// +// ADDITIONAL CONFIGURATION +// +// - You can suppress implementation of any of the decoders to reduce +// your code footprint by #defining one or more of the following +// symbols before creating the implementation. +// +// STBI_NO_JPEG +// STBI_NO_PNG +// STBI_NO_BMP +// STBI_NO_PSD +// STBI_NO_TGA +// STBI_NO_GIF +// STBI_NO_HDR +// STBI_NO_PIC +// STBI_NO_PNM (.ppm and .pgm) +// +// - You can request *only* certain decoders and suppress all other ones +// (this will be more forward-compatible, as addition of new decoders +// doesn't require you to disable them explicitly): +// +// STBI_ONLY_JPEG +// STBI_ONLY_PNG +// STBI_ONLY_BMP +// STBI_ONLY_PSD +// STBI_ONLY_TGA +// STBI_ONLY_GIF +// STBI_ONLY_HDR +// STBI_ONLY_PIC +// STBI_ONLY_PNM (.ppm and .pgm) +// +// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still +// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB +// + + +#ifndef STBI_NO_STDIO +#include +#endif // STBI_NO_STDIO + +#define STBI_VERSION 1 + +enum +{ + STBI_default = 0, // only used for desired_channels + + STBI_grey = 1, + STBI_grey_alpha = 2, + STBI_rgb = 3, + STBI_rgb_alpha = 4 +}; + +typedef unsigned char stbi_uc; +typedef unsigned short stbi_us; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef STB_IMAGE_STATIC +#define STBIDEF static +#else +#define STBIDEF extern +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// PRIMARY API - works on images of any type +// + +// +// load image by filename, open file, or memory buffer +// + +typedef struct +{ + int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read + void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative + int (*eof) (void *user); // returns nonzero if we are at end of file/data +} stbi_io_callbacks; + +//////////////////////////////////// +// +// 8-bits-per-channel interface +// + +STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *channels_in_file, int desired_channels); +#ifndef STBI_NO_GIF +STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp); +#endif + + +#ifndef STBI_NO_STDIO +STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); +// for stbi_load_from_file, file pointer is left pointing immediately after image +#endif + +//////////////////////////////////// +// +// 16-bits-per-channel interface +// + +STBIDEF stbi_us *stbi_load_16_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); + +#ifndef STBI_NO_STDIO +STBIDEF stbi_us *stbi_load_16 (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); +#endif + +//////////////////////////////////// +// +// float-per-channel interface +// +#ifndef STBI_NO_LINEAR + STBIDEF float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); + + #ifndef STBI_NO_STDIO + STBIDEF float *stbi_loadf (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); + #endif +#endif + +#ifndef STBI_NO_HDR + STBIDEF void stbi_hdr_to_ldr_gamma(float gamma); + STBIDEF void stbi_hdr_to_ldr_scale(float scale); +#endif // STBI_NO_HDR + +#ifndef STBI_NO_LINEAR + STBIDEF void stbi_ldr_to_hdr_gamma(float gamma); + STBIDEF void stbi_ldr_to_hdr_scale(float scale); +#endif // STBI_NO_LINEAR + +// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR +STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); +STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); +#ifndef STBI_NO_STDIO +STBIDEF int stbi_is_hdr (char const *filename); +STBIDEF int stbi_is_hdr_from_file(FILE *f); +#endif // STBI_NO_STDIO + + +// get a VERY brief reason for failure +// NOT THREADSAFE +STBIDEF const char *stbi_failure_reason (void); + +// free the loaded image -- this is just free() +STBIDEF void stbi_image_free (void *retval_from_stbi_load); + +// get image dimensions & components without fully decoding +STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); +STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); +STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len); +STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *clbk, void *user); + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_info (char const *filename, int *x, int *y, int *comp); +STBIDEF int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); +STBIDEF int stbi_is_16_bit (char const *filename); +STBIDEF int stbi_is_16_bit_from_file(FILE *f); +#endif + + + +// for image formats that explicitly notate that they have premultiplied alpha, +// we just return the colors as stored in the file. set this flag to force +// unpremultiplication. results are undefined if the unpremultiply overflow. +STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); + +// indicate whether we should process iphone images back to canonical format, +// or just pass them through "as-is" +STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); + +// flip the image vertically, so the first pixel in the output array is the bottom left +STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip); + +// ZLIB client - used by PNG, available for other purposes + +STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); +STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header); +STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); +STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + +STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); +STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + + +#ifdef __cplusplus +} +#endif + +// +// +//// end header file ///////////////////////////////////////////////////// +#endif // STBI_INCLUDE_STB_IMAGE_H + +#ifdef STB_IMAGE_IMPLEMENTATION + +#if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) \ + || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) \ + || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) \ + || defined(STBI_ONLY_ZLIB) + #ifndef STBI_ONLY_JPEG + #define STBI_NO_JPEG + #endif + #ifndef STBI_ONLY_PNG + #define STBI_NO_PNG + #endif + #ifndef STBI_ONLY_BMP + #define STBI_NO_BMP + #endif + #ifndef STBI_ONLY_PSD + #define STBI_NO_PSD + #endif + #ifndef STBI_ONLY_TGA + #define STBI_NO_TGA + #endif + #ifndef STBI_ONLY_GIF + #define STBI_NO_GIF + #endif + #ifndef STBI_ONLY_HDR + #define STBI_NO_HDR + #endif + #ifndef STBI_ONLY_PIC + #define STBI_NO_PIC + #endif + #ifndef STBI_ONLY_PNM + #define STBI_NO_PNM + #endif +#endif + +#if defined(STBI_NO_PNG) && !defined(STBI_SUPPORT_ZLIB) && !defined(STBI_NO_ZLIB) +#define STBI_NO_ZLIB +#endif + + +#include +#include // ptrdiff_t on osx +#include +#include +#include + +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) +#include // ldexp, pow +#endif + +#ifndef STBI_NO_STDIO +#include +#endif + +#ifndef STBI_ASSERT +#include +#define STBI_ASSERT(x) assert(x) +#endif + + +#ifndef _MSC_VER + #ifdef __cplusplus + #define stbi_inline inline + #else + #define stbi_inline + #endif +#else + #define stbi_inline __forceinline +#endif + + +#ifdef _MSC_VER +typedef unsigned short stbi__uint16; +typedef signed short stbi__int16; +typedef unsigned int stbi__uint32; +typedef signed int stbi__int32; +#else +#include +typedef uint16_t stbi__uint16; +typedef int16_t stbi__int16; +typedef uint32_t stbi__uint32; +typedef int32_t stbi__int32; +#endif + +// should produce compiler error if size is wrong +typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; + +#ifdef _MSC_VER +#define STBI_NOTUSED(v) (void)(v) +#else +#define STBI_NOTUSED(v) (void)sizeof(v) +#endif + +#ifdef _MSC_VER +#define STBI_HAS_LROTL +#endif + +#ifdef STBI_HAS_LROTL + #define stbi_lrot(x,y) _lrotl(x,y) +#else + #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) +#endif + +#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED)) +// ok +#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED) +// ok +#else +#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)." +#endif + +#ifndef STBI_MALLOC +#define STBI_MALLOC(sz) malloc(sz) +#define STBI_REALLOC(p,newsz) realloc(p,newsz) +#define STBI_FREE(p) free(p) +#endif + +#ifndef STBI_REALLOC_SIZED +#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz) +#endif + +// x86/x64 detection +#if defined(__x86_64__) || defined(_M_X64) +#define STBI__X64_TARGET +#elif defined(__i386) || defined(_M_IX86) +#define STBI__X86_TARGET +#endif + +#if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD) +// gcc doesn't support sse2 intrinsics unless you compile with -msse2, +// which in turn means it gets to use SSE2 everywhere. This is unfortunate, +// but previous attempts to provide the SSE2 functions with runtime +// detection caused numerous issues. The way architecture extensions are +// exposed in GCC/Clang is, sadly, not really suited for one-file libs. +// New behavior: if compiled with -msse2, we use SSE2 without any +// detection; if not, we don't use it at all. +#define STBI_NO_SIMD +#endif + +#if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD) +// Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET +// +// 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the +// Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant. +// As a result, enabling SSE2 on 32-bit MinGW is dangerous when not +// simultaneously enabling "-mstackrealign". +// +// See https://github.com/nothings/stb/issues/81 for more information. +// +// So default to no SSE2 on 32-bit MinGW. If you've read this far and added +// -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2. +#define STBI_NO_SIMD +#endif + +#if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) +#define STBI_SSE2 +#include + +#ifdef _MSC_VER + +#if _MSC_VER >= 1400 // not VC6 +#include // __cpuid +static int stbi__cpuid3(void) +{ + int info[4]; + __cpuid(info,1); + return info[3]; +} +#else +static int stbi__cpuid3(void) +{ + int res; + __asm { + mov eax,1 + cpuid + mov res,edx + } + return res; +} +#endif + +#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name + +static int stbi__sse2_available(void) +{ + int info3 = stbi__cpuid3(); + return ((info3 >> 26) & 1) != 0; +} +#else // assume GCC-style if not VC++ +#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) + +static int stbi__sse2_available(void) +{ + // If we're even attempting to compile this on GCC/Clang, that means + // -msse2 is on, which means the compiler is allowed to use SSE2 + // instructions at will, and so are we. + return 1; +} +#endif +#endif + +// ARM NEON +#if defined(STBI_NO_SIMD) && defined(STBI_NEON) +#undef STBI_NEON +#endif + +#ifdef STBI_NEON +#include +// assume GCC or Clang on ARM targets +#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) +#endif + +#ifndef STBI_SIMD_ALIGN +#define STBI_SIMD_ALIGN(type, name) type name +#endif + +/////////////////////////////////////////////// +// +// stbi__context struct and start_xxx functions + +// stbi__context structure is our basic context used by all images, so it +// contains all the IO context, plus some basic image information +typedef struct +{ + stbi__uint32 img_x, img_y; + int img_n, img_out_n; + + stbi_io_callbacks io; + void *io_user_data; + + int read_from_callbacks; + int buflen; + stbi_uc buffer_start[128]; + + stbi_uc *img_buffer, *img_buffer_end; + stbi_uc *img_buffer_original, *img_buffer_original_end; +} stbi__context; + + +static void stbi__refill_buffer(stbi__context *s); + +// initialize a memory-decode context +static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len) +{ + s->io.read = NULL; + s->read_from_callbacks = 0; + s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer; + s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len; +} + +// initialize a callback-based context +static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *user) +{ + s->io = *c; + s->io_user_data = user; + s->buflen = sizeof(s->buffer_start); + s->read_from_callbacks = 1; + s->img_buffer_original = s->buffer_start; + stbi__refill_buffer(s); + s->img_buffer_original_end = s->img_buffer_end; +} + +#ifndef STBI_NO_STDIO + +static int stbi__stdio_read(void *user, char *data, int size) +{ + return (int) fread(data,1,size,(FILE*) user); +} + +static void stbi__stdio_skip(void *user, int n) +{ + fseek((FILE*) user, n, SEEK_CUR); +} + +static int stbi__stdio_eof(void *user) +{ + return feof((FILE*) user); +} + +static stbi_io_callbacks stbi__stdio_callbacks = +{ + stbi__stdio_read, + stbi__stdio_skip, + stbi__stdio_eof, +}; + +static void stbi__start_file(stbi__context *s, FILE *f) +{ + stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f); +} + +//static void stop_file(stbi__context *s) { } + +#endif // !STBI_NO_STDIO + +static void stbi__rewind(stbi__context *s) +{ + // conceptually rewind SHOULD rewind to the beginning of the stream, + // but we just rewind to the beginning of the initial buffer, because + // we only use it after doing 'test', which only ever looks at at most 92 bytes + s->img_buffer = s->img_buffer_original; + s->img_buffer_end = s->img_buffer_original_end; +} + +enum +{ + STBI_ORDER_RGB, + STBI_ORDER_BGR +}; + +typedef struct +{ + int bits_per_channel; + int num_channels; + int channel_order; +} stbi__result_info; + +#ifndef STBI_NO_JPEG +static int stbi__jpeg_test(stbi__context *s); +static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PNG +static int stbi__png_test(stbi__context *s); +static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__png_is16(stbi__context *s); +#endif + +#ifndef STBI_NO_BMP +static int stbi__bmp_test(stbi__context *s); +static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_TGA +static int stbi__tga_test(stbi__context *s); +static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PSD +static int stbi__psd_test(stbi__context *s); +static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc); +static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__psd_is16(stbi__context *s); +#endif + +#ifndef STBI_NO_HDR +static int stbi__hdr_test(stbi__context *s); +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PIC +static int stbi__pic_test(stbi__context *s); +static void *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_GIF +static int stbi__gif_test(stbi__context *s); +static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp); +static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PNM +static int stbi__pnm_test(stbi__context *s); +static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +// this is not threadsafe +static const char *stbi__g_failure_reason; + +STBIDEF const char *stbi_failure_reason(void) +{ + return stbi__g_failure_reason; +} + +static int stbi__err(const char *str) +{ + stbi__g_failure_reason = str; + return 0; +} + +static void *stbi__malloc(size_t size) +{ + return STBI_MALLOC(size); +} + +// stb_image uses ints pervasively, including for offset calculations. +// therefore the largest decoded image size we can support with the +// current code, even on 64-bit targets, is INT_MAX. this is not a +// significant limitation for the intended use case. +// +// we do, however, need to make sure our size calculations don't +// overflow. hence a few helper functions for size calculations that +// multiply integers together, making sure that they're non-negative +// and no overflow occurs. + +// return 1 if the sum is valid, 0 on overflow. +// negative terms are considered invalid. +static int stbi__addsizes_valid(int a, int b) +{ + if (b < 0) return 0; + // now 0 <= b <= INT_MAX, hence also + // 0 <= INT_MAX - b <= INTMAX. + // And "a + b <= INT_MAX" (which might overflow) is the + // same as a <= INT_MAX - b (no overflow) + return a <= INT_MAX - b; +} + +// returns 1 if the product is valid, 0 on overflow. +// negative factors are considered invalid. +static int stbi__mul2sizes_valid(int a, int b) +{ + if (a < 0 || b < 0) return 0; + if (b == 0) return 1; // mul-by-0 is always safe + // portable way to check for no overflows in a*b + return a <= INT_MAX/b; +} + +// returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow +static int stbi__mad2sizes_valid(int a, int b, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, add); +} + +// returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow +static int stbi__mad3sizes_valid(int a, int b, int c, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && + stbi__addsizes_valid(a*b*c, add); +} + +// returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) +static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && + stbi__mul2sizes_valid(a*b*c, d) && stbi__addsizes_valid(a*b*c*d, add); +} +#endif + +// mallocs with size overflow checking +static void *stbi__malloc_mad2(int a, int b, int add) +{ + if (!stbi__mad2sizes_valid(a, b, add)) return NULL; + return stbi__malloc(a*b + add); +} + +static void *stbi__malloc_mad3(int a, int b, int c, int add) +{ + if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL; + return stbi__malloc(a*b*c + add); +} + +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) +static void *stbi__malloc_mad4(int a, int b, int c, int d, int add) +{ + if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL; + return stbi__malloc(a*b*c*d + add); +} +#endif + +// stbi__err - error +// stbi__errpf - error returning pointer to float +// stbi__errpuc - error returning pointer to unsigned char + +#ifdef STBI_NO_FAILURE_STRINGS + #define stbi__err(x,y) 0 +#elif defined(STBI_FAILURE_USERMSG) + #define stbi__err(x,y) stbi__err(y) +#else + #define stbi__err(x,y) stbi__err(x) +#endif + +#define stbi__errpf(x,y) ((float *)(size_t) (stbi__err(x,y)?NULL:NULL)) +#define stbi__errpuc(x,y) ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL)) + +STBIDEF void stbi_image_free(void *retval_from_stbi_load) +{ + STBI_FREE(retval_from_stbi_load); +} + +#ifndef STBI_NO_LINEAR +static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp); +#endif + +#ifndef STBI_NO_HDR +static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp); +#endif + +static int stbi__vertically_flip_on_load = 0; + +STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) +{ + stbi__vertically_flip_on_load = flag_true_if_should_flip; +} + +static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) +{ + memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields + ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed + ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order + ri->num_channels = 0; + + #ifndef STBI_NO_JPEG + if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_PNG + if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_BMP + if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_GIF + if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_PSD + if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc); + #endif + #ifndef STBI_NO_PIC + if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_PNM + if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp, ri); + #endif + + #ifndef STBI_NO_HDR + if (stbi__hdr_test(s)) { + float *hdr = stbi__hdr_load(s, x,y,comp,req_comp, ri); + return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); + } + #endif + + #ifndef STBI_NO_TGA + // test tga last because it's a crappy test! + if (stbi__tga_test(s)) + return stbi__tga_load(s,x,y,comp,req_comp, ri); + #endif + + return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); +} + +static stbi_uc *stbi__convert_16_to_8(stbi__uint16 *orig, int w, int h, int channels) +{ + int i; + int img_len = w * h * channels; + stbi_uc *reduced; + + reduced = (stbi_uc *) stbi__malloc(img_len); + if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory"); + + for (i = 0; i < img_len; ++i) + reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling + + STBI_FREE(orig); + return reduced; +} + +static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int channels) +{ + int i; + int img_len = w * h * channels; + stbi__uint16 *enlarged; + + enlarged = (stbi__uint16 *) stbi__malloc(img_len*2); + if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); + + for (i = 0; i < img_len; ++i) + enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff + + STBI_FREE(orig); + return enlarged; +} + +static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel) +{ + int row; + size_t bytes_per_row = (size_t)w * bytes_per_pixel; + stbi_uc temp[2048]; + stbi_uc *bytes = (stbi_uc *)image; + + for (row = 0; row < (h>>1); row++) { + stbi_uc *row0 = bytes + row*bytes_per_row; + stbi_uc *row1 = bytes + (h - row - 1)*bytes_per_row; + // swap row0 with row1 + size_t bytes_left = bytes_per_row; + while (bytes_left) { + size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp); + memcpy(temp, row0, bytes_copy); + memcpy(row0, row1, bytes_copy); + memcpy(row1, temp, bytes_copy); + row0 += bytes_copy; + row1 += bytes_copy; + bytes_left -= bytes_copy; + } + } +} + +static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel) +{ + int slice; + int slice_size = w * h * bytes_per_pixel; + + stbi_uc *bytes = (stbi_uc *)image; + for (slice = 0; slice < z; ++slice) { + stbi__vertical_flip(bytes, w, h, bytes_per_pixel); + bytes += slice_size; + } +} + +static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi__result_info ri; + void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8); + + if (result == NULL) + return NULL; + + if (ri.bits_per_channel != 8) { + STBI_ASSERT(ri.bits_per_channel == 16); + result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp); + ri.bits_per_channel = 8; + } + + // @TODO: move stbi__convert_format to here + + if (stbi__vertically_flip_on_load) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc)); + } + + return (unsigned char *) result; +} + +static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi__result_info ri; + void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16); + + if (result == NULL) + return NULL; + + if (ri.bits_per_channel != 16) { + STBI_ASSERT(ri.bits_per_channel == 8); + result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp); + ri.bits_per_channel = 16; + } + + // @TODO: move stbi__convert_format16 to here + // @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision + + if (stbi__vertically_flip_on_load) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16)); + } + + return (stbi__uint16 *) result; +} + +#if !defined(STBI_NO_HDR) || !defined(STBI_NO_LINEAR) +static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp) +{ + if (stbi__vertically_flip_on_load && result != NULL) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(float)); + } +} +#endif + +#ifndef STBI_NO_STDIO + +static FILE *stbi__fopen(char const *filename, char const *mode) +{ + FILE *f; +#if defined(_MSC_VER) && _MSC_VER >= 1400 + if (0 != fopen_s(&f, filename, mode)) + f=0; +#else + f = fopen(filename, mode); +#endif + return f; +} + + +STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + unsigned char *result; + if (!f) return stbi__errpuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *result; + stbi__context s; + stbi__start_file(&s,f); + result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); + if (result) { + // need to 'unget' all the characters in the IO buffer + fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); + } + return result; +} + +STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi__uint16 *result; + stbi__context s; + stbi__start_file(&s,f); + result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp); + if (result) { + // need to 'unget' all the characters in the IO buffer + fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); + } + return result; +} + +STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + stbi__uint16 *result; + if (!f) return (stbi_us *) stbi__errpuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file_16(f,x,y,comp,req_comp); + fclose(f); + return result; +} + + +#endif //!STBI_NO_STDIO + +STBIDEF stbi_us *stbi_load_16_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); +} + +STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user); + return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); +} + +STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); +} + +STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_GIF +STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp) +{ + unsigned char *result; + stbi__context s; + stbi__start_mem(&s,buffer,len); + + result = (unsigned char*) stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp); + if (stbi__vertically_flip_on_load) { + stbi__vertical_flip_slices( result, *x, *y, *z, *comp ); + } + + return result; +} +#endif + +#ifndef STBI_NO_LINEAR +static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *data; + #ifndef STBI_NO_HDR + if (stbi__hdr_test(s)) { + stbi__result_info ri; + float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp, &ri); + if (hdr_data) + stbi__float_postprocess(hdr_data,x,y,comp,req_comp); + return hdr_data; + } + #endif + data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp); + if (data) + return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); + return stbi__errpf("unknown image type", "Image not of any known type, or corrupt"); +} + +STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} + +STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_STDIO +STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + float *result; + FILE *f = stbi__fopen(filename, "rb"); + if (!f) return stbi__errpf("can't fopen", "Unable to open file"); + result = stbi_loadf_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_file(&s,f); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} +#endif // !STBI_NO_STDIO + +#endif // !STBI_NO_LINEAR + +// these is-hdr-or-not is defined independent of whether STBI_NO_LINEAR is +// defined, for API simplicity; if STBI_NO_LINEAR is defined, it always +// reports false! + +STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) +{ + #ifndef STBI_NO_HDR + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__hdr_test(&s); + #else + STBI_NOTUSED(buffer); + STBI_NOTUSED(len); + return 0; + #endif +} + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_is_hdr (char const *filename) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result=0; + if (f) { + result = stbi_is_hdr_from_file(f); + fclose(f); + } + return result; +} + +STBIDEF int stbi_is_hdr_from_file(FILE *f) +{ + #ifndef STBI_NO_HDR + long pos = ftell(f); + int res; + stbi__context s; + stbi__start_file(&s,f); + res = stbi__hdr_test(&s); + fseek(f, pos, SEEK_SET); + return res; + #else + STBI_NOTUSED(f); + return 0; + #endif +} +#endif // !STBI_NO_STDIO + +STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) +{ + #ifndef STBI_NO_HDR + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__hdr_test(&s); + #else + STBI_NOTUSED(clbk); + STBI_NOTUSED(user); + return 0; + #endif +} + +#ifndef STBI_NO_LINEAR +static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f; + +STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; } +STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; } +#endif + +static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f; + +STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; } +STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; } + + +////////////////////////////////////////////////////////////////////////////// +// +// Common code used by all image loaders +// + +enum +{ + STBI__SCAN_load=0, + STBI__SCAN_type, + STBI__SCAN_header +}; + +static void stbi__refill_buffer(stbi__context *s) +{ + int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen); + if (n == 0) { + // at end of file, treat same as if from memory, but need to handle case + // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file + s->read_from_callbacks = 0; + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start+1; + *s->img_buffer = 0; + } else { + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start + n; + } +} + +stbi_inline static stbi_uc stbi__get8(stbi__context *s) +{ + if (s->img_buffer < s->img_buffer_end) + return *s->img_buffer++; + if (s->read_from_callbacks) { + stbi__refill_buffer(s); + return *s->img_buffer++; + } + return 0; +} + +stbi_inline static int stbi__at_eof(stbi__context *s) +{ + if (s->io.read) { + if (!(s->io.eof)(s->io_user_data)) return 0; + // if feof() is true, check if buffer = end + // special case: we've only got the special 0 character at the end + if (s->read_from_callbacks == 0) return 1; + } + + return s->img_buffer >= s->img_buffer_end; +} + +static void stbi__skip(stbi__context *s, int n) +{ + if (n < 0) { + s->img_buffer = s->img_buffer_end; + return; + } + if (s->io.read) { + int blen = (int) (s->img_buffer_end - s->img_buffer); + if (blen < n) { + s->img_buffer = s->img_buffer_end; + (s->io.skip)(s->io_user_data, n - blen); + return; + } + } + s->img_buffer += n; +} + +static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n) +{ + if (s->io.read) { + int blen = (int) (s->img_buffer_end - s->img_buffer); + if (blen < n) { + int res, count; + + memcpy(buffer, s->img_buffer, blen); + + count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen); + res = (count == (n-blen)); + s->img_buffer = s->img_buffer_end; + return res; + } + } + + if (s->img_buffer+n <= s->img_buffer_end) { + memcpy(buffer, s->img_buffer, n); + s->img_buffer += n; + return 1; + } else + return 0; +} + +static int stbi__get16be(stbi__context *s) +{ + int z = stbi__get8(s); + return (z << 8) + stbi__get8(s); +} + +static stbi__uint32 stbi__get32be(stbi__context *s) +{ + stbi__uint32 z = stbi__get16be(s); + return (z << 16) + stbi__get16be(s); +} + +#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) +// nothing +#else +static int stbi__get16le(stbi__context *s) +{ + int z = stbi__get8(s); + return z + (stbi__get8(s) << 8); +} +#endif + +#ifndef STBI_NO_BMP +static stbi__uint32 stbi__get32le(stbi__context *s) +{ + stbi__uint32 z = stbi__get16le(s); + return z + (stbi__get16le(s) << 16); +} +#endif + +#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings + + +////////////////////////////////////////////////////////////////////////////// +// +// generic converter from built-in img_n to req_comp +// individual types do this automatically as much as possible (e.g. jpeg +// does all cases internally since it needs to colorspace convert anyway, +// and it never has alpha, so very few cases ). png can automatically +// interleave an alpha=255 channel, but falls back to this for other cases +// +// assume data buffer is malloced, so malloc a new one and free that one +// only failure mode is malloc failing + +static stbi_uc stbi__compute_y(int r, int g, int b) +{ + return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8); +} + +static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y) +{ + int i,j; + unsigned char *good; + + if (req_comp == img_n) return data; + STBI_ASSERT(req_comp >= 1 && req_comp <= 4); + + good = (unsigned char *) stbi__malloc_mad3(req_comp, x, y, 0); + if (good == NULL) { + STBI_FREE(data); + return stbi__errpuc("outofmem", "Out of memory"); + } + + for (j=0; j < (int) y; ++j) { + unsigned char *src = data + j * x * img_n ; + unsigned char *dest = good + j * x * req_comp; + + #define STBI__COMBO(a,b) ((a)*8+(b)) + #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch (STBI__COMBO(img_n, req_comp)) { + STBI__CASE(1,2) { dest[0]=src[0], dest[1]=255; } break; + STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; } break; + STBI__CASE(2,1) { dest[0]=src[0]; } break; + STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break; + STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; } break; + STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; + STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = 255; } break; + STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; + STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; } break; + STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break; + default: STBI_ASSERT(0); + } + #undef STBI__CASE + } + + STBI_FREE(data); + return good; +} + +static stbi__uint16 stbi__compute_y_16(int r, int g, int b) +{ + return (stbi__uint16) (((r*77) + (g*150) + (29*b)) >> 8); +} + +static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y) +{ + int i,j; + stbi__uint16 *good; + + if (req_comp == img_n) return data; + STBI_ASSERT(req_comp >= 1 && req_comp <= 4); + + good = (stbi__uint16 *) stbi__malloc(req_comp * x * y * 2); + if (good == NULL) { + STBI_FREE(data); + return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); + } + + for (j=0; j < (int) y; ++j) { + stbi__uint16 *src = data + j * x * img_n ; + stbi__uint16 *dest = good + j * x * req_comp; + + #define STBI__COMBO(a,b) ((a)*8+(b)) + #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch (STBI__COMBO(img_n, req_comp)) { + STBI__CASE(1,2) { dest[0]=src[0], dest[1]=0xffff; } break; + STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=0xffff; } break; + STBI__CASE(2,1) { dest[0]=src[0]; } break; + STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break; + STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=0xffff; } break; + STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; + STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = 0xffff; } break; + STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; + STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = src[3]; } break; + STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break; + default: STBI_ASSERT(0); + } + #undef STBI__CASE + } + + STBI_FREE(data); + return good; +} + +#ifndef STBI_NO_LINEAR +static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) +{ + int i,k,n; + float *output; + if (!data) return NULL; + output = (float *) stbi__malloc_mad4(x, y, comp, sizeof(float), 0); + if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale); + } + if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f; + } + STBI_FREE(data); + return output; +} +#endif + +#ifndef STBI_NO_HDR +#define stbi__float2int(x) ((int) (x)) +static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp) +{ + int i,k,n; + stbi_uc *output; + if (!data) return NULL; + output = (stbi_uc *) stbi__malloc_mad3(x, y, comp, 0); + if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + float z = (float) pow(data[i*comp+k]*stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (stbi_uc) stbi__float2int(z); + } + if (k < comp) { + float z = data[i*comp+k] * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (stbi_uc) stbi__float2int(z); + } + } + STBI_FREE(data); + return output; +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// "baseline" JPEG/JFIF decoder +// +// simple implementation +// - doesn't support delayed output of y-dimension +// - simple interface (only one output format: 8-bit interleaved RGB) +// - doesn't try to recover corrupt jpegs +// - doesn't allow partial loading, loading multiple at once +// - still fast on x86 (copying globals into locals doesn't help x86) +// - allocates lots of intermediate memory (full size of all components) +// - non-interleaved case requires this anyway +// - allows good upsampling (see next) +// high-quality +// - upsampled channels are bilinearly interpolated, even across blocks +// - quality integer IDCT derived from IJG's 'slow' +// performance +// - fast huffman; reasonable integer IDCT +// - some SIMD kernels for common paths on targets with SSE2/NEON +// - uses a lot of intermediate memory, could cache poorly + +#ifndef STBI_NO_JPEG + +// huffman decoding acceleration +#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache + +typedef struct +{ + stbi_uc fast[1 << FAST_BITS]; + // weirdly, repacking this into AoS is a 10% speed loss, instead of a win + stbi__uint16 code[256]; + stbi_uc values[256]; + stbi_uc size[257]; + unsigned int maxcode[18]; + int delta[17]; // old 'firstsymbol' - old 'firstcode' +} stbi__huffman; + +typedef struct +{ + stbi__context *s; + stbi__huffman huff_dc[4]; + stbi__huffman huff_ac[4]; + stbi__uint16 dequant[4][64]; + stbi__int16 fast_ac[4][1 << FAST_BITS]; + +// sizes for components, interleaved MCUs + int img_h_max, img_v_max; + int img_mcu_x, img_mcu_y; + int img_mcu_w, img_mcu_h; + +// definition of jpeg image component + struct + { + int id; + int h,v; + int tq; + int hd,ha; + int dc_pred; + + int x,y,w2,h2; + stbi_uc *data; + void *raw_data, *raw_coeff; + stbi_uc *linebuf; + short *coeff; // progressive only + int coeff_w, coeff_h; // number of 8x8 coefficient blocks + } img_comp[4]; + + stbi__uint32 code_buffer; // jpeg entropy-coded buffer + int code_bits; // number of valid bits + unsigned char marker; // marker seen while filling entropy buffer + int nomore; // flag if we saw a marker so must stop + + int progressive; + int spec_start; + int spec_end; + int succ_high; + int succ_low; + int eob_run; + int jfif; + int app14_color_transform; // Adobe APP14 tag + int rgb; + + int scan_n, order[4]; + int restart_interval, todo; + +// kernels + void (*idct_block_kernel)(stbi_uc *out, int out_stride, short data[64]); + void (*YCbCr_to_RGB_kernel)(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step); + stbi_uc *(*resample_row_hv_2_kernel)(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs); +} stbi__jpeg; + +static int stbi__build_huffman(stbi__huffman *h, int *count) +{ + int i,j,k=0; + unsigned int code; + // build size list for each symbol (from JPEG spec) + for (i=0; i < 16; ++i) + for (j=0; j < count[i]; ++j) + h->size[k++] = (stbi_uc) (i+1); + h->size[k] = 0; + + // compute actual symbols (from jpeg spec) + code = 0; + k = 0; + for(j=1; j <= 16; ++j) { + // compute delta to add to code to compute symbol id + h->delta[j] = k - code; + if (h->size[k] == j) { + while (h->size[k] == j) + h->code[k++] = (stbi__uint16) (code++); + if (code-1 >= (1u << j)) return stbi__err("bad code lengths","Corrupt JPEG"); + } + // compute largest code + 1 for this size, preshifted as needed later + h->maxcode[j] = code << (16-j); + code <<= 1; + } + h->maxcode[j] = 0xffffffff; + + // build non-spec acceleration table; 255 is flag for not-accelerated + memset(h->fast, 255, 1 << FAST_BITS); + for (i=0; i < k; ++i) { + int s = h->size[i]; + if (s <= FAST_BITS) { + int c = h->code[i] << (FAST_BITS-s); + int m = 1 << (FAST_BITS-s); + for (j=0; j < m; ++j) { + h->fast[c+j] = (stbi_uc) i; + } + } + } + return 1; +} + +// build a table that decodes both magnitude and value of small ACs in +// one go. +static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h) +{ + int i; + for (i=0; i < (1 << FAST_BITS); ++i) { + stbi_uc fast = h->fast[i]; + fast_ac[i] = 0; + if (fast < 255) { + int rs = h->values[fast]; + int run = (rs >> 4) & 15; + int magbits = rs & 15; + int len = h->size[fast]; + + if (magbits && len + magbits <= FAST_BITS) { + // magnitude code followed by receive_extend code + int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); + int m = 1 << (magbits - 1); + if (k < m) k += (~0U << magbits) + 1; + // if the result is small enough, we can fit it in fast_ac table + if (k >= -128 && k <= 127) + fast_ac[i] = (stbi__int16) ((k * 256) + (run * 16) + (len + magbits)); + } + } + } +} + +static void stbi__grow_buffer_unsafe(stbi__jpeg *j) +{ + do { + unsigned int b = j->nomore ? 0 : stbi__get8(j->s); + if (b == 0xff) { + int c = stbi__get8(j->s); + while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes + if (c != 0) { + j->marker = (unsigned char) c; + j->nomore = 1; + return; + } + } + j->code_buffer |= b << (24 - j->code_bits); + j->code_bits += 8; + } while (j->code_bits <= 24); +} + +// (1 << n) - 1 +static const stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; + +// decode a jpeg huffman value from the bitstream +stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h) +{ + unsigned int temp; + int c,k; + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + + // look at the top FAST_BITS and determine what symbol ID it is, + // if the code is <= FAST_BITS + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + k = h->fast[c]; + if (k < 255) { + int s = h->size[k]; + if (s > j->code_bits) + return -1; + j->code_buffer <<= s; + j->code_bits -= s; + return h->values[k]; + } + + // naive test is to shift the code_buffer down so k bits are + // valid, then test against maxcode. To speed this up, we've + // preshifted maxcode left so that it has (16-k) 0s at the + // end; in other words, regardless of the number of bits, it + // wants to be compared against something shifted to have 16; + // that way we don't need to shift inside the loop. + temp = j->code_buffer >> 16; + for (k=FAST_BITS+1 ; ; ++k) + if (temp < h->maxcode[k]) + break; + if (k == 17) { + // error! code not found + j->code_bits -= 16; + return -1; + } + + if (k > j->code_bits) + return -1; + + // convert the huffman code to the symbol id + c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; + STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); + + // convert the id to a symbol + j->code_bits -= k; + j->code_buffer <<= k; + return h->values[c]; +} + +// bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); + + sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB + k = stbi_lrot(j->code_buffer, n); + STBI_ASSERT(n >= 0 && n < (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask))); + j->code_buffer = k & ~stbi__bmask[n]; + k &= stbi__bmask[n]; + j->code_bits -= n; + return k + (stbi__jbias[n] & ~sgn); +} + +// get some unsigned bits +stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n) +{ + unsigned int k; + if (j->code_bits < n) stbi__grow_buffer_unsafe(j); + k = stbi_lrot(j->code_buffer, n); + j->code_buffer = k & ~stbi__bmask[n]; + k &= stbi__bmask[n]; + j->code_bits -= n; + return k; +} + +stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j) +{ + unsigned int k; + if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); + k = j->code_buffer; + j->code_buffer <<= 1; + --j->code_bits; + return k & 0x80000000; +} + +// given a value that's at position X in the zigzag stream, +// where does it appear in the 8x8 matrix coded as row-major? +static const stbi_uc stbi__jpeg_dezigzag[64+15] = +{ + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + // let corrupt input sample past end + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63 +}; + +// decode one 64-entry block-- +static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi__uint16 *dequant) +{ + int diff,dc,k; + int t; + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + t = stbi__jpeg_huff_decode(j, hdc); + if (t < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + + // 0 all the ac values now so we can do it 32-bits at a time + memset(data,0,64*sizeof(data[0])); + + diff = t ? stbi__extend_receive(j, t) : 0; + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short) (dc * dequant[0]); + + // decode AC components, see JPEG spec + k = 1; + do { + unsigned int zig; + int c,r,s; + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + r = fac[c]; + if (r) { // fast-AC path + k += (r >> 4) & 15; // run + s = r & 15; // combined length + j->code_buffer <<= s; + j->code_bits -= s; + // decode into unzigzag'd location + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) ((r >> 8) * dequant[zig]); + } else { + int rs = stbi__jpeg_huff_decode(j, hac); + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (rs != 0xf0) break; // end block + k += 16; + } else { + k += r; + // decode into unzigzag'd location + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) (stbi__extend_receive(j,s) * dequant[zig]); + } + } + } while (k < 64); + return 1; +} + +static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__huffman *hdc, int b) +{ + int diff,dc; + int t; + if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + + if (j->succ_high == 0) { + // first scan for DC coefficient, must be first + memset(data,0,64*sizeof(data[0])); // 0 all the ac values now + t = stbi__jpeg_huff_decode(j, hdc); + diff = t ? stbi__extend_receive(j, t) : 0; + + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short) (dc << j->succ_low); + } else { + // refinement scan for DC coefficient + if (stbi__jpeg_get_bit(j)) + data[0] += (short) (1 << j->succ_low); + } + return 1; +} + +// @OPTIMIZE: store non-zigzagged during the decode passes, +// and only de-zigzag when dequantizing +static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__huffman *hac, stbi__int16 *fac) +{ + int k; + if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + + if (j->succ_high == 0) { + int shift = j->succ_low; + + if (j->eob_run) { + --j->eob_run; + return 1; + } + + k = j->spec_start; + do { + unsigned int zig; + int c,r,s; + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + r = fac[c]; + if (r) { // fast-AC path + k += (r >> 4) & 15; // run + s = r & 15; // combined length + j->code_buffer <<= s; + j->code_bits -= s; + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) ((r >> 8) << shift); + } else { + int rs = stbi__jpeg_huff_decode(j, hac); + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (r < 15) { + j->eob_run = (1 << r); + if (r) + j->eob_run += stbi__jpeg_get_bits(j, r); + --j->eob_run; + break; + } + k += 16; + } else { + k += r; + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) (stbi__extend_receive(j,s) << shift); + } + } + } while (k <= j->spec_end); + } else { + // refinement scan for these AC coefficients + + short bit = (short) (1 << j->succ_low); + + if (j->eob_run) { + --j->eob_run; + for (k = j->spec_start; k <= j->spec_end; ++k) { + short *p = &data[stbi__jpeg_dezigzag[k]]; + if (*p != 0) + if (stbi__jpeg_get_bit(j)) + if ((*p & bit)==0) { + if (*p > 0) + *p += bit; + else + *p -= bit; + } + } + } else { + k = j->spec_start; + do { + int r,s; + int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (r < 15) { + j->eob_run = (1 << r) - 1; + if (r) + j->eob_run += stbi__jpeg_get_bits(j, r); + r = 64; // force end of block + } else { + // r=15 s=0 should write 16 0s, so we just do + // a run of 15 0s and then write s (which is 0), + // so we don't have to do anything special here + } + } else { + if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); + // sign bit + if (stbi__jpeg_get_bit(j)) + s = bit; + else + s = -bit; + } + + // advance by r + while (k <= j->spec_end) { + short *p = &data[stbi__jpeg_dezigzag[k++]]; + if (*p != 0) { + if (stbi__jpeg_get_bit(j)) + if ((*p & bit)==0) { + if (*p > 0) + *p += bit; + else + *p -= bit; + } + } else { + if (r == 0) { + *p = (short) s; + break; + } + --r; + } + } + } while (k <= j->spec_end); + } + } + return 1; +} + +// take a -128..127 value and stbi__clamp it and convert to 0..255 +stbi_inline static stbi_uc stbi__clamp(int x) +{ + // trick to use a single test to catch both cases + if ((unsigned int) x > 255) { + if (x < 0) return 0; + if (x > 255) return 255; + } + return (stbi_uc) x; +} + +#define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) +#define stbi__fsh(x) ((x) * 4096) + +// derived from jidctint -- DCT_ISLOW +#define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ + int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ + p2 = s2; \ + p3 = s6; \ + p1 = (p2+p3) * stbi__f2f(0.5411961f); \ + t2 = p1 + p3*stbi__f2f(-1.847759065f); \ + t3 = p1 + p2*stbi__f2f( 0.765366865f); \ + p2 = s0; \ + p3 = s4; \ + t0 = stbi__fsh(p2+p3); \ + t1 = stbi__fsh(p2-p3); \ + x0 = t0+t3; \ + x3 = t0-t3; \ + x1 = t1+t2; \ + x2 = t1-t2; \ + t0 = s7; \ + t1 = s5; \ + t2 = s3; \ + t3 = s1; \ + p3 = t0+t2; \ + p4 = t1+t3; \ + p1 = t0+t3; \ + p2 = t1+t2; \ + p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ + t0 = t0*stbi__f2f( 0.298631336f); \ + t1 = t1*stbi__f2f( 2.053119869f); \ + t2 = t2*stbi__f2f( 3.072711026f); \ + t3 = t3*stbi__f2f( 1.501321110f); \ + p1 = p5 + p1*stbi__f2f(-0.899976223f); \ + p2 = p5 + p2*stbi__f2f(-2.562915447f); \ + p3 = p3*stbi__f2f(-1.961570560f); \ + p4 = p4*stbi__f2f(-0.390180644f); \ + t3 += p1+p4; \ + t2 += p2+p3; \ + t1 += p2+p4; \ + t0 += p1+p3; + +static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64]) +{ + int i,val[64],*v=val; + stbi_uc *o; + short *d = data; + + // columns + for (i=0; i < 8; ++i,++d, ++v) { + // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing + if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 + && d[40]==0 && d[48]==0 && d[56]==0) { + // no shortcut 0 seconds + // (1|2|3|4|5|6|7)==0 0 seconds + // all separate -0.047 seconds + // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds + int dcterm = d[0]*4; + v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; + } else { + STBI__IDCT_1D(d[ 0],d[ 8],d[16],d[24],d[32],d[40],d[48],d[56]) + // constants scaled things up by 1<<12; let's bring them back + // down, but keep 2 extra bits of precision + x0 += 512; x1 += 512; x2 += 512; x3 += 512; + v[ 0] = (x0+t3) >> 10; + v[56] = (x0-t3) >> 10; + v[ 8] = (x1+t2) >> 10; + v[48] = (x1-t2) >> 10; + v[16] = (x2+t1) >> 10; + v[40] = (x2-t1) >> 10; + v[24] = (x3+t0) >> 10; + v[32] = (x3-t0) >> 10; + } + } + + for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { + // no fast case since the first 1D IDCT spread components out + STBI__IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) + // constants scaled things up by 1<<12, plus we had 1<<2 from first + // loop, plus horizontal and vertical each scale by sqrt(8) so together + // we've got an extra 1<<3, so 1<<17 total we need to remove. + // so we want to round that, which means adding 0.5 * 1<<17, + // aka 65536. Also, we'll end up with -128 to 127 that we want + // to encode as 0..255 by adding 128, so we'll add that before the shift + x0 += 65536 + (128<<17); + x1 += 65536 + (128<<17); + x2 += 65536 + (128<<17); + x3 += 65536 + (128<<17); + // tried computing the shifts into temps, or'ing the temps to see + // if any were out of range, but that was slower + o[0] = stbi__clamp((x0+t3) >> 17); + o[7] = stbi__clamp((x0-t3) >> 17); + o[1] = stbi__clamp((x1+t2) >> 17); + o[6] = stbi__clamp((x1-t2) >> 17); + o[2] = stbi__clamp((x2+t1) >> 17); + o[5] = stbi__clamp((x2-t1) >> 17); + o[3] = stbi__clamp((x3+t0) >> 17); + o[4] = stbi__clamp((x3-t0) >> 17); + } +} + +#ifdef STBI_SSE2 +// sse2 integer IDCT. not the fastest possible implementation but it +// produces bit-identical results to the generic C version so it's +// fully "transparent". +static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) +{ + // This is constructed to match our regular (generic) integer IDCT exactly. + __m128i row0, row1, row2, row3, row4, row5, row6, row7; + __m128i tmp; + + // dot product constant: even elems=x, odd elems=y + #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) + + // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) + // out(1) = c1[even]*x + c1[odd]*y + #define dct_rot(out0,out1, x,y,c0,c1) \ + __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ + __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ + __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ + __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ + __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ + __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) + + // out = in << 12 (in 16-bit, out 32-bit) + #define dct_widen(out, in) \ + __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ + __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) + + // wide add + #define dct_wadd(out, a, b) \ + __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_add_epi32(a##_h, b##_h) + + // wide sub + #define dct_wsub(out, a, b) \ + __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) + + // butterfly a/b, add bias, then shift by "s" and pack + #define dct_bfly32o(out0, out1, a,b,bias,s) \ + { \ + __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ + __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ + dct_wadd(sum, abiased, b); \ + dct_wsub(dif, abiased, b); \ + out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ + out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ + } + + // 8-bit interleave step (for transposes) + #define dct_interleave8(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi8(a, b); \ + b = _mm_unpackhi_epi8(tmp, b) + + // 16-bit interleave step (for transposes) + #define dct_interleave16(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi16(a, b); \ + b = _mm_unpackhi_epi16(tmp, b) + + #define dct_pass(bias,shift) \ + { \ + /* even part */ \ + dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ + __m128i sum04 = _mm_add_epi16(row0, row4); \ + __m128i dif04 = _mm_sub_epi16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ + dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ + __m128i sum17 = _mm_add_epi16(row1, row7); \ + __m128i sum35 = _mm_add_epi16(row3, row5); \ + dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ + dct_wadd(x4, y0o, y4o); \ + dct_wadd(x5, y1o, y5o); \ + dct_wadd(x6, y2o, y5o); \ + dct_wadd(x7, y3o, y4o); \ + dct_bfly32o(row0,row7, x0,x7,bias,shift); \ + dct_bfly32o(row1,row6, x1,x6,bias,shift); \ + dct_bfly32o(row2,row5, x2,x5,bias,shift); \ + dct_bfly32o(row3,row4, x3,x4,bias,shift); \ + } + + __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); + __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f( 0.765366865f), stbi__f2f(0.5411961f)); + __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); + __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); + __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f( 0.298631336f), stbi__f2f(-1.961570560f)); + __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f( 3.072711026f)); + __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f( 2.053119869f), stbi__f2f(-0.390180644f)); + __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f( 1.501321110f)); + + // rounding biases in column/row passes, see stbi__idct_block for explanation. + __m128i bias_0 = _mm_set1_epi32(512); + __m128i bias_1 = _mm_set1_epi32(65536 + (128<<17)); + + // load + row0 = _mm_load_si128((const __m128i *) (data + 0*8)); + row1 = _mm_load_si128((const __m128i *) (data + 1*8)); + row2 = _mm_load_si128((const __m128i *) (data + 2*8)); + row3 = _mm_load_si128((const __m128i *) (data + 3*8)); + row4 = _mm_load_si128((const __m128i *) (data + 4*8)); + row5 = _mm_load_si128((const __m128i *) (data + 5*8)); + row6 = _mm_load_si128((const __m128i *) (data + 6*8)); + row7 = _mm_load_si128((const __m128i *) (data + 7*8)); + + // column pass + dct_pass(bias_0, 10); + + { + // 16bit 8x8 transpose pass 1 + dct_interleave16(row0, row4); + dct_interleave16(row1, row5); + dct_interleave16(row2, row6); + dct_interleave16(row3, row7); + + // transpose pass 2 + dct_interleave16(row0, row2); + dct_interleave16(row1, row3); + dct_interleave16(row4, row6); + dct_interleave16(row5, row7); + + // transpose pass 3 + dct_interleave16(row0, row1); + dct_interleave16(row2, row3); + dct_interleave16(row4, row5); + dct_interleave16(row6, row7); + } + + // row pass + dct_pass(bias_1, 17); + + { + // pack + __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 + __m128i p1 = _mm_packus_epi16(row2, row3); + __m128i p2 = _mm_packus_epi16(row4, row5); + __m128i p3 = _mm_packus_epi16(row6, row7); + + // 8bit 8x8 transpose pass 1 + dct_interleave8(p0, p2); // a0e0a1e1... + dct_interleave8(p1, p3); // c0g0c1g1... + + // transpose pass 2 + dct_interleave8(p0, p1); // a0c0e0g0... + dct_interleave8(p2, p3); // b0d0f0h0... + + // transpose pass 3 + dct_interleave8(p0, p2); // a0b0c0d0... + dct_interleave8(p1, p3); // a4b4c4d4... + + // store + _mm_storel_epi64((__m128i *) out, p0); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p2); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p1); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p3); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p3, 0x4e)); + } + +#undef dct_const +#undef dct_rot +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_interleave8 +#undef dct_interleave16 +#undef dct_pass +} + +#endif // STBI_SSE2 + +#ifdef STBI_NEON + +// NEON integer IDCT. should produce bit-identical +// results to the generic C version. +static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) +{ + int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; + + int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); + int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); + int16x4_t rot0_2 = vdup_n_s16(stbi__f2f( 0.765366865f)); + int16x4_t rot1_0 = vdup_n_s16(stbi__f2f( 1.175875602f)); + int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); + int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); + int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); + int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); + int16x4_t rot3_0 = vdup_n_s16(stbi__f2f( 0.298631336f)); + int16x4_t rot3_1 = vdup_n_s16(stbi__f2f( 2.053119869f)); + int16x4_t rot3_2 = vdup_n_s16(stbi__f2f( 3.072711026f)); + int16x4_t rot3_3 = vdup_n_s16(stbi__f2f( 1.501321110f)); + +#define dct_long_mul(out, inq, coeff) \ + int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) + +#define dct_long_mac(out, acc, inq, coeff) \ + int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) + +#define dct_widen(out, inq) \ + int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ + int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) + +// wide add +#define dct_wadd(out, a, b) \ + int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vaddq_s32(a##_h, b##_h) + +// wide sub +#define dct_wsub(out, a, b) \ + int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vsubq_s32(a##_h, b##_h) + +// butterfly a/b, then shift using "shiftop" by "s" and pack +#define dct_bfly32o(out0,out1, a,b,shiftop,s) \ + { \ + dct_wadd(sum, a, b); \ + dct_wsub(dif, a, b); \ + out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ + out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ + } + +#define dct_pass(shiftop, shift) \ + { \ + /* even part */ \ + int16x8_t sum26 = vaddq_s16(row2, row6); \ + dct_long_mul(p1e, sum26, rot0_0); \ + dct_long_mac(t2e, p1e, row6, rot0_1); \ + dct_long_mac(t3e, p1e, row2, rot0_2); \ + int16x8_t sum04 = vaddq_s16(row0, row4); \ + int16x8_t dif04 = vsubq_s16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + int16x8_t sum15 = vaddq_s16(row1, row5); \ + int16x8_t sum17 = vaddq_s16(row1, row7); \ + int16x8_t sum35 = vaddq_s16(row3, row5); \ + int16x8_t sum37 = vaddq_s16(row3, row7); \ + int16x8_t sumodd = vaddq_s16(sum17, sum35); \ + dct_long_mul(p5o, sumodd, rot1_0); \ + dct_long_mac(p1o, p5o, sum17, rot1_1); \ + dct_long_mac(p2o, p5o, sum35, rot1_2); \ + dct_long_mul(p3o, sum37, rot2_0); \ + dct_long_mul(p4o, sum15, rot2_1); \ + dct_wadd(sump13o, p1o, p3o); \ + dct_wadd(sump24o, p2o, p4o); \ + dct_wadd(sump23o, p2o, p3o); \ + dct_wadd(sump14o, p1o, p4o); \ + dct_long_mac(x4, sump13o, row7, rot3_0); \ + dct_long_mac(x5, sump24o, row5, rot3_1); \ + dct_long_mac(x6, sump23o, row3, rot3_2); \ + dct_long_mac(x7, sump14o, row1, rot3_3); \ + dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ + dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ + dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ + dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ + } + + // load + row0 = vld1q_s16(data + 0*8); + row1 = vld1q_s16(data + 1*8); + row2 = vld1q_s16(data + 2*8); + row3 = vld1q_s16(data + 3*8); + row4 = vld1q_s16(data + 4*8); + row5 = vld1q_s16(data + 5*8); + row6 = vld1q_s16(data + 6*8); + row7 = vld1q_s16(data + 7*8); + + // add DC bias + row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); + + // column pass + dct_pass(vrshrn_n_s32, 10); + + // 16bit 8x8 transpose + { +// these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. +// whether compilers actually get this is another story, sadly. +#define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } +#define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } + + // pass 1 + dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 + dct_trn16(row2, row3); + dct_trn16(row4, row5); + dct_trn16(row6, row7); + + // pass 2 + dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 + dct_trn32(row1, row3); + dct_trn32(row4, row6); + dct_trn32(row5, row7); + + // pass 3 + dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 + dct_trn64(row1, row5); + dct_trn64(row2, row6); + dct_trn64(row3, row7); + +#undef dct_trn16 +#undef dct_trn32 +#undef dct_trn64 + } + + // row pass + // vrshrn_n_s32 only supports shifts up to 16, we need + // 17. so do a non-rounding shift of 16 first then follow + // up with a rounding shift by 1. + dct_pass(vshrn_n_s32, 16); + + { + // pack and round + uint8x8_t p0 = vqrshrun_n_s16(row0, 1); + uint8x8_t p1 = vqrshrun_n_s16(row1, 1); + uint8x8_t p2 = vqrshrun_n_s16(row2, 1); + uint8x8_t p3 = vqrshrun_n_s16(row3, 1); + uint8x8_t p4 = vqrshrun_n_s16(row4, 1); + uint8x8_t p5 = vqrshrun_n_s16(row5, 1); + uint8x8_t p6 = vqrshrun_n_s16(row6, 1); + uint8x8_t p7 = vqrshrun_n_s16(row7, 1); + + // again, these can translate into one instruction, but often don't. +#define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } +#define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } + + // sadly can't use interleaved stores here since we only write + // 8 bytes to each scan line! + + // 8x8 8-bit transpose pass 1 + dct_trn8_8(p0, p1); + dct_trn8_8(p2, p3); + dct_trn8_8(p4, p5); + dct_trn8_8(p6, p7); + + // pass 2 + dct_trn8_16(p0, p2); + dct_trn8_16(p1, p3); + dct_trn8_16(p4, p6); + dct_trn8_16(p5, p7); + + // pass 3 + dct_trn8_32(p0, p4); + dct_trn8_32(p1, p5); + dct_trn8_32(p2, p6); + dct_trn8_32(p3, p7); + + // store + vst1_u8(out, p0); out += out_stride; + vst1_u8(out, p1); out += out_stride; + vst1_u8(out, p2); out += out_stride; + vst1_u8(out, p3); out += out_stride; + vst1_u8(out, p4); out += out_stride; + vst1_u8(out, p5); out += out_stride; + vst1_u8(out, p6); out += out_stride; + vst1_u8(out, p7); + +#undef dct_trn8_8 +#undef dct_trn8_16 +#undef dct_trn8_32 + } + +#undef dct_long_mul +#undef dct_long_mac +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_pass +} + +#endif // STBI_NEON + +#define STBI__MARKER_none 0xff +// if there's a pending marker from the entropy stream, return that +// otherwise, fetch from the stream and get a marker. if there's no +// marker, return 0xff, which is never a valid marker value +static stbi_uc stbi__get_marker(stbi__jpeg *j) +{ + stbi_uc x; + if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } + x = stbi__get8(j->s); + if (x != 0xff) return STBI__MARKER_none; + while (x == 0xff) + x = stbi__get8(j->s); // consume repeated 0xff fill bytes + return x; +} + +// in each scan, we'll have scan_n components, and the order +// of the components is specified by order[] +#define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) + +// after a restart interval, stbi__jpeg_reset the entropy decoder and +// the dc prediction +static void stbi__jpeg_reset(stbi__jpeg *j) +{ + j->code_bits = 0; + j->code_buffer = 0; + j->nomore = 0; + j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; + j->marker = STBI__MARKER_none; + j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; + j->eob_run = 0; + // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, + // since we don't even allow 1<<30 pixels +} + +static int stbi__parse_entropy_coded_data(stbi__jpeg *z) +{ + stbi__jpeg_reset(z); + if (!z->progressive) { + if (z->scan_n == 1) { + int i,j; + STBI_SIMD_ALIGN(short, data[64]); + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + // if it's NOT a restart, then just bail, so we get corrupt data + // rather than no data + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } else { // interleaved + int i,j,k,x,y; + STBI_SIMD_ALIGN(short, data[64]); + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x)*8; + int y2 = (j*z->img_comp[n].v + y)*8; + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data); + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + } else { + if (z->scan_n == 1) { + int i,j; + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + if (z->spec_start == 0) { + if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } else { + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) + return 0; + } + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } else { // interleaved + int i,j,k,x,y; + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x); + int y2 = (j*z->img_comp[n].v + y); + short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); + if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + } +} + +static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant) +{ + int i; + for (i=0; i < 64; ++i) + data[i] *= dequant[i]; +} + +static void stbi__jpeg_finish(stbi__jpeg *z) +{ + if (z->progressive) { + // dequantize and idct the data + int i,j,n; + for (n=0; n < z->s->img_n; ++n) { + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + } + } + } + } +} + +static int stbi__process_marker(stbi__jpeg *z, int m) +{ + int L; + switch (m) { + case STBI__MARKER_none: // no marker found + return stbi__err("expected marker","Corrupt JPEG"); + + case 0xDD: // DRI - specify restart interval + if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len","Corrupt JPEG"); + z->restart_interval = stbi__get16be(z->s); + return 1; + + case 0xDB: // DQT - define quantization table + L = stbi__get16be(z->s)-2; + while (L > 0) { + int q = stbi__get8(z->s); + int p = q >> 4, sixteen = (p != 0); + int t = q & 15,i; + if (p != 0 && p != 1) return stbi__err("bad DQT type","Corrupt JPEG"); + if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG"); + + for (i=0; i < 64; ++i) + z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); + L -= (sixteen ? 129 : 65); + } + return L==0; + + case 0xC4: // DHT - define huffman table + L = stbi__get16be(z->s)-2; + while (L > 0) { + stbi_uc *v; + int sizes[16],i,n=0; + int q = stbi__get8(z->s); + int tc = q >> 4; + int th = q & 15; + if (tc > 1 || th > 3) return stbi__err("bad DHT header","Corrupt JPEG"); + for (i=0; i < 16; ++i) { + sizes[i] = stbi__get8(z->s); + n += sizes[i]; + } + L -= 17; + if (tc == 0) { + if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0; + v = z->huff_dc[th].values; + } else { + if (!stbi__build_huffman(z->huff_ac+th, sizes)) return 0; + v = z->huff_ac[th].values; + } + for (i=0; i < n; ++i) + v[i] = stbi__get8(z->s); + if (tc != 0) + stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); + L -= n; + } + return L==0; + } + + // check for comment block or APP blocks + if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { + L = stbi__get16be(z->s); + if (L < 2) { + if (m == 0xFE) + return stbi__err("bad COM len","Corrupt JPEG"); + else + return stbi__err("bad APP len","Corrupt JPEG"); + } + L -= 2; + + if (m == 0xE0 && L >= 5) { // JFIF APP0 segment + static const unsigned char tag[5] = {'J','F','I','F','\0'}; + int ok = 1; + int i; + for (i=0; i < 5; ++i) + if (stbi__get8(z->s) != tag[i]) + ok = 0; + L -= 5; + if (ok) + z->jfif = 1; + } else if (m == 0xEE && L >= 12) { // Adobe APP14 segment + static const unsigned char tag[6] = {'A','d','o','b','e','\0'}; + int ok = 1; + int i; + for (i=0; i < 6; ++i) + if (stbi__get8(z->s) != tag[i]) + ok = 0; + L -= 6; + if (ok) { + stbi__get8(z->s); // version + stbi__get16be(z->s); // flags0 + stbi__get16be(z->s); // flags1 + z->app14_color_transform = stbi__get8(z->s); // color transform + L -= 6; + } + } + + stbi__skip(z->s, L); + return 1; + } + + return stbi__err("unknown marker","Corrupt JPEG"); +} + +// after we see SOS +static int stbi__process_scan_header(stbi__jpeg *z) +{ + int i; + int Ls = stbi__get16be(z->s); + z->scan_n = stbi__get8(z->s); + if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return stbi__err("bad SOS component count","Corrupt JPEG"); + if (Ls != 6+2*z->scan_n) return stbi__err("bad SOS len","Corrupt JPEG"); + for (i=0; i < z->scan_n; ++i) { + int id = stbi__get8(z->s), which; + int q = stbi__get8(z->s); + for (which = 0; which < z->s->img_n; ++which) + if (z->img_comp[which].id == id) + break; + if (which == z->s->img_n) return 0; // no match + z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff","Corrupt JPEG"); + z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff","Corrupt JPEG"); + z->order[i] = which; + } + + { + int aa; + z->spec_start = stbi__get8(z->s); + z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 + aa = stbi__get8(z->s); + z->succ_high = (aa >> 4); + z->succ_low = (aa & 15); + if (z->progressive) { + if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) + return stbi__err("bad SOS", "Corrupt JPEG"); + } else { + if (z->spec_start != 0) return stbi__err("bad SOS","Corrupt JPEG"); + if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS","Corrupt JPEG"); + z->spec_end = 63; + } + } + + return 1; +} + +static int stbi__free_jpeg_components(stbi__jpeg *z, int ncomp, int why) +{ + int i; + for (i=0; i < ncomp; ++i) { + if (z->img_comp[i].raw_data) { + STBI_FREE(z->img_comp[i].raw_data); + z->img_comp[i].raw_data = NULL; + z->img_comp[i].data = NULL; + } + if (z->img_comp[i].raw_coeff) { + STBI_FREE(z->img_comp[i].raw_coeff); + z->img_comp[i].raw_coeff = 0; + z->img_comp[i].coeff = 0; + } + if (z->img_comp[i].linebuf) { + STBI_FREE(z->img_comp[i].linebuf); + z->img_comp[i].linebuf = NULL; + } + } + return why; +} + +static int stbi__process_frame_header(stbi__jpeg *z, int scan) +{ + stbi__context *s = z->s; + int Lf,p,i,q, h_max=1,v_max=1,c; + Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len","Corrupt JPEG"); // JPEG + p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline + s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG + s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires + c = stbi__get8(s); + if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG"); + s->img_n = c; + for (i=0; i < c; ++i) { + z->img_comp[i].data = NULL; + z->img_comp[i].linebuf = NULL; + } + + if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG"); + + z->rgb = 0; + for (i=0; i < s->img_n; ++i) { + static const unsigned char rgb[3] = { 'R', 'G', 'B' }; + z->img_comp[i].id = stbi__get8(s); + if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) + ++z->rgb; + q = stbi__get8(s); + z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG"); + z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG"); + z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ","Corrupt JPEG"); + } + + if (scan != STBI__SCAN_load) return 1; + + if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); + + for (i=0; i < s->img_n; ++i) { + if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; + if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; + } + + // compute interleaved mcu info + z->img_h_max = h_max; + z->img_v_max = v_max; + z->img_mcu_w = h_max * 8; + z->img_mcu_h = v_max * 8; + // these sizes can't be more than 17 bits + z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; + z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; + + for (i=0; i < s->img_n; ++i) { + // number of effective pixels (e.g. for non-interleaved MCU) + z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; + z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; + // to simplify generation, we'll allocate enough memory to decode + // the bogus oversized data from using interleaved MCUs and their + // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't + // discard the extra data until colorspace conversion + // + // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) + // so these muls can't overflow with 32-bit ints (which we require) + z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; + z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; + z->img_comp[i].coeff = 0; + z->img_comp[i].raw_coeff = 0; + z->img_comp[i].linebuf = NULL; + z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); + if (z->img_comp[i].raw_data == NULL) + return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); + // align blocks for idct using mmx/sse + z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); + if (z->progressive) { + // w2, h2 are multiples of 8 (see above) + z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; + z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; + z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); + if (z->img_comp[i].raw_coeff == NULL) + return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); + z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15); + } + } + + return 1; +} + +// use comparisons since in some cases we handle more than one case (e.g. SOF) +#define stbi__DNL(x) ((x) == 0xdc) +#define stbi__SOI(x) ((x) == 0xd8) +#define stbi__EOI(x) ((x) == 0xd9) +#define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) +#define stbi__SOS(x) ((x) == 0xda) + +#define stbi__SOF_progressive(x) ((x) == 0xc2) + +static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) +{ + int m; + z->jfif = 0; + z->app14_color_transform = -1; // valid values are 0,1,2 + z->marker = STBI__MARKER_none; // initialize cached marker to empty + m = stbi__get_marker(z); + if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG"); + if (scan == STBI__SCAN_type) return 1; + m = stbi__get_marker(z); + while (!stbi__SOF(m)) { + if (!stbi__process_marker(z,m)) return 0; + m = stbi__get_marker(z); + while (m == STBI__MARKER_none) { + // some files have extra padding after their blocks, so ok, we'll scan + if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); + m = stbi__get_marker(z); + } + } + z->progressive = stbi__SOF_progressive(m); + if (!stbi__process_frame_header(z, scan)) return 0; + return 1; +} + +// decode image to YCbCr format +static int stbi__decode_jpeg_image(stbi__jpeg *j) +{ + int m; + for (m = 0; m < 4; m++) { + j->img_comp[m].raw_data = NULL; + j->img_comp[m].raw_coeff = NULL; + } + j->restart_interval = 0; + if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; + m = stbi__get_marker(j); + while (!stbi__EOI(m)) { + if (stbi__SOS(m)) { + if (!stbi__process_scan_header(j)) return 0; + if (!stbi__parse_entropy_coded_data(j)) return 0; + if (j->marker == STBI__MARKER_none ) { + // handle 0s at the end of image data from IP Kamera 9060 + while (!stbi__at_eof(j->s)) { + int x = stbi__get8(j->s); + if (x == 255) { + j->marker = stbi__get8(j->s); + break; + } + } + // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 + } + } else if (stbi__DNL(m)) { + int Ld = stbi__get16be(j->s); + stbi__uint32 NL = stbi__get16be(j->s); + if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); + if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); + } else { + if (!stbi__process_marker(j, m)) return 0; + } + m = stbi__get_marker(j); + } + if (j->progressive) + stbi__jpeg_finish(j); + return 1; +} + +// static jfif-centered resampling (across block boundaries) + +typedef stbi_uc *(*resample_row_func)(stbi_uc *out, stbi_uc *in0, stbi_uc *in1, + int w, int hs); + +#define stbi__div4(x) ((stbi_uc) ((x) >> 2)) + +static stbi_uc *resample_row_1(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + STBI_NOTUSED(out); + STBI_NOTUSED(in_far); + STBI_NOTUSED(w); + STBI_NOTUSED(hs); + return in_near; +} + +static stbi_uc* stbi__resample_row_v_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate two samples vertically for every one in input + int i; + STBI_NOTUSED(hs); + for (i=0; i < w; ++i) + out[i] = stbi__div4(3*in_near[i] + in_far[i] + 2); + return out; +} + +static stbi_uc* stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate two samples horizontally for every one in input + int i; + stbi_uc *input = in_near; + + if (w == 1) { + // if only one sample, can't do any interpolation + out[0] = out[1] = input[0]; + return out; + } + + out[0] = input[0]; + out[1] = stbi__div4(input[0]*3 + input[1] + 2); + for (i=1; i < w-1; ++i) { + int n = 3*input[i]+2; + out[i*2+0] = stbi__div4(n+input[i-1]); + out[i*2+1] = stbi__div4(n+input[i+1]); + } + out[i*2+0] = stbi__div4(input[w-2]*3 + input[w-1] + 2); + out[i*2+1] = input[w-1]; + + STBI_NOTUSED(in_far); + STBI_NOTUSED(hs); + + return out; +} + +#define stbi__div16(x) ((stbi_uc) ((x) >> 4)) + +static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i,t0,t1; + if (w == 1) { + out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + out[0] = stbi__div4(t1+2); + for (i=1; i < w; ++i) { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = stbi__div16(3*t0 + t1 + 8); + out[i*2 ] = stbi__div16(3*t1 + t0 + 8); + } + out[w*2-1] = stbi__div4(t1+2); + + STBI_NOTUSED(hs); + + return out; +} + +#if defined(STBI_SSE2) || defined(STBI_NEON) +static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i=0,t0,t1; + + if (w == 1) { + out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + // process groups of 8 pixels for as long as we can. + // note we can't handle the last pixel in a row in this loop + // because we need to handle the filter boundary conditions. + for (; i < ((w-1) & ~7); i += 8) { +#if defined(STBI_SSE2) + // load and perform the vertical filtering pass + // this uses 3*x + y = 4*x + (y - x) + __m128i zero = _mm_setzero_si128(); + __m128i farb = _mm_loadl_epi64((__m128i *) (in_far + i)); + __m128i nearb = _mm_loadl_epi64((__m128i *) (in_near + i)); + __m128i farw = _mm_unpacklo_epi8(farb, zero); + __m128i nearw = _mm_unpacklo_epi8(nearb, zero); + __m128i diff = _mm_sub_epi16(farw, nearw); + __m128i nears = _mm_slli_epi16(nearw, 2); + __m128i curr = _mm_add_epi16(nears, diff); // current row + + // horizontal filter works the same based on shifted vers of current + // row. "prev" is current row shifted right by 1 pixel; we need to + // insert the previous pixel value (from t1). + // "next" is current row shifted left by 1 pixel, with first pixel + // of next block of 8 pixels added in. + __m128i prv0 = _mm_slli_si128(curr, 2); + __m128i nxt0 = _mm_srli_si128(curr, 2); + __m128i prev = _mm_insert_epi16(prv0, t1, 0); + __m128i next = _mm_insert_epi16(nxt0, 3*in_near[i+8] + in_far[i+8], 7); + + // horizontal filter, polyphase implementation since it's convenient: + // even pixels = 3*cur + prev = cur*4 + (prev - cur) + // odd pixels = 3*cur + next = cur*4 + (next - cur) + // note the shared term. + __m128i bias = _mm_set1_epi16(8); + __m128i curs = _mm_slli_epi16(curr, 2); + __m128i prvd = _mm_sub_epi16(prev, curr); + __m128i nxtd = _mm_sub_epi16(next, curr); + __m128i curb = _mm_add_epi16(curs, bias); + __m128i even = _mm_add_epi16(prvd, curb); + __m128i odd = _mm_add_epi16(nxtd, curb); + + // interleave even and odd pixels, then undo scaling. + __m128i int0 = _mm_unpacklo_epi16(even, odd); + __m128i int1 = _mm_unpackhi_epi16(even, odd); + __m128i de0 = _mm_srli_epi16(int0, 4); + __m128i de1 = _mm_srli_epi16(int1, 4); + + // pack and write output + __m128i outv = _mm_packus_epi16(de0, de1); + _mm_storeu_si128((__m128i *) (out + i*2), outv); +#elif defined(STBI_NEON) + // load and perform the vertical filtering pass + // this uses 3*x + y = 4*x + (y - x) + uint8x8_t farb = vld1_u8(in_far + i); + uint8x8_t nearb = vld1_u8(in_near + i); + int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); + int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); + int16x8_t curr = vaddq_s16(nears, diff); // current row + + // horizontal filter works the same based on shifted vers of current + // row. "prev" is current row shifted right by 1 pixel; we need to + // insert the previous pixel value (from t1). + // "next" is current row shifted left by 1 pixel, with first pixel + // of next block of 8 pixels added in. + int16x8_t prv0 = vextq_s16(curr, curr, 7); + int16x8_t nxt0 = vextq_s16(curr, curr, 1); + int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); + int16x8_t next = vsetq_lane_s16(3*in_near[i+8] + in_far[i+8], nxt0, 7); + + // horizontal filter, polyphase implementation since it's convenient: + // even pixels = 3*cur + prev = cur*4 + (prev - cur) + // odd pixels = 3*cur + next = cur*4 + (next - cur) + // note the shared term. + int16x8_t curs = vshlq_n_s16(curr, 2); + int16x8_t prvd = vsubq_s16(prev, curr); + int16x8_t nxtd = vsubq_s16(next, curr); + int16x8_t even = vaddq_s16(curs, prvd); + int16x8_t odd = vaddq_s16(curs, nxtd); + + // undo scaling and round, then store with even/odd phases interleaved + uint8x8x2_t o; + o.val[0] = vqrshrun_n_s16(even, 4); + o.val[1] = vqrshrun_n_s16(odd, 4); + vst2_u8(out + i*2, o); +#endif + + // "previous" value for next iter + t1 = 3*in_near[i+7] + in_far[i+7]; + } + + t0 = t1; + t1 = 3*in_near[i] + in_far[i]; + out[i*2] = stbi__div16(3*t1 + t0 + 8); + + for (++i; i < w; ++i) { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = stbi__div16(3*t0 + t1 + 8); + out[i*2 ] = stbi__div16(3*t1 + t0 + 8); + } + out[w*2-1] = stbi__div4(t1+2); + + STBI_NOTUSED(hs); + + return out; +} +#endif + +static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // resample with nearest-neighbor + int i,j; + STBI_NOTUSED(in_far); + for (i=0; i < w; ++i) + for (j=0; j < hs; ++j) + out[i*hs+j] = in_near[i]; + return out; +} + +// this is a reduced-precision calculation of YCbCr-to-RGB introduced +// to make sure the code produces the same results in both SIMD and scalar +#define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) +static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) +{ + int i; + for (i=0; i < count; ++i) { + int y_fixed = (y[i] << 20) + (1<<19); // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr* stbi__float2fixed(1.40200f); + g = y_fixed + (cr*-stbi__float2fixed(0.71414f)) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* stbi__float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} + +#if defined(STBI_SSE2) || defined(STBI_NEON) +static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step) +{ + int i = 0; + +#ifdef STBI_SSE2 + // step == 3 is pretty ugly on the final interleave, and i'm not convinced + // it's useful in practice (you wouldn't use it for textures, for example). + // so just accelerate step == 4 case. + if (step == 4) { + // this is a fairly straightforward implementation and not super-optimized. + __m128i signflip = _mm_set1_epi8(-0x80); + __m128i cr_const0 = _mm_set1_epi16( (short) ( 1.40200f*4096.0f+0.5f)); + __m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f)); + __m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f)); + __m128i cb_const1 = _mm_set1_epi16( (short) ( 1.77200f*4096.0f+0.5f)); + __m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128); + __m128i xw = _mm_set1_epi16(255); // alpha channel + + for (; i+7 < count; i += 8) { + // load + __m128i y_bytes = _mm_loadl_epi64((__m128i *) (y+i)); + __m128i cr_bytes = _mm_loadl_epi64((__m128i *) (pcr+i)); + __m128i cb_bytes = _mm_loadl_epi64((__m128i *) (pcb+i)); + __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 + __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 + + // unpack to short (and left-shift cr, cb by 8) + __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); + __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); + __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); + + // color transform + __m128i yws = _mm_srli_epi16(yw, 4); + __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); + __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); + __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); + __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); + __m128i rws = _mm_add_epi16(cr0, yws); + __m128i gwt = _mm_add_epi16(cb0, yws); + __m128i bws = _mm_add_epi16(yws, cb1); + __m128i gws = _mm_add_epi16(gwt, cr1); + + // descale + __m128i rw = _mm_srai_epi16(rws, 4); + __m128i bw = _mm_srai_epi16(bws, 4); + __m128i gw = _mm_srai_epi16(gws, 4); + + // back to byte, set up for transpose + __m128i brb = _mm_packus_epi16(rw, bw); + __m128i gxb = _mm_packus_epi16(gw, xw); + + // transpose to interleave channels + __m128i t0 = _mm_unpacklo_epi8(brb, gxb); + __m128i t1 = _mm_unpackhi_epi8(brb, gxb); + __m128i o0 = _mm_unpacklo_epi16(t0, t1); + __m128i o1 = _mm_unpackhi_epi16(t0, t1); + + // store + _mm_storeu_si128((__m128i *) (out + 0), o0); + _mm_storeu_si128((__m128i *) (out + 16), o1); + out += 32; + } + } +#endif + +#ifdef STBI_NEON + // in this version, step=3 support would be easy to add. but is there demand? + if (step == 4) { + // this is a fairly straightforward implementation and not super-optimized. + uint8x8_t signflip = vdup_n_u8(0x80); + int16x8_t cr_const0 = vdupq_n_s16( (short) ( 1.40200f*4096.0f+0.5f)); + int16x8_t cr_const1 = vdupq_n_s16( - (short) ( 0.71414f*4096.0f+0.5f)); + int16x8_t cb_const0 = vdupq_n_s16( - (short) ( 0.34414f*4096.0f+0.5f)); + int16x8_t cb_const1 = vdupq_n_s16( (short) ( 1.77200f*4096.0f+0.5f)); + + for (; i+7 < count; i += 8) { + // load + uint8x8_t y_bytes = vld1_u8(y + i); + uint8x8_t cr_bytes = vld1_u8(pcr + i); + uint8x8_t cb_bytes = vld1_u8(pcb + i); + int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); + int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); + + // expand to s16 + int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); + int16x8_t crw = vshll_n_s8(cr_biased, 7); + int16x8_t cbw = vshll_n_s8(cb_biased, 7); + + // color transform + int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); + int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); + int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); + int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); + int16x8_t rws = vaddq_s16(yws, cr0); + int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); + int16x8_t bws = vaddq_s16(yws, cb1); + + // undo scaling, round, convert to byte + uint8x8x4_t o; + o.val[0] = vqrshrun_n_s16(rws, 4); + o.val[1] = vqrshrun_n_s16(gws, 4); + o.val[2] = vqrshrun_n_s16(bws, 4); + o.val[3] = vdup_n_u8(255); + + // store, interleaving r/g/b/a + vst4_u8(out, o); + out += 8*4; + } + } +#endif + + for (; i < count; ++i) { + int y_fixed = (y[i] << 20) + (1<<19); // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr* stbi__float2fixed(1.40200f); + g = y_fixed + cr*-stbi__float2fixed(0.71414f) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* stbi__float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} +#endif + +// set up the kernels +static void stbi__setup_jpeg(stbi__jpeg *j) +{ + j->idct_block_kernel = stbi__idct_block; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; + +#ifdef STBI_SSE2 + if (stbi__sse2_available()) { + j->idct_block_kernel = stbi__idct_simd; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; + } +#endif + +#ifdef STBI_NEON + j->idct_block_kernel = stbi__idct_simd; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; +#endif +} + +// clean up the temporary component buffers +static void stbi__cleanup_jpeg(stbi__jpeg *j) +{ + stbi__free_jpeg_components(j, j->s->img_n, 0); +} + +typedef struct +{ + resample_row_func resample; + stbi_uc *line0,*line1; + int hs,vs; // expansion factor in each axis + int w_lores; // horizontal pixels pre-expansion + int ystep; // how far through vertical expansion we are + int ypos; // which pre-expansion row we're on +} stbi__resample; + +// fast 0..255 * 0..255 => 0..255 rounded multiplication +static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) +{ + unsigned int t = x*y + 128; + return (stbi_uc) ((t + (t >>8)) >> 8); +} + +static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) +{ + int n, decode_n, is_rgb; + z->s->img_n = 0; // make stbi__cleanup_jpeg safe + + // validate req_comp + if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); + + // load a jpeg image from whichever source, but leave in YCbCr format + if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } + + // determine actual number of components to generate + n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; + + is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); + + if (z->s->img_n == 3 && n < 3 && !is_rgb) + decode_n = 1; + else + decode_n = z->s->img_n; + + // resample and color-convert + { + int k; + unsigned int i,j; + stbi_uc *output; + stbi_uc *coutput[4]; + + stbi__resample res_comp[4]; + + for (k=0; k < decode_n; ++k) { + stbi__resample *r = &res_comp[k]; + + // allocate line buffer big enough for upsampling off the edges + // with upsample factor of 4 + z->img_comp[k].linebuf = (stbi_uc *) stbi__malloc(z->s->img_x + 3); + if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } + + r->hs = z->img_h_max / z->img_comp[k].h; + r->vs = z->img_v_max / z->img_comp[k].v; + r->ystep = r->vs >> 1; + r->w_lores = (z->s->img_x + r->hs-1) / r->hs; + r->ypos = 0; + r->line0 = r->line1 = z->img_comp[k].data; + + if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; + else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; + else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; + else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; + else r->resample = stbi__resample_row_generic; + } + + // can't error after this so, this is safe + output = (stbi_uc *) stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); + if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } + + // now go ahead and resample + for (j=0; j < z->s->img_y; ++j) { + stbi_uc *out = output + n * z->s->img_x * j; + for (k=0; k < decode_n; ++k) { + stbi__resample *r = &res_comp[k]; + int y_bot = r->ystep >= (r->vs >> 1); + coutput[k] = r->resample(z->img_comp[k].linebuf, + y_bot ? r->line1 : r->line0, + y_bot ? r->line0 : r->line1, + r->w_lores, r->hs); + if (++r->ystep >= r->vs) { + r->ystep = 0; + r->line0 = r->line1; + if (++r->ypos < z->img_comp[k].y) + r->line1 += z->img_comp[k].w2; + } + } + if (n >= 3) { + stbi_uc *y = coutput[0]; + if (z->s->img_n == 3) { + if (is_rgb) { + for (i=0; i < z->s->img_x; ++i) { + out[0] = y[i]; + out[1] = coutput[1][i]; + out[2] = coutput[2][i]; + out[3] = 255; + out += n; + } + } else { + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + } + } else if (z->s->img_n == 4) { + if (z->app14_color_transform == 0) { // CMYK + for (i=0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + out[0] = stbi__blinn_8x8(coutput[0][i], m); + out[1] = stbi__blinn_8x8(coutput[1][i], m); + out[2] = stbi__blinn_8x8(coutput[2][i], m); + out[3] = 255; + out += n; + } + } else if (z->app14_color_transform == 2) { // YCCK + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + for (i=0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + out[0] = stbi__blinn_8x8(255 - out[0], m); + out[1] = stbi__blinn_8x8(255 - out[1], m); + out[2] = stbi__blinn_8x8(255 - out[2], m); + out += n; + } + } else { // YCbCr + alpha? Ignore the fourth channel for now + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + } + } else + for (i=0; i < z->s->img_x; ++i) { + out[0] = out[1] = out[2] = y[i]; + out[3] = 255; // not used if n==3 + out += n; + } + } else { + if (is_rgb) { + if (n == 1) + for (i=0; i < z->s->img_x; ++i) + *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); + else { + for (i=0; i < z->s->img_x; ++i, out += 2) { + out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); + out[1] = 255; + } + } + } else if (z->s->img_n == 4 && z->app14_color_transform == 0) { + for (i=0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); + stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); + stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); + out[0] = stbi__compute_y(r, g, b); + out[1] = 255; + out += n; + } + } else if (z->s->img_n == 4 && z->app14_color_transform == 2) { + for (i=0; i < z->s->img_x; ++i) { + out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); + out[1] = 255; + out += n; + } + } else { + stbi_uc *y = coutput[0]; + if (n == 1) + for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; + else + for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255; + } + } + } + stbi__cleanup_jpeg(z); + *out_x = z->s->img_x; + *out_y = z->s->img_y; + if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output + return output; + } +} + +static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + unsigned char* result; + stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg)); + STBI_NOTUSED(ri); + j->s = s; + stbi__setup_jpeg(j); + result = load_jpeg_image(j, x,y,comp,req_comp); + STBI_FREE(j); + return result; +} + +static int stbi__jpeg_test(stbi__context *s) +{ + int r; + stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); + j->s = s; + stbi__setup_jpeg(j); + r = stbi__decode_jpeg_header(j, STBI__SCAN_type); + stbi__rewind(s); + STBI_FREE(j); + return r; +} + +static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp) +{ + if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { + stbi__rewind( j->s ); + return 0; + } + if (x) *x = j->s->img_x; + if (y) *y = j->s->img_y; + if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; + return 1; +} + +static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp) +{ + int result; + stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg))); + j->s = s; + result = stbi__jpeg_info_raw(j, x, y, comp); + STBI_FREE(j); + return result; +} +#endif + +// public domain zlib decode v0.2 Sean Barrett 2006-11-18 +// simple implementation +// - all input must be provided in an upfront buffer +// - all output is written to a single output buffer (can malloc/realloc) +// performance +// - fast huffman + +#ifndef STBI_NO_ZLIB + +// fast-way is faster to check than jpeg huffman, but slow way is slower +#define STBI__ZFAST_BITS 9 // accelerate all cases in default tables +#define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) + +// zlib-style huffman encoding +// (jpegs packs from left, zlib from right, so can't share code) +typedef struct +{ + stbi__uint16 fast[1 << STBI__ZFAST_BITS]; + stbi__uint16 firstcode[16]; + int maxcode[17]; + stbi__uint16 firstsymbol[16]; + stbi_uc size[288]; + stbi__uint16 value[288]; +} stbi__zhuffman; + +stbi_inline static int stbi__bitreverse16(int n) +{ + n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); + n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); + n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); + n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); + return n; +} + +stbi_inline static int stbi__bit_reverse(int v, int bits) +{ + STBI_ASSERT(bits <= 16); + // to bit reverse n bits, reverse 16 and shift + // e.g. 11 bits, bit reverse and shift away 5 + return stbi__bitreverse16(v) >> (16-bits); +} + +static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int num) +{ + int i,k=0; + int code, next_code[16], sizes[17]; + + // DEFLATE spec for generating codes + memset(sizes, 0, sizeof(sizes)); + memset(z->fast, 0, sizeof(z->fast)); + for (i=0; i < num; ++i) + ++sizes[sizelist[i]]; + sizes[0] = 0; + for (i=1; i < 16; ++i) + if (sizes[i] > (1 << i)) + return stbi__err("bad sizes", "Corrupt PNG"); + code = 0; + for (i=1; i < 16; ++i) { + next_code[i] = code; + z->firstcode[i] = (stbi__uint16) code; + z->firstsymbol[i] = (stbi__uint16) k; + code = (code + sizes[i]); + if (sizes[i]) + if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt PNG"); + z->maxcode[i] = code << (16-i); // preshift for inner loop + code <<= 1; + k += sizes[i]; + } + z->maxcode[16] = 0x10000; // sentinel + for (i=0; i < num; ++i) { + int s = sizelist[i]; + if (s) { + int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; + stbi__uint16 fastv = (stbi__uint16) ((s << 9) | i); + z->size [c] = (stbi_uc ) s; + z->value[c] = (stbi__uint16) i; + if (s <= STBI__ZFAST_BITS) { + int j = stbi__bit_reverse(next_code[s],s); + while (j < (1 << STBI__ZFAST_BITS)) { + z->fast[j] = fastv; + j += (1 << s); + } + } + ++next_code[s]; + } + } + return 1; +} + +// zlib-from-memory implementation for PNG reading +// because PNG allows splitting the zlib stream arbitrarily, +// and it's annoying structurally to have PNG call ZLIB call PNG, +// we require PNG read all the IDATs and combine them into a single +// memory buffer + +typedef struct +{ + stbi_uc *zbuffer, *zbuffer_end; + int num_bits; + stbi__uint32 code_buffer; + + char *zout; + char *zout_start; + char *zout_end; + int z_expandable; + + stbi__zhuffman z_length, z_distance; +} stbi__zbuf; + +stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z) +{ + if (z->zbuffer >= z->zbuffer_end) return 0; + return *z->zbuffer++; +} + +static void stbi__fill_bits(stbi__zbuf *z) +{ + do { + STBI_ASSERT(z->code_buffer < (1U << z->num_bits)); + z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits; + z->num_bits += 8; + } while (z->num_bits <= 24); +} + +stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n) +{ + unsigned int k; + if (z->num_bits < n) stbi__fill_bits(z); + k = z->code_buffer & ((1 << n) - 1); + z->code_buffer >>= n; + z->num_bits -= n; + return k; +} + +static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) +{ + int b,s,k; + // not resolved by fast table, so compute it the slow way + // use jpeg approach, which requires MSbits at top + k = stbi__bit_reverse(a->code_buffer, 16); + for (s=STBI__ZFAST_BITS+1; ; ++s) + if (k < z->maxcode[s]) + break; + if (s == 16) return -1; // invalid code! + // code size is s, so: + b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; + STBI_ASSERT(z->size[b] == s); + a->code_buffer >>= s; + a->num_bits -= s; + return z->value[b]; +} + +stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) +{ + int b,s; + if (a->num_bits < 16) stbi__fill_bits(a); + b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; + if (b) { + s = b >> 9; + a->code_buffer >>= s; + a->num_bits -= s; + return b & 511; + } + return stbi__zhuffman_decode_slowpath(a, z); +} + +static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes +{ + char *q; + int cur, limit, old_limit; + z->zout = zout; + if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG"); + cur = (int) (z->zout - z->zout_start); + limit = old_limit = (int) (z->zout_end - z->zout_start); + while (cur + n > limit) + limit *= 2; + q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); + STBI_NOTUSED(old_limit); + if (q == NULL) return stbi__err("outofmem", "Out of memory"); + z->zout_start = q; + z->zout = q + cur; + z->zout_end = q + limit; + return 1; +} + +static const int stbi__zlength_base[31] = { + 3,4,5,6,7,8,9,10,11,13, + 15,17,19,23,27,31,35,43,51,59, + 67,83,99,115,131,163,195,227,258,0,0 }; + +static const int stbi__zlength_extra[31]= +{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; + +static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, +257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; + +static const int stbi__zdist_extra[32] = +{ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +static int stbi__parse_huffman_block(stbi__zbuf *a) +{ + char *zout = a->zout; + for(;;) { + int z = stbi__zhuffman_decode(a, &a->z_length); + if (z < 256) { + if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); // error in huffman codes + if (zout >= a->zout_end) { + if (!stbi__zexpand(a, zout, 1)) return 0; + zout = a->zout; + } + *zout++ = (char) z; + } else { + stbi_uc *p; + int len,dist; + if (z == 256) { + a->zout = zout; + return 1; + } + z -= 257; + len = stbi__zlength_base[z]; + if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); + z = stbi__zhuffman_decode(a, &a->z_distance); + if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); + dist = stbi__zdist_base[z]; + if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); + if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG"); + if (zout + len > a->zout_end) { + if (!stbi__zexpand(a, zout, len)) return 0; + zout = a->zout; + } + p = (stbi_uc *) (zout - dist); + if (dist == 1) { // run of one byte; common in images. + stbi_uc v = *p; + if (len) { do *zout++ = v; while (--len); } + } else { + if (len) { do *zout++ = *p++; while (--len); } + } + } + } +} + +static int stbi__compute_huffman_codes(stbi__zbuf *a) +{ + static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; + stbi__zhuffman z_codelength; + stbi_uc lencodes[286+32+137];//padding for maximum single op + stbi_uc codelength_sizes[19]; + int i,n; + + int hlit = stbi__zreceive(a,5) + 257; + int hdist = stbi__zreceive(a,5) + 1; + int hclen = stbi__zreceive(a,4) + 4; + int ntot = hlit + hdist; + + memset(codelength_sizes, 0, sizeof(codelength_sizes)); + for (i=0; i < hclen; ++i) { + int s = stbi__zreceive(a,3); + codelength_sizes[length_dezigzag[i]] = (stbi_uc) s; + } + if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; + + n = 0; + while (n < ntot) { + int c = stbi__zhuffman_decode(a, &z_codelength); + if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); + if (c < 16) + lencodes[n++] = (stbi_uc) c; + else { + stbi_uc fill = 0; + if (c == 16) { + c = stbi__zreceive(a,2)+3; + if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); + fill = lencodes[n-1]; + } else if (c == 17) + c = stbi__zreceive(a,3)+3; + else { + STBI_ASSERT(c == 18); + c = stbi__zreceive(a,7)+11; + } + if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); + memset(lencodes+n, fill, c); + n += c; + } + } + if (n != ntot) return stbi__err("bad codelengths","Corrupt PNG"); + if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; + if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; + return 1; +} + +static int stbi__parse_uncompressed_block(stbi__zbuf *a) +{ + stbi_uc header[4]; + int len,nlen,k; + if (a->num_bits & 7) + stbi__zreceive(a, a->num_bits & 7); // discard + // drain the bit-packed data into header + k = 0; + while (a->num_bits > 0) { + header[k++] = (stbi_uc) (a->code_buffer & 255); // suppress MSVC run-time check + a->code_buffer >>= 8; + a->num_bits -= 8; + } + STBI_ASSERT(a->num_bits == 0); + // now fill header the normal way + while (k < 4) + header[k++] = stbi__zget8(a); + len = header[1] * 256 + header[0]; + nlen = header[3] * 256 + header[2]; + if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt","Corrupt PNG"); + if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer","Corrupt PNG"); + if (a->zout + len > a->zout_end) + if (!stbi__zexpand(a, a->zout, len)) return 0; + memcpy(a->zout, a->zbuffer, len); + a->zbuffer += len; + a->zout += len; + return 1; +} + +static int stbi__parse_zlib_header(stbi__zbuf *a) +{ + int cmf = stbi__zget8(a); + int cm = cmf & 15; + /* int cinfo = cmf >> 4; */ + int flg = stbi__zget8(a); + if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec + if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png + if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png + // window = 1 << (8 + cinfo)... but who cares, we fully buffer output + return 1; +} + +static const stbi_uc stbi__zdefault_length[288] = +{ + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 +}; +static const stbi_uc stbi__zdefault_distance[32] = +{ + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 +}; +/* +Init algorithm: +{ + int i; // use <= to match clearly with spec + for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; + for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; + for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; + for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; + + for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; +} +*/ + +static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) +{ + int final, type; + if (parse_header) + if (!stbi__parse_zlib_header(a)) return 0; + a->num_bits = 0; + a->code_buffer = 0; + do { + final = stbi__zreceive(a,1); + type = stbi__zreceive(a,2); + if (type == 0) { + if (!stbi__parse_uncompressed_block(a)) return 0; + } else if (type == 3) { + return 0; + } else { + if (type == 1) { + // use fixed code lengths + if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0; + if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; + } else { + if (!stbi__compute_huffman_codes(a)) return 0; + } + if (!stbi__parse_huffman_block(a)) return 0; + } + } while (!final); + return 1; +} + +static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse_header) +{ + a->zout_start = obuf; + a->zout = obuf; + a->zout_end = obuf + olen; + a->z_expandable = exp; + + return stbi__parse_zlib(a, parse_header); +} + +STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer + len; + if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) +{ + return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); +} + +STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer + len; + if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) +{ + stbi__zbuf a; + a.zbuffer = (stbi_uc *) ibuffer; + a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) + return (int) (a.zout - a.zout_start); + else + return -1; +} + +STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(16384); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer+len; + if (stbi__do_zlib(&a, p, 16384, 1, 0)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) +{ + stbi__zbuf a; + a.zbuffer = (stbi_uc *) ibuffer; + a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) + return (int) (a.zout - a.zout_start); + else + return -1; +} +#endif + +// public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 +// simple implementation +// - only 8-bit samples +// - no CRC checking +// - allocates lots of intermediate memory +// - avoids problem of streaming data between subsystems +// - avoids explicit window management +// performance +// - uses stb_zlib, a PD zlib implementation with fast huffman decoding + +#ifndef STBI_NO_PNG +typedef struct +{ + stbi__uint32 length; + stbi__uint32 type; +} stbi__pngchunk; + +static stbi__pngchunk stbi__get_chunk_header(stbi__context *s) +{ + stbi__pngchunk c; + c.length = stbi__get32be(s); + c.type = stbi__get32be(s); + return c; +} + +static int stbi__check_png_header(stbi__context *s) +{ + static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; + int i; + for (i=0; i < 8; ++i) + if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig","Not a PNG"); + return 1; +} + +typedef struct +{ + stbi__context *s; + stbi_uc *idata, *expanded, *out; + int depth; +} stbi__png; + + +enum { + STBI__F_none=0, + STBI__F_sub=1, + STBI__F_up=2, + STBI__F_avg=3, + STBI__F_paeth=4, + // synthetic filters used for first scanline to avoid needing a dummy row of 0s + STBI__F_avg_first, + STBI__F_paeth_first +}; + +static stbi_uc first_row_filter[5] = +{ + STBI__F_none, + STBI__F_sub, + STBI__F_none, + STBI__F_avg_first, + STBI__F_paeth_first +}; + +static int stbi__paeth(int a, int b, int c) +{ + int p = a + b - c; + int pa = abs(p-a); + int pb = abs(p-b); + int pc = abs(p-c); + if (pa <= pb && pa <= pc) return a; + if (pb <= pc) return b; + return c; +} + +static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; + +// create the png data from post-deflated data +static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) +{ + int bytes = (depth == 16? 2 : 1); + stbi__context *s = a->s; + stbi__uint32 i,j,stride = x*out_n*bytes; + stbi__uint32 img_len, img_width_bytes; + int k; + int img_n = s->img_n; // copy it into a local for later + + int output_bytes = out_n*bytes; + int filter_bytes = img_n*bytes; + int width = x; + + STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1); + a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into + if (!a->out) return stbi__err("outofmem", "Out of memory"); + + if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); + img_width_bytes = (((img_n * x * depth) + 7) >> 3); + img_len = (img_width_bytes + 1) * y; + + // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, + // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), + // so just check for raw_len < img_len always. + if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG"); + + for (j=0; j < y; ++j) { + stbi_uc *cur = a->out + stride*j; + stbi_uc *prior; + int filter = *raw++; + + if (filter > 4) + return stbi__err("invalid filter","Corrupt PNG"); + + if (depth < 8) { + STBI_ASSERT(img_width_bytes <= x); + cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place + filter_bytes = 1; + width = img_width_bytes; + } + prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above + + // if first row, use special filter that doesn't sample previous row + if (j == 0) filter = first_row_filter[filter]; + + // handle first byte explicitly + for (k=0; k < filter_bytes; ++k) { + switch (filter) { + case STBI__F_none : cur[k] = raw[k]; break; + case STBI__F_sub : cur[k] = raw[k]; break; + case STBI__F_up : cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; + case STBI__F_avg : cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); break; + case STBI__F_paeth : cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0,prior[k],0)); break; + case STBI__F_avg_first : cur[k] = raw[k]; break; + case STBI__F_paeth_first: cur[k] = raw[k]; break; + } + } + + if (depth == 8) { + if (img_n != out_n) + cur[img_n] = 255; // first pixel + raw += img_n; + cur += out_n; + prior += out_n; + } else if (depth == 16) { + if (img_n != out_n) { + cur[filter_bytes] = 255; // first pixel top byte + cur[filter_bytes+1] = 255; // first pixel bottom byte + } + raw += filter_bytes; + cur += output_bytes; + prior += output_bytes; + } else { + raw += 1; + cur += 1; + prior += 1; + } + + // this is a little gross, so that we don't switch per-pixel or per-component + if (depth < 8 || img_n == out_n) { + int nk = (width - 1)*filter_bytes; + #define STBI__CASE(f) \ + case f: \ + for (k=0; k < nk; ++k) + switch (filter) { + // "none" filter turns into a memcpy here; make that explicit. + case STBI__F_none: memcpy(cur, raw, nk); break; + STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); } break; + STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; + STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); } break; + STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); } break; + STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); } break; + STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); } break; + } + #undef STBI__CASE + raw += nk; + } else { + STBI_ASSERT(img_n+1 == out_n); + #define STBI__CASE(f) \ + case f: \ + for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ + for (k=0; k < filter_bytes; ++k) + switch (filter) { + STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; + STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); } break; + STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; + STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); } break; + STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); } break; + STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); } break; + STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); } break; + } + #undef STBI__CASE + + // the loop above sets the high byte of the pixels' alpha, but for + // 16 bit png files we also need the low byte set. we'll do that here. + if (depth == 16) { + cur = a->out + stride*j; // start at the beginning of the row again + for (i=0; i < x; ++i,cur+=output_bytes) { + cur[filter_bytes+1] = 255; + } + } + } + } + + // we make a separate pass to expand bits to pixels; for performance, + // this could run two scanlines behind the above code, so it won't + // intefere with filtering but will still be in the cache. + if (depth < 8) { + for (j=0; j < y; ++j) { + stbi_uc *cur = a->out + stride*j; + stbi_uc *in = a->out + stride*j + x*out_n - img_width_bytes; + // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit + // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop + stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range + + // note that the final byte might overshoot and write more data than desired. + // we can allocate enough data that this never writes out of memory, but it + // could also overwrite the next scanline. can it overwrite non-empty data + // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. + // so we need to explicitly clamp the final ones + + if (depth == 4) { + for (k=x*img_n; k >= 2; k-=2, ++in) { + *cur++ = scale * ((*in >> 4) ); + *cur++ = scale * ((*in ) & 0x0f); + } + if (k > 0) *cur++ = scale * ((*in >> 4) ); + } else if (depth == 2) { + for (k=x*img_n; k >= 4; k-=4, ++in) { + *cur++ = scale * ((*in >> 6) ); + *cur++ = scale * ((*in >> 4) & 0x03); + *cur++ = scale * ((*in >> 2) & 0x03); + *cur++ = scale * ((*in ) & 0x03); + } + if (k > 0) *cur++ = scale * ((*in >> 6) ); + if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); + if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); + } else if (depth == 1) { + for (k=x*img_n; k >= 8; k-=8, ++in) { + *cur++ = scale * ((*in >> 7) ); + *cur++ = scale * ((*in >> 6) & 0x01); + *cur++ = scale * ((*in >> 5) & 0x01); + *cur++ = scale * ((*in >> 4) & 0x01); + *cur++ = scale * ((*in >> 3) & 0x01); + *cur++ = scale * ((*in >> 2) & 0x01); + *cur++ = scale * ((*in >> 1) & 0x01); + *cur++ = scale * ((*in ) & 0x01); + } + if (k > 0) *cur++ = scale * ((*in >> 7) ); + if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); + if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); + if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); + if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); + if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); + if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); + } + if (img_n != out_n) { + int q; + // insert alpha = 255 + cur = a->out + stride*j; + if (img_n == 1) { + for (q=x-1; q >= 0; --q) { + cur[q*2+1] = 255; + cur[q*2+0] = cur[q]; + } + } else { + STBI_ASSERT(img_n == 3); + for (q=x-1; q >= 0; --q) { + cur[q*4+3] = 255; + cur[q*4+2] = cur[q*3+2]; + cur[q*4+1] = cur[q*3+1]; + cur[q*4+0] = cur[q*3+0]; + } + } + } + } + } else if (depth == 16) { + // force the image data from big-endian to platform-native. + // this is done in a separate pass due to the decoding relying + // on the data being untouched, but could probably be done + // per-line during decode if care is taken. + stbi_uc *cur = a->out; + stbi__uint16 *cur16 = (stbi__uint16*)cur; + + for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) { + *cur16 = (cur[0] << 8) | cur[1]; + } + } + + return 1; +} + +static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) +{ + int bytes = (depth == 16 ? 2 : 1); + int out_bytes = out_n * bytes; + stbi_uc *final; + int p; + if (!interlaced) + return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); + + // de-interlacing + final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); + for (p=0; p < 7; ++p) { + int xorig[] = { 0,4,0,2,0,1,0 }; + int yorig[] = { 0,0,4,0,2,0,1 }; + int xspc[] = { 8,8,4,4,2,2,1 }; + int yspc[] = { 8,8,8,4,4,2,2 }; + int i,j,x,y; + // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 + x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p]; + y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p]; + if (x && y) { + stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; + if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { + STBI_FREE(final); + return 0; + } + for (j=0; j < y; ++j) { + for (i=0; i < x; ++i) { + int out_y = j*yspc[p]+yorig[p]; + int out_x = i*xspc[p]+xorig[p]; + memcpy(final + out_y*a->s->img_x*out_bytes + out_x*out_bytes, + a->out + (j*x+i)*out_bytes, out_bytes); + } + } + STBI_FREE(a->out); + image_data += img_len; + image_data_len -= img_len; + } + } + a->out = final; + + return 1; +} + +static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi_uc *p = z->out; + + // compute color-based transparency, assuming we've + // already got 255 as the alpha value in the output + STBI_ASSERT(out_n == 2 || out_n == 4); + + if (out_n == 2) { + for (i=0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 255); + p += 2; + } + } else { + for (i=0; i < pixel_count; ++i) { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi__uint16 *p = (stbi__uint16*) z->out; + + // compute color-based transparency, assuming we've + // already got 65535 as the alpha value in the output + STBI_ASSERT(out_n == 2 || out_n == 4); + + if (out_n == 2) { + for (i = 0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 65535); + p += 2; + } + } else { + for (i = 0; i < pixel_count; ++i) { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n) +{ + stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; + stbi_uc *p, *temp_out, *orig = a->out; + + p = (stbi_uc *) stbi__malloc_mad2(pixel_count, pal_img_n, 0); + if (p == NULL) return stbi__err("outofmem", "Out of memory"); + + // between here and free(out) below, exitting would leak + temp_out = p; + + if (pal_img_n == 3) { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p += 3; + } + } else { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p[3] = palette[n+3]; + p += 4; + } + } + STBI_FREE(a->out); + a->out = temp_out; + + STBI_NOTUSED(len); + + return 1; +} + +static int stbi__unpremultiply_on_load = 0; +static int stbi__de_iphone_flag = 0; + +STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) +{ + stbi__unpremultiply_on_load = flag_true_if_should_unpremultiply; +} + +STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) +{ + stbi__de_iphone_flag = flag_true_if_should_convert; +} + +static void stbi__de_iphone(stbi__png *z) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi_uc *p = z->out; + + if (s->img_out_n == 3) { // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + stbi_uc t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 3; + } + } else { + STBI_ASSERT(s->img_out_n == 4); + if (stbi__unpremultiply_on_load) { + // convert bgr to rgb and unpremultiply + for (i=0; i < pixel_count; ++i) { + stbi_uc a = p[3]; + stbi_uc t = p[0]; + if (a) { + stbi_uc half = a / 2; + p[0] = (p[2] * 255 + half) / a; + p[1] = (p[1] * 255 + half) / a; + p[2] = ( t * 255 + half) / a; + } else { + p[0] = p[2]; + p[2] = t; + } + p += 4; + } + } else { + // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + stbi_uc t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 4; + } + } + } +} + +#define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) + +static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) +{ + stbi_uc palette[1024], pal_img_n=0; + stbi_uc has_trans=0, tc[3]; + stbi__uint16 tc16[3]; + stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0; + int first=1,k,interlace=0, color=0, is_iphone=0; + stbi__context *s = z->s; + + z->expanded = NULL; + z->idata = NULL; + z->out = NULL; + + if (!stbi__check_png_header(s)) return 0; + + if (scan == STBI__SCAN_type) return 1; + + for (;;) { + stbi__pngchunk c = stbi__get_chunk_header(s); + switch (c.type) { + case STBI__PNG_TYPE('C','g','B','I'): + is_iphone = 1; + stbi__skip(s, c.length); + break; + case STBI__PNG_TYPE('I','H','D','R'): { + int comp,filter; + if (!first) return stbi__err("multiple IHDR","Corrupt PNG"); + first = 0; + if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG"); + s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)"); + s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)"); + z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only"); + color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG"); + if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG"); + if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG"); + comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG"); + filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG"); + interlace = stbi__get8(s); if (interlace>1) return stbi__err("bad interlace method","Corrupt PNG"); + if (!s->img_x || !s->img_y) return stbi__err("0-pixel image","Corrupt PNG"); + if (!pal_img_n) { + s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); + if (scan == STBI__SCAN_header) return 1; + } else { + // if paletted, then pal_n is our final components, and + // img_n is # components to decompress/filter. + s->img_n = 1; + if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG"); + // if SCAN_header, have to scan to see if we have a tRNS + } + break; + } + + case STBI__PNG_TYPE('P','L','T','E'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (c.length > 256*3) return stbi__err("invalid PLTE","Corrupt PNG"); + pal_len = c.length / 3; + if (pal_len * 3 != c.length) return stbi__err("invalid PLTE","Corrupt PNG"); + for (i=0; i < pal_len; ++i) { + palette[i*4+0] = stbi__get8(s); + palette[i*4+1] = stbi__get8(s); + palette[i*4+2] = stbi__get8(s); + palette[i*4+3] = 255; + } + break; + } + + case STBI__PNG_TYPE('t','R','N','S'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (z->idata) return stbi__err("tRNS after IDAT","Corrupt PNG"); + if (pal_img_n) { + if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } + if (pal_len == 0) return stbi__err("tRNS before PLTE","Corrupt PNG"); + if (c.length > pal_len) return stbi__err("bad tRNS len","Corrupt PNG"); + pal_img_n = 4; + for (i=0; i < c.length; ++i) + palette[i*4+3] = stbi__get8(s); + } else { + if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG"); + if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG"); + has_trans = 1; + if (z->depth == 16) { + for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is + } else { + for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger + } + } + break; + } + + case STBI__PNG_TYPE('I','D','A','T'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG"); + if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; } + if ((int)(ioff + c.length) < (int)ioff) return 0; + if (ioff + c.length > idata_limit) { + stbi__uint32 idata_limit_old = idata_limit; + stbi_uc *p; + if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; + while (ioff + c.length > idata_limit) + idata_limit *= 2; + STBI_NOTUSED(idata_limit_old); + p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); + z->idata = p; + } + if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG"); + ioff += c.length; + break; + } + + case STBI__PNG_TYPE('I','E','N','D'): { + stbi__uint32 raw_len, bpl; + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (scan != STBI__SCAN_load) return 1; + if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG"); + // initial guess for decoded data size to avoid unnecessary reallocs + bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component + raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; + z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone); + if (z->expanded == NULL) return 0; // zlib should set error + STBI_FREE(z->idata); z->idata = NULL; + if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) + s->img_out_n = s->img_n+1; + else + s->img_out_n = s->img_n; + if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; + if (has_trans) { + if (z->depth == 16) { + if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; + } else { + if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; + } + } + if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) + stbi__de_iphone(z); + if (pal_img_n) { + // pal_img_n == 3 or 4 + s->img_n = pal_img_n; // record the actual colors we had + s->img_out_n = pal_img_n; + if (req_comp >= 3) s->img_out_n = req_comp; + if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) + return 0; + } else if (has_trans) { + // non-paletted image with tRNS -> source image has (constant) alpha + ++s->img_n; + } + STBI_FREE(z->expanded); z->expanded = NULL; + return 1; + } + + default: + // if critical, fail + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if ((c.type & (1 << 29)) == 0) { + #ifndef STBI_NO_FAILURE_STRINGS + // not threadsafe + static char invalid_chunk[] = "XXXX PNG chunk not known"; + invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); + invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); + invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); + invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); + #endif + return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); + } + stbi__skip(s, c.length); + break; + } + // end of PNG chunk, read and skip CRC + stbi__get32be(s); + } +} + +static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri) +{ + void *result=NULL; + if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); + if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { + if (p->depth < 8) + ri->bits_per_channel = 8; + else + ri->bits_per_channel = p->depth; + result = p->out; + p->out = NULL; + if (req_comp && req_comp != p->s->img_out_n) { + if (ri->bits_per_channel == 8) + result = stbi__convert_format((unsigned char *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + else + result = stbi__convert_format16((stbi__uint16 *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + p->s->img_out_n = req_comp; + if (result == NULL) return result; + } + *x = p->s->img_x; + *y = p->s->img_y; + if (n) *n = p->s->img_n; + } + STBI_FREE(p->out); p->out = NULL; + STBI_FREE(p->expanded); p->expanded = NULL; + STBI_FREE(p->idata); p->idata = NULL; + + return result; +} + +static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi__png p; + p.s = s; + return stbi__do_png(&p, x,y,comp,req_comp, ri); +} + +static int stbi__png_test(stbi__context *s) +{ + int r; + r = stbi__check_png_header(s); + stbi__rewind(s); + return r; +} + +static int stbi__png_info_raw(stbi__png *p, int *x, int *y, int *comp) +{ + if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { + stbi__rewind( p->s ); + return 0; + } + if (x) *x = p->s->img_x; + if (y) *y = p->s->img_y; + if (comp) *comp = p->s->img_n; + return 1; +} + +static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp) +{ + stbi__png p; + p.s = s; + return stbi__png_info_raw(&p, x, y, comp); +} + +static int stbi__png_is16(stbi__context *s) +{ + stbi__png p; + p.s = s; + if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) + return 0; + if (p.depth != 16) { + stbi__rewind(p.s); + return 0; + } + return 1; +} +#endif + +// Microsoft/Windows BMP image + +#ifndef STBI_NO_BMP +static int stbi__bmp_test_raw(stbi__context *s) +{ + int r; + int sz; + if (stbi__get8(s) != 'B') return 0; + if (stbi__get8(s) != 'M') return 0; + stbi__get32le(s); // discard filesize + stbi__get16le(s); // discard reserved + stbi__get16le(s); // discard reserved + stbi__get32le(s); // discard data offset + sz = stbi__get32le(s); + r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); + return r; +} + +static int stbi__bmp_test(stbi__context *s) +{ + int r = stbi__bmp_test_raw(s); + stbi__rewind(s); + return r; +} + + +// returns 0..31 for the highest set bit +static int stbi__high_bit(unsigned int z) +{ + int n=0; + if (z == 0) return -1; + if (z >= 0x10000) n += 16, z >>= 16; + if (z >= 0x00100) n += 8, z >>= 8; + if (z >= 0x00010) n += 4, z >>= 4; + if (z >= 0x00004) n += 2, z >>= 2; + if (z >= 0x00002) n += 1, z >>= 1; + return n; +} + +static int stbi__bitcount(unsigned int a) +{ + a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 + a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits + a = (a + (a >> 8)); // max 16 per 8 bits + a = (a + (a >> 16)); // max 32 per 8 bits + return a & 0xff; +} + +// extract an arbitrarily-aligned N-bit value (N=bits) +// from v, and then make it 8-bits long and fractionally +// extend it to full full range. +static int stbi__shiftsigned(int v, int shift, int bits) +{ + static unsigned int mul_table[9] = { + 0, + 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, + 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, + }; + static unsigned int shift_table[9] = { + 0, 0,0,1,0,2,4,6,0, + }; + if (shift < 0) + v <<= -shift; + else + v >>= shift; + STBI_ASSERT(v >= 0 && v < 256); + v >>= (8-bits); + STBI_ASSERT(bits >= 0 && bits <= 8); + return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits]; +} + +typedef struct +{ + int bpp, offset, hsz; + unsigned int mr,mg,mb,ma, all_a; +} stbi__bmp_data; + +static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) +{ + int hsz; + if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); + stbi__get32le(s); // discard filesize + stbi__get16le(s); // discard reserved + stbi__get16le(s); // discard reserved + info->offset = stbi__get32le(s); + info->hsz = hsz = stbi__get32le(s); + info->mr = info->mg = info->mb = info->ma = 0; + + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); + if (hsz == 12) { + s->img_x = stbi__get16le(s); + s->img_y = stbi__get16le(s); + } else { + s->img_x = stbi__get32le(s); + s->img_y = stbi__get32le(s); + } + if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); + info->bpp = stbi__get16le(s); + if (hsz != 12) { + int compress = stbi__get32le(s); + if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); + stbi__get32le(s); // discard sizeof + stbi__get32le(s); // discard hres + stbi__get32le(s); // discard vres + stbi__get32le(s); // discard colorsused + stbi__get32le(s); // discard max important + if (hsz == 40 || hsz == 56) { + if (hsz == 56) { + stbi__get32le(s); + stbi__get32le(s); + stbi__get32le(s); + stbi__get32le(s); + } + if (info->bpp == 16 || info->bpp == 32) { + if (compress == 0) { + if (info->bpp == 32) { + info->mr = 0xffu << 16; + info->mg = 0xffu << 8; + info->mb = 0xffu << 0; + info->ma = 0xffu << 24; + info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 + } else { + info->mr = 31u << 10; + info->mg = 31u << 5; + info->mb = 31u << 0; + } + } else if (compress == 3) { + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); + // not documented, but generated by photoshop and handled by mspaint + if (info->mr == info->mg && info->mg == info->mb) { + // ?!?!? + return stbi__errpuc("bad BMP", "bad BMP"); + } + } else + return stbi__errpuc("bad BMP", "bad BMP"); + } + } else { + int i; + if (hsz != 108 && hsz != 124) + return stbi__errpuc("bad BMP", "bad BMP"); + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); + info->ma = stbi__get32le(s); + stbi__get32le(s); // discard color space + for (i=0; i < 12; ++i) + stbi__get32le(s); // discard color space parameters + if (hsz == 124) { + stbi__get32le(s); // discard rendering intent + stbi__get32le(s); // discard offset of profile data + stbi__get32le(s); // discard size of profile data + stbi__get32le(s); // discard reserved + } + } + } + return (void *) 1; +} + + +static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi_uc *out; + unsigned int mr=0,mg=0,mb=0,ma=0, all_a; + stbi_uc pal[256][4]; + int psize=0,i,j,width; + int flip_vertically, pad, target; + stbi__bmp_data info; + STBI_NOTUSED(ri); + + info.all_a = 255; + if (stbi__bmp_parse_header(s, &info) == NULL) + return NULL; // error code already set + + flip_vertically = ((int) s->img_y) > 0; + s->img_y = abs((int) s->img_y); + + mr = info.mr; + mg = info.mg; + mb = info.mb; + ma = info.ma; + all_a = info.all_a; + + if (info.hsz == 12) { + if (info.bpp < 24) + psize = (info.offset - 14 - 24) / 3; + } else { + if (info.bpp < 16) + psize = (info.offset - 14 - info.hsz) >> 2; + } + + s->img_n = ma ? 4 : 3; + if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 + target = req_comp; + else + target = s->img_n; // if they want monochrome, we'll post-convert + + // sanity-check size + if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) + return stbi__errpuc("too large", "Corrupt BMP"); + + out = (stbi_uc *) stbi__malloc_mad3(target, s->img_x, s->img_y, 0); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + if (info.bpp < 16) { + int z=0; + if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } + for (i=0; i < psize; ++i) { + pal[i][2] = stbi__get8(s); + pal[i][1] = stbi__get8(s); + pal[i][0] = stbi__get8(s); + if (info.hsz != 12) stbi__get8(s); + pal[i][3] = 255; + } + stbi__skip(s, info.offset - 14 - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); + if (info.bpp == 1) width = (s->img_x + 7) >> 3; + else if (info.bpp == 4) width = (s->img_x + 1) >> 1; + else if (info.bpp == 8) width = s->img_x; + else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } + pad = (-width)&3; + if (info.bpp == 1) { + for (j=0; j < (int) s->img_y; ++j) { + int bit_offset = 7, v = stbi__get8(s); + for (i=0; i < (int) s->img_x; ++i) { + int color = (v>>bit_offset)&0x1; + out[z++] = pal[color][0]; + out[z++] = pal[color][1]; + out[z++] = pal[color][2]; + if((--bit_offset) < 0) { + bit_offset = 7; + v = stbi__get8(s); + } + } + stbi__skip(s, pad); + } + } else { + for (j=0; j < (int) s->img_y; ++j) { + for (i=0; i < (int) s->img_x; i += 2) { + int v=stbi__get8(s),v2=0; + if (info.bpp == 4) { + v2 = v & 15; + v >>= 4; + } + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + if (i+1 == (int) s->img_x) break; + v = (info.bpp == 8) ? stbi__get8(s) : v2; + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + } + stbi__skip(s, pad); + } + } + } else { + int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; + int z = 0; + int easy=0; + stbi__skip(s, info.offset - 14 - info.hsz); + if (info.bpp == 24) width = 3 * s->img_x; + else if (info.bpp == 16) width = 2*s->img_x; + else /* bpp = 32 and pad = 0 */ width=0; + pad = (-width) & 3; + if (info.bpp == 24) { + easy = 1; + } else if (info.bpp == 32) { + if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) + easy = 2; + } + if (!easy) { + if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } + // right shift amt to put high bit in position #7 + rshift = stbi__high_bit(mr)-7; rcount = stbi__bitcount(mr); + gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg); + bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb); + ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma); + } + for (j=0; j < (int) s->img_y; ++j) { + if (easy) { + for (i=0; i < (int) s->img_x; ++i) { + unsigned char a; + out[z+2] = stbi__get8(s); + out[z+1] = stbi__get8(s); + out[z+0] = stbi__get8(s); + z += 3; + a = (easy == 2 ? stbi__get8(s) : 255); + all_a |= a; + if (target == 4) out[z++] = a; + } + } else { + int bpp = info.bpp; + for (i=0; i < (int) s->img_x; ++i) { + stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s)); + unsigned int a; + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); + a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); + all_a |= a; + if (target == 4) out[z++] = STBI__BYTECAST(a); + } + } + stbi__skip(s, pad); + } + } + + // if alpha channel is all 0s, replace with all 255s + if (target == 4 && all_a == 0) + for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4) + out[i] = 255; + + if (flip_vertically) { + stbi_uc t; + for (j=0; j < (int) s->img_y>>1; ++j) { + stbi_uc *p1 = out + j *s->img_x*target; + stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; + for (i=0; i < (int) s->img_x*target; ++i) { + t = p1[i], p1[i] = p2[i], p2[i] = t; + } + } + } + + if (req_comp && req_comp != target) { + out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + + *x = s->img_x; + *y = s->img_y; + if (comp) *comp = s->img_n; + return out; +} +#endif + +// Targa Truevision - TGA +// by Jonathan Dummer +#ifndef STBI_NO_TGA +// returns STBI_rgb or whatever, 0 on error +static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) +{ + // only RGB or RGBA (incl. 16bit) or grey allowed + if (is_rgb16) *is_rgb16 = 0; + switch(bits_per_pixel) { + case 8: return STBI_grey; + case 16: if(is_grey) return STBI_grey_alpha; + // fallthrough + case 15: if(is_rgb16) *is_rgb16 = 1; + return STBI_rgb; + case 24: // fallthrough + case 32: return bits_per_pixel/8; + default: return 0; + } +} + +static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) +{ + int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; + int sz, tga_colormap_type; + stbi__get8(s); // discard Offset + tga_colormap_type = stbi__get8(s); // colormap type + if( tga_colormap_type > 1 ) { + stbi__rewind(s); + return 0; // only RGB or indexed allowed + } + tga_image_type = stbi__get8(s); // image type + if ( tga_colormap_type == 1 ) { // colormapped (paletted) image + if (tga_image_type != 1 && tga_image_type != 9) { + stbi__rewind(s); + return 0; + } + stbi__skip(s,4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) { + stbi__rewind(s); + return 0; + } + stbi__skip(s,4); // skip image x and y origin + tga_colormap_bpp = sz; + } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE + if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) { + stbi__rewind(s); + return 0; // only RGB or grey allowed, +/- RLE + } + stbi__skip(s,9); // skip colormap specification and image x/y origin + tga_colormap_bpp = 0; + } + tga_w = stbi__get16le(s); + if( tga_w < 1 ) { + stbi__rewind(s); + return 0; // test width + } + tga_h = stbi__get16le(s); + if( tga_h < 1 ) { + stbi__rewind(s); + return 0; // test height + } + tga_bits_per_pixel = stbi__get8(s); // bits per pixel + stbi__get8(s); // ignore alpha bits + if (tga_colormap_bpp != 0) { + if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { + // when using a colormap, tga_bits_per_pixel is the size of the indexes + // I don't think anything but 8 or 16bit indexes makes sense + stbi__rewind(s); + return 0; + } + tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); + } else { + tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); + } + if(!tga_comp) { + stbi__rewind(s); + return 0; + } + if (x) *x = tga_w; + if (y) *y = tga_h; + if (comp) *comp = tga_comp; + return 1; // seems to have passed everything +} + +static int stbi__tga_test(stbi__context *s) +{ + int res = 0; + int sz, tga_color_type; + stbi__get8(s); // discard Offset + tga_color_type = stbi__get8(s); // color type + if ( tga_color_type > 1 ) goto errorEnd; // only RGB or indexed allowed + sz = stbi__get8(s); // image type + if ( tga_color_type == 1 ) { // colormapped (paletted) image + if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 + stbi__skip(s,4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; + stbi__skip(s,4); // skip image x and y origin + } else { // "normal" image w/o colormap + if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE + stbi__skip(s,9); // skip colormap specification and image x/y origin + } + if ( stbi__get16le(s) < 1 ) goto errorEnd; // test width + if ( stbi__get16le(s) < 1 ) goto errorEnd; // test height + sz = stbi__get8(s); // bits per pixel + if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; + + res = 1; // if we got this far, everything's good and we can return 1 instead of 0 + +errorEnd: + stbi__rewind(s); + return res; +} + +// read 16bit value and convert to 24bit RGB +static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) +{ + stbi__uint16 px = (stbi__uint16)stbi__get16le(s); + stbi__uint16 fiveBitMask = 31; + // we have 3 channels with 5bits each + int r = (px >> 10) & fiveBitMask; + int g = (px >> 5) & fiveBitMask; + int b = px & fiveBitMask; + // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later + out[0] = (stbi_uc)((r * 255)/31); + out[1] = (stbi_uc)((g * 255)/31); + out[2] = (stbi_uc)((b * 255)/31); + + // some people claim that the most significant bit might be used for alpha + // (possibly if an alpha-bit is set in the "image descriptor byte") + // but that only made 16bit test images completely translucent.. + // so let's treat all 15 and 16bit TGAs as RGB with no alpha. +} + +static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + // read in the TGA header stuff + int tga_offset = stbi__get8(s); + int tga_indexed = stbi__get8(s); + int tga_image_type = stbi__get8(s); + int tga_is_RLE = 0; + int tga_palette_start = stbi__get16le(s); + int tga_palette_len = stbi__get16le(s); + int tga_palette_bits = stbi__get8(s); + int tga_x_origin = stbi__get16le(s); + int tga_y_origin = stbi__get16le(s); + int tga_width = stbi__get16le(s); + int tga_height = stbi__get16le(s); + int tga_bits_per_pixel = stbi__get8(s); + int tga_comp, tga_rgb16=0; + int tga_inverted = stbi__get8(s); + // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) + // image data + unsigned char *tga_data; + unsigned char *tga_palette = NULL; + int i, j; + unsigned char raw_data[4] = {0}; + int RLE_count = 0; + int RLE_repeating = 0; + int read_next_pixel = 1; + STBI_NOTUSED(ri); + + // do a tiny bit of precessing + if ( tga_image_type >= 8 ) + { + tga_image_type -= 8; + tga_is_RLE = 1; + } + tga_inverted = 1 - ((tga_inverted >> 5) & 1); + + // If I'm paletted, then I'll use the number of bits from the palette + if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); + else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); + + if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency + return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); + + // tga info + *x = tga_width; + *y = tga_height; + if (comp) *comp = tga_comp; + + if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) + return stbi__errpuc("too large", "Corrupt TGA"); + + tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); + if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); + + // skip to the data's starting position (offset usually = 0) + stbi__skip(s, tga_offset ); + + if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) { + for (i=0; i < tga_height; ++i) { + int row = tga_inverted ? tga_height -i - 1 : i; + stbi_uc *tga_row = tga_data + row*tga_width*tga_comp; + stbi__getn(s, tga_row, tga_width * tga_comp); + } + } else { + // do I need to load a palette? + if ( tga_indexed) + { + // any data to skip? (offset usually = 0) + stbi__skip(s, tga_palette_start ); + // load the palette + tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); + if (!tga_palette) { + STBI_FREE(tga_data); + return stbi__errpuc("outofmem", "Out of memory"); + } + if (tga_rgb16) { + stbi_uc *pal_entry = tga_palette; + STBI_ASSERT(tga_comp == STBI_rgb); + for (i=0; i < tga_palette_len; ++i) { + stbi__tga_read_rgb16(s, pal_entry); + pal_entry += tga_comp; + } + } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { + STBI_FREE(tga_data); + STBI_FREE(tga_palette); + return stbi__errpuc("bad palette", "Corrupt TGA"); + } + } + // load the data + for (i=0; i < tga_width * tga_height; ++i) + { + // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? + if ( tga_is_RLE ) + { + if ( RLE_count == 0 ) + { + // yep, get the next byte as a RLE command + int RLE_cmd = stbi__get8(s); + RLE_count = 1 + (RLE_cmd & 127); + RLE_repeating = RLE_cmd >> 7; + read_next_pixel = 1; + } else if ( !RLE_repeating ) + { + read_next_pixel = 1; + } + } else + { + read_next_pixel = 1; + } + // OK, if I need to read a pixel, do it now + if ( read_next_pixel ) + { + // load however much data we did have + if ( tga_indexed ) + { + // read in index, then perform the lookup + int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); + if ( pal_idx >= tga_palette_len ) { + // invalid index + pal_idx = 0; + } + pal_idx *= tga_comp; + for (j = 0; j < tga_comp; ++j) { + raw_data[j] = tga_palette[pal_idx+j]; + } + } else if(tga_rgb16) { + STBI_ASSERT(tga_comp == STBI_rgb); + stbi__tga_read_rgb16(s, raw_data); + } else { + // read in the data raw + for (j = 0; j < tga_comp; ++j) { + raw_data[j] = stbi__get8(s); + } + } + // clear the reading flag for the next pixel + read_next_pixel = 0; + } // end of reading a pixel + + // copy data + for (j = 0; j < tga_comp; ++j) + tga_data[i*tga_comp+j] = raw_data[j]; + + // in case we're in RLE mode, keep counting down + --RLE_count; + } + // do I need to invert the image? + if ( tga_inverted ) + { + for (j = 0; j*2 < tga_height; ++j) + { + int index1 = j * tga_width * tga_comp; + int index2 = (tga_height - 1 - j) * tga_width * tga_comp; + for (i = tga_width * tga_comp; i > 0; --i) + { + unsigned char temp = tga_data[index1]; + tga_data[index1] = tga_data[index2]; + tga_data[index2] = temp; + ++index1; + ++index2; + } + } + } + // clear my palette, if I had one + if ( tga_palette != NULL ) + { + STBI_FREE( tga_palette ); + } + } + + // swap RGB - if the source data was RGB16, it already is in the right order + if (tga_comp >= 3 && !tga_rgb16) + { + unsigned char* tga_pixel = tga_data; + for (i=0; i < tga_width * tga_height; ++i) + { + unsigned char temp = tga_pixel[0]; + tga_pixel[0] = tga_pixel[2]; + tga_pixel[2] = temp; + tga_pixel += tga_comp; + } + } + + // convert to target component count + if (req_comp && req_comp != tga_comp) + tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); + + // the things I do to get rid of an error message, and yet keep + // Microsoft's C compilers happy... [8^( + tga_palette_start = tga_palette_len = tga_palette_bits = + tga_x_origin = tga_y_origin = 0; + // OK, done + return tga_data; +} +#endif + +// ************************************************************************************************* +// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB + +#ifndef STBI_NO_PSD +static int stbi__psd_test(stbi__context *s) +{ + int r = (stbi__get32be(s) == 0x38425053); + stbi__rewind(s); + return r; +} + +static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount) +{ + int count, nleft, len; + + count = 0; + while ((nleft = pixelCount - count) > 0) { + len = stbi__get8(s); + if (len == 128) { + // No-op. + } else if (len < 128) { + // Copy next len+1 bytes literally. + len++; + if (len > nleft) return 0; // corrupt data + count += len; + while (len) { + *p = stbi__get8(s); + p += 4; + len--; + } + } else if (len > 128) { + stbi_uc val; + // Next -len+1 bytes in the dest are replicated from next source byte. + // (Interpret len as a negative 8-bit int.) + len = 257 - len; + if (len > nleft) return 0; // corrupt data + val = stbi__get8(s); + count += len; + while (len) { + *p = val; + p += 4; + len--; + } + } + } + + return 1; +} + +static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) +{ + int pixelCount; + int channelCount, compression; + int channel, i; + int bitdepth; + int w,h; + stbi_uc *out; + STBI_NOTUSED(ri); + + // Check identifier + if (stbi__get32be(s) != 0x38425053) // "8BPS" + return stbi__errpuc("not PSD", "Corrupt PSD image"); + + // Check file type version. + if (stbi__get16be(s) != 1) + return stbi__errpuc("wrong version", "Unsupported version of PSD image"); + + // Skip 6 reserved bytes. + stbi__skip(s, 6 ); + + // Read the number of channels (R, G, B, A, etc). + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) + return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); + + // Read the rows and columns of the image. + h = stbi__get32be(s); + w = stbi__get32be(s); + + // Make sure the depth is 8 bits. + bitdepth = stbi__get16be(s); + if (bitdepth != 8 && bitdepth != 16) + return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); + + // Make sure the color mode is RGB. + // Valid options are: + // 0: Bitmap + // 1: Grayscale + // 2: Indexed color + // 3: RGB color + // 4: CMYK color + // 7: Multichannel + // 8: Duotone + // 9: Lab color + if (stbi__get16be(s) != 3) + return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); + + // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) + stbi__skip(s,stbi__get32be(s) ); + + // Skip the image resources. (resolution, pen tool paths, etc) + stbi__skip(s, stbi__get32be(s) ); + + // Skip the reserved data. + stbi__skip(s, stbi__get32be(s) ); + + // Find out if the data is compressed. + // Known values: + // 0: no compression + // 1: RLE compressed + compression = stbi__get16be(s); + if (compression > 1) + return stbi__errpuc("bad compression", "PSD has an unknown compression format"); + + // Check size + if (!stbi__mad3sizes_valid(4, w, h, 0)) + return stbi__errpuc("too large", "Corrupt PSD"); + + // Create the destination image. + + if (!compression && bitdepth == 16 && bpc == 16) { + out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0); + ri->bits_per_channel = 16; + } else + out = (stbi_uc *) stbi__malloc(4 * w*h); + + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + pixelCount = w*h; + + // Initialize the data to zero. + //memset( out, 0, pixelCount * 4 ); + + // Finally, the image data. + if (compression) { + // RLE as used by .PSD and .TIFF + // Loop until you get the number of unpacked bytes you are expecting: + // Read the next source byte into n. + // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. + // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. + // Else if n is 128, noop. + // Endloop + + // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data, + // which we're going to just skip. + stbi__skip(s, h * channelCount * 2 ); + + // Read the RLE data by channel. + for (channel = 0; channel < 4; channel++) { + stbi_uc *p; + + p = out+channel; + if (channel >= channelCount) { + // Fill this channel with default data. + for (i = 0; i < pixelCount; i++, p += 4) + *p = (channel == 3 ? 255 : 0); + } else { + // Read the RLE data. + if (!stbi__psd_decode_rle(s, p, pixelCount)) { + STBI_FREE(out); + return stbi__errpuc("corrupt", "bad RLE data"); + } + } + } + + } else { + // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) + // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. + + // Read the data by channel. + for (channel = 0; channel < 4; channel++) { + if (channel >= channelCount) { + // Fill this channel with default data. + if (bitdepth == 16 && bpc == 16) { + stbi__uint16 *q = ((stbi__uint16 *) out) + channel; + stbi__uint16 val = channel == 3 ? 65535 : 0; + for (i = 0; i < pixelCount; i++, q += 4) + *q = val; + } else { + stbi_uc *p = out+channel; + stbi_uc val = channel == 3 ? 255 : 0; + for (i = 0; i < pixelCount; i++, p += 4) + *p = val; + } + } else { + if (ri->bits_per_channel == 16) { // output bpc + stbi__uint16 *q = ((stbi__uint16 *) out) + channel; + for (i = 0; i < pixelCount; i++, q += 4) + *q = (stbi__uint16) stbi__get16be(s); + } else { + stbi_uc *p = out+channel; + if (bitdepth == 16) { // input bpc + for (i = 0; i < pixelCount; i++, p += 4) + *p = (stbi_uc) (stbi__get16be(s) >> 8); + } else { + for (i = 0; i < pixelCount; i++, p += 4) + *p = stbi__get8(s); + } + } + } + } + } + + // remove weird white matte from PSD + if (channelCount >= 4) { + if (ri->bits_per_channel == 16) { + for (i=0; i < w*h; ++i) { + stbi__uint16 *pixel = (stbi__uint16 *) out + 4*i; + if (pixel[3] != 0 && pixel[3] != 65535) { + float a = pixel[3] / 65535.0f; + float ra = 1.0f / a; + float inv_a = 65535.0f * (1 - ra); + pixel[0] = (stbi__uint16) (pixel[0]*ra + inv_a); + pixel[1] = (stbi__uint16) (pixel[1]*ra + inv_a); + pixel[2] = (stbi__uint16) (pixel[2]*ra + inv_a); + } + } + } else { + for (i=0; i < w*h; ++i) { + unsigned char *pixel = out + 4*i; + if (pixel[3] != 0 && pixel[3] != 255) { + float a = pixel[3] / 255.0f; + float ra = 1.0f / a; + float inv_a = 255.0f * (1 - ra); + pixel[0] = (unsigned char) (pixel[0]*ra + inv_a); + pixel[1] = (unsigned char) (pixel[1]*ra + inv_a); + pixel[2] = (unsigned char) (pixel[2]*ra + inv_a); + } + } + } + } + + // convert to desired output format + if (req_comp && req_comp != 4) { + if (ri->bits_per_channel == 16) + out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, 4, req_comp, w, h); + else + out = stbi__convert_format(out, 4, req_comp, w, h); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + + if (comp) *comp = 4; + *y = h; + *x = w; + + return out; +} +#endif + +// ************************************************************************************************* +// Softimage PIC loader +// by Tom Seddon +// +// See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format +// See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ + +#ifndef STBI_NO_PIC +static int stbi__pic_is4(stbi__context *s,const char *str) +{ + int i; + for (i=0; i<4; ++i) + if (stbi__get8(s) != (stbi_uc)str[i]) + return 0; + + return 1; +} + +static int stbi__pic_test_core(stbi__context *s) +{ + int i; + + if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) + return 0; + + for(i=0;i<84;++i) + stbi__get8(s); + + if (!stbi__pic_is4(s,"PICT")) + return 0; + + return 1; +} + +typedef struct +{ + stbi_uc size,type,channel; +} stbi__pic_packet; + +static stbi_uc *stbi__readval(stbi__context *s, int channel, stbi_uc *dest) +{ + int mask=0x80, i; + + for (i=0; i<4; ++i, mask>>=1) { + if (channel & mask) { + if (stbi__at_eof(s)) return stbi__errpuc("bad file","PIC file too short"); + dest[i]=stbi__get8(s); + } + } + + return dest; +} + +static void stbi__copyval(int channel,stbi_uc *dest,const stbi_uc *src) +{ + int mask=0x80,i; + + for (i=0;i<4; ++i, mask>>=1) + if (channel&mask) + dest[i]=src[i]; +} + +static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *comp, stbi_uc *result) +{ + int act_comp=0,num_packets=0,y,chained; + stbi__pic_packet packets[10]; + + // this will (should...) cater for even some bizarre stuff like having data + // for the same channel in multiple packets. + do { + stbi__pic_packet *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return stbi__errpuc("bad format","too many packets"); + + packet = &packets[num_packets++]; + + chained = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); + packet->channel = stbi__get8(s); + + act_comp |= packet->channel; + + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (reading packets)"); + if (packet->size != 8) return stbi__errpuc("bad format","packet isn't 8bpp"); + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? + + for(y=0; ytype) { + default: + return stbi__errpuc("bad format","packet has bad compression type"); + + case 0: {//uncompressed + int x; + + for(x=0;xchannel,dest)) + return 0; + break; + } + + case 1://Pure RLE + { + int left=width, i; + + while (left>0) { + stbi_uc count,value[4]; + + count=stbi__get8(s); + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pure read count)"); + + if (count > left) + count = (stbi_uc) left; + + if (!stbi__readval(s,packet->channel,value)) return 0; + + for(i=0; ichannel,dest,value); + left -= count; + } + } + break; + + case 2: {//Mixed RLE + int left=width; + while (left>0) { + int count = stbi__get8(s), i; + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (mixed read count)"); + + if (count >= 128) { // Repeated + stbi_uc value[4]; + + if (count==128) + count = stbi__get16be(s); + else + count -= 127; + if (count > left) + return stbi__errpuc("bad file","scanline overrun"); + + if (!stbi__readval(s,packet->channel,value)) + return 0; + + for(i=0;ichannel,dest,value); + } else { // Raw + ++count; + if (count>left) return stbi__errpuc("bad file","scanline overrun"); + + for(i=0;ichannel,dest)) + return 0; + } + left-=count; + } + break; + } + } + } + } + + return result; +} + +static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri) +{ + stbi_uc *result; + int i, x,y, internal_comp; + STBI_NOTUSED(ri); + + if (!comp) comp = &internal_comp; + + for (i=0; i<92; ++i) + stbi__get8(s); + + x = stbi__get16be(s); + y = stbi__get16be(s); + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)"); + if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode"); + + stbi__get32be(s); //skip `ratio' + stbi__get16be(s); //skip `fields' + stbi__get16be(s); //skip `pad' + + // intermediate buffer is RGBA + result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0); + memset(result, 0xff, x*y*4); + + if (!stbi__pic_load_core(s,x,y,comp, result)) { + STBI_FREE(result); + result=0; + } + *px = x; + *py = y; + if (req_comp == 0) req_comp = *comp; + result=stbi__convert_format(result,4,req_comp,x,y); + + return result; +} + +static int stbi__pic_test(stbi__context *s) +{ + int r = stbi__pic_test_core(s); + stbi__rewind(s); + return r; +} +#endif + +// ************************************************************************************************* +// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb + +#ifndef STBI_NO_GIF +typedef struct +{ + stbi__int16 prefix; + stbi_uc first; + stbi_uc suffix; +} stbi__gif_lzw; + +typedef struct +{ + int w,h; + stbi_uc *out; // output buffer (always 4 components) + stbi_uc *background; // The current "background" as far as a gif is concerned + stbi_uc *history; + int flags, bgindex, ratio, transparent, eflags; + stbi_uc pal[256][4]; + stbi_uc lpal[256][4]; + stbi__gif_lzw codes[8192]; + stbi_uc *color_table; + int parse, step; + int lflags; + int start_x, start_y; + int max_x, max_y; + int cur_x, cur_y; + int line_size; + int delay; +} stbi__gif; + +static int stbi__gif_test_raw(stbi__context *s) +{ + int sz; + if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; + sz = stbi__get8(s); + if (sz != '9' && sz != '7') return 0; + if (stbi__get8(s) != 'a') return 0; + return 1; +} + +static int stbi__gif_test(stbi__context *s) +{ + int r = stbi__gif_test_raw(s); + stbi__rewind(s); + return r; +} + +static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], int num_entries, int transp) +{ + int i; + for (i=0; i < num_entries; ++i) { + pal[i][2] = stbi__get8(s); + pal[i][1] = stbi__get8(s); + pal[i][0] = stbi__get8(s); + pal[i][3] = transp == i ? 0 : 255; + } +} + +static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info) +{ + stbi_uc version; + if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') + return stbi__err("not GIF", "Corrupt GIF"); + + version = stbi__get8(s); + if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); + if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); + + stbi__g_failure_reason = ""; + g->w = stbi__get16le(s); + g->h = stbi__get16le(s); + g->flags = stbi__get8(s); + g->bgindex = stbi__get8(s); + g->ratio = stbi__get8(s); + g->transparent = -1; + + if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments + + if (is_info) return 1; + + if (g->flags & 0x80) + stbi__gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1); + + return 1; +} + +static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp) +{ + stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); + if (!stbi__gif_header(s, g, comp, 1)) { + STBI_FREE(g); + stbi__rewind( s ); + return 0; + } + if (x) *x = g->w; + if (y) *y = g->h; + STBI_FREE(g); + return 1; +} + +static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code) +{ + stbi_uc *p, *c; + int idx; + + // recurse to decode the prefixes, since the linked-list is backwards, + // and working backwards through an interleaved image would be nasty + if (g->codes[code].prefix >= 0) + stbi__out_gif_code(g, g->codes[code].prefix); + + if (g->cur_y >= g->max_y) return; + + idx = g->cur_x + g->cur_y; + p = &g->out[idx]; + g->history[idx / 4] = 1; + + c = &g->color_table[g->codes[code].suffix * 4]; + if (c[3] > 128) { // don't render transparent pixels; + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = c[3]; + } + g->cur_x += 4; + + if (g->cur_x >= g->max_x) { + g->cur_x = g->start_x; + g->cur_y += g->step; + + while (g->cur_y >= g->max_y && g->parse > 0) { + g->step = (1 << g->parse) * g->line_size; + g->cur_y = g->start_y + (g->step >> 1); + --g->parse; + } + } +} + +static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g) +{ + stbi_uc lzw_cs; + stbi__int32 len, init_code; + stbi__uint32 first; + stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; + stbi__gif_lzw *p; + + lzw_cs = stbi__get8(s); + if (lzw_cs > 12) return NULL; + clear = 1 << lzw_cs; + first = 1; + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + bits = 0; + valid_bits = 0; + for (init_code = 0; init_code < clear; init_code++) { + g->codes[init_code].prefix = -1; + g->codes[init_code].first = (stbi_uc) init_code; + g->codes[init_code].suffix = (stbi_uc) init_code; + } + + // support no starting clear code + avail = clear+2; + oldcode = -1; + + len = 0; + for(;;) { + if (valid_bits < codesize) { + if (len == 0) { + len = stbi__get8(s); // start new block + if (len == 0) + return g->out; + } + --len; + bits |= (stbi__int32) stbi__get8(s) << valid_bits; + valid_bits += 8; + } else { + stbi__int32 code = bits & codemask; + bits >>= codesize; + valid_bits -= codesize; + // @OPTIMIZE: is there some way we can accelerate the non-clear path? + if (code == clear) { // clear code + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + avail = clear + 2; + oldcode = -1; + first = 0; + } else if (code == clear + 1) { // end of stream code + stbi__skip(s, len); + while ((len = stbi__get8(s)) > 0) + stbi__skip(s,len); + return g->out; + } else if (code <= avail) { + if (first) { + return stbi__errpuc("no clear code", "Corrupt GIF"); + } + + if (oldcode >= 0) { + p = &g->codes[avail++]; + if (avail > 8192) { + return stbi__errpuc("too many codes", "Corrupt GIF"); + } + + p->prefix = (stbi__int16) oldcode; + p->first = g->codes[oldcode].first; + p->suffix = (code == avail) ? p->first : g->codes[code].first; + } else if (code == avail) + return stbi__errpuc("illegal code in raster", "Corrupt GIF"); + + stbi__out_gif_code(g, (stbi__uint16) code); + + if ((avail & codemask) == 0 && avail <= 0x0FFF) { + codesize++; + codemask = (1 << codesize) - 1; + } + + oldcode = code; + } else { + return stbi__errpuc("illegal code in raster", "Corrupt GIF"); + } + } + } +} + +// this function is designed to support animated gifs, although stb_image doesn't support it +// two back is the image from two frames ago, used for a very specific disposal format +static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp, stbi_uc *two_back) +{ + int dispose; + int first_frame; + int pi; + int pcount; + + // on first frame, any non-written pixels get the background colour (non-transparent) + first_frame = 0; + if (g->out == 0) { + if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header + g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h); + g->background = (stbi_uc *) stbi__malloc(4 * g->w * g->h); + g->history = (stbi_uc *) stbi__malloc(g->w * g->h); + if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory"); + + // image is treated as "tranparent" at the start - ie, nothing overwrites the current background; + // background colour is only used for pixels that are not rendered first frame, after that "background" + // color refers to teh color that was there the previous frame. + memset( g->out, 0x00, 4 * g->w * g->h ); + memset( g->background, 0x00, 4 * g->w * g->h ); // state of the background (starts transparent) + memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame + first_frame = 1; + } else { + // second frame - how do we dispoase of the previous one? + dispose = (g->eflags & 0x1C) >> 2; + pcount = g->w * g->h; + + if ((dispose == 3) && (two_back == 0)) { + dispose = 2; // if I don't have an image to revert back to, default to the old background + } + + if (dispose == 3) { // use previous graphic + for (pi = 0; pi < pcount; ++pi) { + if (g->history[pi]) { + memcpy( &g->out[pi * 4], &two_back[pi * 4], 4 ); + } + } + } else if (dispose == 2) { + // restore what was changed last frame to background before that frame; + for (pi = 0; pi < pcount; ++pi) { + if (g->history[pi]) { + memcpy( &g->out[pi * 4], &g->background[pi * 4], 4 ); + } + } + } else { + // This is a non-disposal case eithe way, so just + // leave the pixels as is, and they will become the new background + // 1: do not dispose + // 0: not specified. + } + + // background is what out is after the undoing of the previou frame; + memcpy( g->background, g->out, 4 * g->w * g->h ); + } + + // clear my history; + memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame + + for (;;) { + int tag = stbi__get8(s); + switch (tag) { + case 0x2C: /* Image Descriptor */ + { + stbi__int32 x, y, w, h; + stbi_uc *o; + + x = stbi__get16le(s); + y = stbi__get16le(s); + w = stbi__get16le(s); + h = stbi__get16le(s); + if (((x + w) > (g->w)) || ((y + h) > (g->h))) + return stbi__errpuc("bad Image Descriptor", "Corrupt GIF"); + + g->line_size = g->w * 4; + g->start_x = x * 4; + g->start_y = y * g->line_size; + g->max_x = g->start_x + w * 4; + g->max_y = g->start_y + h * g->line_size; + g->cur_x = g->start_x; + g->cur_y = g->start_y; + + g->lflags = stbi__get8(s); + + if (g->lflags & 0x40) { + g->step = 8 * g->line_size; // first interlaced spacing + g->parse = 3; + } else { + g->step = g->line_size; + g->parse = 0; + } + + if (g->lflags & 0x80) { + stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); + g->color_table = (stbi_uc *) g->lpal; + } else if (g->flags & 0x80) { + g->color_table = (stbi_uc *) g->pal; + } else + return stbi__errpuc("missing color table", "Corrupt GIF"); + + o = stbi__process_gif_raster(s, g); + if (o == NULL) return NULL; + + // if this was the first frame, + pcount = g->w * g->h; + if (first_frame && (g->bgindex > 0)) { + // if first frame, any pixel not drawn to gets the background color + for (pi = 0; pi < pcount; ++pi) { + if (g->history[pi] == 0) { + g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be; + memcpy( &g->out[pi * 4], &g->pal[g->bgindex], 4 ); + } + } + } + + return o; + } + + case 0x21: // Comment Extension. + { + int len; + int ext = stbi__get8(s); + if (ext == 0xF9) { // Graphic Control Extension. + len = stbi__get8(s); + if (len == 4) { + g->eflags = stbi__get8(s); + g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths. + + // unset old transparent + if (g->transparent >= 0) { + g->pal[g->transparent][3] = 255; + } + if (g->eflags & 0x01) { + g->transparent = stbi__get8(s); + if (g->transparent >= 0) { + g->pal[g->transparent][3] = 0; + } + } else { + // don't need transparent + stbi__skip(s, 1); + g->transparent = -1; + } + } else { + stbi__skip(s, len); + break; + } + } + while ((len = stbi__get8(s)) != 0) { + stbi__skip(s, len); + } + break; + } + + case 0x3B: // gif stream termination code + return (stbi_uc *) s; // using '1' causes warning on some compilers + + default: + return stbi__errpuc("unknown code", "Corrupt GIF"); + } + } +} + +static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp) +{ + if (stbi__gif_test(s)) { + int layers = 0; + stbi_uc *u = 0; + stbi_uc *out = 0; + stbi_uc *two_back = 0; + stbi__gif g; + int stride; + memset(&g, 0, sizeof(g)); + if (delays) { + *delays = 0; + } + + do { + u = stbi__gif_load_next(s, &g, comp, req_comp, two_back); + if (u == (stbi_uc *) s) u = 0; // end of animated gif marker + + if (u) { + *x = g.w; + *y = g.h; + ++layers; + stride = g.w * g.h * 4; + + if (out) { + out = (stbi_uc*) STBI_REALLOC( out, layers * stride ); + if (delays) { + *delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers ); + } + } else { + out = (stbi_uc*)stbi__malloc( layers * stride ); + if (delays) { + *delays = (int*) stbi__malloc( layers * sizeof(int) ); + } + } + memcpy( out + ((layers - 1) * stride), u, stride ); + if (layers >= 2) { + two_back = out - 2 * stride; + } + + if (delays) { + (*delays)[layers - 1U] = g.delay; + } + } + } while (u != 0); + + // free temp buffer; + STBI_FREE(g.out); + STBI_FREE(g.history); + STBI_FREE(g.background); + + // do the final conversion after loading everything; + if (req_comp && req_comp != 4) + out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h); + + *z = layers; + return out; + } else { + return stbi__errpuc("not GIF", "Image was not as a gif type."); + } +} + +static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi_uc *u = 0; + stbi__gif g; + memset(&g, 0, sizeof(g)); + + u = stbi__gif_load_next(s, &g, comp, req_comp, 0); + if (u == (stbi_uc *) s) u = 0; // end of animated gif marker + if (u) { + *x = g.w; + *y = g.h; + + // moved conversion to after successful load so that the same + // can be done for multiple frames. + if (req_comp && req_comp != 4) + u = stbi__convert_format(u, 4, req_comp, g.w, g.h); + } + + // free buffers needed for multiple frame loading; + STBI_FREE(g.history); + STBI_FREE(g.background); + + return u; +} + +static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp) +{ + return stbi__gif_info_raw(s,x,y,comp); +} +#endif + +// ************************************************************************************************* +// Radiance RGBE HDR loader +// originally by Nicolas Schulz +#ifndef STBI_NO_HDR +static int stbi__hdr_test_core(stbi__context *s, const char *signature) +{ + int i; + for (i=0; signature[i]; ++i) + if (stbi__get8(s) != signature[i]) + return 0; + stbi__rewind(s); + return 1; +} + +static int stbi__hdr_test(stbi__context* s) +{ + int r = stbi__hdr_test_core(s, "#?RADIANCE\n"); + stbi__rewind(s); + if(!r) { + r = stbi__hdr_test_core(s, "#?RGBE\n"); + stbi__rewind(s); + } + return r; +} + +#define STBI__HDR_BUFLEN 1024 +static char *stbi__hdr_gettoken(stbi__context *z, char *buffer) +{ + int len=0; + char c = '\0'; + + c = (char) stbi__get8(z); + + while (!stbi__at_eof(z) && c != '\n') { + buffer[len++] = c; + if (len == STBI__HDR_BUFLEN-1) { + // flush to end of line + while (!stbi__at_eof(z) && stbi__get8(z) != '\n') + ; + break; + } + c = (char) stbi__get8(z); + } + + buffer[len] = 0; + return buffer; +} + +static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp) +{ + if ( input[3] != 0 ) { + float f1; + // Exponent + f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); + if (req_comp <= 2) + output[0] = (input[0] + input[1] + input[2]) * f1 / 3; + else { + output[0] = input[0] * f1; + output[1] = input[1] * f1; + output[2] = input[2] * f1; + } + if (req_comp == 2) output[1] = 1; + if (req_comp == 4) output[3] = 1; + } else { + switch (req_comp) { + case 4: output[3] = 1; /* fallthrough */ + case 3: output[0] = output[1] = output[2] = 0; + break; + case 2: output[1] = 1; /* fallthrough */ + case 1: output[0] = 0; + break; + } + } +} + +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + char buffer[STBI__HDR_BUFLEN]; + char *token; + int valid = 0; + int width, height; + stbi_uc *scanline; + float *hdr_data; + int len; + unsigned char count, value; + int i, j, k, c1,c2, z; + const char *headerToken; + STBI_NOTUSED(ri); + + // Check identifier + headerToken = stbi__hdr_gettoken(s,buffer); + if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0) + return stbi__errpf("not HDR", "Corrupt HDR image"); + + // Parse header + for(;;) { + token = stbi__hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) return stbi__errpf("unsupported format", "Unsupported HDR format"); + + // Parse width and height + // can't use sscanf() if we're not using stdio! + token = stbi__hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + token += 3; + height = (int) strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + token += 3; + width = (int) strtol(token, NULL, 10); + + *x = width; + *y = height; + + if (comp) *comp = 3; + if (req_comp == 0) req_comp = 3; + + if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0)) + return stbi__errpf("too large", "HDR image is too large"); + + // Read data + hdr_data = (float *) stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0); + if (!hdr_data) + return stbi__errpf("outofmem", "Out of memory"); + + // Load image data + // image data is stored as some number of sca + if ( width < 8 || width >= 32768) { + // Read flat data + for (j=0; j < height; ++j) { + for (i=0; i < width; ++i) { + stbi_uc rgbe[4]; + main_decode_loop: + stbi__getn(s, rgbe, 4); + stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); + } + } + } else { + // Read RLE-encoded data + scanline = NULL; + + for (j = 0; j < height; ++j) { + c1 = stbi__get8(s); + c2 = stbi__get8(s); + len = stbi__get8(s); + if (c1 != 2 || c2 != 2 || (len & 0x80)) { + // not run-length encoded, so we have to actually use THIS data as a decoded + // pixel (note this can't be a valid pixel--one of RGB must be >= 128) + stbi_uc rgbe[4]; + rgbe[0] = (stbi_uc) c1; + rgbe[1] = (stbi_uc) c2; + rgbe[2] = (stbi_uc) len; + rgbe[3] = (stbi_uc) stbi__get8(s); + stbi__hdr_convert(hdr_data, rgbe, req_comp); + i = 1; + j = 0; + STBI_FREE(scanline); + goto main_decode_loop; // yes, this makes no sense + } + len <<= 8; + len |= stbi__get8(s); + if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } + if (scanline == NULL) { + scanline = (stbi_uc *) stbi__malloc_mad2(width, 4, 0); + if (!scanline) { + STBI_FREE(hdr_data); + return stbi__errpf("outofmem", "Out of memory"); + } + } + + for (k = 0; k < 4; ++k) { + int nleft; + i = 0; + while ((nleft = width - i) > 0) { + count = stbi__get8(s); + if (count > 128) { + // Run + value = stbi__get8(s); + count -= 128; + if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = value; + } else { + // Dump + if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = stbi__get8(s); + } + } + } + for (i=0; i < width; ++i) + stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); + } + if (scanline) + STBI_FREE(scanline); + } + + return hdr_data; +} + +static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp) +{ + char buffer[STBI__HDR_BUFLEN]; + char *token; + int valid = 0; + int dummy; + + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + + if (stbi__hdr_test(s) == 0) { + stbi__rewind( s ); + return 0; + } + + for(;;) { + token = stbi__hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) { + stbi__rewind( s ); + return 0; + } + token = stbi__hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) { + stbi__rewind( s ); + return 0; + } + token += 3; + *y = (int) strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) { + stbi__rewind( s ); + return 0; + } + token += 3; + *x = (int) strtol(token, NULL, 10); + *comp = 3; + return 1; +} +#endif // STBI_NO_HDR + +#ifndef STBI_NO_BMP +static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) +{ + void *p; + stbi__bmp_data info; + + info.all_a = 255; + p = stbi__bmp_parse_header(s, &info); + stbi__rewind( s ); + if (p == NULL) + return 0; + if (x) *x = s->img_x; + if (y) *y = s->img_y; + if (comp) *comp = info.ma ? 4 : 3; + return 1; +} +#endif + +#ifndef STBI_NO_PSD +static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) +{ + int channelCount, dummy, depth; + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + if (stbi__get32be(s) != 0x38425053) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 1) { + stbi__rewind( s ); + return 0; + } + stbi__skip(s, 6); + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) { + stbi__rewind( s ); + return 0; + } + *y = stbi__get32be(s); + *x = stbi__get32be(s); + depth = stbi__get16be(s); + if (depth != 8 && depth != 16) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 3) { + stbi__rewind( s ); + return 0; + } + *comp = 4; + return 1; +} + +static int stbi__psd_is16(stbi__context *s) +{ + int channelCount, depth; + if (stbi__get32be(s) != 0x38425053) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 1) { + stbi__rewind( s ); + return 0; + } + stbi__skip(s, 6); + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) { + stbi__rewind( s ); + return 0; + } + (void) stbi__get32be(s); + (void) stbi__get32be(s); + depth = stbi__get16be(s); + if (depth != 16) { + stbi__rewind( s ); + return 0; + } + return 1; +} +#endif + +#ifndef STBI_NO_PIC +static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) +{ + int act_comp=0,num_packets=0,chained,dummy; + stbi__pic_packet packets[10]; + + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + + if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) { + stbi__rewind(s); + return 0; + } + + stbi__skip(s, 88); + + *x = stbi__get16be(s); + *y = stbi__get16be(s); + if (stbi__at_eof(s)) { + stbi__rewind( s); + return 0; + } + if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) { + stbi__rewind( s ); + return 0; + } + + stbi__skip(s, 8); + + do { + stbi__pic_packet *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return 0; + + packet = &packets[num_packets++]; + chained = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); + packet->channel = stbi__get8(s); + act_comp |= packet->channel; + + if (stbi__at_eof(s)) { + stbi__rewind( s ); + return 0; + } + if (packet->size != 8) { + stbi__rewind( s ); + return 0; + } + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); + + return 1; +} +#endif + +// ************************************************************************************************* +// Portable Gray Map and Portable Pixel Map loader +// by Ken Miller +// +// PGM: http://netpbm.sourceforge.net/doc/pgm.html +// PPM: http://netpbm.sourceforge.net/doc/ppm.html +// +// Known limitations: +// Does not support comments in the header section +// Does not support ASCII image data (formats P2 and P3) +// Does not support 16-bit-per-channel + +#ifndef STBI_NO_PNM + +static int stbi__pnm_test(stbi__context *s) +{ + char p, t; + p = (char) stbi__get8(s); + t = (char) stbi__get8(s); + if (p != 'P' || (t != '5' && t != '6')) { + stbi__rewind( s ); + return 0; + } + return 1; +} + +static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi_uc *out; + STBI_NOTUSED(ri); + + if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n)) + return 0; + + *x = s->img_x; + *y = s->img_y; + if (comp) *comp = s->img_n; + + if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0)) + return stbi__errpuc("too large", "PNM too large"); + + out = (stbi_uc *) stbi__malloc_mad3(s->img_n, s->img_x, s->img_y, 0); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + stbi__getn(s, out, s->img_n * s->img_x * s->img_y); + + if (req_comp && req_comp != s->img_n) { + out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + return out; +} + +static int stbi__pnm_isspace(char c) +{ + return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; +} + +static void stbi__pnm_skip_whitespace(stbi__context *s, char *c) +{ + for (;;) { + while (!stbi__at_eof(s) && stbi__pnm_isspace(*c)) + *c = (char) stbi__get8(s); + + if (stbi__at_eof(s) || *c != '#') + break; + + while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' ) + *c = (char) stbi__get8(s); + } +} + +static int stbi__pnm_isdigit(char c) +{ + return c >= '0' && c <= '9'; +} + +static int stbi__pnm_getinteger(stbi__context *s, char *c) +{ + int value = 0; + + while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) { + value = value*10 + (*c - '0'); + *c = (char) stbi__get8(s); + } + + return value; +} + +static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) +{ + int maxv, dummy; + char c, p, t; + + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + + stbi__rewind(s); + + // Get identifier + p = (char) stbi__get8(s); + t = (char) stbi__get8(s); + if (p != 'P' || (t != '5' && t != '6')) { + stbi__rewind(s); + return 0; + } + + *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm + + c = (char) stbi__get8(s); + stbi__pnm_skip_whitespace(s, &c); + + *x = stbi__pnm_getinteger(s, &c); // read width + stbi__pnm_skip_whitespace(s, &c); + + *y = stbi__pnm_getinteger(s, &c); // read height + stbi__pnm_skip_whitespace(s, &c); + + maxv = stbi__pnm_getinteger(s, &c); // read max value + + if (maxv > 255) + return stbi__err("max value > 255", "PPM image not 8-bit"); + else + return 1; +} +#endif + +static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp) +{ + #ifndef STBI_NO_JPEG + if (stbi__jpeg_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PNG + if (stbi__png_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_GIF + if (stbi__gif_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_BMP + if (stbi__bmp_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PSD + if (stbi__psd_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PIC + if (stbi__pic_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PNM + if (stbi__pnm_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_HDR + if (stbi__hdr_info(s, x, y, comp)) return 1; + #endif + + // test tga last because it's a crappy test! + #ifndef STBI_NO_TGA + if (stbi__tga_info(s, x, y, comp)) + return 1; + #endif + return stbi__err("unknown image type", "Image not of any known type, or corrupt"); +} + +static int stbi__is_16_main(stbi__context *s) +{ + #ifndef STBI_NO_PNG + if (stbi__png_is16(s)) return 1; + #endif + + #ifndef STBI_NO_PSD + if (stbi__psd_is16(s)) return 1; + #endif + + return 0; +} + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result; + if (!f) return stbi__err("can't fopen", "Unable to open file"); + result = stbi_info_from_file(f, x, y, comp); + fclose(f); + return result; +} + +STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) +{ + int r; + stbi__context s; + long pos = ftell(f); + stbi__start_file(&s, f); + r = stbi__info_main(&s,x,y,comp); + fseek(f,pos,SEEK_SET); + return r; +} + +STBIDEF int stbi_is_16_bit(char const *filename) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result; + if (!f) return stbi__err("can't fopen", "Unable to open file"); + result = stbi_is_16_bit_from_file(f); + fclose(f); + return result; +} + +STBIDEF int stbi_is_16_bit_from_file(FILE *f) +{ + int r; + stbi__context s; + long pos = ftell(f); + stbi__start_file(&s, f); + r = stbi__is_16_main(&s); + fseek(f,pos,SEEK_SET); + return r; +} +#endif // !STBI_NO_STDIO + +STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__info_main(&s,x,y,comp); +} + +STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); + return stbi__info_main(&s,x,y,comp); +} + +STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__is_16_main(&s); +} + +STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); + return stbi__is_16_main(&s); +} + +#endif // STB_IMAGE_IMPLEMENTATION + +/* + revision history: + 2.19 (2018-02-11) fix warning + 2.18 (2018-01-30) fix warnings + 2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug + 1-bit BMP + *_is_16_bit api + avoid warnings + 2.16 (2017-07-23) all functions have 16-bit variants; + STBI_NO_STDIO works again; + compilation fixes; + fix rounding in unpremultiply; + optimize vertical flip; + disable raw_len validation; + documentation fixes + 2.15 (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode; + warning fixes; disable run-time SSE detection on gcc; + uniform handling of optional "return" values; + thread-safe initialization of zlib tables + 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs + 2.13 (2016-11-29) add 16-bit API, only supported for PNG right now + 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes + 2.11 (2016-04-02) allocate large structures on the stack + remove white matting for transparent PSD + fix reported channel count for PNG & BMP + re-enable SSE2 in non-gcc 64-bit + support RGB-formatted JPEG + read 16-bit PNGs (only as 8-bit) + 2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED + 2.09 (2016-01-16) allow comments in PNM files + 16-bit-per-pixel TGA (not bit-per-component) + info() for TGA could break due to .hdr handling + info() for BMP to shares code instead of sloppy parse + can use STBI_REALLOC_SIZED if allocator doesn't support realloc + code cleanup + 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA + 2.07 (2015-09-13) fix compiler warnings + partial animated GIF support + limited 16-bpc PSD support + #ifdef unused functions + bug with < 92 byte PIC,PNM,HDR,TGA + 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value + 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning + 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit + 2.03 (2015-04-12) extra corruption checking (mmozeiko) + stbi_set_flip_vertically_on_load (nguillemot) + fix NEON support; fix mingw support + 2.02 (2015-01-19) fix incorrect assert, fix warning + 2.01 (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2 + 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG + 2.00 (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg) + progressive JPEG (stb) + PGM/PPM support (Ken Miller) + STBI_MALLOC,STBI_REALLOC,STBI_FREE + GIF bugfix -- seemingly never worked + STBI_NO_*, STBI_ONLY_* + 1.48 (2014-12-14) fix incorrectly-named assert() + 1.47 (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb) + optimize PNG (ryg) + fix bug in interlaced PNG with user-specified channel count (stb) + 1.46 (2014-08-26) + fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG + 1.45 (2014-08-16) + fix MSVC-ARM internal compiler error by wrapping malloc + 1.44 (2014-08-07) + various warning fixes from Ronny Chevalier + 1.43 (2014-07-15) + fix MSVC-only compiler problem in code changed in 1.42 + 1.42 (2014-07-09) + don't define _CRT_SECURE_NO_WARNINGS (affects user code) + fixes to stbi__cleanup_jpeg path + added STBI_ASSERT to avoid requiring assert.h + 1.41 (2014-06-25) + fix search&replace from 1.36 that messed up comments/error messages + 1.40 (2014-06-22) + fix gcc struct-initialization warning + 1.39 (2014-06-15) + fix to TGA optimization when req_comp != number of components in TGA; + fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite) + add support for BMP version 5 (more ignored fields) + 1.38 (2014-06-06) + suppress MSVC warnings on integer casts truncating values + fix accidental rename of 'skip' field of I/O + 1.37 (2014-06-04) + remove duplicate typedef + 1.36 (2014-06-03) + convert to header file single-file library + if de-iphone isn't set, load iphone images color-swapped instead of returning NULL + 1.35 (2014-05-27) + various warnings + fix broken STBI_SIMD path + fix bug where stbi_load_from_file no longer left file pointer in correct place + fix broken non-easy path for 32-bit BMP (possibly never used) + TGA optimization by Arseny Kapoulkine + 1.34 (unknown) + use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case + 1.33 (2011-07-14) + make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements + 1.32 (2011-07-13) + support for "info" function for all supported filetypes (SpartanJ) + 1.31 (2011-06-20) + a few more leak fixes, bug in PNG handling (SpartanJ) + 1.30 (2011-06-11) + added ability to load files via callbacks to accomidate custom input streams (Ben Wenger) + removed deprecated format-specific test/load functions + removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway + error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) + fix inefficiency in decoding 32-bit BMP (David Woo) + 1.29 (2010-08-16) + various warning fixes from Aurelien Pocheville + 1.28 (2010-08-01) + fix bug in GIF palette transparency (SpartanJ) + 1.27 (2010-08-01) + cast-to-stbi_uc to fix warnings + 1.26 (2010-07-24) + fix bug in file buffering for PNG reported by SpartanJ + 1.25 (2010-07-17) + refix trans_data warning (Won Chun) + 1.24 (2010-07-12) + perf improvements reading from files on platforms with lock-heavy fgetc() + minor perf improvements for jpeg + deprecated type-specific functions so we'll get feedback if they're needed + attempt to fix trans_data warning (Won Chun) + 1.23 fixed bug in iPhone support + 1.22 (2010-07-10) + removed image *writing* support + stbi_info support from Jetro Lauha + GIF support from Jean-Marc Lienher + iPhone PNG-extensions from James Brown + warning-fixes from Nicolas Schulz and Janez Zemva (i.stbi__err. Janez (U+017D)emva) + 1.21 fix use of 'stbi_uc' in header (reported by jon blow) + 1.20 added support for Softimage PIC, by Tom Seddon + 1.19 bug in interlaced PNG corruption check (found by ryg) + 1.18 (2008-08-02) + fix a threading bug (local mutable static) + 1.17 support interlaced PNG + 1.16 major bugfix - stbi__convert_format converted one too many pixels + 1.15 initialize some fields for thread safety + 1.14 fix threadsafe conversion bug + header-file-only version (#define STBI_HEADER_FILE_ONLY before including) + 1.13 threadsafe + 1.12 const qualifiers in the API + 1.11 Support installable IDCT, colorspace conversion routines + 1.10 Fixes for 64-bit (don't use "unsigned long") + optimized upsampling by Fabian "ryg" Giesen + 1.09 Fix format-conversion for PSD code (bad global variables!) + 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz + 1.07 attempt to fix C++ warning/errors again + 1.06 attempt to fix C++ warning/errors again + 1.05 fix TGA loading to return correct *comp and use good luminance calc + 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free + 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR + 1.02 support for (subset of) HDR files, float interface for preferred access to them + 1.01 fix bug: possible bug in handling right-side up bmps... not sure + fix bug: the stbi__bmp_load() and stbi__tga_load() functions didn't work at all + 1.00 interface to zlib that skips zlib header + 0.99 correct handling of alpha in palette + 0.98 TGA loader by lonesock; dynamically add loaders (untested) + 0.97 jpeg errors on too large a file; also catch another malloc failure + 0.96 fix detection of invalid v value - particleman@mollyrocket forum + 0.95 during header scan, seek to markers in case of padding + 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same + 0.93 handle jpegtran output; verbose errors + 0.92 read 4,8,16,24,32-bit BMP files of several formats + 0.91 output 24-bit Windows 3.0 BMP files + 0.90 fix a few more warnings; bump version number to approach 1.0 + 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd + 0.60 fix compiling as c++ + 0.59 fix warnings: merge Dave Moore's -Wall fixes + 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian + 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available + 0.56 fix bug: zlib uncompressed mode len vs. nlen + 0.55 fix bug: restart_interval not initialized to 0 + 0.54 allow NULL for 'int *comp' + 0.53 fix bug in png 3->4; speedup png decoding + 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments + 0.51 obey req_comp requests, 1-component jpegs return as 1-component, + on 'test' only check type, not whether we support this variant + 0.50 (2006-11-19) + first released version +*/ + + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +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. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +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 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. +------------------------------------------------------------------------------ +*/ diff --git a/hanzi_detection/src/stb_image_write.h b/hanzi_detection/src/stb_image_write.h new file mode 100755 index 0000000..c05e958 --- /dev/null +++ b/hanzi_detection/src/stb_image_write.h @@ -0,0 +1,1568 @@ +/* stb_image_write - v1.09 - public domain - http://nothings.org/stb/stb_image_write.h + writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015 + no warranty implied; use at your own risk + + Before #including, + + #define STB_IMAGE_WRITE_IMPLEMENTATION + + in the file that you want to have the implementation. + + Will probably not work correctly with strict-aliasing optimizations. + + If using a modern Microsoft Compiler, non-safe versions of CRT calls may cause + compilation warnings or even errors. To avoid this, also before #including, + + #define STBI_MSC_SECURE_CRT + +ABOUT: + + This header file is a library for writing images to C stdio. It could be + adapted to write to memory or a general streaming interface; let me know. + + The PNG output is not optimal; it is 20-50% larger than the file + written by a decent optimizing implementation; though providing a custom + zlib compress function (see STBIW_ZLIB_COMPRESS) can mitigate that. + This library is designed for source code compactness and simplicity, + not optimal image file size or run-time performance. + +BUILDING: + + You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h. + You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace + malloc,realloc,free. + You can #define STBIW_MEMMOVE() to replace memmove() + You can #define STBIW_ZLIB_COMPRESS to use a custom zlib-style compress function + for PNG compression (instead of the builtin one), it must have the following signature: + unsigned char * my_compress(unsigned char *data, int data_len, int *out_len, int quality); + The returned data will be freed with STBIW_FREE() (free() by default), + so it must be heap allocated with STBIW_MALLOC() (malloc() by default), + +USAGE: + + There are five functions, one for each image file format: + + int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); + int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); + int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); + int stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality); + int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); + + void stbi_flip_vertically_on_write(int flag); // flag is non-zero to flip data vertically + + There are also five equivalent functions that use an arbitrary write function. You are + expected to open/close your file-equivalent before and after calling these: + + int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes); + int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); + int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); + int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); + int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality); + + where the callback is: + void stbi_write_func(void *context, void *data, int size); + + You can configure it with these global variables: + int stbi_write_tga_with_rle; // defaults to true; set to 0 to disable RLE + int stbi_write_png_compression_level; // defaults to 8; set to higher for more compression + int stbi_write_force_png_filter; // defaults to -1; set to 0..5 to force a filter mode + + + You can define STBI_WRITE_NO_STDIO to disable the file variant of these + functions, so the library will not use stdio.h at all. However, this will + also disable HDR writing, because it requires stdio for formatted output. + + Each function returns 0 on failure and non-0 on success. + + The functions create an image file defined by the parameters. The image + is a rectangle of pixels stored from left-to-right, top-to-bottom. + Each pixel contains 'comp' channels of data stored interleaved with 8-bits + per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is + monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall. + The *data pointer points to the first byte of the top-left-most pixel. + For PNG, "stride_in_bytes" is the distance in bytes from the first byte of + a row of pixels to the first byte of the next row of pixels. + + PNG creates output files with the same number of components as the input. + The BMP format expands Y to RGB in the file format and does not + output alpha. + + PNG supports writing rectangles of data even when the bytes storing rows of + data are not consecutive in memory (e.g. sub-rectangles of a larger image), + by supplying the stride between the beginning of adjacent rows. The other + formats do not. (Thus you cannot write a native-format BMP through the BMP + writer, both because it is in BGR order and because it may have padding + at the end of the line.) + + PNG allows you to set the deflate compression level by setting the global + variable 'stbi_write_png_compression_level' (it defaults to 8). + + HDR expects linear float data. Since the format is always 32-bit rgb(e) + data, alpha (if provided) is discarded, and for monochrome data it is + replicated across all three channels. + + TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed + data, set the global variable 'stbi_write_tga_with_rle' to 0. + + JPEG does ignore alpha channels in input data; quality is between 1 and 100. + Higher quality looks better but results in a bigger image. + JPEG baseline (no JPEG progressive). + +CREDITS: + + + Sean Barrett - PNG/BMP/TGA + Baldur Karlsson - HDR + Jean-Sebastien Guay - TGA monochrome + Tim Kelsey - misc enhancements + Alan Hickman - TGA RLE + Emmanuel Julien - initial file IO callback implementation + Jon Olick - original jo_jpeg.cpp code + Daniel Gibson - integrate JPEG, allow external zlib + Aarni Koskela - allow choosing PNG filter + + bugfixes: + github:Chribba + Guillaume Chereau + github:jry2 + github:romigrou + Sergio Gonzalez + Jonas Karlsson + Filip Wasil + Thatcher Ulrich + github:poppolopoppo + Patrick Boettcher + github:xeekworx + Cap Petschulat + Simon Rodriguez + Ivan Tikhonov + github:ignotion + Adam Schackart + +LICENSE + + See end of file for license information. + +*/ + +#ifndef INCLUDE_STB_IMAGE_WRITE_H +#define INCLUDE_STB_IMAGE_WRITE_H + +// if STB_IMAGE_WRITE_STATIC causes problems, try defining STBIWDEF to 'inline' or 'static inline' +#ifndef STBIWDEF +#ifdef STB_IMAGE_WRITE_STATIC +#define STBIWDEF static +#else +#ifdef __cplusplus +#define STBIWDEF extern "C" +#else +#define STBIWDEF extern +#endif +#endif +#endif + +#ifndef STB_IMAGE_WRITE_STATIC // C++ forbids static forward declarations +extern int stbi_write_tga_with_rle; +extern int stbi_write_png_compression_level; +extern int stbi_write_force_png_filter; +#endif + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); +STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); +STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality); +#endif + +typedef void stbi_write_func(void *context, void *data, int size); + +STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes); +STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); +STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality); + +STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean); + +#endif//INCLUDE_STB_IMAGE_WRITE_H + +#ifdef STB_IMAGE_WRITE_IMPLEMENTATION + +#ifdef _WIN32 + #ifndef _CRT_SECURE_NO_WARNINGS + #define _CRT_SECURE_NO_WARNINGS + #endif + #ifndef _CRT_NONSTDC_NO_DEPRECATE + #define _CRT_NONSTDC_NO_DEPRECATE + #endif +#endif + +#ifndef STBI_WRITE_NO_STDIO +#include +#endif // STBI_WRITE_NO_STDIO + +#include +#include +#include +#include + +#if defined(STBIW_MALLOC) && defined(STBIW_FREE) && (defined(STBIW_REALLOC) || defined(STBIW_REALLOC_SIZED)) +// ok +#elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) && !defined(STBIW_REALLOC_SIZED) +// ok +#else +#error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC (or STBIW_REALLOC_SIZED)." +#endif + +#ifndef STBIW_MALLOC +#define STBIW_MALLOC(sz) malloc(sz) +#define STBIW_REALLOC(p,newsz) realloc(p,newsz) +#define STBIW_FREE(p) free(p) +#endif + +#ifndef STBIW_REALLOC_SIZED +#define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz) +#endif + + +#ifndef STBIW_MEMMOVE +#define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz) +#endif + + +#ifndef STBIW_ASSERT +#include +#define STBIW_ASSERT(x) assert(x) +#endif + +#define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff) + +#ifdef STB_IMAGE_WRITE_STATIC +static int stbi__flip_vertically_on_write=0; +static int stbi_write_png_compression_level = 8; +static int stbi_write_tga_with_rle = 1; +static int stbi_write_force_png_filter = -1; +#else +int stbi_write_png_compression_level = 8; +int stbi__flip_vertically_on_write=0; +int stbi_write_tga_with_rle = 1; +int stbi_write_force_png_filter = -1; +#endif + +STBIWDEF void stbi_flip_vertically_on_write(int flag) +{ + stbi__flip_vertically_on_write = flag; +} + +typedef struct +{ + stbi_write_func *func; + void *context; +} stbi__write_context; + +// initialize a callback-based context +static void stbi__start_write_callbacks(stbi__write_context *s, stbi_write_func *c, void *context) +{ + s->func = c; + s->context = context; +} + +#ifndef STBI_WRITE_NO_STDIO + +static void stbi__stdio_write(void *context, void *data, int size) +{ + fwrite(data,1,size,(FILE*) context); +} + +static int stbi__start_write_file(stbi__write_context *s, const char *filename) +{ + FILE *f; +#ifdef STBI_MSC_SECURE_CRT + if (fopen_s(&f, filename, "wb")) + f = NULL; +#else + f = fopen(filename, "wb"); +#endif + stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f); + return f != NULL; +} + +static void stbi__end_write_file(stbi__write_context *s) +{ + fclose((FILE *)s->context); +} + +#endif // !STBI_WRITE_NO_STDIO + +typedef unsigned int stbiw_uint32; +typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1]; + +static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v) +{ + while (*fmt) { + switch (*fmt++) { + case ' ': break; + case '1': { unsigned char x = STBIW_UCHAR(va_arg(v, int)); + s->func(s->context,&x,1); + break; } + case '2': { int x = va_arg(v,int); + unsigned char b[2]; + b[0] = STBIW_UCHAR(x); + b[1] = STBIW_UCHAR(x>>8); + s->func(s->context,b,2); + break; } + case '4': { stbiw_uint32 x = va_arg(v,int); + unsigned char b[4]; + b[0]=STBIW_UCHAR(x); + b[1]=STBIW_UCHAR(x>>8); + b[2]=STBIW_UCHAR(x>>16); + b[3]=STBIW_UCHAR(x>>24); + s->func(s->context,b,4); + break; } + default: + STBIW_ASSERT(0); + return; + } + } +} + +static void stbiw__writef(stbi__write_context *s, const char *fmt, ...) +{ + va_list v; + va_start(v, fmt); + stbiw__writefv(s, fmt, v); + va_end(v); +} + +static void stbiw__putc(stbi__write_context *s, unsigned char c) +{ + s->func(s->context, &c, 1); +} + +static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c) +{ + unsigned char arr[3]; + arr[0] = a, arr[1] = b, arr[2] = c; + s->func(s->context, arr, 3); +} + +static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d) +{ + unsigned char bg[3] = { 255, 0, 255}, px[3]; + int k; + + if (write_alpha < 0) + s->func(s->context, &d[comp - 1], 1); + + switch (comp) { + case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case + case 1: + if (expand_mono) + stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp + else + s->func(s->context, d, 1); // monochrome TGA + break; + case 4: + if (!write_alpha) { + // composite against pink background + for (k = 0; k < 3; ++k) + px[k] = bg[k] + ((d[k] - bg[k]) * d[3]) / 255; + stbiw__write3(s, px[1 - rgb_dir], px[1], px[1 + rgb_dir]); + break; + } + /* FALLTHROUGH */ + case 3: + stbiw__write3(s, d[1 - rgb_dir], d[1], d[1 + rgb_dir]); + break; + } + if (write_alpha > 0) + s->func(s->context, &d[comp - 1], 1); +} + +static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono) +{ + stbiw_uint32 zero = 0; + int i,j, j_end; + + if (y <= 0) + return; + + if (stbi__flip_vertically_on_write) + vdir *= -1; + + if (vdir < 0) + j_end = -1, j = y-1; + else + j_end = y, j = 0; + + for (; j != j_end; j += vdir) { + for (i=0; i < x; ++i) { + unsigned char *d = (unsigned char *) data + (j*x+i)*comp; + stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d); + } + s->func(s->context, &zero, scanline_pad); + } +} + +static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, int expand_mono, void *data, int alpha, int pad, const char *fmt, ...) +{ + if (y < 0 || x < 0) { + return 0; + } else { + va_list v; + va_start(v, fmt); + stbiw__writefv(s, fmt, v); + va_end(v); + stbiw__write_pixels(s,rgb_dir,vdir,x,y,comp,data,alpha,pad, expand_mono); + return 1; + } +} + +static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data) +{ + int pad = (-x*3) & 3; + return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad, + "11 4 22 4" "4 44 22 444444", + 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header + 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header +} + +STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) +{ + stbi__write_context s; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_bmp_core(&s, x, y, comp, data); +} + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data) +{ + stbi__write_context s; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_bmp_core(&s, x, y, comp, data); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif //!STBI_WRITE_NO_STDIO + +static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, void *data) +{ + int has_alpha = (comp == 2 || comp == 4); + int colorbytes = has_alpha ? comp-1 : comp; + int format = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3 + + if (y < 0 || x < 0) + return 0; + + if (!stbi_write_tga_with_rle) { + return stbiw__outfile(s, -1, -1, x, y, comp, 0, (void *) data, has_alpha, 0, + "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8); + } else { + int i,j,k; + int jend, jdir; + + stbiw__writef(s, "111 221 2222 11", 0,0,format+8, 0,0,0, 0,0,x,y, (colorbytes + has_alpha) * 8, has_alpha * 8); + + if (stbi__flip_vertically_on_write) { + j = 0; + jend = y; + jdir = 1; + } else { + j = y-1; + jend = -1; + jdir = -1; + } + for (; j != jend; j += jdir) { + unsigned char *row = (unsigned char *) data + j * x * comp; + int len; + + for (i = 0; i < x; i += len) { + unsigned char *begin = row + i * comp; + int diff = 1; + len = 1; + + if (i < x - 1) { + ++len; + diff = memcmp(begin, row + (i + 1) * comp, comp); + if (diff) { + const unsigned char *prev = begin; + for (k = i + 2; k < x && len < 128; ++k) { + if (memcmp(prev, row + k * comp, comp)) { + prev += comp; + ++len; + } else { + --len; + break; + } + } + } else { + for (k = i + 2; k < x && len < 128; ++k) { + if (!memcmp(begin, row + k * comp, comp)) { + ++len; + } else { + break; + } + } + } + } + + if (diff) { + unsigned char header = STBIW_UCHAR(len - 1); + s->func(s->context, &header, 1); + for (k = 0; k < len; ++k) { + stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp); + } + } else { + unsigned char header = STBIW_UCHAR(len - 129); + s->func(s->context, &header, 1); + stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin); + } + } + } + } + return 1; +} + +STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) +{ + stbi__write_context s; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_tga_core(&s, x, y, comp, (void *) data); +} + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data) +{ + stbi__write_context s; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_tga_core(&s, x, y, comp, (void *) data); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif + +// ************************************************************************************************* +// Radiance RGBE HDR writer +// by Baldur Karlsson + +#define stbiw__max(a, b) ((a) > (b) ? (a) : (b)) + +void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear) +{ + int exponent; + float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2])); + + if (maxcomp < 1e-32f) { + rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0; + } else { + float normalize = (float) frexp(maxcomp, &exponent) * 256.0f/maxcomp; + + rgbe[0] = (unsigned char)(linear[0] * normalize); + rgbe[1] = (unsigned char)(linear[1] * normalize); + rgbe[2] = (unsigned char)(linear[2] * normalize); + rgbe[3] = (unsigned char)(exponent + 128); + } +} + +void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte) +{ + unsigned char lengthbyte = STBIW_UCHAR(length+128); + STBIW_ASSERT(length+128 <= 255); + s->func(s->context, &lengthbyte, 1); + s->func(s->context, &databyte, 1); +} + +void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data) +{ + unsigned char lengthbyte = STBIW_UCHAR(length); + STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code + s->func(s->context, &lengthbyte, 1); + s->func(s->context, data, length); +} + +void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline) +{ + unsigned char scanlineheader[4] = { 2, 2, 0, 0 }; + unsigned char rgbe[4]; + float linear[3]; + int x; + + scanlineheader[2] = (width&0xff00)>>8; + scanlineheader[3] = (width&0x00ff); + + /* skip RLE for images too small or large */ + if (width < 8 || width >= 32768) { + for (x=0; x < width; x++) { + switch (ncomp) { + case 4: /* fallthrough */ + case 3: linear[2] = scanline[x*ncomp + 2]; + linear[1] = scanline[x*ncomp + 1]; + linear[0] = scanline[x*ncomp + 0]; + break; + default: + linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0]; + break; + } + stbiw__linear_to_rgbe(rgbe, linear); + s->func(s->context, rgbe, 4); + } + } else { + int c,r; + /* encode into scratch buffer */ + for (x=0; x < width; x++) { + switch(ncomp) { + case 4: /* fallthrough */ + case 3: linear[2] = scanline[x*ncomp + 2]; + linear[1] = scanline[x*ncomp + 1]; + linear[0] = scanline[x*ncomp + 0]; + break; + default: + linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0]; + break; + } + stbiw__linear_to_rgbe(rgbe, linear); + scratch[x + width*0] = rgbe[0]; + scratch[x + width*1] = rgbe[1]; + scratch[x + width*2] = rgbe[2]; + scratch[x + width*3] = rgbe[3]; + } + + s->func(s->context, scanlineheader, 4); + + /* RLE each component separately */ + for (c=0; c < 4; c++) { + unsigned char *comp = &scratch[width*c]; + + x = 0; + while (x < width) { + // find first run + r = x; + while (r+2 < width) { + if (comp[r] == comp[r+1] && comp[r] == comp[r+2]) + break; + ++r; + } + if (r+2 >= width) + r = width; + // dump up to first run + while (x < r) { + int len = r-x; + if (len > 128) len = 128; + stbiw__write_dump_data(s, len, &comp[x]); + x += len; + } + // if there's a run, output it + if (r+2 < width) { // same test as what we break out of in search loop, so only true if we break'd + // find next byte after run + while (r < width && comp[r] == comp[x]) + ++r; + // output run up to r + while (x < r) { + int len = r-x; + if (len > 127) len = 127; + stbiw__write_run_data(s, len, comp[x]); + x += len; + } + } + } + } + } +} + +static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, float *data) +{ + if (y <= 0 || x <= 0 || data == NULL) + return 0; + else { + // Each component is stored separately. Allocate scratch space for full output scanline. + unsigned char *scratch = (unsigned char *) STBIW_MALLOC(x*4); + int i, len; + char buffer[128]; + char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n"; + s->func(s->context, header, sizeof(header)-1); + +#ifdef STBI_MSC_SECURE_CRT + len = sprintf_s(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); +#else + len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); +#endif + s->func(s->context, buffer, len); + + for(i=0; i < y; i++) + stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i)*x); + STBIW_FREE(scratch); + return 1; + } +} + +STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data) +{ + stbi__write_context s; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_hdr_core(&s, x, y, comp, (float *) data); +} + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data) +{ + stbi__write_context s; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif // STBI_WRITE_NO_STDIO + + +////////////////////////////////////////////////////////////////////////////// +// +// PNG writer +// + +#ifndef STBIW_ZLIB_COMPRESS +// stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size() +#define stbiw__sbraw(a) ((int *) (a) - 2) +#define stbiw__sbm(a) stbiw__sbraw(a)[0] +#define stbiw__sbn(a) stbiw__sbraw(a)[1] + +#define stbiw__sbneedgrow(a,n) ((a)==0 || stbiw__sbn(a)+n >= stbiw__sbm(a)) +#define stbiw__sbmaybegrow(a,n) (stbiw__sbneedgrow(a,(n)) ? stbiw__sbgrow(a,n) : 0) +#define stbiw__sbgrow(a,n) stbiw__sbgrowf((void **) &(a), (n), sizeof(*(a))) + +#define stbiw__sbpush(a, v) (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v)) +#define stbiw__sbcount(a) ((a) ? stbiw__sbn(a) : 0) +#define stbiw__sbfree(a) ((a) ? STBIW_FREE(stbiw__sbraw(a)),0 : 0) + +static void *stbiw__sbgrowf(void **arr, int increment, int itemsize) +{ + int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1; + void *p = STBIW_REALLOC_SIZED(*arr ? stbiw__sbraw(*arr) : 0, *arr ? (stbiw__sbm(*arr)*itemsize + sizeof(int)*2) : 0, itemsize * m + sizeof(int)*2); + STBIW_ASSERT(p); + if (p) { + if (!*arr) ((int *) p)[1] = 0; + *arr = (void *) ((int *) p + 2); + stbiw__sbm(*arr) = m; + } + return *arr; +} + +static unsigned char *stbiw__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount) +{ + while (*bitcount >= 8) { + stbiw__sbpush(data, STBIW_UCHAR(*bitbuffer)); + *bitbuffer >>= 8; + *bitcount -= 8; + } + return data; +} + +static int stbiw__zlib_bitrev(int code, int codebits) +{ + int res=0; + while (codebits--) { + res = (res << 1) | (code & 1); + code >>= 1; + } + return res; +} + +static unsigned int stbiw__zlib_countm(unsigned char *a, unsigned char *b, int limit) +{ + int i; + for (i=0; i < limit && i < 258; ++i) + if (a[i] != b[i]) break; + return i; +} + +static unsigned int stbiw__zhash(unsigned char *data) +{ + stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16); + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + return hash; +} + +#define stbiw__zlib_flush() (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount)) +#define stbiw__zlib_add(code,codebits) \ + (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush()) +#define stbiw__zlib_huffa(b,c) stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c) +// default huffman tables +#define stbiw__zlib_huff1(n) stbiw__zlib_huffa(0x30 + (n), 8) +#define stbiw__zlib_huff2(n) stbiw__zlib_huffa(0x190 + (n)-144, 9) +#define stbiw__zlib_huff3(n) stbiw__zlib_huffa(0 + (n)-256,7) +#define stbiw__zlib_huff4(n) stbiw__zlib_huffa(0xc0 + (n)-280,8) +#define stbiw__zlib_huff(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : (n) <= 255 ? stbiw__zlib_huff2(n) : (n) <= 279 ? stbiw__zlib_huff3(n) : stbiw__zlib_huff4(n)) +#define stbiw__zlib_huffb(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : stbiw__zlib_huff2(n)) + +#define stbiw__ZHASH 16384 + +#endif // STBIW_ZLIB_COMPRESS + +unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality) +{ +#ifdef STBIW_ZLIB_COMPRESS + // user provided a zlib compress implementation, use that + return STBIW_ZLIB_COMPRESS(data, data_len, out_len, quality); +#else // use builtin + static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 }; + static unsigned char lengtheb[]= { 0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 }; + static unsigned short distc[] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 }; + static unsigned char disteb[] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; + unsigned int bitbuf=0; + int i,j, bitcount=0; + unsigned char *out = NULL; + unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(char**)); + if (hash_table == NULL) + return NULL; + if (quality < 5) quality = 5; + + stbiw__sbpush(out, 0x78); // DEFLATE 32K window + stbiw__sbpush(out, 0x5e); // FLEVEL = 1 + stbiw__zlib_add(1,1); // BFINAL = 1 + stbiw__zlib_add(1,2); // BTYPE = 1 -- fixed huffman + + for (i=0; i < stbiw__ZHASH; ++i) + hash_table[i] = NULL; + + i=0; + while (i < data_len-3) { + // hash next 3 bytes of data to be compressed + int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3; + unsigned char *bestloc = 0; + unsigned char **hlist = hash_table[h]; + int n = stbiw__sbcount(hlist); + for (j=0; j < n; ++j) { + if (hlist[j]-data > i-32768) { // if entry lies within window + int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i); + if (d >= best) best=d,bestloc=hlist[j]; + } + } + // when hash table entry is too long, delete half the entries + if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) { + STBIW_MEMMOVE(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality); + stbiw__sbn(hash_table[h]) = quality; + } + stbiw__sbpush(hash_table[h],data+i); + + if (bestloc) { + // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal + h = stbiw__zhash(data+i+1)&(stbiw__ZHASH-1); + hlist = hash_table[h]; + n = stbiw__sbcount(hlist); + for (j=0; j < n; ++j) { + if (hlist[j]-data > i-32767) { + int e = stbiw__zlib_countm(hlist[j], data+i+1, data_len-i-1); + if (e > best) { // if next match is better, bail on current match + bestloc = NULL; + break; + } + } + } + } + + if (bestloc) { + int d = (int) (data+i - bestloc); // distance back + STBIW_ASSERT(d <= 32767 && best <= 258); + for (j=0; best > lengthc[j+1]-1; ++j); + stbiw__zlib_huff(j+257); + if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]); + for (j=0; d > distc[j+1]-1; ++j); + stbiw__zlib_add(stbiw__zlib_bitrev(j,5),5); + if (disteb[j]) stbiw__zlib_add(d - distc[j], disteb[j]); + i += best; + } else { + stbiw__zlib_huffb(data[i]); + ++i; + } + } + // write out final bytes + for (;i < data_len; ++i) + stbiw__zlib_huffb(data[i]); + stbiw__zlib_huff(256); // end of block + // pad with 0 bits to byte boundary + while (bitcount) + stbiw__zlib_add(0,1); + + for (i=0; i < stbiw__ZHASH; ++i) + (void) stbiw__sbfree(hash_table[i]); + STBIW_FREE(hash_table); + + { + // compute adler32 on input + unsigned int s1=1, s2=0; + int blocklen = (int) (data_len % 5552); + j=0; + while (j < data_len) { + for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1; + s1 %= 65521, s2 %= 65521; + j += blocklen; + blocklen = 5552; + } + stbiw__sbpush(out, STBIW_UCHAR(s2 >> 8)); + stbiw__sbpush(out, STBIW_UCHAR(s2)); + stbiw__sbpush(out, STBIW_UCHAR(s1 >> 8)); + stbiw__sbpush(out, STBIW_UCHAR(s1)); + } + *out_len = stbiw__sbn(out); + // make returned pointer freeable + STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len); + return (unsigned char *) stbiw__sbraw(out); +#endif // STBIW_ZLIB_COMPRESS +} + +static unsigned int stbiw__crc32(unsigned char *buffer, int len) +{ + static unsigned int crc_table[256] = + { + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0eDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D + }; + + unsigned int crc = ~0u; + int i; + for (i=0; i < len; ++i) + crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)]; + return ~crc; +} + +#define stbiw__wpng4(o,a,b,c,d) ((o)[0]=STBIW_UCHAR(a),(o)[1]=STBIW_UCHAR(b),(o)[2]=STBIW_UCHAR(c),(o)[3]=STBIW_UCHAR(d),(o)+=4) +#define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v)); +#define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3]) + +static void stbiw__wpcrc(unsigned char **data, int len) +{ + unsigned int crc = stbiw__crc32(*data - len - 4, len+4); + stbiw__wp32(*data, crc); +} + +static unsigned char stbiw__paeth(int a, int b, int c) +{ + int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c); + if (pa <= pb && pa <= pc) return STBIW_UCHAR(a); + if (pb <= pc) return STBIW_UCHAR(b); + return STBIW_UCHAR(c); +} + +// @OPTIMIZE: provide an option that always forces left-predict or paeth predict +static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int width, int height, int y, int n, int filter_type, signed char *line_buffer) +{ + static int mapping[] = { 0,1,2,3,4 }; + static int firstmap[] = { 0,1,0,5,6 }; + int *mymap = (y != 0) ? mapping : firstmap; + int i; + int type = mymap[filter_type]; + unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y); + int signed_stride = stbi__flip_vertically_on_write ? -stride_bytes : stride_bytes; + for (i = 0; i < n; ++i) { + switch (type) { + case 0: line_buffer[i] = z[i]; break; + case 1: line_buffer[i] = z[i]; break; + case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break; + case 3: line_buffer[i] = z[i] - (z[i-signed_stride]>>1); break; + case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-signed_stride],0)); break; + case 5: line_buffer[i] = z[i]; break; + case 6: line_buffer[i] = z[i]; break; + } + } + for (i=n; i < width*n; ++i) { + switch (type) { + case 0: line_buffer[i] = z[i]; break; + case 1: line_buffer[i] = z[i] - z[i-n]; break; + case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break; + case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-signed_stride])>>1); break; + case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-signed_stride], z[i-signed_stride-n]); break; + case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break; + case 6: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break; + } + } +} + +unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len) +{ + int force_filter = stbi_write_force_png_filter; + int ctype[5] = { -1, 0, 4, 2, 6 }; + unsigned char sig[8] = { 137,80,78,71,13,10,26,10 }; + unsigned char *out,*o, *filt, *zlib; + signed char *line_buffer; + int j,zlen; + + if (stride_bytes == 0) + stride_bytes = x * n; + + if (force_filter >= 5) { + force_filter = -1; + } + + filt = (unsigned char *) STBIW_MALLOC((x*n+1) * y); if (!filt) return 0; + line_buffer = (signed char *) STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; } + for (j=0; j < y; ++j) { + int filter_type; + if (force_filter > -1) { + filter_type = force_filter; + stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, force_filter, line_buffer); + } else { // Estimate the best filter by running through all of them: + int best_filter = 0, best_filter_val = 0x7fffffff, est, i; + for (filter_type = 0; filter_type < 5; filter_type++) { + stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, filter_type, line_buffer); + + // Estimate the entropy of the line using this filter; the less, the better. + est = 0; + for (i = 0; i < x*n; ++i) { + est += abs((signed char) line_buffer[i]); + } + if (est < best_filter_val) { + best_filter_val = est; + best_filter = filter_type; + } + } + if (filter_type != best_filter) { // If the last iteration already got us the best filter, don't redo it + stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, best_filter, line_buffer); + filter_type = best_filter; + } + } + // when we get here, filter_type contains the filter type, and line_buffer contains the data + filt[j*(x*n+1)] = (unsigned char) filter_type; + STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n); + } + STBIW_FREE(line_buffer); + zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, stbi_write_png_compression_level); + STBIW_FREE(filt); + if (!zlib) return 0; + + // each tag requires 12 bytes of overhead + out = (unsigned char *) STBIW_MALLOC(8 + 12+13 + 12+zlen + 12); + if (!out) return 0; + *out_len = 8 + 12+13 + 12+zlen + 12; + + o=out; + STBIW_MEMMOVE(o,sig,8); o+= 8; + stbiw__wp32(o, 13); // header length + stbiw__wptag(o, "IHDR"); + stbiw__wp32(o, x); + stbiw__wp32(o, y); + *o++ = 8; + *o++ = STBIW_UCHAR(ctype[n]); + *o++ = 0; + *o++ = 0; + *o++ = 0; + stbiw__wpcrc(&o,13); + + stbiw__wp32(o, zlen); + stbiw__wptag(o, "IDAT"); + STBIW_MEMMOVE(o, zlib, zlen); + o += zlen; + STBIW_FREE(zlib); + stbiw__wpcrc(&o, zlen); + + stbiw__wp32(o,0); + stbiw__wptag(o, "IEND"); + stbiw__wpcrc(&o,0); + + STBIW_ASSERT(o == out + *out_len); + + return out; +} + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes) +{ + FILE *f; + int len; + unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len); + if (png == NULL) return 0; +#ifdef STBI_MSC_SECURE_CRT + if (fopen_s(&f, filename, "wb")) + f = NULL; +#else + f = fopen(filename, "wb"); +#endif + if (!f) { STBIW_FREE(png); return 0; } + fwrite(png, 1, len, f); + fclose(f); + STBIW_FREE(png); + return 1; +} +#endif + +STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int stride_bytes) +{ + int len; + unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len); + if (png == NULL) return 0; + func(context, png, len); + STBIW_FREE(png); + return 1; +} + + +/* *************************************************************************** + * + * JPEG writer + * + * This is based on Jon Olick's jo_jpeg.cpp: + * public domain Simple, Minimalistic JPEG writer - http://www.jonolick.com/code.html + */ + +static const unsigned char stbiw__jpg_ZigZag[] = { 0,1,5,6,14,15,27,28,2,4,7,13,16,26,29,42,3,8,12,17,25,30,41,43,9,11,18, + 24,31,40,44,53,10,19,23,32,39,45,52,54,20,22,33,38,46,51,55,60,21,34,37,47,50,56,59,61,35,36,48,49,57,58,62,63 }; + +static void stbiw__jpg_writeBits(stbi__write_context *s, int *bitBufP, int *bitCntP, const unsigned short *bs) { + int bitBuf = *bitBufP, bitCnt = *bitCntP; + bitCnt += bs[1]; + bitBuf |= bs[0] << (24 - bitCnt); + while(bitCnt >= 8) { + unsigned char c = (bitBuf >> 16) & 255; + stbiw__putc(s, c); + if(c == 255) { + stbiw__putc(s, 0); + } + bitBuf <<= 8; + bitCnt -= 8; + } + *bitBufP = bitBuf; + *bitCntP = bitCnt; +} + +static void stbiw__jpg_DCT(float *d0p, float *d1p, float *d2p, float *d3p, float *d4p, float *d5p, float *d6p, float *d7p) { + float d0 = *d0p, d1 = *d1p, d2 = *d2p, d3 = *d3p, d4 = *d4p, d5 = *d5p, d6 = *d6p, d7 = *d7p; + float z1, z2, z3, z4, z5, z11, z13; + + float tmp0 = d0 + d7; + float tmp7 = d0 - d7; + float tmp1 = d1 + d6; + float tmp6 = d1 - d6; + float tmp2 = d2 + d5; + float tmp5 = d2 - d5; + float tmp3 = d3 + d4; + float tmp4 = d3 - d4; + + // Even part + float tmp10 = tmp0 + tmp3; // phase 2 + float tmp13 = tmp0 - tmp3; + float tmp11 = tmp1 + tmp2; + float tmp12 = tmp1 - tmp2; + + d0 = tmp10 + tmp11; // phase 3 + d4 = tmp10 - tmp11; + + z1 = (tmp12 + tmp13) * 0.707106781f; // c4 + d2 = tmp13 + z1; // phase 5 + d6 = tmp13 - z1; + + // Odd part + tmp10 = tmp4 + tmp5; // phase 2 + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + // The rotator is modified from fig 4-8 to avoid extra negations. + z5 = (tmp10 - tmp12) * 0.382683433f; // c6 + z2 = tmp10 * 0.541196100f + z5; // c2-c6 + z4 = tmp12 * 1.306562965f + z5; // c2+c6 + z3 = tmp11 * 0.707106781f; // c4 + + z11 = tmp7 + z3; // phase 5 + z13 = tmp7 - z3; + + *d5p = z13 + z2; // phase 6 + *d3p = z13 - z2; + *d1p = z11 + z4; + *d7p = z11 - z4; + + *d0p = d0; *d2p = d2; *d4p = d4; *d6p = d6; +} + +static void stbiw__jpg_calcBits(int val, unsigned short bits[2]) { + int tmp1 = val < 0 ? -val : val; + val = val < 0 ? val-1 : val; + bits[1] = 1; + while(tmp1 >>= 1) { + ++bits[1]; + } + bits[0] = val & ((1<0)&&(DU[end0pos]==0); --end0pos) { + } + // end0pos = first element in reverse order !=0 + if(end0pos == 0) { + stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB); + return DU[0]; + } + for(i = 1; i <= end0pos; ++i) { + int startpos = i; + int nrzeroes; + unsigned short bits[2]; + for (; DU[i]==0 && i<=end0pos; ++i) { + } + nrzeroes = i-startpos; + if ( nrzeroes >= 16 ) { + int lng = nrzeroes>>4; + int nrmarker; + for (nrmarker=1; nrmarker <= lng; ++nrmarker) + stbiw__jpg_writeBits(s, bitBuf, bitCnt, M16zeroes); + nrzeroes &= 15; + } + stbiw__jpg_calcBits(DU[i], bits); + stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTAC[(nrzeroes<<4)+bits[1]]); + stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits); + } + if(end0pos != 63) { + stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB); + } + return DU[0]; +} + +static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, int comp, const void* data, int quality) { + // Constants that don't pollute global namespace + static const unsigned char std_dc_luminance_nrcodes[] = {0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0}; + static const unsigned char std_dc_luminance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11}; + static const unsigned char std_ac_luminance_nrcodes[] = {0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d}; + static const unsigned char std_ac_luminance_values[] = { + 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08, + 0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28, + 0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59, + 0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89, + 0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6, + 0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2, + 0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa + }; + static const unsigned char std_dc_chrominance_nrcodes[] = {0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0}; + static const unsigned char std_dc_chrominance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11}; + static const unsigned char std_ac_chrominance_nrcodes[] = {0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77}; + static const unsigned char std_ac_chrominance_values[] = { + 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91, + 0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26, + 0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58, + 0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87, + 0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4, + 0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda, + 0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa + }; + // Huffman tables + static const unsigned short YDC_HT[256][2] = { {0,2},{2,3},{3,3},{4,3},{5,3},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9}}; + static const unsigned short UVDC_HT[256][2] = { {0,2},{1,2},{2,2},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9},{1022,10},{2046,11}}; + static const unsigned short YAC_HT[256][2] = { + {10,4},{0,2},{1,2},{4,3},{11,4},{26,5},{120,7},{248,8},{1014,10},{65410,16},{65411,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {12,4},{27,5},{121,7},{502,9},{2038,11},{65412,16},{65413,16},{65414,16},{65415,16},{65416,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {28,5},{249,8},{1015,10},{4084,12},{65417,16},{65418,16},{65419,16},{65420,16},{65421,16},{65422,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {58,6},{503,9},{4085,12},{65423,16},{65424,16},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {59,6},{1016,10},{65430,16},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {122,7},{2039,11},{65438,16},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {123,7},{4086,12},{65446,16},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {250,8},{4087,12},{65454,16},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {504,9},{32704,15},{65462,16},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {505,9},{65470,16},{65471,16},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {506,9},{65479,16},{65480,16},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {1017,10},{65488,16},{65489,16},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {1018,10},{65497,16},{65498,16},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {2040,11},{65506,16},{65507,16},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {65515,16},{65516,16},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{0,0},{0,0},{0,0},{0,0},{0,0}, + {2041,11},{65525,16},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0} + }; + static const unsigned short UVAC_HT[256][2] = { + {0,2},{1,2},{4,3},{10,4},{24,5},{25,5},{56,6},{120,7},{500,9},{1014,10},{4084,12},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {11,4},{57,6},{246,8},{501,9},{2038,11},{4085,12},{65416,16},{65417,16},{65418,16},{65419,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {26,5},{247,8},{1015,10},{4086,12},{32706,15},{65420,16},{65421,16},{65422,16},{65423,16},{65424,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {27,5},{248,8},{1016,10},{4087,12},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{65430,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {58,6},{502,9},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{65438,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {59,6},{1017,10},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{65446,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {121,7},{2039,11},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{65454,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {122,7},{2040,11},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{65462,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {249,8},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{65470,16},{65471,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {503,9},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{65479,16},{65480,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {504,9},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{65488,16},{65489,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {505,9},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{65497,16},{65498,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {506,9},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{65506,16},{65507,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {2041,11},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{65515,16},{65516,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {16352,14},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{65525,16},{0,0},{0,0},{0,0},{0,0},{0,0}, + {1018,10},{32707,15},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0} + }; + static const int YQT[] = {16,11,10,16,24,40,51,61,12,12,14,19,26,58,60,55,14,13,16,24,40,57,69,56,14,17,22,29,51,87,80,62,18,22, + 37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99}; + static const int UVQT[] = {17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99, + 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99}; + static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f, + 1.0f * 2.828427125f, 0.785694958f * 2.828427125f, 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f }; + + int row, col, i, k; + float fdtbl_Y[64], fdtbl_UV[64]; + unsigned char YTable[64], UVTable[64]; + + if(!data || !width || !height || comp > 4 || comp < 1) { + return 0; + } + + quality = quality ? quality : 90; + quality = quality < 1 ? 1 : quality > 100 ? 100 : quality; + quality = quality < 50 ? 5000 / quality : 200 - quality * 2; + + for(i = 0; i < 64; ++i) { + int uvti, yti = (YQT[i]*quality+50)/100; + YTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (yti < 1 ? 1 : yti > 255 ? 255 : yti); + uvti = (UVQT[i]*quality+50)/100; + UVTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (uvti < 1 ? 1 : uvti > 255 ? 255 : uvti); + } + + for(row = 0, k = 0; row < 8; ++row) { + for(col = 0; col < 8; ++col, ++k) { + fdtbl_Y[k] = 1 / (YTable [stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]); + fdtbl_UV[k] = 1 / (UVTable[stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]); + } + } + + // Write Headers + { + static const unsigned char head0[] = { 0xFF,0xD8,0xFF,0xE0,0,0x10,'J','F','I','F',0,1,1,0,0,1,0,1,0,0,0xFF,0xDB,0,0x84,0 }; + static const unsigned char head2[] = { 0xFF,0xDA,0,0xC,3,1,0,2,0x11,3,0x11,0,0x3F,0 }; + const unsigned char head1[] = { 0xFF,0xC0,0,0x11,8,(unsigned char)(height>>8),STBIW_UCHAR(height),(unsigned char)(width>>8),STBIW_UCHAR(width), + 3,1,0x11,0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 }; + s->func(s->context, (void*)head0, sizeof(head0)); + s->func(s->context, (void*)YTable, sizeof(YTable)); + stbiw__putc(s, 1); + s->func(s->context, UVTable, sizeof(UVTable)); + s->func(s->context, (void*)head1, sizeof(head1)); + s->func(s->context, (void*)(std_dc_luminance_nrcodes+1), sizeof(std_dc_luminance_nrcodes)-1); + s->func(s->context, (void*)std_dc_luminance_values, sizeof(std_dc_luminance_values)); + stbiw__putc(s, 0x10); // HTYACinfo + s->func(s->context, (void*)(std_ac_luminance_nrcodes+1), sizeof(std_ac_luminance_nrcodes)-1); + s->func(s->context, (void*)std_ac_luminance_values, sizeof(std_ac_luminance_values)); + stbiw__putc(s, 1); // HTUDCinfo + s->func(s->context, (void*)(std_dc_chrominance_nrcodes+1), sizeof(std_dc_chrominance_nrcodes)-1); + s->func(s->context, (void*)std_dc_chrominance_values, sizeof(std_dc_chrominance_values)); + stbiw__putc(s, 0x11); // HTUACinfo + s->func(s->context, (void*)(std_ac_chrominance_nrcodes+1), sizeof(std_ac_chrominance_nrcodes)-1); + s->func(s->context, (void*)std_ac_chrominance_values, sizeof(std_ac_chrominance_values)); + s->func(s->context, (void*)head2, sizeof(head2)); + } + + // Encode 8x8 macroblocks + { + static const unsigned short fillBits[] = {0x7F, 7}; + const unsigned char *imageData = (const unsigned char *)data; + int DCY=0, DCU=0, DCV=0; + int bitBuf=0, bitCnt=0; + // comp == 2 is grey+alpha (alpha is ignored) + int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0; + int x, y, pos; + for(y = 0; y < height; y += 8) { + for(x = 0; x < width; x += 8) { + float YDU[64], UDU[64], VDU[64]; + for(row = y, pos = 0; row < y+8; ++row) { + for(col = x; col < x+8; ++col, ++pos) { + int p = (stbi__flip_vertically_on_write ? height-1-row : row)*width*comp + col*comp; + float r, g, b; + if(row >= height) { + p -= width*comp*(row+1 - height); + } + if(col >= width) { + p -= comp*(col+1 - width); + } + + r = imageData[p+0]; + g = imageData[p+ofsG]; + b = imageData[p+ofsB]; + YDU[pos]=+0.29900f*r+0.58700f*g+0.11400f*b-128; + UDU[pos]=-0.16874f*r-0.33126f*g+0.50000f*b; + VDU[pos]=+0.50000f*r-0.41869f*g-0.08131f*b; + } + } + + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); + DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); + } + } + + // Do the bit alignment of the EOI marker + stbiw__jpg_writeBits(s, &bitBuf, &bitCnt, fillBits); + } + + // EOI + stbiw__putc(s, 0xFF); + stbiw__putc(s, 0xD9); + + return 1; +} + +STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality) +{ + stbi__write_context s; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_jpg_core(&s, x, y, comp, (void *) data, quality); +} + + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality) +{ + stbi__write_context s; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_jpg_core(&s, x, y, comp, data, quality); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif + +#endif // STB_IMAGE_WRITE_IMPLEMENTATION + +/* Revision history + 1.09 (2018-02-11) + fix typo in zlib quality API, improve STB_I_W_STATIC in C++ + 1.08 (2018-01-29) + add stbi__flip_vertically_on_write, external zlib, zlib quality, choose PNG filter + 1.07 (2017-07-24) + doc fix + 1.06 (2017-07-23) + writing JPEG (using Jon Olick's code) + 1.05 ??? + 1.04 (2017-03-03) + monochrome BMP expansion + 1.03 ??? + 1.02 (2016-04-02) + avoid allocating large structures on the stack + 1.01 (2016-01-16) + STBIW_REALLOC_SIZED: support allocators with no realloc support + avoid race-condition in crc initialization + minor compile issues + 1.00 (2015-09-14) + installable file IO function + 0.99 (2015-09-13) + warning fixes; TGA rle support + 0.98 (2015-04-08) + added STBIW_MALLOC, STBIW_ASSERT etc + 0.97 (2015-01-18) + fixed HDR asserts, rewrote HDR rle logic + 0.96 (2015-01-17) + add HDR output + fix monochrome BMP + 0.95 (2014-08-17) + add monochrome TGA output + 0.94 (2014-05-31) + rename private functions to avoid conflicts with stb_image.h + 0.93 (2014-05-27) + warning fixes + 0.92 (2010-08-01) + casts to unsigned char to fix warnings + 0.91 (2010-07-17) + first public release + 0.90 first internal release +*/ + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +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. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +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 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. +------------------------------------------------------------------------------ +*/ diff --git a/hanzi_detection/src/tree.c b/hanzi_detection/src/tree.c new file mode 100755 index 0000000..67b6d43 --- /dev/null +++ b/hanzi_detection/src/tree.c @@ -0,0 +1,139 @@ +#include +#include +#include "tree.h" +#include "utils.h" +#include "data.h" + +void change_leaves(tree *t, char *leaf_list) +{ + list *llist = get_paths(leaf_list); + char **leaves = (char **)list_to_array(llist); + int n = llist->size; + int i,j; + int found = 0; + for(i = 0; i < t->n; ++i){ + t->leaf[i] = 0; + for(j = 0; j < n; ++j){ + if (0==strcmp(t->name[i], leaves[j])){ + t->leaf[i] = 1; + ++found; + break; + } + } + } + fprintf(stderr, "Found %d leaves.\n", found); +} + +float get_hierarchy_probability(float *x, tree *hier, int c, int stride) +{ + float p = 1; + while(c >= 0){ + p = p * x[c*stride]; + c = hier->parent[c]; + } + return p; +} + +void hierarchy_predictions(float *predictions, int n, tree *hier, int only_leaves, int stride) +{ + int j; + for(j = 0; j < n; ++j){ + int parent = hier->parent[j]; + if(parent >= 0){ + predictions[j*stride] *= predictions[parent*stride]; + } + } + if(only_leaves){ + for(j = 0; j < n; ++j){ + if(!hier->leaf[j]) predictions[j*stride] = 0; + } + } +} + +int hierarchy_top_prediction(float *predictions, tree *hier, float thresh, int stride) +{ + float p = 1; + int group = 0; + int i; + while(1){ + float max = 0; + int max_i = 0; + + for(i = 0; i < hier->group_size[group]; ++i){ + int index = i + hier->group_offset[group]; + float val = predictions[(i + hier->group_offset[group])*stride]; + if(val > max){ + max_i = index; + max = val; + } + } + if(p*max > thresh){ + p = p*max; + group = hier->child[max_i]; + if(hier->child[max_i] < 0) return max_i; + } else if (group == 0){ + return max_i; + } else { + return hier->parent[hier->group_offset[group]]; + } + } + return 0; +} + +tree *read_tree(char *filename) +{ + tree t = {0}; + FILE *fp = fopen(filename, "r"); + + char *line; + int last_parent = -1; + int group_size = 0; + int groups = 0; + int n = 0; + while((line=fgetl(fp)) != 0){ + char *id = calloc(256, sizeof(char)); + int parent = -1; + sscanf(line, "%s %d", id, &parent); + t.parent = realloc(t.parent, (n+1)*sizeof(int)); + t.parent[n] = parent; + + t.child = realloc(t.child, (n+1)*sizeof(int)); + t.child[n] = -1; + + t.name = realloc(t.name, (n+1)*sizeof(char *)); + t.name[n] = id; + if(parent != last_parent){ + ++groups; + t.group_offset = realloc(t.group_offset, groups * sizeof(int)); + t.group_offset[groups - 1] = n - group_size; + t.group_size = realloc(t.group_size, groups * sizeof(int)); + t.group_size[groups - 1] = group_size; + group_size = 0; + last_parent = parent; + } + t.group = realloc(t.group, (n+1)*sizeof(int)); + t.group[n] = groups; + if (parent >= 0) { + t.child[parent] = groups; + } + ++n; + ++group_size; + } + ++groups; + t.group_offset = realloc(t.group_offset, groups * sizeof(int)); + t.group_offset[groups - 1] = n - group_size; + t.group_size = realloc(t.group_size, groups * sizeof(int)); + t.group_size[groups - 1] = group_size; + t.n = n; + t.groups = groups; + t.leaf = calloc(n, sizeof(int)); + int i; + for(i = 0; i < n; ++i) t.leaf[i] = 1; + for(i = 0; i < n; ++i) if(t.parent[i] >= 0) t.leaf[t.parent[i]] = 0; + + fclose(fp); + tree *tree_ptr = calloc(1, sizeof(tree)); + *tree_ptr = t; + //error(0); + return tree_ptr; +} diff --git a/hanzi_detection/src/tree.h b/hanzi_detection/src/tree.h new file mode 100755 index 0000000..3802b8e --- /dev/null +++ b/hanzi_detection/src/tree.h @@ -0,0 +1,8 @@ +#ifndef TREE_H +#define TREE_H +#include "darknet.h" + +int hierarchy_top_prediction(float *predictions, tree *hier, float thresh, int stride); +float get_hierarchy_probability(float *x, tree *hier, int c, int stride); + +#endif diff --git a/hanzi_detection/src/upsample_layer.c b/hanzi_detection/src/upsample_layer.c new file mode 100755 index 0000000..605f21f --- /dev/null +++ b/hanzi_detection/src/upsample_layer.c @@ -0,0 +1,106 @@ +#include "upsample_layer.h" +#include "cuda.h" +#include "blas.h" + +#include + +layer make_upsample_layer(int batch, int w, int h, int c, int stride) +{ + layer l = {0}; + l.type = UPSAMPLE; + l.batch = batch; + l.w = w; + l.h = h; + l.c = c; + l.out_w = w*stride; + l.out_h = h*stride; + l.out_c = c; + if(stride < 0){ + stride = -stride; + l.reverse=1; + l.out_w = w/stride; + l.out_h = h/stride; + } + l.stride = stride; + l.outputs = l.out_w*l.out_h*l.out_c; + l.inputs = l.w*l.h*l.c; + l.delta = calloc(l.outputs*batch, sizeof(float)); + l.output = calloc(l.outputs*batch, sizeof(float));; + + l.forward = forward_upsample_layer; + l.backward = backward_upsample_layer; + #ifdef GPU + l.forward_gpu = forward_upsample_layer_gpu; + l.backward_gpu = backward_upsample_layer_gpu; + + l.delta_gpu = cuda_make_array(l.delta, l.outputs*batch); + l.output_gpu = cuda_make_array(l.output, l.outputs*batch); + #endif + if(l.reverse) fprintf(stderr, "downsample %2dx %4d x%4d x%4d -> %4d x%4d x%4d\n", stride, w, h, c, l.out_w, l.out_h, l.out_c); + else fprintf(stderr, "upsample %2dx %4d x%4d x%4d -> %4d x%4d x%4d\n", stride, w, h, c, l.out_w, l.out_h, l.out_c); + return l; +} + +void resize_upsample_layer(layer *l, int w, int h) +{ + l->w = w; + l->h = h; + l->out_w = w*l->stride; + l->out_h = h*l->stride; + if(l->reverse){ + l->out_w = w/l->stride; + l->out_h = h/l->stride; + } + l->outputs = l->out_w*l->out_h*l->out_c; + l->inputs = l->h*l->w*l->c; + l->delta = realloc(l->delta, l->outputs*l->batch*sizeof(float)); + l->output = realloc(l->output, l->outputs*l->batch*sizeof(float)); + +#ifdef GPU + cuda_free(l->output_gpu); + cuda_free(l->delta_gpu); + l->output_gpu = cuda_make_array(l->output, l->outputs*l->batch); + l->delta_gpu = cuda_make_array(l->delta, l->outputs*l->batch); +#endif + +} + +void forward_upsample_layer(const layer l, network net) +{ + fill_cpu(l.outputs*l.batch, 0, l.output, 1); + if(l.reverse){ + upsample_cpu(l.output, l.out_w, l.out_h, l.c, l.batch, l.stride, 0, l.scale, net.input); + }else{ + upsample_cpu(net.input, l.w, l.h, l.c, l.batch, l.stride, 1, l.scale, l.output); + } +} + +void backward_upsample_layer(const layer l, network net) +{ + if(l.reverse){ + upsample_cpu(l.delta, l.out_w, l.out_h, l.c, l.batch, l.stride, 1, l.scale, net.delta); + }else{ + upsample_cpu(net.delta, l.w, l.h, l.c, l.batch, l.stride, 0, l.scale, l.delta); + } +} + +#ifdef GPU +void forward_upsample_layer_gpu(const layer l, network net) +{ + fill_gpu(l.outputs*l.batch, 0, l.output_gpu, 1); + if(l.reverse){ + upsample_gpu(l.output_gpu, l.out_w, l.out_h, l.c, l.batch, l.stride, 0, l.scale, net.input_gpu); + }else{ + upsample_gpu(net.input_gpu, l.w, l.h, l.c, l.batch, l.stride, 1, l.scale, l.output_gpu); + } +} + +void backward_upsample_layer_gpu(const layer l, network net) +{ + if(l.reverse){ + upsample_gpu(l.delta_gpu, l.out_w, l.out_h, l.c, l.batch, l.stride, 1, l.scale, net.delta_gpu); + }else{ + upsample_gpu(net.delta_gpu, l.w, l.h, l.c, l.batch, l.stride, 0, l.scale, l.delta_gpu); + } +} +#endif diff --git a/hanzi_detection/src/upsample_layer.h b/hanzi_detection/src/upsample_layer.h new file mode 100755 index 0000000..86790d1 --- /dev/null +++ b/hanzi_detection/src/upsample_layer.h @@ -0,0 +1,15 @@ +#ifndef UPSAMPLE_LAYER_H +#define UPSAMPLE_LAYER_H +#include "darknet.h" + +layer make_upsample_layer(int batch, int w, int h, int c, int stride); +void forward_upsample_layer(const layer l, network net); +void backward_upsample_layer(const layer l, network net); +void resize_upsample_layer(layer *l, int w, int h); + +#ifdef GPU +void forward_upsample_layer_gpu(const layer l, network net); +void backward_upsample_layer_gpu(const layer l, network net); +#endif + +#endif diff --git a/hanzi_detection/src/utils.c b/hanzi_detection/src/utils.c new file mode 100755 index 0000000..626b467 --- /dev/null +++ b/hanzi_detection/src/utils.c @@ -0,0 +1,726 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" + + +/* +// old timing. is it better? who knows!! +double get_wall_time() +{ + struct timeval time; + if (gettimeofday(&time,NULL)){ + return 0; + } + return (double)time.tv_sec + (double)time.tv_usec * .000001; +} +*/ + +double what_time_is_it_now() +{ + struct timeval time; + if (gettimeofday(&time,NULL)){ + return 0; + } + return (double)time.tv_sec + (double)time.tv_usec * .000001; +} + +int *read_intlist(char *gpu_list, int *ngpus, int d) +{ + int *gpus = 0; + if(gpu_list){ + int len = strlen(gpu_list); + *ngpus = 1; + int i; + for(i = 0; i < len; ++i){ + if (gpu_list[i] == ',') ++*ngpus; + } + gpus = calloc(*ngpus, sizeof(int)); + for(i = 0; i < *ngpus; ++i){ + gpus[i] = atoi(gpu_list); + gpu_list = strchr(gpu_list, ',')+1; + } + } else { + gpus = calloc(1, sizeof(float)); + *gpus = d; + *ngpus = 1; + } + return gpus; +} + +int *read_map(char *filename) +{ + int n = 0; + int *map = 0; + char *str; + FILE *file = fopen(filename, "r"); + if(!file) file_error(filename); + while((str=fgetl(file))){ + ++n; + map = realloc(map, n*sizeof(int)); + map[n-1] = atoi(str); + } + return map; +} + +void sorta_shuffle(void *arr, size_t n, size_t size, size_t sections) +{ + size_t i; + for(i = 0; i < sections; ++i){ + size_t start = n*i/sections; + size_t end = n*(i+1)/sections; + size_t num = end-start; + shuffle(arr+(start*size), num, size); + } +} + +void shuffle(void *arr, size_t n, size_t size) +{ + size_t i; + void *swp = calloc(1, size); + for(i = 0; i < n-1; ++i){ + size_t j = i + rand()/(RAND_MAX / (n-i)+1); + memcpy(swp, arr+(j*size), size); + memcpy(arr+(j*size), arr+(i*size), size); + memcpy(arr+(i*size), swp, size); + } +} + +int *random_index_order(int min, int max) +{ + int *inds = calloc(max-min, sizeof(int)); + int i; + for(i = min; i < max; ++i){ + inds[i] = i; + } + for(i = min; i < max-1; ++i){ + int swap = inds[i]; + int index = i + rand()%(max-i); + inds[i] = inds[index]; + inds[index] = swap; + } + return inds; +} + +void del_arg(int argc, char **argv, int index) +{ + int i; + for(i = index; i < argc-1; ++i) argv[i] = argv[i+1]; + argv[i] = 0; +} + +int find_arg(int argc, char* argv[], char *arg) +{ + int i; + for(i = 0; i < argc; ++i) { + if(!argv[i]) continue; + if(0==strcmp(argv[i], arg)) { + del_arg(argc, argv, i); + return 1; + } + } + return 0; +} + +int find_int_arg(int argc, char **argv, char *arg, int def) +{ + int i; + for(i = 0; i < argc-1; ++i){ + if(!argv[i]) continue; + if(0==strcmp(argv[i], arg)){ + def = atoi(argv[i+1]); + del_arg(argc, argv, i); + del_arg(argc, argv, i); + break; + } + } + return def; +} + +float find_float_arg(int argc, char **argv, char *arg, float def) +{ + int i; + for(i = 0; i < argc-1; ++i){ + if(!argv[i]) continue; + if(0==strcmp(argv[i], arg)){ + def = atof(argv[i+1]); + del_arg(argc, argv, i); + del_arg(argc, argv, i); + break; + } + } + return def; +} + +char *find_char_arg(int argc, char **argv, char *arg, char *def) +{ + int i; + for(i = 0; i < argc-1; ++i){ + if(!argv[i]) continue; + if(0==strcmp(argv[i], arg)){ + def = argv[i+1]; + del_arg(argc, argv, i); + del_arg(argc, argv, i); + break; + } + } + return def; +} + + +char *basecfg(char *cfgfile) +{ + char *c = cfgfile; + char *next; + while((next = strchr(c, '/'))) + { + c = next+1; + } + c = copy_string(c); + next = strchr(c, '.'); + if (next) *next = 0; + return c; +} + +int alphanum_to_int(char c) +{ + return (c < 58) ? c - 48 : c-87; +} +char int_to_alphanum(int i) +{ + if (i == 36) return '.'; + return (i < 10) ? i + 48 : i + 87; +} + +void pm(int M, int N, float *A) +{ + int i,j; + for(i =0 ; i < M; ++i){ + printf("%d ", i+1); + for(j = 0; j < N; ++j){ + printf("%2.4f, ", A[i*N+j]); + } + printf("\n"); + } + printf("\n"); +} + +void find_replace(char *str, char *orig, char *rep, char *output) +{ + char buffer[4096] = {0}; + char *p; + + sprintf(buffer, "%s", str); + if(!(p = strstr(buffer, orig))){ // Is 'orig' even in 'str'? + sprintf(output, "%s", str); + return; + } + + *p = '\0'; + + sprintf(output, "%s%s%s", buffer, rep, p+strlen(orig)); +} + +float sec(clock_t clocks) +{ + return (float)clocks/CLOCKS_PER_SEC; +} + +void top_k(float *a, int n, int k, int *index) +{ + int i,j; + for(j = 0; j < k; ++j) index[j] = -1; + for(i = 0; i < n; ++i){ + int curr = i; + for(j = 0; j < k; ++j){ + if((index[j] < 0) || a[curr] > a[index[j]]){ + int swap = curr; + curr = index[j]; + index[j] = swap; + } + } + } +} + +void error(const char *s) +{ + perror(s); + assert(0); + exit(-1); +} + +unsigned char *read_file(char *filename) +{ + FILE *fp = fopen(filename, "rb"); + size_t size; + + fseek(fp, 0, SEEK_END); + size = ftell(fp); + fseek(fp, 0, SEEK_SET); + + unsigned char *text = calloc(size+1, sizeof(char)); + fread(text, 1, size, fp); + fclose(fp); + return text; +} + +void malloc_error() +{ + fprintf(stderr, "Malloc error\n"); + exit(-1); +} + +void file_error(char *s) +{ + fprintf(stderr, "Couldn't open file: %s\n", s); + exit(0); +} + +list *split_str(char *s, char delim) +{ + size_t i; + size_t len = strlen(s); + list *l = make_list(); + list_insert(l, s); + for(i = 0; i < len; ++i){ + if(s[i] == delim){ + s[i] = '\0'; + list_insert(l, &(s[i+1])); + } + } + return l; +} + +void strip(char *s) +{ + size_t i; + size_t len = strlen(s); + size_t offset = 0; + for(i = 0; i < len; ++i){ + char c = s[i]; + if(c==' '||c=='\t'||c=='\n') ++offset; + else s[i-offset] = c; + } + s[len-offset] = '\0'; +} + +void strip_char(char *s, char bad) +{ + size_t i; + size_t len = strlen(s); + size_t offset = 0; + for(i = 0; i < len; ++i){ + char c = s[i]; + if(c==bad) ++offset; + else s[i-offset] = c; + } + s[len-offset] = '\0'; +} + +void free_ptrs(void **ptrs, int n) +{ + int i; + for(i = 0; i < n; ++i) free(ptrs[i]); + free(ptrs); +} + +char *fgetl(FILE *fp) +{ + if(feof(fp)) return 0; + size_t size = 512; + char *line = malloc(size*sizeof(char)); + if(!fgets(line, size, fp)){ + free(line); + return 0; + } + + size_t curr = strlen(line); + + while((line[curr-1] != '\n') && !feof(fp)){ + if(curr == size-1){ + size *= 2; + line = realloc(line, size*sizeof(char)); + if(!line) { + printf("%ld\n", size); + malloc_error(); + } + } + size_t readsize = size-curr; + if(readsize > INT_MAX) readsize = INT_MAX-1; + fgets(&line[curr], readsize, fp); + curr = strlen(line); + } + if(line[curr-1] == '\n') line[curr-1] = '\0'; + + return line; +} + +int read_int(int fd) +{ + int n = 0; + int next = read(fd, &n, sizeof(int)); + if(next <= 0) return -1; + return n; +} + +void write_int(int fd, int n) +{ + int next = write(fd, &n, sizeof(int)); + if(next <= 0) error("read failed"); +} + +int read_all_fail(int fd, char *buffer, size_t bytes) +{ + size_t n = 0; + while(n < bytes){ + int next = read(fd, buffer + n, bytes-n); + if(next <= 0) return 1; + n += next; + } + return 0; +} + +int write_all_fail(int fd, char *buffer, size_t bytes) +{ + size_t n = 0; + while(n < bytes){ + size_t next = write(fd, buffer + n, bytes-n); + if(next <= 0) return 1; + n += next; + } + return 0; +} + +void read_all(int fd, char *buffer, size_t bytes) +{ + size_t n = 0; + while(n < bytes){ + int next = read(fd, buffer + n, bytes-n); + if(next <= 0) error("read failed"); + n += next; + } +} + +void write_all(int fd, char *buffer, size_t bytes) +{ + size_t n = 0; + while(n < bytes){ + size_t next = write(fd, buffer + n, bytes-n); + if(next <= 0) error("write failed"); + n += next; + } +} + + +char *copy_string(char *s) +{ + char *copy = malloc(strlen(s)+1); + strncpy(copy, s, strlen(s)+1); + return copy; +} + +list *parse_csv_line(char *line) +{ + list *l = make_list(); + char *c, *p; + int in = 0; + for(c = line, p = line; *c != '\0'; ++c){ + if(*c == '"') in = !in; + else if(*c == ',' && !in){ + *c = '\0'; + list_insert(l, copy_string(p)); + p = c+1; + } + } + list_insert(l, copy_string(p)); + return l; +} + +int count_fields(char *line) +{ + int count = 0; + int done = 0; + char *c; + for(c = line; !done; ++c){ + done = (*c == '\0'); + if(*c == ',' || done) ++count; + } + return count; +} + +float *parse_fields(char *line, int n) +{ + float *field = calloc(n, sizeof(float)); + char *c, *p, *end; + int count = 0; + int done = 0; + for(c = line, p = line; !done; ++c){ + done = (*c == '\0'); + if(*c == ',' || done){ + *c = '\0'; + field[count] = strtod(p, &end); + if(p == c) field[count] = nan(""); + if(end != c && (end != c-1 || *end != '\r')) field[count] = nan(""); //DOS file formats! + p = c+1; + ++count; + } + } + return field; +} + +float sum_array(float *a, int n) +{ + int i; + float sum = 0; + for(i = 0; i < n; ++i) sum += a[i]; + return sum; +} + +float mean_array(float *a, int n) +{ + return sum_array(a,n)/n; +} + +void mean_arrays(float **a, int n, int els, float *avg) +{ + int i; + int j; + memset(avg, 0, els*sizeof(float)); + for(j = 0; j < n; ++j){ + for(i = 0; i < els; ++i){ + avg[i] += a[j][i]; + } + } + for(i = 0; i < els; ++i){ + avg[i] /= n; + } +} + +void print_statistics(float *a, int n) +{ + float m = mean_array(a, n); + float v = variance_array(a, n); + printf("MSE: %.6f, Mean: %.6f, Variance: %.6f\n", mse_array(a, n), m, v); +} + +float variance_array(float *a, int n) +{ + int i; + float sum = 0; + float mean = mean_array(a, n); + for(i = 0; i < n; ++i) sum += (a[i] - mean)*(a[i]-mean); + float variance = sum/n; + return variance; +} + +int constrain_int(int a, int min, int max) +{ + if (a < min) return min; + if (a > max) return max; + return a; +} + +float constrain(float min, float max, float a) +{ + if (a < min) return min; + if (a > max) return max; + return a; +} + +float dist_array(float *a, float *b, int n, int sub) +{ + int i; + float sum = 0; + for(i = 0; i < n; i += sub) sum += pow(a[i]-b[i], 2); + return sqrt(sum); +} + +float mse_array(float *a, int n) +{ + int i; + float sum = 0; + for(i = 0; i < n; ++i) sum += a[i]*a[i]; + return sqrt(sum/n); +} + +void normalize_array(float *a, int n) +{ + int i; + float mu = mean_array(a,n); + float sigma = sqrt(variance_array(a,n)); + for(i = 0; i < n; ++i){ + a[i] = (a[i] - mu)/sigma; + } + mu = mean_array(a,n); + sigma = sqrt(variance_array(a,n)); +} + +void translate_array(float *a, int n, float s) +{ + int i; + for(i = 0; i < n; ++i){ + a[i] += s; + } +} + +float mag_array(float *a, int n) +{ + int i; + float sum = 0; + for(i = 0; i < n; ++i){ + sum += a[i]*a[i]; + } + return sqrt(sum); +} + +void scale_array(float *a, int n, float s) +{ + int i; + for(i = 0; i < n; ++i){ + a[i] *= s; + } +} + +int sample_array(float *a, int n) +{ + float sum = sum_array(a, n); + scale_array(a, n, 1./sum); + float r = rand_uniform(0, 1); + int i; + for(i = 0; i < n; ++i){ + r = r - a[i]; + if (r <= 0) return i; + } + return n-1; +} + +int max_int_index(int *a, int n) +{ + if(n <= 0) return -1; + int i, max_i = 0; + int max = a[0]; + for(i = 1; i < n; ++i){ + if(a[i] > max){ + max = a[i]; + max_i = i; + } + } + return max_i; +} + +int max_index(float *a, int n) +{ + if(n <= 0) return -1; + int i, max_i = 0; + float max = a[0]; + for(i = 1; i < n; ++i){ + if(a[i] > max){ + max = a[i]; + max_i = i; + } + } + return max_i; +} + +int int_index(int *a, int val, int n) +{ + int i; + for(i = 0; i < n; ++i){ + if(a[i] == val) return i; + } + return -1; +} + +int rand_int(int min, int max) +{ + if (max < min){ + int s = min; + min = max; + max = s; + } + int r = (rand()%(max - min + 1)) + min; + return r; +} + +// From http://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform +float rand_normal() +{ + static int haveSpare = 0; + static double rand1, rand2; + + if(haveSpare) + { + haveSpare = 0; + return sqrt(rand1) * sin(rand2); + } + + haveSpare = 1; + + rand1 = rand() / ((double) RAND_MAX); + if(rand1 < 1e-100) rand1 = 1e-100; + rand1 = -2 * log(rand1); + rand2 = (rand() / ((double) RAND_MAX)) * TWO_PI; + + return sqrt(rand1) * cos(rand2); +} + +/* + float rand_normal() + { + int n = 12; + int i; + float sum= 0; + for(i = 0; i < n; ++i) sum += (float)rand()/RAND_MAX; + return sum-n/2.; + } + */ + +size_t rand_size_t() +{ + return ((size_t)(rand()&0xff) << 56) | + ((size_t)(rand()&0xff) << 48) | + ((size_t)(rand()&0xff) << 40) | + ((size_t)(rand()&0xff) << 32) | + ((size_t)(rand()&0xff) << 24) | + ((size_t)(rand()&0xff) << 16) | + ((size_t)(rand()&0xff) << 8) | + ((size_t)(rand()&0xff) << 0); +} + +float rand_uniform(float min, float max) +{ + if(max < min){ + float swap = min; + min = max; + max = swap; + } + return ((float)rand()/RAND_MAX * (max - min)) + min; +} + +float rand_scale(float s) +{ + float scale = rand_uniform(1, s); + if(rand()%2) return scale; + return 1./scale; +} + +float **one_hot_encode(float *a, int n, int k) +{ + int i; + float **t = calloc(n, sizeof(float*)); + for(i = 0; i < n; ++i){ + t[i] = calloc(k, sizeof(float)); + int index = (int)a[i]; + t[i][index] = 1; + } + return t; +} + diff --git a/hanzi_detection/src/utils.h b/hanzi_detection/src/utils.h new file mode 100755 index 0000000..ef24da7 --- /dev/null +++ b/hanzi_detection/src/utils.h @@ -0,0 +1,53 @@ +#ifndef UTILS_H +#define UTILS_H +#include +#include +#include "darknet.h" +#include "list.h" + +#define TIME(a) \ + do { \ + double start = what_time_is_it_now(); \ + a; \ + printf("%s took: %f seconds\n", #a, what_time_is_it_now() - start); \ + } while (0) + +#define TWO_PI 6.2831853071795864769252866f + +double what_time_is_it_now(); +void shuffle(void *arr, size_t n, size_t size); +void sorta_shuffle(void *arr, size_t n, size_t size, size_t sections); +void free_ptrs(void **ptrs, int n); +int alphanum_to_int(char c); +char int_to_alphanum(int i); +int read_int(int fd); +void write_int(int fd, int n); +void read_all(int fd, char *buffer, size_t bytes); +void write_all(int fd, char *buffer, size_t bytes); +int read_all_fail(int fd, char *buffer, size_t bytes); +int write_all_fail(int fd, char *buffer, size_t bytes); +void find_replace(char *str, char *orig, char *rep, char *output); +void malloc_error(); +void file_error(char *s); +void strip(char *s); +void strip_char(char *s, char bad); +list *split_str(char *s, char delim); +char *fgetl(FILE *fp); +list *parse_csv_line(char *line); +char *copy_string(char *s); +int count_fields(char *line); +float *parse_fields(char *line, int n); +void translate_array(float *a, int n, float s); +float constrain(float min, float max, float a); +int constrain_int(int a, int min, int max); +float rand_scale(float s); +int rand_int(int min, int max); +void mean_arrays(float **a, int n, int els, float *avg); +float dist_array(float *a, float *b, int n, int sub); +float **one_hot_encode(float *a, int n, int k); +float sec(clock_t clocks); +void print_statistics(float *a, int n); +int int_index(int *a, int val, int n); + +#endif + diff --git a/hanzi_detection/src/yolo_layer.c b/hanzi_detection/src/yolo_layer.c new file mode 100755 index 0000000..c338036 --- /dev/null +++ b/hanzi_detection/src/yolo_layer.c @@ -0,0 +1,374 @@ +#include "yolo_layer.h" +#include "activations.h" +#include "blas.h" +#include "box.h" +#include "cuda.h" +#include "utils.h" + +#include +#include +#include +#include + +layer make_yolo_layer(int batch, int w, int h, int n, int total, int *mask, int classes) +{ + int i; + layer l = {0}; + l.type = YOLO; + + l.n = n; + l.total = total; + l.batch = batch; + l.h = h; + l.w = w; + l.c = n*(classes + 4 + 1); + l.out_w = l.w; + l.out_h = l.h; + l.out_c = l.c; + l.classes = classes; + l.cost = calloc(1, sizeof(float)); + l.biases = calloc(total*2, sizeof(float)); + if(mask) l.mask = mask; + else{ + l.mask = calloc(n, sizeof(int)); + for(i = 0; i < n; ++i){ + l.mask[i] = i; + } + } + l.bias_updates = calloc(n*2, sizeof(float)); + l.outputs = h*w*n*(classes + 4 + 1); + l.inputs = l.outputs; + l.truths = 90*(4 + 1); + l.delta = calloc(batch*l.outputs, sizeof(float)); + l.output = calloc(batch*l.outputs, sizeof(float)); + for(i = 0; i < total*2; ++i){ + l.biases[i] = .5; + } + + l.forward = forward_yolo_layer; + l.backward = backward_yolo_layer; +#ifdef GPU + l.forward_gpu = forward_yolo_layer_gpu; + l.backward_gpu = backward_yolo_layer_gpu; + l.output_gpu = cuda_make_array(l.output, batch*l.outputs); + l.delta_gpu = cuda_make_array(l.delta, batch*l.outputs); +#endif + + fprintf(stderr, "yolo\n"); + srand(0); + + return l; +} + +void resize_yolo_layer(layer *l, int w, int h) +{ + l->w = w; + l->h = h; + + l->outputs = h*w*l->n*(l->classes + 4 + 1); + l->inputs = l->outputs; + + l->output = realloc(l->output, l->batch*l->outputs*sizeof(float)); + l->delta = realloc(l->delta, l->batch*l->outputs*sizeof(float)); + +#ifdef GPU + cuda_free(l->delta_gpu); + cuda_free(l->output_gpu); + + l->delta_gpu = cuda_make_array(l->delta, l->batch*l->outputs); + l->output_gpu = cuda_make_array(l->output, l->batch*l->outputs); +#endif +} + +box get_yolo_box(float *x, float *biases, int n, int index, int i, int j, int lw, int lh, int w, int h, int stride) +{ + box b; + b.x = (i + x[index + 0*stride]) / lw; + b.y = (j + x[index + 1*stride]) / lh; + b.w = exp(x[index + 2*stride]) * biases[2*n] / w; + b.h = exp(x[index + 3*stride]) * biases[2*n+1] / h; + return b; +} + +float delta_yolo_box(box truth, float *x, float *biases, int n, int index, int i, int j, int lw, int lh, int w, int h, float *delta, float scale, int stride) +{ + box pred = get_yolo_box(x, biases, n, index, i, j, lw, lh, w, h, stride); + float iou = box_iou(pred, truth); + + float tx = (truth.x*lw - i); + float ty = (truth.y*lh - j); + float tw = log(truth.w*w / biases[2*n]); + float th = log(truth.h*h / biases[2*n + 1]); + + delta[index + 0*stride] = scale * (tx - x[index + 0*stride]); + delta[index + 1*stride] = scale * (ty - x[index + 1*stride]); + delta[index + 2*stride] = scale * (tw - x[index + 2*stride]); + delta[index + 3*stride] = scale * (th - x[index + 3*stride]); + return iou; +} + + +void delta_yolo_class(float *output, float *delta, int index, int class, int classes, int stride, float *avg_cat) +{ + int n; + if (delta[index]){ + delta[index + stride*class] = 1 - output[index + stride*class]; + if(avg_cat) *avg_cat += output[index + stride*class]; + return; + } + for(n = 0; n < classes; ++n){ + delta[index + stride*n] = ((n == class)?1 : 0) - output[index + stride*n]; + if(n == class && avg_cat) *avg_cat += output[index + stride*n]; + } +} + +static int entry_index(layer l, int batch, int location, int entry) +{ + int n = location / (l.w*l.h); + int loc = location % (l.w*l.h); + return batch*l.outputs + n*l.w*l.h*(4+l.classes+1) + entry*l.w*l.h + loc; +} + +void forward_yolo_layer(const layer l, network net) +{ + int i,j,b,t,n; + memcpy(l.output, net.input, l.outputs*l.batch*sizeof(float)); + +#ifndef GPU + for (b = 0; b < l.batch; ++b){ + for(n = 0; n < l.n; ++n){ + int index = entry_index(l, b, n*l.w*l.h, 0); + activate_array(l.output + index, 2*l.w*l.h, LOGISTIC); + index = entry_index(l, b, n*l.w*l.h, 4); + activate_array(l.output + index, (1+l.classes)*l.w*l.h, LOGISTIC); + } + } +#endif + + memset(l.delta, 0, l.outputs * l.batch * sizeof(float)); + if(!net.train) return; + float avg_iou = 0; + float recall = 0; + float recall75 = 0; + float avg_cat = 0; + float avg_obj = 0; + float avg_anyobj = 0; + int count = 0; + int class_count = 0; + *(l.cost) = 0; + for (b = 0; b < l.batch; ++b) { + for (j = 0; j < l.h; ++j) { + for (i = 0; i < l.w; ++i) { + for (n = 0; n < l.n; ++n) { + int box_index = entry_index(l, b, n*l.w*l.h + j*l.w + i, 0); + box pred = get_yolo_box(l.output, l.biases, l.mask[n], box_index, i, j, l.w, l.h, net.w, net.h, l.w*l.h); + float best_iou = 0; + int best_t = 0; + for(t = 0; t < l.max_boxes; ++t){ + box truth = float_to_box(net.truth + t*(4 + 1) + b*l.truths, 1); + if(!truth.x) break; + float iou = box_iou(pred, truth); + if (iou > best_iou) { + best_iou = iou; + best_t = t; + } + } + int obj_index = entry_index(l, b, n*l.w*l.h + j*l.w + i, 4); + avg_anyobj += l.output[obj_index]; + l.delta[obj_index] = 0 - l.output[obj_index]; + if (best_iou > l.ignore_thresh) { + l.delta[obj_index] = 0; + } + if (best_iou > l.truth_thresh) { + l.delta[obj_index] = 1 - l.output[obj_index]; + + int class = net.truth[best_t*(4 + 1) + b*l.truths + 4]; + if (l.map) class = l.map[class]; + int class_index = entry_index(l, b, n*l.w*l.h + j*l.w + i, 4 + 1); + delta_yolo_class(l.output, l.delta, class_index, class, l.classes, l.w*l.h, 0); + box truth = float_to_box(net.truth + best_t*(4 + 1) + b*l.truths, 1); + delta_yolo_box(truth, l.output, l.biases, l.mask[n], box_index, i, j, l.w, l.h, net.w, net.h, l.delta, (2-truth.w*truth.h), l.w*l.h); + } + } + } + } + for(t = 0; t < l.max_boxes; ++t){ + box truth = float_to_box(net.truth + t*(4 + 1) + b*l.truths, 1); + + if(!truth.x) break; + float best_iou = 0; + int best_n = 0; + i = (truth.x * l.w); + j = (truth.y * l.h); + box truth_shift = truth; + truth_shift.x = truth_shift.y = 0; + for(n = 0; n < l.total; ++n){ + box pred = {0}; + pred.w = l.biases[2*n]/net.w; + pred.h = l.biases[2*n+1]/net.h; + float iou = box_iou(pred, truth_shift); + if (iou > best_iou){ + best_iou = iou; + best_n = n; + } + } + + int mask_n = int_index(l.mask, best_n, l.n); + if(mask_n >= 0){ + int box_index = entry_index(l, b, mask_n*l.w*l.h + j*l.w + i, 0); + float iou = delta_yolo_box(truth, l.output, l.biases, best_n, box_index, i, j, l.w, l.h, net.w, net.h, l.delta, (2-truth.w*truth.h), l.w*l.h); + + int obj_index = entry_index(l, b, mask_n*l.w*l.h + j*l.w + i, 4); + avg_obj += l.output[obj_index]; + l.delta[obj_index] = 1 - l.output[obj_index]; + + int class = net.truth[t*(4 + 1) + b*l.truths + 4]; + if (l.map) class = l.map[class]; + int class_index = entry_index(l, b, mask_n*l.w*l.h + j*l.w + i, 4 + 1); + delta_yolo_class(l.output, l.delta, class_index, class, l.classes, l.w*l.h, &avg_cat); + + ++count; + ++class_count; + if(iou > .5) recall += 1; + if(iou > .75) recall75 += 1; + avg_iou += iou; + } + } + } + *(l.cost) = pow(mag_array(l.delta, l.outputs * l.batch), 2); + printf("Region %d Avg IOU: %f, Class: %f, Obj: %f, No Obj: %f, .5R: %f, .75R: %f, count: %d\n", net.index, avg_iou/count, avg_cat/class_count, avg_obj/count, avg_anyobj/(l.w*l.h*l.n*l.batch), recall/count, recall75/count, count); +} + +void backward_yolo_layer(const layer l, network net) +{ + axpy_cpu(l.batch*l.inputs, 1, l.delta, 1, net.delta, 1); +} + +void correct_yolo_boxes(detection *dets, int n, int w, int h, int netw, int neth, int relative) +{ + int i; + int new_w=0; + int new_h=0; + if (((float)netw/w) < ((float)neth/h)) { + new_w = netw; + new_h = (h * netw)/w; + } else { + new_h = neth; + new_w = (w * neth)/h; + } + for (i = 0; i < n; ++i){ + box b = dets[i].bbox; + b.x = (b.x - (netw - new_w)/2./netw) / ((float)new_w/netw); + b.y = (b.y - (neth - new_h)/2./neth) / ((float)new_h/neth); + b.w *= (float)netw/new_w; + b.h *= (float)neth/new_h; + if(!relative){ + b.x *= w; + b.w *= w; + b.y *= h; + b.h *= h; + } + dets[i].bbox = b; + } +} + +int yolo_num_detections(layer l, float thresh) +{ + int i, n; + int count = 0; + for (i = 0; i < l.w*l.h; ++i){ + for(n = 0; n < l.n; ++n){ + int obj_index = entry_index(l, 0, n*l.w*l.h + i, 4); + if(l.output[obj_index] > thresh){ + ++count; + } + } + } + return count; +} + +void avg_flipped_yolo(layer l) +{ + int i,j,n,z; + float *flip = l.output + l.outputs; + for (j = 0; j < l.h; ++j) { + for (i = 0; i < l.w/2; ++i) { + for (n = 0; n < l.n; ++n) { + for(z = 0; z < l.classes + 4 + 1; ++z){ + int i1 = z*l.w*l.h*l.n + n*l.w*l.h + j*l.w + i; + int i2 = z*l.w*l.h*l.n + n*l.w*l.h + j*l.w + (l.w - i - 1); + float swap = flip[i1]; + flip[i1] = flip[i2]; + flip[i2] = swap; + if(z == 0){ + flip[i1] = -flip[i1]; + flip[i2] = -flip[i2]; + } + } + } + } + } + for(i = 0; i < l.outputs; ++i){ + l.output[i] = (l.output[i] + flip[i])/2.; + } +} + +int get_yolo_detections(layer l, int w, int h, int netw, int neth, float thresh, int *map, int relative, detection *dets) +{ + int i,j,n; + float *predictions = l.output; + if (l.batch == 2) avg_flipped_yolo(l); + int count = 0; + for (i = 0; i < l.w*l.h; ++i){ + int row = i / l.w; + int col = i % l.w; + for(n = 0; n < l.n; ++n){ + int obj_index = entry_index(l, 0, n*l.w*l.h + i, 4); + float objectness = predictions[obj_index]; + if(objectness <= thresh) continue; + int box_index = entry_index(l, 0, n*l.w*l.h + i, 0); + dets[count].bbox = get_yolo_box(predictions, l.biases, l.mask[n], box_index, col, row, l.w, l.h, netw, neth, l.w*l.h); + dets[count].objectness = objectness; + dets[count].classes = l.classes; + for(j = 0; j < l.classes; ++j){ + int class_index = entry_index(l, 0, n*l.w*l.h + i, 4 + 1 + j); + float prob = objectness*predictions[class_index]; + dets[count].prob[j] = (prob > thresh) ? prob : 0; + } + ++count; + } + } + correct_yolo_boxes(dets, count, w, h, netw, neth, relative); + return count; +} + +#ifdef GPU + +void forward_yolo_layer_gpu(const layer l, network net) +{ + copy_gpu(l.batch*l.inputs, net.input_gpu, 1, l.output_gpu, 1); + int b, n; + for (b = 0; b < l.batch; ++b){ + for(n = 0; n < l.n; ++n){ + int index = entry_index(l, b, n*l.w*l.h, 0); + activate_array_gpu(l.output_gpu + index, 2*l.w*l.h, LOGISTIC); + index = entry_index(l, b, n*l.w*l.h, 4); + activate_array_gpu(l.output_gpu + index, (1+l.classes)*l.w*l.h, LOGISTIC); + } + } + if(!net.train || l.onlyforward){ + cuda_pull_array(l.output_gpu, l.output, l.batch*l.outputs); + return; + } + + cuda_pull_array(l.output_gpu, net.input, l.batch*l.inputs); + forward_yolo_layer(l, net); + cuda_push_array(l.delta_gpu, l.delta, l.batch*l.outputs); +} + +void backward_yolo_layer_gpu(const layer l, network net) +{ + axpy_gpu(l.batch*l.inputs, 1, l.delta_gpu, 1, net.delta_gpu, 1); +} +#endif + diff --git a/hanzi_detection/src/yolo_layer.h b/hanzi_detection/src/yolo_layer.h new file mode 100755 index 0000000..d2a0243 --- /dev/null +++ b/hanzi_detection/src/yolo_layer.h @@ -0,0 +1,19 @@ +#ifndef YOLO_LAYER_H +#define YOLO_LAYER_H + +#include "darknet.h" +#include "layer.h" +#include "network.h" + +layer make_yolo_layer(int batch, int w, int h, int n, int total, int *mask, int classes); +void forward_yolo_layer(const layer l, network net); +void backward_yolo_layer(const layer l, network net); +void resize_yolo_layer(layer *l, int w, int h); +int yolo_num_detections(layer l, float thresh); + +#ifdef GPU +void forward_yolo_layer_gpu(const layer l, network net); +void backward_yolo_layer_gpu(layer l, network net); +#endif + +#endif diff --git "a/media/0b7bbb3595309f7f9123704ef354a52d\346\227\205_u65c5.jpg" "b/media/0b7bbb3595309f7f9123704ef354a52d\346\227\205_u65c5.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..63708d84a61e8807929ed063175a613014d1fa0b GIT binary patch literal 3966 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 F`ZvIsd{F=Z literal 0 HcmV?d00001 diff --git a/media/1590951689.png b/media/1590951689.png new file mode 100755 index 0000000000000000000000000000000000000000..f09a8cd000a26a32814c1ce1f567232f49ed7f50 GIT binary patch literal 24312 zcmV)7K*zs{P)Px#9BD*PQ~&?~0ssI2000008vp6~QNft#)rbJq#Oi|34qRb#B5IJLzBf&u!FIpKd1C<*je4P5-CRXDCj7V2nGfcQ)>8H>kYJX>H8BJ9WqO#~jK zt1wl?C>AYoJXfj^wOX!H&2oh*U#s(2jYrD@!xu_Sp;Y9V8jCcTbe+l6IE?0tSgD4V z>O`ShDHW;$R;4mk1}zmhwpgUfJX2(a0#)I$Itw=#sKJ0EUS+u=R}#2Nff1@S0p{yO zxB}VpL2W8xOF}UiOEGA$kxf)RDy$od80}Qd24XG!sM9> zm1}S%zDQ<}Odt$LqE((N=QCijH9l8mQgtR?W1>|qUKJ9xLZV(wH7c1Bm&oV5iMS=5 za#spMP2fs2Sz)MpQK%M6EF%bfxg->;JlhcP29Gq@T#ZJ{G+tuaQlU@=#`6^(ya@2q zOj%%o6*(Fhn5hujz;CmVF4!GOhMLQ$ZF62S=Ir85juD3{r49Vyk*e2p)$T#4n2 zTmh_2U>Y3WV9^ExZU+ViScAoDM7Bo5RXUT8Sh}yDJa^*2{QMXix7H(zjkFVuB@$UC z!&T{8r7RG5SU=i+r1iwkvC*C+j+3=23!Jl5;#r2H$ZEL`a4(TUHBW+T@gf6PIkZ~f zmhKhcaA;<*@66Ey6N8;0r&>00_so{n=7An294N6k#bIQlDCFa+sowU}pY^t#C!k2R z%+{&}mZM3Us?=(XP$XEE<~gwBN~O?fl*oKWC7Efv)N=jO$vm6|Kh>xdfmMqIf#Yd# zLlJ~Td1+pt8XUT`d=9VibVcCGz%K;;i@_4!1(xDzLSRTR0H@241Neax0Ef5_APOD@ z#J#{0zykz<)@v14E}pr4>$=UX`xDr6WtOY*-~zAFaOuM7_B+>928qwA?rCWrI@jV> zi#RgXD3c8WZBSH|rk2nw)0HA!C-DN$vxO2{C#>ZQUfkms{&Fk;Czv%OBJ$IWr`p+gepfh*nERV8Whqf@jOK_B*{<| zoR0V1X*+*>-|TP)G<%)9@Gd336bl+XIWmCNA*_n!XgK4a8gILKy?Ju94}x*5T1(d( zscIc9fOlA^mxU^YR&kAp1eeNerCJtBxoBE6HgWpIv3tYaE{{=Br;sKY(B0$V@V#*T~HVbvhCL6WH?=l&vNN zHcICF2K}7IBnrhH1Qhd%7JL#}E*KIhs?72AJl!C;2E$ebs#3rjT&_VtfDg+YQR3;M zzyS&X98eJWB6xIxSu&0mSgOEL6@dnK2~@ts5j;!MEG3kfIuomLP(fgbVkK8@WGjt) zsYVvdAPw-mz;VFst9h;rktK*I!gSV<)xp+lfnW#!P*|WGI?uvI#zy zATTm(^DEWbDUVglj!8y?YJ+adVp$;R6f58$?Xl$oA%OK4 zD1j$AK!H_;E23GPMk$`)lD@E2rnV{6R30uZ#Vg3X;0^)&1O8Vm0SYJig(gcZWqkqx z#xwYT!v3qLd^ydQJq5;DFN9grixEDWNz_=Zl!S^94oI@VmU#*!?NU8os1jV6qsu&2 zrQteAf>gXg$Lnmi%7g2QOtDH8t7M@Hn3WK!I9JLO6p5onGFvC&bs|#7L$!RcibWbs zvOxtJOrp$TAn~E4YNp)CR2onjP(lM)wo)ToXr!51nkeP+B#Wf!kQvrb=GxY?@BjDU zjt3BN3+h+pq6s*X&m~ceL?Jwug#!#6sRN0F<#-AfIJnGYL4q$+WQnG$ELLH1JOi_Z zyifvO!B!})f%A2OFX0r1qge*cmBD+ZAv8ng^E?hhuv{oNh+=~R$P_SyLGldBS6GV6 z7l3Ff0Yr%+ixt>>iNORs7jxMbMh7)>(^Mv1#4$FTr6G|1$XbangX~ri%H>kA1hf<2 ze2~+ZII#j00C>wRSz-Y8WVJvSnS9t|U7Q|OEX=0j5dbrQf0^)?V;!V`KVrX>duR-R zTB``lat|1lUT@=h$Pb4JOn{_KEq>)ay|k)te*2U^6p07TSY>A zHbvkZ%GP)WEfXOjALNN>m4WLt)*y%mN;EL4LDL05aTPE{V>K$z<;#^~tyn29X{;(I zG^k30s5XdlohsM)YK`Fmy@A|JR)G=%O05WvFcEjkM(-TkvHEiJ&XiMAWwH$+UuO}( zjzEL~F${>NSXyFwZb|O~+yTP@HvlA101_DJTaYEI1(JqiqOtzZc5S(Q=D62s<0u@^ zKFId~a_}^O0|5E|5&LS1126+D0p!c*g3#v~41feqzY72IU%xz(WdQ}rtXiQ-gd@`> zHeKUV4Ii3mAJ72c}i%4Mj(QqSOP6$sX7*J;DH7nsWRyThj9Xs zK{Urv`Ew#BI@qLT;2u#?yQ% zSxJS2l#_=o)vTqSwAK@@Vk&~>uozMIlXWDYDIo45<}c#mNCTim`u4u)p@!~5EX)IlxqdP&N4NMtN`Qrx*#-opih9@7Qj0x*XuwyfaRtf zCh1W3mHE+Ic*Nd=e_KGHlgI*VayjBJgM+5i)_J9NagU;uHDh67wz;HAM4EOYJ!P7ps*(#js}uwAjb!>au}^-awL_F zS0HBt(l@f&I%=t7o*EIT;r<$8uanLOVr--|^|+y$^3c&>!V?I%!Wmf)fBEO0mEVo* zc^kUd9hppJ5ZpSU%&X(Flzt zC^*4F=>n9k!bl^JH)x{7q6HyGb4dtt`5dx*%wB@Sb>N)<4}qxRaE-`ULCHYURdOj8 zaD0sfH6viVavd(!;bILfmQjv|uryA_OG2u|hRTeuQHa+|OZ68AG#0BW52o!C8Ly1;7#X*P^t<4wHym|BNe>lu z^Fccov@&5k5whVyD;%^!5eJ;`LCIh?8OdkTWHv`Zz+g6yvN+6AP&)3Mo49-a==O!7 zTREShL1*e5Qbyx-G|<384LsVwz&KT7@G_ulzDNmWyjaZ_>sX}$Bq3QYgMbi5vBKH_2{RwChuM(mMHC;-PpXey2+VrdVa^9D?__pTr5IJqlom@nl*5DCJh2n0?w z>#66wbT*oT^T8|=N+Ph|Dj55tx7LZa|8jKqD*?%X+u?8o;!bZc=(J?qIymHkJtowp zB0Nemq(kD)44jCgxhRs0=h8Vin$P%%YzWCj(}^VD^Qb2nw^*_!EiLWhZ-4CD`G|Yd z1Ng-kY6C0zp0)AYTUq@O>ej^l?r<<13Iu#crB^%Wh-SFL*1&p z-;fJh;D{@i3?rE&luky&Aq;`BT!zS{(qWHudiYH9o|&Ppn9s&j2;fv4PF3(g4f9k` zPYw0e(NK+u*T_tTMv6et#1%(E2{i0*CKc0|sFNQ%N!?uM+V`lt>93Jpe_7uBH|(}= zIo3P?O&s@I=d3=LJCIEHle)>#xoZbimsYvXzU4jiIC}h-Y}>2oz^?4f)x7j}PT7xG zX46h-GGIu=oWXz{$;R^;K(h%f9#8uMO0n4GbjDKYG)AOJCWcWY1(8^kM8hl=Ef6st z4HnT*1&>yVcm;`6(P#}%*GZ&K;We77384Nj6+k?K1_x*a&=4pDfKyOBPY@UZg>4J> zqJ}9lX5sNP&d@nfYV$<|&E=AQJn1as5fJwk;fn(8i}+rS^8fd^#QDoH{a+pd-T|*; zp!d$i=shq1cmoE*YcZh-rn$Q`^crJL!-A@b-s`- z8u!P7v9KfL)`kO4r$1nFha9e;Te;xrIpsX{f#={WzI|_qHa;ZX{1@K!e@?9ab7sX~ zxL4e-YhABZ4e7iNr#}US5R*tO?YkVAIg8%gX4&#!eAEAmuKaV$x_{8^deYkbimBzD zQ15=v*eSR4R@^g>!;VzYNW}egG(`A=SRe|=(rE~bC|WSlLh-!*)>r%br7q581Z;KzHcH@P&6x2cK5%dD7FmB0GNx zF;Bp*g`8uKu#c8q_tLXxOg*3Xo!xnS*Sg*7K52UQ#r-e;@c7f;?0Eejr8{2NoPO`> zhyO6s^wZRZcMErRvSa7NlCDTV8;E$kohGI4eB{_*PkU6^m%ewP+_w@v@@Qn+ z_nhm$Yg~K3cH=*bHvdd|;w|6Q5zIT7agQS2dDqvO)!Jx+z4LYJB zUplRiXZ0!60ujy}`VEAPOb2Sf%+o zm1HmoCy87>k3xx3)>q3K>KSDPZnn6lUS{H1o^H*Zi%k@#(X?dJr?pqE4sT9{~|*_eOmFaMcm;`&G3zN?!!-cw?7!%^7nx)-*#{Qj<@NbLVF$#A9yr+0H_$iUhK@a>Ui$;pu3tK@f0CF#nl-g$%$=yQD>8C6)Oi%{J69Cl zAw-?9{BBCqn=;%>n}!pbd*FXg`d!JOClT~T1KzOT9}b4XkytpEiY78C2uVU{5<;L{ z9w#U)kI@w9MiXEwp+MsRdkRS*D4K=oZ<4OXTq2an;W>%}iBB^( zs2sf^~k>~X*|HifEo6wQRye+So&wpxdYw~sMjNRM-cdmo` zcE!iehNOcbqe9VtRn@vPcw>$K#BFxb4!5vk_y|CCO@M2lhAZd*`(a#}DdVMwQd%w%Su>Gvd%A0ev!R z_66)#m)GWrI|E6l+hvxIN3|pH{HavuD(8{cq+5R#Y+aX|YRSkhMU+=ErVdDc)p%*0 z`oP=n=J%k>YXWEAcVBwXapfI%>$~Ch4-;)4#e0v%2hS&lFDA#Xq$jTA{=HyQf0! z+l(oax$}8afi1xEfyUk1zJ*Mvn!KKX2Xe9skaU@Y^f> z11EIjUFx}U^Zc-H{91DOczo!%Z=%&DpK_Xwy{)Ia4z2Lq+8k?rXJPGwsg4cC&cjae z@ND1hTPF{O7rMd|7a~)aVv2!;$Ka1fTf6&@oI5){J>m#hO+F)Jkm=4fUtRI)wa->6 zG{a`U(P=Q`>`u~SLw#yEBFlwjs9&FSnte8#!|l|YHF}LieEZ1oq2CVfdQ)+7eRkq1 zuIx>!x_yd{sQ#{h=B)V0dy?(XyAHjYIQgc( z71zO+eTQF;9DOx?>P_tW2XxO`W^gMx*u+lkCufdgix(-&KryMt;(8j7;!GB15QK!w zaEOLeP&$*0#UQ^muN%^we1Br&&ukYyqBPw^#FmEOSRx}A&)qrS+;e6x6S0(7f+um^)L<9?a&mrwto^}a-X8C?+Ez<|~x@>%ewWxN68U$p#iFbSjpoXy1IpHz$_POdCc!-Tf!LU5DH~ z&Ay3i5yh~q_tNGGYm(1jvJUP|*vI_Z#k9?a`rY}kiHJy9??lNn z%{u1Nrg^tv(d#iNWV5FZuiLxw*{-7-y`vq;`FnB6Xh=2T)lJxy{fk{k`wzUQI{rz% zdvAI2P(^ZxnOKM3eLHaEG2M#4iEaFzZ{O4Q-M_Ln{oJwjVawX@Y2N?3`J=D-*8Wvs z!~e3c`D_2~ADDLk#B%(_)bN3Nc%~3nGq4xV#nU)~P&l9RP}yWAnT~}*DW^8C>{fpE z%G~-N`!9XKsX8&AHVZn^S;Vea&-Gjr-9E#F%>qS$%_0J{{J?(L|F!>;0RC9tFXO$8 zE)aCUmQ(u@0q|f~ZOI$J42i*T28gssE)>eUU65@tEo-x#|3J3!7mj0Z^M<=#$F#rcNXBV2*tC;Gc#hHEC@h{Y&7H~JJ7nwKtvmTU(e@`tR{ePN(}%P>AB!A)I`Y}$ zw(URC@BCS+b7OYuLSVApK5@%2e$zF0&eO5Sb!mmYh)0nf zKVsbfxO(IF0w-Tc4u6h17NS0j-)m0>?R?5v2q`i96y}&AJPVL*#yD~P*v2>ZY$CFXNKVgw)Mc3tfo;K`y48HkkQF#+}$Wqa09>wrX0`(g5 z4rvwgGdKn_WfZhvfa}l%FwoFlwy(MZ2>qqL9flJ@IV76|fxbMC zAsKKA3}`^a8^MiUShJ9wz3e~vJLl$~C6By-jqJI0^xw~2*s&;^R;gsyuU*)_XN}o5 z6}C;q)#EY6oJ%QL)F>P?9r584sXJRECtq|m{gZS3-#IsYOTXstBF@vxdZs~#C~Tg>jF&x^UNEfxPH@*R z3ezna(}>5fafMysfG6#8AOUyOXY#s~Zo`y$qILAx$30EYOx|qL%Q`~pAy_>FNoEqV z1;0ve(I_QS(f&Q#FP~_h@9nUNhK%A~wWLcUzcbiz=wj2q-(2?=HPR86_c+Dvj+ra2 zsf+5n2fGjc`%v@yhMPMR6K9eW=aN$wW0O~7bDgMurV@3cPID2;6cL;S`?+bj0tL`m zC>c$}1A(|n5*|J^z3wO0-H+k7SCy1)xKj$4HpjwW*Dk)nXjWQ&ap(|NZ0DHI$ zkzY2jbqfr5!?FPki*Kf4+HZ z*gTyujK`FtG3}z)W|LdI4z)b4n1mL(Q^TjDo!k9q-i;l9F23ub;3xkh_32+HH~y`C z%MYa6pPJqGmZK95dOBDceY_^CRz;e++E+ zF5cG^G|X6iPIu6ia%*!|N!nxaIDs&j^NyX=H9xD|_Rp>p&sirfT6E%|Y8=syXOxp6 zrP!mE+vT&W{)^W(zbd}8OFz<~63@t$3YmD!CGMO$z4GFUC)>8X8{INvRpUSyoP#_qHx{X1bK5UTT3)jyveX4YrY0w#9qbY8X8r7QZR(QRVG&$Z4_#B085pVwE8Gb|&}! zz`ODrsn&NqigA<8?s8btw#A%jD(uj@EZU%~-*@d3<;VZiz4hDq&JR6{1A48&uMt6- zk(heYp`5oV7aViF%5!U{H~ovhZJl@gnqq!NqSWc;MxytQsrNlIu;QP`KL5n4l}c5L z1&v;+)+ohOs_t{mzy0ZG%LemQw?!>A8nr-80!iTs*+B^ygkm{3$mBdU5{nfD*FC6{+;F;DNcY5y5jon$C>66LlO%6*q6@igh8j674 zb}F06rW4t8GM!97nKTS#a@h<5XYo8rV0oIvIU2tYX3I296tD!731CToJ{8PIY$?-h zOgkPoFC=}Ygx{X^8d45L(rb)^eudX(HS0oVX;3GMgMGHeR$KG)qBRfckG>hW*Af(U zM;H4v*Z1fzZ}Qwd7@5BASse1J7lL|OP`Bt&iR{Wnx5W&4<{qucp_;WS=8OuFNjl{c zbvb(u$v=Og_k(YFZmcyAo?962o0^%Kot>19-7$>cG){IZr~1T`Ba8P2XGVwShHq%@ z?Dm~}*1!6%om(IFv^SY1+LaU6yhEQE4m`EE`eFU?k9~7p4x3u3mxSDgtV5TzY2zM~ z-ENCmWz^iM?D3}@AAdb{`ZuBJRa~-5 z*4(~yOgefeqMPZnbl)RXx?I9=zbb(WKn|Z|a@D zcDFZ$6a!|X3^b&@1|3j>S)0UW)Vhr7tn_aD;@kQaU-#{MI5*J}QcoDwa)nBxFxVtU zr%|IY_a4_A{Izn!gZ}pQw%H!JL?V+b%^JB~De{|CX4#x>vPXLTVArb0%q?$5`VM*K z?&=n243b$`b~k+fx28?^+xGn;KJb}yVJN1V@XLlhqVDj-mB_8FgC9I#XnrFx*pgKa z!WMDXG?leZr(Du_z?h8M(U_T!8~CIH&%{7YAN5-e4woYsNe8X|vC~)I_~z)=$9+?m ze8vTtX#8ILiT>jo+P43$WyK3kum1egC%(Jx=l^@vqkpykrAMxA{$1aRErVxw&bA-b zkF*?#nYg0)aj07y&1;saV)+_sEAQPp$6U{Ori_RaQ}- zNi8wUrjy#y=*$&U$6jk+OBkfmgVcqu@SKMzu`-!#x?Bd`p^>n{u;GFT;JIXDOY4`rx-*q6Q9CI7BKBqV8cE{{G zv)!k&`khL#vva><+s~#x`c|@czhBgARLJC7+nmNZEz#Me)7JLwimi{x);;LHwNo)Q zs1#2dB~upJw03^PBAao^C(J{aMJGNPTK|}*b+x1Kgl2j`A_hh2SYYCk@$=`ztG}x~ z{6cc!wo$9`%E#T3;h=OlCF%^_+&1>fkBrT~jrJXniFyOl(S&v~Wu8xXH1UWl3AP85 ze(((s67|KRNnaG~dRc5?zshD&E)Gd;5XV$)SrRkmNYoFy^QX-%)LcVf7R>V^G z;WV92#*lP07xyOvHn264FpE^T4;%07arPZBcYhAx*NR5nl6%&>2N(7~E8q8T{=P$t z-RC6t+APCYjMp}Ie{jF)*lVfbBQZ&@K|F4hiCyA*p@}P@u05^`ALu`Sac=A5;(gES zTenyzZYUN-3kIJ`AvP-~?W#$eWWYAlroX+{bme2m=@;z>ACZ3YHTCLmdJg``bL?ML z2cDSR`9x;^i1+q7@AVI&?eF@}y=?sKdEJq>Z0A-4udIxn{cZH~r=;uuIo!F+GksSy zGHBQ99kc!3JNr$CUr=m%*! zZQJA>yQ-TRmWUS>3awT=6Buu`9D7~9;#=lzKhE4cY@O|MPIm^UuleRWjAJ*<6E|Yw zo1WV{Ps9u;cm@I1XlyCTqY~QcvHb0`d@TpfdB{BJ|N|9YQjccak#`%a{74X`@26Ei*Onb~RkJICgIRYRSjaIK^ zY;Hs$8F0>>?^yjK#kqF^^R0fvtk*0{+hv4xmNHH<77_1|7i>~iHHyoJvvd8?(QCfJ z7T@qGThCF+wY`()x2w8OQ672Tqv8_IVlGm|()W=ho&hbxRBS1=o5d;9Ox!p-bK{6@ z=tQt@x8mrVj=rP1*?!$jzpi7yde7sMkG^4SdA;|<*7jrDdz)8}?SG^9$f9+B}*` zr$G|7$YF;ZaVk-_0r6O1hY`}tagP~ySxKvmvyAZeNya*!Q4M(KZU?0UY{ZEAbWGAK zAaMbM?!%D`gyQi;JmFMlbwjASJ1D<*=lo}jHxHXGu9#l;L(}PZjHA~S<9AJcCxaK> z(tY}u;!Qug-t^Xqjc=b``J2{HA0Jr%*vOV&N=|;LzI|BIb4hgX=HgJNes;hp8d6U7 z%Er2-gYDA0r?hvEI{T0NhffBEPlg6gIXe%_Pj49A{@U1@$0cijBL3jp>Q(ngKYtoI z|K`lU|Gjq2L&4_f{TEjmZXSW0#{SMbofj`jx^MWWI&H&e)f0X4sX6t?u&ehRHFogc z_NP_7=f>}ioIKk#zhIphpVZ6^c*f6rF8tp3>35>revJ1Y3~8oKb_dwm_1J7)ojj_V zN{Tz(9lM9t{tHN0{%dPPJ)gO|o4s8JlI^RYQ_ncp|Go0}U(;{-f&S1b)h_L#M=>3ox$U~TY3RKNX4gI@J@~fd^d`mC{m#41zJV71_+|h6osgtI zCFw#IJ9E;$q+%wlT1+bMIYqtw7xpjQJnZQ|d}r-rf&Tq*NvBse;nXh%?b@JK5q9Wf zes{?410T8g><+)f;dOXoHhs=K1DR$Z^L*B}n6gSTPBoQqBVh;lQijWCSUmTC00030 z|Lk}99{>O_UP(kjR9(6UbX(`SEvP%Q)~x&Pn@nEjz9dfKJeRo3B`zvfvzjf*lC9n) zij*j-us5-Zy;rgKPJkd-0fOit0D>fX@4a_`=m06nR_3Rj+_%<{n^;E&1O=S^mHqAW z?Qj~EI*UW5(wIf70p?_Y)b3@@@|PFPY>Wn8hDdymko*y=KXZMmO*q$Xg61mA56&gL zJ^1L*OjRPTJ$t6?=1kG~qLXjk-SxXWd;gg5&D%Hky^-?6SA$iV^P}CP!-M^!(7wTu z$$@rkPYJ&_#XWM**?JnE`ZeUvSCa{Q7atv7$vR?dzRJluw4CydsQIC8ta>{2$A$DC z*Xon`kPg}sPHYY@aDCG>%ksLCx5iw3?6(JtA0WS4x;VA(M?5_AzGzt79%~n`Z0@HtW!Q{5y=| zcsWyp{2ujcbjLcti(Yn5y~dcaHvZxDq19<%al^CM7+x5Sv+38OwN@l6>_mr zOjq+(m7G85X!W8s@odv{)-gosWy(b3 zI&x$cQb(+~2*3FkM%lN5flS7DC2gcaFjhF0`1w-WS1YYa>(lM)@Yd<(oaW4Hspt1y zJ@D@NU4Ol}>o0MK-hOoQ)0DG&?*Fj&+R@LF&g_~fzD26Jj?dgpO#Cb9`hTYv9mnRK zhTPvbcIQjT%?}JMS83VbET$gg^%Urk{bOmDCX>IXH$IZXTQSga7@9dkR6y}U#3GS6 zJ+{8kwldwzTbNWM#`IHF>cMzI`O)$0W0Pf%@WTV-MJ$QBy10y`5GHk)_UL4;FmpdL zor>XPE^u+ zxYBd%=~fyFx{R1)Ee>%Pdnxk+q`6@UrhlpI;_Rc(7*(gO*yeTg1P-@E!Y^`AgYwaA zO!BALw7*OHlFWo2DRoB5TV*p>*z7g_I!S;UX0$zo-+rH6a!S$tP}rZ%?#bkJBrzLr z;L9#d<(wLPaA4rpPRPyor|*3^lXi0U$#rc0t<|~|R!bJ4IBq)m1nKD|`)rMQu~m!d zQxL{Pq)82P>F9>34G}ncu%ypd9=)w>Ji{3- zSQzV>hfmB`-^1MdfKqmG1>Qx1brGg|Q4?MBBOUO8XOOPi$&QNgy3CRr2eOa9-g@b8 zq}=_;d+#jXeQW9dJBa)5&m?}pt@)un{;RwnKFB@wPTq;X)|~o-pzbU=?-1<4?(x*` zYOj2SE4hG8*~Ko{Z|J_g)|s|4H-tsP33J1YsYcmk5f_$AYrIV>`jL`;cN#;o2NW#bH!tYjlGAI+Zl<`{QTsg7e$V~bHR7)zAfIv~{bIa=(0v51~Ct~pg z3?9}!oOcD5_XBIBfKPzUFJa+$8iq(tBe z1u?OTnPHI->}3RxG|NQ|%~mH4-2HO)&YR+#4>=G2#7udcQ}WGv{WW;$4P;wRUFOAt z#P5ple^>k9SX<(5T-j+ zhj#JEP65-c<1#~=jz6FwY5T1RM*p)#?^wQ?KB(Rd{ zl-u@3+!~|om zlhT~fa`gjb{R7705T8yIa@XX%HM)quCY93poORMXxxc9W#%J`F`({j+feO=7ryTT2 zFKg1nop$gR?40=x#zctL=fHQ#7P{yYt=wmsgo4Y{Nr#7T?e4z5t1E8beBOC<(OE+2 zSwh9d#fmFarPl~uY1F|dn6~7F`nxhjt$3zfyI7-L9+A-rDmGccqA0mEjgX<2aEx-k zO)GO6R9>q-;Iixpn?zx&+@zLBC44c9B3tTNDLpxr@WDc5{QN}!7z9EZt4AfiPkZz> zt^UR=Y_xlUiiP#^%8%j_-o7&$iLvU2AjwY~%oYu8TTWvoc(UZF;m&@B=b+ z?{el>%%?}>J@@nr^%Bg;BD8m~rwumJ1RJiN8Yo8$mLS_xN1psJQFtCwcB?J>O8SM} zOSN|Be=u_E_r-VjPCWX8^<*zSXWvlb?uv)s zmfhVo`(*!0-q*+nyLys;fcDhPPIt}2+mWy??EK6Uiikuk5SGTMxG^GT3JYspMf73j zhT-rr7^HWmEeD!)Y#`~&h3Z=?km|YC3{1tjv0HDfl%G&8)KE|(%TzpxjA0OG*h`~K zoLPME6`dRw3-a7C&HgC&$QFw^*m@fbG(u? z)`%N!Vs>P#)y1K5PK-Y|&>p|P>iX9cdFP?2-@qR28oT#d>-CR%9vz;@KaZ}B$JXAN zE4qj*y^O8AMytQI)}2M2Xk49q#+vIDVJGC2S?&6gnNRkpI9{#LZ<0qGx*cJQV#}en zs04BeUn*d!R^}C>S=0AFgJgU+(^Wn{JB1kUM3sRfvPxfP zuo&w!&I*FF3}fQP)`3QwZEH%q*!}cAYOI}znCfb(ZOBckxb;o@?JuB@_l`W++naI} zQGb^{l)ch^xA)=hyH~z0IRDX9^8Tfwvu&A|lM=68I(MM=>2++yrO~^e*IxZR`NHmt zCq6xS_@fg?cbz_S=H$8ShmIXTe&nmOCw5&vb1?qYr+2^m;OeoRKOFz^?1|mCkGSN@1d_zS)4FmE843awdR>{}kMruOA>26L6rV)a-SB<{WS zf_<9K>w^At>`?9OL_cDzV{NpY{VWcZ{5j^y(ba(hBD8IKpsB4m`O4RC+&r=K^0zy0 zo!D8Oa7Zweec*GStPxhBd61NwjH` z?}&IU5vSIn5$I%G8J{kqB8{X0QuVc=qMVCoWZojI)O zmUT!SxAHXe{vVL{KjIAJt`3(iR3?l**f(|yl;2N?<(JtLHG<^@CX+#AO7KE6M&!Wq zjB8w(R?M}qv0B=!mI^meV0yy18r9#CdbKnA-eO-XWoD|gvI5dnJ6&5qXwDT57HeTO zoZ&M1SPgr+jXBdn8LN|`J1DJ*(Bys7+27&2a?5fPOYLF!|tE>Y-i8?*os&nn?X>H2YY8>FwIW`<0p3JJU{$B=4U{ zJ2;Vlaj5hm71GI_8y3%xsFq+F+?)V5C>-zP_7&5b?~?1|=L;`FvVZ7EI@Wma*yz)E zJsBENtv)yLpIaq6{DDBgV{;p%Rs~zbUlFciRBK2!qz0P({osTBi}gv^iH@0xf!^A@ zXAh3U9)9H*f6N=s2Pb)bnbMMjWA}DVRX(DOHjsM?sr3oMXSYpbnX2hp$O&; zC)+!m>mN)B3_SD>g0Uw@HdfAowlc<>1*M0{NpFhsKX!JUbPe9(w%=v-WpjGdNyVp7 z_umzl?B!N`%W6+zj8{=%?WmEamAT%PxjquS4>#G1gSOK~D}YABcVxm_av|+y(2jD_ zXiabS#ny+%VNWk(s&911eM+vs)&BV8r33Gs-v4pjsa^Mv{_WnOH&Q_2#vdCmyg5~P zwdMBSw4-m{+V^Js>3x^K-FN-Sr_G7Skon*DUwdcb@xI*eKa4x{e$w~5Y9IcHYt2}E zmb%oLi|@`~>&g(d#-Sd3x>|N_y(gD2(ujg|65W1CqRE39chD(wBQDd=zXcIzBKAk85Y_{TS73gC@ywML?S8H zSQ|2>W|^eJLOhgi?R2?zwpKn>Er3*tXPPZ5lYTKVs9cL0_*)?FZGo6C7~HUF-D-|i zOjB{l!ZiX9GmdL|IR0qgc*-}dnYOv9@v*+Pp4_YBcivZ49~Jc`qsH1;!%yXn7bntA zmft&v=&GU(Rj|9#l)VovkbDKKTDs6BTkO*=c6cx?zNOj_rf!qi{9?KJC8pxlVxbq+ zY@KU#!b&&Bvz687(QzNi@{al&FL=to^_3m=m3|Yd`ZiQ~G*tHWR>huJ#U6Y4AyLIS zQcV(~`~m&y?^F+d>&bmBTJl!7@uQH@YtPCoq+PmM56~*D&GApm` z!Zto4bQMfCKAC8K3T@1rsY{)yPlwiK^c6p>PQEtNS~S)8WTY~EusV0RxxBmP=|FYv zY-7f3$<59?d$84a#-H99El(M%$%5AB2p76}r~%gEFdI3{fwhq9?m_N<&F;)pVJD2Uw?83wB=g4#=u<6J%sd&7qhK&}0zt4!=dNd0h281)a}p*UwR_X{Vt1NFYqeqRvCl4PUbEnSg?BJ)3d#IKBe^J zE{t{{A$>EA8IT8G&BwpVZH-5DmoQqBG_@y}^3N1rJ_M;qUFpacw8YD5&M0etkT&0t zcP8q(5}X~EUUr{)(Ry(6**B5S?}NP;e4Xb)-RD)Eca&XsjU6|1H76O5Kf>Mki!|eN zN6}t$`n%TT|K-m9(46t1A?-a|#@oTHzxY#sYe{>JoB7#n#_`Ui6U1xp*b3hFWc}X$ z@ZT+|ztd%XBG1~T%K1W-`ynUg_4zBmv3FdvwcRl_-7r79YVNvfAC5D3-Eefr*@seP zqlNgoBuaMyy0c`e;mJtJ!_k~8Gr8xW=_jZ1E+MNQ&R0KbyL*^ec|$#v;g~LUBkDAe z65V9EVWw6-S%q#&FSvRb)m0`&ji`x}3jBl|2a#eXiq(?&q=ix@Tn zF1OX8=F)MqJ#9^`^)*`(%u0RS#Qj}UMOT(4Iwz**U@*vF#pB8RbNKrBHAo!=Jww1C zmoZ2>2`yM(;jXW*6LCE?#jy5jJqu^%En7t^4mr~*V;V$sqm<*bXf|wmpTiXN*mvk+ zuWaGx0k1P`kp^{ako^)4jkki9;>T8dG6(PPZHwQFc$Pz*d`2CqM3i0YkK4&=zlW($ z>~ zl)msYUH&Jg{EzqrUkXb0D9U#6vfm#+^?$;zzD7ykB`Q8HFFqnE*vBjQhEez(r}VVE z{Ft%eBgd0JnQ~ueSlOp#Sw)jrv8%iC$p|C=KJ9pjUC!X+PWHXPJ9UYNYMr}O@)=0}&C?w@VHxfgQf z&D96*X)BM}dlSX&kH#Jz$7O#jE8K4dJtgNINACODoR8HdhZMyJPp=O-G`YpF8V5H&yR+ zx9#?id_Q*aKX66IxC0qdSfyyPQaD+|o$F$wCm4&MNY>~_AHGE1lT>{*obXmd%JE5P z|Im^NHaIMwZP;4tc2ma@EsX&g$G6a+Zn%gmI$j=kh}c;vtVnQ|9eGvv+0WH)ZC1bc zQ{@}~$otJdp8hG)e1w|()pX7!Omn_yq{1_j@^kBvmxZqfvj1$z`H+#ZYd-E{b>Y{+ z^#A!&(*N-)e#fgj|Mn{7--2ns^*{b^=J5%kF3E*X+tfD{M*p`$Ao>Q z1|mYmVrk_nhhFEi>H;ovz-_627+GahRxtGs7xv`@Xf`mSS}t;7;mn6c&_g8 zxs~x+!9vGkYsT2q>)gpQbp73>@~gC___fXy+F;RO{*7mkPfwQK0;H5p2tT=3oc{3@+i<|^wbCm)-6I0NYK6L-jbTfm!yPo zU^YWbCe>T^!=g zwlRmF3P%gM1G&`pR7l~qva5S=O^;cA5P*dk=T0M3o-(RP- zTg5I{^#MoC5mWUsUe0cE>MniH!w{|`%9@YKs4onHmwxjLzirEHjXErDjm$3N8TfQ1 zb45(T@cTMjZk~naCzAUsc#FLn+GKyhHCp>a!$g*L-~qAZ%(J*pCQ8mxA%y}`uaF8A ztu4ydh$b%6CYPA>YLh|hc36RX?{eBbZdWK62>5-0pg$B2Mk1jdu}Cx)jYPu1pwGME zvb!t>i%y{tv!zTjpMqLj9EY`+7T!HQ(~`@bZDT-dDFcPFg~s707YFmNpu3*n`iclc z<P1z_md3tud$C|x|`|yMLtG~ykylE)@LYMc6GJB^Y_cKA}r_8j^G_|KKoj3KJ@#>!Ys{T~@ zNS=KBscotKrEDq6U+~hP08Yw;7STg*FRQzL0#^KZb)->>8{bf_U`J|sOZ_VHxCGm` z0<9UZeNdBjwyX5s;z$hxJ;uaL$<_!e235sb*Gjlnt;}uF`kdzQhAZrI`#g@2&l8IT zV$tAcB)HA}CisbjLV*px$LY139Y(cL!B_HDCF?jIah5vM+mLmuBmWMntAGt}VnV6} z)3u$c-*=|}2+9DiI}h7igy}7LmUF8l>D*v#_9|kCiG{HUGhEWVkctAvj*^a((NH`* zoHjRz9ecLWTLZ1n91RiBFT+dk%#895gKSs^>ZsbI&Bx zjU&02p4~k>lYd#>pU-bj<~2NAt%#dRKhb&Xi=oGdI92EQ6=yglCpbmNR?>GdvUZ7! z_KWj(^D;i+W$xsq0g3uPH|--$ zv?}?+v#hJYibuAj;X1Q>v(L4qeh(>&!*=E%TQgS1tD*I28cw{E@p+(q;Od^Hj`S+qt8JHOP{1r(bFKTB{UQZ1D)%w z8EeRG%}XeMc)s%SrHO`YknSS!G5t@*^w*quZ(1wALe^ex zOWcF6yRU>cDdBz0@qRXHj!wo?SC@&a%cK=Ng@|Mtr{X|1{!fZ!57YCP6kUZ=Z8#N&%z(p8{ z7&{@sjEk3s#pofKtlE`XD@d?M1@1D%KeyrfaVMul&x~rTt z)8StbsCA4rEtv&V{PDef_!Tm;3TS zdou&R$$yj@!N>H@_|=wc5n@Gf^g*ouPO$EbJAc2YV1J>jWi#)uI;I4N|9B<@cEVURxvxTE73E+`rh2J&%Sr!+~hf7Y%qq z8;%XT0bCt}l&xSdt62o$^33X7-*8QOY2xXwg4=|FQbK?6Ox?qd)Kld*zs7gv;JWii z$`Y#{{`ln9w*~QMFr&>}+@y#+FQy`;D=672TDgV+T2ITw>)8Y&mo(bhG}O^TMbGO* zY^{Ky;jU`AD+a-;QMf9lVPxw#Hers5o8?kad>U3OVv1QS3L#Uk6loPgqe`q-2=#Kl zLC!VGIZmAjxX~^R-=i0L^n##O?lVb4c6HQaih3XWZo9{B z0t(1wR62DMhe}|Tv1~G?Q^^J%h@M9=iPykCe_48=srhRrIhRF2i;xgAe#*{XVh~4I ztSPQwmd}E*F};-DQc_JituAY=Esr`-NSJtvoGc_QR@3Gyr)%!iUHE)5@q}<`d}+L+ zukPt!OBH5zqM@RAaTd;Fvm|1%Las0xjSjobWiz{N2Cr3XRL|Qc z{^(41Whw90z{A7qS|ok!+u93=#E8x&HGs7MJxii---k`K^q8d0Q$kK z>9uIAYN1B3reqN%D@ZYU20zi<@+2<%`r-NZeBy8=uBTw6@Otj~&s$P{94L%y$+*&x zes!oSZLYgw9Werkm#?8!OoEO>(Q&B&dJf2Pijlu!7OwWT)OWWuQLreJN@i9`%}TLJ zF0iVEPL0SYW`Rv3t&pylu(e_~xV;1@SIdP)ozia68}(|d32Yx2TwokE0cS+!v1&Xf zWx%ctIkZ8$ChXG3yyi`xb<=N;Y}l-N#pqync}W2dv$)}P2K?UVAm+g|>#}Y*jNn@P zEgFwOwqXJhBlqaUHU-zE6N57jjo75%8mS@!kM(P zpwh)wXx=q`XTEQ$d2^;UI9cx)DX~x2STSunVwafEEnFU2o@r?-eNdcw{aJY?896Fv z0q!XV1>0$qxh$$!$Q2E`qrY+wSpNkf!2MPvuo($#h5eBYr{7`Ruxh|shl~m8Ge$&R zV4}x>uzGy)Ku6JCNMk0nHn}VNO5ybbWp|FZW?vtxNdq@D!HobZWnM&Hkb-+ctYy7m z)huOO42}`G$=hLmCGPEDFs%o1f;Cp zs4{64fO4nZ>~`5)F1y`swb{%bkJG zIXBnfZOnx}Ai}`{lZdh)Tg7O&6uppc5VK7(o<${c>J(nH)^7vX*BG!F!NG>Z=6AaS z9+%&32MD-PIMLXog95byzy z0;rRa@8xC$=ocX6fRNb&A1UD41P3AS%dODQKgC{dg<~QAW)!^059ZhxFJ6X1Az*6& zKO++KM}r&NAJ*prh-}y+UfUM9EXf?gMZ#h~?oJ1kzi)@9b3^)`#iYqhxa zI*UeW&?+=~g-9b5C^o0;l|v`i3fF+xR^B5CTEBvIx|flC`YigLPmwNOYSP_z8Ni-Le680zIz4hBxTZjYqf2uA|Iga&rhHh$p{ za2bt;!Hf!$dn*cv5C8uFi2oIvfb!U8?AI?40f2t+LO_4ypZyNBysa<*NPyt>#Jk-Z z{GmVqIHBIK*AsCE{mvI|`_DGp&sN(@t0m$vxjhEkhTh`UI$Ro`RUOeOw&aqinC}&` zO<;9eNaKpBG6qUXUy{+$ycN_c5kaHkxqOaXqfwi!YKz_C@tGVBhuh)v+BfVvvx4PS zvwX@`-TFKoF}O~^N?CM+Ol(yv>^dcIX~JI9X2`k~GH(X;TLJC!4b=;`a?7p=nG|j< zn9LO#sZu6Vsf2u^XvH9=nPhaUit98;yjE4fZHxpQu`tm2p!WrK0M=i|LI5vf|E&BV z6+oT*Mf8C*wQo2;KUSDke7%IB7q1(|t8C(|f{9aem*uQwC5NKsuj)ihgN$odiR^lX z%cAqx%s#jC7s~yiU@*L$q~KC-Mk8AhP@yB6&%>dY;lMT`{-47BpCbO3Vc*N}#*5H) z5d0TF=>}zdE8+tQy%h}rYC-x&H@Bi7eK)sao16cla@(E)*aFq-U-+*G_}|=bN6R+% z;0HJwz|{Jc{>|;U32*(Pd%)w?_8SE;0V+y38V*N7+W@f;jDhMB_{rycFChsW#k`#l>TyIBw9h1_9O0>uNiU7Q@ATOxC5RKT0E*fb8eE)+Dq z44eNEGW;W;{fA!#@N+=5cnhl4}Z8EquCb!b;QYf8jj#C4qtI%zfZUEw)hVX_p z7IbY!HeylW?QCK)U;+Ro<#U5(rw4M{X^>gfd@zJ)_#m1XCI!bJ z=K&>bQHyOlIcU#-bzlhxJdWUoCmiqtn;2B(ZQC%mwHbR6i@gMh#$EutjD~-X1b>bO zU&R8iqTBcx0K`GW_cG#p5e8yy;{`Z~_@0BusDB%=z;-d;3~g?+zO@Oyeq|p7z-AP< z6#oJ!^4k&cU)+OZaAq4o8EpSDFf+EX9Raa_2F)*V6L}u{=O6jy{IBux&&Nm%v<=WN zwzk5X&x5h&f#_Bc7-S$SfN%&0BB5XydLAgYXc3|l@+)N2MK38>$owE;0}Fq`!jo5AjKSnWT{70=b`fI;iD z8>|~vTgd5+c_Xon%?QX4_w$hBdBnaMwT7eCK-lW{S%Xe%)NFgMw?z$lzgZqID*}LZ rFa)^_5wA7scW#1o0*d|@Pxt==`PRN18{?2E00000NkvXXu0mjfa4UJ( literal 0 HcmV?d00001 diff --git a/media/ab9a8dcdda85f1d8789909803374fbea.jpg b/media/ab9a8dcdda85f1d8789909803374fbea.jpg new file mode 100644 index 0000000000000000000000000000000000000000..691750abd308bccaa93919bc152b888ed3baf852 GIT binary patch literal 174536 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 literal 0 HcmV?d00001 diff --git a/media/jiyan_test_api.png b/media/jiyan_test_api.png new file mode 100644 index 0000000000000000000000000000000000000000..2848d84cf3000a54ed5919c92eb09c6b36652e74 GIT binary patch literal 42887 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 Mp#LdjfPatu7fj_`1poj5 literal 0 HcmV?d00001 diff --git a/media/yidun_demo.jpg b/media/yidun_demo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d5b944941d36e1287b41fd7fd3bb38f0c2d80a41 GIT binary patch literal 41793 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 R=AoK%oR-Z$XXY+*|Jg0KiC+K! literal 0 HcmV?d00001 diff --git "a/media/\351\230\277_1cde28c6abce11eab97c0242ac110002.jpg" "b/media/\351\230\277_1cde28c6abce11eab97c0242ac110002.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..b1b8681893432dd8c7148adad7895bc9061c3c49 GIT binary patch literal 1843 zcmbV}X;jl!8pdySRzpw%1qO(L0ER6HwpEltAgIh(1rb3cBS^y*kwq2-GcJHeN(@V? zc7$3GkRlisK_^hzMQk;Qlq4mPASj}cAYhb)e-k}t=F5DT_PytQ&b{Zp_ul7sUuYDX z07kp0JE;H$0|2HO01^XV0EcNqt8i@~5n4qdkq9Ijg+_l&jIItEql-bKb@X*~^|Yax z8R+X7XcyW`J{^Ul5D1hW295bx@`nVv4{$nw2&@pW^#G28A#gCL2Uu%-qCVQwnEezm zI0A`6V>CAOH3cn38v6)@#xzRfSW}&&*#}4*%9ud$L9g9=7_&Zko%?Cdbsge%UZ+Wr zKyJG+D&>r>9^TaKGjltVy@TTh56?}XfAQsJUq63pz>b}}g7<~&4?PeT9(^R{YkF*4 zd}`Y9^o-1`6KBum=H;Kiz$z*(Ddm29`O4KFDk^VORoC3CZER|8xzpNq_g+_bPj6rU zgMo)bPlun4{5mQWNoAAIr>0-LoOz{Kc)Pf?{7(7)gO&>h5TCF#`aijF8ZNlD2N*3E z44$D$1P+NJP|(IcdohQT*RFRzt+Q@B=Q^)bm$)%VZW5Iu(8Jq$NbM9_w2x%}AJ~~c zMfM-C|8j|d0RpCJ9s&ovfjU;*4gp33e6_b6o*k;l@B6UrW>$jqnv3K>^Xxu~;qK|_ zU{w3Rg55?77o-ulqs^@;AuJA!Lo?wM6;GG-l?*8aM1h^m7CPI*RrGi=vUOX744W&$ zb3M1X8pns1K1$?%QxSn**?f@b+{R6E|GK2a3^u`@g8*LjSGoP0*_G&c<{B?w`P?{7 zPP;!w)j#ifB`Jx-n(s4RbK9@#7YCMC`u4CUuY9)$5ZEx$o(uta3j~B@DFXt1N#e*= zZ`^DLK|XgQt4jG;W__N~WH%^unMw5EO!Hb>4fZ=o(O!+zf=4*r_pH&Yr5m;~On3{= zc){1G4Y9Y_G3|=tSYt)(-ICxOZ z<+UMs?mI1A@@y0DhaOM&ZeqTks#h5a@>*BSR-cuvALi@d3?RlyunJOD8R1E@danBC zr_;ZE>!uQHi+U@uS$LF=CNk=>+smC=7G1u0H!$d&gLP8`30Hs7yo}BLiS8}bd>=QX z%vO13e_wY`-t&iaej7K;GbbfZ><|)cj2TG0_rrV$%FVgMD%(m@e{FT2UdokCbS4d$lpHOx}01bi6hRETi$GWQ{ z5YSJoCp7NkH!4C4XglsW5+vD|mq@us(%tGI;F=1E_Mf5KX+7gS2)r&<_;z!xEtp3j zz*;rWT*A1|oU)f!RVUnfDe7d=^QcAk?qUh@(%v7Sw7da8=4I~3c2R~LClxnArrm&fFvT}-<-?B!n*&y@*mXull{3m{YC z?20#jMat?TS~gi`ILZtAC+@Ii4F%2>Ri6* zvD11H0WpkYT+TrAQ70aJsF=Lg(PbBTj%@ducKuyQ(6Z|j6H zRL%BuH9a--llk#O(ZNsa7rWz5R@Q}YY`BtI-z6=)%3bLU3{1{@U=>N#joL*Xco=P( XTbvM?wBVIkOUcaI)G`eLA|(7B*K0NU literal 0 HcmV?d00001 diff --git a/nine b/nine new file mode 160000 index 0000000..4a03d40 --- /dev/null +++ b/nine @@ -0,0 +1 @@ +Subproject commit 4a03d405982aa1e1e911eac42b0ffce29cc8c8ef From 0f8c5c81ca31e844a65a55e79b64a8a6e8a5778f Mon Sep 17 00:00:00 2001 From: huaiyukeji Date: Sun, 17 Dec 2023 22:22:32 +0800 Subject: [PATCH 2/3] docs: readme --- README.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index fb5146d..5dbf2ac 100644 --- a/README.md +++ b/README.md @@ -30,13 +30,17 @@ --- +## 联系方式 + +[TG电报群](https://t.me/+Wj3ALdyYXV1lNmM1) + ## 待更新内容 如果对您有用,请给个star:star::star::star:谢谢。点赞可让我看到大家的关注情况,持续更新的动力,谢谢支持。 -刚建了个群,随缘加加!不能分享的代码在群里交流!群号::rocket:`1040784971`:rocket: + 许多内容待整理。 @@ -86,11 +90,3 @@ - -## 联系方式 -欢迎技术交流:`huaiyukeji@gmail.com` - - - -TG电报群:https://t.me/joinchat/99xuS4HiOIc2YTU1(老群已解散) - From 3d9448ee32e7c7ded4ce3465465ac527eae51493 Mon Sep 17 00:00:00 2001 From: huaiyukeji Date: Mon, 18 Dec 2023 19:09:03 +0800 Subject: [PATCH 3/3] docs: readme --- IMG_1766.JPG | Bin 219722 -> 0 bytes README.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 IMG_1766.JPG diff --git a/IMG_1766.JPG b/IMG_1766.JPG deleted file mode 100644 index 4f7e7a76e149339bb98c64f6fc760f9914466fef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 219722 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