Re: [rp-ml] How to convert human face to CAD format

From: Steve Baker (sjbaker1@airmail.net)
Date: Thu Aug 18 2005 - 06:20:20 EEST


Kevin Smith wrote:
> Hi all,
> I'm looking to make a replica model of my 4yr old son on RP machine. Could
> someone pls advise the best approach to get the scanning done.

Well, there are companies out there that offer head scanning services. They
aren't generally cheap.

For an enthusiastic amateur, there are basically three technologies:

1) Shine a vertical laser line onto the face, place a video camera off to one
    side a little - rotate the person slowly through 360 degrees while videoing.
    It's a relatively simple matter to digitize each frame of the imagery to make
    a bunch of 2D slices that can be combined like the segments of an orange to
    reconstruct the 3D volume. Works great on faces - not so good on most other
    3D objects for various reasons.

2) Take a plaster cast of the face. Now you can use a 3D digitizing pen to
    collect points over the face.

3) Simply walk around the subject videotaping the face from a wide variety of
    angles. There is sophisticated software out there that can reconstruct the
    camera angles from the photo's - then reconstruct the face from the photo's.

If you are interested (and reasonably proficient at software), you might be
interested in my $15 head scanner.

I built a rig to scan faces using the first approach - with a laser.

* Take a laser pointer - buy a 'laser line' lens (I found one on eBay for $15).
   This spreads the laser from a spot into a vertical line - dramatically reducing
   it's power in the process - which has the side effect of lessening the risk of
   eye damage from looking directly into the laser. I read that someone used a
   cylindrical glass rod to do this job - but I had no success with the glass and
   plastic rods I had access too. You want a THIN laser line...the thinner the
   better.

* Mount the laser point/lens onto a tripod so it points at the subject.

* Take a moderately priced digital video camera (not an analog one), place it
   so it's 'line of sight' intersects the line from the laser to the subject
   by about 15 degrees. Zoom in so the head pretty much fills the screen.

* Adjust the laser and camera so that the laser points right over the top
   of the center of spindle of the office chair. And the center of the
   of camera's viewfinder also goes right over the center of the spindle.
   I made a little sighting rod that fit onto the chair to help to get this
   accurately right.

* Place the subject in an office chair...and here is the tricky part...arrange
   for the chair to rotate at constant speed while you film...you can do that
   with some kind of motor rig...but it's hard. Let's come back to this part.
   Try to have the subject sit as still as possible. They should probably
   close their eyes to avoid the laser light - but with the light spread into
   a nice long line and a very brief flash as the chair rotates pass the laser,
   I don't think there is significant risk in scanning with eyes open.

* Do this in a darkened room...preferably with a black background behind the subject.

* Have the subject hold up a battery operated green LED (eg from one of those cheap
   laser flashlights) stuffed into the end of a thin tube (I used a drinking straw
   wrapped with black electrical tape). This produces a brief green flash into the
   camera as it rotates past.

The resulting video will be a wobbly red line that represents a cross-section of
the subject's head - with a couple of green flashes from when the LED goes past
the camera.

Use video editing tools to cut out all of the video before the first green flash
and all of the video after the second green flash - so you have exactly one
360 degree rotation of the subject.

I used 'mplayer' and 'mencode' (freeware video tools) to chop the video into
individual still image files - one for every frame. With one revolution of
the chair every 10 seconds or so, I ended up with 300 frames of video - 300
separate 'PNG' format images.

   You can use very simple software to find the brightest point
on each scanline of each frame of the video. You can draw a plan-view of
your laser, camera and chair and figure out the angles and distances make
up a triangle. High school geometry gets you the distance of the laser
line from the center of the chair for every scanline for every frame.

   The result is a 'fuzzy' cloud of 3D points. My camera had 475 scanlines
so each 'slice' contained 475 distances (well, actually more like 300 because
some scanlines were above the subject's head) - with 300 frames of video,
I had a 'point cloud' of 300x300 = 90,000 points! That was more than I
needed - and my naive approach of picking the brightest point on each
scanline instead of finding some 'centroid' value resulted in a lot of
noise in the image. So I averaged a bunch of points together to filter
out the noise and ended up with about 100 slices and 100 layers. Still
a fairly accurate 3D model - one vertex every few millimeters in each
direction. I estimate the precision in terms of distance from the
center of the chair to be of the same order.

   Now - one nasty point here is arranging to rotate the chair smoothly
so that our 3D slices are equally spaced. I thought about motorizing it
with some kind of constant speed motor - but that was hard to do. Spinning
the chair by hand produced somewhat uneven speeds - so the resulting 3D
model was a bit uneven.

   In the end, I made a paper headband for the subject composed of alternating
1cm black and white lines. As the laser passes over the band, it brightens and
dims. Extracting that information from the video stream got me a way to
measure the approximate speed of rotation - and hence the position of each
slice around the 360 degrees of video footage.

   The software was hand-written in C++ and was a horrible kludge - but I only
needed to do it once. I could probably have gotten better precision by
doing better 'extraction' of the center of the laser line from the images.
The line tended to be 5 to 10 pixels wide (depending on where it was on the
face - wider as it slid down the sides of the nose).

   Going from a set of slices and layers to a polygonal skin is easy -
just stitch them together into triangles the order they are generated.

   I would imagine your 3D printer gizmo has some kind of software to
turn a polygonal skin into volumetric data.

   I did a second scan of the person (without the laser and in full
daylight) to extract a texture map for the subject.

   It took me a couple of days to figure out the best way to make a
good laser line - but aside from that, it took me one evening to write
the software and another to set up for the scan and actually do the work.

---------------------------- Steve Baker -------------------------
HomeEmail: <sjbaker1@airmail.net> WorkEmail: <sjbaker@link.com>
HomePage : http://www.sjbaker.org
Projects : http://plib.sf.net http://tuxaqfh.sf.net
            http://tuxkart.sf.net http://prettypoly.sf.net
-----BEGIN GEEK CODE BLOCK-----
GCS d-- s:+ a+ C++++$ UL+++$ P--- L++++$ E--- W+++ N o+ K? w--- !O M-
V-- PS++ PE- Y-- PGP-- t+ 5 X R+++ tv b++ DI++ D G+ e++ h--(-) r+++ y++++
-----END GEEK CODE BLOCK-----



This archive was generated by hypermail 2.1.7 : Mon Jan 02 2006 - 08:09:18 EET