Introduction: Virtual 3D Imaging

About: I'm a school student who aspires to pursue robotics. I love working on DIY projects and am learning programming and algorithms.

Ever wished to view or share your real life objects from all sides on your big screens ? In normal images, we can only view a part of the the image from a specific angle. Virtual 3-D images provide an amazing experience of sharing and viewing objects and products. This tutorial will show you how make required software to capture the minimum number of required images and view your object on computer from all sides.

DOWNLOADS: Processing IDE 3.0a5

Link: https://processing.org/download/?processing

Under the category: "Pre-releases" select 3.0a5 and download for your OS.

PART LIST:

  • Cardboard Box of dimensions: 20 cm x 16 cm x 12 cm
  • Cardboard 15 cm x 15 cm
  • 10 RPM DC motor x1
  • 1.5 V DC Cell x1
  • USB LED x1
  • HD Webcam / Camera with Audio-Video to USB cable x1
  • White Papers

TOOLS:

  • Pair of scissors
  • Wire Strippers
  • Glue
  • Duct Tape

OPTIONAL

  • If your motor shaft has a hole in it, you will need a screw for it with a broad head.

Step 1: Build the Rotating Platform

First, cut a 5 cm x 5 cm square out of your cardboard with a hole in the center so that the shaft of the motor can fit in tight and easy. Cut out 4 such squares and stick them together. Make sure that the holes are above each other.

(OPTIONAL) If the motor shaft has a hole in it, do add a screw with a broad head as show in the pictures for firm attachment.

You can be sure of this by first inserting the shaft in all the 4 pieces and then sticking them together. On this, your main rotating platform will rest. This small base ensures that the actual base does not swindle but is always horizontal to the ground. Add Duct tape on surrounding edges.

If the shape of your motor does not match with what shown in the pictures ( I have used a gearbox ), you can still get an idea of how to build a holder for yourself. The aim is to keep the motor shaft upwards. In order to hold the motor in position, add cardboard pieces at the points where the motor can sway or fall.

For the base of the motor holder, cut out another rectangular cardboard of dimensions 14.5 cm x 3 cm. Then cut 10 small pieces of 4 cm x 3 cm. Place and glue 5 of the pieces on one end. Then place the motor above it with least part hanging and use duct tape all around. In order to give support from the other side, place the remaining 5 cardboard pieces below the other side. Make sure that the motor shaft is free and does not touch anything. Add more cardboard pieces if the shaft touches the base.

Next, place a 1.5 V cell one side and a switch on the other side. Make a simple on/off circuit to turn the motor on and off.

The current path will be: Positive terminal of cell > Switch > Motor > Negative terminal of cell

Finally cut out card board piece of 11.5 cm x 11.5 cm and stick it on the small base you attached to the motor shaft earlier.

Step 2: Setting Up the IDE

After you have installed the IDE, open it.

First save this blank file anywhere you want with any name. Now, open the blank .pde file.

In the menu bar, go to: Sketch > Import Library > Add Library. A new applet with title "Library Manager" will appear. In the category sub-menu, select Video & Vision. Find the library "Video" by The Processing Foundation. Install it. After it is done, close and restart processing. Now if you go and find the Video library, you will see a "Remove" button next to it. This tells you that you have successfully installed your library.

Now, connect your camera to the computer.

Next, copy and paste the following code:

import processing.video.*;
void setup()
{
  println(Capture.list()); //Capture.list() returns an array of list of available cameras
}

Click Run and then click Stop to stop execution of the code. In the console(the black area in the IDE), you will see a list. Each line is in the following format: name="nameOfCamera", size=X x Y, fps=FramesPerSecond

Now, look for a line that states the name of your camera and the dimensions (in pixels) of the image you want to be in, given after size, and rate of change in images to be displayed on screen, given after fps. Frames per second signifies the number of images changed on screen in 1 second. For example, if fps = 30, 30 images from your camera will be captured and displayed on screen in 1 second. So, it seems like you are watching a video. Once you have selected the line, copy that line in notepad and saved it anywhere. This data will be required later. You can delete the text file you saved after the next step.

Next, go to: File > Preferences . A new window will appear. Click on the check-box next to "Increase maximum available memory to..." Refer to the images. The default memory is 256 MB. Now, increase the memory to 1024 MB. This is done because you will need to store a large array of images and for which, 256 MB is insufficient.

Finally, go to: Tools > Create Font . A new window will come up. Select the font you want. Once done with it, Click OK. In the location where you saved this blank code file, you will find a new folder named "data" will be created and in it, you will see a .vlw file. This is your font file.

Step 3: Coding: Capturing Images

Copy and Save this code in the blank file you saved earlier.

// Run this program only in the Java mode inside the IDE, <br>// not on Processing.js (web mode)!!</p><p>import processing.video.*; </p><p> PFont font;
String msg = "Click when Ready!";</p><p>Capture cam; //captures images from the camera
int brightness = 150; //default brightness</p><p>PImage img;
PImage X[] =  new PImage[360];
PImage Y[] =  new PImage[360];</p><p>int arr = 0, c = 0;//arr stores the clicks and c the array, index
boolean start = false;// checks capturing</p><p>void setup() {
  size(640, 480);
  
  font = loadFont("CopperplateGothic-Bold-48.vlw"); //Replace the font with your selected font. Do include the extension .vlw
  textFont(font, 20);
  fill(0, 0, 0); //set font color in RGB format
  
  cam = new Capture(this, 640, 480, 30); //set the camera resolution to 640x480 and frameRate to 30fps
  cam.start();   //activate the camera
}</p><p>void draw() {
  if(cam.available()==true && arr<3) //cam.avaialbe() checks if there are any bytes available to read from camera
                                     //also check if the number of clicks do not exceed 2
  {
    cam.read(); //capture the imagees
  }
  img = cam;           // store image from camera in variable
  image(cam, 0, 0);    //display camera image on window  
  Brighten();          //brighten the image for better visibility
  
  if(start)
  {
  if(arr == 1)              //check if user has clicked once
  {
    X[c] = get();           //capture the screen
    println("X"+c+" saved");//display status in console
    c++;                    //update index
    
  }
  if(arr == 2)               //checked if the user has clicked twice
  {
    Y[c] = get();            // capture the screen
    println("Y"+c+" saved"); //display status in console
    c++;                     //update index
  }
  }
  if(arr == 3)           //check if the user has clicked thrice
  {
    saveImages(X, "X"); // save images set X to data folder
    saveImages(Y, "Y"); // save images set Y to data folder
    arr++;              // update click so saving process is not repeated
    msg = "Done!";      // Display status
  }
  if(c>359) { start = false; msg = "Click when ready"; } //check if the number of images captured do not exceed the array size, ie, 360
 text(msg, width/2-80, height-20);                       //display required messages
}
void saveImages(PImage pic[], String ini)
{
  for(int i = 0;i<360; i++)  //loop runs 360 times
    pic[i].save(ini+i+".png"); // PImage_Variable.save("nameOfFile") saves images
} </p><p> void mousePressed() //called when mouse buttons are pressed
{
  msg = ""; //clear text on screen so that the text is not saved in the images
  arr++; //update number of clicks
  c = 0; //reset array index
  start = true; //to begin capturing
}
void keyPressed() // called when keyboard buttons are pressed
{
  //brightness variable stores the amount of brightness
  if(key == 'w') brightness++; //Press 'w' to increase brightness
  else if(key == 's') brightness--; //Press 's' to decrease brightness
  if(brightness<0) brightness =0; //avoid unnecessary reduction
}
void Brighten() 
{
   loadPixels(); </p><p>  // We must also call loadPixels() on the PImage since we are going to read its pixels.  img.loadPixels(); 
  for (int x = 0; x < img.width; x++ ) {
    for (int y = 0; y < img.height; y++ ) {</p><p>      // Calculate the 1D pixel location
      int loc = x + y*img.width;</p><p>      // Get the R,G,B values from image
      float r = red (img.pixels[loc]);
      float g = green (img.pixels[loc]);
      float b = blue (img.pixels[loc]);</p><p>      // We calculate a multiplier ranging from 0.0 to 8.0 based on mouseX position. 
      // That multiplier changes the RGB value of each pixel.      
      float adjustBrightness = ((float) brightness / width) * 8.0; 
      r *= adjustBrightness;
      g *= adjustBrightness;
      b *= adjustBrightness; </p><p>      // The RGB values are constrained between 0 and 255 before being set as a new color.      
      r = constrain(r,0,255); 
      g = constrain(g,0,255);
      b = constrain(b,0,255); </p><p>      // Make a new color and set pixel in the window
      color c = color(r,g,b);
      pixels[loc] = c;
    }
  }
  updatePixels(); 
}</p>

Now in the text file you saved, suppose you have the following data:

name=myCamera, size = X x Y, fps=F

In the function setup(), find the line:

size(640, 480);

Change it and enter your values like this:

size(X, Y);

Then, find the line:

cam = new Capture(this, 640, 480, 30);<br>

Here, do the changes like this and enter your own values like this:

cam = new Capture(this, X, Y, F);

Now you can delete the text file and you do not need to remember any data.

The comments describe most part of working of code.

This is what happens:

  1. Capture from camera
  2. Change the brightness according to user input.
  3. Increase the brightness level
  4. Display the image on window
  5. If the user has clicked once, store the next 360 images in the array X
  6. If the user has clicked twice, store the next 360 images in the array Y
  7. If the user has clicked thrice, save the images stored in the arrays X and Y in the computer in png format.

This code helps you to capture the required number of images and store it in png format.

You may even download the file Virtual3D.rar. It contains all the required code and data files required.

Step 4: Coding: Viewing Images

Now, create a new blank file and save it.

Copy the following code:

PImage img;           //stores imagesint c = 0;            //stores index
String ini = "X";     //stores initial file name
float zoom = 1;       //stores zoom value
float angle = 0.0;    //stores angle of rotation
int x = 0, y = 0;     //coordinates of location of image in pixels</p><p>void setup()
{
  size(1280, 720);   //window size
  frameRate(30);     //rate at which images on screen
}
void draw()
{
  background(255);    //bacground color in rgb 
  
  img = loadImage(ini+c+".png"); //name of image file to be loaded
  
  //Instructions for rotating image around center:
  translate(width/2, height/2);  
  rotate(angle*TWO_PI/360);
  translate(-img.width/2, -img.height/2);
  
  scale(zoom);      // zoom in and out according to user input
  image(img, x, y); //display the image
}
void keyPressed()
{
  switch(key)
  {
    case 'a': {  
                
                 ini="X";  //X is name of file in set 1
                 c--;      //change the image
                 break;  
              }
    case 'd': {  
                ini="X";  //X is name of file in set 1
                c++;      //change the image
                break;  
              }
    case 'w': {  
                ini = "Y"; //Y is the name of file in set 2
                c++;      //change the image       
                break;  
              }
    case 's': {  
                ini = "Y"; //Y is the name of file in set 2
                c--;       //change the image
                break; 
              }
    
    case 'i': angle++; break; //increase andgle
    case 'k': angle--; break; //decrease angle
    
    case '+': zoom+=0.1; break; //zoom in
    case '-': zoom-=0.1; break; //zoom out
    
    case 'j': x++; break; //move the image right
    case 'g': x--; break; //move the image left
    case 'h': y--; break; //move the image up    
    case 'y': y++; break; //move the image down
  }  
  //prevent the name of file from being out of reach
  if(c<0) c=0;
  else if(c>359) c=359;
}

The comments describe the working of the code.

With it you can create a viewer that helps you to rotate, zoom and view your every part of your object.

You can download the file View3D.pde . It contains all the required code you need.

Step 5: Build the Photo Booth

Using a pair of scissors, cut the top cover of your cardboard box. The cut pieces are not to be thrown. Now, cut any of the long side of the cardboard. Refer to picture for which side to cut. Now you have a small room with three walls. Use the remaining pieces to cover the bottom and make sure it is flat.

Now, cover the inner sides with white paper. This is the place where you will keep your rotating platform.

Connect your USB light to the USB port of your computer and place the box near your computer. Next, place the USB light so that the light falls all around around the center, where the object will be kept. Leave no room for shadows above the platform and the cardboard wall just behind the platform.

Step 6: Run the Code!

First, place the rotating platform inside the box. Keep the object at the center of the platform.

Next, Run the Image Capturing code (the code in Step 4). Position your USB light and increase the brightness so that the background of the object is white and only the object is visible. Move the position of your camera to an appropriate angle and height.

Switch on the motor to rotate the object.

Click once anywhere in the window where you can see the object. When the text in the bottom says "Click When Ready", turn the object to 90 degrees left and click again.

Again, the same message will be displayed. Now, you can switch off the motor and remove the object. Click again and images will be saved where you saved your code.

Create a new folder named "data" in the same location where you saved your Image viewing code (the code in Step 5). Inside this "data" folder, paste all these images.

Finally, run the code. The instructions are:

d - turn right

a - turn left

w - turn up

s - turn down

+ - zoom in

- - zoom out

y - move up

h - move down

g - move left

j - move right

i - rotate clockwise

k - rotate anticlockwise

You can use the captured images to make GIF files.

You can even export the viewing code to make an executable file for Windows as well as Linux and share it with your friends. Thus, you can share your 3-D images with your friends instead of the usual image which let you see only a part of an object. This can be useful in sharing what you make, even small products for digital advertisements.

Move It

Participated in the
Move It

Automation Contest

Participated in the
Automation Contest