Turinys:

Pagrindinis 3D skaitytuvas skaitmeniniam 3D žemėlapiui: 5 žingsniai
Pagrindinis 3D skaitytuvas skaitmeniniam 3D žemėlapiui: 5 žingsniai

Video: Pagrindinis 3D skaitytuvas skaitmeniniam 3D žemėlapiui: 5 žingsniai

Video: Pagrindinis 3D skaitytuvas skaitmeniniam 3D žemėlapiui: 5 žingsniai
Video: MICHAILAS TRAUBAS -- „Efektyvi vaizdinė komunikacija -- sprendimai Jūsų verslui" 2024, Rugsėjis
Anonim
Pagrindinis 3D skaitytuvas skaitmeniniam 3D žemėlapiui
Pagrindinis 3D skaitytuvas skaitmeniniam 3D žemėlapiui

Šiame projekte aprašysiu ir paaiškinsiu pagrindinius 3D nuskaitymo ir rekonstrukcijos pagrindus, pirmiausia taikomus mažų pusiau plokštuminių objektų nuskaitymui ir kurių veikimą galima išplėsti iki nuskaitymo ir rekonstrukcijos sistemų, kurios gali būti įdiegtos nuotolinio valdymo orlaiviuose. 3D modelis. vietų, kuriose skrenda juos skraidinantis lėktuvas

Galutinė idėja yra gauti 3D vaizdą iš tam tikros vietos ar srities, jos išorės ar vidaus, ir naudoti ją kaip skaitmeninį žemėlapį (kaip filme „Prometėjas“).

1 žingsnis:

Vaizdas
Vaizdas

idėja yra įdiegti visą 3D nuskaitymo sistemą nuotoliniu būdu valdomoje plokštumoje, kad būtų galima skaitmenizuoti bet kurios srities, kurioje ji skrenda, virtualų žemėlapį 3D formatu, tačiau tai pradėjome nuo lazerio trikampio veikimo pradžios. nuskaitymas arba 3D rekonstrukcija naudojant lazerio trikampio metodą iš esmės apima lazerio spindulio praleidimą per prizmę, kuri sukuria lazerio juostą, kad gautų visą lazerio juostą, kuri bus projektuojama ant nuskaitomo objekto, ir kai ši lazerio projekcija bus gauta ant Paviršiaus paviršius Nuo nuskaitymo vietos vaizdas turi būti užfiksuotas naudojant tam tikros rūšies fotoaparatą ir, pageidautina, žinant kampą, kuris susidaro, atsižvelgiant į skleidžiamos lazerio juostos projekcijos kampą, nes kiekvienas iš šių vaizdų fiksuoja projektuojamas lazerio juosteles. Objekto paviršiuje jie bus iš anksto apdoroti, kad būtų išgautos nuskaitymo objekto matmenų charakteristikos, ir tiesiog nuskaitykite juostelę po juostelės virš objekto, kad gautumėte jo paviršiaus profilį tame skersiniame objekto segmente, ir vėliau užfiksuokite kito objekto skerspjūvio projektuojama juosta, kad visos suprojektuotos juostelės būtų sujungtos Prieš visus obto skerspjūvius gauname trimatį jo paviršiaus nuskaitymą

2 žingsnis:

Vaizdas
Vaizdas

Kadangi mes nustatėme savo tikslą, kitas žingsnis žinant, kad norint pakilti, pirmiausia turite tvirtai laikyti kojas ant žemės, todėl pradėjome nuo žemės su eksperimentiniu linijinio 3D skaitytuvo prototipu, kad patvirtintume teisingą pagrindo veikimą. 3D skenavimas ir, kaip matote aukščiau esančiame paveikslėlyje, naudojau kompiuterį, „OpenCV“, „Glut of OpenGL“, internetinę kamerą, lazerinį, lazerinį ūkio generatorių (šiuo atveju per sukamąjį veidrodį), elektroninę linijinio poslinkio sistemą (pagamintą iš bėgelio) ir sistema, išgauta iš seno spausdintuvo) iš pagrindo, ant kurio dedu skenuojamus objektus, medžio ir plastilino, ir, kaip matote nuotraukoje, kompiuteryje: man pavyko sukurti ir parodyti naudojant „Glut“iš „OpenGL“tris matmenų modelis, atkurtas remiantis nuskaitytu tikru objektu (šiuo atveju žaisliniu voru)

Taigi daugiau nei akivaizdu, kad veikimo principas yra funkcionalus ir kad, atitinkamai sureguliuodamas ir pritaikydamas skraidančią sistemą, jis galės nuskaityti ir atkurti 3D žemėlapį vietovės, kurioje jis skrenda.

Bet ši sistema bus naudojama tik norint gauti 3D žemėlapius apie vietų, kuriose ji skrenda, išorinį paviršių ???…

3 žingsnis:

Vaizdas
Vaizdas

urvų ir kanalų interjero žemėlapių sudarymas (kaip ir filme „Prometėjas“) Ši 3D nuskaitymo sistema taip pat skirta rekonstruoti trimatius didelių ir tuščiavidurių objektų, tokių kaip urvai, pastatai, tuneliai ir pan., interjero modelius. visiškai tas pats, kas jau aprašyta ir kurį iš esmės sudaro šie dalykai:

  1. užfiksuokite kiekvienos lazerio juostos projekcijos nuotrauką ant nuskaitymo paviršiaus
  2. filtruokite ir pašalinkite spalvą iš vaizdo
  3. binarizuokite spalvą dinaminio vaizdo slenksčiu
  4. uždėkite krašto detektorių, kad atpažintų kiekvieno lazerio projekcijos skerspjūvio užfiksuotą profilį
  5. ir naudodamiesi segmentacija, pasirinkite tinkamą kraštą, skirtą 3D atvaizduoti tą skerspjūvio objektą, kurį norite nuskaityti ir atkurti virtualiame 3D žemėlapyje
  6. tada šie veiksmai paprasčiausiai kartojami kiekvienai nuotraukai, padarytai pagal lazerio juostelių, kurias nuolat projektuoja kiekvienas poskyris, poskyrį.
  7. sluoksnių sluoksniai pavaizduoti skerspjūvius iš eilės, kol gaunamas taškinis debesis, sudarytas iš daugelio atvaizduojamų objektų skerspjūvių vaizdų

4 žingsnis:

Vaizdas
Vaizdas

Tada praleidžiu paviršinių lazerinių juostelių projekcijų vaizdų apdorojimo programas. ir virtuali šių sussive skersinių vaizdų 3D rekonstrukcija parengtame trimatiame žemėlapio modelyje:

vaizdo apdorojimas:

n

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

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

void Writepoints () {char bufferx [33], buferis [33]; itoa (x, buferis, 10); itoa (y, buferis, 10); fprintf (NuPu, bufferx); fprintf („NuPu“, „\ t“); fprintf (NuPu, buferis); 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; vardas [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 buferis [33]; itoa (n, buferis, 10); fprintf (NuPu, „Fin:“); fprintf (NuPu, buferis); fprintf („NuPu“, „\ n“); fclose (NuPu);

cvWaitKey (0); //_execlp("calc.exe "," calc.exe ", argstr, NULL); cvDestroyAllWindows (); cvReleaseImage (& vaizdas); cvReleaseImage (& img); cvReleaseImage (& img0); cvReleaseImage (& img1); cvReleaseImage (& img2); grįžti 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) naudojant vardų sritį std; int s, Boton = 1, Pulbut = 1; plūdė mx = 0, mano = 0, mtx = 0, mty = 0, mtz = -5,0; const int Avance = 1; eilutės eilutė, Aux; char Character = 'H'; FILE *NuPu; int NP, h, w; plūdė G = 0, n = 0, cx [5000], cy [5000], x, y, ax, ay, az; int šriftas = (int) GLUT_BITMAP_8_BY_13; statinės anglies etiketė [100]; anglies buferis [3]; GLfloat anguloCuboX = 0.0f; GLfloat anguloCuboY = 0.0f; GLfloat anguloEsfera = 0.0f; GLint ancho = 500; GLint alto = 500; int hazPerspectiva = 0; void reshape (int plotis, int aukštis) {glViewport (0, 0, plotis, aukštis); glMatrixMode (GL_PROJECTION); glLoadIdentity (); if (hazPerspectiva) gluPerspective (23.0f, (GLfloat) plotis/(GLfloat) aukštis, 1.0f, 20.0f); kitaip glOrtho (-1, 1, -1, 1, -10, 10); glMatrixMode (GL_MODELVIEW); ancho = plotis; alto = aukštis; } void Kolorear (int K) {float Hip; x = (cx [s] -320)/480; y = (cy [s] -240)/640; Klubas = sqrt (pow (x, 2)+pow (y, 2)); jei ((Hip> = 0) && (Hip =.07) && (Hip =.14) && (Hip =.21) && (Hip =.28) && (Hip =.35) && (Hip =.42) && (Klubas <=. 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 (šriftas, *c);}} void display () {// mx = 468; itoa (mx, buferis, 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;; s <3; s ++) {glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24, buferis [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, „Labas tekstas“); glutBitmapCharacterAP);* / /*glColor3f (1. 0f, 1.0f, 1.0f); setOrthographicProjection (); glPushMatrix (); glLoadIdentity (); renderBitmapString (30, 15, (void *) šriftas, „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); ancho = 500; alto = 500; } void leer () {ifstream myfile ("A:/Respaldo rugsėjo 2016/D/Respaldos/Respaldo compu CICATA abril 2015/usb1/rekostruccion 3D en Especialidad CICATA/Software/Reconstruccion 3D/R3d_0 / bin/Debug/NuPu.txt"); jei (myfile.is_open ()) {s = 0; while (getline (mano failas, eilutė)) {if ((eilutė [0]! = 'N') && (eilutė [0]! = 'F')) {Aux = line; eilutė [0] = 48; eilutė [1] = 48; eilutė [2] = 48; eilutė [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 (); } tuščia klaviatūra (nepasirašytas char klavišas, int x, int y) {jungiklis (klavišas) {case 'p': case 'P': hazPerspectiva = 1; pertvarkyti (ancho, alto); pertrauka; atvejis „o“: atvejis „O“: hazPerspectiva = 0; pertvarkyti (ancho, alto); pertrauka; 27 atvejis: // pabėgimo išėjimas (0); pertrauka; }} void raton (int mygtukas, int būsena, int x, int y) { / * GLUT_LEFT_BUTTON 0 GLUT_MIDDLE_BUTTON 1 GLUT_RIGHT_BUTTON 2 GLUT_DOWN 0 GLUT_UP 1 * / Boton = mygtukas; Pulbut = būsena; // mx = y; ekranas (); } void ratmov (int x, int y) {if ((Boton == 0) & (Pulbut == 0)) {mx = y; mano = x; } jei ((Boton == 2) & (Pulbut == 0)) {mtx = (y/200) -1; mty = (x/200) -1; } jei ((Boton == 1) & (Pulbut == 0)) {mtz =-(y/40) -5; } ekranas (); } int main (int argc, char ** argv) { /*glutAddMenuEntry () glutAddSubMenu () glutAttachMenu () glutCreateMenu () glutSetMenu () glutStrokeCharacter () glutStrokeLength ()* / /*gl skaityti iš pikselių kadrų buferis glGetPixelMapfv () grąžina nurodytą pikselių žemėlapį glGetPixelMapuiv () grąžina nurodytą pikselių žemėlapį glGetPointerv () Grąžina nurodyto rodyklės adresą.*/ Init (); leer (); glutInit (& argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition (50, 50); glutInitWindowSize (ancho, alto); glutCreateWindow („Cubo 1“); init (); glutDisplayFunc (ekranas); glutReshapeFunc (pertvarkyti); glutIdleFunc (nenaudojamas); glutMouseFunc (ratonas); glutMotionFunc (ratmov); glutKeyboardFunc (klaviatūra); glutMainLoop (); grįžti 0; }

5 veiksmas:

Vaizdas
Vaizdas

kol kas turiu sustoti! … Bet kitame skyriuje pažadu jums, kad tai įgyvendinsiu savo aviečių pi 3 ar savo „jetson“nanoplokštėje, jau sumontuotoje ant kai kurių nuotoliniu būdu valdomų orlaivių, arba ant kažkokio voro roboto, kad nuskaitytų urvų vidų.

Rekomenduojamas: