Inhoudsopgave:
Video: Basis 3D-scanner voor digitale 3D-toewijzing: 5 stappen
2024 Auteur: John Day | [email protected]. Laatst gewijzigd: 2024-01-30 11:15
In dit project zal ik de basisprincipes van 3D-scannen en reconstructie beschrijven en uitleggen die voornamelijk worden toegepast op het scannen van kleine semi-vlakke objecten, en waarvan de werking kan worden uitgebreid tot scan- en reconstructiesystemen die kunnen worden geïnstalleerd op op afstand bestuurbare vliegtuigen om een 3D-model. van de plaatsen waar het vliegtuig dat ze brengt, vliegt
Het uiteindelijke idee is om een 3D-scan te maken van een plaats of gebied, zowel de buitenkant als de binnenkant, om deze te gebruiken als een digitale kaart (zoals in de film van Prometeus)
Stap 1:
het idee is om het volledige 3D-scansysteem op een op afstand bestuurbaar vliegtuig te installeren om de virtuele kaart van elk gebied waarover het in 3D vliegt te digitaliseren, maar hiervoor zijn we begonnen vanaf het begin van de werking van de lasertriangulatiede methode van scannen of 3D-reconstructie door lasertriangulatie bestaat in feite uit het passeren van een laserstraal door een prisma dat een laserstreep genereert om een volledige laserstreep te verkrijgen die op een te scannen object wordt geprojecteerd, en zodra deze laserprojectie is verkregen op de oppervlakte oppervlak Van de plaats die moet worden gescand, moet het beeld worden vastgelegd met een soort camera en bij voorkeur de hoek kennen die wordt gevormd met betrekking tot de projectiehoek van de uitgezonden laserstreep, aangezien elk van deze beelden de geprojecteerde laserstroken vastlegt. Op het oppervlak van het object worden ze voorbewerkt om de dimensionale kenmerken van het te scannen object te extraheren en eenvoudig strook voor strook boven het object te scannen om het profiel van het oppervlak in dat transversale segment van het object te verkrijgen, en vervolgens vast te leggen de geprojecteerde strook van de volgende dwarsdoorsnede van het object, om alle geprojecteerde strepen bij elkaar op te tellen Vóór alle dwarsdoorsneden van de obto verkrijgen we een driedimensionale scan van het oppervlak
Stap 2:
Omdat we ons doel hebben geïdentificeerd, is de volgende stap, wetende dat om op te stijgen, je eerst stevig op de grond moet staan, dus zijn we op de grond begonnen met een experimenteel prototype van een lineaire 3D-scanner, om de juiste werking van de basis te valideren 3D-scanner en zoals je kunt zien in de afbeelding hierboven, gebruikte ik een pc, OpenCV, Glut of OpenGL, een webcam, een laser, een laserfarmgenerator (in dit geval door een roterende spiegel) een elektronisch lineair verplaatsingssysteem (gemaakt met een rail en systeem geëxtraheerd uit een oude printer) van een basis waarop ik de te scannen objecten, hout en plasticine plaats en zoals je op de foto kunt zien, op de computer: ik slaagde erin om met Glut van OpenGL een drie- dimensionaal model gereproduceerd op basis van het gescande echte object (in dit geval een speelgoedspin)
het is dus meer dan duidelijk dat het werkingsprincipe functioneel is en dat het met zijn respectievelijke aanpassingen en aanpassingen aan een vliegend systeem in staat zal zijn om een 3D-kaart te scannen en te reproduceren van het gebied waarin het vliegt.
Maar dit systeem zal alleen dienen om 3D-kaarten te verkrijgen van het buitenoppervlak van de plaatsen waar het overheen vliegt???…
Stap 3:
het in kaart brengen van het interieur van de grotten en kanalen (net als in de Prometeus-film) Dit 3D-scansysteem dient ook om driedimensionale modellen te reconstrueren van het interieur van grote en holle objecten zoals grotten, gebouwen, tunnels, enz. Het werkingsprincipe is precies hetzelfde als al beschreven en die in wezen uit het volgende bestaat:
- maak de foto van elke projectie van de laserstreep op het te scannen oppervlak
- filter en verwijder kleur uit afbeelding
- binariseer de kleur met een dynamische beelddrempel
- pas een randdetector toe om het vastgelegde profiel van elke laserprojectiedwarsdoorsnede te herkennen
- en selecteer met behulp van segmentatie de juiste rand voor de 3D-weergave van die dwarsdoorsnede van het object dat moet worden gescand en gereconstrueerd op de virtuele 3D-kaart
- vervolgens worden deze stappen eenvoudig herhaald voor elke foto die is genomen op een submanier van de laserstrepen die continu worden geprojecteerd door elke subsectie in subsectie.
laag voor laag van de weergave van de doorsneden worden achtereenvolgens toegevoegd totdat een puntenwolk wordt verkregen die wordt gevormd door vele weergaven van doorsneden van het in kaart te brengen object
Stap 4:
Daarna slaag ik voor de programma's voor beeldverwerking van de projecties van de oppervlakkige laserstrips. en van de virtuele 3D-reconstructie van deze sussieve transversale representaties in het uitgewerkte driedimensionale kaartmodel:
afbeelding verwerken:
N
#include #include "cv.h" #include "highgui.h" #include //#include #include #include #include
char f=0; char naam={"0.jpg"}; int n=0, s, x, y; CvScalar sp; BESTAND *NuPu;
void Writepoints() { char bufferx[33], buffery[33]; itoa (x, bufferx, 10); itoa (y, buffer, 10); fprintf(NuPu, bufferx); fprintf(NuPu, "\t"); fprintf(NuPu, buffer); fprintf(NuPu, "\n"); }
void noteblockInit() { NuPu=fopen("NuPu.txt", "w"); fseek(NuPu, 0, 0); fprintf(NuPu, "NP:"); fprintf(NuPu, "\n"); }
int main() { char argstr[128]; notitieblokInit(); cout<<"Teklea!…:"f; naam[0]=f; cout<
IplImage* img0=cvLoadImage("00.jpg", 0); if(f=='0') { for(y=1;yheight-2;y++) { for(x=1;xwidth-2;x++) { sp=cvGet2D(img0, y, x); if(sp.val[0]>50){Writepoints();n++;} } } else { for(y=1;yheight-2;y++) { for(x=1;xwidth-2;x++) { sp=cvGet2D(img1, y, x); if(sp.val[0]>50){Writepoints();n++;} } } } char buffer[33]; itoa (n, buffer, 10); fprintf(NuPu, "Fin:"); fprintf(NuPu, buffer); fprintf(NuPu, "\n"); fclose (NuPu);
cvWachtKey(0); //_execlp("calc.exe", "calc.exe", argstr, NULL); cvDestroyAllWindows(); cvReleaseImage(&afbeelding); cvReleaseImage(&img); cvReleaseImage(&img0); cvReleaseImage(&img1); cvReleaseImage(&img2); retourneer 0; }
3D-reconstructie:
#include ////////////////// #ifdef _APPLE_ #include #else #include #include #endif #include #include #include #include #include #include
#define violeta glColor3f(1, 0, 1) #define azul glColor3f(0, 0, 1) #define turkeza glColor3f(0, 1, 1) #define verde glColor3f(0, 1, 0) #define amarillo glColor3f(1, 1, 0) #define naranja glColor3f(1,.3, 0) #define rojo glColor3f(1, 0, 0) met namespace std; int s, Boton=1, Pulbut=1; float mx=0, my=0, mtx=0, mty=0, mtz=-5,0; const int Avance=1; tekenreeks, Aux; karakter Karakter='H'; BESTAND *NuPu; int NP, h, w; float G=0, n=0, cx[5000], cy[5000], x, y, ax, ay, az; int font=(int)GLUT_BITMAP_8_BY_13; statisch tekenlabel [100]; char-buffer [3]; GLfloat anguloCuboX = 0.0f; GLfloat anguloCuboY = 0.0f; GLfloat anguloEsfera = 0,0f; Glint ancho=500; Glint alt="500; int hazPerspectiva = 0; void reshape (int breedte, int hoogte) { glViewport (0, 0, breedte, hoogte); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(hazPerspectiva) gluPerspective(23.0f, (GLfloat)width/(GLfloat)height, 1.0f, 20.0f); anders glOrtho(-1, 1, -1, 1, -10, 10); glMatrixMode(GL_MODELVIEW); ancho = breedte; alt=hoogte; } void Kolorear(int K) { float Hip; x=(cx[s]-320)/480; y=(cy[s]-240)/640; Heup=sqrt(pow(x, 2)+pow(y, 2)); if((Hip>=0)&&(Hip=.07)&&(Hip=.14)&&(Hip=.21)&&(Hip=.28)&&(Hip=.35)&&(Hip=.42) &&(Hip<=.49)){violeta;} } void drawNuPu(void) { glColor3f(1, 1, 1); glBegin(GL_LINES); glVertex3f(.2, 0, 0); glVertex3f(-.2, 0, 0); glVertex3f(0,.2, 0); glVertex3f(0, -.2, 0); glEnd(); rojo; glBegin(GL_POINTS); for(n=0;n<10;n++) { for(s=0;s void setOrthographicProjection() { glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluOrtho2D(0, w, 0, h); glScalef (1, -1, 1); glTranslatef(0, -h, 0); glMatrixMode(GL_MODELVIEW); } void renderBitmapString(float x, float y, void *font, char *string) { char *c; glRasterPos2f(x, y); for (c=string; *c != '\0'; c++) { glutBitmapCharacter(font, *c); } } void display() { //mx=468; itoa (mx, buffer, 10); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// glLoadIdentity(); glColor3f(1.0, 1.0, 1.0); glRasterPos2f(-1,.9); //glutBitmapString(GLUT_BITMAP_TIMES_ROMAN_24); for;s<3;s++) { glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, buffer[s]); } glTranslatef(mty, -mtx, mtz); glRotatef(mx, 1.0f, 0.0f, 0.0f); glRotatef(my, 0.0f, 1.0f, 0.0f); drawNuPu(); /*glColor3f(1.0, 1.0, 1.0); glRasterPos2f(.5,.5); //glutBitmapString(GLUT_BITMAP_TIMES_ROMAN_24, "Hallo tekst"); glutBitmapCharacter(GLUT_BITMAP_TIMES_'ROMAN_24, '7);*/ /*glColor3f(1. 0f, 1.0f, 1.0f); setOrthographicProjection(); glPushMatrix(); glLoadIdentity(); renderBitmapString(30, 15, (void *)font, "GLUT Tutorial ---_------_@ 3D Tech");*/ glFlush(); glutSwapBuffers(); anguloCuboX+=0.1f; anguloCuboY+=0.1f; anguloEsfera+=0.2f; } void init() { glClearColor(0, 0, 0, 0); glEnable(GL_DEPTH_TEST); ancho = 500; alt=500; } void leer() { ifstream myfile("A:/Respaldo sept 2016/D/Respaldos/Respaldo compu CICATA april 2015/usb1/rekostruccion 3D en Especialidad CICATA/Software/Reconstructccion 3D/R3d_0\bin/Debug/NuPu.txt"); if (mijnbestand.is_open()) { s=0; while(getline(mijnbestand, regel)) { if((line[0]!='N')&&(line[0]!='F')) { Aux=line; lijn[0]=48; lijn[1]=48; lijn[2]=48; lijn[3]=48; cy[s]=atoi(line.c_str()); Hulp[4]=48; Hulp[5]=48; Hulp[6]=48; //Aux[7]=48; cx[s]=atoi(Aux.c_str()); s++; } } mijnbestand.close(); } else cout <1780)NP=1700; cout< ongeldig inactief () { display (); } void keyboard(unsigned char key, int x, int y) { switch(key) { case 'p': case 'P': hazPerspectiva=1; hervormen (ancho, alt); pauze; geval 'o': geval 'O': hazPerspectiva=0; hervormen (ancho, alt); pauze; geval 27: // ontsnappingsuitgang (0); pauze; } } void raton (int-knop, int-status, int x, int y) { /* GLUT_LEFT_BUTTON 0 GLUT_MIDDLE_BUTTON 1 GLUT_RIGHT_BUTTON 2 GLUT_DOWN 0 GLUT_UP 1 */ Boton=knop; Pulbut=staat; //mx=j; Scherm(); } void ratmov(int x, int y) { if((Boton==0)&(Pulbut==0)) { mx=y; mijn=x; } if((Boton==2)&(Pulbut==0)) { mtx=(y/200)-1; mty=(x/200)-1; } if((Boton==1)&(Pulbut==0)) { mtz=-(y/40)-5; } Scherm(); } int main(int argc, char **argv) { /*glutAddMenuEntry() glutAddSubMenu() glutAttachMenu() glutCreateMenu() glutSetMenu() glutStrokeCharacter() glutStrokeLength()*/ /*glReadPixels() framebuffer glGetPixelMapfv() geeft de gespecificeerde pixelkaart terug glGetPixelMapuiv() geeft de gespecificeerde pixelkaart terug glGetPointerv() Geeft het adres van de gespecificeerde aanwijzer.*/ Init(); koeloven(); glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition(50, 50); glutInitWindowSize(ancho, alt); glutCreateWindow("Cubo 1"); in het(); glutDisplayFunc(weergave); glutReshapeFunc(hervormen); glutIdleFunc(inactief); glutMouseFunc(raton); glutMotionFunc(ratmov); glutKeyboardFunc(toetsenbord); glutMainLoop(); retourneer 0; }
Stap 5:
voorlopig moet ik stoppen! … maar in het volgende hoofdstuk beloof ik je dat ik het zal implementeren op mijn Raspberry pi 3 of mijn jetson nanoboard, al gemonteerd op een op afstand bestuurbaar vliegtuig, of op een spinrobot om het interieur van grotten te scannen
Aanbevolen:
Terug naar de basis: solderen voor kinderen: 6 stappen (met afbeeldingen)
Back to Basics: Solderen voor kinderen: Of je nu een robot bouwt of met Arduino werkt, vorm "hands-on" elektronica tot prototyping van een projectidee, weten hoe te solderen komt van pas. solderen is een essentiële vaardigheid om te leren als iemand echt van elektr
MAAK JE EIGEN DIGITALE DASHBOARD OP GPS-BASIS VOOR EBIKE OF ELEKTRISCHE MOTORFIETS - Ajarnpa
MAAK JE EIGEN GPS-GEBASEERD DIGITAAL DASHBOARD VOOR EBIKE OF ELEKTRISCHE MOTORFIETS: HALLO IEDEREEN Deze keer kwam ik met een nieuwe instructable met zowel een stand-alone display als een logger met behulp van arduino mega 2560 en Nextion LCD-display En voor trackingdoeleinden kun je ook de NMEA-zinnen van GPS loggen in sdcard en natuurlijk project
Idee voor doe-het-zelf-activiteit voor weerstations voor 12+ jaar: 4 stappen
Idee voor doe-het-zelf-weerstationactiviteit voor 12-plussers: in deze activiteit zullen deelnemers hun weerstation opzetten, de lucht in sturen en de opnames (licht, temperatuur, vochtigheid) in realtime volgen via de Blynk-app. Bovendien leert u hoe u de geregistreerde waarden publiceert
Sewart Digitale Borduursoftware Basis: 4 Stappen
Sewart Digital Embroidery Software Basics: Het gebruik van digitale borduursoftware kan in het begin intimiderend en frustrerend lijken, maar met wat oefening en geduld en deze SUPER handige gids, zult u binnen de kortste keren een meester zijn. Deze gids zal zich richten op het gebruik van de software, SewArt Embroidery Digitalize
Water is de basis voor het menselijk leven: 4 stappen
Water is de basis voor het menselijk leven: Inleiding: Arduino gebruiken om een project te maken dat een functie bevat. Ik maak een Arduino-project dat je eraan herinnert om een bepaalde tijd water te drinken.Motivatie:Tegenwoordig besteden de meeste mensen het grootste deel van hun tijd aan hun werk en ze vaak voor