diff --git a/README.md b/README.md index a2bb371c..610ef555 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ These online demos run entirely in your browser: object recognition. - [whisper](https://huggingface.co/spaces/lmz/candle-whisper): text to speech. - [LLaMA2](https://huggingface.co/spaces/lmz/candle-llama2): text generation. +- [Segment Anything Model](https://huggingface.co/spaces/radames/candle-segment-anything-wasm): Image segmentation. We also provide a some command line based examples using state of the art models: @@ -96,7 +97,8 @@ There are also some wasm examples for whisper and [llama2.c](https://github.com/karpathy/llama2.c). You can either build them with `trunk` or try them online: [whisper](https://huggingface.co/spaces/lmz/candle-whisper), -[llama2](https://huggingface.co/spaces/lmz/candle-llama2). +[llama2](https://huggingface.co/spaces/lmz/candle-llama2), +[Segment Anything Model](https://huggingface.co/spaces/radames/candle-segment-anything-wasm). For LLaMA2, run the following command to retrieve the weight files and start a test server: diff --git a/candle-wasm-examples/segment-anything/Cargo.toml b/candle-wasm-examples/segment-anything/Cargo.toml index b67de112..a847424d 100644 --- a/candle-wasm-examples/segment-anything/Cargo.toml +++ b/candle-wasm-examples/segment-anything/Cargo.toml @@ -27,3 +27,4 @@ serde_json = { workspace = true } # Wasm specific crates. console_error_panic_hook = "0.1.7" wasm-bindgen = "0.2.87" +serde-wasm-bindgen = "0.6.0" diff --git a/candle-wasm-examples/segment-anything/samWorker.js b/candle-wasm-examples/segment-anything/samWorker.js index b90498de..c1a152ef 100644 --- a/candle-wasm-examples/segment-anything/samWorker.js +++ b/candle-wasm-examples/segment-anything/samWorker.js @@ -141,8 +141,7 @@ self.addEventListener("message", async (event) => { } self.postMessage({ status: "segmenting", message: "Segmenting" }); - const result = sam.mask_for_point(points.x, points.y); - const { mask, image } = JSON.parse(result); + const { mask, image } = sam.mask_for_point(points.x, points.y); const maskDataURL = await createImageCanvas(mask, image); // Send the segment back to the main thread as JSON self.postMessage({ diff --git a/candle-wasm-examples/segment-anything/src/bin/m.rs b/candle-wasm-examples/segment-anything/src/bin/m.rs index 949c18a0..5140b979 100644 --- a/candle-wasm-examples/segment-anything/src/bin/m.rs +++ b/candle-wasm-examples/segment-anything/src/bin/m.rs @@ -76,7 +76,7 @@ impl Model { } // x and y have to be between 0 and 1 - pub fn mask_for_point(&self, x: f64, y: f64) -> Result { + pub fn mask_for_point(&self, x: f64, y: f64) -> Result { if !(0. ..=1.).contains(&x) { Err(JsError::new(&format!( "x has to be between 0 and 1, got {x}" @@ -112,8 +112,7 @@ impl Model { width: embeddings.width, height: embeddings.height, }; - let json = serde_json::to_string(&MaskImage { mask, image })?; - Ok(json) + Ok(serde_wasm_bindgen::to_value(&MaskImage { mask, image })?) } }