Introduction: Time of Flight Camera (ToF)

The acronym ToF comes from the English name "Time of Flight", it seems like a pretty strange name for a camera, but it's not at all if you look at it in its operating scheme.

TOF 3D cameras work in a very similar way to the sonar of a submarine.

They are commonly used to accurately measure the distance at which an object is projected towards a beam of light.

Time-of-flight cameras work by emitting pulses of light and measuring the time it takes for the light to travel to an object, be reflected and captured by the camera sensor, with that measurement of time, the camera is capable of calculating the distance to the object and even making a representation in 3 dimensions of the scene.

In this instructable I will teach you how I made a very innexpensive ToF with limited resoruces and a lot of areas of opportunity to make it better.

Supplies

For the camera I used an OpenMV camera that you can program with MicroPython.

https://openmv.io/

The only thing you need is an enclosure or a room where you can keep the lighting constant, this is important because of the way the code works.

For example, if you place this camera in front of a TV, changing light will affect the results, so keep it consistent. Preferably a dark room/box

You will also need a PC with OpenMV software and Matlab or similar.

Step 1:

As a first step I created the dark enclosure with aluminum extrusion and 3mm MDF to close it, making a hole at one end for the camera lens to enter, and a second hole so that the LED could illuminate the object. . (This LED is built into the camera PCB) I made this 3D model for you to see, the small black box its a 3D printed enclosure, mostly for looks, to hide the cables and the back of the pcb.

Make sure that the distance from your camera and the object you are using is around 15cm, if its too close or too far its not going to work.

Step 2:

Now that we have our dark enclosure we can work on the code.

To progam one of these small cameras you need to download the Open MV software, this is also helpfull to see the capabilities of the camera with the example codes.

When you have the software installed you can create a blank project, paste this code and upload it.

____________________________________________

threshold_list = [(200, 255) ]

valores =[]

i=0


cpufreq.set_frequency (216) #Define the cpu frew to the highest

led = pyb. LED (3) #Define led as the blue one

#led = Pin ("LED BLUE", Pin. OUT)

#led = Pin ("P5", Pin. OUT)


sensor. reset ()

sensor. set_pixformat (sensor. GRAYSCALE)

sensor.set framesize (sensor. QQVGA) #This is the quality, QQQVGA is lowest VGA Highest (not recomended)

#If you change the resolution you need to change the for cycles X and Y to correspond with the bigger picture

sensor. set_auto_exposure (True, exposure_us=100) # make smaller to go faster

sensor.skip_frames (time = 2000)

foto = []

led.off ()

fila = 0

suma = 0


for i in range (159) : #159 is the size in X pixels

t = [] #list to store distances

for j in range (119) : #119 size in Y

ref = sensor. snapshot () .get_pixel (i, j) #Takes a picture of the present value of the pixel

t on = time.ticks cpu() #capure the clock cycles so far

while (1) :

led. on () #turn on led

actual = sensor.snapshot ().get_pixel (i, j) #get value of that same pixel

if actual != ref: #if the vlaue changed

led.off () #turn off led

t off = time. ticks_cpu() #How many clock cyles pased?

tVuelo = (time.ticks_diff(t_off, t_on) ) /1000000 #Reduce the scale of the number

tVuelo = round (tVuelo, 2) #Round two decimals

time. sleep_ms (3)

t.append (0.8 - tVuelo) #adjustment factor

break

else:

led.off ()

time. sleep_ms (3)


#print (fila)

fila+=1

#Condition to clear RAM before overflow

if(fila == 39 or fila == 79 or fila == 119) :

print (foto)

foto=[]

foto, append(t) #We printed the list of 18,921 measurements



When you hit upload it means that the code is going to run so put your object in front of the camera and go to the next step.

Step 3:

Once you have uploaded the code please make sure the blue LED is flashing very fast, after a few seconds you will be able to see on the terminal (in the OpenMV software) the matrix that the camera is sending you, be patient, it will take a while depending on the resolution you defined in the code.


It will send you a list of lists (matrix) that you must copy and paste into other software to make a representation of the image, I used Matlab.


There is an intermediate step though... you need to clean the matrix, by replacing all the square brackets with commas, for example replace all "], [" with a single comma and a space ", " for this process I used windows notepads, it is quite easy using the tool "replace".


Also at the beginning of the array you will have a double bracket "[[" and the same at the end "]]" delete a pair so that your end up with a single bracket at the beggining and a single one at the end, something like this:


[number, number, number, end of line; many numbers here... ... ; number, number, last number];


The image on this step shows how your matrix should look like when you finish cleaning it.


You can now copy the matrix again and paste it on Matlab or other software and use the command "imshow"


I defined my matrix like this

Results = [put your matrix here...]

imshow(Results)



Step 4: Results

After running this you will have a visual representation of the matrix that your camera took, keep in mind that the resolution is quite low, but high enough to be able to see the shapes of the objects you place in front of the camera.


Grayscale is defined by the depth of the pixel or the distance to the camera, the lighter it is, the closer it is to the camera


Step 5: Avoiding Noise

Depending on the absorption of the material you will have some noise, as in the base, you can avoid it by using some non-reflective material such as fabric.


But anyways, you should be as surprised as I was,

You just measured the time of flight of a ray of light! With an $80 dollar camera!


That's pretty impressive if you ask me.