oh ok.
the geometry is basically just similar triangles or intercept theorem.
you can skip more involved camera “calibration”. just take a picture of something you can measure physically (width of tape, distance to camera) and in pixels (literally selection rectangle in mspaint will do). choice of physical units doesn’t matter, just has to be consistent.
focal length [px] = width [px] / width [m] * distance [m]
that’s the single constant for the camera (and lens) that’ll relate angles to pixels. angles because it’s a camera, that’s all it sees, and because there’s an angle hidden in the projection equation (see also: camera matrix):
width[px] = f[px] * width[m] / distance[m]
where tan(angle) = width/distance
. the calculations don’t involve actual angles most of the time, just f
.
amazon link says 72 degrees field of view (diagonally), so I would expect f ~ 2230
or so, because f * tan(72/2 * pi/180) == hypot(2592/2, 1944/2)
I’d recommend first working on a single picture. since that’s a “pi camera”, there are many ways to take a single picture. when your code works on a single picture, you can easily extend it to work on (live) video. trying to develop while everything moves is just needless complication.
for the programming, you might want to start with
https://docs.opencv.org/4.x/df/d9d/tutorial_py_colorspaces.html
or whatever you need that leads up to that.
that should give you a “mask” image of your colored tape. you can measure on that by slicing one row of pixels (plot that, see what it looks like) and finding the indices of the first and last positive elements. you can write your own loop for that, or use numpy
all of that relates to “augmented reality”, where the task is to find the pose (distance, orientation) of a square of known size. OpenCV comes with an aruco
module. that’s basically what you’re doing, just with a dimension more/less (tape vs square…)
from the equation you’ll see that distance depends strongly on how accurately you can measure pixel distances. since that has practical limits, you can and should use larger physical objects, i.e. make the tape wider rather than narrower.
practical tip: work with jupyter notebook/jupyter lab, rather than plain python scripts. notebooks are a bit more interactive and exploratory than trying to develop an entire script by restarting it all the time. notebooks are also usable from Visual Studio Code. a less complicated notebook of my recent ones (inline matplotlib graphs and images): so-72854648.ipynb · GitHub. to show numpy arrays as images inline, I use a bit of custom code in my PYTHONSTARTUP
script that works similar to the cv2_imshow
shim available in google colab. oh, yes, you can work in google colab too, but that’s running on a server, so you won’t have access to any local devices (your camera).