Innholdsfortegnelse:
Video: Grunnleggende 3D -skanner for digital 3D -kartlegging: 5 trinn
2024 Forfatter: John Day | [email protected]. Sist endret: 2024-01-30 11:21
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:
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:
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:
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:
- ta bildet av hver projeksjon av laserstripen på overflaten som skal skannes
- filtrer og fjern farge fra bildet
- binære fargen med en dynamisk bildeterskel
- bruk en kantdetektor for å gjenkjenne den fangede profilen til hvert laserprojeksjonstverrsnitt
- 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
- 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.
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:
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:
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:
Komponenter for lodding på overflaten - Grunnleggende for lodding: 9 trinn (med bilder)
Komponenter for lodding på overflaten | Grunnleggende for lodding: Så langt i min grunnleggende serie for lodding har jeg diskutert nok grunnleggende om lodding for at du skal begynne å øve. I denne instruksjonsboken er det jeg vil diskutere litt mer avansert, men det er noen av grunnleggende for lodding av overflatemonterte komponenter
Lodding gjennom hullkomponenter - Grunnleggende for lodding: 8 trinn (med bilder)
Lodding gjennom hullkomponenter | Grunnleggende for lodding: I denne instruksjonsboken vil jeg diskutere noen grunnleggende om lodding gjennom hullkomponenter til kretskort. Jeg antar at du allerede har sjekket ut de to første instruksjonene for min Lodding Basics -serie. Hvis du ikke har sjekket inn min
Loddetråder til ledninger - Grunnleggende for lodding: 11 trinn
Loddetråder til ledninger | Grunnleggende for lodding: For denne instruksen vil jeg diskutere vanlige måter for lodding av ledninger til andre ledninger. Jeg antar at du allerede har sjekket ut de to første instruksjonene for min Lodding Basics -serie. Hvis du ikke har sjekket ut instruksjonene mine om bruk
Tiny H-Bridge drivere - Grunnleggende: 6 trinn (med bilder)
Tiny H-Bridge drivere | Grunnleggende: Hei og velkommen tilbake til en annen instruerbar! I den forrige viste jeg deg hvordan jeg opprettet spoler i KiCad ved hjelp av et python -skript. Deretter opprettet og testet jeg noen varianter av spoler for å se hvilken som fungerer best. Målet mitt er å erstatte den enorme
Sewart Digital Embroidery Software Grunnleggende: 4 trinn
Grunnleggende om Sewart digital broderiprogramvare: Bruk av digital broderiprogramvare kan virke skremmende og frustrerende i begynnelsen, men med litt øvelse og tålmodighet og denne SUPER praktiske guiden blir du en mester på kort tid. Denne guiden vil fokusere på bruk av programvaren, SewArt Embroidery Digitize