Cuprins:
2024 Autor: John Day | [email protected]. Modificat ultima dată: 2024-01-30 11:42
Î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:
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:
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:
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:
- surprindeți fotografia fiecărei proiecții a benzii laser pe suprafața de scanat
- filtrați și eliminați culoarea din imagine
- binarizează culoarea cu un prag de imagine dinamic
- aplicați un detector de margine pentru a recunoaște profilul capturat al fiecărei secțiuni transversale de proiecție laser
- ș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ă
- 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.
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:
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:
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:
Sfaturi pentru cartografiere: 3 pași
Sfaturi de cartografiere: Indiferent de activitatea dvs., indiferent dacă este mersul pe jos, drumeții, ciclism sau chiar conducere, puteți înregistra traseele pe care le parcurgeți. Apoi, puteți partaja aceste rute cu prietenii și familia. În plus, puteți utiliza ruta înregistrată pentru a adăuga locații la orice fotografii pe care le puteți h
Mașină de vot biometric pe bază de amprentă digitală folosind Arduino: 4 pași (cu imagini)
Aparat de vot biometric bazat pe amprentă digitală care folosește Arduino: Toți suntem conștienți de aparatul de vot electronic existent în care utilizatorul trebuie să apese un buton pentru a vota. Dar aceste mașini au fost criticate pentru temperare încă de la început. Deci, guvernul intenționează să introducă o bază de amprentă digitală
Amprentă digitală și sistem de prezență bazat pe RFID utilizând baza de date Raspberry Pi și MySQL: 5 pași
Amprentă digitală și sistem de prezență bazat pe RFID utilizând baza de date Raspberry Pi și MySQL: Video al acestui proiect
Tutorial de bază foarte de bază: 6 pași
Tutorial Batch foarte de bază: dacă știți deja elementele esențiale ale lotului, NU este necesar să citiți acest instructable, continuați cu Tutorialul de bază nu atât de simplu. NOTĂ! ghilimele (dacă vedeți t
O bază pentru încărcător dual pentru iPod și telefon mobil: 4 pași
O bază pentru încărcător dual pentru iPod și telefon mobil: în urmă cu doar câteva zile mașina mea de cafea instant nu mai putea face cafele, așa că am demolat corpul. Am luat toate piesele utile, cum ar fi comutatorul, cablul, unele piese ale motorului. Corpul din plastic era gata să-l arunce când soția mea mi-a făcut cadou un touch pod de a doua generație. Deci eu