Sommario:
Video: Scanner 3D di base per la mappatura 3D digitale: 5 passaggi
2024 Autore: John Day | [email protected]. Ultima modifica: 2024-01-30 10:01
In questo progetto descriverò e spiegherò i fondamenti di base della scansione e ricostruzione 3D applicata principalmente alla scansione di piccoli oggetti semipiani e il cui funzionamento può essere esteso ai sistemi di scansione e ricostruzione che possono essere installati su velivoli telecomandati per ottenere un modello 3D. dei luoghi dove l'aereo che li porta installato vola
L'idea finale è quella di ottenere una scansione 3D di un luogo o di un'area, sia esterna che interna, per utilizzarla come mappa digitale (come nel film di Prometeus)
Passo 1:
l'idea è quella di installare l'intero sistema di scansione 3d su un aereo telecomandato, in modo da digitalizzare la mappa virtuale di qualsiasi area su cui si sorvola in 3d, ma per questo siamo partiti dall'inizio dell'operazione di triangolazione laser il metodo della scansione o ricostruzione 3d mediante triangolazione laser consiste essenzialmente nel far passare un raggio laser attraverso un prisma che genera una striscia laser per ottenere un'intera striscia laser che verrà proiettata su un oggetto da scansionare, e una volta ottenuta tale proiezione laser sul superficie superficie Dal luogo da scansionare, l'immagine deve essere catturata con qualche tipo di macchina fotografica e preferibilmente conoscendo l'angolo che si forma rispetto all'angolo di proiezione della striscia laser emessa, poiché ciascuna di queste immagini cattura le strisce laser proiettate. Sulla superficie dell'oggetto, verranno pretrattati per estrarre le caratteristiche dimensionali dell'oggetto da scansionare, e semplicemente scansionare striscia per striscia sopra l'oggetto per ottenere il profilo della sua superficie in quel segmento trasversale dell'oggetto, e successivamente catturare la striscia proiettata della successiva sezione trasversale dell'oggetto, per sommare tutte le strisce proiettate insieme Prima di tutte le sezioni trasversali dell'obto si ottiene una scansione tridimensionale della sua superficie
Passo 2:
Dato che abbiamo individuato il nostro obiettivo, il passo successivo sapendo che per decollare bisogna prima avere i piedi ben saldi a terra, quindi siamo partiti a terra con un prototipo sperimentale di scanner 3d lineare, per validare il corretto funzionamento della base Scanner 3d e come potete vedere nell'immagine sopra, ho utilizzato un PC, OpenCV, Glut di OpenGL, una webcam, un laser, generatore di laser farm (in questo caso tramite uno specchio rotativo) un sistema elettronico di spostamento lineare (realizzato con un binario e sistema estratto da una vecchia stampante) da una base su cui poggio gli oggetti da scansionare, legno e plastilina e come potete vedere nella foto, sul computer: sono riuscito a generare e visualizzare con Glut da OpenGL un tre- modello dimensionale riprodotto sulla base dell'oggetto reale scansionato (in questo caso un ragno giocattolo)
quindi è più che evidente che il principio di funzionamento è funzionale, e che con le relative regolazioni e adattamenti ad un sistema di volo sarà in grado di scansionare e riprodurre una mappa 3d dell'area in cui vola.
Ma questo sistema servirà solo per ottenere mappe 3D della superficie esterna dei luoghi su cui sorvola???…
Passaggio 3:
mappatura dell'interno delle grotte e dei condotti (proprio come nel film Prometeus) Questo sistema di scansione 3D serve anche a ricostruire modelli tridimensionali dell'interno di oggetti grandi e cavi come grotte, edifici, gallerie, ecc. Il suo principio di funzionamento è esattamente uguale a quanto già descritto e che sostanzialmente consiste in quanto segue:
- cattura la foto di ogni proiezione della striscia laser sulla superficie da scansionare
- filtra e rimuovi il colore dall'immagine
- binarizzare il colore con una soglia dell'immagine dinamica
- applicare un rilevatore di bordi per riconoscere il profilo catturato di ciascuna sezione trasversale di proiezione laser
- e utilizzando la segmentazione selezionare il bordo appropriato per la rappresentazione 3d di quella sezione trasversale dell'oggetto da scansionare e ricostruire sulla mappa 3D virtuale
- quindi questi passaggi vengono semplicemente ripetuti per ogni foto scattata in modo subordinato alle strisce laser proiettate in modo continuo da ciascuna sottosezione in sottosezione.
strato per strato della rappresentazione delle sezioni trasversali vengono aggiunti successivamente fino ad ottenere una nuvola di punti formata da tante rappresentazioni delle sezioni trasversali dell'oggetto da mappare
Passaggio 4:
Poi passo ai programmi per l'elaborazione delle immagini delle proiezioni delle strisce laser superficiali. e della ricostruzione virtuale 3d di queste rappresentazioni sussive trasversali nel modello cartografico tridimensionale elaborato:
elaborazione delle immagini:
n
#include #include "cv.h" #include "highgui.h" #include //#include #include #include #include
carattere f=0; nome carattere={"0.jpg"}; int n=0, s, x, y; CvScalar sp; FILE *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]; noteblockInit(); cout<<"Teklea!…:"f; nome[0]=f; cout<
IplImage* img0=cvLoadImage("00.jpg", 0); if(f=='0') { for(y=1;yaltezza-2;y++) { for(x=1;xlarghezza-2;x++) { sp=cvGet2D(img0, y, x); if(sp.val[0]>50){Writepoints();n++;} } } } else { for(y=1;yaltezza-2;y++) { for(x=1;xlarghezza-2;x++) { sp=cvGet2D(img1, y, x); if(sp.val[0]>50){Writepoints();n++;} } } } char buffer[33]; itoa (n, tampone, 10); fprintf(NuPu, "Fina:"); fprintf(NuPu, buffer); fprintf(NuPu, "\n"); fclose(NuPu);
cvWaitKey(0); //_execlp("calc.exe", "calc.exe", argstr, NULL); cvDestroyAllWindows(); cvReleaseImage(&image); cvReleaseImage(&img); cvReleaseImage(&img0); cvReleaseImage(&img1); cvReleaseImage(&img2); restituisce 0; }
Ricostruzione 3D:
#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) using namespace std; int s, Boton=1, Pulbut=1; float mx=0, mio=0, mtx=0, mty=0, mtz=-5.0; const int Avance=1; linea di stringa, Aux; carattere Carattere='H'; FILE *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; etichetta carattere statico[100]; buffer di caratteri[3]; GLfloat anguloCuboX = 0.0f; GLfloat anguloCuboY = 0.0f; GLfloat anguloEsfera = 0.0f; GLint ancora=500; GLint alto=500; int hazPerspectiva = 0; void reshape(int larghezza, int altezza) { glViewport(0, 0, larghezza, altezza); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(hazPerspectiva) gluPerspective(23.0f, (GLfloat)width/(GLfloat)height, 1.0f, 20.0f); else glOrtho(-1, 1, -1, 1, -10, 10); glMatrixMode(GL_MODELVIEW); ancho = larghezza; alto = altezza; } void Kolorear(int K) { float Hip; x=(cx[s]-320)/480; y=(cy[s]-240)/640; Anca=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); gEnd(); rosso; 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, "Hello Text");;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, "Hello Text"); glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, '7');*/ /*glColor3f(1. 0f, 1.0f, 1.0f); setOrthographicProjection(); glPushMatrix(); glLoadIdentity(); renderBitmapString(30, 15, (void *)font, "Esercitazione GLUT ---_------_@ 3D Tech");*/ glFlush(); glutSwapBuffers(); anguloCuboX+=0.1f; anguloCuboY+=0.1f; anguloEsfera+=0.2f; } void init() { glClearColor(0, 0, 0, 0); glEnable(GL_DEPTH_TEST); ancora = 500; contralto = 500; } void leer() { ifstream myfile("A:/Respaldo sept 2016/D/Respaldos/Respaldo compu CICATA abril 2015/usb1/rekostruccion 3D en Especialidad CICATA/Software/Reconstruccion 3D/R3d_0\bin/Debug/NuPu.txt"); if (miofile.is_open()) { s=0; while(getline(myfile, line)) { if((line[0]!='N')&&(line[0]!='F')) { Aux=line; riga[0]=48; riga[1]=48; riga[2]=48; riga[3]=48; cy[s]=atoi(line.c_str()); Ausiliario[4]=48; Ausiliario[5]=48; Ausiliario[6]=48; //Aux[7]=48; cx[s]=atoi(Aux.c_str()); s++; } } miofile.close(); } else cout <1780)NP=1700; cout< void inattivo() { display(); } void keyboard(unsigned char key, int x, int y) { switch(key) { case 'p': case 'P': hazPerspectiva=1; rimodellare(ancho, alto); rottura; case 'o': case 'O': hazPerspectiva=0; rimodellare(ancho, alto); rottura; case 27: // escape exit(0); rottura; } } void raton(int button, int state, int x, int y) { /* GLUT_LEFT_BUTTON 0 GLUT_MIDDLE_BUTTON 1 GLUT_RIGHT_BUTTON 2 GLUT_DOWN 0 GLUT_UP 1 */ Boton=button; Pulbut=stato; //mx=y; Schermo(); } void ratmov(int x, int y) { if((Boton==0)&(Pulbut==0)) { mx=y; mio=x; } if((Boton==2)&(Pulbut==0)) { mtx=(y/200)-1; mty=(x/200)-1; } if((Boton==1)&(Pulbut==0)) { mtz=-(y/40)-5; } Schermo(); } int main(int argc, char **argv) { /*glutAddMenuEntry() glutAddSubMenu() glutAttachMenu() glutCreateMenu() glutSetMenu() glutStrokeCharacter() glutStrokeLength()*/ /*glReadPixels() legge un blocco di pixel dal frame buffer glGetPixelMapfv() restituisce la mappa di pixel specificata glGetPixelMapuiv() restituisce la mappa di pixel specificata glGetPointerv() Restituisce l'indirizzo del puntatore specificato.*/ Init(); leer(); glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition(50, 50); glutInitWindowSize(ancho, alto); glutCreateWindow("Cubo 1"); dentro(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutIdleFunc(idle); glutMouseFunc(raton); glutMotionFunc(ratmov); glutKeyboardFunc(tastiera); glutMainLoop(); restituisce 0; }
Passaggio 5:
per il momento mi devo fermare! …ma nel prossimo capitolo vi prometto che lo realizzerò sul mio raspberry pi 3 o sulla mia nanoboard jetson, già montata su qualche aereo telecomandato, o su qualche robot ragno per scansionare l'interno delle caverne
Consigliato:
Suggerimenti per la mappatura: 3 passaggi
Suggerimenti per la mappatura: qualunque sia la tua attività, che si tratti di camminare, fare escursioni, andare in bicicletta o persino guidare, puoi registrare i percorsi che fai. Quindi puoi condividere questi percorsi con amici e familiari. Inoltre, puoi utilizzare il percorso registrato per aggiungere posizioni a qualsiasi foto che potresti
Mappatura del controller di gioco per PC (Linux e Windows): 5 passaggi
Mappatura del controller di gioco per PC (Linux e Windows): se stai iniziando nel campo dei giochi su un personal computer, potresti dover eseguire alcuni passaggi per arrivarci. Oggi ti mostrerò come utilizzare un controller di gioco USB con anche il più vecchio dei giochi per PC, gratuitamente. La tecnica
The Mappifier - Mappatura + Sistema di notifica: 9 passaggi
The Mappifier - Mappatura + Sistema di notifica: la guida notturna è molto divertente. Ma spesso si rivela un incubo, sotto forma di animali che attraversano la strada (soprattutto quei cani e gatti randagi, che aspettano che tu guidi vicino a loro in modo che possano attraversare!!). Allora ho pensato di fare così
Mappatura dell'inquinamento atmosferico di CEL (modificata): 7 passaggi
Air Pollution Maper di CEL (Modificato): L'inquinamento atmosferico è un problema globale nella società di oggi, è causa di numerose malattie e causa disagio. Questo è il motivo per cui abbiamo cercato di costruire un sistema in grado di tracciare sia la tua posizione GPS che l'inquinamento atmosferico in quel punto esatto, per poi essere
Preallarme Raspberry PI Runway Light utilizzando i dati di mappatura di volo: 14 passaggi (con immagini)
Avviso anticipato Luce pista Raspberry PI utilizzando i dati di mappatura di volo: questa lampada è nata da diversi motivi in quanto sono sempre interessato agli aerei che volano sopra la testa e durante l'estate nei fine settimana ce ne sono spesso alcuni piuttosto eccitanti che volano in giro. Anche se tendi a sentirli solo mentre passano