Compress First: What a ₱43,000 Smart Cane Taught Me About Cheap Hardware

A WeWalk smart cane costs about ₱43,000. Median monthly income in the Philippines is roughly ₱18,000.
That gap is the whole problem. The technology is not at fault: assistive navigation works, and has for years. The devices that do it well are priced for a market that mostly doesn’t include the people who need them. So our thesis group asked a narrower question: if the hardware has to be cheap, what can software do about it?
The answer we landed on was unglamorous. Compress the image before the detector sees it.
The experiment
We ran MobileNet-SSD over ten urban street scenes: pedestrian crossings, Session Road sidewalks, an overpass with traffic underneath. Each image five times, with and without OpenCV JPEG compression at quality 50. To stand in for a Raspberry Pi 5, we throttled a desktop with CPU affinity until it performed like one.
Detection time without compression averaged 0.1006s. With compression, 0.0396s.
That is a 39.36% reduction. Welch’s t-test put it at t(55.02) = 22.55, p < .001, with a Cohen’s d of 4.51. That is an effect size large enough that I double-checked the arithmetic twice before believing it.
The counterintuitive part is that compressing costs time too. Encoding ran about 0.002s per frame. You pay that, and you still come out 0.061s ahead, because a smaller array is less work for the network to chew through. On constrained hardware, the trade is lopsided in your favour.
The number nobody reports
The standard deviation fell from 0.01856 to 0.00461.
Averages get the headline, but for a navigation aid the variance matters just as much. A detector that usually answers in 40ms and occasionally stalls for 200ms is a detector people stop trusting. You feel the stall, not the average. Compression made the pipeline four times more consistent, and that is the part I would sell to a user.
Then I tried to put it in a browser
Published research has a credibility problem: nobody clicks the link. I wanted a page where you upload a street photo and watch the effect happen, no faith required.
So I built it. TensorFlow.js, COCO-SSD on a MobileNet v2 backbone, JPEG quality 50, confidence threshold 0.2: the same parameters, running client-side.
It measured nothing.
The compressed image came back 1.5% faster. Then 0.6% slower. Then 1.8% faster. Noise, wearing a percentage sign.
My first theory was the GPU. WebGL was doing the inference, and on a GPU the bottleneck is shader dispatch rather than pixel throughput, so a smaller input wouldn’t help much. Reasonable. I added a CPU backend toggle, expecting the effect to appear once the work moved onto a path that resembled a Raspberry Pi.
It didn’t. CPU gave me −0.6%.
Measuring the thing instead of guessing at it
At that point I stopped theorising and ran the actual comparison: same model, different input sizes, nothing else changing.
webgl 640×480 → 645 ms
webgl 160×120 → 667 ms
cpu 640×480 → 3162 ms
cpu 160×120 → 3106 ms
Sixteen times fewer pixels. No improvement, on either backend.
coco-ssd calls tf.browser.fromPixels() and hands the tensor to a graph whose input resolution is fixed. Whatever you give it gets rescaled to the same dimensions before a single convolution runs. Inference cost is a constant. There was never an effect to find, and both of my theories about why I couldn’t find one were wrong for the same reason: I was explaining away a result instead of checking the mechanism.
OpenCV’s cv2.dnn doesn’t work like that. It sizes its work from the decoded array, so a smaller image is genuinely less work. That is why the finding is real on a Raspberry Pi and structurally impossible to reproduce in TensorFlow.js. The runtime, not the research.
What the demo measures now
I could have shipped the timing anyway. A number that moves looks like a finding, and almost nobody would have checked.
Instead the page measures the assumption underneath the result, that a heavily compressed frame still contains the obstacles. That part reproduces beautifully:
900 KB of raw pixels → 44.3 KB of JPEG. 20:1. All 20 objects still detected: 10 people, 5 cars, 5 traffic lights. Identical.
At 29.7 dB PSNR and 0.935 SSIM, an image that looks visibly degraded to you is unchanged as far as the detector is concerned. That is the premise the entire paper rests on, and it holds up live, on whatever photo you feed it.
The speed-up stays where it belongs: reported from the study, with all ten cases and the statistics behind it, attributed to the hardware it was measured on.
The part that generalises
The bandwidth angle turned out to matter more than I expected. If a cheap cane offloads frames rather than processing them locally, the radio is the bottleneck, and over 2G, 900 KB takes 61 seconds while 44 KB takes 3. That is the difference between a device that works and a device that doesn’t, and it comes from the same 20:1 the detector didn’t notice.
Compression buys you two things on cheap hardware: less work for the processor, and less to send. The literature mostly studies the second. We measured the first.
Neither requires a ₱43,000 cane.
Takeaways
- On resource-constrained hardware, compressing before inference cut detection time 39.36%, and cut variance by four times, which matters more than the mean for anything a person relies on.
- A 20:1 compression ratio changed nothing about what the detector found. You can discard 95% of the bytes and keep every object.
- When a result won’t reproduce, measure the mechanism before theorising about it. I had two confident explanations for my missing effect and both were wrong; one direct comparison settled it in a minute.
- Ship the measurement you can defend, not the one that looks best. A demo that quietly reports noise is worse than a demo that admits what it cannot show.