Cuprins:

Scanner 3D de bază pentru cartografiere digitală 3D: 5 pași
Scanner 3D de bază pentru cartografiere digitală 3D: 5 pași
Anonim
Scanner 3D de bază pentru cartografiere digitală 3D
Scanner 3D de bază pentru cartografiere digitală 3D

În acest proiect, voi descrie și explica bazele de bază ale scanării și reconstrucției 3D aplicate în primul rând scanării obiectelor semi-plane mici și a căror funcționare poate fi extinsă la sistemele de scanare și reconstrucție care pot fi instalate pe aeronavele cu telecomandă pentru a obține un model 3D. a locurilor unde avionul care le ia instalat zboară

Ideea finală este de a obține o scanare 3D a unui loc sau zonă, fie exterioară, fie interioară, pentru a o folosi ca hartă digitală (ca în filmul lui Prometeu)

Pasul 1:

Imagine
Imagine

ideea este de a instala întregul sistem de scanare 3d pe un plan controlat de la distanță, pentru a digitaliza harta virtuală a oricărei zone peste care zboară în 3d, dar pentru aceasta am început de la începutul operației de triangulare laser metoda de scanare sau reconstrucție 3D prin triangulare laser constă practic în trecerea unui fascicul laser printr-o prismă care generează o bandă laser pentru a obține o bandă laser întreagă care va fi proiectată pe un obiect care urmează să fie scanat și, odată ce această proiecție laser a fost obținută pe suprafața suprafeței De la locul de scanare, imaginea trebuie capturată cu un anumit tip de cameră și, de preferință, cunoscând unghiul care se formează în raport cu unghiul de proiecție al benzii laser emise, deoarece fiecare dintre aceste imagini surprinde benzile laser proiectate. Pe suprafața obiectului, acestea vor fi preprocesate pentru a extrage caracteristicile dimensionale ale obiectului care urmează să fie scanat și pur și simplu scanează bandă cu bandă deasupra obiectului pentru a obține profilul suprafeței sale în acel segment transversal al obiectului și, ulterior, pentru a captura fâșia proiectată a următoarei secțiuni transversale a obiectului, pentru a adăuga toate fâșiile proiectate împreună Înainte de toate secțiunile transversale ale obto-ului obținem o scanare tridimensională a suprafeței sale

Pasul 2:

Imagine
Imagine

Deoarece ne-am identificat obiectivul, următorul pas știind că pentru a decola trebuie să aveți mai întâi picioarele ferm pe pământ, așa că am început pe pământ cu un prototip experimental de scaner 3d liniar, pentru a valida funcționarea corectă a sistemului de bază. Scanner 3D și după cum puteți vedea în imaginea de mai sus, am folosit un computer, OpenCV, Glut of OpenGL, o cameră web, un laser, un generator de fermă laser (în acest caz printr-o oglindă rotativă) un sistem electronic de deplasare liniară (realizat cu o șină și sistem extras dintr-o imprimantă veche) dintr-o bază pe care așez obiectele de scanat, lemn și plastilină și după cum puteți vedea în fotografie, pe computer: am reușit să generez și să afișez cu Glut de la OpenGL un model dimensional reprodus pe baza obiectului real scanat (în acest caz un păianjen de jucărie)

deci este mai mult decât evident că principiul de funcționare este funcțional și că, cu ajustările și adaptările sale respective la un sistem de zbor, va putea să scaneze și să reproducă o hartă 3D a zonei în care zboară.

Dar acest sistem va servi doar pentru a obține hărți 3D ale suprafeței exterioare a locurilor pe care le zboară ??? …

Pasul 3:

Imagine
Imagine

cartografierea interiorului peșterilor și canalelor (la fel ca în filmul Prometeus) Acest sistem de scanare 3D servește, de asemenea, la reconstrucția modelelor tridimensionale ale interiorului obiectelor mari și goale, cum ar fi peșteri, clădiri, tuneluri, etc. exact la fel ca deja descris și care constă în principiu în următoarele:

  1. surprindeți fotografia fiecărei proiecții a benzii laser pe suprafața de scanat
  2. filtrați și eliminați culoarea din imagine
  3. binarizează culoarea cu un prag de imagine dinamic
  4. aplicați un detector de margine pentru a recunoaște profilul capturat al fiecărei secțiuni transversale de proiecție laser
  5. și folosind segmentarea selectați chenarul adecvat pentru reprezentarea 3D a acelei secțiuni transversale a obiectului care urmează să fie scanat și reconstituit pe harta 3D virtuală
  6. apoi acești pași sunt repetați pur și simplu pentru fiecare fotografie făcută într-o sub-manieră a benzilor laser proiectate continuu de fiecare sub-secțiune din subsecțiune.
  7. strat cu strat al reprezentării secțiunilor transversale se adaugă succesiv până la obținerea unui nor de punct format din mai multe reprezentări ale secțiunilor transversale ale obiectului care trebuie mapat

Pasul 4:

Imagine
Imagine

Apoi trec programele de procesare a imaginilor proiecțiilor benzilor laser superficiale. și a reconstrucției virtuale 3D a acestor reprezentări transversale sussive în modelul de hartă tridimensional elaborat:

procesarea imaginii:

n

#include #include "cv.h" #include "highgui.h" #include // # include #include #include #include

char f = 0; char name = {"0.jpg"}; int n = 0, s, x, y; CvScalar sp; FIȘIER * NuPu;

void Writepoints () {char bufferx [33], buffery [33]; itoa (x, bufferx, 10); itoa (y, tampon, 10); fprintf (NuPu, bufferx); fprintf (NuPu, "\ t"); fprintf (NuPu, tampon); 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; nume [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 ++;}}}} buff buff [33]; itoa (n, tampon, 10); fprintf (NuPu, "Fin:"); fprintf (NuPu, tampon); 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); retur 0; }

Reconstrucție 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) folosind spațiul de nume std; int s, Boton = 1, Pulbut = 1; float mx = 0, my = 0, mtx = 0, mty = 0, mtz = -5.0; const int Avance = 1; linie de șir, Aux; char Caracter = „H”; FIȘIER * 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; etichetă de caracter static [100]; tampon char [3]; GLfloat anguloCuboX = 0,0f; GLfloat anguloCuboY = 0,0f; GLfloat anguloEsfera = 0,0f; GLint ancho = 500; GLint alto = 500; int hazPerspectiva = 0; remodelare nulă (lățime int, înălțime int) {glViewport (0, 0, lățime, înălțime); 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 = lățime; alto = inaltime; } void Kolorear (int K) {float Hip; x = (cx [s] -320) / 480; y = (cy [s] -240) / 640; Hip = 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_T_ES);; 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");); * / / * glColor3f (1. 0f, 1.0f, 1.0f); setOrthographicProjection (); glPushMatrix (); glLoadIdentity (); renderBitmapString (30, 15, font (void *), "Tutorial 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); ancho = 500; alto = 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 (myfile.is_open ()) {s = 0; while (getline (myfile, line)) {if ((line [0]! = 'N') && (line [0]! = 'F')) {Aux = line; linia [0] = 48; linia [1] = 48; linia [2] = 48; linia [3] = 48; cy [s] = atoi (line.c_str ()); Aux [4] = 48; Aux [5] = 48; Aux [6] = 48; // Aux [7] = 48; cx [s] = atoi (Aux.c_str ()); s ++; }} fișierul meu.close (); } else cout <1780) NP = 1700; cout <void idle () {display (); } void keyboard (tastă char nesemnată, int x, int y) {switch (key) {case 'p': case 'P': hazPerspectiva = 1; remodela (ancho, alto); pauză; case 'o': case 'O': hazPerspectiva = 0; remodela (ancho, alto); pauză; caz 27: // escape escape (0); pauză; }} void raton (butonul int, starea int, int x, int y) {/ * GLUT_LEFT_BUTTON 0 GLUT_MIDDLE_BUTTON 1 GLUT_RIGHT_BUTTON 2 GLUT_DOWN 0 GLUT_UP 1 * / Boton = buton; Pulbut = stare; // mx = y; afişa(); } void ratmov (int x, int y) {if ((Boton == 0) & (Pulbut == 0)) {mx = y; al meu = x; } if ((Boton == 2) & (Pulbut == 0)) {mtx = (y / 200) -1; mty = (x / 200) -1; } if ((Boton == 1) & (Pulbut == 0)) {mtz = - (y / 40) -5; } display (); } int main (int argc, char ** argv) {/ * glutAddMenuEntry () glutAddSubMenu () glutAttachMenu () glutCreateMenu () glutSetMenu () glutStrokeCharacter () glutStrokeLength () * / / * glReadPixels () citește un bloc de pixeli () buffer cadru glGetPixelMapfv () returnează harta de pixeli specificată glGetPixelMapuiv () returnează harta de pixeli specificată glGetPointerv () Returnează adresa indicatorului specificat. * / Init (); leer (); glutInit (& argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition (50, 50); glutInitWindowSize (ancho, alto); glutCreateWindow ("Cubo 1"); init (); glutDisplayFunc (display); glutReshapeFunc (remodelare); glutIdleFunc (inactiv); glutMouseFunc (raton); glutMotionFunc (ratmov); glutKeyboardFunc (tastatură); glutMainLoop (); retur 0; }

Pasul 5:

Imagine
Imagine

pentru moment trebuie să mă opresc! … dar în capitolul următor vă promit că îl voi implementa pe raspberry pi 3 sau nanoardul meu jetson, montat deja pe niște aeronave cu telecomandă sau pe vreun robot păianjen pentru a scana interiorul peșterilor

Recomandat: