Pi 3D scanner: a DIY body scanner

The blog’s rather late today but definitely worth the wait we think. It’s an jaw-droppingly brilliant Raspberry Pi-driven 3D scanner by Richard Garsthagen . He used it recently to scan over 200 people at the Groningen Makerfaire with spectacular results:

Richard’s site has details on recent events (including the best party ever: a scanning party) and instructions on how to build your own. It uses 40 Raspberry Pis and cameras but Richard says that he has had impressive results with 12 Pis.

Setting up the scanner. Each of the ‘arms’ has three Pis and cameras mounted top, middle and bottom.

Of course once you’ve been scanned you can be 3D printed:

An early sample taken with 21 cameras. Notice the lettering on the shirt.

There are lots of 3D scanners popping up at the moment. The standout thing about Richard’s build is that the scan is instant—the Pi cameras take simultaneous photos—so there’s no standing still in a ker-ayzee pose whilst lasers or Kinects wibble about doing their thing.

But best of all is that you can build your own 3D scanner and then print yourself. For a science fiction-brewed child of the 70s like myself this is a deeply magical thing and it makes me insanely happy. And just bit overawed.



This is terrifc higher performance solution for a very low budget price.
My first thought was the
PiScan can make a 1:1 scale 3D model of a face in about an hour.
Use this a mould to make a latex mask.
Paint it up in line with the images and you can make a look-alike in a few hours.

Is it me or am I the only one expecting rooms full of Ebon/Liz impersonators at the next Jam. !!


If you’re impersonating Eben any time this month, you will need to come with a shoe brush affixed to your top lip. (Please, nobody 3d print the thing. I am planning on using December to pretend it never happened.)


reminds me of the thing from one of the spider man movies


Definitely the BIG RAT from the Joe 90 series (anyone else remember that….?)


I found this in the Raspberry Pi contest at instructables:
P.S. Please vote for the stepper motor controller (Me!)


3D fax machine is finally upon us!
“Scotty, beam me up!”
A few minutes later, a 3D printed Kirk showed up on the destination.
“Very funny, Scotty!”

12 pis is still too much for me, though. I’d rather pay 40 bucks for little painted statue of me, even if I have to stand still for a while.


I spotted this a couple of weeks ago and thought it was really awesome :-D

Printing the output via http://www.shapeways.com/materials/sandstone would be cool.

I wonder what the scanner’s maximum ‘framerate’ is – could it be used to create low-FPS fully 3D animations?


Hmmm, or instead of using raspistill to take pictures, I wonder if you could use raspivid to capture videos, and then reconstruct those frame-by-frame into a full-on 3D animation?


I remember some papers a few years ago about doing interesting tricks with cameras and DLP projectors where they used the projector to illuminate individual pixels and then recorded the results on a very simple camera (some tests just used a single-pixel light sensor) and they were then able to mantmatically manipulate the result to present the image as seen from the point of view of the projector.

With cheap DPL projectors available now like this one for $300 (854×480 85 lumins http://www.brookstone.com/hdmi-pocket-projector?bkiid=World_Landing_Page_Electronics_Projectors___Screens|CategoryWidget|801143p&catId= or this one for $430 (1280×800 200 lumins http://www.brookstone.com/200-lumen-pocket-projector-pro?bkiid=World_Landing_Page_Electronics_Projectors___Screens|CategoryWidget|864129p&catId=)

I wonder how you could combine a number of pi/cameras with a few projectors for illumination and quickly do a very detailed scan

the combination of controlled lighting and even modest cameras should produce very interesting results and would solve the problem the author described of scanning people’s backs


Wow !! That’s 40 Pis and cameras on the Xmas list :O)


I was reading his instructables and spotted one thing that screamed out at me.

He has a central CIFS (windows share) server mounted on all pies (*smile*) as /server. And in his listening script when all the pies are triggered at the same time they will try to access the server to read one file /server/options.cfg.

He would be better keeping a local copy of this file that is updated when servers updates (possibly stored in RAM, to avoid wearing out the writes on the SSD’s).

Because 39 machines all trying to accessing the same file at the same millisecond – won’t and this will delay some photos from being taken at the same instance.

I personally would have done something like this to keep a local copy of the config file in RAM, that is automatically updated every at most 10 minutes (random)
#!/bin/sh —
# maximum time between updates is 600 seconds (10 minutes)
# random number from 0 to 65536
randnum=`echo “obase=10; ibase=8; ” \`dd if=/dev/urandom count=1 bs=2 2>/dev/null | od -N 2 | head -1 | awk ‘{print $2}’\` | bc`
rand_sleep_time=`expr $randnum % $timespan`

sleep $rand_sleep_time

test /server/options.cfg -nt /tmp/local_options.cfg
if [ $? ] ; then
cp /server/options.cfg /tmp/local_options.cfg


Actually scratch that, I just reread his script (my python is not so good) and the pi’s only access this file when told to do so, and not when every photo is taken.


Heh, that’s cool. For the Pi rig featured here to give such smooth animation, I guess you’d need really tight synchronization between all the cameras, which I dunno is possible?


I could see this being used for a party event. Instead of those photo booth deals, you and maybe a friend could slide in and get a figurine of yourselves. It’d be a cool souvenir of things like weddings, birthdays, etc.


NOW we’re talking! This shows how to do 3-D optical input to the Pi’s honkin’ GPU (for such a low-cost device) to take advantage of its power, and in parallel in this case (both within the GPU and among the multiple Pi boards). As we say in the Navy, Bravo Zulu!

When I was working on my Master thesis on $50,000 Silicon Graphics Iris 2400 3-D workstations that could do a whole 30,000 Gouraud-shaded polygons per second (vs. the Pi’s 40,000,000) in 1986, a guy in a garage (naturally) down the road from us in Pacific Grove (adjacent to Monterey) had fashioned a 3-D capture rig using a single camera and a motorized turntable. Our professor had his head scanned and, hours of work and millions of pixels translated into a 3-D mesh file later, we had a very rough, barely-recognizable likeness of him that could be spun around virtually on the Iris 2400s in response to user-controlled input. This Pi-based version is sooooo much better and faster and, even using 40 Pi boards, is infinitesimally cheaper.


Wow. They put their professor’s head on a turntable to scan him in? If it was voluntary, that’s really going above and beyond for the sake of science!


It was carefully phrased in the passive voice so you would not know whether he volunteered or not. :) Sometimes a lab full of grad students declares mutiny…


The statute of limitations for murder is indefinite, so you’ll never get me to talk coppers, see? Yeah, I have the right to remain silent, see? I have the right to not incriminate myself, see? If I can’t afford a lawyer, one will be provided to me at no cost to me, see? Yeah, see? :D


Hmmm… wonder if a single Raspi and camera plus a turntable could be used to 3D-scan an inanimate object?


Hi Richard,

It is a wonderful device, I would like to scan by little son as well, but it is really cannot let him hold a position. My first step to scan a toy model instead, but I failure to group the image into 3D as clear as you have, could you share with me what software you use to group the image into 3D model? Thanks a lot.


some diagnosics added:

import socket
import struct
import fcntl
import subprocess
import sys
import os

# Setup File Locations
tmpfilename = "/tmp/photo.jpg"
storagepath = "/mnt/3dscan/"
optionsfile = storagepath + "/options.cfg"

# Initialisation of the LED ping functionality, added because
# The camera led was disabled by adding "disable_camera_led=1"
# in raspberry config file /boot/config.txt
import time
import RPi.GPIO as GPIO
# Disable GPIO In-Use warnings
# Use GPIO numbering
# Set GPIO for camera LED
# Set GPIO to output
GPIO.setup(CAMLED, GPIO.OUT, initial=False)

# Setup Listener

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', MCAST_PORT))
mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)

sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

def get_ip_address(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
struct.pack('256s', ifname[:15])

id = get_ip_address('eth0')

ip1, ip2, ip3, ip4 = id.split('.')

print 'ID: ' + ip4

#create an options file, this file should containt the parameters for the raspistill image cmd
optionfile = open(optionsfile,'r')
options = optionfile.readline()
print "options: " + options

while True:
data = sock.recv(10240)
data = data.strip()
if data == "reboot":
print "rebooting..."
cmd = 'sudo reboot'
pid = subprocess.call(cmd, shell=True)
elif data == "shutdown":
print "shutting down..."
cmd = 'sudo shutdown -Fh now'
pid = subprocess.call(cmd, shell=True)
elif data == "quit":
print "exiting the script..."
elif data == "ping":
print "flashing camera LED..."
for i in range(5):
GPIO.output(CAMLED,True) # On
GPIO.output(CAMLED,False) # Off

elif data == "update":
args = sys.argv[:]
print "updating script "+ args[0] + " from " + storagepath

cmd = 'cp ' + storagepath + "/" + args[0] + " ."
pid = subprocess.call(cmd, shell=True)

print "restarting " + args[0] + " ..."
args.insert(0, sys.executable)

os.execv(sys.executable, args)

print "shooting " + data
cmd = 'raspistill -o ' + tmpfilename + " " + options
pid = subprocess.call(cmd, shell=True)
print "creating directory"
cmd = 'mkdir ' + storagepath + data
pid = subprocess.call(cmd, shell=True)
print "copy image"
cmd = 'cp ' + tmpfilename + " " + storagepath + data + "/" + data + "_" + ip4 + '.jpg'
pid = subprocess.call(cmd, shell=True)
print "photo uploaded"


Scanboostar, nice update on the listen script, can you help me with ideas to create the /server/config.cfg file.
I know the commands and attributes for the raspistill, but not how to put all my preferences into a single file.
Thank you in advance…


I would like to have such a box installed for 3d scanning reasons. Is it possible to buy this? Knowing that my DIY-attitude is high but qualification level may be far to low to do so on my own. Thanks for comments.
Best regards,

Leave a Comment

Comments are closed