Indholdsfortegnelse:
Video: Grundlæggende 3D -scanner til digital 3D -kortlægning: 5 trin
2024 Forfatter: John Day | [email protected]. Sidst ændret: 2024-01-30 08:26
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:
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:
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:
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:
- tag et foto af hver projektion af laserstrimlen på den overflade, der skal scannes
- filtrer og fjern farve fra billedet
- binære farven med en dynamisk billedgrænse
- anvende en kantdetektor til at genkende den fangede profil for hvert laserprojektions tværsnit
- 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
- derefter gentages disse trin simpelthen for hvert foto taget på en undermåde af laserstrimlerne, der kontinuerligt projiceres af hvert undersektion i undersektion.
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:
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:
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:
Lodningstråde til ledninger - Grundlæggende for lodning: 11 trin
Lodningstråde til ledninger | Grundlæggende for lodning: Til denne instruks vil jeg diskutere almindelige måder til lodning af ledninger til andre ledninger. Jeg går ud fra, at du allerede har tjekket de første 2 instruktioner til min Lodning Basics -serie. Hvis du ikke har tjekket min instruks om brug af
HC-05 (bluetooth) modul til hjemmeautomatisering Grundlæggende: 3 trin
HC-05 (bluetooth) -modul til hjemmeautomatisering Grundlæggende: I mit sidste projekt styrede jeg LED ved hjælp af en trykknap, men i dette projekt har jeg udskiftet PUSH BUTTON med HC-05-modul. Jeg anbefaler stærkt at gå igennem disse projekter før fortsætter med dette projekt. Du får alle detaljer i
Tilbage til det grundlæggende: Lodning til børn: 6 trin (med billeder)
Tilbage til det grundlæggende: Lodning til børn: Uanset om du bygger en robot eller arbejder med Arduino, skal du danne " hands-on " elektronik til prototyper af en projektide, at vide, hvordan man lodder, vil være praktisk. lodning er en væsentlig færdighed, der skal læres, hvis nogen virkelig er til el
Sådan bruges en Piezo til at producere tone: Grundlæggende: 4 trin (med billeder)
Sådan bruges en Piezo til at producere tone: Grundlæggende: Hej alle sammen, I denne instruktive vil vi bruge en Piezo -summer til at producere tone. Hvad er en Piezo -summer? En Piezo er en elektronisk enhed, der både kan bruges til at producere og detektere lyd. Applikationer: Du kan bruge det samme kredsløb til at afspille
6 år gammel skaber grundlæggende trafiklys med ridser til Arduino: 3 trin
6 år gammel Oprettelse af grundlæggende trafiklys med ridser til Arduino: Min søn var allerede nysgerrig på mine Arduino -projekter. Han spillede et stykke tid med Snap Circuits, og LEGOHe begyndte også at bygge nogle Scratch -projekter. Det var kun et spørgsmål om tid for os at lege med Scratch for Arduino. Dette er vores første projekt. Ob