INHOUDSOPGAWE:

Basiese 3D -skandeerder vir digitale 3D -kartering: 5 stappe
Basiese 3D -skandeerder vir digitale 3D -kartering: 5 stappe

Video: Basiese 3D -skandeerder vir digitale 3D -kartering: 5 stappe

Video: Basiese 3D -skandeerder vir digitale 3D -kartering: 5 stappe
Video: СТРАШНАЯ УЧИТЕЛЬНИЦА 3D В РЕАЛЬНОЙ ЖИЗНИ! Scary teacher 3d ПРАНКИ над УЧИЛКОЙ! 2024, September
Anonim
Basiese 3D -skandeerder vir digitale 3D -kartering
Basiese 3D -skandeerder vir digitale 3D -kartering

In hierdie projek sal ek die basiese grondslae van 3D-skandering en rekonstruksie beskryf en verduidelik wat hoofsaaklik toegepas word op die skandering van klein halfvliegtuigvoorwerpe, en waarvan die werking uitgebrei kan word na skandering- en rekonstruksiestelsels wat op afstandbeheervliegtuie geïnstalleer kan word om 'n 3D -model. van die plekke waar die vliegtuig wat dit geneem het, geïnstalleer is

Die laaste idee is om 'n 3D -skandering van 'n plek of gebied, van buite of binne, te verkry om dit as 'n digitale kaart te gebruik (soos in die film van Prometeus)

Stap 1:

Beeld
Beeld

die idee is om die hele 3D-skanderingstelsel op 'n afstandbeheerde vliegtuig te installeer om die virtuele kaart van enige gebied waaroor dit vlieg in 3d te digitaliseer, maar hiervoor het ons begin vanaf die begin van die lasertriangulasie metode van skandering of 3D -rekonstruksie deur lasertriangulasie bestaan basies uit die deurlaat van 'n laserstraal deur 'n prisma wat 'n laserstreep genereer om 'n hele laserstreep te verkry wat op 'n voorwerp geprojekteer sal word, en sodra hierdie laserprojeksie op die oppervlak vanaf die plek om te skandeer, moet die beeld met 'n kamera geneem word, en verkieslik die hoek wat gevorm word ten opsigte van die projeksiehoek van die uitgestraalde laserstreep, aangesien elkeen van hierdie beelde die geprojekteerde laserstroke vaslê. Op die oppervlak van die voorwerp word hulle vooraf verwerk om die dimensionele eienskappe van die voorwerp wat geskandeer moet word, te onttrek, en eenvoudig strook vir strook bo die voorwerp te skandeer om die profiel van die oppervlak in die transversale segment van die voorwerp te kry en daarna vas te vang die geprojekteerde strook van die volgende dwarssnit van die voorwerp, om al die geprojekteerde strepe bymekaar te voeg

Stap 2:

Beeld
Beeld

Aangesien ons ons doelwit geïdentifiseer het, is die volgende stap om te weet dat u, om op te styg, eers u voete stewig op die grond moet hê, sodat ons op die grond begin het met 'n eksperimentele prototipe van 'n lineêre 3D -skandeerder om die korrekte werking van die basiese 3D -skandeerder en soos u op die prent hierbo kan sien, gebruik ek 'n rekenaar, OpenCV, Glut van OpenGL, 'n webkamera, 'n laser, laserplaasgenerator (in hierdie geval deur 'n rotasiespieël), 'n elektroniese lineêre verplasingstelsel (gemaak met 'n spoor) en stelsel onttrek uit 'n ou drukker) van 'n basis waarop ek die voorwerpe wat geskandeer moet word, op hout en plastiek plaas, en soos u op die foto kan sien, op die rekenaar: ek het daarin geslaag om met Glut van OpenGL 'n drie- en dimensionele model weergegee op grond van die geskandeerde werklike voorwerp (in hierdie geval 'n speelding)

Dit is dus meer as duidelik dat die werkingsbeginsel funksioneel is en dat dit met sy onderskeie aanpassings en aanpassings aan 'n vlieënde stelsel 'n 3D -kaart kan skandeer en weergee van die gebied waarin dit vlieg.

Maar hierdie stelsel sal slegs dien om 3D -kaarte te verkry van die buitekant van die plekke waaroor dit vlieg ??? …

Stap 3:

Beeld
Beeld

om die binnekant van die grotte en kanale in kaart te bring (net soos in die Prometeus-film) Hierdie 3D-skanderingstelsel dien ook om driedimensionele modelle van die binnekant van groot en hol voorwerpe soos grotte, geboue, tonnels, ens te rekonstrueer. presies dieselfde as reeds beskryf en wat basies uit die volgende bestaan:

  1. neem die foto van elke projeksie van die laserstreep op die oppervlak wat geskandeer moet word
  2. filter en verwyder kleur van die prent
  3. binariseer die kleur met 'n dinamiese beelddrempel
  4. pas 'n randdetektor toe om die vasgelegde profiel van elke laserprojeksie -deursnit te herken
  5. en gebruik segmentering om die toepaslike grens te kies vir die 3D -voorstelling van die deursnit van die voorwerp wat geskandeer en gerekonstrueer moet word op die virtuele 3D -kaart
  6. dan word hierdie stappe eenvoudig herhaal vir elke foto wat op 'n sub-manier geneem word van die laserstrepe wat deurlopend deur elke onderafdeling in die onderafdeling geprojekteer word.
  7. laag vir laag word die voorstelling van die deursnee agtereenvolgens bygevoeg totdat 'n puntwolk verkry word deur baie voorstellings van deursnee van die voorwerp wat gekarteer moet word

Stap 4:

Beeld
Beeld

Dan slaag ek die programme vir beeldverwerking van die projeksies van die oppervlakkige laserstroke. en van die virtuele 3d rekonstruksie van hierdie sussiewe transversale voorstellings in die uitgebreide driedimensionele kaartmodel:

Beeldverwerking:

n

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

char f = 0; char naam = {"0.jpg"}; int n = 0, s, x, y; CvScalar sp; LêER *NuPu;

leegte Skryfpunte () {char bufferx [33], buffery [33]; itoa (x, bufferx, 10); itoa (y, buffery, 10); fprintf (NuPu, bufferx); fprintf (NuPu, "\ t"); fprintf (NuPu, buffery); 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; naam [0] = f; sê <

IplImage* img0 = cvLoadImage ("00.jpg", 0); as (f == '0') {vir (y = 1; yheight-2; y ++) {vir (x = 1; xwidth-2; x ++) {sp = cvGet2D (img0, y, x); if (sp.val [0]> 50) {Writepoints (); n ++;}}}} anders {vir (y = 1; yheight-2; y ++) {vir (x = 1; xwidth-2; x ++) { sp = cvGet2D (img1, y, x); if (sp.val [0]> 50) {Writepoints (); n ++;}}}} char buffer [33]; itoa (n, buffer, 10); fprintf (NuPu, "Fin:"); fprintf (NuPu, buffer); 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); terugkeer 0; }

3D rekonstruksie:

#include ////////////////////ifif #_APPLE_ #include #else #include #include #endif #include #include #include #include #include #include

#define violeta glColor3f (1, 0, 1) #definieer azul glColor3f (0, 0, 1) #definieer turkeza glColor3f (0, 1, 1) #definieer verde glColor3f (0, 1, 0) #definieer amarillo glColor3f (1, 1, 0) #define naranja glColor3f (1,.3, 0) #define rojo glColor3f (1, 0, 0) met behulp van naamruimte std; int s, Boton = 1, Pulbut = 1; float mx = 0, my = 0, mtx = 0, mty = 0, mtz = -5,0; const int Avance = 1; snaarlyn, Aux; char Karakter = 'H'; LêER *NuPu; int NP, h, w; dryf G = 0, n = 0, cx [5000], cy [5000], x, y, byl, ay, az; int font = (int) GLUT_BITMAP_8_BY_13; statiese char etiket [100]; char buffer [3]; GLfloat anguloCuboX = 0.0f; GLfloat anguloCuboY = 0.0f; GLfloat anguloEsfera = 0.0f; Glint ancho = 500; Glinster alt=500; int hazPerspectiva = 0; leemte hervorm (int breedte, int hoogte) {glViewport (0, 0, breedte, hoogte); glMatrixMode (GL_PROJECTION); glLoadIdentity (); as (hazPerspectiva) gluPerspective (23.0f, (GLfloat) breedte/(GLfloat) hoogte, 1.0f, 20.0f); anders glOrtho (-1, 1, -1, 1, -10, 10); glMatrixMode (GL_MODELVIEW); ancho = breedte; alt=hoogte; } void Kolorear (int K) {float Hip; x = (cx [s] -320)/480; y = (cy [s] -240)/640; Heup = sqrt (pow (x, 2)+pow (y, 2)); as ((Heup> = 0) && (Heup =.07) && (Heup =.14) && (Heup =.21) && (Heup =.28) && (Heup =.35) && (Heup =.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); vir (c = string; *c! = '\ 0'; c ++) {glutBitmapCharacter (font, *c);}} leegte vertoon () {// 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_TIMES_,; 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"); glutBitmapCharacter (GLUT_BIT_24 ',);* / /*glColor3f (1. 0f, 1.0f, 1.0f); setOrthographicProjection (); glPushMatrix (); glLoadIdentity (); renderBitmapString (30, 15, (leegte *) lettertipe, "GLUT-tutoriaal ---_ ------ _@ 3D Tech"); */ glFlush (); glutSwapBuffers (); anguloCuboX+= 0.1f; anguloCuboY+= 0.1f; anguloEsfera+= 0.2f; } ongeldig init () {glClearColor (0, 0, 0, 0); glEnable (GL_DEPTH_TEST); ancho = 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"); as (myfile.is_open ()) {s = 0; while (getline (myfile, line)) {if ((line [0]! = 'N') && (line [0]! = 'F')) {Aux = line; reël [0] = 48; reël [1] = 48; reël [2] = 48; reël [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 (); } anders cout <1780) NP = 1700; cout <void idle () {display (); } leë sleutelbord (ongetekende char key, int x, int y) {switch (key) {case 'p': case 'P': hazPerspectiva = 1; hervorm (ancho, alt); breek; case 'o': case 'O': hazPerspectiva = 0; hervorm (ancho, alt); breek; saak 27: // ontsnap uitgang (0); breek; }} void raton (int knoppie, int toestand, int x, int y) { / * GLUT_LEFT_BUTTON 0 GLUT_MIDDLE_BUTTON 1 GLUT_RIGHT_BUTTON 2 GLUT_DOWN 0 GLUT_UP 1 * / Boton = knoppie; Pulbut = staat; // mx = y; vertoon (); } ongeldig ratmov (int x, int y) {if ((Boton == 0) & (Pulbut == 0)) {mx = y; my = x; } as ((Boton == 2) & (Pulbut == 0)) {mtx = (y/200) -1; mty = (x/200) -1; } as ((Boton == 1) & (Pulbut == 0)) {mtz =-(y/40) -5; } vertoon (); } int main (int argc, char ** argv) { /*glutAddMenuEntry () glutAddSubMenu () glutAttachMenu () glutCreateMenu () glutSetMenu () glutStrokeCharacter () glutStrokeLength ()* / /*glReadPixels () raambuffer glGetPixelMapfv () gee die gespesifiseerde pixelkaart terug glGetPixelMapuiv () gee die gespesifiseerde pixelkaart terug glGetPointerv () Wys die adres van die gespesifiseerde wyser.*/ Init (); leer (); glutInit (& argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition (50, 50); glutInitWindowSize (ancho, alt); glutCreateWindow ("Cubo 1"); init (); glutDisplayFunc (vertoon); glutReshapeFunc (hervorm); glutIdleFunc (ledig); glutMouseFunc (raton); glutMotionFunc (ratmov); glutKeyboardFunc (sleutelbord); glutMainLoop (); terugkeer 0; }

Stap 5:

Beeld
Beeld

vir die oomblik moet ek stop! … maar in die volgende hoofstuk belowe ek u dat ek dit sal implementeer op my framboos pi 3 of my jetson nanoboard, reeds op 'n afstandbeheerde vliegtuig, of op 'n spinnekoprobot om die binnekant van grotte te skandeer

Aanbeveel: