Lazer Tarayıcı İle 3D Modelleme Yapımı
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:
- Arduino
- Mekaniği için lego
- Step motor
- Step motor sürücü
- Batarya
- Lineer lazer
- 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'); }
[wp-review]
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!
İ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?
kamera çözünürlüğünden kaynaklı olabilir. bir de geometri şeklinden kaynaklı çizginin kamera açısında iken kesikli yansıması olabilir.
kullanılan step motorun özellikleri ne olmalıdır?
yardımcı olur musunuz..
48 adım bipolar step motor.
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?
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.
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.
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