Sadržaj:

Osnovni 3D skener za digitalno 3D mapiranje: 5 koraka
Osnovni 3D skener za digitalno 3D mapiranje: 5 koraka

Video: Osnovni 3D skener za digitalno 3D mapiranje: 5 koraka

Video: Osnovni 3D skener za digitalno 3D mapiranje: 5 koraka
Video: Java Tech Talk: Hand-made Spring Boot Starter 2024, Studeni
Anonim
Osnovni 3D skener za digitalno 3D mapiranje
Osnovni 3D skener za digitalno 3D mapiranje

U ovom projektu opisat ću i objasniti osnovne temelje 3D skeniranja i rekonstrukcije koji se prvenstveno primjenjuju na skeniranje malih poluravnih objekata, a čiji se rad može proširiti na sustave skeniranja i rekonstrukcije koji se mogu instalirati na zrakoplove s daljinskim upravljanjem radi dobivanja 3D model. mjesta na kojima leti avion koji ih instalira

Konačna ideja je dobiti 3D skeniranje nekog mjesta ili područja, bilo vanjskog ili unutarnjeg, kako bi se koristilo kao digitalna karta (kao u filmu Prometeus)

Korak 1:

Slika
Slika

ideja je instalirati cijeli sustav 3D skeniranja na daljinski upravljanu ravninu kako bi se digitalizirala virtualna karta bilo kojeg područja iznad kojeg leti u 3D, no za to smo krenuli od početka rada laserske triangulacije metodom skeniranja ili 3D rekonstrukcije laserskom triangulacijom u osnovi se sastoji od prolaska laserskog snopa kroz prizmu koja generira lasersku traku kako bi se dobila cijela laserska traka koja će biti projicirana na objekt koji će se skenirati, a nakon što se ta laserska projekcija dobije na površinska površina Od mjesta za skeniranje, slika se mora snimiti nekom vrstom fotoaparata i po mogućnosti poznavanjem kuta koji se formira s obzirom na kut projekcije emitirane laserske trake, budući da svaka od ovih slika snima projicirane laserske trake. Na površini objekta oni će se prethodno obraditi kako bi se izdvojile dimenzionalne karakteristike objekta koji će se skenirati, i jednostavno skenirati traku po traku iznad objekta kako bi se dobio profil njegove površine u tom poprečnom segmentu objekta, a zatim snimiti projicirane trake sljedećeg presjeka objekta za zbrajanje svih projiciranih pruga Prije svih presjeka obtoka dobivamo trodimenzionalno skeniranje njegove površine

Korak 2:

Slika
Slika

Budući da smo identificirali naš cilj, sljedeći korak znajući da za polijetanje morate prvo imati noge čvrsto na zemlji, pa smo krenuli na tlo s eksperimentalnim prototipom linearnog 3D skenera, kako bismo potvrdili ispravan rad osnovnog 3D skener i, kao što možete vidjeti na gornjoj slici, koristio sam računalo, OpenCV, Glut of OpenGL, web kameru, laser, laserski generator farmi (u ovom slučaju kroz rotacijsko zrcalo), elektronički sustav linearnog pomaka (napravljen sa šinom i sustav izvađen iz starog pisača) s baze na koju postavljam predmete za skeniranje, drveta i plastelina i kao što možete vidjeti na fotografiji, na računalu: uspio sam generirati i prikazati pomoću Gluta iz OpenGL-a tri dimenzionalni model reproduciran na temelju skeniranog stvarnog objekta (u ovom slučaju pauka igračke)

pa je više nego očito da je princip rada funkcionalan te da će svojim odgovarajućim prilagodbama i prilagodbama letećem sustavu moći skenirati i reproducirati 3d kartu područja na kojem leti.

Ali ovaj će sustav poslužiti samo za dobivanje 3D karata vanjske površine mjesta preko kojih leti ??? …

3. korak:

Slika
Slika

kartiranje unutrašnjosti špilja i kanala (baš kao u filmu Prometeus) Ovaj sustav 3D skeniranja također služi za rekonstrukciju trodimenzionalnih modela unutrašnjosti velikih i šupljih objekata kao što su špilje, zgrade, tuneli itd. Njegov princip rada je potpuno isto kao što je već opisano i koje se u osnovi sastoji od sljedećeg:

  1. snimite fotografiju svake projekcije laserske trake na površini za skeniranje
  2. filtrirati i ukloniti boju sa slike
  3. binarnizirajte boju s pragom dinamičke slike
  4. primijenite rubni detektor za prepoznavanje snimljenog profila svakog presjeka laserske projekcije
  5. i pomoću segmentacije odaberite odgovarajuću granicu za 3d prikaz tog presjeka objekta koji će se skenirati i rekonstruirati na virtualnoj 3D karti
  6. tada se ti koraci jednostavno ponavljaju za svaku fotografiju snimljenu na pod način laserskih traka koje neprestano projiciraju svaki pododsjek u pododsjeku.
  7. sloj po sloj prikaza presjeka dodaju se sukcesivno sve dok se ne dobije oblak točaka formiran od mnogih prikaza presjeka objekta koji se preslikava

Korak 4:

Slika
Slika

Zatim prolazim programe za obradu slike projekcija površinskih laserskih traka. i virtualne 3d rekonstrukcije ovih susivnih poprečnih prikaza u razrađenom trodimenzionalnom modelu karte:

obrada slike:

n

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

char f = 0; naziv naziva = {"0.jpg"}; int n = 0, s, x, y; CvScalar sp; DATOTEKA *NuPu;

void Writepoints () {char bufferx [33], buffery [33]; itoa (x, puferx, 10); itoa (y, tampon, 10); fprintf (NuPu, međuspremnik); fprintf (NuPu, "\ t"); fprintf (NuPu, međuspremnik); 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; naziv [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 ++;}}}} me uspremnik [33]; itoa (n, pufer, 10); fprintf (NuPu, "Fin:"); fprintf (NuPu, međuspremnik); 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); return 0; }

3D rekonstrukcija:

#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; plovak mx = 0, my = 0, mtx = 0, mty = 0, mtz = -5,0; const int Avance = 1; žica, Aux; char Caracter = 'H'; DATOTEKA *NuPu; int NP, h, w; plovak G = 0, n = 0, cx [5000], cy [5000], x, y, ax, ay, az; int font = (int) GLUT_BITMAP_8_BY_13; statička naljepnica [100]; me uspremnik [3]; GLfloat anguloCuboX = 0,0f; GLfloat anguloCuboY = 0,0f; GLfloat anguloEsfera = 0,0f; GLCH ancho = 500; Visina sjaja = 500; int hazPerspectiva = 0; preoblikovanje praznine (int width, int height) {glViewport (0, 0, width, height); glMatrixMode (GL_PROJECTION); glLoadIdentity (); if (hazPerspectiva) gluPerspective (23.0f, (GLfloat) širina/(GLfloat) visina, 1.0f, 20.0f); else glOrtho (-1, 1, -1, 1, -10, 10); glMatrixMode (GL_MODELVIEW); sidro = širina; alt=visina; } void Kolorear (int K) {float Hip; x = (cx [s] -320)/480; y = (cy [s] -240)/640; Hip = sqrt (pow (x, 2)+pow (y, 2)); ako ((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 (0,2, 0, 0); glVertex3f (-. 2, 0, 0); glVertex3f (0, 0,2, 0); glVertex3f (0, -2, 0); glEnd (); rojo; glBegin (GL_POINTS); za (n = 0; n <10; n ++) {za (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, međuspremnik, 10); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // glLoadIdentity (); glColor3f (1.0, 1.0, 1.0); glRasterPos2f (-1,.9); // glutBitmapString (GLUT_BITM; s <3; s ++) {glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24, međuspremnik [s]);} glTranslatef (mty, -mtx, mtz); glRotatef (mx, 1.0f, 0.0f, 0.0f); glRotatef (my, 1.0f, 0.0f); drawNuPu (); /*glColor3f(1.0, 1.0, 1.0); glRasterPos2f (.5,.5); // glutBitmapString (GLUT_BITMAP_TIMES_ROMAN_24, "Hello Text"); glutBitmapCharacM_MAN_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); sidro = 500; alt=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; redak [0] = 48; redak [1] = 48; redak [2] = 48; redak [3] = 48; cy [s] = atoi (linija.c_str ()); Aux [4] = 48; Aux [5] = 48; Aux [6] = 48; // Aux [7] = 48; cx [s] = atoi (Aux.c_str ()); s ++; }} myfile.close (); } else cout <1780) NP = 1700; cout <void idle () {display (); } void tipkovnica (nepotpisani ključ char, int x, int y) {prekidač (ključ) {velika slova "p": velika slova "P": hazPerspectiva = 1; preoblikovati (sardo, alt); pauza; case 'o': case 'O': hazPerspectiva = 0; preoblikovati (sardo, alt); pauza; slučaj 27: // escape izlaz (0); pauza; }} void raton (int gumb, int stanje, int x, int y) { / * GLUT_LEFT_BUTTON 0 GLUT_MIDDLE_BUTTON 1 GLUT_RIGHT_BUTTON 2 GLUT_DOWN 0 GLUT_UP 1 * / Boton = gumb; Pulbut = stanje; // mx = y; prikaz(); } void ratmov (int x, int y) {if ((Boton == 0) & (Pulbut == 0)) {mx = y; moj = x; } if ((Boton == 2) & (Pulbut == 0)) {mtx = (y/200) -1; mty = (x/200) -1; } if ((Boton == 1) & (Pulbut == 0)) {mtz =-(y/40) -5; } prikaz(); } int main (int argc, char ** argv) { /*glutAddMenuEntry () glutAddSubMenu () glutAttachMenu () glutCreateMenu () glutSetMenu () glutStrokeCharacter () glutStrokeLength ()* / /pi piksela) međuspremnik okvira glGetPixelMapfv () vraća navedenu mapu piksela glGetPixelMapuiv () vraća navedenu mapu piksela glGetPointerv () Vraća adresu navedenog pokazivača.*/ Init (); leer (); glutInit (& argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition (50, 50); glutInitWindowSize (sidro, alt); glutCreateWindow ("Cubo 1"); u tome(); glutDisplayFunc (zaslon); glutReshapeFunc (preoblikovanje); glutIdleFunc (neaktivan); glutMouseFunc (raton); glutMotionFunc (ratmov); glutKeyboardFunc (tipkovnica); glutMainLoop (); return 0; }

5. korak:

Slika
Slika

na trenutak moram stati! … ali u sljedećem poglavlju obećavam vam da ću ga implementirati na svoj malina pi 3 ili moju jetson nanoboard, već montiranu na neki daljinski upravljani zrakoplov, ili na nekog robota-pauka za skeniranje unutrašnjosti špilja

Preporučeni: