Skip to content

Commit 3d9a8ca

Browse files
committed
Update docs for mode B!
Includes: * new performance numbers. Very exciting. Very cool. Ambient lighting helps! * deprecating the old 8-color mode ("mode 8C" under the new naming scheme). This simplifies things, and a newer, faster format is waiting in the wings... * misc updates based on what I've learned
1 parent 4c6c37c commit 3d9a8ca

File tree

6 files changed

+52
-26
lines changed

6 files changed

+52
-26
lines changed

DETAILS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ These properties may appear to be magical as you consider them more, and they do
8484
2. wirehair requires the file contents to be stored in RAM
8585
* this relates to the size limit!
8686

87-
This constraint is less of an obstacle than it may seem -- the fountain codes are essentially being used as a wire format, and the encoder and decoder could agree on a scheme to split up, and then reassemble, larger files. Cimbar does not (yet?) implement this, however!
87+
The size constraint is less of an obstacle than it may seem -- the fountain codes are essentially being used as a wire format, and the encoder and decoder could agree on a scheme to split up, and then reassemble, larger files. Cimbar does not (yet?) implement this, however!
8888

8989
## Implementation: Decoder
9090

PERFORMANCE.md

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,48 @@
44
## Numbers of note
55

66
* The barcode is `1024x1024` pixels. The individual tiles are `8x8` in a `9x9` grid (there is an empty row/column of spacing on either side)
7-
* **7500** or 8750 bytes per cimbar image, after error correction
7+
* **7500** bytes per cimbar image, after error correction
88
* There are 16 possible symbols per tile, encoding 4 bits
99
* There are 4 or 8 possible colors, encoding an additional 2-3 bits per tile.
10-
* These 6-7 bits per tile work out to a maximum of 9300-10850 bytes per barcode, though in practice this number is reduced by error correction.
10+
* These 6 bits per tile work out to a maximum of 9300 bytes per barcode, though in practice this number is reduced by error correction.
1111
* The default ecc setting is 30/155, which is how we go from 9300 -> 7500 bytes of real data for a 4-color cimbar image.
1212
* Reed Solomon is not perfect for this use case -- specifically, it corrects byte errors, and cimbar errors tend to involve 1-3 bits at a time. However, since Reed Solomon implementations are ubiquitous, it is currently in use.
1313

1414
## Current sustained benchmark
1515

16-
* 4-color cimbar with ecc=30:
16+
* `mode B` (8x8 4-color) cimbar with ecc=30/155:
17+
* 4,689,084 bytes (after compression) in 43s -> 872 kilobits/s (~109 KB/s)
18+
* mode B was introduced in 0.6.0, and should work in a wide variety of scenarios
19+
20+
* *legacy* `mode 4C` (8x8 4-color) cimbar with ecc=30/155:
1721
* 4,717,525 bytes (after compression) in 45s -> 838 kilobits/s (~104 KB/s)
22+
* the original configuration. Mostly replaced by mode B.
1823

19-
* 8-color cimbar with ecc=30:
24+
* *deprecated* `mode 8C` (8x8 8-color) cimbar with ecc=30/155:
2025
* 4,717,525 bytes in 40s -> 943 kilobits/s (~118 KB/s)
26+
* removed in 0.6.0. 8-color has always been inconsistent, and needs future research
27+
28+
* *beta* `mode S` (5x5 4-color) cimbar with ecc=40/216 (note: not finalized, and requires a special build)
29+
* safely >1 Mbit/s
30+
* format still a WIP. To be continued...
2131

2232
* details:
2333
* cimbar has built-in compression using zstd. What's being measured here is bits over the wire, e.g. data after compression is applied.
24-
* these numbers are using https://github.com/sz3/cfc, running with 4 CPU threads on a Qualcomm Snapdragon 625
25-
* perhaps I will buy a new cell phone to inflate the benchmark numbers.
26-
* the sender is the cimbar.org wasm implementation. An equivalent command line is `./cimbar_send /path/to/file -s`
34+
* these numbers are using https://github.com/sz3/cfc, running with 4 CPU threads on a venerable Qualcomm Snapdragon 625
35+
* more modern cell CPUs run the decoder more quickly, but it turns out that this does not benefit performance much: the camera is usually the bottleneck.
36+
* the sender is the cimbar.org wasm implementation. An equivalent command line is `./cimbar_send /path/to/file`
2737
* cimbar.org uses the `shakycam` option to allow the receiver to detect/discard "in between" frames as part of the scan step. This allows it to spend more processing time decoding real data.
2838
* burst rate can be higher (or lower)
29-
* to this end, lower ecc settings *can* provide better burst rates
30-
* 4-color cimbar is currently preferred, and will give more consistent transfer speeds.
31-
* 8-color cimbar should be considered a prototype within a prototype. It is considerably more sensitive to lighting conditions and color tints.
39+
* to this end, lower ecc settings *can* provide better burst rates. I've aimed for a balance of performance and reliability.
40+
* cimbar `mode B` is preferred, and should be the most reliable.
41+
* The older `mode 4C` *may* give more consistent transfer speeds in certain scenarios, but is mostly included for backwards-compatibility reasons.
3242

3343
* other notes:
34-
* having better lighting in the frame often leads to better results -- this is why cimbar.org has a (mostly) white background. cfc uses android's auto-exposure, auto-focus, etc (it's a very simple app). Good ambient light -- or a white background -- can lead to more consitent quality frame capture.
44+
* having better lighting in the frame often leads to better results -- this is why cimbar.org has a (mostly) white background. cfc uses android's auto-exposure, auto-focus, etc (it's a demo app). Good ambient light -- or a white background -- can lead to more consitent quality frame capture.
45+
* screen brightness on the sender is good, but ambient light is better.
3546
* because of the lighting/exposure question, landscape *may* be better than portrait.
36-
* cfc currently has a low resolution, so the cimbar frame should take up as much of the display as possible (trust the guide brackets)
47+
* the cimbar frame should take up as much of the display as possible (trust the guide brackets)
48+
* the format is designed to decode at resolutions as low as 700x700, but performance may suffer.
3749
* similarly, it's best to keep the camera angle straight-on -- instead of at an angle -- to decode the whole image successfully. Decodes should still happen at higher angles, but the "smaller" part of the image may have more errors than the ECC can deal with.
3850
* other things to be wary of:
3951
* glare from light sources.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
Behold: an experimental barcode format for air-gapped data transfer.
77

8-
It can sustain speeds of 943+ kilobits/s (~118 KB/s) using just a computer monitor and a smartphone camera!
8+
It can sustain speeds of 872 kilobits/s (~109 KB/s) using just a computer monitor and a smartphone camera!
99

1010
<p align="center">
1111
<img src="https://github.com/sz3/cimbar-samples/blob/v0.5/6bit/4cecc30f.png" width="70%" title="A non-animated cimbar code" >

TODO.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Performance optimizations aside, there are a number of paths that might be inter
1010
* proper metadata/header information?
1111
* would be nice to be able to determine ecc/#colors/#symbols from the cimbar image itself?
1212
* The bottom right corner is the obvious place to reclaim space to make this possible.
13+
* this is complicated by potential aspect ratio changes for future cimbar modes.
1314
* multi-frame decoding?
1415
* when decoding a static cimbar image, it would be useful to be able to use prior (unsuccessful) decode attempts to inform a future decode, and -- hopefully -- increase the probability of success. Currently, all frames are decoded independently.
1516
* there is already a granular confidence metric that could be reused -- the `distance` that's tracked when decoding symbol tiles...
@@ -18,18 +19,18 @@ Performance optimizations aside, there are a number of paths that might be inter
1819
* there is surely a more optimal set -- a more rigorous approach should yield lower error rates!
1920
* but, more importantly, it may be possible to go up to 32 symbols, and encode 5 symbol bits per tile?
2021
* optimal symbol size?
21-
* the symbols that make up each cell on the cimbar grid are 8x8 (in a 9x9 grid).
22-
* this is because imagehash was on 8x8 tiles!
23-
* smaller sizes might also work?
22+
* the symbols that make up each cell on the cimbar grid are 8x8 (in a 9x9 grid). this is because imagehash was on 8x8 tiles!
23+
* smaller sizes might also work? I've been looking into 5x5 (in a 6x6 grid) as a starting point. It seems promising.
2424
* the limiting factor is the hamming distance between each image hash "bucket", and the 9Xth percentile decoding errors.
2525
* optimal color set?
2626
* the 4-color (2 bit) pallettes seem reasonable. 8-color, perhaps less so?
2727
* this may be a limitation of the algorithm/approach, however. Notably, since each symbol is drawn with one pallette color, all colors need sufficient contrast against the backdrop (#000 or #FFF, depending). This constrains the color space somewhat, and less distinct colors == more errors.
28-
* in addition to contrast, there is interplay (that I don't currently understand) between the overall brightness of the image and the exposure time needed for high framerate capture. More clean frames == more troughput.
28+
* in addition to contrast, there is interplay between the overall brightness of the image and the exposure time needed for high framerate capture. More clean frames == more troughput.
29+
* the camera framerate in the CFC app is limited by auto-exposure and auto-focus behavior. A newer/better decoder app might be helpful.
2930
* optimal grid size?
3031
* 1024x1024 is a remnant of the early prototyping process. There is nothing inherently special about it (except that it fits on a 1920x1080 screen, which seems good)
3132
* the tile grid itself is 1008x1008 (1008 == 9x112 -- there are 112 tile rows and columns)
32-
* a smaller grid would be less information dense, but more resilient to errors. Probably.
33+
* a smaller grid *could* be more resilient to errors, at the expense of data capacity.
3334
* optimal grid shape?
3435
* it's a square because QR codes are square. That's it. Should it be?
3536
* I'm strongly considering 4:3 for the next revision.
@@ -41,6 +42,8 @@ Performance optimizations aside, there are a number of paths that might be inter
4142
* proper GPU support (OpenCV + openCL) on android?
4243
* It *might* be useful. [CFC]((https://github.com/sz3/cfc) is the current test bed for this.
4344
* wasm decoder?
45+
* android is going to kick CFC out of the store! (testing requirement)
46+
* so it might be time to write this...
4447
* probably needs to use Web Workers
4548
* in-browser GPGPU support would be interesting (but I'm not counting on it)
4649
* ???

WASM.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,30 @@
44

55
## Releases
66

7-
wasm and asm.js releases are available [here](https://github.com/sz3/libcimbar/releases/latest). The wasm build is what cimbar.org uses. The asm.js build can be downloaded, extracted, and run in a local web browser.
7+
wasm and asm.js releases are available [here](https://github.com/sz3/libcimbar/releases/latest). The wasm build is what cimbar.org uses. [cimbar_js.html](https://github.com/sz3/libcimbar/releases/latest/cimbar_js.html) can be downloaded and opened/run in a local web browser -- no install required.
88

99
## Build
1010

11-
To build opencv.js (and the static libraries we'll need to build against opencv)...
11+
To build, use the `package-wasm.sh` script in a docker container:
12+
13+
```
14+
docker run --mount type=bind,source="$(pwd)",target="/usr/src/app" -it emscripten/emsdk:3.1.39
15+
```
16+
Then, inside the container:
17+
```
18+
bash /usr/src/app/package-wasm.sh
19+
```
20+
21+
## Alternative build for the adventurous
22+
23+
Alternatively, if you have a local emscripten setup, you can try to run the package-wasm.sh commands piecemeal:
24+
25+
To build opencv.js:
1226
```
1327
cd /path/to/opencv
1428
mkdir opencv-build-wasm
1529
cd opencv-build-wasm
16-
python ../platforms/js/build_js.py build_wasm --build_wasm --emscripten_dir=/path/to/emscripten
30+
python3 ../platforms/js/build_js.py build_wasm --build_wasm --emscripten_dir=/path/to/emscripten
1731
```
1832

1933
With opencv.js built:
@@ -22,7 +36,7 @@ mkdir build-wasm
2236
cd build-wasm
2337
source /path/to/emscripten/emsdk/emsdk_env.sh
2438
emcmake cmake .. -DUSE_WASM=1 -DOPENCV_DIR=/path/to/opencv
25-
make -j7 install
39+
make -j5 install
2640
```
2741

2842
(do `-DUSE_WASM=2` to use asm.js instead of wasm)

src/lib/cimb_translator/GridConf.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,5 @@ namespace cimbar
2727
static constexpr unsigned cell_size = 8;
2828
static constexpr unsigned cell_offset = 8;
2929
static constexpr unsigned cells_per_col = 112;
30-
31-
static constexpr int interleave_partitions = 2;
32-
static constexpr int fountain_chunks_per_frame = 10;
3330
};
3431
}

0 commit comments

Comments
 (0)