Låt oss laga: 3D skanner baserat på Arduino och bearbetning (9 / 13 steg)
Steg 9: bearbetning
Första sak att göra i bearbetningen är installation av GSVideo bibliotek. Instruktioner för nedladdning och installation är det: http://gsvideo.sourceforge.net/
Så i princip program sekvens ser något ut som, men det är uppdelat i 2 slingor (göra bilder och resten):
gör bilden = > hitta ljusaste pixel i varje rad = > Spara bild representation ljusaste pixlar = > hitta avståndet mellan mitten av bilden och ljusaste pixel i varje rad = > Konvertera samlades Polära koordinater till kartesian XYZ = > Spara ASC fil med punktmoln.
Förklaring finns i kommentarer i kod.
Första sak måste göras preety snart är inställningen där Z-värdet är lika 0. Nu ligger Z = 0 inte på mitten av plattform, men på den första raden i foto. Detta orsakar att punktmoln output är uppochner.
kod: objekt färger variabler scanner parametrar koordinater //================= CONFIG =================== void setup() { typsnitt kamera conf. Följetong (COM) conf. utdatafil } === MAIN PROGRAM === void draw() { PImage zdjecie=createImage(cam.width,cam.height,RGB); } void licz() { String nazwaPliku = "zdjecie-" + nf(itr+1, 3) + "png"; för (rad = 0; rad < skan.height; rad ++) {//starting rad analys
import codeanticode.gsvideo.*;
import processing.serial.*;
PFont f;
GSCapture cam;
Seriella myPort;
PrintWriter utgång;
färg black=color(0);
färg white=color(255);
int itr; iteration
float pixBright;
flyta maxBright = 0;
int maxBrightPos = 0;
int prevMaxBrightPos;
int cntr = 1;
int raden;
int col;
flyta odl = 210; avståndet mellan webbkamera och roterande axel, [milimeter], inte använt ännu
flyta etap = 120; antal faser profilering per varv
flyta katLaser = 25 * PI/180; vinkeln mellan laser och kamera [radian]
flyta katOperacji = 2 * PI/etap; vinkeln mellan 2 profiler [radian]
float x, y, z; kartesiska sladdar., [milimeter]
float ro; första av polär koordinat, [milimeter]
float fi; andra av polär koordinat, [radian]
float b; avståndet mellan ljusaste pixel och mitten av foto [pixlar]
flyta pxmmpoz = 5; pixlar per milimeter horisontellt 1px = 0,2 mm
flyta pxmmpion = 5; pixlar per milimeter vertikalt 1px = 0,2 mm
storlek (800, 600);
strokeWeight(1);
Smooth();
Background(0);
f=createFont("Arial",16,true);
String [] avcams=GSCapture.list();
om (avcams.length==0) {
println ("det finns inga kameror för fånga.");
textFont(f,12);
Fill(255,0,0);
text ("Kamera inte redo", 680, 32);
}
annat {
println ("tillgängliga kameror:");
för (int jag = 0; jag < avcams.length; i ++) {
println(avcams[i]);
}
textFont(f,12);
Fill(0,255,0);
text ("kameran redo", 680, 32);
cam = nya GSCapture (denna, 640, 480,avcams[0]);
cam.start();
}
println(Serial.list());
myPort = ny följetong (denna, Serial.list() [0], 9600);
output=createWriter("skan.ASC"); plik wynikowy *.asc
cam.Read();
Delay(2000);
för (itr = 0; itr < etap; itr ++) {
cam.Read();
zdjecie.loadPixels();
cam.loadPixels();
för (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();
för (itr = 0; itr < etap; itr ++) {
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);
maxBrightPos = 0;
maxBright = 0;
för (col = 0; col < skan.width, col ++) {
currentPos = ror * skan.width + col;
pixBright=brightness(skan.pixels[currentPos]);
IF(pixBright>maxBright) {
maxBright = pixBright;
maxBrightPos = currentPos;
}
odwz.pixels[currentPos]=Black; ställa in alla pixlar svart
}
odwz.pixels[maxBrightPos]=White; inställningen ljusaste pixel vit
b = ((maxBrightPos+1-row*skan.width)-skan.width/2) / pxmmpoz;
ro=b/sin(katLaser);
output.println (b + "," + prevMaxBrightPos + "," + maxBrightPos); Jag använde detta för felsökning
x = ro * cos(fi); ändra polar coords till kartesian
y = ro * sin(fi);
z = rad/pxmmpion;
om ((ro > = 30) & & (ro < = 60)) {//printing koordinater
output.println (x + "," y + "," + z);
}
} //end rad analys
odwz.updatePixels();
odwz.Save(nazwaPliku2);
}
output.flush();
output.Close();
}
void obroc() {//sending kommandot för att stänga
myPort.write('S');
Delay(50);
myPort.write('K');
}