February
2026
Architecture Decision
The AI inference cost problem โ and why I went fully local
As the detection logic matured, I started thinking seriously about what a deployed version of HomeHalo would actually cost to run. The naive path is obvious: send sensor data to a cloud API, run inference there, return a result. That's how most AI-powered products work. I ran the numbers and didn't like what I found.
At any reasonable deployment scale โ a few hundred homes, let alone thousands โ the per-inference cost of cloud API calls adds up quickly. More importantly, it creates a dependency: if the API is down, or the home's internet connection is slow, or the latency spikes, the safety system degrades. That's not acceptable for something that's supposed to catch a developing cooking hazard in near-real time.
The shift: Every frame of thermal data needs to be analyzed on the device itself. No cloud round-trip. No subscription to an inference API. The compute budget is whatever fits in the enclosure, and the latency budget is the time it takes to process a single frame locally โ nothing more.
This isn't just a cost decision โ it's the right architecture for a safety-critical application. Local inference means the system keeps working regardless of network state, and it means thermal data never leaves the home. That second point became a core part of the privacy story.
Deep Dive ยท February 2026
How I detect liquid in a pot using thermal imaging and Otsu's method
By Aki Suda ยท 8 min read ยท Algorithm design
The hardest part of cooktop hazard detection isn't finding the pot. It's distinguishing a pot with something in it from an empty one โ and doing it reliably across different cookware materials, burner types, and cooking states.
The core problem
When you look at a thermal image of a cooktop, a hot pan is easy to spot โ it's the brightest blob. But "bright" means hot, and hot can mean many things: full pan cooking normally, half-empty pan, or completely empty pan running dry. The average temperatures might not differ much at first. The internal structure does.
A pan with liquid in it has a characteristic thermal profile: a slightly cooler rim (the metal walls absorbing heat) and a hotter center (the liquid surface, especially near boiling). An empty pan heats more uniformly โ the whole surface climbs together, with no cool liquid mass to absorb energy unevenly.
Otsu's method as a thermal segmentation tool
Otsu's method is a classic image processing technique for finding the optimal threshold to separate two classes of pixels based on their intensity distribution. It finds the threshold that minimizes within-class variance โ in other words, it finds the natural dividing line in your histogram.
I'm using it here differently from its typical application. Instead of thresholding a grayscale image into foreground and background, I'm applying it to the temperature histogram of just the pixels inside the detected vessel blob. That gives me the dividing temperature between the cooler rim structure and the hotter liquid surface.
# Otsu threshold applied to vessel interior pixels
vessel_pixels = extract_blob_pixels(thermal_frame, vessel_mask)
threshold = otsu_threshold(vessel_pixels)
# Segment into rim (cool) vs liquid (hot)
rim_mask = vessel_pixels < threshold
liquid_mask = vessel_pixels >= threshold
fill_ratio = np.sum(liquid_mask) / np.sum(vessel_mask)
liquid_temp = np.mean(vessel_pixels[liquid_mask])
What this tells me
If Otsu finds a clean split โ a meaningful cooler region and a meaningful hotter region โ that's evidence of liquid. The fill ratio (liquid area / total vessel area) tells me how full the pot is. A high fill ratio near boiling temperature triggers a boil-over prediction. A fill ratio that was high and is now dropping fast indicates liquid is boiling off. A fill ratio consistently below 0.15 with a rising temperature means the pan is probably empty.
The elegance of this approach is that it's self-calibrating. I don't need to know the cookware material or the burner power setting. The threshold is computed fresh from each frame's own temperature distribution โ so it adapts to whatever is in front of the sensor.
Failure modes I've found so far
- Very small amounts of liquid (less than ~10% fill ratio) can be misclassified as empty โ the thermal contrast isn't strong enough for Otsu to find a clean split
- Cast iron cookware heats so slowly and uniformly that the rim/liquid contrast is low even with normal liquid content
- Oil doesn't behave like water โ it heats more uniformly and doesn't boil in the conventional sense. Boil-over prediction for oil isn't reliable yet
These are documented limitations, not hidden ones. The system is designed to fail conservatively โ if the classification is ambiguous, it defaults to a lower-severity alert rather than no alert.