Lazer Tarayıcı İle 3D Modelleme Yapımı

9 3.370

Lazerden nesnenin üzerine düşen ışınlar nesnenin şeklini alırlar ve bu çizgiler  webcam üzerinden processing arayüze gönderilir.Gönderilen her çizginin 3 boyutlu koordinatları processingde işelenerek asc dosya uzantısında kaydedilir.Kaydedilen dosyayı meshlab 3d modelleme programına import ederek model oluşturulur.

Malzemeler:

  1. Arduino
  2. Mekaniği için lego
  3. Step motor
  4. Step motor sürücü
  5. Batarya
  6. Lineer lazer
  7. Webcam

 

Elektronik Kısım:

 

Mekanik Kısımlar:

Arduino Yazılımı

#include <Stepper.h>
Stepper oki(48,8,9); //see stepper tutorial in arduino.cc for info about that
const int ledPin = 13; // the pin that the LED is attached to
int incomingByte; // a variable to read incoming serial data into
 
void setup() {
 // initialize serial communication:
 Serial.begin(9600);
 // initialize the LED pin as an output:
 pinMode(ledPin, OUTPUT);
 oki.setSpeed(60);
}
 
void loop() {
 // see if there's incoming serial data:
 if (Serial.available() > 0) {
 // read the oldest byte in the serial buffer:
 incomingByte = Serial.read();
 // if it's a capital H (ASCII 72), turn on the LED:
 if (incomingByte == 'S') {
 digitalWrite(ledPin, HIGH);
 oki.step(4);
 }
 // if it's an L (ASCII 76) turn off the LED:
 if (incomingByte == 'K') {
 digitalWrite(ledPin, LOW);
 }
 }
}

Processing Yazılımı

import codeanticode.gsvideo.*;
import processing.serial.*;
 
//objects
PFont f;
GSCapture cam;
Serial myPort;
PrintWriter output;
 
//colors
color black=color(0);
color white=color(255);
 
//variables
int itr; //iteration
float pixBright;
float maxBright=0;
int maxBrightPos=0;
int prevMaxBrightPos;
int cntr=1;
int row;
int col;
 
//scanner parameters
float odl = 210; //distance between webcam and turning axle, [milimeter], not used yet
float etap = 120; //number of phases profiling per revolution
float katLaser = 25*PI/180; //angle between laser and camera [radian]
float katOperacji=2*PI/etap; //angle between 2 profiles [radian]
 
//coordinates
float x, y, z; //cartesian cords., [milimeter]
float ro; //first of polar coordinate, [milimeter]
float fi; //second of polar coordinate, [radian]
float b; //distance between brightest pixel and middle of photo [pixel]
float pxmmpoz = 5; //pixels per milimeter horizontally 1px=0.2mm
float pxmmpion = 5; //pixels per milimeter vertically 1px=0.2mm
 
//================= CONFIG ===================
 
void setup() {
 size(800, 600);
 strokeWeight(1);
 smooth();
 background(0);
 
 //fonts
 f=createFont("Arial",16,true);
 
 //camera conf.
 String[] avcams=GSCapture.list();
 if (avcams.length==0){
 println("There are no cameras available for capture.");
 textFont(f,12);
 fill(255,0,0);
 text("Camera not ready",680,32);
 }
 else{
 println("Available cameras:");
 for (int i = 0; i < avcams.length; i++) {
 println(avcams[i]);
 }
 textFont(f,12);
 fill(0,255,0);
 text("Camera ready",680,32);
 cam=new GSCapture(this, 640, 480,avcams[0]);
 cam.start();
 }
 
 //Serial (COM) conf.
 println(Serial.list());
 myPort=new Serial(this, Serial.list()[0], 9600);
 
 //output file
 output=createWriter("skan.asc"); //plik wynikowy *.asc
 
 
 
}
 
//============== MAIN PROGRAM =================
 
void draw() {
 
 PImage zdjecie=createImage(cam.width,cam.height,RGB);
 cam.read();
 delay(2000);
 for (itr=0;itr<etap;itr++) {
 cam.read();
 zdjecie.loadPixels();
 cam.loadPixels();
 for (int n=0;n<zdjecie.width*zdjecie.height;n++){
 zdjecie.pixels[n]=cam.pixels[n];
 }
 zdjecie.updatePixels();
 set(20,20,cam);
 String nazwaPliku="zdjecie-"+nf(itr+1, 3)+".png";
 zdjecie.save(nazwaPliku);
 obroc();
 delay(500);
 }
 obroc();
 licz();
 noLoop();
 
}
 
void licz(){
 for (itr=0; itr<etap; itr++){
 
 String nazwaPliku="zdjecie-"+nf(itr+1, 3)+".png";
 PImage skan=loadImage(nazwaPliku);
 String nazwaPliku2="odzw-"+nf(itr+1, 3)+".png";
 PImage odwz=createImage(skan.width, skan.height, RGB);
 skan.loadPixels();
 odwz.loadPixels();
 int currentPos;
 fi=itr*katOperacji;
 println(fi);
 
 for(row=0; row<skan.height; row++){ //starting row analysis
 maxBrightPos=0;
 maxBright=0;
 for(col=0; col<skan.width; col++){
 currentPos = row * skan.width + col;
 pixBright=brightness(skan.pixels[currentPos]);
 if(pixBright>maxBright){
 maxBright=pixBright;
 maxBrightPos=currentPos;
 }
 odwz.pixels[currentPos]=black; //setting all pixels black
 }
 
 odwz.pixels[maxBrightPos]=white; //setting brightest pixel white
 
 b=((maxBrightPos+1-row*skan.width)-skan.width/2)/pxmmpoz;
 ro=b/sin(katLaser);
 //output.println(b + ", " + prevMaxBrightPos + ", " + maxBrightPos); //I used this for debugging
 
 x=ro * cos(fi); //changing polar coords to kartesian
 y=ro * sin(fi);
 z=row/pxmmpion;
 
 if( (ro>=-30) && (ro<=60) ){ //printing coordinates
 output.println(x + "," + y + "," + z);
 }
 
 }//end of row analysis
 
 odwz.updatePixels();
 odwz.save(nazwaPliku2);
 
 }
 output.flush();
 output.close();
}
 
void obroc() { //sending command to turn
 myPort.write('S');
 delay(50);
 myPort.write('K');
}
Bunlar da İlgini Çekebilir

Cevap bırakın

E-posta hesabınız yayımlanmayacak.

  1. Hasan Koç

    Hocam merhaba, öncelikle yaptığınız çalışma ve paylaşımınızdan dolayı size teşekkür ve tebrik ederim çok güzel bir çalışma.Benim burada sormak istediğim kullandığınız kamera normal webcam mi yoksa görüntü işlemeyle ilgili özellikli bir kamera mı?Teşekkürler!

  2. Semiye

    İyi akşamlar lazer taraması yaparken David programına aktarılan görüntü net bir şekilde elde edilmiyor.(Kullandığımız webcam logitech 5 mp.)Ayrıca tarama yaparken cismin orta ve alt kısımlarının görüntülerinde boşluklar oluşuyor.Sizce sorun nerede olabilir yardımcı olabilir misiniz?

    1. Sezgin GÜL

      kamera çözünürlüğünden kaynaklı olabilir. bir de geometri şeklinden kaynaklı çizginin kamera açısında iken kesikli yansıması olabilir.

  3. ibrahim süsli

    kullanılan step motorun özellikleri ne olmalıdır?
    yardımcı olur musunuz..

    1. Sezgin GÜL

      48 adım bipolar step motor.

  4. Kerimhan Bilgin

    Merhaba, bir kaç soruma olacak; Lineer lazer’i nereden temin edebilirim ve 3d modellemeyi yaptıktan sonra (*.asc) uzantılı dosyayı hangi yazılımda açabilirim?

    1. Sezgin GÜL

      Merhaba Kerimhan, Normal lazeri bardak kadehin sap kısmından geçirirsen ışık kırılmaya uğradığından lineer çıkış alacaktır. (*.asc) dosyayı meshlab programından açabilirsiniz.Ayrıca Autodesk 123d programı ile de ister telefondan isterseniz de bilgisayarınızdan nesnelerin 3d modelini çıkarabilirsiniz.Telefondan modelleme en basit şekildir.

      1. KERİMHAN BİLGİN

        Cevabınız için teşekkürler hocam elimden geldiğince ve imkanlarım el verdikçe yaptığınız tüm projeleri uygulamaya çalışıyorum. Bu projeyide yapmak için işe koyulmayı düşünüyorum fakat Arduino Uno’un hangi pinlerine bağlantı yapıcam konu üzerinde böyle bir bilgiye veya şemaya rastlamadığım için soruyorum. Çok soru sordum ve vaktinizi aldım hakkınızı helal edin.

        1. Sezgin GÜL

          Arduino 8 ve 9. dijital pinleri l293d sürücünün motor sinyal pinine bağla.Step motorun pinleri zaten sürücünün 4 tane motor pinine bağlanacak.Şekilde motor pinleri gösterilmiş.Burda step motor sadece bir yönde döneceğinden sürücünün bir tarafındaki sinyal pinlerini kullanıyoruz.Processing yazılımı yenilendi.Kamera modelin karşısına konulacak.Lazer ise kamera ile belli bir açıda modele yansıtılacak şekilde yerleştirilecek.Şekilde açı gösterilmiş.Modelin altındaki motor her dönüşte lazerden gelen ışınla taranacak ve kamera oluşan çizgisel yüzeyleri processing e aktaracak.Burda arduinonun görevi motoru döndürmektir.Asıl işi yapan processing görüntü işlemedir.
          Helal olsun.Lütfen Takıldığınız noktada sormaktan çekinmeyin. İyi çalışmalar