diff --git a/ocr/README.md b/ocr/README.md new file mode 100644 index 0000000..aed4f16 --- /dev/null +++ b/ocr/README.md @@ -0,0 +1,73 @@ +# OCR Diagram Tools + +This suite of tools is to help create a simpler way to get braille diagrams made. +This works upon the *original* image and does not create a new diagram from scratch. +I believe this is optimal for most cases. + +You can run each tool individually with `cargo run --bin [arg1] [arg2]`. + +Go to `braille-diagram-tools` to use the binaries. + +## btt-get-ocr + +`btt-get-ocr [diagram.png] [out.json]` + +This program take the image at `diagram.png` (this is the default value) and output OCR data in JSON format into `out.json` (default). + +## btt-label-ocr + +`btt-label-ocr [diagram.png] [out.json]` + +This program takes the OCR data and lays it overtop the diagram. +How so? +It adds a rectangular box around each OCRed piece of text, along with a label (usually a number starting from 0) to the left of the box. +This allows you to see how acurate the OCR was and to change what is broken with this next tool: + +## btt-edit-tools + +`btt-edit-tools [out.json]` + +The program edits the json (NOT in place) with advanced manipulation functions to help with OCR-related tasks. +The id to the left of the box is very useful right about now. + +Here is a list of all the commands you can use while running `btt-edit-tools`: + +``` +merge|id1|id2 # merges two OCRed sections together, least of x and y to greatest of x+width and y+height. +vsplit|id # split OCRed section into top and bottom pieces. +hsplit|id # split OCRed section into left and right pieces. +add|x|y|w|h # add a new OCR section with x, y, width and height. +rem|id # remove an OCR section +triml|id|dw # change width by dw (delta width) +trimr|id|dw # change width by dw (delta width) and move x the same amount (plus) +trimt|id|dh # change height by dh (delta height) and move y the same amount (minus) +trimb|id|dh # change height by dh (delta height) +movel|id|dx # change x by dx (positive = left move) +mover|id|dx # change x by dx (positive = right move) +moveu|id|dy # change y by dy (positive = upward move) +moved|id|dy # change y by dy (positive = downward move) +paddl|id|dx # change x by dx and add to width same amount +paddr|id|dx # add dx to width +paddt|id|dy # negate dy from y +paddb|id|dy # add dy to height +text|id|some string # make the text of some string (used for braille printing later) associated with id +save|filename # save current json data to filename +``` + +**NOTE: currently, any command error will crash the program; +this will be fixed eventually.** + +## btt-whiteout-labels + +`btt-whiteout-labels [out.img] [out.json]` + +This program takes an image and a json file and places a filled white box overtop all OCR sections. +This is useful before running the next tool. + +## btt-add-braille + +`btt-add-braille [out.img] [out.json] [font_size]` + +This program takes an image and a json file and based upon the position (x,y) adds text of `font_size` (default `20.0`) where each OCR section is in the JSON. +This often does not work the first time due to the braille using more characters than standard print. +You'll generally need to go back to editing the json, running `whiteout` and running this tool a few times to get it just right. diff --git a/ocr/braille-diagram-tools/Cargo.lock b/ocr/braille-diagram-tools/Cargo.lock new file mode 100644 index 0000000..5f951af --- /dev/null +++ b/ocr/braille-diagram-tools/Cargo.lock @@ -0,0 +1,1138 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13739d7177fbd22bb0ed28badfff9f372f8bef46c863db4e1c6248f6b223b6e" + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "autotools" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26fdaa336c5acffd54aebb95c7086109fdce5128570c8150ebfd1d5bdee89e0c" +dependencies = [ + "cc", +] + +[[package]] +name = "bindgen" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2da379dbebc0b76ef63ca68d8fc6e71c0f13e59432e0987e508c1820e6ab5239" +dependencies = [ + "bitflags", + "cexpr 0.4.0", + "clang-sys", + "clap", + "env_logger 0.8.4", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex 0.1.1", + "which 3.1.1", +] + +[[package]] +name = "bindgen" +version = "0.59.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8" +dependencies = [ + "bitflags", + "cexpr 0.6.0", + "clang-sys", + "clap", + "env_logger 0.9.0", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex 1.1.0", + "which 4.2.2", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "braille-diagram-tools" +version = "0.1.0" +dependencies = [ + "image", + "imageproc", + "leptess", + "louis", + "ocr-json-common", + "rusttype", + "serde_json", + "text_io", +] + +[[package]] +name = "bytemuck" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72957246c41db82b8ef88a5486143830adeb8227ef9837740bdec67724cf2c5b" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cc" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" + +[[package]] +name = "cexpr" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" +dependencies = [ + "nom 5.1.2", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom 7.1.0", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clang-sys" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa66045b9cb23c2e9c1520732030608b02ee07e5cfaa5a521ec15ded7fa24c90" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "conv" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" +dependencies = [ + "custom_derive", +] + +[[package]] +name = "crc32fast" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +dependencies = [ + "cfg-if", + "lazy_static", +] + +[[package]] +name = "custom_derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" + +[[package]] +name = "deflate" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "env_logger" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "env_logger" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gif" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3a7187e78088aead22ceedeee99779455b23fc231fe13ec443f99bb71694e5b" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "hermit-abi" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7a30908dbce072eca83216eab939d2290080e00ca71611b96a09e5cdce5f3fa" +dependencies = [ + "libc", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "image" +version = "0.23.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "gif", + "jpeg-decoder", + "num-iter", + "num-rational", + "num-traits", + "png", + "scoped_threadpool", + "tiff", +] + +[[package]] +name = "imageproc" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7923654f3ce7cb6849d5dc9e544aaeab49c508a90b56c721b046e7234c74ab53" +dependencies = [ + "conv", + "image", + "itertools", + "num 0.3.1", + "rand", + "rand_distr", + "rayon", + "rulinalg", + "rusttype", +] + +[[package]] +name = "itertools" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "jpeg-decoder" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2" +dependencies = [ + "rayon", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "leptess" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771f22866e3f8129250c8353c9da920f13d93d276846ba9367771d2fdb7b4091" +dependencies = [ + "tesseract-plumbing", + "thiserror", +] + +[[package]] +name = "leptonica-plumbing" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13adbee6950b65822bbc7a737aff78ee1d837b732a4bcee50f3aba5d89c519c3" +dependencies = [ + "leptonica-sys", + "thiserror", +] + +[[package]] +name = "leptonica-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bb31a2bd5897466300ade8d8398b1a005fbcf1250a0e44301f5ff72568190d3" +dependencies = [ + "bindgen 0.56.0", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libc" +version = "0.2.110" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b58a4469763e4e3a906c4ed786e1c70512d16aa88f84dded826da42640fc6a1c" + +[[package]] +name = "libloading" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afe203d669ec979b7128619bae5a63b7b42e9203c1b29146079ee05e2f604b52" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "louis" +version = "0.6.2" +source = "git+https://github.com/TTWNO/liblouis-rust#dad39678ede154a9c6296fa0852c565258ed854c" +dependencies = [ + "log", + "louis-sys", + "semver", + "widestring", +] + +[[package]] +name = "louis-sys" +version = "0.6.1" +source = "git+https://github.com/TTWNO/liblouis-rust#dad39678ede154a9c6296fa0852c565258ed854c" +dependencies = [ + "autotools", + "bindgen 0.59.2", + "log", + "pkg-config", +] + +[[package]] +name = "matrixmultiply" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcad67dcec2d58ff56f6292582377e6921afdf3bfbd533e26fb8900ae575e002" +dependencies = [ + "rawpointer", +] + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +dependencies = [ + "adler32", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "nom" +version = "5.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" +dependencies = [ + "memchr", + "version_check", +] + +[[package]] +name = "nom" +version = "7.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109" +dependencies = [ + "memchr", + "minimal-lexical", + "version_check", +] + +[[package]] +name = "num" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" +dependencies = [ + "num-integer", + "num-iter", + "num-traits", +] + +[[package]] +name = "num" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b7a8e9be5e039e2ff869df49155f1c06bd01ade2117ec783e56ab0932b67a8f" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "ocr-json-common" +version = "0.1.0" +dependencies = [ + "serde", +] + +[[package]] +name = "owned_ttf_parser" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f923fb806c46266c02ab4a5b239735c144bdeda724a50ed058e5226f594cde3" +dependencies = [ + "ttf-parser", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pkg-config" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1a3ea4f0dd7f1f3e512cf97bf100819aa547f36a6eccac8dbaae839eb92363e" + +[[package]] +name = "png" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" +dependencies = [ + "bitflags", + "crc32fast", + "deflate", + "miniz_oxide 0.3.7", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" + +[[package]] +name = "proc-macro2" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb37d2df5df740e582f28f8560cf425f52bb267d872fe58358eadb554909f07a" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_distr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2" +dependencies = [ + "rand", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rawpointer" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebac11a9d2e11f2af219b8b8d833b76b1ea0e054aa0e8d8e9e4cbde353bdf019" + +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "rulinalg" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04ada202c9685e1d72a7420c578e92b358dbf807d3dfabb676a3dab9cc3bb12f" +dependencies = [ + "matrixmultiply", + "num 0.1.42", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rusttype" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc7c727aded0be18c5b80c1640eae0ac8e396abf6fa8477d96cb37d18ee5ec59" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ryu" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568" + +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.131" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ad69dfbd3e45369132cc64e6748c2d65cdfb001a2b1c232d128b4ad60561c1" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.131" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b710a83c4e0dff6a3d511946b95274ad9ca9e5d3ae497b63fda866ac955358d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "shlex" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" + +[[package]] +name = "shlex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "syn" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "tesseract-plumbing" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef98c10d582467f68646ab60fb257cbcb122fa70b3153ec9dac858170ccc58f7" +dependencies = [ + "leptonica-plumbing", + "tesseract-sys", + "thiserror", +] + +[[package]] +name = "tesseract-sys" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1615a77aacfad673fe1dc5762f06ab3529c1a52bdb5bf6624f790f0ab2b74fd" +dependencies = [ + "bindgen 0.56.0", + "leptonica-sys", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "text_io" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee74b5019b48991b09803402aaf9e65a053b3993fe9d9c475ab67a395358ba76" + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tiff" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a53f4706d65497df0c4349241deddf35f84cee19c87ed86ea8ca590f4464437" +dependencies = [ + "jpeg-decoder", + "miniz_oxide 0.4.4", + "weezl", +] + +[[package]] +name = "ttf-parser" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e5d7cd7ab3e47dda6e56542f4bbf3824c15234958c6e1bd6aaa347e93499fdc" + +[[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "weezl" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b77fdfd5a253be4ab714e4ffa3c49caf146b4de743e97510c0656cf90f1e8e" + +[[package]] +name = "which" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724" +dependencies = [ + "libc", +] + +[[package]] +name = "which" +version = "4.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea187a8ef279bc014ec368c27a920da2024d2a711109bfbe3440585d5cf27ad9" +dependencies = [ + "either", + "lazy_static", + "libc", +] + +[[package]] +name = "widestring" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/ocr/braille-diagram-tools/Cargo.toml b/ocr/braille-diagram-tools/Cargo.toml new file mode 100644 index 0000000..1f38750 --- /dev/null +++ b/ocr/braille-diagram-tools/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "braille-diagram-tools" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +leptess = "^0.13.1" +ocr-json-common = { path = "../ocr-json-common" } +serde_json = "^1.0" +imageproc = "^0.22.0" +image = "^0.23.14" +louis = { git = "https://github.com/TTWNO/liblouis-rust" } +rusttype = "^0.9.2" +text_io = "^0.1.9" diff --git a/ocr/braille-diagram-tools/done/and-gate/AND.png b/ocr/braille-diagram-tools/done/and-gate/AND.png new file mode 100644 index 0000000..e0b2233 Binary files /dev/null and b/ocr/braille-diagram-tools/done/and-gate/AND.png differ diff --git a/ocr/braille-diagram-tools/done/and-gate/braille.json b/ocr/braille-diagram-tools/done/and-gate/braille.json new file mode 100644 index 0000000..e2adfdb --- /dev/null +++ b/ocr/braille-diagram-tools/done/and-gate/braille.json @@ -0,0 +1 @@ +[{"id":"0","hint":"A","confidence":0,"width":89,"height":94,"x":212,"y":105},{"id":"1","hint":"AND","confidence":0,"width":333,"height":112,"x":512,"y":500},{"id":"3","hint":"AB","confidence":0,"width":180,"height":130,"x":1080,"y":170},{"id":"2","hint":"B","confidence":0,"width":140,"height":95,"x":162,"y":257}] \ No newline at end of file diff --git a/ocr/braille-diagram-tools/done/and-gate/out.json b/ocr/braille-diagram-tools/done/and-gate/out.json new file mode 100644 index 0000000..3fff728 --- /dev/null +++ b/ocr/braille-diagram-tools/done/and-gate/out.json @@ -0,0 +1 @@ +[{"id":"0","hint":"A\n","confidence":96,"width":89,"height":94,"x":212,"y":105},{"id":"1","hint":"AND","confidence":0,"width":333,"height":112,"x":512,"y":500},{"id":"3","hint":"AB","confidence":0,"width":200,"height":100,"x":1075,"y":187},{"id":"2","hint":"B","confidence":0,"width":89,"height":98,"x":212,"y":254}] \ No newline at end of file diff --git a/ocr/braille-diagram-tools/done/and-gate/out.png b/ocr/braille-diagram-tools/done/and-gate/out.png new file mode 100644 index 0000000..09b40a5 Binary files /dev/null and b/ocr/braille-diagram-tools/done/and-gate/out.png differ diff --git a/ocr/braille-diagram-tools/done/and-gate/ready.png b/ocr/braille-diagram-tools/done/and-gate/ready.png new file mode 100644 index 0000000..121740b Binary files /dev/null and b/ocr/braille-diagram-tools/done/and-gate/ready.png differ diff --git a/ocr/braille-diagram-tools/done/and-gate/whiteout.json b/ocr/braille-diagram-tools/done/and-gate/whiteout.json new file mode 100644 index 0000000..e2adfdb --- /dev/null +++ b/ocr/braille-diagram-tools/done/and-gate/whiteout.json @@ -0,0 +1 @@ +[{"id":"0","hint":"A","confidence":0,"width":89,"height":94,"x":212,"y":105},{"id":"1","hint":"AND","confidence":0,"width":333,"height":112,"x":512,"y":500},{"id":"3","hint":"AB","confidence":0,"width":180,"height":130,"x":1080,"y":170},{"id":"2","hint":"B","confidence":0,"width":140,"height":95,"x":162,"y":257}] \ No newline at end of file diff --git a/ocr/braille-diagram-tools/done/clock-timing-d-flip-flop/braille.json b/ocr/braille-diagram-tools/done/clock-timing-d-flip-flop/braille.json new file mode 100644 index 0000000..587951f --- /dev/null +++ b/ocr/braille-diagram-tools/done/clock-timing-d-flip-flop/braille.json @@ -0,0 +1 @@ +[{"id":"0","hint":"1\n","confidence":90,"width":14,"height":23,"x":322,"y":4},{"id":"1","hint":"1\n","confidence":80,"width":14,"height":23,"x":571,"y":4},{"id":"2","hint":"1\n","confidence":90,"width":14,"height":23,"x":821,"y":4},{"id":"3","hint":"1\n","confidence":90,"width":14,"height":23,"x":1070,"y":4},{"id":"4","hint":"Clock","confidence":0,"width":130,"height":55,"x":6,"y":28},{"id":"5","hint":"0","confidence":0,"width":48,"height":28,"x":418,"y":38},{"id":"6","hint":"0","confidence":0,"width":62,"height":28,"x":663,"y":38},{"id":"7","hint":"0","confidence":0,"width":78,"height":28,"x":912,"y":38},{"id":"8","hint":"Load","confidence":0,"width":134,"height":54,"x":5,"y":91},{"id":"9","hint":"D","confidence":0,"width":130,"height":53,"x":4,"y":167},{"id":"10","hint":"Q","confidence":0,"width":133,"height":35,"x":6,"y":273},{"id":"11","hint":"0","confidence":0,"width":63,"height":28,"x":168,"y":38}] \ No newline at end of file diff --git a/ocr/braille-diagram-tools/done/clock-timing-d-flip-flop/diagram.png b/ocr/braille-diagram-tools/done/clock-timing-d-flip-flop/diagram.png new file mode 100644 index 0000000..7d2f9b7 Binary files /dev/null and b/ocr/braille-diagram-tools/done/clock-timing-d-flip-flop/diagram.png differ diff --git a/ocr/braille-diagram-tools/done/clock-timing-d-flip-flop/out.png b/ocr/braille-diagram-tools/done/clock-timing-d-flip-flop/out.png new file mode 100644 index 0000000..c8d46ea Binary files /dev/null and b/ocr/braille-diagram-tools/done/clock-timing-d-flip-flop/out.png differ diff --git a/ocr/braille-diagram-tools/done/clock-timing-d-flip-flop/ready.png b/ocr/braille-diagram-tools/done/clock-timing-d-flip-flop/ready.png new file mode 100644 index 0000000..54ab746 Binary files /dev/null and b/ocr/braille-diagram-tools/done/clock-timing-d-flip-flop/ready.png differ diff --git a/ocr/braille-diagram-tools/done/clock-timing-d-flip-flop/whiteout.json b/ocr/braille-diagram-tools/done/clock-timing-d-flip-flop/whiteout.json new file mode 100644 index 0000000..ac5216a --- /dev/null +++ b/ocr/braille-diagram-tools/done/clock-timing-d-flip-flop/whiteout.json @@ -0,0 +1 @@ +[{"id":"0","hint":"1\n","confidence":90,"width":14,"height":23,"x":322,"y":4},{"id":"1","hint":"1\n","confidence":80,"width":14,"height":23,"x":571,"y":4},{"id":"2","hint":"1\n","confidence":90,"width":14,"height":23,"x":821,"y":4},{"id":"3","hint":"1\n","confidence":90,"width":14,"height":23,"x":1070,"y":4},{"id":"11","hint":"","confidence":0,"width":63,"height":28,"x":168,"y":38},{"id":"4","hint":"Clock","confidence":0,"width":130,"height":55,"x":6,"y":28},{"id":"5","hint":"0","confidence":0,"width":48,"height":28,"x":418,"y":38},{"id":"6","hint":"0","confidence":0,"width":62,"height":28,"x":663,"y":38},{"id":"7","hint":"0","confidence":0,"width":78,"height":28,"x":912,"y":38},{"id":"8","hint":"Load","confidence":0,"width":134,"height":54,"x":5,"y":91},{"id":"9","hint":"D","confidence":0,"width":130,"height":53,"x":4,"y":167},{"id":"10","hint":"Q","confidence":0,"width":133,"height":35,"x":6,"y":273}] \ No newline at end of file diff --git a/ocr/braille-diagram-tools/done/example-of-microprocessor/braille.json b/ocr/braille-diagram-tools/done/example-of-microprocessor/braille.json new file mode 100644 index 0000000..836927d --- /dev/null +++ b/ocr/braille-diagram-tools/done/example-of-microprocessor/braille.json @@ -0,0 +1 @@ +[{"id":"0","hint":"branch","confidence":0,"width":78,"height":19,"x":1015,"y":15},{"id":"1","hint":"ALU operation","confidence":0,"width":162,"height":25,"x":792,"y":431},{"id":"2","hint":"add","confidence":0,"width":47,"height":23,"x":567,"y":317},{"id":"3","hint":"pc","confidence":0,"width":39,"height":42,"x":97,"y":557},{"id":"6","hint":"add","confidence":0,"width":47,"height":21,"x":362,"y":329},{"id":"12","hint":"MemRead","confidence":0,"width":125,"height":33,"x":1143,"y":735},{"id":"21","hint":"m","confidence":0,"width":25,"height":27,"x":385,"y":90},{"id":"22","hint":"m","confidence":0,"width":33,"height":28,"x":840,"y":589},{"id":"24","hint":"u","confidence":0,"width":25,"height":25,"x":385,"y":125},{"id":"26","hint":"x","confidence":0,"width":25,"height":25,"x":385,"y":155},{"id":"28","hint":"x","confidence":0,"width":30,"height":30,"x":840,"y":655},{"id":"27","hint":"u","confidence":0,"width":30,"height":30,"x":840,"y":620},{"id":"29","hint":"m","confidence":0,"width":30,"height":30,"x":844,"y":310},{"id":"30","hint":"u","confidence":0,"width":30,"height":30,"x":845,"y":340},{"id":"31","hint":"x","confidence":0,"width":30,"height":30,"x":845,"y":375},{"id":"33","hint":"0","confidence":0,"width":57,"height":25,"x":1000,"y":598},{"id":"4","hint":"Data","confidence":0,"width":56,"height":24,"x":522,"y":463},{"id":"11","hint":"Registers","confidence":0,"width":118,"height":28,"x":624,"y":564},{"id":"14","hint":"Register #","confidence":0,"width":120,"height":29,"x":519,"y":599},{"id":"5","hint":"Register #","confidence":0,"width":119,"height":28,"x":522,"y":532},{"id":"19","hint":"Register #","confidence":0,"width":119,"height":28,"x":522,"y":663},{"id":"25","hint":"control","confidence":0,"width":134,"height":45,"x":527,"y":877},{"id":"13","hint":"Address","confidence":0,"width":98,"height":24,"x":1068,"y":560},{"id":"17","hint":"Data memory","confidence":0,"width":151,"height":76,"x":1094,"y":612},{"id":"23","hint":"Data","confidence":0,"width":56,"height":24,"x":1072,"y":718},{"id":"9","hint":"Instruction","confidence":0,"width":120,"height":23,"x":312,"y":565},{"id":"8","hint":"Address","confidence":0,"width":98,"height":23,"x":192,"y":565},{"id":"16","hint":"Insturction","confidence":0,"width":135,"height":23,"x":199,"y":628},{"id":"18","hint":"memory","confidence":0,"width":104,"height":24,"x":215,"y":665},{"id":"7","hint":"MemWrite","confidence":0,"width":139,"height":24,"x":1128,"y":516},{"id":"32","hint":"ALU","confidence":0,"width":52,"height":25,"x":913,"y":520},{"id":"20","hint":"RegWrite","confidence":0,"width":118,"height":28,"x":642,"y":681},{"id":"15","hint":"4","confidence":0,"width":25,"height":25,"x":278,"y":237}] \ No newline at end of file diff --git a/ocr/braille-diagram-tools/done/example-of-microprocessor/diagram.png b/ocr/braille-diagram-tools/done/example-of-microprocessor/diagram.png new file mode 100644 index 0000000..6545ce7 Binary files /dev/null and b/ocr/braille-diagram-tools/done/example-of-microprocessor/diagram.png differ diff --git a/ocr/braille-diagram-tools/done/example-of-microprocessor/out.png b/ocr/braille-diagram-tools/done/example-of-microprocessor/out.png new file mode 100644 index 0000000..a99ed57 Binary files /dev/null and b/ocr/braille-diagram-tools/done/example-of-microprocessor/out.png differ diff --git a/ocr/braille-diagram-tools/done/example-of-microprocessor/ready.png b/ocr/braille-diagram-tools/done/example-of-microprocessor/ready.png new file mode 100644 index 0000000..38056ef Binary files /dev/null and b/ocr/braille-diagram-tools/done/example-of-microprocessor/ready.png differ diff --git a/ocr/braille-diagram-tools/done/example-of-microprocessor/whiteout.json b/ocr/braille-diagram-tools/done/example-of-microprocessor/whiteout.json new file mode 100644 index 0000000..b7c6f27 --- /dev/null +++ b/ocr/braille-diagram-tools/done/example-of-microprocessor/whiteout.json @@ -0,0 +1 @@ +[{"id":"15","hint":"","confidence":0,"width":25,"height":25,"x":278,"y":237},{"id":"0","hint":"branch","confidence":0,"width":78,"height":19,"x":1015,"y":15},{"id":"1","hint":"ALU operation","confidence":0,"width":162,"height":25,"x":792,"y":431},{"id":"2","hint":"add","confidence":0,"width":47,"height":23,"x":567,"y":317},{"id":"3","hint":"pc","confidence":0,"width":39,"height":42,"x":97,"y":557},{"id":"6","hint":"add","confidence":0,"width":47,"height":21,"x":362,"y":329},{"id":"12","hint":"MemRead","confidence":0,"width":125,"height":33,"x":1143,"y":735},{"id":"21","hint":"m","confidence":0,"width":25,"height":27,"x":385,"y":90},{"id":"22","hint":"m","confidence":0,"width":33,"height":28,"x":840,"y":589},{"id":"24","hint":"u","confidence":0,"width":25,"height":25,"x":385,"y":125},{"id":"26","hint":"x","confidence":0,"width":25,"height":25,"x":385,"y":155},{"id":"28","hint":"x","confidence":0,"width":30,"height":30,"x":840,"y":655},{"id":"27","hint":"u","confidence":0,"width":30,"height":30,"x":840,"y":620},{"id":"29","hint":"m","confidence":0,"width":30,"height":30,"x":844,"y":310},{"id":"30","hint":"u","confidence":0,"width":30,"height":30,"x":845,"y":340},{"id":"31","hint":"x","confidence":0,"width":30,"height":30,"x":845,"y":375},{"id":"33","hint":"0","confidence":0,"width":57,"height":25,"x":1000,"y":598},{"id":"4","hint":"Data","confidence":0,"width":56,"height":24,"x":522,"y":463},{"id":"11","hint":"Registers","confidence":0,"width":118,"height":28,"x":624,"y":564},{"id":"14","hint":"Register #","confidence":0,"width":120,"height":29,"x":519,"y":599},{"id":"5","hint":"Register #","confidence":0,"width":119,"height":28,"x":522,"y":532},{"id":"19","hint":"Register #","confidence":0,"width":119,"height":28,"x":522,"y":663},{"id":"20","hint":"RegWrite","confidence":0,"width":108,"height":28,"x":662,"y":671},{"id":"25","hint":"control","confidence":0,"width":134,"height":45,"x":527,"y":877},{"id":"13","hint":"Address","confidence":0,"width":98,"height":24,"x":1068,"y":560},{"id":"17","hint":"Data memory","confidence":0,"width":151,"height":76,"x":1094,"y":612},{"id":"23","hint":"Data","confidence":0,"width":56,"height":24,"x":1072,"y":718},{"id":"32","hint":"ALU","confidence":0,"width":52,"height":25,"x":933,"y":560},{"id":"9","hint":"Instruction","confidence":0,"width":120,"height":23,"x":312,"y":565},{"id":"8","hint":"Address","confidence":0,"width":98,"height":23,"x":192,"y":565},{"id":"16","hint":"Insturction","confidence":0,"width":135,"height":23,"x":199,"y":628},{"id":"18","hint":"memory","confidence":0,"width":104,"height":24,"x":215,"y":665},{"id":"7","hint":"MemWrite","confidence":0,"width":139,"height":24,"x":1128,"y":516}] \ No newline at end of file diff --git a/ocr/braille-diagram-tools/done/fa-4/FA-4.png b/ocr/braille-diagram-tools/done/fa-4/FA-4.png new file mode 100644 index 0000000..1c7acbb Binary files /dev/null and b/ocr/braille-diagram-tools/done/fa-4/FA-4.png differ diff --git a/ocr/braille-diagram-tools/done/fa-4/braille.json b/ocr/braille-diagram-tools/done/fa-4/braille.json new file mode 100644 index 0000000..898ca0d --- /dev/null +++ b/ocr/braille-diagram-tools/done/fa-4/braille.json @@ -0,0 +1 @@ +[{"id":"9","hint":"S3","confidence":0,"width":61,"height":60,"x":300,"y":517},{"id":"10","hint":"S2","confidence":0,"width":60,"height":59,"x":543,"y":517},{"id":"11","hint":"S1","confidence":0,"width":60,"height":59,"x":786,"y":517},{"id":"12","hint":"S0","confidence":0,"width":60,"height":60,"x":1029,"y":517},{"id":"6","hint":"FA","confidence":0,"width":133,"height":61,"x":244,"y":260},{"id":"4","hint":"FA","confidence":0,"width":112,"height":68,"x":491,"y":260},{"id":"7","hint":"FA","confidence":0,"width":124,"height":81,"x":737,"y":260},{"id":"13","hint":"FA","confidence":0,"width":89,"height":76,"x":991,"y":260},{"id":"14","hint":"B3","confidence":0,"width":66,"height":59,"x":321,"y":8},{"id":"0","hint":"A3","confidence":0,"width":66,"height":59,"x":255,"y":8},{"id":"1","hint":"A2","confidence":0,"width":66,"height":58,"x":498,"y":8},{"id":"15","hint":"B2","confidence":0,"width":66,"height":58,"x":564,"y":8},{"id":"2","hint":"A1","confidence":0,"width":66,"height":58,"x":741,"y":8},{"id":"16","hint":"B1","confidence":0,"width":66,"height":58,"x":807,"y":8},{"id":"8","hint":"C0","confidence":0,"width":77,"height":61,"x":1267,"y":270},{"id":"5","hint":"C4","confidence":0,"width":87,"height":60,"x":3,"y":268},{"id":"18","hint":"C3","confidence":0,"width":80,"height":42,"x":390,"y":225},{"id":"19","hint":"C3","confidence":0,"width":75,"height":45,"x":635,"y":225},{"id":"20","hint":"C1","confidence":0,"width":72,"height":45,"x":877,"y":225},{"id":"17","hint":"B0","confidence":0,"width":66,"height":59,"x":1050,"y":8},{"id":"3","hint":"A0","confidence":0,"width":66,"height":59,"x":984,"y":8}] \ No newline at end of file diff --git a/ocr/braille-diagram-tools/done/fa-4/out.png b/ocr/braille-diagram-tools/done/fa-4/out.png new file mode 100644 index 0000000..982d85b Binary files /dev/null and b/ocr/braille-diagram-tools/done/fa-4/out.png differ diff --git a/ocr/braille-diagram-tools/done/fa-4/ready.png b/ocr/braille-diagram-tools/done/fa-4/ready.png new file mode 100644 index 0000000..e9d60bc Binary files /dev/null and b/ocr/braille-diagram-tools/done/fa-4/ready.png differ diff --git a/ocr/braille-diagram-tools/done/fa-4/whiteout.json b/ocr/braille-diagram-tools/done/fa-4/whiteout.json new file mode 100644 index 0000000..88b8aab --- /dev/null +++ b/ocr/braille-diagram-tools/done/fa-4/whiteout.json @@ -0,0 +1 @@ +[{"id":"5","hint":"C4","confidence":0,"width":62,"height":60,"x":28,"y":268},{"id":"9","hint":"S3","confidence":0,"width":61,"height":60,"x":300,"y":517},{"id":"10","hint":"S2","confidence":0,"width":60,"height":59,"x":543,"y":517},{"id":"11","hint":"S1","confidence":0,"width":60,"height":59,"x":786,"y":517},{"id":"12","hint":"S0","confidence":0,"width":60,"height":60,"x":1029,"y":517},{"id":"6","hint":"FA","confidence":0,"width":133,"height":61,"x":244,"y":260},{"id":"14","hint":"","confidence":0,"width":66,"height":59,"x":321,"y":8},{"id":"1","hint":"AsB5","confidence":0,"width":66,"height":58,"x":498,"y":8},{"id":"15","hint":"","confidence":0,"width":66,"height":58,"x":564,"y":8},{"id":"2","hint":"A,B4","confidence":0,"width":66,"height":58,"x":741,"y":8},{"id":"16","hint":"","confidence":0,"width":66,"height":58,"x":807,"y":8},{"id":"3","hint":"AnBg","confidence":0,"width":66,"height":59,"x":984,"y":8},{"id":"17","hint":"","confidence":0,"width":66,"height":59,"x":1050,"y":8},{"id":"0","hint":"ALB4","confidence":0,"width":66,"height":59,"x":255,"y":8},{"id":"18","hint":"","confidence":0,"width":70,"height":67,"x":405,"y":200},{"id":"19","hint":"C3","confidence":0,"width":75,"height":70,"x":645,"y":200},{"id":"20","hint":"C1","confidence":0,"width":72,"height":70,"x":885,"y":200},{"id":"8","hint":"C0","confidence":0,"width":62,"height":61,"x":1282,"y":270},{"id":"4","hint":"FA","confidence":0,"width":112,"height":68,"x":491,"y":260},{"id":"7","hint":"FA","confidence":0,"width":124,"height":81,"x":737,"y":260},{"id":"13","hint":"FA","confidence":0,"width":89,"height":76,"x":991,"y":260}] \ No newline at end of file diff --git a/ocr/braille-diagram-tools/done/full-adder/out.json b/ocr/braille-diagram-tools/done/full-adder/out.json new file mode 100644 index 0000000..3f3f7f0 --- /dev/null +++ b/ocr/braille-diagram-tools/done/full-adder/out.json @@ -0,0 +1 @@ +[{"id":"0","hint":"Half Adder","confidence":0,"width":154,"height":24,"x":189,"y":38},{"id":"2","hint":"A","confidence":0,"width":21,"height":26,"x":28,"y":107},{"id":"1","hint":"B","confidence":0,"width":21,"height":26,"x":28,"y":133},{"id":"3","hint":"S (sum)","confidence":0,"width":122,"height":25,"x":437,"y":124},{"id":"5","hint":"C (carry out)","confidence":0,"width":230,"height":28,"x":436,"y":232}] \ No newline at end of file diff --git a/ocr/braille-diagram-tools/done/full-adder/out.png b/ocr/braille-diagram-tools/done/full-adder/out.png new file mode 100644 index 0000000..4469bdf Binary files /dev/null and b/ocr/braille-diagram-tools/done/full-adder/out.png differ diff --git a/ocr/braille-diagram-tools/done/full-adder/ready.png b/ocr/braille-diagram-tools/done/full-adder/ready.png new file mode 100644 index 0000000..764e8c7 Binary files /dev/null and b/ocr/braille-diagram-tools/done/full-adder/ready.png differ diff --git a/ocr/braille-diagram-tools/done/or-gate/OR.png b/ocr/braille-diagram-tools/done/or-gate/OR.png new file mode 100644 index 0000000..5b2b01f Binary files /dev/null and b/ocr/braille-diagram-tools/done/or-gate/OR.png differ diff --git a/ocr/braille-diagram-tools/done/or-gate/braille.json b/ocr/braille-diagram-tools/done/or-gate/braille.json new file mode 100644 index 0000000..46464c1 --- /dev/null +++ b/ocr/braille-diagram-tools/done/or-gate/braille.json @@ -0,0 +1 @@ +[{"id":"4","hint":"OR","confidence":0,"width":212,"height":118,"x":439,"y":477},{"id":"2","hint":"A+B","confidence":0,"width":319,"height":109,"x":996,"y":171},{"id":"0","hint":"A","confidence":0,"width":189,"height":93,"x":102,"y":83},{"id":"1","hint":"B","confidence":0,"width":194,"height":130,"x":100,"y":227}] \ No newline at end of file diff --git a/ocr/braille-diagram-tools/done/or-gate/out.png b/ocr/braille-diagram-tools/done/or-gate/out.png new file mode 100644 index 0000000..a0f2035 Binary files /dev/null and b/ocr/braille-diagram-tools/done/or-gate/out.png differ diff --git a/ocr/braille-diagram-tools/done/or-gate/ready.png b/ocr/braille-diagram-tools/done/or-gate/ready.png new file mode 100644 index 0000000..633e9a5 Binary files /dev/null and b/ocr/braille-diagram-tools/done/or-gate/ready.png differ diff --git a/ocr/braille-diagram-tools/done/or-gate/whiteout.json b/ocr/braille-diagram-tools/done/or-gate/whiteout.json new file mode 100644 index 0000000..46464c1 --- /dev/null +++ b/ocr/braille-diagram-tools/done/or-gate/whiteout.json @@ -0,0 +1 @@ +[{"id":"4","hint":"OR","confidence":0,"width":212,"height":118,"x":439,"y":477},{"id":"2","hint":"A+B","confidence":0,"width":319,"height":109,"x":996,"y":171},{"id":"0","hint":"A","confidence":0,"width":189,"height":93,"x":102,"y":83},{"id":"1","hint":"B","confidence":0,"width":194,"height":130,"x":100,"y":227}] \ No newline at end of file diff --git a/ocr/braille-diagram-tools/done/xor-gate/XOR.png b/ocr/braille-diagram-tools/done/xor-gate/XOR.png new file mode 100644 index 0000000..b545938 Binary files /dev/null and b/ocr/braille-diagram-tools/done/xor-gate/XOR.png differ diff --git a/ocr/braille-diagram-tools/done/xor-gate/braille.json b/ocr/braille-diagram-tools/done/xor-gate/braille.json new file mode 100644 index 0000000..b7aa47e --- /dev/null +++ b/ocr/braille-diagram-tools/done/xor-gate/braille.json @@ -0,0 +1 @@ +[{"id":"0","hint":"A\n","confidence":96,"width":89,"height":93,"x":171,"y":46},{"id":"2","hint":"XOR\n","confidence":77,"width":310,"height":118,"x":440,"y":435},{"id":"1","hint":"B","confidence":0,"width":162,"height":116,"x":89,"y":185},{"id":"3","hint":"A$=[\"6B","confidence":0,"width":350,"height":125,"x":1025,"y":125}] \ No newline at end of file diff --git a/ocr/braille-diagram-tools/done/xor-gate/out.png b/ocr/braille-diagram-tools/done/xor-gate/out.png new file mode 100644 index 0000000..127a086 Binary files /dev/null and b/ocr/braille-diagram-tools/done/xor-gate/out.png differ diff --git a/ocr/braille-diagram-tools/done/xor-gate/ready.png b/ocr/braille-diagram-tools/done/xor-gate/ready.png new file mode 100644 index 0000000..1fac97e Binary files /dev/null and b/ocr/braille-diagram-tools/done/xor-gate/ready.png differ diff --git a/ocr/braille-diagram-tools/done/xor-gate/whiteout.json b/ocr/braille-diagram-tools/done/xor-gate/whiteout.json new file mode 100644 index 0000000..cd9bf36 --- /dev/null +++ b/ocr/braille-diagram-tools/done/xor-gate/whiteout.json @@ -0,0 +1 @@ +[{"id":"0","hint":"A\n","confidence":96,"width":89,"height":93,"x":171,"y":46},{"id":"2","hint":"XOR\n","confidence":77,"width":310,"height":118,"x":440,"y":435},{"id":"1","hint":"‘B‘::>D—>A@B\n","confidence":0,"width":162,"height":116,"x":89,"y":185},{"id":"3","hint":"","confidence":0,"width":350,"height":125,"x":1025,"y":125}] \ No newline at end of file diff --git a/ocr/braille-diagram-tools/easy.sh b/ocr/braille-diagram-tools/easy.sh new file mode 100755 index 0000000..7d1f6d4 --- /dev/null +++ b/ocr/braille-diagram-tools/easy.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +prefix="btt-" +cmd=$1 +extra=$2 + + +if [[ "$cmd" == "edit-json" ]]; then +# TODO: find easier way + json=$(test -z "$extra" && echo "./out.json" || echo "$extra") + cargo run --bin "${prefix}edit-tools" "$json" +elif [[ "$cmd" == "whiteout" ]]; then + json=$(test -z "$extra" && echo "./out.json" || echo "$extra") + cargo run --bin "${prefix}whiteout-labels" ./diagram.png "$json" +elif [[ "$cmd" == "gen-ocr" ]]; then + cargo run --bin "${prefix}get-ocr" ./diagram.png > out.json +elif [[ "$cmd" == "show-labels" ]]; then + cargo run --bin "${prefix}label-ocr" ./diagram.png ./out.json +elif [[ "$cmd" == "add-braille" ]]; then + json=$(test -z "$extra" && echo "./out.json" || echo "$extra") + cargo run --bin "${prefix}add-braille" ./out.png "$json" $3 +fi diff --git a/ocr/braille-diagram-tools/fonts/DejaVuSans.ttf b/ocr/braille-diagram-tools/fonts/DejaVuSans.ttf new file mode 100644 index 0000000..494bffe Binary files /dev/null and b/ocr/braille-diagram-tools/fonts/DejaVuSans.ttf differ diff --git a/ocr/braille-diagram-tools/fonts/DejaVuSansMono.ttf b/ocr/braille-diagram-tools/fonts/DejaVuSansMono.ttf new file mode 100644 index 0000000..d017d72 Binary files /dev/null and b/ocr/braille-diagram-tools/fonts/DejaVuSansMono.ttf differ diff --git a/ocr/braille-diagram-tools/fonts/UBraille.ttf b/ocr/braille-diagram-tools/fonts/UBraille.ttf new file mode 100644 index 0000000..18a9f12 Binary files /dev/null and b/ocr/braille-diagram-tools/fonts/UBraille.ttf differ diff --git a/ocr/braille-diagram-tools/fonts/dejavu-font-license.txt b/ocr/braille-diagram-tools/fonts/dejavu-font-license.txt new file mode 100644 index 0000000..cdf662f --- /dev/null +++ b/ocr/braille-diagram-tools/fonts/dejavu-font-license.txt @@ -0,0 +1,99 @@ +DejaVu Fonts License + +Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. +Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below) + +Bitstream Vera Fonts Copyright +——————————————— + +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is +a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of the fonts accompanying this license (“Fonts”) and associated +documentation files (the “Font Software”), to reproduce and distribute the +Font Software, including without limitation the rights to use, copy, merge, +publish, distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to the +following conditions: + +The above copyright and trademark notices and this permission notice shall +be included in all copies of one or more of the Font Software typefaces. + +The Font Software may be modified, altered, or added to, and in particular +the designs of glyphs or characters in the Fonts may be modified and +additional glyphs or characters may be added to the Fonts, only if the fonts +are renamed to names not containing either the words “Bitstream” or the word +“Vera”. + +This License becomes null and void to the extent applicable to Fonts or Font +Software that has been modified and is distributed under the “Bitstream +Vera” names. + +The Font Software may be sold as part of a larger software package but no +copy of one or more of the Font Software typefaces may be sold by itself. + +THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, +TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME +FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING +ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE +FONT SOFTWARE. + +Except as contained in this notice, the names of Gnome, the Gnome +Foundation, and Bitstream Inc., shall not be used in advertising or +otherwise to promote the sale, use or other dealings in this Font Software +without prior written authorization from the Gnome Foundation or Bitstream +Inc., respectively. For further information, contact: fonts at gnome dot +org. + +Arev Fonts Copyright +——————————————— + +Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the fonts accompanying this license (“Fonts”) and +associated documentation files (the “Font Software”), to reproduce +and distribute the modifications to the Bitstream Vera Font Software, +including without limitation the rights to use, copy, merge, publish, +distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to +the following conditions: + +The above copyright and trademark notices and this permission notice +shall be included in all copies of one or more of the Font Software +typefaces. + +The Font Software may be modified, altered, or added to, and in +particular the designs of glyphs or characters in the Fonts may be +modified and additional glyphs or characters may be added to the +Fonts, only if the fonts are renamed to names not containing either +the words “Tavmjong Bah” or the word “Arev”. + +This License becomes null and void to the extent applicable to Fonts +or Font Software that has been modified and is distributed under the +“Tavmjong Bah Arev” names. + +The Font Software may be sold as part of a larger software package but +no copy of one or more of the Font Software typefaces may be sold by +itself. + +THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL +TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +Except as contained in this notice, the name of Tavmjong Bah shall not +be used in advertising or otherwise to promote the sale, use or other +dealings in this Font Software without prior written authorization +from Tavmjong Bah. For further information, contact: tavmjong @ free +. fr. diff --git a/ocr/braille-diagram-tools/src/bin/btt-add-braille.rs b/ocr/braille-diagram-tools/src/bin/btt-add-braille.rs new file mode 100644 index 0000000..9162de0 --- /dev/null +++ b/ocr/braille-diagram-tools/src/bin/btt-add-braille.rs @@ -0,0 +1,51 @@ +use std::fs; +use ocr_json_common::TextBox; +use image::{Rgba}; +use imageproc::drawing::{ + draw_text_mut, +}; +use std::env; +use std::path::Path; +use rusttype::{Font, Scale}; +use louis::Louis; +use louis::modes::DOTS_UNICODE; + +fn main() { + let img_file_name = if env::args().count() >= 2 { + env::args().nth(1).unwrap() + } else { + panic!("Please enter a target file path for image") + }; + let json_file_name = if env::args().count() >= 3 { + env::args().nth(2).unwrap() + } else{ + panic!("Please enter a target file path for json") + }; + let font_size_str = if env::args().count() >= 4 { + env::args().nth(3).unwrap() + } else { + "20.0".to_string() + }; + let font_size = font_size_str.parse().unwrap(); + let json = fs::read_to_string(json_file_name).expect("There was an error reading the file."); + let ocr_rects: Vec = serde_json::from_str(&json).unwrap(); + let image_path = Path::new(&img_file_name); + let black = Rgba([0u8, 0u8, 0u8, 255u8]); + + let font_data: &[u8] = include_bytes!("../../fonts/UBraille.ttf"); + let font: Font<'static> = Font::try_from_bytes(font_data).expect("Error loading font."); + + let mut img = image::open(image_path).unwrap(); + + let brl = Louis::new().unwrap(); + + // run OCR on each word bounding box + for rect in &ocr_rects { + let text = rect.hint.clone(); + let brl_text = brl.translate_simple("en_US.tbl", &text, false, DOTS_UNICODE); + println!("[{}]: {}", rect.id, brl_text); + draw_text_mut(&mut img, black, rect.x.try_into().unwrap(), rect.y.try_into().unwrap(), Scale::uniform(font_size), &font, &brl_text); + } + + img.save("out.png").unwrap(); +} diff --git a/ocr/braille-diagram-tools/src/bin/btt-edit-tools.rs b/ocr/braille-diagram-tools/src/bin/btt-edit-tools.rs new file mode 100644 index 0000000..3ce69e8 --- /dev/null +++ b/ocr/braille-diagram-tools/src/bin/btt-edit-tools.rs @@ -0,0 +1,473 @@ +use ocr_json_common::TextBox; +use serde_json; +use std::{ + env, + cmp::min, + process::Command, + io::Write, + fs::OpenOptions, + fs, +}; +use text_io::read; + +// TODO: make more extensible +fn save_json(json: String, fname: &String) { + let mut file = OpenOptions::new().write(true).truncate(true).create(true).open(fname).expect("Unable to open file"); + file.write_all(json.as_bytes()).expect("unable to write to file"); +} + +// TODO: make more exensible!!! +fn reload_json(fname: &String) { + Command::new("cargo") + .arg("run") + .arg("--bin") + .arg("btt-label-ocr") + .arg("./diagram.png") + .arg(fname) + .output() + .expect("Failed to execute command"); +} + +fn new_id(ids: &Vec) -> String { + let mut new_id = 0; + let mut new_sid = format!("{}", new_id); + while ids.contains(&new_sid) { + new_sid = format!("{}", new_id); + new_id+=1; + } + new_sid +} + +fn rem_rect(boxes: &mut Vec, id: String) { + boxes.retain(|b| b.id != id); +} + +fn new_rect(boxes: &mut Vec, id: String, x: String, y: String, w: String, h: String) { + // TODO: unsafe + boxes.push(TextBox { + id, + x: x.parse().unwrap(), + y: y.parse().unwrap(), + width: w.parse().unwrap(), + height: h.parse().unwrap(), + hint: String::new(), + confidence: 0 + }); +} + +fn set_text(boxes: &mut Vec, xid: String, new_text: String) { + // TODO: unsafe + let bx = boxes.iter().find(|b| b.id == xid).unwrap().clone(); + boxes.retain(|b| b.id != xid); + boxes.push(TextBox{ + id: bx.id, + confidence: 0, + hint: new_text.clone(), + x: bx.x, + y: bx.y, + width: bx.width, + height: bx.height, + }); +} + +fn merge(boxes: &mut Vec, xid: String, yid: String) { + // TODO: unsafe + let bx = boxes.iter().find(|b| b.id == xid).unwrap(); + // TODO: unsafe + let by = boxes.iter().find(|b| b.id == yid).unwrap(); + let y = min(bx.y, by.y); + let x = min(bx.x, by.x); + let w = (bx.x - by.x).abs() + (if x == bx.x {by.width as i32} else {bx.width as i32}); + let h = (bx.y - by.y).abs() + (if y == by.y {by.height as i32} else {bx.height as i32}); + let text = format!("{} {}", bx.hint, by.hint); + let confi = 0; + let id = bx.id.clone(); + boxes.retain(|b| b.id != xid && b.id != yid); + boxes.push(TextBox { + id, + confidence: confi, + hint: text, + x, + y, + width: w as u32, + height: h as u32, + }); +} + +fn vsplit(boxes: &mut Vec, sid: String) { + // TODO: unsafe + let bx = boxes.iter().find(|b| b.id == sid).unwrap(); + + let w = bx.width; + let x = bx.x; + let h = bx.height/2; + let y1 = bx.y; + let y2 = bx.y + (bx.height as i32)/2; + let hint = bx.hint.clone(); + let mut tsplit = hint.split("\n"); // tesseract likes to use newlines for some reason... use to our advantage + let t1 = tsplit.next().unwrap_or(""); + let t2 = tsplit.next().unwrap_or(""); + let id1 = bx.id.clone(); + let ids: Vec = boxes.iter().map(|b| b.id.clone()).collect(); + let id2 = new_id(&ids); + boxes.retain(|b| b.id != sid); + boxes.push(TextBox { + x, + y: y1, + hint: t1.to_string().clone(), + confidence: 0, + id: id1, + width: w, + height: h, + }); + boxes.push(TextBox { + x, + y: y2, + hint: t2.to_string().clone(), + confidence: 0, + id: id2, + width: w, + height: h, + }); +} + +fn hsplit(boxes: &mut Vec, sid: String) { + // TODO: unsafe + let bx = boxes.iter().find(|b| b.id == sid).unwrap(); + + let w = bx.width/2; + let y = bx.y; + let h = bx.height; + let x1 = bx.x; + let x2 = bx.x + (bx.width as i32)/2; + let hint = bx.hint.clone(); + let mut tsplit = hint.split("\n"); // tesseract likes to use newlines for some reason... use to our advantage + let t1 = tsplit.next().unwrap_or(""); + let t2 = tsplit.next().unwrap_or(""); + let id1 = bx.id.clone(); + let ids: Vec = boxes.iter().map(|b| b.id.clone()).collect(); + let id2 = new_id(&ids); + boxes.retain(|b| b.id != sid); + boxes.push(TextBox { + x: x1, + y, + hint: t1.to_string().clone(), + confidence: 0, + id: id1, + width: w, + height: h, + }); + boxes.push(TextBox { + x: x2, + y, + hint: t2.to_string().clone(), + confidence: 0, + id: id2, + width: w, + height: h, + }); +} + +fn triml(boxes: &mut Vec, sid: String, mw: i32) { + // TODO: unsafe + let bx = boxes.iter().find(|b| b.id == sid).unwrap().clone(); + boxes.retain(|b| b.id != sid); + boxes.push(TextBox{ + id: bx.id, + hint: bx.hint, + x: bx.x + mw, + width: bx.width - (mw as u32), + y: bx.y, + height: bx.height, + confidence: 0, + }); +} +fn trimr(boxes: &mut Vec, sid: String, mw: i32) { + // TODO: unsafe + let bx = boxes.iter().find(|b| b.id == sid).unwrap().clone(); + boxes.retain(|b| b.id != sid); + boxes.push(TextBox{ + id: bx.id, + hint: bx.hint, + x: bx.x, + width: bx.width - (mw as u32), + y: bx.y, + height: bx.height, + confidence: 0, + }); +} +fn trimt(boxes: &mut Vec, sid: String, mw: i32) { + // TODO: unsafe + let bx = boxes.iter().find(|b| b.id == sid).unwrap().clone(); + boxes.retain(|b| b.id != sid); + boxes.push(TextBox{ + id: bx.id, + hint: bx.hint, + x: bx.x, + width: bx.width, + y: bx.y + mw, + height: bx.height - (mw as u32), + confidence: 0, + }); +} +fn trimb(boxes: &mut Vec, sid: String, mw: i32) { + // TODO: unsafe + let bx = boxes.iter().find(|b| b.id == sid).unwrap().clone(); + boxes.retain(|b| b.id != sid); + boxes.push(TextBox{ + id: bx.id, + hint: bx.hint, + x: bx.x, + width: bx.width, + y: bx.y, + height: bx.height - (mw as u32), + confidence: 0, + }); +} + +fn movel(boxes: &mut Vec, sid: String, mw: i32) { + // TODO: unsafe + let bx = boxes.iter().find(|b| b.id == sid).unwrap().clone(); + boxes.retain(|b| b.id != sid); + boxes.push(TextBox{ + id: bx.id, + hint: bx.hint, + x: bx.x - mw, + width: bx.width, + y: bx.y, + height: bx.height, + confidence: 0, + }); +} +fn mover(boxes: &mut Vec, sid: String, mw: i32) { + // TODO: unsafe + let bx = boxes.iter().find(|b| b.id == sid).unwrap().clone(); + boxes.retain(|b| b.id != sid); + boxes.push(TextBox{ + id: bx.id, + hint: bx.hint, + x: bx.x + mw, + width: bx.width, + y: bx.y, + height: bx.height, + confidence: 0, + }); +} +fn moveu(boxes: &mut Vec, sid: String, mw: i32) { + // TODO: unsafe + let bx = boxes.iter().find(|b| b.id == sid).unwrap().clone(); + boxes.retain(|b| b.id != sid); + boxes.push(TextBox{ + id: bx.id, + hint: bx.hint, + x: bx.x, + width: bx.width, + y: bx.y - mw, + height: bx.height, + confidence: 0, + }); +} +fn moved(boxes: &mut Vec, sid: String, mw: i32) { + // TODO: unsafe + let bx = boxes.iter().find(|b| b.id == sid).unwrap().clone(); + boxes.retain(|b| b.id != sid); + boxes.push(TextBox{ + id: bx.id, + hint: bx.hint, + x: bx.x, + width: bx.width, + y: bx.y + mw, + height: bx.height, + confidence: 0, + }); +} + +fn paddl(boxes: &mut Vec, sid: String, mw: i32) { + // TODO: unsafe + let bx = boxes.iter().find(|b| b.id == sid).unwrap().clone(); + boxes.retain(|b| b.id != sid); + boxes.push(TextBox{ + id: bx.id, + hint: bx.hint, + x: bx.x - mw, + width: bx.width + (mw as u32), + y: bx.y, + height: bx.height, + confidence: 0, + }); +} +fn paddr(boxes: &mut Vec, sid: String, mw: i32) { + // TODO: unsafe + let bx = boxes.iter().find(|b| b.id == sid).unwrap().clone(); + boxes.retain(|b| b.id != sid); + boxes.push(TextBox{ + id: bx.id, + hint: bx.hint, + x: bx.x, + width: bx.width + (mw as u32), + y: bx.y, + height: bx.height, + confidence: 0, + }); +} +fn paddt(boxes: &mut Vec, sid: String, mw: i32) { + // TODO: unsafe + let bx = boxes.iter().find(|b| b.id == sid).unwrap().clone(); + boxes.retain(|b| b.id != sid); + boxes.push(TextBox{ + id: bx.id, + hint: bx.hint, + x: bx.x, + width: bx.width, + y: bx.y - mw, + height: bx.height + (mw as u32), + confidence: 0, + }); +} +fn paddb(boxes: &mut Vec, sid: String, mw: i32) { + // TODO: unsafe + let bx = boxes.iter().find(|b| b.id == sid).unwrap().clone(); + boxes.retain(|b| b.id != sid); + boxes.push(TextBox{ + id: bx.id, + hint: bx.hint, + x: bx.x, + width: bx.width, + y: bx.y, + height: bx.height + (mw as u32), + confidence: 0, + }); +} + +fn main() { + let json_fname = if env::args().count() == 2 { + env::args().nth(1).unwrap() + } else { + panic!("Please enter a file path"); + }; + let json_str = fs::read_to_string(json_fname.clone()).expect("There was an error reading the provided file."); + let mut boxes: Vec = serde_json::from_str(&json_str).unwrap(); + let mut line: String = String::new(); + println!("Type 'exit' to quit!"); + while line != "exit" { + line = read!("{}\n"); + let mut split = line.split("|"); + let command = split.next(); + if command == Some("merge") { + // TODO: not safe + let one_id = split.next().unwrap(); + let two_id = split.next().unwrap(); + merge(&mut boxes, one_id.to_string(), two_id.to_string()); + } else if command == Some("vsplit") { + // TODO: not safe + let id = split.next().unwrap(); + vsplit(&mut boxes, id.to_string()); + } else if command == Some("hsplit") { + // TODO: not safe + let id = split.next().unwrap(); + hsplit(&mut boxes, id.to_string()); + } else if command == Some("triml") { + // TODO: not safe + let id = split.next().unwrap(); + let px = split.next().unwrap(); + triml(&mut boxes, id.to_string(), px.parse().unwrap()); + } else if command == Some("trimr") { + // TODO: not safe + let id = split.next().unwrap(); + let px = split.next().unwrap(); + trimr(&mut boxes, id.to_string(), px.parse().unwrap()); + } else if command == Some("trimt") { + // TODO: not safe + let id = split.next().unwrap(); + let px = split.next().unwrap(); + trimt(&mut boxes, id.to_string(), px.parse().unwrap()); + } else if command == Some("trimb") { + // TODO: not safe + let id = split.next().unwrap(); + let px = split.next().unwrap(); + trimb(&mut boxes, id.to_string(), px.parse().unwrap()); + } else if command == Some("text") { + // TODO: not safe + let id = split.next().unwrap(); + let new_text = split.next().unwrap(); + set_text(&mut boxes, id.to_string(), new_text.to_string()); + } else if command == Some("moveu") { + // TODO: not safe + let id = split.next().unwrap().to_string(); + let diff = split.next().unwrap().parse().unwrap(); + moveu(&mut boxes, id, diff); + } else if command == Some("moved") { + // TODO: not safe + let id = split.next().unwrap().to_string(); + let diff = split.next().unwrap().parse().unwrap(); + moved(&mut boxes, id, diff); + } else if command == Some("mover") { + // TODO: not safe + let id = split.next().unwrap().to_string(); + let diff = split.next().unwrap().parse().unwrap(); + mover(&mut boxes, id, diff); + } else if command == Some("movel") { + // TODO: not safe + let id = split.next().unwrap().to_string(); + let diff = split.next().unwrap().parse().unwrap(); + movel(&mut boxes, id, diff); + } else if command == Some("paddl") { + // TODO: not safe + let id = split.next().unwrap().to_string(); + let diff = split.next().unwrap().parse().unwrap(); + paddl(&mut boxes, id, diff); + } else if command == Some("paddr") { + // TODO: not safe + let id = split.next().unwrap().to_string(); + let diff = split.next().unwrap().parse().unwrap(); + paddr(&mut boxes, id, diff); + } else if command == Some("paddt") { + // TODO: not safe + let id = split.next().unwrap().to_string(); + let diff = split.next().unwrap().parse().unwrap(); + paddt(&mut boxes, id, diff); + } else if command == Some("paddb") { + // TODO: not safe + let id = split.next().unwrap().to_string(); + let diff = split.next().unwrap().parse().unwrap(); + paddb(&mut boxes, id, diff); + } else if command == Some("add") { + // TODO: not safe + let ids: Vec = boxes.iter().map(|b| b.id.clone()).collect(); + let id = new_id(&ids); + let x = split.next().unwrap(); + let y = split.next().unwrap(); + let w = split.next().unwrap(); + let h = split.next().unwrap(); + new_rect(&mut boxes, + id.to_string(), + x.to_string(), + y.to_string(), + w.to_string(), + h.to_string()); + } else if command == Some("save") { + // TODO: unsafe + let fname = split.next().unwrap(); + let json_out = serde_json::to_string(&boxes).unwrap(); + save_json(json_out, &fname.to_string()); + println!("Saved as {}", fname); + } else if command == Some("show") { + // TODO: VERY unsafe + let id = split.next().unwrap(); + let bx = boxes.iter().find(|b| b.id == id).unwrap(); + let json = serde_json::to_string(bx).unwrap(); + println!("JSON: {}", json); + } else if command == Some("rem") { + // TODO: unsafe + let id = split.next().unwrap(); + rem_rect(&mut boxes, id.to_string()); + } else if command == Some("exit") { + continue; + } else { + println!("Invalid command."); + } + let json_out = serde_json::to_string(&boxes).unwrap(); + save_json(json_out, &json_fname); + reload_json(&json_fname); + } +} diff --git a/ocr/braille-diagram-tools/src/bin/btt-get-ocr.rs b/ocr/braille-diagram-tools/src/bin/btt-get-ocr.rs new file mode 100644 index 0000000..eab872f --- /dev/null +++ b/ocr/braille-diagram-tools/src/bin/btt-get-ocr.rs @@ -0,0 +1,53 @@ +extern crate leptess; + +use ocr_json_common::TextBox; +use leptess::{leptonica, tesseract}; +use std::env; +use std::path::Path; + +/* TODO: preprox here */ + +fn main() { + let mut ocr_rects = Vec::new(); + let file_name = if env::args().count() == 2 { + env::args().nth(1).unwrap() + } else { + panic!("Please enter a target file path") + }; + let image_path = Path::new(&file_name); + let mut api = tesseract::TessApi::new(Some("/usr/share/tessdata/"), "eng").unwrap(); + let pix = leptonica::pix_read(image_path).unwrap(); + api.set_image(&pix); + + // detect bounding boxes for words + let boxes = api + .get_component_images(leptess::capi::TessPageIteratorLevel_RIL_WORD, true) + .unwrap(); + + let mut boxid = 0; + // run OCR on each word bounding box + for b in &boxes { + api.set_rectangle(&b); + let text = api.get_utf8_text().unwrap(); + let confi = api.mean_text_conf(); + let bref = b.as_ref(); + /* + println!( + "[X: {}, Y: {}, W: {}, H: {}]: confidence: {}, text: {}", + bref.x, bref.y, bref.w, bref.h, confi, text + );*/ + ocr_rects.push(TextBox { + id: format!("{}", boxid), + hint: text, + confidence: confi as u32, + x: bref.x, + y: bref.y, + height: bref.h as u32, + width: bref.w as u32, + }); + boxid += 1; + } + + let json = serde_json::to_string(&ocr_rects).unwrap(); + println!("{}", json); +} diff --git a/ocr/braille-diagram-tools/src/bin/btt-label-ocr.rs b/ocr/braille-diagram-tools/src/bin/btt-label-ocr.rs new file mode 100644 index 0000000..28dbe29 --- /dev/null +++ b/ocr/braille-diagram-tools/src/bin/btt-label-ocr.rs @@ -0,0 +1,45 @@ +use std::fs; +use ocr_json_common::TextBox; +use image::{Rgba}; +use imageproc::drawing::{ + draw_hollow_rect_mut, + draw_text_mut, +}; +use imageproc::rect::Rect; +use std::env; +use std::path::Path; +use rusttype::{Font, Scale}; + +fn main() { + let img_file_name = if env::args().count() >= 2 { + env::args().nth(1).unwrap() + } else { + panic!("Please enter a target file path for image") + }; + let json_file_name = if env::args().count() >= 3 { + env::args().nth(2).unwrap() + } else{ + panic!("Please enter a target file path for json") + }; + let json = fs::read_to_string(json_file_name).expect("There was an error reading the file."); + let ocr_rects: Vec = serde_json::from_str(&json).unwrap(); + let image_path = Path::new(&img_file_name); + let red = Rgba([255u8, 0u8, 0u8, 255u8]); + + let font_data: &[u8] = include_bytes!("../../fonts/DejaVuSansMono.ttf"); + let font: Font<'static> = Font::try_from_bytes(font_data).expect("Error loading font."); + + let mut img = image::open(image_path).unwrap(); + + // run OCR on each word bounding box + for rect in &ocr_rects { + draw_hollow_rect_mut(&mut img, Rect::at(rect.x, rect.y).of_size(rect.width, rect.height), red); + let y: u32 = rect.y as u32; + let x: u32 = (rect.x-25) as u32; + let text = String::from(rect.id.clone()); + //let text = "⠨⠙⠕⠃⠗⠕⠙⠕⠱⠇⠊"; + draw_text_mut(&mut img, red, x, y, Scale::uniform(20.0), &font, &text); + } + + img.save("out.png").unwrap(); +} diff --git a/ocr/braille-diagram-tools/src/bin/btt-whiteout-labels.rs b/ocr/braille-diagram-tools/src/bin/btt-whiteout-labels.rs new file mode 100644 index 0000000..19a480f --- /dev/null +++ b/ocr/braille-diagram-tools/src/bin/btt-whiteout-labels.rs @@ -0,0 +1,35 @@ +use std::fs; +use ocr_json_common::TextBox; +use image::{Rgba}; +use imageproc::drawing::{ + draw_filled_rect_mut +}; +use imageproc::rect::Rect; +use std::env; +use std::path::Path; + +fn main() { + let img_file_name = if env::args().count() >= 2 { + env::args().nth(1).unwrap() + } else { + panic!("Please enter a target file path for image") + }; + let json_file_name = if env::args().count() >= 3 { + env::args().nth(2).unwrap() + } else{ + panic!("Please enter a target file path for json") + }; + let json = fs::read_to_string(json_file_name).expect("There was an error reading the file."); + let ocr_rects: Vec = serde_json::from_str(&json).unwrap(); + let image_path = Path::new(&img_file_name); + let white = Rgba([255u8, 255u8, 255u8, 255u8]); + + let mut img = image::open(image_path).unwrap(); + + // run OCR on each word bounding box + for rect in &ocr_rects { + draw_filled_rect_mut(&mut img, Rect::at(rect.x, rect.y).of_size(rect.width, rect.height), white); + } + + img.save("out.png").unwrap(); +} diff --git a/ocr/braille-diagram-tools/src/main.rs b/ocr/braille-diagram-tools/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/ocr/braille-diagram-tools/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/ocr/ocr-json-common b/ocr/ocr-json-common new file mode 160000 index 0000000..954e7a2 --- /dev/null +++ b/ocr/ocr-json-common @@ -0,0 +1 @@ +Subproject commit 954e7a20b3fbe2bc613d1ec072aa8e4704f2c691