Innholdsfortegnelse:

Grunnleggende 3D -skanner for digital 3D -kartlegging: 5 trinn
Grunnleggende 3D -skanner for digital 3D -kartlegging: 5 trinn

Video: Grunnleggende 3D -skanner for digital 3D -kartlegging: 5 trinn

Video: Grunnleggende 3D -skanner for digital 3D -kartlegging: 5 trinn
Video: 🟢 Как нарисовать 3D ШАР (Круг) с тенью шаг за шагом (Easy 3D Drawing) Easy Art 2024, November
Anonim
Grunnleggende 3D -skanner for digital 3D -kartlegging
Grunnleggende 3D -skanner for digital 3D -kartlegging

I dette prosjektet vil jeg beskrive og forklare de grunnleggende grunnlagene for 3D-skanning og rekonstruksjon som hovedsakelig brukes på skanning av små halvflyobjekter, og hvis operasjon kan utvides til skanne- og rekonstruksjonssystemer som kan installeres på fjernkontrollfly for å få en 3D -modell. av stedene hvor flyet som tar dem installert flyr

Den siste ideen er å skaffe en 3D -skanning av et sted eller område, enten utsiden eller interiøret, for å bruke det som et digitalt kart (som i filmen Prometeus)

Trinn 1:

Bilde
Bilde

tanken er å installere hele 3d-skanningssystemet på et fjernstyrt fly, for å digitalisere det virtuelle kartet over ethvert område det flyr over i 3d, men for dette startet vi fra begynnelsen av operasjonen av lasertrianguleringsmetoden av skanning eller 3d rekonstruksjon ved lasertriangulering består i utgangspunktet av å føre en laserstråle gjennom et prisme som genererer en laserstrimmel for å oppnå en hel laserstrimmel som vil bli projisert på et objekt som skal skannes, og når denne laserprojeksjonen er oppnådd på overflate Fra stedet for å skanne, må bildet tas med en slags kamera og fortrinnsvis å kjenne vinkelen som dannes i forhold til projiseringsvinkelen til den utsendte laserstrimmelen, siden hvert av disse bildene fanger de projiserte laserstrimlene. På overflaten av objektet vil de bli forbehandlet for å trekke ut dimensjonale egenskaper til objektet som skal skannes, og ganske enkelt skanne stripe for strimmel over objektet for å få profilen til overflaten i det tverrgående segmentet av objektet, og deretter fange opp den projiserte stripen av det følgende tverrsnittet av objektet, for å legge alle de projiserte stripene sammen Før alle tverrsnitt av obto får vi en tredimensjonal skanning av overflaten

Steg 2:

Bilde
Bilde

Siden vi har identifisert målet vårt, er det neste trinnet å vite at for å ta av må du først ha føttene godt på bakken, så vi startet på bakken med en eksperimentell prototype av en lineær 3d -skanner, for å validere riktig drift av den grunnleggende 3d -skanner og som du kan se på bildet ovenfor, brukte jeg en PC, OpenCV, Glut fra OpenGL, et webkamera, en laser, laser gårdsgenerator (i dette tilfellet gjennom et rotasjonsspeil) et elektronisk lineært forskyvningssystem (laget med en skinne og system hentet fra en gammel skriver) fra en base der jeg plasserer objektene som skal skannes, tre og plasticine og som du kan se på bildet, på datamaskinen: Jeg klarte å generere og vise med Glut fra OpenGL en tre- dimensjonell modell gjengitt basert på det skannede virkelige objektet (i dette tilfellet en leke edderkopp)

så det er mer enn tydelig at driftsprinsippet er funksjonelt, og at det med sine respektive justeringer og tilpasninger til et flygende system vil kunne skanne og gjengi et 3d -kart over området det flyr i.

Men dette systemet vil bare tjene til å skaffe 3D -kart over den ytre overflaten av stedene det flyr over ??? …

Trinn 3:

Bilde
Bilde

kartlegge det indre av hulene og kanalene (akkurat som i Prometeus-filmen) Dette 3D-skanningssystemet tjener også til å rekonstruere tredimensjonale modeller av interiøret i store og hule gjenstander som huler, bygninger, tunneler, etc. nøyaktig det samme som allerede beskrevet og som i utgangspunktet består av følgende:

  1. ta bildet av hver projeksjon av laserstripen på overflaten som skal skannes
  2. filtrer og fjern farge fra bildet
  3. binære fargen med en dynamisk bildeterskel
  4. bruk en kantdetektor for å gjenkjenne den fangede profilen til hvert laserprojeksjonstverrsnitt
  5. og ved å bruke segmentering velg den riktige grensen for 3d -representasjonen av det tverrsnittet av objektet som skal skannes og rekonstrueres på det virtuelle 3D -kartet
  6. så blir disse trinnene ganske enkelt gjentatt for hvert foto som er tatt på en sub-måte av laserstrimlene som kontinuerlig projiseres av hver underseksjon i underseksjonen.
  7. lag for lag av representasjonen av tverrsnittene legges til suksessivt inntil en punktsky dannes av mange representasjoner av tverrsnitt av objektet som skal kartlegges

Trinn 4:

Bilde
Bilde

Deretter sender jeg programmene for bildebehandling av projeksjonene til de overfladiske laserstrimlene. og av den virtuelle 3d-rekonstruksjonen av disse sussive transversale representasjonene i den utarbeidede tredimensjonale kartmodellen:

bildebehandling:

n

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

røye f = 0; røyenavn = {"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 ++;}}}} annet {for (y = 1; yheight-2; y ++) {for (x = 1; xwidth-2; x ++) { sp = cvGet2D (img1, y, x); if (sp.val [0]> 50) {Writepoints (); n ++;}}}} røyebuffer [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); retur 0; }

3D -rekonstruksjon:

#include ////////////////////ifif #_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 hjelp av 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; flyte G = 0, n = 0, cx [5000], cy [5000], x, y, ax, ay, az; int font = (int) GLUT_BITMAP_8_BY_13; etikett for statisk røye [100]; røyebuffer [3]; GLfloat anguloCuboX = 0,0f; GLfloat anguloCuboY = 0,0f; GLfloat anguloEsfera = 0,0f; Glint ancho = 500; Glint alt=500; int hazPerspectiva = 0; ugyldig omforming (int bredde, int høyde) {glViewport (0, 0, bredde, høyde); glMatrixMode (GL_PROJECTION); glLoadIdentity (); hvis (hazPerspectiva) gluPerspective (23.0f, (GLfloat) bredde/(GLfloat) høyde, 1.0f, 20.0f); annet glOrtho (-1, 1, -1, 1, -10, 10); glMatrixMode (GL_MODELVIEW); ancho = bredde; alt=høyde; } 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 (font, *c);}} ugyldig visning () {// 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_BIT_BITM_);* / /*glColor3f (1. 0f, 1.0f, 1.0f); setOrthographicProjection (); glPushMatrix (); glLoadIdentity (); renderBitmapString (30, 15, (void *) font, "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 no 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 (); } ugyldig tastatur (usignert char -nøkkel, int x, int y) {switch (key) {case 'p': case 'P': hazPerspectiva = 1; omforme (ancho, alt); gå i stykker; case 'o': case 'O': hazPerspectiva = 0; omforme (ancho, alt); gå i stykker; sak 27: // rømningsutgang (0); gå i stykker; }} void raton (int -knapp, 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 = -knapp; Pulbut = tilstand; // mx = y; vise(); } 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; } vise(); } int main (int argc, char ** argv) { /*glutAddMenuEntry () glutAddSubMenu () glutAttachMenu () glutCreateMenu () glutSetMenu () glutStrokeCharacter () glutStrokeLength ()* / /*glReadPixels () rammebuffer glGetPixelMapfv () returnerer det angitte pikselkartet glGetPixelMapuiv () returnerer det angitte pikselkartet glGetPointerv () Returnerer adressen til den angitte pekeren.*/ Init (); leer (); glutInit (& argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition (50, 50); glutInitWindowSize (ancho, alt); glutCreateWindow ("Cubo 1"); i det(); glutDisplayFunc (display); glutReshapeFunc (omforme); glutIdleFunc (inaktiv); glutMouseFunc (raton); glutMotionFunc (ratmov); glutKeyboardFunc (tastatur); glutMainLoop (); retur 0; }

Trinn 5:

Bilde
Bilde

for øyeblikket må jeg stoppe! … men i neste kapittel lover jeg deg at jeg vil implementere det på bringebær pi 3 eller jetson nanoboardet mitt, allerede montert på noen fjernstyrte fly, eller på en edderkopprobot for å skanne det indre av huler

Anbefalt: