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, Novembar
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 sisteme za skeniranje i rekonstrukciju koji se mogu instalirati na zrakoplove s daljinskim upravljanjem radi dobivanja 3D model. od mesta 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:

Image
Image

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, ali 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 ova laserska projekcija dobije na površinska površina Od mjesta skeniranja, slika se mora snimiti nekom vrstom kamere i po mogućnosti poznavanjem kuta koji se formira s obzirom na kut projekcije emitirane laserske trake, jer svaka od ovih slika snima projicirane laserske trake. Na površini objekta ć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 projiciranu traku sljedećeg poprečnog presjeka objekta, za zbrajanje svih projiciranih pruga Prije svih presjeka obtoka dobivamo trodimenzionalno skeniranje njegove površine

Korak 2:

Image
Image

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čunar, OpenCV, Glut of OpenGL, web kameru, laser, laserski generator farmi (u ovom slučaju kroz rotaciono ogledalo), elektronski sistem linearnog pomaka (napravljen sa šinom i sistem izvađen iz starog štampača) sa baze na koju postavljam predmete za skeniranje, drveta i plastelina i kao što vidite na fotografiji, na računaru: uspio sam generirati i prikazati pomoću Gluta iz OpenGL-a tri dimenzionalni model reproduciran na osnovu skeniranog stvarnog objekta (u ovom slučaju pauka igračke)

tako da je više nego očito da je princip rada funkcionalan, te da će s odgovarajućim prilagodbama i prilagodbama letećeg sistema moći skenirati i reproducirati 3D kartu područja u kojem leti.

Ali ovaj sistem će služiti samo za dobijanje 3D mapa vanjske površine mjesta preko kojih leti ??? …

Korak 3:

Image
Image

mapiranje unutrašnjosti pećina i kanala (baš kao u filmu Prometeus) Ovaj sistem za 3D skeniranje služi i za rekonstrukciju trodimenzionalnih modela unutrašnjosti velikih i šupljih objekata poput pećina, zgrada, tunela 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. filtrirajte i uklonite boju sa slike
  3. binarnizirajte boju pomoću praga 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. prikaz poprečnih presjeka sloj po sloj dodaju se sukcesivno sve dok se ne dobije oblak tačaka formiran od mnogih prikaza presjeka objekta koji se preslikava

Korak 4:

Image
Image

Zatim prolazim programe za obradu slike projekcija površinskih laserskih traka. i virtualne 3D rekonstrukcije ovih suzističnih transverzalnih 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; char name = {"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, buffery, 10); fprintf (NuPu, bafferx); 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; ime [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 međuspremnik [33]; itoa (n, bafer, 10); fprintf (NuPu, "Fin:"); fprintf (NuPu, bafer); 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; float mx = 0, my = 0, mtx = 0, mty = 0, mtz = -5,0; const int Avance = 1; žica, Aux; char Caracter = 'H'; FILE *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]; char buffer [3]; GLfloat anguloCuboX = 0,0f; GLfloat anguloCuboY = 0,0f; GLfloat anguloEsfera = 0,0f; Ancho GLint = 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; alto = 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)); 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); 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, bafer, 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, bafer [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, "Zdravo Tekst"););* / /*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; red [0] = 48; red [1] = 48; red [2] = 48; red [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 ++; }} myfile.close (); } else cout <1780) NP = 1700; cout <void idle () {display (); } void tastatura (nepotpisani taster char, int x, int y) {prekidač (ključ) {velika slova "p": velika slova "P": hazPerspectiva = 1; preoblikovanje (ancho, alt); break; case 'o': case 'O': hazPerspectiva = 0; preoblikovanje (ancho, alt); break; slučaj 27: // escape izlaz (0); break; }} void raton (int dugme, 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 = dugme; Pulbut = stanje; // mx = y; display (); } void ratmov (int x, int y) {if ((Boton == 0) & (Pulbut == 0)) {mx = y; my = 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 ()* / /ip piksela) međuspremnik okvira glGetPixelMapfv () vraća specificiranu mapu piksela glGetPixelMapuiv () vraća specificiranu mapu piksela glGetPointerv () Vraća adresu navedenog pokazivača.*/ Init (); leer (); glutInit (& argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition (50, 50); glutInitWindowSize (ancho, alto); glutCreateWindow ("Cubo 1"); u tome(); glutDisplayFunc (ekran); glutReshapeFunc (preoblikovanje); glutIdleFunc (neaktivan); glutMouseFunc (raton); glutMotionFunc (ratmov); glutKeyboardFunc (tastatura); glutMainLoop (); return 0; }

Korak 5:

Image
Image

na trenutak moram prestati! … ali u sljedećem poglavlju obećavam vam da ću ga implementirati na svoj maline pi 3 ili jetson nanoboard, koji je već montiran na neki daljinski upravljani avion, ili na nekog robota-pauka da skenira unutrašnjost pećina

Preporučuje se: