About the DIY 3D Scanner project
The idea to make a 3D scanner started sometime in the 1990's and has been revived several times in various programming language incarnations. An initial lack of programming skills forced me learn several languages to find one that was easy but powerful enough for my needs, but each had its own set of limitations and strengths which led to various workarounds and code changes for each new attempt.
September 2009 News:
Click the link below to see my latest 3D scanner development attempt:
My first 3D graphic mission was to create a spinning solid 3D 'L shaped' object with hidden face removal using an Amiga 500 using SAS Lattice C. Woah...what a task I set myself. I didn't know how to program, had forgotten math from my school days and I thought it would be an easy project to start. Little did I know it would take 8 months of headaches combined with trial and error coding to finally get this baby working. The results were fantastic and the hidden line worked a treat (I used a 'painters' type function for the hidden face removal). I was hooked from this point onwards and wanted to create more detailed objects and add special effects e.g. shadows but unfortunately all the features I wanted to add (including the possibility of creating a 3D modelling application!) were well outside my capabilities. From that day forward I dreamed up various ways to create 3D objects without reverting to the old point plotting and gridded paper techniques or expensive software.
Researching 3D graphics slowly introduced various incarnations of data gathering mechanisms and image and vision technologies, which intrigued me. I eventually found articles and text related to structured light techniques for obtaining depth data. 3D laser scanning caught my imagination with its high tech point clouds and precision and seemed easy enough to replicate on the cheap (in theory anyway).
With a desire to make some sort of 3D input device I embarked on another difficult path. I had written loads of theory and notes explaining exactly how the thing should work but had completely underestimated the amount work required. My programming skills needed to improve, capturing camera images on the PC and analysing pixel values to compute XYZ data had to be understood. A bit of maths had to be revised too. Rotations, matrix, radians, coordinates and angles would be required too (actually this bit isn't as complex as you might thing. Only basic math is needed to get decent results).
My first PC programming experience with 3D graphics began using Microsoft C 3.0 and OpenGL. It was relatively easy to setup simple objects and lights using OpengGL but I found it very awkward to implement some sort of GUI interface to my projects. After months of tinkering (using a typical ill thought out suck it and see programming style) I quickly understood that a whole new learning curve was required to just use Windows GUI elements alone never mind the complicated math routines required. Too much document reading eventually took its toll and I eventually decided to look for an alternative language.
Months passed and I eventually read an article introducing the BlitzBasic3D (BB) programming language to Windows. It was a real eye opener. It's easy syntax and great image handling functions gave me the break I needed with an easy way of reading image file JPGs, BMP etc. This was the key that enabling me to read image files and get any pixel value I wanted with ease. After working out the code to extrapolate height values from an image I quickly realised I didn't actually need much math at all. Using simple math I was actually able to develop the code for a 360 degree virtual scanner.
In the early stages I found it much easier to setup my trials using a 3D application. Rather than setting up real apparatus, rotating tables, cameras, and electronic boards around the house I chose to pre rendered virtual scenes with objects and laser lines. These test images were produced quickly and enabled me to quickly test code and alter scanning angles etc. to achieve good results.
Using some small BB code to read each individual pre rendered image (360 of them, one image for each scan rotation angle) I was able to output text files with all the xyz vertex information. These files were then merged into one big text file containing the full object point cloud. (No colour or textures at this early stage)
Meshing the point cloud in my program (covering the point cloud with triangles) was a completely different ball game and the nested looping of the code was too much for my layman programming skills, so I hunted the internet for an alternative way of creating a solid object using the point cloud data.
Eventually I found a great free point cloud program called Points2Polys by Paraform (not now available). I simply imported my 'object.asc' file and it was ready to view and mesh. Initial results were poor (due to the 3D scanner program bugs) but after a lot of code tweeking setup changes I eventually great results and a good mesh.
After many more test scans and not much technical progression I eventually placed the project to the sidelines. It lay dormant from then onwards until I found a shiny new language called Just Basic.
The 3D Scanner phoenix returns...
Just Basic....What can I say but wow! At last a very easy but powerful programming language that really helped me realise many projects. Simple syntax, easy to setup GUI, but alas not perfect for my 3D scanner needs.
This language really helped me learn new programming skills and breathed new life into other programming projects too but it still wasn't without its problems. No decent pixel value functions/commands hindered my visions but with the easy accessibility of the language, I quickly learnt how to overcome these restrictions (reading the pixel values directly from the BMP file!) and started the 3D scanning projects all over again. Added GUI elements was very easy and enabled me to view the scanned profile results and buttons controlled threshold values and saving of the point cloud text file.
Some great results were created here too with the near inclusion of texture colour per pixel and meshing but these were difficult to code and initial results were not good. After loads of tests I still wanted to scan real objects but obtaining webcam images was still evading me (no DLL's allowed) so the project was sidelined again. For a while I played with the language further and wrote other valuable tools and utilities e.g. a save as you type notepad and a 2D image motion tracker to name a couple.
I want to make a realtime 3D scanner now but need a little more power!
Once again the project has been revisited. This time I'm using Visual Basic 6. It does have all the functions and GUI commands I need and has really opened up the project and my programming experience further. Near realtime 3D scanning here I come!
Pixel reading, simple GUI commands, easy syntax all I need in one package. A straightforward transition from Just Basic was a benefit and I didn't have too much new stuff to learn.
Using a nice webcam image grabber program called VFWGrab (no complicated DLL programming) I can easily save single frames of video to an image file. The image can be updated at about 4-6 fps. Analysing the image is easy in VB. Get the image from the folder, view the image in a VB Form (picturebox), read the pixel values and output the 'Object.asc' text file when finished. These near realtime 3D scanning results are good, but nowhere near perfect (see my hand at the top of the screen).
In all I have had a great time with this project, but please bear in mind it is ONLY a hobby. I'm not looking to start a 3D scanning business and I'm not worried about precision, perfect point clouds, or watertight meshes I just like playing with my creation and like the results it creates.
Hope you enjoy the site and, who knows it might even inspire you to create your own 3D scanner!
Points2Polys - Free ascii point cloud viewer and mesh utility.
Naughter Webcam VFWGrab 1.07 (grabs images from a webcam to a file)
Just Basic (Great free basic programming language)