├── .gitignore ├── .gitmodules ├── LICENSE ├── Makefile ├── README.md ├── components ├── c │ └── wasmcv │ │ ├── README.md │ │ ├── imports.c │ │ ├── imports.h │ │ └── imports_component_type.o └── rust │ └── wasmcv │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── README.md │ └── src │ └── imports.rs ├── docs ├── imports.html └── imports.md ├── examples ├── basic │ ├── README.md │ ├── go.mod │ ├── go.sum │ ├── main.go │ └── modules │ │ ├── processor.wasm │ │ └── processor │ │ ├── go.mod │ │ ├── go.sum │ │ └── processor.go ├── multi │ ├── README.md │ ├── go.mod │ ├── go.sum │ ├── main.go │ └── modules │ │ ├── processc.wasm │ │ ├── processc │ │ ├── README.md │ │ ├── build.sh │ │ ├── itoa.c │ │ └── process.c │ │ ├── processor.wasm │ │ ├── processor │ │ ├── README.md │ │ ├── go.mod │ │ ├── go.sum │ │ └── processor.go │ │ ├── processrs.wasm │ │ └── processrs │ │ ├── .cargo │ │ └── config.toml │ │ ├── .gitignore │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ ├── README.md │ │ └── src │ │ └── lib.rs └── wasmcam │ ├── README.md │ ├── frame.go │ ├── go.mod │ ├── go.sum │ ├── main.go │ └── modules │ ├── processor.wasm │ └── processor │ ├── go.mod │ ├── go.sum │ └── processor.go ├── images └── wasmcam.png └── wit ├── core.wit ├── dnn.wit ├── features2d.wit ├── mat.wit ├── objdetect.wit ├── request.wit ├── types.wit └── world.wit /.gitignore: -------------------------------------------------------------------------------- 1 | # Common files and folders 2 | .vscode/* 3 | 4 | # OS generated files 5 | .DS_Store 6 | .DS_Store? 7 | ._* 8 | .Spotlight-V100 9 | .Trashes 10 | ehthumbs.db 11 | Thumbs.db 12 | 13 | # Example build files 14 | examples/basic/basic 15 | examples/wasmcam/wasmcam 16 | examples/multi/multi 17 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "components/tinygo/wasm/cv"] 2 | path = components/tinygo/wasm/cv 3 | url = git@github.com:wasmvision/go-wasmcv.git 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2024-2025 The Hybrid Group and friends 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | generate-go: 3 | wit-bindgen-go generate --out ./components/tinygo -w imports -p wasmcv.org -cm go.bytecodealliance.org/cm ./wit 4 | 5 | generate-rust: 6 | wit-bindgen rust --out-dir ./components/rust/wasmcv/src -w imports ./wit/ 7 | 8 | generate-c: 9 | wit-bindgen c --out-dir ./components/c/wasmcv -w imports ./wit/ 10 | 11 | generate-docs: 12 | wit-bindgen markdown --out-dir ./docs -w imports ./wit/ 13 | 14 | generate: generate-go generate-rust generate-c 15 | 16 | # build basic example guest module 17 | basic: 18 | cd examples/basic/modules/processor; tinygo build -o ../processor.wasm -target=wasm-unknown . 19 | 20 | # build multi example guest modules 21 | multi: 22 | cd examples/multi/modules/processc; ./build.sh 23 | cd examples/multi/modules/processor; tinygo build -o ../processor.wasm -target=wasm-unknown . 24 | cd examples/multi/modules/processrs; cargo build --target wasm32-unknown-unknown --release; \ 25 | cp ./target/wasm32-unknown-unknown/release/processrs.wasm ../ 26 | 27 | # build wasmcam example guest module 28 | wasmcam: 29 | cd examples/wasmcam/modules/processor; tinygo build -o ../processor.wasm -target=wasm-unknown . 30 | 31 | examples: basic multi wasmcam 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wasmCV 2 | 3 | wasmCV provides WebAssembly guest interface bindings for computer vision applications based on [OpenCV](https://github.com/opencv/opencv). 4 | 5 | It includes [WIT](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md) files defining the interface to be used between a WebAssembly host application and a WASM guest module intended to process OpenCV `Mat` image frames. 6 | 7 | These interface definitions are then used to generate WASM bindings for TinyGo, Rust, and C. Those bindings can then be used in a WASM guest module to call OpenCV functions implemented by the host to obtain information or perform operations on OpenCV image frames. 8 | 9 | ```mermaid 10 | flowchart LR 11 | subgraph host 12 | OpenCV 13 | Runtime[WASM Runtime]<-->OpenCV 14 | end 15 | subgraph guest 16 | Runtime<--wasmCV-->processor-go.wasm 17 | Runtime<--wasmCV-->processor-rust.wasm 18 | Runtime<--wasmCV-->processor-c.wasm 19 | processor-go.wasm 20 | processor-rust.wasm 21 | processor-c.wasm 22 | end 23 | ``` 24 | 25 | ## Example wasmCV modules 26 | 27 | ### TinyGo 28 | 29 | This TinyGo module exports a `process()` function to the WASM host application, which passes in the wasmCV image `Mat` to be processed. It then calls functions on that `Mat` which are handled by the host application by calling OpenCV to actually perform the operations. 30 | 31 | ```go 32 | package main 33 | 34 | import ( 35 | "github.com/hybridgroup/mechanoid/convert" 36 | "go.bytecodealliance.org/cm" 37 | "wasmcv.org/wasm/cv/mat" 38 | ) 39 | 40 | //go:wasmimport hosted println 41 | func println(ptr *byte, size uint32) 42 | 43 | //export process 44 | func process(image mat.Mat) mat.Mat { 45 | println(cm.LowerString("Cols: " + 46 | convert.IntToString(int(image.Cols())) + 47 | " Rows: " + 48 | convert.IntToString(int(image.Rows())) + 49 | " Type: " + 50 | convert.IntToString(int(image.Type())))) 51 | 52 | return image 53 | } 54 | ``` 55 | 56 | Install the `wasmcv` package into your Go package: 57 | 58 | ```shell 59 | go get wasmcv.org/wasm/cv 60 | ``` 61 | 62 | You can then compile this module using the TinyGo compiler. 63 | 64 | ```shell 65 | tinygo build -o processor.wasm -target=wasm-unknown processor.go 66 | ``` 67 | 68 | Note that the `wasm-unknown` target can be used with wasmCV to produce very lightweight guest modules. The example above compiles to around 31k, including debug information. 69 | 70 | ```shell 71 | -rwxrwxr-x 1 ron ron 31248 sep 11 11:00 processor.wasm 72 | ``` 73 | 74 | See the [basic example application here](./examples/basic) to give it a try. 75 | 76 | ### Rust 77 | 78 | This Rust module does the same thing as the TinyGo wasm module example. It exports a `process()` function to the WASM host application, which then passes in the wasmCV image `Mat` to be processed. The module then calls functions on that `Mat` which are handled by the host application by calling OpenCV to actually perform the operations. 79 | 80 | ```rust 81 | #![no_std] 82 | 83 | extern crate core; 84 | extern crate alloc; 85 | 86 | use alloc::string::String; 87 | use alloc::string::ToString; 88 | use wasmcv::wasm::cv; 89 | 90 | #[no_mangle] 91 | pub extern fn process(mat: cv::mat::Mat) -> cv::mat::Mat { 92 | println(&["Cols: ", &mat.cols().to_string(), " Rows: ", &mat.rows().to_string(), " Size: ", &mat.size().len().to_string()].concat()); 93 | 94 | return mat; 95 | } 96 | 97 | /// Print a message to the host [`_println`]. 98 | fn println(message: &String) { 99 | unsafe { 100 | let (ptr, len) = string_to_ptr(message); 101 | _println(ptr, len); 102 | } 103 | } 104 | 105 | #[link(wasm_import_module = "hosted")] 106 | extern "C" { 107 | #[link_name = "println"] 108 | fn _println(ptr: u32, size: u32); 109 | } 110 | 111 | unsafe fn string_to_ptr(s: &String) -> (u32, u32) { 112 | return (s.as_ptr() as u32, s.len() as u32); 113 | } 114 | 115 | #[no_mangle] 116 | pub extern fn malloc(size: usize) -> *mut u8 { 117 | let layout = core::alloc::Layout::from_size_align(size, 1).unwrap(); 118 | unsafe { alloc::alloc::alloc(layout) } 119 | } 120 | ``` 121 | 122 | Install the `wasmcv` crate into your Rust project: 123 | 124 | ```shell 125 | cargo add wasmcv 126 | ``` 127 | 128 | You can then compile this module using the Rust compiler. 129 | 130 | ```shell 131 | cargo build --target wasm32-unknown-unknown --release 132 | ``` 133 | 134 | The `wasm32-unknown-unknown` target can be used with wasmCV to produce very lightweight guest modules when combined with `no_std`. The example above compiles to around 14k, including debug information. 135 | 136 | ```shell 137 | -rwxrwxr-x 1 ron ron 14488 sep 12 14:23 processrs.wasm 138 | ``` 139 | 140 | See the [multi example application here](./examples/multi) to try wasmCV with Rust. 141 | 142 | ### C 143 | 144 | This C module does the same thing as the TinyGo and Rust wasm module examples. It exports a `process()` function to the WASM host application, which then passes in the wasmCV image `Mat` to be processed. The module then calls functions on that `Mat` which are handled by the host application by calling OpenCV to actually perform the operations. 145 | 146 | ```c 147 | #include 148 | #include "../../../../components/c/wasmcv/imports.h" 149 | 150 | extern int itoa(int value, char *sp, int radix); 151 | 152 | __attribute__((import_module("hosted"), import_name("println"))) void println(int32_t str, int32_t len); 153 | 154 | wasm_cv_mat_borrow_mat_t process(wasm_cv_mat_borrow_mat_t image) { 155 | int32_t cols, rows; 156 | cols = wasm_cv_mat_method_mat_cols(image); 157 | rows = wasm_cv_mat_method_mat_rows(image); 158 | 159 | char buf[20]; 160 | strcpy(buf, "Cols: "); 161 | itoa(cols, buf+6, 10); 162 | strcpy(buf+9, " Rows: "); 163 | itoa(rows, buf+16, 10); 164 | 165 | println((int32_t)buf, 20); 166 | 167 | return image; 168 | } 169 | ``` 170 | 171 | You can then compile this module using the `clang` compiler. 172 | 173 | ```shell 174 | /opt/wasi-sdk/bin/clang --target=wasm32-unknown-unknown -O3 \ 175 | --sysroot="/path/to/lib/wasi-libc/sysroot" \ 176 | -z stack-size=4096 -Wl,--initial-memory=65536 \ 177 | -o ../processc.wasm process.c itoa.c ../../../../components/c/wasmcv/import.c ../../../../components/c/wasmcv/import_component_type.o \ 178 | -Wl,--export=process \ 179 | -Wl,--export=__data_end -Wl,--export=__heap_base \ 180 | -Wl,--strip-all,--no-entry \ 181 | -Wl,--unresolved-symbols=ignore-all \ 182 | -nostdlib \ 183 | ``` 184 | 185 | The `wasm32-unknown-unknown` target can be used with wasmCV to produce very lightweight guest modules. The example above compiles to just under 3k, including debug information. 186 | 187 | ```shell 188 | -rwxrwxr-x 1 ron ron 2916 sep 13 20:03 processc.wasm 189 | ``` 190 | 191 | See the [multi example application here](./examples/multi) to try wasmCV with C. 192 | 193 | ## WASM Component Generation 194 | 195 | WASM Guest bindings are generated using `wit-bindgen` v0.41 or above. 196 | 197 | https://github.com/bytecodealliance/wit-bindgen 198 | 199 | Go bindings are generated by `wit-bindgen-go` command line tool v0.6.0 or above. 200 | 201 | https://github.com/bytecodealliance/go-modules 202 | 203 | ### TinyGo 204 | 205 | ```shell 206 | wit-bindgen-go generate --out ./components/tinygo -w imports -p wasmcv.org ./wit 207 | ``` 208 | 209 | Note that the TinyGo bindings are a git submodule. When regenerating the submodule must be updated in order to update the separate Go package repo. 210 | 211 | ### Rust 212 | 213 | ```shell 214 | wit-bindgen rust --out-dir ./components/rust/wasmcv/src -w imports ./wit 215 | ``` 216 | 217 | ### C 218 | 219 | ```shell 220 | wit-bindgen c --out-dir ./components/c/wasmcv/ -w imports ./wit 221 | ``` 222 | -------------------------------------------------------------------------------- /components/c/wasmcv/README.md: -------------------------------------------------------------------------------- 1 | # wasmCV 2 | 3 | C bindings for wasmCV WebAssembly interfaces to computer vision systems. 4 | 5 | See https://github.com/wasmvision/wasmcv for information about wasmCV. 6 | 7 | ## How to use 8 | 9 | This example C module exports a `process()` function to the WASM host application. When the host calls the processor, it passes in the wasmCV image `Mat` to be processed. The wasmCV module then calls functions on that `Mat` which are handled by the host application, by calling OpenCV to actually perform the operations. 10 | 11 | ```c 12 | #include 13 | #include "wasmcv/imports.h" 14 | 15 | extern int itoa(int value, char *sp, int radix); 16 | 17 | __attribute__((import_module("hosted"), import_name("println"))) void println(int32_t str, int32_t len); 18 | 19 | wasm_cv_mat_borrow_mat_t process(wasm_cv_mat_borrow_mat_t image) { 20 | int32_t cols, rows; 21 | cols = wasm_cv_mat_method_mat_cols(image); 22 | rows = wasm_cv_mat_method_mat_rows(image); 23 | 24 | char buf[20]; 25 | strcpy(buf, "Cols: "); 26 | itoa(cols, buf+6, 10); 27 | strcpy(buf+9, " Rows: "); 28 | itoa(rows, buf+16, 10); 29 | 30 | println((int32_t)buf, 20); 31 | 32 | return image; 33 | } 34 | ``` 35 | 36 | You can then compile this module using the `clang` compiler. 37 | 38 | ```shell 39 | /opt/wasi-sdk/bin/clang --target=wasm32-unknown-unknown -O3 \ 40 | --sysroot="/path/to/lib/wasi-libc/sysroot" \ 41 | -z stack-size=4096 -Wl,--initial-memory=65536 \ 42 | -o build/processc.wasm process.c itoa.c /path/to/wasmcv/import.c /path/to/wasmcv/import_component_type.o \ 43 | -Wl,--export=process \ 44 | -Wl,--export=__data_end -Wl,--export=__heap_base \ 45 | -Wl,--strip-all,--no-entry \ 46 | -Wl,--unresolved-symbols=ignore-all \ 47 | -nostdlib \ 48 | ``` 49 | 50 | The `wasm32-unknown-unknown` target can be used with wasmCV to produce very lightweight guest modules. The example above compiles to just under 3k, including debug information. 51 | 52 | ```shell 53 | -rwxrwxr-x 1 ron ron 2916 sep 13 20:03 processc.wasm 54 | ``` 55 | -------------------------------------------------------------------------------- /components/c/wasmcv/imports_component_type.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wasmvision/wasmcv/276954feff9177637c1ee822bff813f1aeb5b358/components/c/wasmcv/imports_component_type.o -------------------------------------------------------------------------------- /components/rust/wasmcv/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /components/rust/wasmcv/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "adler2" 7 | version = "2.0.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 10 | 11 | [[package]] 12 | name = "anyhow" 13 | version = "1.0.89" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" 16 | 17 | [[package]] 18 | name = "auditable-serde" 19 | version = "0.8.0" 20 | source = "registry+https://github.com/rust-lang/crates.io-index" 21 | checksum = "5c7bf8143dfc3c0258df908843e169b5cc5fcf76c7718bd66135ef4a9cd558c5" 22 | dependencies = [ 23 | "semver", 24 | "serde", 25 | "serde_json", 26 | "topological-sort", 27 | ] 28 | 29 | [[package]] 30 | name = "autocfg" 31 | version = "1.4.0" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 34 | 35 | [[package]] 36 | name = "bitflags" 37 | version = "2.6.0" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 40 | 41 | [[package]] 42 | name = "cfg-if" 43 | version = "1.0.0" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 46 | 47 | [[package]] 48 | name = "crc32fast" 49 | version = "1.4.2" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" 52 | dependencies = [ 53 | "cfg-if", 54 | ] 55 | 56 | [[package]] 57 | name = "displaydoc" 58 | version = "0.2.5" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 61 | dependencies = [ 62 | "proc-macro2", 63 | "quote", 64 | "syn", 65 | ] 66 | 67 | [[package]] 68 | name = "equivalent" 69 | version = "1.0.1" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 72 | 73 | [[package]] 74 | name = "flate2" 75 | version = "1.1.1" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" 78 | dependencies = [ 79 | "crc32fast", 80 | "miniz_oxide", 81 | ] 82 | 83 | [[package]] 84 | name = "foldhash" 85 | version = "0.1.4" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" 88 | 89 | [[package]] 90 | name = "form_urlencoded" 91 | version = "1.2.1" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 94 | dependencies = [ 95 | "percent-encoding", 96 | ] 97 | 98 | [[package]] 99 | name = "futures" 100 | version = "0.3.31" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" 103 | dependencies = [ 104 | "futures-channel", 105 | "futures-core", 106 | "futures-executor", 107 | "futures-io", 108 | "futures-sink", 109 | "futures-task", 110 | "futures-util", 111 | ] 112 | 113 | [[package]] 114 | name = "futures-channel" 115 | version = "0.3.31" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 118 | dependencies = [ 119 | "futures-core", 120 | "futures-sink", 121 | ] 122 | 123 | [[package]] 124 | name = "futures-core" 125 | version = "0.3.31" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 128 | 129 | [[package]] 130 | name = "futures-executor" 131 | version = "0.3.31" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" 134 | dependencies = [ 135 | "futures-core", 136 | "futures-task", 137 | "futures-util", 138 | ] 139 | 140 | [[package]] 141 | name = "futures-io" 142 | version = "0.3.31" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 145 | 146 | [[package]] 147 | name = "futures-macro" 148 | version = "0.3.31" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" 151 | dependencies = [ 152 | "proc-macro2", 153 | "quote", 154 | "syn", 155 | ] 156 | 157 | [[package]] 158 | name = "futures-sink" 159 | version = "0.3.31" 160 | source = "registry+https://github.com/rust-lang/crates.io-index" 161 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 162 | 163 | [[package]] 164 | name = "futures-task" 165 | version = "0.3.31" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 168 | 169 | [[package]] 170 | name = "futures-util" 171 | version = "0.3.31" 172 | source = "registry+https://github.com/rust-lang/crates.io-index" 173 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 174 | dependencies = [ 175 | "futures-channel", 176 | "futures-core", 177 | "futures-io", 178 | "futures-macro", 179 | "futures-sink", 180 | "futures-task", 181 | "memchr", 182 | "pin-project-lite", 183 | "pin-utils", 184 | "slab", 185 | ] 186 | 187 | [[package]] 188 | name = "hashbrown" 189 | version = "0.15.2" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 192 | dependencies = [ 193 | "foldhash", 194 | ] 195 | 196 | [[package]] 197 | name = "heck" 198 | version = "0.5.0" 199 | source = "registry+https://github.com/rust-lang/crates.io-index" 200 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 201 | 202 | [[package]] 203 | name = "icu_collections" 204 | version = "1.5.0" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" 207 | dependencies = [ 208 | "displaydoc", 209 | "yoke", 210 | "zerofrom", 211 | "zerovec", 212 | ] 213 | 214 | [[package]] 215 | name = "icu_locid" 216 | version = "1.5.0" 217 | source = "registry+https://github.com/rust-lang/crates.io-index" 218 | checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" 219 | dependencies = [ 220 | "displaydoc", 221 | "litemap", 222 | "tinystr", 223 | "writeable", 224 | "zerovec", 225 | ] 226 | 227 | [[package]] 228 | name = "icu_locid_transform" 229 | version = "1.5.0" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" 232 | dependencies = [ 233 | "displaydoc", 234 | "icu_locid", 235 | "icu_locid_transform_data", 236 | "icu_provider", 237 | "tinystr", 238 | "zerovec", 239 | ] 240 | 241 | [[package]] 242 | name = "icu_locid_transform_data" 243 | version = "1.5.0" 244 | source = "registry+https://github.com/rust-lang/crates.io-index" 245 | checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" 246 | 247 | [[package]] 248 | name = "icu_normalizer" 249 | version = "1.5.0" 250 | source = "registry+https://github.com/rust-lang/crates.io-index" 251 | checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" 252 | dependencies = [ 253 | "displaydoc", 254 | "icu_collections", 255 | "icu_normalizer_data", 256 | "icu_properties", 257 | "icu_provider", 258 | "smallvec", 259 | "utf16_iter", 260 | "utf8_iter", 261 | "write16", 262 | "zerovec", 263 | ] 264 | 265 | [[package]] 266 | name = "icu_normalizer_data" 267 | version = "1.5.0" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" 270 | 271 | [[package]] 272 | name = "icu_properties" 273 | version = "1.5.1" 274 | source = "registry+https://github.com/rust-lang/crates.io-index" 275 | checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" 276 | dependencies = [ 277 | "displaydoc", 278 | "icu_collections", 279 | "icu_locid_transform", 280 | "icu_properties_data", 281 | "icu_provider", 282 | "tinystr", 283 | "zerovec", 284 | ] 285 | 286 | [[package]] 287 | name = "icu_properties_data" 288 | version = "1.5.0" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" 291 | 292 | [[package]] 293 | name = "icu_provider" 294 | version = "1.5.0" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" 297 | dependencies = [ 298 | "displaydoc", 299 | "icu_locid", 300 | "icu_provider_macros", 301 | "stable_deref_trait", 302 | "tinystr", 303 | "writeable", 304 | "yoke", 305 | "zerofrom", 306 | "zerovec", 307 | ] 308 | 309 | [[package]] 310 | name = "icu_provider_macros" 311 | version = "1.5.0" 312 | source = "registry+https://github.com/rust-lang/crates.io-index" 313 | checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" 314 | dependencies = [ 315 | "proc-macro2", 316 | "quote", 317 | "syn", 318 | ] 319 | 320 | [[package]] 321 | name = "id-arena" 322 | version = "2.2.1" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" 325 | 326 | [[package]] 327 | name = "idna" 328 | version = "1.0.3" 329 | source = "registry+https://github.com/rust-lang/crates.io-index" 330 | checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" 331 | dependencies = [ 332 | "idna_adapter", 333 | "smallvec", 334 | "utf8_iter", 335 | ] 336 | 337 | [[package]] 338 | name = "idna_adapter" 339 | version = "1.2.0" 340 | source = "registry+https://github.com/rust-lang/crates.io-index" 341 | checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" 342 | dependencies = [ 343 | "icu_normalizer", 344 | "icu_properties", 345 | ] 346 | 347 | [[package]] 348 | name = "indexmap" 349 | version = "2.7.1" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" 352 | dependencies = [ 353 | "equivalent", 354 | "hashbrown", 355 | "serde", 356 | ] 357 | 358 | [[package]] 359 | name = "itoa" 360 | version = "1.0.11" 361 | source = "registry+https://github.com/rust-lang/crates.io-index" 362 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 363 | 364 | [[package]] 365 | name = "leb128fmt" 366 | version = "0.1.0" 367 | source = "registry+https://github.com/rust-lang/crates.io-index" 368 | checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" 369 | 370 | [[package]] 371 | name = "litemap" 372 | version = "0.7.4" 373 | source = "registry+https://github.com/rust-lang/crates.io-index" 374 | checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" 375 | 376 | [[package]] 377 | name = "log" 378 | version = "0.4.22" 379 | source = "registry+https://github.com/rust-lang/crates.io-index" 380 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 381 | 382 | [[package]] 383 | name = "memchr" 384 | version = "2.7.4" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 387 | 388 | [[package]] 389 | name = "miniz_oxide" 390 | version = "0.8.5" 391 | source = "registry+https://github.com/rust-lang/crates.io-index" 392 | checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" 393 | dependencies = [ 394 | "adler2", 395 | ] 396 | 397 | [[package]] 398 | name = "once_cell" 399 | version = "1.20.0" 400 | source = "registry+https://github.com/rust-lang/crates.io-index" 401 | checksum = "33ea5043e58958ee56f3e15a90aee535795cd7dfd319846288d93c5b57d85cbe" 402 | 403 | [[package]] 404 | name = "percent-encoding" 405 | version = "2.3.1" 406 | source = "registry+https://github.com/rust-lang/crates.io-index" 407 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 408 | 409 | [[package]] 410 | name = "pin-project-lite" 411 | version = "0.2.16" 412 | source = "registry+https://github.com/rust-lang/crates.io-index" 413 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 414 | 415 | [[package]] 416 | name = "pin-utils" 417 | version = "0.1.0" 418 | source = "registry+https://github.com/rust-lang/crates.io-index" 419 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 420 | 421 | [[package]] 422 | name = "prettyplease" 423 | version = "0.2.22" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" 426 | dependencies = [ 427 | "proc-macro2", 428 | "syn", 429 | ] 430 | 431 | [[package]] 432 | name = "proc-macro2" 433 | version = "1.0.93" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" 436 | dependencies = [ 437 | "unicode-ident", 438 | ] 439 | 440 | [[package]] 441 | name = "quote" 442 | version = "1.0.37" 443 | source = "registry+https://github.com/rust-lang/crates.io-index" 444 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 445 | dependencies = [ 446 | "proc-macro2", 447 | ] 448 | 449 | [[package]] 450 | name = "ryu" 451 | version = "1.0.18" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 454 | 455 | [[package]] 456 | name = "semver" 457 | version = "1.0.23" 458 | source = "registry+https://github.com/rust-lang/crates.io-index" 459 | checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" 460 | dependencies = [ 461 | "serde", 462 | ] 463 | 464 | [[package]] 465 | name = "serde" 466 | version = "1.0.210" 467 | source = "registry+https://github.com/rust-lang/crates.io-index" 468 | checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" 469 | dependencies = [ 470 | "serde_derive", 471 | ] 472 | 473 | [[package]] 474 | name = "serde_derive" 475 | version = "1.0.210" 476 | source = "registry+https://github.com/rust-lang/crates.io-index" 477 | checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" 478 | dependencies = [ 479 | "proc-macro2", 480 | "quote", 481 | "syn", 482 | ] 483 | 484 | [[package]] 485 | name = "serde_json" 486 | version = "1.0.128" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" 489 | dependencies = [ 490 | "itoa", 491 | "memchr", 492 | "ryu", 493 | "serde", 494 | ] 495 | 496 | [[package]] 497 | name = "slab" 498 | version = "0.4.9" 499 | source = "registry+https://github.com/rust-lang/crates.io-index" 500 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 501 | dependencies = [ 502 | "autocfg", 503 | ] 504 | 505 | [[package]] 506 | name = "smallvec" 507 | version = "1.13.2" 508 | source = "registry+https://github.com/rust-lang/crates.io-index" 509 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 510 | 511 | [[package]] 512 | name = "spdx" 513 | version = "0.10.6" 514 | source = "registry+https://github.com/rust-lang/crates.io-index" 515 | checksum = "47317bbaf63785b53861e1ae2d11b80d6b624211d42cb20efcd210ee6f8a14bc" 516 | dependencies = [ 517 | "smallvec", 518 | ] 519 | 520 | [[package]] 521 | name = "stable_deref_trait" 522 | version = "1.2.0" 523 | source = "registry+https://github.com/rust-lang/crates.io-index" 524 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 525 | 526 | [[package]] 527 | name = "syn" 528 | version = "2.0.96" 529 | source = "registry+https://github.com/rust-lang/crates.io-index" 530 | checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" 531 | dependencies = [ 532 | "proc-macro2", 533 | "quote", 534 | "unicode-ident", 535 | ] 536 | 537 | [[package]] 538 | name = "synstructure" 539 | version = "0.13.1" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" 542 | dependencies = [ 543 | "proc-macro2", 544 | "quote", 545 | "syn", 546 | ] 547 | 548 | [[package]] 549 | name = "tinystr" 550 | version = "0.7.6" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" 553 | dependencies = [ 554 | "displaydoc", 555 | "zerovec", 556 | ] 557 | 558 | [[package]] 559 | name = "topological-sort" 560 | version = "0.2.2" 561 | source = "registry+https://github.com/rust-lang/crates.io-index" 562 | checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d" 563 | 564 | [[package]] 565 | name = "unicode-ident" 566 | version = "1.0.13" 567 | source = "registry+https://github.com/rust-lang/crates.io-index" 568 | checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" 569 | 570 | [[package]] 571 | name = "unicode-xid" 572 | version = "0.2.5" 573 | source = "registry+https://github.com/rust-lang/crates.io-index" 574 | checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" 575 | 576 | [[package]] 577 | name = "url" 578 | version = "2.5.4" 579 | source = "registry+https://github.com/rust-lang/crates.io-index" 580 | checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" 581 | dependencies = [ 582 | "form_urlencoded", 583 | "idna", 584 | "percent-encoding", 585 | ] 586 | 587 | [[package]] 588 | name = "utf16_iter" 589 | version = "1.0.5" 590 | source = "registry+https://github.com/rust-lang/crates.io-index" 591 | checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" 592 | 593 | [[package]] 594 | name = "utf8_iter" 595 | version = "1.0.4" 596 | source = "registry+https://github.com/rust-lang/crates.io-index" 597 | checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 598 | 599 | [[package]] 600 | name = "wasm-encoder" 601 | version = "0.227.1" 602 | source = "registry+https://github.com/rust-lang/crates.io-index" 603 | checksum = "80bb72f02e7fbf07183443b27b0f3d4144abf8c114189f2e088ed95b696a7822" 604 | dependencies = [ 605 | "leb128fmt", 606 | "wasmparser", 607 | ] 608 | 609 | [[package]] 610 | name = "wasm-metadata" 611 | version = "0.227.1" 612 | source = "registry+https://github.com/rust-lang/crates.io-index" 613 | checksum = "ce1ef0faabbbba6674e97a56bee857ccddf942785a336c8b47b42373c922a91d" 614 | dependencies = [ 615 | "anyhow", 616 | "auditable-serde", 617 | "flate2", 618 | "indexmap", 619 | "serde", 620 | "serde_derive", 621 | "serde_json", 622 | "spdx", 623 | "url", 624 | "wasm-encoder", 625 | "wasmparser", 626 | ] 627 | 628 | [[package]] 629 | name = "wasmcv" 630 | version = "0.8.2" 631 | dependencies = [ 632 | "wit-bindgen", 633 | ] 634 | 635 | [[package]] 636 | name = "wasmparser" 637 | version = "0.227.1" 638 | source = "registry+https://github.com/rust-lang/crates.io-index" 639 | checksum = "0f51cad774fb3c9461ab9bccc9c62dfb7388397b5deda31bf40e8108ccd678b2" 640 | dependencies = [ 641 | "bitflags", 642 | "hashbrown", 643 | "indexmap", 644 | "semver", 645 | ] 646 | 647 | [[package]] 648 | name = "wit-bindgen" 649 | version = "0.41.0" 650 | source = "registry+https://github.com/rust-lang/crates.io-index" 651 | checksum = "10fb6648689b3929d56bbc7eb1acf70c9a42a29eb5358c67c10f54dbd5d695de" 652 | dependencies = [ 653 | "wit-bindgen-rt", 654 | "wit-bindgen-rust-macro", 655 | ] 656 | 657 | [[package]] 658 | name = "wit-bindgen-core" 659 | version = "0.41.0" 660 | source = "registry+https://github.com/rust-lang/crates.io-index" 661 | checksum = "92fa781d4f2ff6d3f27f3cc9b74a73327b31ca0dc4a3ef25a0ce2983e0e5af9b" 662 | dependencies = [ 663 | "anyhow", 664 | "heck", 665 | "wit-parser", 666 | ] 667 | 668 | [[package]] 669 | name = "wit-bindgen-rt" 670 | version = "0.41.0" 671 | source = "registry+https://github.com/rust-lang/crates.io-index" 672 | checksum = "c4db52a11d4dfb0a59f194c064055794ee6564eb1ced88c25da2cf76e50c5621" 673 | dependencies = [ 674 | "bitflags", 675 | "futures", 676 | "once_cell", 677 | ] 678 | 679 | [[package]] 680 | name = "wit-bindgen-rust" 681 | version = "0.41.0" 682 | source = "registry+https://github.com/rust-lang/crates.io-index" 683 | checksum = "9d0809dc5ba19e2e98661bf32fc0addc5a3ca5bf3a6a7083aa6ba484085ff3ce" 684 | dependencies = [ 685 | "anyhow", 686 | "heck", 687 | "indexmap", 688 | "prettyplease", 689 | "syn", 690 | "wasm-metadata", 691 | "wit-bindgen-core", 692 | "wit-component", 693 | ] 694 | 695 | [[package]] 696 | name = "wit-bindgen-rust-macro" 697 | version = "0.41.0" 698 | source = "registry+https://github.com/rust-lang/crates.io-index" 699 | checksum = "ad19eec017904e04c60719592a803ee5da76cb51c81e3f6fbf9457f59db49799" 700 | dependencies = [ 701 | "anyhow", 702 | "prettyplease", 703 | "proc-macro2", 704 | "quote", 705 | "syn", 706 | "wit-bindgen-core", 707 | "wit-bindgen-rust", 708 | ] 709 | 710 | [[package]] 711 | name = "wit-component" 712 | version = "0.227.1" 713 | source = "registry+https://github.com/rust-lang/crates.io-index" 714 | checksum = "635c3adc595422cbf2341a17fb73a319669cc8d33deed3a48368a841df86b676" 715 | dependencies = [ 716 | "anyhow", 717 | "bitflags", 718 | "indexmap", 719 | "log", 720 | "serde", 721 | "serde_derive", 722 | "serde_json", 723 | "wasm-encoder", 724 | "wasm-metadata", 725 | "wasmparser", 726 | "wit-parser", 727 | ] 728 | 729 | [[package]] 730 | name = "wit-parser" 731 | version = "0.227.1" 732 | source = "registry+https://github.com/rust-lang/crates.io-index" 733 | checksum = "ddf445ed5157046e4baf56f9138c124a0824d4d1657e7204d71886ad8ce2fc11" 734 | dependencies = [ 735 | "anyhow", 736 | "id-arena", 737 | "indexmap", 738 | "log", 739 | "semver", 740 | "serde", 741 | "serde_derive", 742 | "serde_json", 743 | "unicode-xid", 744 | "wasmparser", 745 | ] 746 | 747 | [[package]] 748 | name = "write16" 749 | version = "1.0.0" 750 | source = "registry+https://github.com/rust-lang/crates.io-index" 751 | checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" 752 | 753 | [[package]] 754 | name = "writeable" 755 | version = "0.5.5" 756 | source = "registry+https://github.com/rust-lang/crates.io-index" 757 | checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" 758 | 759 | [[package]] 760 | name = "yoke" 761 | version = "0.7.5" 762 | source = "registry+https://github.com/rust-lang/crates.io-index" 763 | checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" 764 | dependencies = [ 765 | "serde", 766 | "stable_deref_trait", 767 | "yoke-derive", 768 | "zerofrom", 769 | ] 770 | 771 | [[package]] 772 | name = "yoke-derive" 773 | version = "0.7.5" 774 | source = "registry+https://github.com/rust-lang/crates.io-index" 775 | checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" 776 | dependencies = [ 777 | "proc-macro2", 778 | "quote", 779 | "syn", 780 | "synstructure", 781 | ] 782 | 783 | [[package]] 784 | name = "zerofrom" 785 | version = "0.1.5" 786 | source = "registry+https://github.com/rust-lang/crates.io-index" 787 | checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" 788 | dependencies = [ 789 | "zerofrom-derive", 790 | ] 791 | 792 | [[package]] 793 | name = "zerofrom-derive" 794 | version = "0.1.5" 795 | source = "registry+https://github.com/rust-lang/crates.io-index" 796 | checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" 797 | dependencies = [ 798 | "proc-macro2", 799 | "quote", 800 | "syn", 801 | "synstructure", 802 | ] 803 | 804 | [[package]] 805 | name = "zerovec" 806 | version = "0.10.4" 807 | source = "registry+https://github.com/rust-lang/crates.io-index" 808 | checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" 809 | dependencies = [ 810 | "yoke", 811 | "zerofrom", 812 | "zerovec-derive", 813 | ] 814 | 815 | [[package]] 816 | name = "zerovec-derive" 817 | version = "0.10.3" 818 | source = "registry+https://github.com/rust-lang/crates.io-index" 819 | checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" 820 | dependencies = [ 821 | "proc-macro2", 822 | "quote", 823 | "syn", 824 | ] 825 | -------------------------------------------------------------------------------- /components/rust/wasmcv/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wasmcv" 3 | description = "Rust bindings for wasmCV computer vision interfaces based on WebAssembly." 4 | version = "0.8.2" 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | keywords = ["opencv", "wasm", "wasi", "vision", "wasmcv"] 8 | categories =["computer-vision", "wasm"] 9 | authors = ["deadprogram "] 10 | repository = "https://github.com/wasmvision/wasmcv" 11 | readme = "README.md" 12 | 13 | [dependencies] 14 | wit-bindgen = "0.41.0" 15 | 16 | [lib] 17 | path = "src/imports.rs" 18 | crate-type = ["lib"] 19 | -------------------------------------------------------------------------------- /components/rust/wasmcv/README.md: -------------------------------------------------------------------------------- 1 | # wasmCV 2 | 3 | Rust bindings for wasmCV WebAssembly interfaces to computer vision systems. 4 | 5 | See https://github.com/wasmvision/wasmcv for information about wasmCV. 6 | 7 | [![Package](https://img.shields.io/crates/v/wasmcv.svg)](https://crates.io/crates/wasmcv) 8 | 9 | ## How to use 10 | 11 | This example Rust module exports a `process()` function to the WASM host application. When the host calls the processor, it passes in the wasmCV image `Mat` to be processed. The wasmCV module then calls functions on that `Mat` which are handled by the host application, by calling OpenCV to actually perform the operations. 12 | 13 | ```rust 14 | #![no_std] 15 | 16 | extern crate core; 17 | extern crate wee_alloc; 18 | extern crate alloc; 19 | extern crate wasmcv; 20 | 21 | use alloc::string::String; 22 | use alloc::string::ToString; 23 | use wasmcv::wasm::cv; 24 | 25 | #[no_mangle] 26 | pub extern fn process(mat: cv::mat::Mat) -> cv::mat::Mat { 27 | println(&["Cols: ", &mat.cols().to_string(), " Rows: ", &mat.rows().to_string()].concat()); 28 | 29 | return mat; 30 | } 31 | 32 | /// Print a message to the host [`_println`]. 33 | fn println(message: &String) { 34 | unsafe { 35 | let (ptr, len) = string_to_ptr(message); 36 | _println(ptr, len); 37 | } 38 | } 39 | 40 | #[link(wasm_import_module = "hosted")] 41 | extern "C" { 42 | #[link_name = "println"] 43 | fn _println(ptr: u32, size: u32); 44 | } 45 | 46 | unsafe fn string_to_ptr(s: &String) -> (u32, u32) { 47 | return (s.as_ptr() as u32, s.len() as u32); 48 | } 49 | 50 | // Use `wee_alloc` as the global allocator...for now. 51 | #[global_allocator] 52 | static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; 53 | ``` 54 | 55 | You can then compile this module using the Rust compiler. 56 | 57 | ```shell 58 | cargo build --target wasm32-unknown-unknown --release 59 | ``` 60 | 61 | The `wasm32-unknown-unknown` target can be used with wasmCV to produce very lightweight guest modules when combined with `no_std`. The example above compiles to around 14k, including debug information. 62 | 63 | ```shell 64 | -rwxrwxr-x 1 ron ron 14488 sep 12 14:23 processrs.wasm 65 | ``` 66 | -------------------------------------------------------------------------------- /examples/basic/README.md: -------------------------------------------------------------------------------- 1 | # Basic 2 | 3 | Basic example that reads frames from a connected webcam, and processes them using a wasmCV guest module compiled using [TinyGo](https://tinygo.org). 4 | 5 | The host application is a Go application written using [GoCV Go language wrappers for OpenCV](https://github.com/hybridgroup/gocv) and the [Wazero WASM runtime](https://github.com/tetratelabs/wazero). 6 | 7 | ## Compile the guest module 8 | 9 | ```shell 10 | $ cd modules/processor 11 | $ tinygo build -o ../processor.wasm -target=wasm-unknown . 12 | $ cd ../.. 13 | ``` 14 | 15 | ## Run the host application 16 | 17 | ```shell 18 | $ go run . 19 | Defining host function... 20 | Start reading device: /dev/video0 21 | ``` 22 | 23 | It will then capture each frame, display some stats, and them perform a gaussian blur on the source image. 24 | 25 | ```shell 26 | Read frame 1 27 | Cols: 640 Rows: 480 Type: 16 28 | Frame complete 29 | ``` 30 | -------------------------------------------------------------------------------- /examples/basic/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/wasmvision/wasmcv/examples/basic 2 | 3 | go 1.22.0 4 | 5 | require ( 6 | github.com/orsinium-labs/wypes v0.3.0 7 | github.com/tetratelabs/wazero v1.8.2 8 | gocv.io/x/gocv v0.41.0 9 | ) 10 | -------------------------------------------------------------------------------- /examples/basic/go.sum: -------------------------------------------------------------------------------- 1 | github.com/orsinium-labs/tinytest v1.0.0 h1:YiGm/whlGm3mn/ynx9CCFuvEa3Q6yEGrzrKXEqJOkdc= 2 | github.com/orsinium-labs/tinytest v1.0.0/go.mod h1:GwcYBp0aKi6zujzBXFpCnqw6RSLSp9JSedDyu/V1DF4= 3 | github.com/orsinium-labs/wypes v0.3.0 h1:kp1NK0SYxh0nNcsiNPI+mSIGZeVfwxEqsWpYg2ooXP0= 4 | github.com/orsinium-labs/wypes v0.3.0/go.mod h1:FSNWGo8I6/D5RYXMkCxyu71TXJAlwJGQUxgs4i6MAwo= 5 | github.com/tetratelabs/wazero v1.8.2 h1:yIgLR/b2bN31bjxwXHD8a3d+BogigR952csSDdLYEv4= 6 | github.com/tetratelabs/wazero v1.8.2/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs= 7 | gocv.io/x/gocv v0.41.0 h1:KM+zRXUP28b6dHfhy+4JxDODbCNQNtLg8kio+YE7TqA= 8 | gocv.io/x/gocv v0.41.0/go.mod h1:zYdWMj29WAEznM3Y8NsU3A0TRq/wR/cy75jeUypThqU= 9 | -------------------------------------------------------------------------------- /examples/basic/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | _ "embed" 6 | "flag" 7 | "fmt" 8 | "log" 9 | 10 | "github.com/orsinium-labs/wypes" 11 | "github.com/tetratelabs/wazero" 12 | "gocv.io/x/gocv" 13 | ) 14 | 15 | // processFrameWasm was generated by the following: 16 | // 17 | // cd modules/processor; tinygo build -o ../processor.wasm -target=wasm-unknown . 18 | // 19 | //go:embed modules/processor.wasm 20 | var processFrameWasm []byte 21 | 22 | var frame gocv.Mat 23 | 24 | var guestDataPtr uint32 25 | 26 | func main() { 27 | flag.Parse() 28 | 29 | ctx := context.Background() 30 | r := wazero.NewRuntime(ctx) 31 | defer r.Close(ctx) 32 | 33 | println("Defining host function...") 34 | modules := wypes.Modules{ 35 | "hosted": wypes.Module{ 36 | "println": wypes.H1(hostPrintln), 37 | }, 38 | "wasm:cv/mat": wypes.Module{ 39 | "[method]mat.cols": wypes.H1(matColsFunc), 40 | "[method]mat.rows": wypes.H1(matRowsFunc), 41 | "[method]mat.mattype": wypes.H1(matTypeFunc), 42 | "[method]mat.size": wypes.H3(matSizeFunc), 43 | }, 44 | } 45 | 46 | err := modules.DefineWazero(r, nil) 47 | if err != nil { 48 | fmt.Printf("error define host functions: %v", err) 49 | return 50 | } 51 | 52 | mod, err := r.InstantiateWithConfig(ctx, processFrameWasm, wazero.NewModuleConfig().WithName("processor").WithStartFunctions("_initialize", "_start")) 53 | if err != nil { 54 | log.Panicf("failed to instantiate module: %v", err) 55 | } 56 | process := mod.ExportedFunction("process") 57 | malloc := mod.ExportedFunction("malloc") 58 | res, err := malloc.Call(ctx, 256) 59 | if err != nil { 60 | log.Panicf("failed to call malloc: %v", err) 61 | } 62 | 63 | guestDataPtr = uint32(res[0]) 64 | 65 | // Open the webcam. 66 | deviceID := "0" 67 | webcam, err := gocv.OpenVideoCapture(deviceID) 68 | if err != nil { 69 | fmt.Printf("Error opening video capture device: %v\n", deviceID) 70 | return 71 | } 72 | defer webcam.Close() 73 | 74 | // streaming, capture from webcam 75 | frame = gocv.NewMat() 76 | defer frame.Close() 77 | 78 | fmt.Printf("Start reading device: %v\n", deviceID) 79 | i := 0 80 | for { 81 | if ok := webcam.Read(&frame); !ok { 82 | fmt.Printf("frame error %v\n", deviceID) 83 | continue 84 | } 85 | if frame.Empty() { 86 | continue 87 | } 88 | 89 | i++ 90 | fmt.Printf("Read frame %d\n", i+1) 91 | _, err := process.Call(ctx, 1) 92 | if err != nil { 93 | fmt.Printf("Error calling process: %v\n", err) 94 | } 95 | } 96 | } 97 | 98 | func hostPrintln(msg wypes.String) wypes.Void { 99 | println(msg.Unwrap()) 100 | return wypes.Void{} 101 | } 102 | 103 | func matColsFunc(matref wypes.UInt32) wypes.UInt32 { 104 | return wypes.UInt32(frame.Cols()) 105 | } 106 | 107 | func matRowsFunc(matref wypes.UInt32) wypes.UInt32 { 108 | return wypes.UInt32(frame.Rows()) 109 | } 110 | 111 | func matTypeFunc(matref wypes.UInt32) wypes.UInt32 { 112 | return wypes.UInt32(frame.Type()) 113 | } 114 | 115 | func matSizeFunc(s *wypes.Store, f wypes.UInt32, list wypes.ReturnedList[wypes.UInt32]) wypes.Void { 116 | dims := frame.Size() 117 | 118 | result := make([]wypes.UInt32, len(dims)) 119 | for i, dim := range dims { 120 | result[i] = wypes.UInt32(dim) 121 | } 122 | 123 | list.Raw = result 124 | list.DataPtr = guestDataPtr 125 | list.Lower(s) 126 | 127 | return wypes.Void{} 128 | } 129 | -------------------------------------------------------------------------------- /examples/basic/modules/processor.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wasmvision/wasmcv/276954feff9177637c1ee822bff813f1aeb5b358/examples/basic/modules/processor.wasm -------------------------------------------------------------------------------- /examples/basic/modules/processor/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/wasmvision/wasmcv/examples/basic/modules/processor 2 | 3 | go 1.23.0 4 | 5 | toolchain go1.24.1 6 | 7 | replace wasmcv.org/wasm/cv => ../../../../components/tinygo/wasm/cv 8 | 9 | require ( 10 | github.com/hybridgroup/mechanoid v0.2.0 11 | wasmcv.org/wasm/cv v0.6.0 12 | ) 13 | 14 | require go.bytecodealliance.org/cm v0.2.2 // indirect 15 | -------------------------------------------------------------------------------- /examples/basic/modules/processor/go.sum: -------------------------------------------------------------------------------- 1 | github.com/hybridgroup/mechanoid v0.2.0 h1:2Kg3c0cK9JK8ZeJkiN+l2o4B0QJYnNHkNEKraMFOugQ= 2 | github.com/hybridgroup/mechanoid v0.2.0/go.mod h1:7jQEJ0blXXbIcqmu2/d7vSxWL5Dxbt18zZirJ35OeXc= 3 | go.bytecodealliance.org/cm v0.2.2 h1:M9iHS6qs884mbQbIjtLX1OifgyPG9DuMs2iwz8G4WQA= 4 | go.bytecodealliance.org/cm v0.2.2/go.mod h1:JD5vtVNZv7sBoQQkvBvAAVKJPhR/bqBH7yYXTItMfZI= 5 | -------------------------------------------------------------------------------- /examples/basic/modules/processor/processor.go: -------------------------------------------------------------------------------- 1 | //go:build tinygo 2 | 3 | package main 4 | 5 | import ( 6 | "unsafe" 7 | 8 | "github.com/hybridgroup/mechanoid/convert" 9 | "go.bytecodealliance.org/cm" 10 | "wasmcv.org/wasm/cv/mat" 11 | ) 12 | 13 | //go:wasmimport hosted println 14 | func println(ptr *byte, size uint32) 15 | 16 | //export process 17 | func process(image mat.Mat) mat.Mat { 18 | println(cm.LowerString("Cols: " + 19 | convert.IntToString(int(image.Cols())) + 20 | " Rows: " + 21 | convert.IntToString(int(image.Rows())) + 22 | " Type: " + 23 | convert.IntToString(int(image.Mattype())) + 24 | " Size: " + 25 | convert.IntToString(int(image.Size().Len())))) 26 | 27 | return image 28 | } 29 | 30 | //export malloc 31 | func malloc(size uint32) uint32 { 32 | data := make([]byte, size) 33 | ptr := uintptr(unsafe.Pointer(unsafe.SliceData(data))) 34 | 35 | return uint32(ptr) 36 | } 37 | 38 | //export free 39 | func free(ptr uint32) { 40 | } 41 | -------------------------------------------------------------------------------- /examples/multi/README.md: -------------------------------------------------------------------------------- 1 | # Multi 2 | 3 | The `multi` example that reads frames from a connected webcam, and processes them using a wasmCV guest module written using either [TinyGo](https://tinygo.org), [Rust](https://www.rust-lang.org/), or C. 4 | 5 | The host application is a Go application written using [GoCV Go language wrappers for OpenCV](https://github.com/hybridgroup/gocv) and the [Wazero WASM runtime](https://github.com/tetratelabs/wazero). 6 | 7 | ## Compile the TinyGo guest module 8 | 9 | ```shell 10 | $ cd modules/processor 11 | $ tinygo build -o ../processor.wasm -target=wasm-unknown . 12 | $ cd ../.. 13 | ``` 14 | 15 | ## Compile the Rust guest module 16 | 17 | ```shell 18 | $ cd modules/processrs 19 | $ cargo build --target wasm32-unknown-unknown --release 20 | $ cd ../.. 21 | $ cp ./modules/processrs/target/wasm32-unknown-unknown/release/processrs.wasm ./modules/ 22 | ``` 23 | 24 | ## Compile the C guest module 25 | 26 | ```shell 27 | $ cd modules/processc 28 | $ ./build.sh 29 | $ cd ../.. 30 | ``` 31 | 32 | ## Run the host application using the TinyGo wasmCV guest module 33 | 34 | ```shell 35 | $ go run . -processor=tinygo 36 | Defining host functions... 37 | Loading tinygo wasmCV guest module... 38 | Start reading device id: 0 39 | ``` 40 | 41 | It will then capture each frame, display some stats, and them perform a gaussian blur on the source image. 42 | 43 | ```shell 44 | Running tinygo wasmCV module 45 | Read frame 34 46 | Cols: 640 Rows: 480 47 | ``` 48 | 49 | ## Run the host application using the Rust wasmCV guest module 50 | 51 | ```shell 52 | $ go run . -processor=rust 53 | Defining host functions... 54 | Loading rust wasmCV guest module... 55 | Start reading device: /dev/video0 56 | ``` 57 | 58 | ```shell 59 | Running rust wasmCV module 60 | Read frame 28 61 | Cols: 640 Rows: 480 62 | ``` 63 | 64 | ## Run the host application using the C wasmCV guest module 65 | 66 | ```shell 67 | $ go run . -processor=c 68 | Defining host functions... 69 | Loading c wasmCV guest module... 70 | Start reading device: /dev/video0 71 | ``` 72 | 73 | ```shell 74 | Running c wasmCV module 75 | Read frame 28 76 | Cols: 640 Rows: 480 77 | ``` 78 | -------------------------------------------------------------------------------- /examples/multi/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/wasmvision/wasmcv/examples/multi 2 | 3 | go 1.23.0 4 | 5 | require ( 6 | github.com/orsinium-labs/wypes v0.3.0 7 | github.com/tetratelabs/wazero v1.8.2 8 | gocv.io/x/gocv v0.41.0 9 | ) 10 | -------------------------------------------------------------------------------- /examples/multi/go.sum: -------------------------------------------------------------------------------- 1 | github.com/orsinium-labs/tinytest v1.0.0 h1:YiGm/whlGm3mn/ynx9CCFuvEa3Q6yEGrzrKXEqJOkdc= 2 | github.com/orsinium-labs/tinytest v1.0.0/go.mod h1:GwcYBp0aKi6zujzBXFpCnqw6RSLSp9JSedDyu/V1DF4= 3 | github.com/orsinium-labs/wypes v0.3.0 h1:kp1NK0SYxh0nNcsiNPI+mSIGZeVfwxEqsWpYg2ooXP0= 4 | github.com/orsinium-labs/wypes v0.3.0/go.mod h1:FSNWGo8I6/D5RYXMkCxyu71TXJAlwJGQUxgs4i6MAwo= 5 | github.com/tetratelabs/wazero v1.8.2 h1:yIgLR/b2bN31bjxwXHD8a3d+BogigR952csSDdLYEv4= 6 | github.com/tetratelabs/wazero v1.8.2/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs= 7 | gocv.io/x/gocv v0.41.0 h1:KM+zRXUP28b6dHfhy+4JxDODbCNQNtLg8kio+YE7TqA= 8 | gocv.io/x/gocv v0.41.0/go.mod h1:zYdWMj29WAEznM3Y8NsU3A0TRq/wR/cy75jeUypThqU= 9 | -------------------------------------------------------------------------------- /examples/multi/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | _ "embed" 6 | "flag" 7 | "fmt" 8 | "log" 9 | 10 | "github.com/orsinium-labs/wypes" 11 | "github.com/tetratelabs/wazero" 12 | "gocv.io/x/gocv" 13 | ) 14 | 15 | //go:embed modules/processor.wasm 16 | var processorFrameWasm []byte 17 | 18 | //go:embed modules/processrs.wasm 19 | var processrsFrameWasm []byte 20 | 21 | //go:embed modules/processc.wasm 22 | var processcFrameWasm []byte 23 | 24 | var ( 25 | processor = flag.String("processor", "tinygo", "which wasmCV processor to use (tinygo|rust|c)") 26 | 27 | frame gocv.Mat 28 | 29 | guestDataPtr uint32 30 | ) 31 | 32 | func main() { 33 | flag.Parse() 34 | 35 | var module []byte 36 | switch *processor { 37 | case "tinygo": 38 | module = processorFrameWasm 39 | case "rust": 40 | module = processrsFrameWasm 41 | case "c": 42 | module = processcFrameWasm 43 | default: 44 | log.Panicf("unsupported processor: %s", *processor) 45 | } 46 | 47 | ctx := context.Background() 48 | r := wazero.NewRuntime(ctx) 49 | defer r.Close(ctx) 50 | 51 | println("Defining host functions...") 52 | modules := wypes.Modules{ 53 | "hosted": wypes.Module{ 54 | "println": wypes.H1(hostPrintln), 55 | }, 56 | "wasm:cv/mat": wypes.Module{ 57 | "[method]mat.cols": wypes.H1(matColsFunc), 58 | "[method]mat.rows": wypes.H1(matRowsFunc), 59 | "[method]mat.mattype": wypes.H1(matTypeFunc), 60 | "[method]mat.size": wypes.H3(matSizeFunc), 61 | }, 62 | } 63 | 64 | err := modules.DefineWazero(r, nil) 65 | if err != nil { 66 | fmt.Printf("error define host functions: %v", err) 67 | return 68 | } 69 | 70 | fmt.Printf("Loading %s wasmCV guest module...\n", *processor) 71 | mod, err := r.InstantiateWithConfig(ctx, module, wazero.NewModuleConfig().WithName("processor").WithStartFunctions("_initialize", "_start")) 72 | if err != nil { 73 | log.Panicf("failed to instantiate module: %v", err) 74 | } 75 | process := mod.ExportedFunction("process") 76 | 77 | // Open the webcam. 78 | deviceID := "0" 79 | webcam, err := gocv.OpenVideoCapture(deviceID) 80 | if err != nil { 81 | fmt.Printf("Error opening video capture device: %v\n", deviceID) 82 | return 83 | } 84 | defer webcam.Close() 85 | 86 | // streaming, capture from webcam 87 | frame = gocv.NewMat() 88 | defer frame.Close() 89 | 90 | fmt.Printf("Start reading device id: %v\n", deviceID) 91 | i := 0 92 | for { 93 | if ok := webcam.Read(&frame); !ok { 94 | fmt.Printf("frame error %v\n", deviceID) 95 | continue 96 | } 97 | if frame.Empty() { 98 | continue 99 | } 100 | 101 | i++ 102 | fmt.Printf("Read frame %d\n", i+1) 103 | _, err := process.Call(ctx, 1) 104 | if err != nil { 105 | fmt.Printf("Error calling process: %v\n", err) 106 | } 107 | } 108 | } 109 | 110 | func hostPrintln(msg wypes.String) wypes.Void { 111 | println(msg.Unwrap()) 112 | return wypes.Void{} 113 | } 114 | 115 | func matColsFunc(matref wypes.UInt32) wypes.UInt32 { 116 | return wypes.UInt32(frame.Cols()) 117 | } 118 | 119 | func matRowsFunc(matref wypes.UInt32) wypes.UInt32 { 120 | return wypes.UInt32(frame.Rows()) 121 | } 122 | 123 | func matTypeFunc(matref wypes.UInt32) wypes.UInt32 { 124 | return wypes.UInt32(frame.Type()) 125 | } 126 | 127 | func matSizeFunc(s *wypes.Store, matref wypes.UInt32, list wypes.ReturnedList[wypes.UInt32]) wypes.Void { 128 | dims := frame.Size() 129 | 130 | result := make([]wypes.UInt32, len(dims)) 131 | for i, dim := range dims { 132 | result[i] = wypes.UInt32(dim) 133 | } 134 | 135 | list.Raw = result 136 | list.DataPtr = guestDataPtr 137 | list.Lower(s) 138 | 139 | return wypes.Void{} 140 | } 141 | -------------------------------------------------------------------------------- /examples/multi/modules/processc.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wasmvision/wasmcv/276954feff9177637c1ee822bff813f1aeb5b358/examples/multi/modules/processc.wasm -------------------------------------------------------------------------------- /examples/multi/modules/processc/README.md: -------------------------------------------------------------------------------- 1 | # Processor 2 | 3 | wasmCV guest module in C that processes image frames. 4 | 5 | ## Building 6 | 7 | ```shell 8 | ./build.sh 9 | ``` 10 | 11 | Note that you need to also have TinyGo installed to obtain the needed `wasi-libc` or else install it separately. 12 | -------------------------------------------------------------------------------- /examples/multi/modules/processc/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # must have TinyGo installed to obtain the TINYGOROOT, or else separately install wasi-lib 4 | WASI_LIBC_SYSROOT=$(tinygo env TINYGOROOT) 5 | 6 | /opt/wasi-sdk/bin/clang --target=wasm32-unknown-unknown -O3 \ 7 | --sysroot="${WASI_LIBC_SYSROOT}/lib/wasi-libc/sysroot" \ 8 | -z stack-size=4096 -Wl,--initial-memory=65536 \ 9 | -o ../processc.wasm process.c itoa.c ../../../../components/c/wasmcv/imports.c ../../../../components/c/wasmcv/imports_component_type.o \ 10 | -Wl,--export=process \ 11 | -Wl,--export=__data_end -Wl,--export=__heap_base \ 12 | -Wl,--strip-all,--no-entry \ 13 | -Wl,--unresolved-symbols=ignore-all \ 14 | -nostdlib \ 15 | -------------------------------------------------------------------------------- /examples/multi/modules/processc/itoa.c: -------------------------------------------------------------------------------- 1 | 2 | int itoa(int value, char *sp, int radix) { 3 | char tmp[16]; 4 | char *tp = tmp; 5 | int i; 6 | unsigned v; 7 | 8 | int sign = (radix == 10 && value < 0); 9 | if (sign) 10 | v = -value; 11 | else 12 | v = (unsigned)value; 13 | 14 | while (v || tp == tmp) 15 | { 16 | i = v % radix; 17 | v /= radix; 18 | if (i < 10) 19 | *tp++ = i+'0'; 20 | else 21 | *tp++ = i + 'a' - 10; 22 | } 23 | 24 | int len = tp - tmp; 25 | 26 | if (sign) 27 | { 28 | *sp++ = '-'; 29 | len++; 30 | } 31 | 32 | while (tp > tmp) 33 | *sp++ = *--tp; 34 | 35 | return len; 36 | } 37 | -------------------------------------------------------------------------------- /examples/multi/modules/processc/process.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../../../../components/c/wasmcv/imports.h" 3 | 4 | extern int itoa(int value, char *sp, int radix); 5 | 6 | __attribute__((import_module("hosted"), import_name("println"))) void println(int32_t str, int32_t len); 7 | 8 | wasm_cv_mat_borrow_mat_t process(wasm_cv_mat_borrow_mat_t image) { 9 | int32_t cols, rows; 10 | cols = wasm_cv_mat_method_mat_cols(image); 11 | rows = wasm_cv_mat_method_mat_rows(image); 12 | 13 | char buf[20]; 14 | strcpy(buf, "Cols: "); 15 | itoa(cols, buf+6, 10); 16 | strcpy(buf+9, " Rows: "); 17 | itoa(rows, buf+16, 10); 18 | 19 | println((int32_t)buf, 20); 20 | 21 | return image; 22 | } 23 | -------------------------------------------------------------------------------- /examples/multi/modules/processor.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wasmvision/wasmcv/276954feff9177637c1ee822bff813f1aeb5b358/examples/multi/modules/processor.wasm -------------------------------------------------------------------------------- /examples/multi/modules/processor/README.md: -------------------------------------------------------------------------------- 1 | # Processor 2 | 3 | wasmCV guest module in TinyGo that processes image frames. 4 | 5 | ## Building 6 | 7 | ```shell 8 | tinygo build -o ../processor.wasm -target=wasm-unknown . 9 | ``` 10 | -------------------------------------------------------------------------------- /examples/multi/modules/processor/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/wasmvision/wasmcv/examples/multi/modules/processor 2 | 3 | go 1.23.0 4 | 5 | toolchain go1.24.1 6 | 7 | replace wasmcv.org/wasm/cv => ../../../../components/tinygo/wasm/cv 8 | 9 | require ( 10 | github.com/hybridgroup/mechanoid v0.2.0 11 | wasmcv.org/wasm/cv v0.0.0-20240916150538-4ca2e2943887 12 | ) 13 | 14 | require go.bytecodealliance.org/cm v0.2.2 15 | -------------------------------------------------------------------------------- /examples/multi/modules/processor/go.sum: -------------------------------------------------------------------------------- 1 | github.com/hybridgroup/mechanoid v0.2.0 h1:2Kg3c0cK9JK8ZeJkiN+l2o4B0QJYnNHkNEKraMFOugQ= 2 | github.com/hybridgroup/mechanoid v0.2.0/go.mod h1:7jQEJ0blXXbIcqmu2/d7vSxWL5Dxbt18zZirJ35OeXc= 3 | go.bytecodealliance.org/cm v0.2.2 h1:M9iHS6qs884mbQbIjtLX1OifgyPG9DuMs2iwz8G4WQA= 4 | go.bytecodealliance.org/cm v0.2.2/go.mod h1:JD5vtVNZv7sBoQQkvBvAAVKJPhR/bqBH7yYXTItMfZI= 5 | -------------------------------------------------------------------------------- /examples/multi/modules/processor/processor.go: -------------------------------------------------------------------------------- 1 | //go:build tinygo 2 | 3 | package main 4 | 5 | import ( 6 | "github.com/hybridgroup/mechanoid/convert" 7 | "go.bytecodealliance.org/cm" 8 | "wasmcv.org/wasm/cv/mat" 9 | ) 10 | 11 | //go:wasmimport hosted println 12 | func println(ptr *byte, size uint32) 13 | 14 | //export process 15 | func process(image mat.Mat) mat.Mat { 16 | println(cm.LowerString("Cols: " + 17 | convert.IntToString(int(image.Cols())) + 18 | " Rows: " + 19 | convert.IntToString(int(image.Rows())) + 20 | " Type: " + 21 | convert.IntToString(int(image.Mattype())))) 22 | 23 | return image 24 | } 25 | -------------------------------------------------------------------------------- /examples/multi/modules/processrs.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wasmvision/wasmcv/276954feff9177637c1ee822bff813f1aeb5b358/examples/multi/modules/processrs.wasm -------------------------------------------------------------------------------- /examples/multi/modules/processrs/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target."wasm32-unknown-unknown"] 2 | rustflags = ["-C", "target-feature=+bulk-memory", 3 | "-C", "link-arg=--initial-memory=65536", 4 | "-C", "link-arg=-zstack-size=4096"] 5 | -------------------------------------------------------------------------------- /examples/multi/modules/processrs/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /examples/multi/modules/processrs/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "adler2" 7 | version = "2.0.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 10 | 11 | [[package]] 12 | name = "anyhow" 13 | version = "1.0.88" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "4e1496f8fb1fbf272686b8d37f523dab3e4a7443300055e74cdaa449f3114356" 16 | 17 | [[package]] 18 | name = "auditable-serde" 19 | version = "0.8.0" 20 | source = "registry+https://github.com/rust-lang/crates.io-index" 21 | checksum = "5c7bf8143dfc3c0258df908843e169b5cc5fcf76c7718bd66135ef4a9cd558c5" 22 | dependencies = [ 23 | "semver", 24 | "serde", 25 | "serde_json", 26 | "topological-sort", 27 | ] 28 | 29 | [[package]] 30 | name = "autocfg" 31 | version = "1.4.0" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 34 | 35 | [[package]] 36 | name = "bitflags" 37 | version = "2.6.0" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 40 | 41 | [[package]] 42 | name = "cfg-if" 43 | version = "1.0.0" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 46 | 47 | [[package]] 48 | name = "crc32fast" 49 | version = "1.4.2" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" 52 | dependencies = [ 53 | "cfg-if", 54 | ] 55 | 56 | [[package]] 57 | name = "displaydoc" 58 | version = "0.2.5" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 61 | dependencies = [ 62 | "proc-macro2", 63 | "quote", 64 | "syn", 65 | ] 66 | 67 | [[package]] 68 | name = "equivalent" 69 | version = "1.0.1" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 72 | 73 | [[package]] 74 | name = "flate2" 75 | version = "1.1.1" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" 78 | dependencies = [ 79 | "crc32fast", 80 | "miniz_oxide", 81 | ] 82 | 83 | [[package]] 84 | name = "foldhash" 85 | version = "0.1.5" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" 88 | 89 | [[package]] 90 | name = "form_urlencoded" 91 | version = "1.2.1" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 94 | dependencies = [ 95 | "percent-encoding", 96 | ] 97 | 98 | [[package]] 99 | name = "futures" 100 | version = "0.3.31" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" 103 | dependencies = [ 104 | "futures-channel", 105 | "futures-core", 106 | "futures-executor", 107 | "futures-io", 108 | "futures-sink", 109 | "futures-task", 110 | "futures-util", 111 | ] 112 | 113 | [[package]] 114 | name = "futures-channel" 115 | version = "0.3.31" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 118 | dependencies = [ 119 | "futures-core", 120 | "futures-sink", 121 | ] 122 | 123 | [[package]] 124 | name = "futures-core" 125 | version = "0.3.31" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 128 | 129 | [[package]] 130 | name = "futures-executor" 131 | version = "0.3.31" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" 134 | dependencies = [ 135 | "futures-core", 136 | "futures-task", 137 | "futures-util", 138 | ] 139 | 140 | [[package]] 141 | name = "futures-io" 142 | version = "0.3.31" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 145 | 146 | [[package]] 147 | name = "futures-macro" 148 | version = "0.3.31" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" 151 | dependencies = [ 152 | "proc-macro2", 153 | "quote", 154 | "syn", 155 | ] 156 | 157 | [[package]] 158 | name = "futures-sink" 159 | version = "0.3.31" 160 | source = "registry+https://github.com/rust-lang/crates.io-index" 161 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 162 | 163 | [[package]] 164 | name = "futures-task" 165 | version = "0.3.31" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 168 | 169 | [[package]] 170 | name = "futures-util" 171 | version = "0.3.31" 172 | source = "registry+https://github.com/rust-lang/crates.io-index" 173 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 174 | dependencies = [ 175 | "futures-channel", 176 | "futures-core", 177 | "futures-io", 178 | "futures-macro", 179 | "futures-sink", 180 | "futures-task", 181 | "memchr", 182 | "pin-project-lite", 183 | "pin-utils", 184 | "slab", 185 | ] 186 | 187 | [[package]] 188 | name = "hashbrown" 189 | version = "0.15.2" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 192 | dependencies = [ 193 | "foldhash", 194 | ] 195 | 196 | [[package]] 197 | name = "heck" 198 | version = "0.5.0" 199 | source = "registry+https://github.com/rust-lang/crates.io-index" 200 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 201 | 202 | [[package]] 203 | name = "icu_collections" 204 | version = "1.5.0" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" 207 | dependencies = [ 208 | "displaydoc", 209 | "yoke", 210 | "zerofrom", 211 | "zerovec", 212 | ] 213 | 214 | [[package]] 215 | name = "icu_locid" 216 | version = "1.5.0" 217 | source = "registry+https://github.com/rust-lang/crates.io-index" 218 | checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" 219 | dependencies = [ 220 | "displaydoc", 221 | "litemap", 222 | "tinystr", 223 | "writeable", 224 | "zerovec", 225 | ] 226 | 227 | [[package]] 228 | name = "icu_locid_transform" 229 | version = "1.5.0" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" 232 | dependencies = [ 233 | "displaydoc", 234 | "icu_locid", 235 | "icu_locid_transform_data", 236 | "icu_provider", 237 | "tinystr", 238 | "zerovec", 239 | ] 240 | 241 | [[package]] 242 | name = "icu_locid_transform_data" 243 | version = "1.5.1" 244 | source = "registry+https://github.com/rust-lang/crates.io-index" 245 | checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" 246 | 247 | [[package]] 248 | name = "icu_normalizer" 249 | version = "1.5.0" 250 | source = "registry+https://github.com/rust-lang/crates.io-index" 251 | checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" 252 | dependencies = [ 253 | "displaydoc", 254 | "icu_collections", 255 | "icu_normalizer_data", 256 | "icu_properties", 257 | "icu_provider", 258 | "smallvec", 259 | "utf16_iter", 260 | "utf8_iter", 261 | "write16", 262 | "zerovec", 263 | ] 264 | 265 | [[package]] 266 | name = "icu_normalizer_data" 267 | version = "1.5.1" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" 270 | 271 | [[package]] 272 | name = "icu_properties" 273 | version = "1.5.1" 274 | source = "registry+https://github.com/rust-lang/crates.io-index" 275 | checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" 276 | dependencies = [ 277 | "displaydoc", 278 | "icu_collections", 279 | "icu_locid_transform", 280 | "icu_properties_data", 281 | "icu_provider", 282 | "tinystr", 283 | "zerovec", 284 | ] 285 | 286 | [[package]] 287 | name = "icu_properties_data" 288 | version = "1.5.1" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" 291 | 292 | [[package]] 293 | name = "icu_provider" 294 | version = "1.5.0" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" 297 | dependencies = [ 298 | "displaydoc", 299 | "icu_locid", 300 | "icu_provider_macros", 301 | "stable_deref_trait", 302 | "tinystr", 303 | "writeable", 304 | "yoke", 305 | "zerofrom", 306 | "zerovec", 307 | ] 308 | 309 | [[package]] 310 | name = "icu_provider_macros" 311 | version = "1.5.0" 312 | source = "registry+https://github.com/rust-lang/crates.io-index" 313 | checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" 314 | dependencies = [ 315 | "proc-macro2", 316 | "quote", 317 | "syn", 318 | ] 319 | 320 | [[package]] 321 | name = "id-arena" 322 | version = "2.2.1" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" 325 | 326 | [[package]] 327 | name = "idna" 328 | version = "1.0.3" 329 | source = "registry+https://github.com/rust-lang/crates.io-index" 330 | checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" 331 | dependencies = [ 332 | "idna_adapter", 333 | "smallvec", 334 | "utf8_iter", 335 | ] 336 | 337 | [[package]] 338 | name = "idna_adapter" 339 | version = "1.2.0" 340 | source = "registry+https://github.com/rust-lang/crates.io-index" 341 | checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" 342 | dependencies = [ 343 | "icu_normalizer", 344 | "icu_properties", 345 | ] 346 | 347 | [[package]] 348 | name = "indexmap" 349 | version = "2.8.0" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" 352 | dependencies = [ 353 | "equivalent", 354 | "hashbrown", 355 | "serde", 356 | ] 357 | 358 | [[package]] 359 | name = "itoa" 360 | version = "1.0.11" 361 | source = "registry+https://github.com/rust-lang/crates.io-index" 362 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 363 | 364 | [[package]] 365 | name = "leb128" 366 | version = "0.2.5" 367 | source = "registry+https://github.com/rust-lang/crates.io-index" 368 | checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" 369 | 370 | [[package]] 371 | name = "leb128fmt" 372 | version = "0.1.0" 373 | source = "registry+https://github.com/rust-lang/crates.io-index" 374 | checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" 375 | 376 | [[package]] 377 | name = "litemap" 378 | version = "0.7.5" 379 | source = "registry+https://github.com/rust-lang/crates.io-index" 380 | checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" 381 | 382 | [[package]] 383 | name = "log" 384 | version = "0.4.22" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 387 | 388 | [[package]] 389 | name = "memchr" 390 | version = "2.7.4" 391 | source = "registry+https://github.com/rust-lang/crates.io-index" 392 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 393 | 394 | [[package]] 395 | name = "miniz_oxide" 396 | version = "0.8.5" 397 | source = "registry+https://github.com/rust-lang/crates.io-index" 398 | checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" 399 | dependencies = [ 400 | "adler2", 401 | ] 402 | 403 | [[package]] 404 | name = "once_cell" 405 | version = "1.19.0" 406 | source = "registry+https://github.com/rust-lang/crates.io-index" 407 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 408 | 409 | [[package]] 410 | name = "percent-encoding" 411 | version = "2.3.1" 412 | source = "registry+https://github.com/rust-lang/crates.io-index" 413 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 414 | 415 | [[package]] 416 | name = "pin-project-lite" 417 | version = "0.2.16" 418 | source = "registry+https://github.com/rust-lang/crates.io-index" 419 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 420 | 421 | [[package]] 422 | name = "pin-utils" 423 | version = "0.1.0" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 426 | 427 | [[package]] 428 | name = "prettyplease" 429 | version = "0.2.22" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" 432 | dependencies = [ 433 | "proc-macro2", 434 | "syn", 435 | ] 436 | 437 | [[package]] 438 | name = "proc-macro2" 439 | version = "1.0.94" 440 | source = "registry+https://github.com/rust-lang/crates.io-index" 441 | checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" 442 | dependencies = [ 443 | "unicode-ident", 444 | ] 445 | 446 | [[package]] 447 | name = "processrs" 448 | version = "0.1.0" 449 | dependencies = [ 450 | "wasmcv", 451 | "wit-bindgen 0.41.0", 452 | ] 453 | 454 | [[package]] 455 | name = "quote" 456 | version = "1.0.37" 457 | source = "registry+https://github.com/rust-lang/crates.io-index" 458 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 459 | dependencies = [ 460 | "proc-macro2", 461 | ] 462 | 463 | [[package]] 464 | name = "ryu" 465 | version = "1.0.18" 466 | source = "registry+https://github.com/rust-lang/crates.io-index" 467 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 468 | 469 | [[package]] 470 | name = "semver" 471 | version = "1.0.23" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" 474 | dependencies = [ 475 | "serde", 476 | ] 477 | 478 | [[package]] 479 | name = "serde" 480 | version = "1.0.210" 481 | source = "registry+https://github.com/rust-lang/crates.io-index" 482 | checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" 483 | dependencies = [ 484 | "serde_derive", 485 | ] 486 | 487 | [[package]] 488 | name = "serde_derive" 489 | version = "1.0.210" 490 | source = "registry+https://github.com/rust-lang/crates.io-index" 491 | checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" 492 | dependencies = [ 493 | "proc-macro2", 494 | "quote", 495 | "syn", 496 | ] 497 | 498 | [[package]] 499 | name = "serde_json" 500 | version = "1.0.128" 501 | source = "registry+https://github.com/rust-lang/crates.io-index" 502 | checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" 503 | dependencies = [ 504 | "itoa", 505 | "memchr", 506 | "ryu", 507 | "serde", 508 | ] 509 | 510 | [[package]] 511 | name = "slab" 512 | version = "0.4.9" 513 | source = "registry+https://github.com/rust-lang/crates.io-index" 514 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 515 | dependencies = [ 516 | "autocfg", 517 | ] 518 | 519 | [[package]] 520 | name = "smallvec" 521 | version = "1.13.2" 522 | source = "registry+https://github.com/rust-lang/crates.io-index" 523 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 524 | 525 | [[package]] 526 | name = "spdx" 527 | version = "0.10.6" 528 | source = "registry+https://github.com/rust-lang/crates.io-index" 529 | checksum = "47317bbaf63785b53861e1ae2d11b80d6b624211d42cb20efcd210ee6f8a14bc" 530 | dependencies = [ 531 | "smallvec", 532 | ] 533 | 534 | [[package]] 535 | name = "stable_deref_trait" 536 | version = "1.2.0" 537 | source = "registry+https://github.com/rust-lang/crates.io-index" 538 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 539 | 540 | [[package]] 541 | name = "syn" 542 | version = "2.0.100" 543 | source = "registry+https://github.com/rust-lang/crates.io-index" 544 | checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" 545 | dependencies = [ 546 | "proc-macro2", 547 | "quote", 548 | "unicode-ident", 549 | ] 550 | 551 | [[package]] 552 | name = "synstructure" 553 | version = "0.13.1" 554 | source = "registry+https://github.com/rust-lang/crates.io-index" 555 | checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" 556 | dependencies = [ 557 | "proc-macro2", 558 | "quote", 559 | "syn", 560 | ] 561 | 562 | [[package]] 563 | name = "tinystr" 564 | version = "0.7.6" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" 567 | dependencies = [ 568 | "displaydoc", 569 | "zerovec", 570 | ] 571 | 572 | [[package]] 573 | name = "topological-sort" 574 | version = "0.2.2" 575 | source = "registry+https://github.com/rust-lang/crates.io-index" 576 | checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d" 577 | 578 | [[package]] 579 | name = "unicode-ident" 580 | version = "1.0.13" 581 | source = "registry+https://github.com/rust-lang/crates.io-index" 582 | checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" 583 | 584 | [[package]] 585 | name = "unicode-xid" 586 | version = "0.2.5" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" 589 | 590 | [[package]] 591 | name = "url" 592 | version = "2.5.4" 593 | source = "registry+https://github.com/rust-lang/crates.io-index" 594 | checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" 595 | dependencies = [ 596 | "form_urlencoded", 597 | "idna", 598 | "percent-encoding", 599 | ] 600 | 601 | [[package]] 602 | name = "utf16_iter" 603 | version = "1.0.5" 604 | source = "registry+https://github.com/rust-lang/crates.io-index" 605 | checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" 606 | 607 | [[package]] 608 | name = "utf8_iter" 609 | version = "1.0.4" 610 | source = "registry+https://github.com/rust-lang/crates.io-index" 611 | checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 612 | 613 | [[package]] 614 | name = "wasm-encoder" 615 | version = "0.224.1" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | checksum = "1ab7a13a23790fe91ea4eb7526a1f3131001d874e3e00c2976c48861f2e82920" 618 | dependencies = [ 619 | "leb128", 620 | "wasmparser 0.224.1", 621 | ] 622 | 623 | [[package]] 624 | name = "wasm-encoder" 625 | version = "0.227.1" 626 | source = "registry+https://github.com/rust-lang/crates.io-index" 627 | checksum = "80bb72f02e7fbf07183443b27b0f3d4144abf8c114189f2e088ed95b696a7822" 628 | dependencies = [ 629 | "leb128fmt", 630 | "wasmparser 0.227.1", 631 | ] 632 | 633 | [[package]] 634 | name = "wasm-metadata" 635 | version = "0.224.1" 636 | source = "registry+https://github.com/rust-lang/crates.io-index" 637 | checksum = "c93c9e49fa2749be3c5ab28ad4be03167294915cd3b2ded3f04f760cef5cfb86" 638 | dependencies = [ 639 | "anyhow", 640 | "indexmap", 641 | "serde", 642 | "serde_derive", 643 | "serde_json", 644 | "spdx", 645 | "url", 646 | "wasm-encoder 0.224.1", 647 | "wasmparser 0.224.1", 648 | ] 649 | 650 | [[package]] 651 | name = "wasm-metadata" 652 | version = "0.227.1" 653 | source = "registry+https://github.com/rust-lang/crates.io-index" 654 | checksum = "ce1ef0faabbbba6674e97a56bee857ccddf942785a336c8b47b42373c922a91d" 655 | dependencies = [ 656 | "anyhow", 657 | "auditable-serde", 658 | "flate2", 659 | "indexmap", 660 | "serde", 661 | "serde_derive", 662 | "serde_json", 663 | "spdx", 664 | "url", 665 | "wasm-encoder 0.227.1", 666 | "wasmparser 0.227.1", 667 | ] 668 | 669 | [[package]] 670 | name = "wasmcv" 671 | version = "0.7.0" 672 | dependencies = [ 673 | "wit-bindgen 0.38.0", 674 | ] 675 | 676 | [[package]] 677 | name = "wasmparser" 678 | version = "0.224.1" 679 | source = "registry+https://github.com/rust-lang/crates.io-index" 680 | checksum = "04f17a5917c2ddd3819e84c661fae0d6ba29d7b9c1f0e96c708c65a9c4188e11" 681 | dependencies = [ 682 | "bitflags", 683 | "hashbrown", 684 | "indexmap", 685 | "semver", 686 | ] 687 | 688 | [[package]] 689 | name = "wasmparser" 690 | version = "0.227.1" 691 | source = "registry+https://github.com/rust-lang/crates.io-index" 692 | checksum = "0f51cad774fb3c9461ab9bccc9c62dfb7388397b5deda31bf40e8108ccd678b2" 693 | dependencies = [ 694 | "bitflags", 695 | "hashbrown", 696 | "indexmap", 697 | "semver", 698 | ] 699 | 700 | [[package]] 701 | name = "wit-bindgen" 702 | version = "0.38.0" 703 | source = "registry+https://github.com/rust-lang/crates.io-index" 704 | checksum = "b550e454e4cce8984398539a94a0226511e1f295b14afdc8f08b4e2e2ff9de3a" 705 | dependencies = [ 706 | "wit-bindgen-rt 0.38.0", 707 | "wit-bindgen-rust-macro 0.38.0", 708 | ] 709 | 710 | [[package]] 711 | name = "wit-bindgen" 712 | version = "0.41.0" 713 | source = "registry+https://github.com/rust-lang/crates.io-index" 714 | checksum = "10fb6648689b3929d56bbc7eb1acf70c9a42a29eb5358c67c10f54dbd5d695de" 715 | dependencies = [ 716 | "wit-bindgen-rt 0.41.0", 717 | "wit-bindgen-rust-macro 0.41.0", 718 | ] 719 | 720 | [[package]] 721 | name = "wit-bindgen-core" 722 | version = "0.38.0" 723 | source = "registry+https://github.com/rust-lang/crates.io-index" 724 | checksum = "70e2f98d49960a416074c5d72889f810ed3032a32ffef5e4760094426fefbfe8" 725 | dependencies = [ 726 | "anyhow", 727 | "heck", 728 | "wit-parser 0.224.1", 729 | ] 730 | 731 | [[package]] 732 | name = "wit-bindgen-core" 733 | version = "0.41.0" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "92fa781d4f2ff6d3f27f3cc9b74a73327b31ca0dc4a3ef25a0ce2983e0e5af9b" 736 | dependencies = [ 737 | "anyhow", 738 | "heck", 739 | "wit-parser 0.227.1", 740 | ] 741 | 742 | [[package]] 743 | name = "wit-bindgen-rt" 744 | version = "0.38.0" 745 | source = "registry+https://github.com/rust-lang/crates.io-index" 746 | checksum = "ed6f8d372a2d4a1227f2556e051cc24b2a5f15768d53451c84ff91e2527139e3" 747 | dependencies = [ 748 | "bitflags", 749 | "futures", 750 | "once_cell", 751 | ] 752 | 753 | [[package]] 754 | name = "wit-bindgen-rt" 755 | version = "0.41.0" 756 | source = "registry+https://github.com/rust-lang/crates.io-index" 757 | checksum = "c4db52a11d4dfb0a59f194c064055794ee6564eb1ced88c25da2cf76e50c5621" 758 | dependencies = [ 759 | "bitflags", 760 | "futures", 761 | "once_cell", 762 | ] 763 | 764 | [[package]] 765 | name = "wit-bindgen-rust" 766 | version = "0.38.0" 767 | source = "registry+https://github.com/rust-lang/crates.io-index" 768 | checksum = "1cc49091f84e4f2ace078bbc86082b57e667b9e789baece4b1184e0963382b6e" 769 | dependencies = [ 770 | "anyhow", 771 | "heck", 772 | "indexmap", 773 | "prettyplease", 774 | "syn", 775 | "wasm-metadata 0.224.1", 776 | "wit-bindgen-core 0.38.0", 777 | "wit-component 0.224.1", 778 | ] 779 | 780 | [[package]] 781 | name = "wit-bindgen-rust" 782 | version = "0.41.0" 783 | source = "registry+https://github.com/rust-lang/crates.io-index" 784 | checksum = "9d0809dc5ba19e2e98661bf32fc0addc5a3ca5bf3a6a7083aa6ba484085ff3ce" 785 | dependencies = [ 786 | "anyhow", 787 | "heck", 788 | "indexmap", 789 | "prettyplease", 790 | "syn", 791 | "wasm-metadata 0.227.1", 792 | "wit-bindgen-core 0.41.0", 793 | "wit-component 0.227.1", 794 | ] 795 | 796 | [[package]] 797 | name = "wit-bindgen-rust-macro" 798 | version = "0.38.0" 799 | source = "registry+https://github.com/rust-lang/crates.io-index" 800 | checksum = "3545a699dc9d72298b2064ce71b771fc10fc6b757d29306b1e54a4283a75abba" 801 | dependencies = [ 802 | "anyhow", 803 | "prettyplease", 804 | "proc-macro2", 805 | "quote", 806 | "syn", 807 | "wit-bindgen-core 0.38.0", 808 | "wit-bindgen-rust 0.38.0", 809 | ] 810 | 811 | [[package]] 812 | name = "wit-bindgen-rust-macro" 813 | version = "0.41.0" 814 | source = "registry+https://github.com/rust-lang/crates.io-index" 815 | checksum = "ad19eec017904e04c60719592a803ee5da76cb51c81e3f6fbf9457f59db49799" 816 | dependencies = [ 817 | "anyhow", 818 | "prettyplease", 819 | "proc-macro2", 820 | "quote", 821 | "syn", 822 | "wit-bindgen-core 0.41.0", 823 | "wit-bindgen-rust 0.41.0", 824 | ] 825 | 826 | [[package]] 827 | name = "wit-component" 828 | version = "0.224.1" 829 | source = "registry+https://github.com/rust-lang/crates.io-index" 830 | checksum = "923637fe647372efbbb654757f8c884ba280924477e1d265eca7e35d4cdcea8b" 831 | dependencies = [ 832 | "anyhow", 833 | "bitflags", 834 | "indexmap", 835 | "log", 836 | "serde", 837 | "serde_derive", 838 | "serde_json", 839 | "wasm-encoder 0.224.1", 840 | "wasm-metadata 0.224.1", 841 | "wasmparser 0.224.1", 842 | "wit-parser 0.224.1", 843 | ] 844 | 845 | [[package]] 846 | name = "wit-component" 847 | version = "0.227.1" 848 | source = "registry+https://github.com/rust-lang/crates.io-index" 849 | checksum = "635c3adc595422cbf2341a17fb73a319669cc8d33deed3a48368a841df86b676" 850 | dependencies = [ 851 | "anyhow", 852 | "bitflags", 853 | "indexmap", 854 | "log", 855 | "serde", 856 | "serde_derive", 857 | "serde_json", 858 | "wasm-encoder 0.227.1", 859 | "wasm-metadata 0.227.1", 860 | "wasmparser 0.227.1", 861 | "wit-parser 0.227.1", 862 | ] 863 | 864 | [[package]] 865 | name = "wit-parser" 866 | version = "0.224.1" 867 | source = "registry+https://github.com/rust-lang/crates.io-index" 868 | checksum = "e3477d8d0acb530d76beaa8becbdb1e3face08929db275f39934963eb4f716f8" 869 | dependencies = [ 870 | "anyhow", 871 | "id-arena", 872 | "indexmap", 873 | "log", 874 | "semver", 875 | "serde", 876 | "serde_derive", 877 | "serde_json", 878 | "unicode-xid", 879 | "wasmparser 0.224.1", 880 | ] 881 | 882 | [[package]] 883 | name = "wit-parser" 884 | version = "0.227.1" 885 | source = "registry+https://github.com/rust-lang/crates.io-index" 886 | checksum = "ddf445ed5157046e4baf56f9138c124a0824d4d1657e7204d71886ad8ce2fc11" 887 | dependencies = [ 888 | "anyhow", 889 | "id-arena", 890 | "indexmap", 891 | "log", 892 | "semver", 893 | "serde", 894 | "serde_derive", 895 | "serde_json", 896 | "unicode-xid", 897 | "wasmparser 0.227.1", 898 | ] 899 | 900 | [[package]] 901 | name = "write16" 902 | version = "1.0.0" 903 | source = "registry+https://github.com/rust-lang/crates.io-index" 904 | checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" 905 | 906 | [[package]] 907 | name = "writeable" 908 | version = "0.5.5" 909 | source = "registry+https://github.com/rust-lang/crates.io-index" 910 | checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" 911 | 912 | [[package]] 913 | name = "yoke" 914 | version = "0.7.5" 915 | source = "registry+https://github.com/rust-lang/crates.io-index" 916 | checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" 917 | dependencies = [ 918 | "serde", 919 | "stable_deref_trait", 920 | "yoke-derive", 921 | "zerofrom", 922 | ] 923 | 924 | [[package]] 925 | name = "yoke-derive" 926 | version = "0.7.5" 927 | source = "registry+https://github.com/rust-lang/crates.io-index" 928 | checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" 929 | dependencies = [ 930 | "proc-macro2", 931 | "quote", 932 | "syn", 933 | "synstructure", 934 | ] 935 | 936 | [[package]] 937 | name = "zerofrom" 938 | version = "0.1.6" 939 | source = "registry+https://github.com/rust-lang/crates.io-index" 940 | checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" 941 | dependencies = [ 942 | "zerofrom-derive", 943 | ] 944 | 945 | [[package]] 946 | name = "zerofrom-derive" 947 | version = "0.1.6" 948 | source = "registry+https://github.com/rust-lang/crates.io-index" 949 | checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" 950 | dependencies = [ 951 | "proc-macro2", 952 | "quote", 953 | "syn", 954 | "synstructure", 955 | ] 956 | 957 | [[package]] 958 | name = "zerovec" 959 | version = "0.10.4" 960 | source = "registry+https://github.com/rust-lang/crates.io-index" 961 | checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" 962 | dependencies = [ 963 | "yoke", 964 | "zerofrom", 965 | "zerovec-derive", 966 | ] 967 | 968 | [[package]] 969 | name = "zerovec-derive" 970 | version = "0.10.3" 971 | source = "registry+https://github.com/rust-lang/crates.io-index" 972 | checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" 973 | dependencies = [ 974 | "proc-macro2", 975 | "quote", 976 | "syn", 977 | ] 978 | -------------------------------------------------------------------------------- /examples/multi/modules/processrs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "processrs" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | wasmcv = { version = "0.8.0", path = "../../../../components/rust/wasmcv" } 10 | wit-bindgen = "0.41.0" 11 | 12 | [lib] 13 | crate-type = ["cdylib"] 14 | -------------------------------------------------------------------------------- /examples/multi/modules/processrs/README.md: -------------------------------------------------------------------------------- 1 | # ProcessRS 2 | 3 | wasmCV module in Rust that processes image frames. 4 | 5 | ## Building 6 | 7 | ```shell 8 | cargo build --target wasm32-unknown-unknown --release 9 | cp ./target/wasm32-unknown-unknown/release/processrs.wasm ../ 10 | ``` 11 | -------------------------------------------------------------------------------- /examples/multi/modules/processrs/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | 3 | extern crate core; 4 | extern crate alloc; 5 | 6 | use alloc::string::String; 7 | use alloc::string::ToString; 8 | use wasmcv::wasm::cv; 9 | 10 | #[no_mangle] 11 | pub extern fn process(mat: cv::mat::Mat) -> cv::mat::Mat { 12 | println(&["Cols: ", &mat.cols().to_string(), " Rows: ", &mat.rows().to_string()].concat()); 13 | 14 | return mat; 15 | } 16 | 17 | /// Print a message to the host [`_println`]. 18 | fn println(message: &String) { 19 | unsafe { 20 | let (ptr, len) = string_to_ptr(message); 21 | _println(ptr, len); 22 | } 23 | } 24 | 25 | #[link(wasm_import_module = "hosted")] 26 | extern "C" { 27 | #[link_name = "println"] 28 | fn _println(ptr: u32, size: u32); 29 | } 30 | 31 | unsafe fn string_to_ptr(s: &String) -> (u32, u32) { 32 | return (s.as_ptr() as u32, s.len() as u32); 33 | } 34 | -------------------------------------------------------------------------------- /examples/wasmcam/README.md: -------------------------------------------------------------------------------- 1 | # WASMcam 2 | 3 | ![../../images/wasmcam.png](../../images/wasmcam.png) 4 | 5 | Example that reads frames from a connected webcam, and processes them using a WASM guest module using a call to host via the wasmCV interface to perform a GaussianBlur, then displays the ascii version of the image on the terminal. 6 | 7 | ## Compile the guest module 8 | 9 | ```shell 10 | $ cd modules/processor 11 | $ tinygo build -o ../processor.wasm -target=wasm-unknown . 12 | $ cd ../.. 13 | ``` 14 | 15 | ## Run the host application 16 | 17 | ```shell 18 | $ go run . 19 | Defining host function... 20 | Start reading device id : 0 21 | ``` 22 | 23 | It will then capture each frame, display some stats, and them perform a gaussian blur on the source image. 24 | 25 | ```shell 26 | Read frame 1 27 | Cols: 640 Rows: 480 Type: 16 28 | Performed GaussianBlur on image 29 | Frame complete 30 | ``` 31 | -------------------------------------------------------------------------------- /examples/wasmcam/frame.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "image" 5 | 6 | "github.com/orsinium-labs/wypes" 7 | "gocv.io/x/gocv" 8 | ) 9 | 10 | var ( 11 | frame gocv.Mat 12 | processed gocv.Mat 13 | ) 14 | 15 | func matColsFunc(matref wypes.UInt32) wypes.UInt32 { 16 | return wypes.UInt32(frame.Cols()) 17 | } 18 | 19 | func matRowsFunc(matref wypes.UInt32) wypes.UInt32 { 20 | return wypes.UInt32(frame.Rows()) 21 | } 22 | 23 | func matTypeFunc(matref wypes.UInt32) wypes.UInt32 { 24 | return wypes.UInt32(frame.Type()) 25 | } 26 | 27 | func matGaussianBlurFunc(s *wypes.Store, matref wypes.UInt32, size0 wypes.UInt32, size1 wypes.UInt32, sigmaX0 wypes.Float32, sigmaY0 wypes.Float32, border0 wypes.UInt32, result wypes.Result[wypes.UInt32, wypes.UInt32, wypes.UInt32]) wypes.Void { 28 | err := gocv.GaussianBlur(frame, &processed, image.Pt(int(size0), int(size1)), float64(sigmaX0), float64(sigmaY0), gocv.BorderType(border0)) 29 | if err != nil { 30 | println("Error processing image") 31 | result.IsError = true 32 | result.Error = wypes.UInt32(1) 33 | result.Lower(s) 34 | return wypes.Void{} 35 | } 36 | 37 | result.IsError = false 38 | result.OK = wypes.UInt32(1) 39 | result.Lower(s) 40 | 41 | return wypes.Void{} 42 | } 43 | -------------------------------------------------------------------------------- /examples/wasmcam/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/wasmvision/wasmcv/examples/wasmcam 2 | 3 | go 1.23.0 4 | 5 | require ( 6 | github.com/orsinium-labs/wypes v0.3.0 7 | github.com/subeshb1/wasm-go-image-to-ascii v0.0.0-20200725121413-d828986df340 8 | github.com/tetratelabs/wazero v1.8.2 9 | gocv.io/x/gocv v0.41.0 10 | ) 11 | 12 | require ( 13 | github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 // indirect 14 | github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /examples/wasmcam/go.sum: -------------------------------------------------------------------------------- 1 | github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 h1:WWB576BN5zNSZc/M9d/10pqEx5VHNhaQ/yOVAkmj5Yo= 2 | github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= 3 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 5 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 6 | github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 7 | github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= 8 | github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= 9 | github.com/orsinium-labs/tinytest v1.0.0 h1:YiGm/whlGm3mn/ynx9CCFuvEa3Q6yEGrzrKXEqJOkdc= 10 | github.com/orsinium-labs/tinytest v1.0.0/go.mod h1:GwcYBp0aKi6zujzBXFpCnqw6RSLSp9JSedDyu/V1DF4= 11 | github.com/orsinium-labs/wypes v0.3.0 h1:kp1NK0SYxh0nNcsiNPI+mSIGZeVfwxEqsWpYg2ooXP0= 12 | github.com/orsinium-labs/wypes v0.3.0/go.mod h1:FSNWGo8I6/D5RYXMkCxyu71TXJAlwJGQUxgs4i6MAwo= 13 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 14 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 15 | github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= 16 | github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= 17 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 18 | github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As= 19 | github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= 20 | github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= 21 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 22 | github.com/subeshb1/wasm-go-image-to-ascii v0.0.0-20200725121413-d828986df340 h1:EN1NUPDAdhpWv9zNNdbovzqfJaRmnrwWaq0huRzQp9I= 23 | github.com/subeshb1/wasm-go-image-to-ascii v0.0.0-20200725121413-d828986df340/go.mod h1:A2X7CsJFb8jEdYaWeCbs2HydXC69J4Iaw4DM+bly5iw= 24 | github.com/tetratelabs/wazero v1.8.2 h1:yIgLR/b2bN31bjxwXHD8a3d+BogigR952csSDdLYEv4= 25 | github.com/tetratelabs/wazero v1.8.2/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs= 26 | github.com/wayneashleyberry/terminal-dimensions v1.0.0/go.mod h1:PW2XrtV6KmKOPhuf7wbtcmw1/IFnC39mryRET2XbxeE= 27 | gocv.io/x/gocv v0.41.0 h1:KM+zRXUP28b6dHfhy+4JxDODbCNQNtLg8kio+YE7TqA= 28 | gocv.io/x/gocv v0.41.0/go.mod h1:zYdWMj29WAEznM3Y8NsU3A0TRq/wR/cy75jeUypThqU= 29 | golang.org/x/sys v0.0.0-20181019160139-8e24a49d80f8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 30 | -------------------------------------------------------------------------------- /examples/wasmcam/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | _ "embed" 6 | "flag" 7 | "fmt" 8 | "log" 9 | 10 | "github.com/subeshb1/wasm-go-image-to-ascii/convert" 11 | 12 | "github.com/orsinium-labs/wypes" 13 | "github.com/tetratelabs/wazero" 14 | "gocv.io/x/gocv" 15 | ) 16 | 17 | // processFrameWasm was generated by the following: 18 | // 19 | // cd modules/processor; tinygo build -o ../processor.wasm -target=wasm-unknown . 20 | // 21 | //go:embed modules/processor.wasm 22 | var processFrameWasm []byte 23 | 24 | var ( 25 | device = flag.String("device", "0", "video capture device") 26 | ascii = flag.Bool("ascii", true, "show video output converted to ASCII art") 27 | width = flag.Int("width", 80, "width of the ASCII art") 28 | height = flag.Int("height", 40, "height of the ASCII art") 29 | ) 30 | 31 | func main() { 32 | flag.Parse() 33 | 34 | ctx := context.Background() 35 | r := wazero.NewRuntime(ctx) 36 | defer r.Close(ctx) 37 | 38 | println("Defining host function...") 39 | modules := wypes.Modules{ 40 | "hosted": wypes.Module{ 41 | "println": wypes.H1(hostPrintln), 42 | "complete": wypes.H0(completeFunc), 43 | }, 44 | "wasm:cv/mat": wypes.Module{ 45 | "[method]mat.cols": wypes.H1(matColsFunc), 46 | "[method]mat.rows": wypes.H1(matRowsFunc), 47 | "[method]mat.mattype": wypes.H1(matTypeFunc), 48 | }, 49 | "wasm:cv/cv": wypes.Module{ 50 | "gaussian-blur": wypes.H8(matGaussianBlurFunc), 51 | }, 52 | } 53 | 54 | err := modules.DefineWazero(r, nil) 55 | if err != nil { 56 | fmt.Printf("error define host functions: %v", err) 57 | return 58 | } 59 | 60 | mod, err := r.InstantiateWithConfig(ctx, processFrameWasm, wazero.NewModuleConfig().WithName("processor").WithStartFunctions("_initialize", "_start")) 61 | if err != nil { 62 | log.Panicf("failed to instantiate module: %v", err) 63 | } 64 | process := mod.ExportedFunction("process") 65 | 66 | // Open the webcam. 67 | webcam, err := gocv.OpenVideoCapture(*device) 68 | if err != nil { 69 | fmt.Printf("Error opening video capture device: %v\n", *device) 70 | return 71 | } 72 | defer webcam.Close() 73 | 74 | // streaming, capture from webcam 75 | frame = gocv.NewMat() 76 | defer frame.Close() 77 | 78 | processed = gocv.NewMat() 79 | defer processed.Close() 80 | 81 | asciiConverter := convert.NewImageConverter() 82 | opts := &convert.Options{FixedWidth: *width, FixedHeight: *height, Colored: true} 83 | 84 | fmt.Printf("Start reading device id: %v\n", *device) 85 | i := 0 86 | for { 87 | if ok := webcam.Read(&frame); !ok { 88 | fmt.Printf("frame error %v\n", *device) 89 | continue 90 | } 91 | if frame.Empty() { 92 | continue 93 | } 94 | 95 | // clear screen 96 | fmt.Print("\033[H\033[2J") 97 | 98 | i++ 99 | fmt.Printf("Read frame %d\n", i+1) 100 | _, err := process.Call(ctx, 0) 101 | if err != nil { 102 | fmt.Printf("Error calling process: %v\n", err) 103 | } 104 | 105 | // print the ASCII representation of the frame 106 | if *ascii { 107 | img, err := processed.ToImage() 108 | if err != nil { 109 | fmt.Printf("Error converting mat to image: %v\n", err) 110 | continue 111 | } 112 | 113 | fmt.Println(asciiConverter.Image2ASCIIString(img, opts)) 114 | } 115 | } 116 | } 117 | 118 | func completeFunc() wypes.Void { 119 | println("Frame complete\n") 120 | return wypes.Void{} 121 | } 122 | 123 | func hostPrintln(msg wypes.String) wypes.Void { 124 | println(msg.Unwrap()) 125 | return wypes.Void{} 126 | } 127 | -------------------------------------------------------------------------------- /examples/wasmcam/modules/processor.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wasmvision/wasmcv/276954feff9177637c1ee822bff813f1aeb5b358/examples/wasmcam/modules/processor.wasm -------------------------------------------------------------------------------- /examples/wasmcam/modules/processor/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/wasmvision/wasmcv/examples/wasmcam/modules/processor 2 | 3 | go 1.23.0 4 | 5 | toolchain go1.24.1 6 | 7 | replace wasmcv.org/wasm/cv => ../../../../components/tinygo/wasm/cv 8 | 9 | require ( 10 | github.com/hybridgroup/mechanoid v0.2.0 11 | wasmcv.org/wasm/cv v0.0.0-20240916150538-4ca2e2943887 12 | ) 13 | 14 | require go.bytecodealliance.org/cm v0.2.2 // indirect 15 | -------------------------------------------------------------------------------- /examples/wasmcam/modules/processor/go.sum: -------------------------------------------------------------------------------- 1 | github.com/hybridgroup/mechanoid v0.2.0 h1:2Kg3c0cK9JK8ZeJkiN+l2o4B0QJYnNHkNEKraMFOugQ= 2 | github.com/hybridgroup/mechanoid v0.2.0/go.mod h1:7jQEJ0blXXbIcqmu2/d7vSxWL5Dxbt18zZirJ35OeXc= 3 | go.bytecodealliance.org/cm v0.2.2 h1:M9iHS6qs884mbQbIjtLX1OifgyPG9DuMs2iwz8G4WQA= 4 | go.bytecodealliance.org/cm v0.2.2/go.mod h1:JD5vtVNZv7sBoQQkvBvAAVKJPhR/bqBH7yYXTItMfZI= 5 | -------------------------------------------------------------------------------- /examples/wasmcam/modules/processor/processor.go: -------------------------------------------------------------------------------- 1 | //go:build tinygo 2 | 3 | package main 4 | 5 | import ( 6 | "github.com/hybridgroup/mechanoid/convert" 7 | "go.bytecodealliance.org/cm" 8 | "wasmcv.org/wasm/cv/cv" 9 | "wasmcv.org/wasm/cv/mat" 10 | "wasmcv.org/wasm/cv/types" 11 | ) 12 | 13 | //go:wasmimport hosted complete 14 | func complete() 15 | 16 | //go:wasmimport hosted println 17 | func println(ptr *byte, size uint32) 18 | 19 | //export process 20 | func process(image mat.Mat) mat.Mat { 21 | println(cm.LowerString("Cols: " + 22 | convert.IntToString(int(image.Cols())) + 23 | " Rows: " + 24 | convert.IntToString(int(image.Rows())) + 25 | " Type: " + 26 | convert.IntToString(int(image.Mattype())))) 27 | 28 | imageOut, _, isErr := cv.GaussianBlur(image, types.Size{X: 5, Y: 5}, 1.5, 1.5, types.BorderTypeBorderReflect101).Result() 29 | if isErr { 30 | println(cm.LowerString("Error processing image")) 31 | return image 32 | } 33 | 34 | println(cm.LowerString("Performed GaussianBlur on image")) 35 | 36 | complete() 37 | return imageOut 38 | } 39 | -------------------------------------------------------------------------------- /images/wasmcam.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wasmvision/wasmcv/276954feff9177637c1ee822bff813f1aeb5b358/images/wasmcam.png -------------------------------------------------------------------------------- /wit/core.wit: -------------------------------------------------------------------------------- 1 | 2 | interface cv { 3 | use types.{error-result, border-type, size, point, adaptive-threshold-type, threshold-type, scalar, rect, RGBA, hershey-font-type, interpolation-type, color-coversion-type, morph-shape}; 4 | use mat.{mat, mattype}; 5 | 6 | // drawing functions 7 | 8 | /// ArrowedLine draws a arrow segment pointing from the first point to the second one. 9 | /// 10 | /// For further details, please see: 11 | /// https://docs.opencv.org/master/d6/d6e/group__imgproc__draw.html#ga0a165a3ca093fd488ac709fdf10c05b2 12 | arrowed-line: func(img: borrow, point1: point, point2: point, c: RGBA, thickness: u8) -> result<_, error-result>; 13 | 14 | /// Rectangle draws a simple, thick, or filled up-right rectangle. 15 | /// 16 | /// For further details, please see: 17 | /// https://docs.opencv.org/4.x/d6/d6e/group__imgproc__draw.html#ga07d2f74cadcf8e305e810ce8f3d1e1b7 18 | rectangle: func(img: borrow, r: rect, c: RGBA, thickness: u8) -> result<_, error-result>; 19 | 20 | /// Circle draws a circle. 21 | /// 22 | /// For further details, please see: 23 | /// https://docs.opencv.org/master/d6/d6e/group__imgproc__draw.html#gaf10604b069374903dbd0f0488cb43670 24 | circle: func(img: borrow, center: point, radius: u32, c: RGBA, thickness: u8) -> result<_, error-result>; 25 | 26 | /// Line draws a line segment connecting two points. 27 | /// 28 | /// For further details, please see: 29 | /// https://docs.opencv.org/master/d6/d6e/group__imgproc__draw.html#ga7078a9fae8c7e7d13d24dac2520ae4a2 30 | line: func(img: borrow, point1: point, point2: point, c: RGBA, thickness: u8) -> result<_, error-result>; 31 | 32 | /// PutText draws a text string. 33 | /// It renders the specified text string into the img Mat at the location 34 | /// passed in the "org" param, using the desired font face, font scale, 35 | /// color, and line thinkness. 36 | /// 37 | /// For further details, please see: 38 | /// http://docs.opencv.org/master/d6/d6e/group__imgproc__draw.html#ga5126f47f883d730f633d74f07456c576 39 | put-text: func(img: borrow, text: string, org: point, font-face: hershey-font-type, font-scale: f64, c: RGBA, thickness: s32) -> result<_, error-result>; 40 | 41 | // imgproc functions 42 | 43 | /// AdaptiveThreshold applies a fixed-level threshold to each array element. 44 | /// 45 | /// For further details, please see: 46 | /// https://docs.opencv.org/master/d7/d1b/group__imgproc__misc.html#ga72b913f352e4a1b1b397736707afcde3 47 | adaptive-threshold: func(src: mat, max-value: f32, adaptive-type: adaptive-threshold-type, threshold-type: threshold-type, block-size: u32, c: f32) -> result; 48 | 49 | /// Blur blurs an image Mat using a normalized box filter. 50 | /// 51 | /// For further details, please see: 52 | /// https://docs.opencv.org/master/d4/d86/group__imgproc__filter.html#ga8c45db9afe636703801b0b2e440fce37 53 | blur: func(src: mat, k-size: size) -> result; 54 | 55 | /// BoxFilter blurs an image using the box filter. 56 | /// 57 | /// For further details, please see: 58 | /// https://docs.opencv.org/master/d4/d86/group__imgproc__filter.html#gad533230ebf2d42509547d514f7d3fbc3 59 | box-filter: func(src: mat, depth: u32, k-size: size) -> result; 60 | 61 | /// Canny finds edges in an image using the Canny algorithm. 62 | /// The function finds edges in the input image image and marks 63 | /// them in the output map edges using the Canny algorithm. 64 | /// The smallest value between threshold1 and threshold2 is used 65 | /// for edge linking. The largest value is used to 66 | /// find initial segments of strong edges. 67 | /// See http://en.wikipedia.org/wiki/Canny_edge_detector 68 | /// 69 | /// For further details, please see: 70 | /// http://docs.opencv.org/master/dd/d1a/group__imgproc__feature.html#ga04723e007ed888ddf11d9ba04e2232de 71 | canny: func(src: mat, threshold1: f32, threshold2: f32) -> result; 72 | 73 | /// CvtColor converts an image from one color space to another. 74 | /// 75 | /// For further details, please see: 76 | /// http://docs.opencv.org/master/d7/d1b/group__imgproc__misc.html#ga4e0972be5de079fed4e3a10e24ef5ef0 77 | cvt-color: func(src: mat, code: color-coversion-type) -> result; 78 | 79 | /// Dilate dilates an image by using a specific structuring element. 80 | /// 81 | /// For further details, please see: 82 | /// https://docs.opencv.org/4.x/d4/d86/group__imgproc__filter.html#ga4ff0f3318642c4f469d0e11f242f3b6c 83 | dilate: func(src: mat, kernel: mat) -> result; 84 | 85 | /// Erode erodes an image by using a specific structuring element. 86 | /// 87 | /// For further details, please see: 88 | /// https://docs.opencv.org/master/d4/d86/group__imgproc__filter.html#gaeb1e0c1033e3f6b891a25d0511362aeb 89 | erode: func(src: mat, kernel: mat) -> result; 90 | 91 | /// EqualizeHist normalizes the brightness and increases the contrast of the image. 92 | /// 93 | /// For further details, please see: 94 | /// https://docs.opencv.org/master/d6/dc7/group__imgproc__hist.html#ga7e54091f0c937d49bf84152a16f76d6e 95 | equalize-hist: func(src: mat) -> result; 96 | 97 | /// GaussianBlur blurs an image using a Gaussian filter. 98 | /// 99 | /// For further details, please see: 100 | /// https://docs.opencv.org/4.x/d4/d86/group__imgproc__filter.html#gae8bdcd9154ed5ca3cbc1766d960f45c1 101 | gaussian-blur: func(src: mat, size: size, sigma-x: f32, sigma-y: f32, border: border-type) -> result; 102 | 103 | /// GetStructuringElement returns a structuring element of the specified size 104 | /// and shape for morphological operations. 105 | /// 106 | /// For further details, please see: 107 | /// https://docs.opencv.org/master/d4/d86/group__imgproc__filter.html#gac342a1bb6eabf6f55c803b09268e36dc 108 | get-structuring-element: func(shape: morph-shape, size: size) -> result; 109 | 110 | /// HoughLines implements the standard or standard multi-scale Hough transform 111 | /// algorithm for line detection. For a good explanation of Hough transform, see: 112 | /// http://homepages.inf.ed.ac.uk/rbf/HIPR2/hough.htm 113 | /// 114 | /// For further details, please see: 115 | /// http://docs.opencv.org/master/dd/d1a/group__imgproc__feature.html#ga46b4e588934f6c8dfd509cc6e0e4545a 116 | hough-lines: func(src: mat, rho: f64, theta: f64, threshold: s32) -> result; 117 | 118 | /// HoughLinesP implements the probabilistic Hough transform 119 | /// algorithm for line detection. For a good explanation of Hough transform, see: 120 | /// http://homepages.inf.ed.ac.uk/rbf/HIPR2/hough.htm 121 | /// 122 | /// For further details, please see: 123 | /// http://docs.opencv.org/master/dd/d1a/group__imgproc__feature.html#ga8618180a5948286384e3b7ca02f6feeb 124 | hough-lines-p: func(src: mat, rho: f64, theta: f64, threshold: s32) -> result; 125 | 126 | /// MedianBlur blurs an image using the median filter. 127 | /// 128 | /// For further details, please see: 129 | /// https://docs.opencv.org/master/d4/d86/group__imgproc__filter.html#ga564869aa33e58769b4469101aac458f9 130 | median-blur: func(src: mat, k-size: size) -> result; 131 | 132 | /// Resize resizes an image. 133 | /// It resizes the image src down to or up to the specified size, storing the 134 | /// result in dst. Note that src and dst may be the same image. If you wish to 135 | /// scale by factor, an empty sz may be passed and non-zero fx and fy. Likewise, 136 | /// if you wish to scale to an explicit size, a non-empty sz may be passed with 137 | /// zero for both fx and fy. 138 | /// 139 | /// For further details, please see: 140 | /// https://docs.opencv.org/master/da/d54/group__imgproc__transform.html#ga47a974309e9102f5f08231edc7e7529d 141 | resize: func(src: mat, size: size, fx: f32, fy: f32, interp: interpolation-type) -> result; 142 | 143 | /// Threshold applies a fixed-level threshold to each array element. 144 | /// 145 | /// For further details, please see: 146 | /// https://docs.opencv.org/3.3.0/d7/d1b/group__imgproc__misc.html#gae8a4a146d1ca78c626a53577199e9c57 147 | threshold: func(src: mat, thresh: f32, max-value: f32, threshold-type: threshold-type) -> result; 148 | 149 | /// Transpose for n-dimensional matrices. 150 | /// 151 | /// For further details, please see: 152 | /// https://docs.opencv.org/4.x/d2/de8/group__core__array.html#gab1b1274b4a563be34cdfa55b8919a4ec 153 | transpose-ND: func(src: mat, order: list) -> result; 154 | 155 | /// estimate-affine2d computes an optimal affine transformation between two 2D point sets. 156 | /// 157 | /// For further details, please see: 158 | /// https://docs.opencv.org/4.0.0/d9/d0c/group__calib3d.html#ga27865b1d26bac9ce91efaee83e94d4dd 159 | estimate-affine2d: func(frm: mat, to: mat) -> result; 160 | 161 | /// warp-affine applies an affine transformation to an image. 162 | /// 163 | /// For further details, please see: 164 | /// https://docs.opencv.org/4.x/da/d54/group__imgproc__transform.html#ga0203d9ee5fcd28d40dbc4a1ea4451983 165 | warp-affine: func(src: mat, m: mat, size: size) -> result; 166 | 167 | /// get-rotation-matrix2d calculates an affine matrix of 2D rotation. 168 | /// 169 | /// For further details, please see: 170 | /// https://docs.opencv.org/4.x/da/d54/group__imgproc__transform.html#gafbbc470ce83812914a70abfb604f4326 171 | get-rotation-matrix2d: func(center: point, angle: f64, scale: f64) -> result; 172 | 173 | /// add calculates the per-element sum of two arrays. 174 | /// 175 | /// For further details, please see: 176 | /// https://docs.opencv.org/4.x/d2/de8/group__core__array.html#ga10ac1bfb180e2cfda1701d06c24fdbd6 177 | add: func(src1: mat, src2: mat) -> result; 178 | 179 | /// add-weighted calculates the weighted sum of two arrays. 180 | /// 181 | /// For further details, please see: 182 | /// https://docs.opencv.org/4.x/d2/de8/group__core__array.html#gafafb2513349db3bcff51f54ee5592a19 183 | add-weighted: func(src1: mat, alpha: f64, src2: mat, beta: f64, gamma: f64) -> result; 184 | 185 | /// divide performs per-element division of two arrays. 186 | /// 187 | /// For further details, please see: 188 | /// https://docs.opencv.org/4.x/d2/de8/group__core__array.html#ga6db555d30115642fedae0cda05604874 189 | divide: func(src1: mat, src2: mat) -> result; 190 | 191 | /// exp calculates the exponent of every array element. 192 | /// 193 | /// For further details, please see: 194 | /// https://docs.opencv.org/4.x/d2/de8/group__core__array.html#ga3e10108e2162c338f1b848af619f39e5 195 | exp: func(src: mat) -> result; 196 | 197 | /// hconcat applies horizontal concatenation to given matrices. 198 | /// 199 | /// For further details, please see: 200 | /// https://docs.opencv.org/4.x/d2/de8/group__core__array.html#gaab5ceee39e0580f879df645a872c6bf7 201 | hconcat: func(src1: mat, src2: mat) -> result; 202 | 203 | /// vconcat applies vertical concatenation to given matrices. 204 | /// 205 | /// For further details, please see: 206 | /// https://docs.opencv.org/4.x/d2/de8/group__core__array.html#ga744f53b69f6e4f12156cdde4e76aed27 207 | vconcat: func(src1: mat, src2: mat) -> result; 208 | 209 | /// lut performs a look-up table transform of an array. 210 | /// 211 | /// The function LUT fills the output array with values from the look-up table. 212 | /// Indices of the entries are taken from the input array. 213 | /// 214 | /// For further details, please see: 215 | /// https://docs.opencv.org/4.x/d2/de8/group__core__array.html#gab55b8d062b7f5587720ede032d34156f 216 | lut: func(src: mat, wblut: mat) -> result; 217 | 218 | /// multiply performs per-element multiplication of two arrays. 219 | /// 220 | /// For further details, please see: 221 | /// https://docs.opencv.org/4.x/d2/de8/group__core__array.html#ga979d898a58d7f61c53003e162e7ad89f 222 | multiply: func(src1: mat, src2: mat) -> result; 223 | 224 | /// reduce reduces the matrix to a vector. 225 | /// 226 | /// For further details, please see: 227 | /// https://docs.opencv.org/4.x/d2/de8/group__core__array.html#ga4b78072a303f29d9031d56e5638da78e 228 | reduce: func(src: mat, dim: u32, reduce-type: u32, depth-type: u32) -> result; 229 | 230 | /// reduce-arg-max finds indices of max elements along provided axis. 231 | /// 232 | /// For further details, please see: 233 | /// https://docs.opencv.org/4.x/d2/de8/group__core__array.html#gaa87ea34d99bcc5bf9695048355163da0 234 | reduce-arg-max: func(src: mat, axis: u32, last-index: bool) -> result; 235 | 236 | /// subtract calculates the per-element sum of two arrays. 237 | /// 238 | /// For further details, please see: 239 | /// https://docs.opencv.org/4.x/d2/de8/group__core__array.html#gaa0f00d98b4b5edeaeb7b8333b2de353b 240 | subtract: func(src1: mat, src2: mat) -> result; 241 | 242 | /// normalize normalizes the norm or value range of an array. 243 | /// 244 | /// For further details, please see: 245 | /// https://docs.opencv.org/4.x/d2/de8/group__core__array.html#ga87eef7ee3970f86906d69a92cbf064bd 246 | normalize: func(src: mat, alpha: f32, beta: f32, norm-type: u32) -> result; 247 | 248 | /// norm calculates the norm of an array. 249 | /// 250 | /// For further details, please see: 251 | /// https://docs.opencv.org/4.x/d2/de8/group__core__array.html#ga7c331fb8dd951707e184ef4e3f21dd33 252 | norm: func(src: mat, norm-type: u32) -> result; 253 | } 254 | -------------------------------------------------------------------------------- /wit/dnn.wit: -------------------------------------------------------------------------------- 1 | interface dnn { 2 | use mat.{mat}; 3 | use types.{error-result, size, scalar, rect, blob-params, data-layout-type, padding-mode-type}; 4 | 5 | enum net-backend-type { 6 | net-backend-default, 7 | net-backend-halide, 8 | net-backend-openvino, 9 | net-backend-opencv, 10 | net-backend-vkcom, 11 | net-backend-cuda, 12 | } 13 | 14 | enum net-target-type { 15 | net-target-cpu, 16 | net-target-fp32, 17 | net-target-fp16, 18 | net-target-vpu, 19 | net-target-vulkan, 20 | net-target-fpga, 21 | net-target-cuda, 22 | net-target-cuda-fp16, 23 | } 24 | 25 | resource layer { 26 | constructor(); 27 | 28 | /// Close the layer 29 | close: func(); 30 | 31 | /// GetName returns the name of the layer. 32 | get-name: func() -> result; 33 | } 34 | 35 | resource net { 36 | /// ReadNet read deep learning network represented in one of the supported formats. 37 | /// 38 | /// For further details, please see: 39 | /// https://docs.opencv.org/4.x/d6/d0f/group__dnn.html#ga138439da76f26266fdefec9723f6c5cd 40 | read: static func(model: string, config: string) -> result; 41 | 42 | /// ReadNetFromONNX reads a network model stored in ONNX framework's format. 43 | /// 44 | /// For further details, please see: 45 | /// https://docs.opencv.org/4.x/d6/d0f/group__dnn.html#ga9198ecaac7c32ddf0aa7a1bcbd359567 46 | read-from-ONNX: static func(model: string) -> result; 47 | 48 | /// Close the network 49 | close: func(); 50 | 51 | /// Empty returns true if there are no layers in the network. 52 | /// 53 | /// For further details, please see: 54 | /// https://docs.opencv.org/master/db/d30/classcv_1_1dnn_1_1Net.html#a6a5778787d5b8770deab5eda6968e66c 55 | empty: func() -> bool; 56 | 57 | /// SetInput sets the new input value for the network. 58 | /// 59 | /// For further details, please see: 60 | /// https://docs.opencv.org/trunk/db/d30/classcv_1_1dnn_1_1Net.html#a672a08ae76444d75d05d7bfea3e4a328 61 | set-input: func(input: mat, name: string) -> result<_, error-result>; 62 | 63 | /// Forward runs forward pass to compute output of layer with name outputName. 64 | /// 65 | /// For further details, please see: 66 | /// https://docs.opencv.org/trunk/db/d30/classcv_1_1dnn_1_1Net.html#a98ed94cb6ef7063d3697259566da310b 67 | forward: func(output-name: string) -> result; 68 | 69 | // ForwardLayers forward pass to compute outputs of layers listed in outBlobNames. 70 | // 71 | // For further details, please see: 72 | // https://docs.opencv.org/4.x/db/d30/classcv_1_1dnn_1_1Net.html#afe22e099b60a2883e220645391f68d4c 73 | forward-layers: func(output-names: list) -> result, error-result>; 74 | 75 | /// GetUnconnectedOutLayers returns indexes of layers with unconnected outputs. 76 | /// 77 | /// For further details, please see: 78 | /// https://docs.opencv.org/4.x/db/d30/classcv_1_1dnn_1_1Net.html#ae26f0c29b3733d15d0482098ef9053e3 79 | get-unconnected-out-layers: func() -> result, error-result>; 80 | 81 | /// GetLayerNames returns names of layers in the network. 82 | /// 83 | /// For further details, please see: 84 | /// hhttps://docs.opencv.org/4.x/db/d30/classcv_1_1dnn_1_1Net.html#a38e67098ae4ae5906bf8d8ea72199c2e 85 | get-layer-names: func() -> result, error-result>; 86 | 87 | /// GetLayer returns layer with specified id. 88 | /// 89 | /// For further details, please see: 90 | /// https://docs.opencv.org/4.x/db/d30/classcv_1_1dnn_1_1Net.html#ac944d7f2d3ead5ef9b1b2fa3885f3ff1 91 | get-layer: func(id: u32) -> result; 92 | } 93 | 94 | /// BlobFromImage creates 4-dimensional blob from image. Optionally resizes and crops image from center, 95 | /// subtract mean values, scales values by scalefactor, swap Blue and Red channels. 96 | /// 97 | /// For further details, please see: 98 | /// https://docs.opencv.org/4.x/d6/d0f/group__dnn.html#ga29f34df9376379a603acd8df581ac8d7 99 | blob-from-image: func(image: mat, scale-factor: f32, size: size, mean: scalar, swap-rb: bool, crop: bool) -> result; 100 | 101 | /// BlobFromImageWithParams creates 4-dimensional blob from image. Optionally resizes and crops image from center, 102 | /// subtract mean values, scales values by scalefactor, swap Blue and Red channels. 103 | /// 104 | /// For further details, please see: 105 | /// https://docs.opencv.org/4.x/d6/d0f/group__dnn.html#ga29f34df9376379a603acd8df581ac8d7 106 | blob-from-image-with-params: func(image: mat, params: blob-params) -> result; 107 | 108 | /// BlobRectsToImageRects converts blob rects to image rects. 109 | /// 110 | /// For further details, please see: 111 | /// https://docs.opencv.org/4.4.0/d6/d0f/group__dnn.html#ga9d118d70a1659af729d01b10233213ee 112 | blob-rects-to-image-rects: func(params: blob-params, blob-rects: list, image-size: size) -> result, error-result>; 113 | 114 | /// NMSBoxes performs non maximum suppression given boxes and corresponding scores. 115 | /// 116 | /// For futher details, please see: 117 | /// https://docs.opencv.org/4.4.0/d6/d0f/group__dnn.html#ga9d118d70a1659af729d01b10233213ee 118 | NMS-boxes: func(bboxes: list, scores: list, score-threshold: f32, nms-threshold: f32) -> result, error-result>; 119 | } 120 | -------------------------------------------------------------------------------- /wit/features2d.wit: -------------------------------------------------------------------------------- 1 | interface features2d { 2 | use mat.{mat}; 3 | use types.{error-result, key-point, d-match}; 4 | 5 | /// detector-result returns the keypoints and descripts for a detector. 6 | record detector-result { 7 | kps: list, 8 | desc: mat, 9 | } 10 | 11 | /// AKAZE-detector is a wrapper around the cv::AKAZE algorithm. 12 | resource AKAZE-detector { 13 | /// Returns a new akaze-detector. 14 | /// 15 | /// For further details, please see: 16 | /// https://docs.opencv.org/4.x/d8/d30/classcv_1_1AKAZE.html 17 | constructor(name: string); 18 | 19 | /// Close the akaze-detector 20 | close: func(); 21 | 22 | /// Detect keypoints in an image using AKAZE. 23 | /// 24 | /// For further details, please see: 25 | /// https://docs.opencv.org/4.x/d0/d13/classcv_1_1Feature2D.html#aa4e9a7082ec61ebc108806704fbd7887 26 | detect: func(src: mat) -> result, error-result>; 27 | 28 | /// Compute keypoints in an image using AKAZE. 29 | /// 30 | /// For further details, please see: 31 | /// https://docs.opencv.org/4.x/d0/d13/classcv_1_1Feature2D.html#ab3cce8d56f4fc5e1d530b5931e1e8dc0 32 | compute: func(src: mat, mask: mat, kps: list) -> result; 33 | 34 | /// DetectAndCompute keypoints and compute in an image using AKAZE. 35 | /// 36 | /// For further details, please see: 37 | /// https://docs.opencv.org/4.x/d0/d13/classcv_1_1Feature2D.html#a8be0d1c20b08eb867184b8d74c15a677 38 | detect-and-compute: func(src: mat, mask: mat) -> result; 39 | } 40 | 41 | /// BRISK-detector is a wrapper around the cv::BRISK algorithm. 42 | resource BRISK-detector { 43 | /// Returns a new BRISK-detector. 44 | /// 45 | /// For further details, please see: 46 | /// https://docs.opencv.org/4.x/de/dbf/classcv_1_1BRISK.html 47 | constructor(name: string); 48 | 49 | /// Close the BRISK-detector 50 | close: func(); 51 | 52 | /// Detect keypoints in an image using BRISK. 53 | /// 54 | /// For further details, please see: 55 | /// https://docs.opencv.org/4.x/d0/d13/classcv_1_1Feature2D.html#aa4e9a7082ec61ebc108806704fbd7887 56 | detect: func(src: mat) -> result, error-result>; 57 | 58 | /// Compute keypoints in an image using BRISK. 59 | /// 60 | /// For further details, please see: 61 | /// https://docs.opencv.org/4.x/d0/d13/classcv_1_1Feature2D.html#ab3cce8d56f4fc5e1d530b5931e1e8dc0 62 | compute: func(src: mat, mask: mat, kps: list) -> result; 63 | 64 | /// DetectAndCompute keypoints and compute in an image using BRISK. 65 | /// 66 | /// For further details, please see: 67 | /// https://docs.opencv.org/4.x/d0/d13/classcv_1_1Feature2D.html#a8be0d1c20b08eb867184b8d74c15a677 68 | detect-and-compute: func(src: mat, mask: mat) -> result; 69 | } 70 | 71 | /// KAZE-detector is a wrapper around the cv::KAZE algorithm. 72 | resource KAZE-detector { 73 | /// Returns a new KAZE-detector. 74 | /// 75 | /// For further details, please see: 76 | /// https://docs.opencv.org/4.x/d3/d61/classcv_1_1KAZE.html 77 | constructor(name: string); 78 | 79 | /// Close the KAZE-detector 80 | close: func(); 81 | 82 | /// Detect keypoints in an image using KAZE. 83 | /// 84 | /// For further details, please see: 85 | /// https://docs.opencv.org/4.x/d0/d13/classcv_1_1Feature2D.html#aa4e9a7082ec61ebc108806704fbd7887 86 | detect: func(src: mat) -> result, error-result>; 87 | 88 | /// Compute keypoints in an image using KAZE. 89 | /// 90 | /// For further details, please see: 91 | /// https://docs.opencv.org/4.x/d0/d13/classcv_1_1Feature2D.html#ab3cce8d56f4fc5e1d530b5931e1e8dc0 92 | compute: func(src: mat, mask: mat, kps: list) -> result; 93 | 94 | /// DetectAndCompute keypoints and compute in an image using KAZE. 95 | /// 96 | /// For further details, please see: 97 | /// https://docs.opencv.org/4.x/d0/d13/classcv_1_1Feature2D.html#a8be0d1c20b08eb867184b8d74c15a677 98 | detect-and-compute: func(src: mat, mask: mat) -> result; 99 | } 100 | 101 | enum ORB-score-type { 102 | ORB-HARRIS, 103 | ORB-FAST, 104 | } 105 | 106 | /// ORB-detector is a wrapper around the cv::ORB algorithm. 107 | resource ORB-detector { 108 | /// Returns a new ORB-detector. 109 | /// 110 | /// For further details, please see: 111 | /// https://docs.opencv.org/4.x/db/d95/classcv_1_1ORB.html 112 | constructor(name: string); 113 | 114 | /// Returns a new ORB-detector. 115 | /// 116 | /// For further details, please see: 117 | /// https://docs.opencv.org/4.x/db/d95/classcv_1_1ORB.html 118 | new-with-params: static func(features: u32, scale: f32, levels: u32, edge-threshold: u32, first: u32, WTAK: u32, score-type: ORB-score-type, patch-size: u32, fast-threshold: u32) -> ORB-detector; 119 | 120 | /// Close the ORB-detector 121 | close: func(); 122 | 123 | /// Detect keypoints in an image using ORB. 124 | /// 125 | /// For further details, please see: 126 | /// https://docs.opencv.org/4.x/d0/d13/classcv_1_1Feature2D.html#aa4e9a7082ec61ebc108806704fbd7887 127 | detect: func(src: mat) -> result, error-result>; 128 | 129 | /// Compute keypoints in an image using ORB. 130 | /// 131 | /// For further details, please see: 132 | /// https://docs.opencv.org/4.x/d0/d13/classcv_1_1Feature2D.html#ab3cce8d56f4fc5e1d530b5931e1e8dc0 133 | compute: func(src: mat, mask: mat, kps: list) -> result; 134 | 135 | /// DetectAndCompute keypoints and compute in an image using ORB. 136 | /// 137 | /// For further details, please see: 138 | /// https://docs.opencv.org/4.x/d0/d13/classcv_1_1Feature2D.html#a8be0d1c20b08eb867184b8d74c15a677 139 | detect-and-compute: func(src: mat, mask: mat) -> result; 140 | } 141 | 142 | /// SIFT-detector is a wrapper around the cv::SIFT algorithm. 143 | resource SIFT-detector { 144 | /// Returns a new SIFT-detector. 145 | /// 146 | /// For further details, please see: 147 | /// https://docs.opencv.org/4.x/d7/d60/classcv_1_1SIFT.html 148 | constructor(name: string); 149 | 150 | /// Close the SIFT-detector 151 | close: func(); 152 | 153 | /// Detect keypoints in an image using SIFT. 154 | /// 155 | /// For further details, please see: 156 | /// https://docs.opencv.org/4.x/d0/d13/classcv_1_1Feature2D.html#aa4e9a7082ec61ebc108806704fbd7887 157 | detect: func(src: mat) -> result, error-result>; 158 | 159 | /// Compute keypoints in an image using SIFT. 160 | /// 161 | /// For further details, please see: 162 | /// https://docs.opencv.org/4.x/d0/d13/classcv_1_1Feature2D.html#ab3cce8d56f4fc5e1d530b5931e1e8dc0 163 | compute: func(src: mat, mask: mat, kps: list) -> result; 164 | 165 | /// DetectAndCompute keypoints and compute in an image using SIFT. 166 | /// 167 | /// For further details, please see: 168 | /// https://docs.opencv.org/4.x/d0/d13/classcv_1_1Feature2D.html#a8be0d1c20b08eb867184b8d74c15a677 169 | detect-and-compute: func(src: mat, mask: mat) -> result; 170 | } 171 | 172 | enum norm-type { 173 | NORM-NONE, 174 | NONE-INF, 175 | NORM-L1, 176 | NORM-NONE2, 177 | NORM-L2, 178 | NORM-L2SQR, 179 | NORM-HAMMING, 180 | NORM-HAMMING2, 181 | NORM-RELATIVE, 182 | } 183 | 184 | /// BF-matcher is a wrapper around the cv::BFMatcher algorithm. 185 | resource BF-matcher { 186 | /// Returns a new BF-matcher. 187 | /// 188 | /// For further details, please see: 189 | /// https://docs.opencv.org/4.x/d3/da1/classcv_1_1BFMatcher.html#abe0bb11749b30d97f60d6ade665617bd 190 | constructor(name: string); 191 | 192 | /// Returns a new BF-matcher. 193 | /// 194 | /// For further details, please see: 195 | /// https://docs.opencv.org/4.x/d3/da1/classcv_1_1BFMatcher.html#abe0bb11749b30d97f60d6ade665617bd 196 | new-with-params: static func(norm: norm-type, cross-check: bool) -> BF-matcher; 197 | 198 | /// Close the BF-matcher 199 | close: func(); 200 | 201 | /// Match Finds the best match for each descriptor from a query set. 202 | /// 203 | /// For further details, please see: 204 | /// https://docs.opencv.org/4.x/db/d39/classcv_1_1DescriptorMatcher.html#a0f046f47b68ec7074391e1e85c750cba 205 | match: func(query: mat, train: mat) -> result, error-result>; 206 | 207 | /// KNNMatch finds the k best matches for each descriptor from a query set. 208 | /// 209 | /// For further details, please see: 210 | /// https://docs.opencv.org/4.x/db/d39/classcv_1_1DescriptorMatcher.html#aa880f9353cdf185ccf3013e08210483a 211 | KNN-match: func(query: mat, train: mat, k: u32) -> result>, error-result>; 212 | } 213 | 214 | /// Flann-based-matcher is a wrapper around the cv::BFMatcher algorithm. 215 | resource flann-based-matcher { 216 | /// Returns a new flann-based-matcher. 217 | /// 218 | /// For further details, please see: 219 | /// https://docs.opencv.org/4.x/dc/de2/classcv_1_1FlannBasedMatcher.html#ab9114a6471e364ad221f89068ca21382 220 | constructor(name: string); 221 | 222 | /// Close the flann-based-matcher 223 | close: func(); 224 | 225 | /// KNNMatch finds the k best matches for each descriptor from a query set. 226 | /// 227 | /// For further details, please see: 228 | /// https://docs.opencv.org/4.x/db/d39/classcv_1_1DescriptorMatcher.html#aa880f9353cdf185ccf3013e08210483a 229 | KNN-match: func(query: mat, train: mat, k: u32) -> result>, error-result>; 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /wit/mat.wit: -------------------------------------------------------------------------------- 1 | /// mat resource is a matrix of bytes, wrapper around the cv::Mat type. 2 | /// 3 | interface mat { 4 | use types.{error-result, mix-max-loc-result, rect}; 5 | 6 | enum mattype { 7 | cv8u, 8 | cv8s, 9 | cv16u, 10 | cv16s, 11 | cv32s, 12 | cv32f, 13 | cv64f, 14 | } 15 | 16 | resource mat { 17 | /// Create a new Mat. id does not currently do anything. 18 | constructor(id: u32); 19 | 20 | /// Create a new Mat with the specified size and type. 21 | new-with-size: static func(cols: u32, rows: u32, mattype: mattype) -> mat; 22 | 23 | /// Clone returns a cloned full copy of the Mat. 24 | clone: func() -> mat; 25 | 26 | /// Close the Mat 27 | close: func(); 28 | 29 | /// Cols returns the number of columns for this Mat. 30 | cols: func() -> u32; 31 | 32 | /// Rows returns the number of rows for this Mat. 33 | rows: func() -> u32; 34 | 35 | /// Region returns a new Mat that points to a region of this Mat. Changes made to the 36 | /// region Mat will affect the original Mat, since they are pointers to the underlying 37 | /// OpenCV Mat object. 38 | region: func(rect: rect) -> mat; 39 | 40 | /// CopyTo copies Mat into destination Mat. 41 | copy-to: func(dst: borrow); 42 | 43 | /// ConvertTo converts Mat into destination Mat. 44 | /// 45 | /// For further details, please see: 46 | /// https://docs.opencv.org/4.x/d3/d63/classcv_1_1Mat.html#adf88c60c5b4980e05bb556080916978b 47 | convert-to: func(mattype: mattype) -> result; 48 | 49 | /// ConvertToWithParams converts Mat into destination Mat using additional params. 50 | /// 51 | /// For further details, please see: 52 | /// https://docs.opencv.org/4.x/d3/d63/classcv_1_1Mat.html#adf88c60c5b4980e05bb556080916978b 53 | convert-to-with-params: func(mattype: mattype, alpha: f32, beta: f32) -> result; 54 | 55 | /// MatType returns the type of the Mat. 56 | mattype: func() -> mattype; 57 | 58 | /// Size returns an array with one element for each dimension containing the size of that dimension for the Mat. 59 | size: func() -> list; 60 | 61 | /// Step returns the number of bytes each matrix row occupies. 62 | step: func() -> u32; 63 | 64 | /// ElemSize returns the matrix element size in bytes. 65 | elemsize: func() -> u32; 66 | 67 | /// Empty returns true if the Mat is empty. 68 | empty: func() -> bool; 69 | 70 | /// GetFloatAt returns the value at the specified row and column as a f32. 71 | get-float-at: func(row: u32, col: u32) -> f32; 72 | 73 | /// SetFloatAt sets the value at the specified row and column as a f32. 74 | set-float-at: func(row: u32, col: u32, val: f32); 75 | 76 | /// GetUCharAt returns the value at the specified row and column as a u8. 77 | get-uchar-at: func(row: u32, col: u32) -> u8; 78 | 79 | /// SetUCharAt sets the value at the specified row and column as a u8. 80 | set-uchar-at: func(row: u32, col: u32, val: u8); 81 | 82 | /// GetIntAt returns the value at the specified row and column as a s32. 83 | get-int-at: func(row: u32, col: u32) -> s32; 84 | 85 | /// SetIntAt sets the value at the specified row and column as a s32. 86 | set-int-at: func(row: u32, col: u32, val: s32); 87 | 88 | /// GetFloatAt3 returns the value at the specified x, y, z as a f32. 89 | get-float-at3: func(x: u32, y: u32, z: u32) -> f32; 90 | 91 | /// SetFloatAt3 sets the value at the specified x, y, z as a f32. 92 | set-float-at3: func(x: u32, y: u32, z: u32, val: f32); 93 | 94 | /// GetUCharAt3 returns the value at the specified x, y, z as a u8. 95 | get-uchar-at3: func(x: u32, y: u32, z: u32) -> u8; 96 | 97 | /// SetUCharAt3 sets the value at the specified x, y, z as a u8. 98 | set-uchar-at3: func(x: u32, y: u32, z: u32, val: u8); 99 | 100 | /// GetIntAt3 returns the value at the specified x, y, z as a s32. 101 | get-int-at3: func(x: u32, y: u32, z: u32) -> s32; 102 | 103 | /// SetIntAt3 sets the value at the specified x, y, z as a s32. 104 | set-int-at3: func(x: u32, y: u32, z: u32, val: s32); 105 | 106 | /// GetVecbAt returns a vector of bytes. Its size corresponds to the number of channels of the Mat. 107 | get-vecb-at: func(row: u32, col: u32) -> list; 108 | 109 | /// GetVecfAt returns a vector of floats. Its size corresponds to the number of channels of the Mat. 110 | get-vecf-at: func(row: u32, col: u32) -> list; 111 | 112 | /// GetVeciAt returns a vector of s32. Its size corresponds to the number of channels of the Mat. 113 | get-veci-at: func(row: u32, col: u32) -> list; 114 | 115 | /// AddUChar adds a u8 value to each element in the Mat. Performs addition in place. 116 | add-uchar: func(val: u8); 117 | 118 | /// SubtractUChar subtracts a u8 value from each element in the Mat. Performs subtraction in place. 119 | subtract-uchar: func(val: u8); 120 | 121 | /// MultiplyUChar multiplies each element in the Mat by a u8 value. Performs multiplication in place. 122 | multiply-uchar: func(val: u8); 123 | 124 | /// DivideUChar divides each element in the Mat by a u8 value. Performs division in place. 125 | divide-uchar: func(val: u8); 126 | 127 | /// AddFloat adds a float value to each element in the Mat. Performs addition in place. 128 | add-float: func(val: f32); 129 | 130 | /// SubtractFloat subtracts a float value from each element in the Mat. Performs subtraction in place. 131 | subtract-float: func(val: f32); 132 | 133 | /// MultiplyFloat multiplies each element in the Mat by a float value. Performs multiplication in place. 134 | multiply-float: func(val: f32); 135 | 136 | /// DivideFloat divides each element in the Mat by a float value. Performs division in place. 137 | divide-float: func(val: f32); 138 | 139 | /// Reshape changes the shape and/or the number of channels of a 2D matrix without copying the data. 140 | /// 141 | /// For further details, please see: 142 | /// https://docs.opencv.org/4.x/d3/d63/classcv_1_1Mat.html#a4eb96e3251417fa88b78e2abd6cfd7d8 143 | reshape: func(channels: u32, rows: u32) -> result; 144 | 145 | /// RowRange creates a matrix header for the specified row span. 146 | /// 147 | /// For further details, please see: 148 | /// https://docs.opencv.org/4.x/d3/d63/classcv_1_1Mat.html#aa6542193430356ad631a9beabc624107 149 | row-range: func(start: u32, end: u32) -> result; 150 | 151 | /// ColRange creates a matrix header for the specified column span. 152 | /// 153 | /// For further details, please see: 154 | /// https://docs.opencv.org/4.x/d3/d63/classcv_1_1Mat.html#aadc8f9210fe4dec50513746c246fa8d9 155 | col-range: func(start: u32, end: u32) -> result; 156 | 157 | /// MinMaxLoc finds the global minimum and maximum in an array. 158 | /// 159 | /// For further details, please see: 160 | /// https://docs.opencv.org/trunk/d2/de8/group__core__array.html#gab473bf2eb6d14ff97e89b355dac20707 161 | min-max-loc: func() -> result; 162 | 163 | /// col creates a matrix header for the specified matrix column. 164 | /// The underlying data of the new matrix is shared with the original matrix. 165 | col: func(col: u32) -> result; 166 | 167 | /// row creates a matrix header for the specified matrix row. 168 | /// The underlying data of the new matrix is shared with the original matrix. 169 | row: func(row: u32) -> result; 170 | 171 | /// Merge creates one multi-channel array out of several single-channel ones. 172 | /// 173 | /// For further details, please see: 174 | /// https://docs.opencv.org/4.x/d2/de8/group__core__array.html#ga7d7b4d6c6ee504b30a20b1680029c7b4 175 | merge: static func(mv: list) -> result; 176 | 177 | /// zeros returns a zero array of the specified size and type. 178 | zeros: static func(cols: u32, rows: u32, mattype: mattype) -> result; 179 | 180 | /// ones returns an array of the specified size and type populated with 1. 181 | /// 182 | /// For further details, please see: 183 | /// https://docs.opencv.org/4.x/d3/d63/classcv_1_1Mat.html#a5e10227b777425407986727e2d26fcdc 184 | ones: static func(cols: u32, rows: u32, mattype: mattype) -> result; 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /wit/objdetect.wit: -------------------------------------------------------------------------------- 1 | interface objdetect { 2 | use mat.{mat}; 3 | use types.{error-result, size, rect}; 4 | 5 | /// CascadeClassifier is a cascade classifier class for object detection. 6 | resource cascade-classifier { 7 | /// NewCascadeClassifier returns a new CascadeClassifier. 8 | /// 9 | /// For further details, please see: 10 | /// https://docs.opencv.org/4.x/df/d20/classcv_1_1FaceDetectorYN.html#a5f7fb43c60c95ca5ebab78483de02516 11 | constructor(name: string); 12 | 13 | /// Close the CascadeClassifier 14 | close: func(); 15 | 16 | /// Load cascade classifier from a file. 17 | /// 18 | /// For further details, please see: 19 | /// http://docs.opencv.org/master/d1/de5/classcv_1_1CascadeClassifier.html#a1a5884c8cc749422f9eb77c2471958bc 20 | load: func(file: string) -> bool; 21 | 22 | /// DetectMultiScale detects objects of different sizes in the input Mat image. 23 | /// The detected objects are returned as a slice of image.Rectangle structs. 24 | /// 25 | /// For further details, please see: 26 | /// http://docs.opencv.org/master/d1/de5/classcv_1_1CascadeClassifier.html#aaf8181cb63968136476ec4204ffca498 27 | detect-multi-scale: func(image: mat) -> result, error-result>; 28 | 29 | /// DetectMultiScaleWithParams detects objects of different sizes in the input Mat image. 30 | /// The detected objects are returned as a slice of image.Rectangle structs. 31 | /// 32 | /// For further details, please see: 33 | /// http://docs.opencv.org/master/d1/de5/classcv_1_1CascadeClassifier.html#aaf8181cb63968136476ec4204ffca498 34 | detect-multi-scale-with-params: func(image: mat, scale: f64, min-neighbors: u32, %flags: u32, min-size: size, max-size: size) -> result, error-result>; 35 | } 36 | 37 | /// HOGDescriptor is a Histogram Of Gradiants (HOG) for object detection. 38 | /// 39 | /// For further details, please see: 40 | /// https://docs.opencv.org/master/d5/d33/structcv_1_1HOGDescriptor.html#a723b95b709cfd3f95cf9e616de988fc8 41 | resource HOG-descriptor { 42 | /// NewHOGDescriptor returns a new HOGDescriptor. 43 | constructor(name: string); 44 | 45 | /// Close the HOGDescriptor 46 | close: func(); 47 | 48 | /// DetectMultiScale detects objects of different sizes in the input Mat image. 49 | /// The detected objects are returned as a slice of image.Rectangle structs. 50 | /// 51 | /// For further details, please see: 52 | /// https://docs.opencv.org/master/d5/d33/structcv_1_1HOGDescriptor.html#a660e5cd036fd5ddf0f5767b352acd948 53 | detect-multi-scale: func(image: mat) -> result, error-result>; 54 | 55 | /// DetectMultiScaleWithParams detects objects of different sizes in the input Mat image. 56 | /// The detected objects are returned as a slice of image.Rectangle structs. 57 | /// 58 | /// For further details, please see: 59 | /// https://docs.opencv.org/master/d5/d33/structcv_1_1HOGDescriptor.html#a660e5cd036fd5ddf0f5767b352acd948 60 | detect-multi-scale-with-params: func(image: mat, hit-threshold: f64, win-stride: size, padding: size, scale: f64, final-threshold: f64, use-meanshift-grouping: bool) -> result, error-result>; 61 | } 62 | 63 | resource face-detector-YN { 64 | /// Creates an instance of face detector YN with given parameters. 65 | /// 66 | /// For further details, please see: 67 | /// https://docs.opencv.org/4.x/df/d20/classcv_1_1FaceDetectorYN.html#a5f7fb43c60c95ca5ebab78483de02516 68 | constructor(model: string, config: string, input-size: size); 69 | 70 | /// Creates an instance of face detector YN with given parameters. 71 | /// 72 | /// For further details, please see: 73 | /// https://docs.opencv.org/4.x/df/d20/classcv_1_1FaceDetectorYN.html#a5f7fb43c60c95ca5ebab78483de02516 74 | new-with-params: static func(model: string, config: string, input-size: size, score-threshold: f32, nms-threshold: f32, top-k: u32, backend-id: u32, target-id: u32) -> face-detector-YN; 75 | 76 | /// Close the face detector 77 | close: func(); 78 | 79 | /// Detects faces in the input image. 80 | /// 81 | /// For further details, please see: 82 | /// https://docs.opencv.org/4.x/df/d20/classcv_1_1FaceDetectorYN.html#ac05bd075ca3e6edc0e328927aae6f45b 83 | detect: func(input: mat) -> result; 84 | 85 | get-input-size: func() -> size; 86 | get-nms-threshold: func() -> f32; 87 | get-score-threshold: func() -> f32; 88 | get-topk: func() -> u32; 89 | 90 | set-input-size: func(size: size); 91 | set-nms-threshold: func(threshold: f32); 92 | set-score-threshold: func(threshold: f32); 93 | set-topk: func(topk: u32); 94 | } 95 | 96 | enum face-distance-type { 97 | face-distance-type-cosine, 98 | face-distance-norm-l2, 99 | } 100 | 101 | resource face-recognizer-SF { 102 | /// Creates an instance of FaceRecognizerSF with given parameters. 103 | /// 104 | /// For further details, please see: 105 | /// https://docs.opencv.org/4.x/da/d09/classcv_1_1FaceRecognizerSF.html#a04df90b0cd7d26d350acd92621a35743 106 | constructor(model: string, config: string); 107 | 108 | /// Creates an instance of FaceRecognizerSF with given parameters. 109 | /// 110 | /// For further details, please see: 111 | /// https://docs.opencv.org/4.x/da/d09/classcv_1_1FaceRecognizerSF.html#a04df90b0cd7d26d350acd92621a35743 112 | new-with-params: static func(model: string, config: string, backend-id: u32, target-id: u32) -> face-recognizer-SF; 113 | 114 | /// Close the face FaceRecognizerSF 115 | close: func(); 116 | 117 | /// Aligns detected face with the source input image and crops it. 118 | /// 119 | /// For further details, please see: 120 | /// https://docs.opencv.org/4.x/da/d09/classcv_1_1FaceRecognizerSF.html#a84492908abecbc9362b4ddc8d46b8345 121 | align-crop: func(src: mat, face-box: mat) -> result; 122 | 123 | /// Feature extracts face feature from aligned image. 124 | /// 125 | /// For further details, please see: 126 | /// https://docs.opencv.org/4.x/da/d09/classcv_1_1FaceRecognizerSF.html#ab1b4a3c12213e89091a490c573dc5aba 127 | feature: func(aligned: mat) -> result; 128 | 129 | /// Match calculates the distance between two face features. 130 | /// 131 | /// For further details, please see: 132 | /// https://docs.opencv.org/4.x/da/d09/classcv_1_1FaceRecognizerSF.html#a2f0362ca1e64320a1f3ba7e1386d0219 133 | match: func(face1: mat, face2: mat) -> result; 134 | 135 | /// Match calculates the distance between two face features. 136 | /// 137 | /// For further details, please see: 138 | /// https://docs.opencv.org/4.x/da/d09/classcv_1_1FaceRecognizerSF.html#a2f0362ca1e64320a1f3ba7e1386d0219 139 | match-with-params: func(face1: mat, face2: mat, distance: face-distance-type) -> result; 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /wit/request.wit: -------------------------------------------------------------------------------- 1 | /// request resource is a request from host for guest module to process an image. 2 | /// 3 | interface request { 4 | use mat.{mat}; 5 | 6 | process: func(image: mat) -> mat; 7 | } 8 | -------------------------------------------------------------------------------- /wit/types.wit: -------------------------------------------------------------------------------- 1 | interface types { 2 | type error-result = string; 3 | 4 | /// size is a 2-element integer vector. 5 | /// It represents a width and height. 6 | record size { 7 | x: s32, 8 | y: s32, 9 | } 10 | 11 | /// point is a 2-element integer vector. 12 | /// It represents a x and y coordinate. 13 | type point = size; 14 | 15 | /// scalar is a 4-element floating point vector. 16 | record scalar { 17 | val1: f32, 18 | val2: f32, 19 | val3: f32, 20 | val4: f32, 21 | } 22 | 23 | /// rect is a rectangle with integer coordinates. 24 | /// It is represented by the top-left corner and the bottom-right corner. 25 | record rect { 26 | min: size, 27 | max: size, 28 | } 29 | 30 | /// RGBA is a color with red, green, blue, and alpha channels. 31 | record RGBA { 32 | r: u8, 33 | g: u8, 34 | b: u8, 35 | a: u8, 36 | } 37 | 38 | /// border-type is a type of border to add to an image. 39 | enum border-type { 40 | border-constant, 41 | border-replicate, 42 | border-reflect, 43 | border-wrap, 44 | border-reflect101, 45 | border-transparent, 46 | border-default, 47 | border-isolated, 48 | } 49 | 50 | /// adaptive-threshold-type is a type of adaptive thresholding. 51 | enum adaptive-threshold-type { 52 | adaptive-threshold-mean, 53 | adaptive-threshold-gaussian, 54 | } 55 | 56 | /// threshold-type is a type of thresholding. 57 | enum threshold-type { 58 | threshold-binary, 59 | threshold-binary-inv, 60 | threshold-trunc, 61 | threshold-to-zero, 62 | threshold-to-zero-inv, 63 | threshold-mask, 64 | threshold-otsu, 65 | tthreshold-triangle, 66 | } 67 | 68 | /// data-layout-type is a type of data layout. 69 | enum data-layout-type { 70 | data-layout-unknown, 71 | data-layout-nd, 72 | data-layout-nchw, 73 | data-layout-ncdhw, 74 | data-layout-nhwc, 75 | data-layout-ndhwc, 76 | data-layout-planar, 77 | } 78 | 79 | enum padding-mode-type { 80 | padding-mode-null, 81 | padding-mode-crop-center, 82 | padding-mode-letterbox, 83 | } 84 | 85 | record blob-params { 86 | scale-factor: f32, 87 | size: size, 88 | mean: scalar, 89 | swap-RB: bool, 90 | ddepth: u8, 91 | data-layout: data-layout-type, 92 | padding-mode: padding-mode-type, 93 | border: scalar, 94 | } 95 | 96 | record mix-max-loc-result { 97 | min-val: f32, 98 | max-val: f32, 99 | min-loc: size, 100 | max-loc: size, 101 | } 102 | 103 | enum hershey-font-type { 104 | hershey-font-simplex, 105 | hershey-font-plain, 106 | hershey-font-duplex, 107 | hershey-font-complex, 108 | hershey-font-triplex, 109 | hershey-font-complex-small, 110 | hershey-font-script-simplex, 111 | hershey-font-script-complex, 112 | hershey-font-italic, 113 | } 114 | 115 | enum interpolation-type { 116 | interpolation-nearest, 117 | interpolation-linear, 118 | interpolation-cubic, 119 | interpolation-area, 120 | interpolation-lanczos4, 121 | } 122 | 123 | enum color-coversion-type { 124 | color-BGR-to-BGRA, 125 | color-RGB-to-RGBA, 126 | color-BGRA-to-BGR, 127 | color-RGBA-to-RGB, 128 | color-BGR-to-RGBA, 129 | color-RGB-to-BGRA, 130 | color-RGBA-to-BGR, 131 | color-BGRA-to-RGB, 132 | color-BGR-to-RGB, 133 | color-RGB-to-BGR, 134 | color-BGRA-to-RGBA, 135 | color-RGBA-to-BGRA, 136 | color-BGR-to-gray, 137 | color-RGB-to-gray, 138 | color-gray-to-BGR, 139 | color-gray-to-RGB, 140 | color-gray-to-BGRA, 141 | color-gray-to-RGBA, 142 | color-BGRA-to-gray, 143 | color-RGBA-to-gray, 144 | } 145 | 146 | enum morph-shape { 147 | morph-rect, 148 | morph-cross, 149 | morph-ellipse, 150 | } 151 | 152 | record key-point { 153 | x: f32, 154 | y: f32, 155 | size: f32, 156 | angle: f32, 157 | response: f32, 158 | octave: s32, 159 | class-id: s32, 160 | } 161 | 162 | /// DMatch is data structure for matching keypoint descriptors. 163 | /// 164 | /// For further details, please see: 165 | /// https://docs.opencv.org/4.x/d4/de0/classcv_1_1DMatch.html#a546ddb9a87898f06e510e015a6de596e 166 | record d-match { 167 | query-idx: u32, 168 | train-idx: u32, 169 | img-idx: u32, 170 | distance: f64, 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /wit/world.wit: -------------------------------------------------------------------------------- 1 | package wasm:cv; 2 | /// wasmCV is a WebAssembly guest module interface for computer vision based on OpenCV. 3 | /// 4 | world imports { 5 | import types; 6 | import mat; 7 | 8 | import cv; 9 | import dnn; 10 | import objdetect; 11 | import features2d; 12 | 13 | export request; 14 | } 15 | --------------------------------------------------------------------------------