Indholdsfortegnelse:

Grundlæggende 3D -scanner til digital 3D -kortlægning: 5 trin
Grundlæggende 3D -scanner til digital 3D -kortlægning: 5 trin

Video: Grundlæggende 3D -scanner til digital 3D -kortlægning: 5 trin

Video: Grundlæggende 3D -scanner til digital 3D -kortlægning: 5 trin
Video: How To Change Filament on the Creality Ender 3 3D printer 2024, November
Anonim
Grundlæggende 3D -scanner til digital 3D -kortlægning
Grundlæggende 3D -scanner til digital 3D -kortlægning

I dette projekt vil jeg beskrive og forklare de grundlæggende fundamenter for 3D-scanning og rekonstruktion, der primært anvendes til scanning af små halvplanobjekter, og hvis drift kan udvides til at scanne og genopbygge systemer, der kan installeres på fjernbetjeningsfly for at opnå en 3D -model. af de steder, hvor flyet, der tager dem installeret, flyver

Den sidste idé er at få en 3D -scanning af et sted eller område, enten dets ydre eller indvendige, for at bruge det som et digitalt kort (som i filmen om Prometeus)

Trin 1:

Billede
Billede

tanken er at installere hele 3d-scanningssystemet på et fjernstyret fly for at digitalisere det virtuelle kort over ethvert område, som det flyver over i 3d, men for dette startede vi fra begyndelsen af lasertrianguleringsmetoden af scanning eller 3d rekonstruktion ved lasertriangulering består grundlæggende i at føre en laserstråle gennem et prisme, der genererer en laserstrimmel for at opnå en hel laserstrimmel, der vil blive projiceret på et objekt, der skal scannes, og når denne laserprojektion er opnået på overfladeoverflade Fra stedet til scanning skal billedet fanges med en slags kamera og helst kende den vinkel, der dannes i forhold til projektionsvinklen for den udsendte laserstrimmel, da hvert af disse billeder fanger de projicerede laserstrimler. På overfladen af objektet vil de blive forbehandlet til at udtrække dimensionelle egenskaber for objektet, der skal scannes, og blot scanne strimmel for strimmel over objektet for at opnå profilen af dens overflade i det tværgående segment af objektet og efterfølgende fange den projicerede strimmel af følgende tværsnit af objektet, for at tilføje alle de projicerede striber sammen Før alle tværsnit af obto'en får vi en tredimensionel scanning af dens overflade

Trin 2:

Billede
Billede

Da vi har identificeret vores mål, er det næste trin at vide, at for at starte skal du først have dine fødder fast på jorden, så vi startede på jorden med en eksperimentel prototype af en lineær 3d -scanner for at validere den korrekte drift af den grundlæggende 3d scanner og som du kan se på billedet ovenfor, brugte jeg en pc, OpenCV, Glut fra OpenGL, et webcam, en laser, laser gård generator (i dette tilfælde gennem et rotations spejl) et elektronisk lineært forskydningssystem (lavet med en skinne og system ekstraheret fra en gammel printer) fra en base, hvorpå jeg placerer de genstande, der skal scannes, træ og plasticine, og som du kan se på billedet, på computeren: Det lykkedes mig at generere og vise med Glut fra OpenGL en tre- dimensionel model gengivet baseret på det scannede virkelige objekt (i dette tilfælde en legetøjsspindel)

så det er mere end tydeligt, at driftsprincippet er funktionelt, og at det med dets respektive justeringer og tilpasninger til et flyvende system vil være i stand til at scanne og gengive et 3d -kort over det område, det flyver i.

Men dette system vil kun tjene til at få 3D -kort over den ydre overflade af de steder, det flyver over ??? …

Trin 3:

Billede
Billede

kortlægning af det indre af huler og kanaler (ligesom i Prometeus-filmen) Dette 3D-scanningssystem tjener også til at rekonstruere tredimensionelle modeller af interiøret i store og hule genstande som huler, bygninger, tunneler osv. dets driftsprincip er nøjagtig det samme som allerede beskrevet, og som grundlæggende består af følgende:

  1. tag et foto af hver projektion af laserstrimlen på den overflade, der skal scannes
  2. filtrer og fjern farve fra billedet
  3. binære farven med en dynamisk billedgrænse
  4. anvende en kantdetektor til at genkende den fangede profil for hvert laserprojektions tværsnit
  5. og ved hjælp af segmentering vælge den passende grænse for 3d -repræsentationen af det tværsnit af objektet, der skal scannes og rekonstrueres på det virtuelle 3D -kort
  6. derefter gentages disse trin simpelthen for hvert foto taget på en undermåde af laserstrimlerne, der kontinuerligt projiceres af hvert undersektion i undersektion.
  7. lag for lag af repræsentationen af tværsnittene tilføjes successivt, indtil der opnås en punktsky dannet af mange repræsentationer af tværsnit af objektet, der skal kortlægges

Trin 4:

Billede
Billede

Derefter sender jeg programmerne til billedbehandling af projektionerne af de overfladiske laserstrimler. og af den virtuelle 3d-rekonstruktion af disse sussive tværgående repræsentationer i den udarbejdede tredimensionelle kortmodel:

billedbehandling:

n

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

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

void Writepoints () {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; navn [0] = f; cout <

IplImage* img0 = cvLoadImage ("00.jpg", 0); hvis (f == '0') {for (y = 1; yheight-2; y ++) {for (x = 1; xwidth-2; x ++) {sp = cvGet2D (img0, y, x); hvis (sp.val [0]> 50) {Writepoints (); n ++;}}}} else {for (y = 1; yheight-2; y ++) {for (x = 1; xwidth-2; x ++) { sp = cvGet2D (img1, y, x); hvis (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 (& billede); cvReleaseImage (& img); cvReleaseImage (& img0); cvReleaseImage (& img1); cvReleaseImage (& img2); returnere 0; }

3D rekonstruktion:

#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) ved hjælp af navneområde std; int s, Boton = 1, Pulbut = 1; float mx = 0, my = 0, mtx = 0, mty = 0, mtz = -5,0; const int Avance = 1; streng linje, Aux; char Karakter = 'H'; FIL *NuPu; int NP, h, w; flyde G = 0, n = 0, cx [5000], cy [5000], x, y, ax, ay, az; int font = (int) GLUT_BITMAP_8_BY_13; statisk mærkning [100]; forkulningsbuffer [3]; GLfloat anguloCuboX = 0,0f; GLfloat anguloCuboY = 0,0f; GLfloat anguloEsfera = 0,0f; Glint ancho = 500; Glint alt=500; int hazPerspectiva = 0; ugyldig omformning (int bredde, int højde) {glViewport (0, 0, bredde, højde); glMatrixMode (GL_PROJECTION); glLoadIdentity (); hvis (hazPerspectiva) gluPerspective (23.0f, (GLfloat) bredde/(GLfloat) højde, 1.0f, 20.0f); ellers glOrtho (-1, 1, -1, 1, -10, 10); glMatrixMode (GL_MODELVIEW); ancho = bredde; alt=højde; } ugyldig Kolorear (int K) {float Hip; x = (cx [s] -320)/480; y = (cy [s] -240)/640; Hofte = sqrt (pow (x, 2)+pow (y, 2)); hvis ((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 = streng; *c! = '\ 0'; c ++) {glutBitmapCharacter (skrifttype, *c);}} ugyldigt 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_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_BITMB_);* / /*glColor3f (1. 0f, 1.0f, 1.0f); setOrthographicProjection (); glPushMatrix (); glLoadIdentity (); renderBitmapString (30, 15, (void *) skrifttype, "GLUT Tutorial ---_ ------ _@ 3D Tech"); */ glFlush (); glutSwapBuffers (); anguloCuboX+= 0,1 f; anguloCuboY+= 0,1f; anguloEsfera+= 0,2f; } ugyldig 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"); hvis (myfile.is_open ()) {s = 0; while (getline (myfile, line)) {if ((line [0]! = 'N') && (line [0]! = 'F')) {Aux = line; linje [0] = 48; linje [1] = 48; linje [2] = 48; linje [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 (); } ellers cout <1780) NP = 1700; cout <void idle () {display (); } ugyldigt tastatur (usigneret char -tast, int x, int y) {switch (key) {case 'p': case 'P': hazPerspectiva = 1; omforme (ancho, alt); pause; case 'o': case 'O': hazPerspectiva = 0; omforme (ancho, alt); pause; sag 27: // flugtudgang (0); pause; }} void raton (int -knap, int -tilstand, int x, int y) { / * GLUT_LEFT_BUTTON 0 GLUT_MIDDLE_BUTTON 1 GLUT_RIGHT_BUTTON 2 GLUT_DOWN 0 GLUT_UP 1 * / Boton = -knap; Pulbut = tilstand; // mx = y; Skærm(); } void ratmov (int x, int y) {if ((Boton == 0) & (Pulbut == 0)) {mx = y; min = x; } hvis ((Boton == 2) & (Pulbut == 0)) {mtx = (y/200) -1; mty = (x/200) -1; } hvis ((Boton == 1) & (Pulbut == 0)) {mtz =-(y/40) -5; } Skærm(); } int main (int argc, char ** argv) { /*glutAddMenuEntry () glutAddSubMenu () glutAttachMenu () glutCreateMenu () glutSetMenu () glutStrokeCharacter () glutStrokeLength ()* / /*glReadPixels () frame buffer glGetPixelMapfv () returnerer det angivne pixelkort glGetPixelMapuiv () returnerer det angivne pixelkort glGetPointerv () Returnerer adressen på den angivne markør.*/ Init (); leer (); glutInit (& argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition (50, 50); glutInitWindowSize (ancho, alt); glutCreateWindow ("Cubo 1"); i det(); glutDisplayFunc (display); glutReshapeFunc (omform); glutIdleFunc (inaktiv); glutMouseFunc (raton); glutMotionFunc (ratmov); glutKeyboardFunc (tastatur); glutMainLoop (); returnere 0; }

Trin 5:

Billede
Billede

for øjeblikket må jeg stoppe! … men i det næste kapitel lover jeg dig, at jeg vil implementere det på min hindbær pi 3 eller mit jetson nanoboard, der allerede er monteret på nogle fjernstyrede fly, eller på en edderkopprobot for at scanne det indre af huler

Anbefalede: