Results With a Low-Cost Stereo Camera Rig

I did an experiment to see if I could train Monty on CAD models, then 3D print those models, and then get Monty to recognize the prints on a low-cost stereo rig that I’ve built.

It was a simple experiment with only three objects and a static rig (no turntable):

  1. A mug
  2. A glass that was just the mug with the handle removed
  3. A block that is essentially a large calibration cube

The glass and the mug were speckled using stick-on labels. Bare glossy filament gives a block matcher nothing to correlate, so curvature came back much flatter than it is. I don’t think that’s specific to a low-cost rig, it’s why commercial depth cameras often project their own pattern.

The setup worked as a simple test and gave some encouraging results. The mug and the block were both identified correctly against the CAD-trained library, and a deliberately unspeckled control was misidentified as the block because the glossy plastic cost the curvature.

There was one interesting failure mode. I ran into trouble that I think is linked to the glass being a subshape of the mug. Here’s the theory on the failure mode: when one object’s graph contains another’s, a capture of the contained object can’t discriminate, because the absence of a handle is never an observation. Demonstrated by the mug capture resolving to rig_mug in 2468 matching steps, while the glass capture ran to a 25,000-step ceiling with rig_mug and rig_glass both still in play. rig_block was correctly eliminated in that run, so it isn’t just noise. A turntable should help recognize a mug, but I’m less sure it helps with the glass. A hypothesis scores -1 when an observation lands where its graph has no node within max_match_distance, but that only fires when the observation falls outside the model. A mug capture disconfirms the glass that way, because the handle lies beyond the glass’s extent. A glass capture never falls outside the mug, so no viewpoint produces the evidence that would rule the mug out. Am I understanding that correctly, and is there any mechanism that penalizes a hypothesis for a stored feature the observation has never visited?

My repository was created to explore the idea of a low-cost, dual camera wildlife trap that could identify and count species using stereo depth perception. It seems like Monty may be a good fit for that purpose eventually. I do wonder if the failure mode outlined above may matter for that application specifically though. A juvenile is often close to a subshape of an adult, and species that differ by one feature - antlers, tail length - might sit in the same relationship as my mug and glass. That said, the conventional alternative has its own problems: large training sets often do not exist for endangered/rare species, and so it can be hard to properly train a traditional ML setup to accurately identify what species (and how many) are in the frame. Some scientists have resorted to having AI generate images to train their setups.

Disclaimer: AI assistance was used throughout the experiment.

1 Like

Follow-up to the above. After posting I realized I should run the same test in simulation as a control, and it adjusts two things I said.

I put the same three objects in front of a Habitat surface agent and scored them against the same CAD-trained library the real captures use, with the matching configuration held identical. Exact depth instead of stereo, no speckle, and an agent that walks over the object instead of a patch moving across one static photograph. Three presented rotations each.

  • rig_mug - correct at all three rotations, in 82 / 212 / 406 steps
  • rig_block - correct at all three rotations, in 45 / 33 / 22 steps
  • rig_glass - hit the step ceiling (4,000) at all three rotations, with rig_mug never eliminated

So, the failure does not seem to be related to my rig. The two objects that resolve on the stereo rig also resolve in simulation in tens to hundreds of steps. The one that doesn’t, doesn’t in simulation either, even with a perfect depth map. So it isn’t SGBM, it isn’t the speckle labels, and it isn’t stereo.

It also isn’t viewpoint coverage, which answers the turntable question I wondered about. Three rotations with an agent walking the surface is about as close to a turntable as you can get without building one, and the glass fails identically at all three.

An adjustment to the previous post: I said a capture of the contained object “can’t discriminate”, but that wording is too strong. most_likely_object is rig_glass in every single run - on the rig, in simulation, at every step budget I tried, including a 25,000 step one. The correct object leads the whole way. What never happens is rig_mug being eliminated, so the terminal condition doesn’t fire and the episode just runs out.

So the accurate version is that it can’t eliminate the superset, and therefore can’t terminate. The evidence ordering is right. What’s missing is a stopping condition.

The mug’s own step counts show the mechanism nicely: 82 steps at one rotation and 406 at another. Same object, same library - the entire cost is how long the walk takes to reach the one feature that distinguishes it. Coverage helps when there is a distinguishing feature to find, and does nothing when there isn’t one.

So, that adjusts my question a bit. Given that the -1 evidence path only fires when an observation lands somewhere the hypothesized graph has no node, and no observation of a glass ever lands outside a mug: is there any intended mechanism for terminating on a subshape? Or is a subshape simply expected to run to max_eval_steps with its superset still standing, and the most likely hypothesis is the thing you’re meant to read in that case?

1 Like

That’s an interesting observation - the absence of an expected feature could be a definitory feature in itself. I wonder if results would be otherwise if mug were a subclass of the glass.

1 Like

Thanks for sharing these results @jmwright and welcome to the community. That’s a cool setup you implemented, and also an interesting use-case (classifying insects that are challenging due to small dataset sizes).

You’re spot on about the issue you identified, and it’s something we’re aware of. Rather than repeat the discussion that has already happened on this, I’ll point you to the Future Work items we have on “Off Object Observations” and “Out of Model Movements”. Please see the video discussions that are also linked in these for more context.

The TLDR is that the problem is surprisingly nuanced, but we have some ideas for how to address it, detailed in those articles. We aren’t prioritizing a solution at the moment, given our focus on compositional objects, but it would be interesting if you end up testing a solution and find that it works.

1 Like

Thanks for the links. The scenario of a “7” vs a “1”, and a lowercase “i” vs an uppercase “I”, feels exactly like what I ran into with the glass and mug. I’ll spend some time with those documents and do some thinking.

1 Like

Exactly! Ok great, please let me know if you have any questions.

1 Like