Πίνακας περιεχομένων:

Βασικός σαρωτής 3D για ψηφιακή χαρτογράφηση 3D: 5 βήματα
Βασικός σαρωτής 3D για ψηφιακή χαρτογράφηση 3D: 5 βήματα

Βίντεο: Βασικός σαρωτής 3D για ψηφιακή χαρτογράφηση 3D: 5 βήματα

Βίντεο: Βασικός σαρωτής 3D για ψηφιακή χαρτογράφηση 3D: 5 βήματα
Βίντεο: Introducing the CS 9600 CBCT Scanner 2024, Σεπτέμβριος
Anonim
Βασικός σαρωτής 3D για ψηφιακή τρισδιάστατη χαρτογράφηση
Βασικός σαρωτής 3D για ψηφιακή τρισδιάστατη χαρτογράφηση

Σε αυτό το έργο, θα περιγράψω και θα εξηγήσω τα βασικά θεμέλια της τρισδιάστατης σάρωσης και της ανακατασκευής που εφαρμόζονται κυρίως στη σάρωση μικρών ημιεπίπεδων αντικειμένων και των οποίων η λειτουργία μπορεί να επεκταθεί σε συστήματα σάρωσης και ανακατασκευής που μπορούν να εγκατασταθούν σε τηλεχειριστήρια αεροσκαφών. ένα τρισδιάστατο μοντέλο. από τα μέρη όπου πετάει το αεροπλάνο που τα μεταφέρει

Η τελική ιδέα είναι να αποκτήσετε μια τρισδιάστατη σάρωση κάποιου τόπου ή περιοχής, είτε εξωτερικά είτε εσωτερικά, για να τον χρησιμοποιήσετε ως ψηφιακό χάρτη (όπως στην ταινία του Προμηθέα)

Βήμα 1:

Εικόνα
Εικόνα

η ιδέα είναι να εγκαταστήσουμε ολόκληρο το σύστημα τρισδιάστατης σάρωσης σε τηλεχειριζόμενο επίπεδο, ώστε να ψηφιοποιήσουμε τον εικονικό χάρτη οποιασδήποτε περιοχής πάνω από την οποία πετάει σε 3d, αλλά για αυτό ξεκινήσαμε από την αρχή της λειτουργίας του τριγωνισμού λέιζερη μέθοδος της σάρωσης ή της τρισδιάστατης ανακατασκευής με τριγωνισμό λέιζερ βασικά συνίσταται στη διέλευση μιας δέσμης λέιζερ μέσα από ένα πρίσμα που δημιουργεί μια λωρίδα λέιζερ για να αποκτήσει μια ολόκληρη λωρίδα λέιζερ που θα προβάλλεται σε ένα αντικείμενο που θα σαρωθεί, και μόλις επιτευχθεί αυτή η προβολή λέιζερ στο επιφανειακή επιφάνεια Από τη θέση προς τη σάρωση, η εικόνα πρέπει να ληφθεί με κάποιο τύπο κάμερας και κατά προτίμηση να γνωρίζετε τη γωνία που σχηματίζεται σε σχέση με τη γωνία προβολής της εκπεμπόμενης λωρίδας λέιζερ, αφού κάθε μία από αυτές τις εικόνες καταγράφει τις προβαλλόμενες λωρίδες λέιζερ. Στην επιφάνεια του αντικειμένου, θα υποβληθούν σε προεπεξεργασία για την εξαγωγή των διαστασιακών χαρακτηριστικών του αντικειμένου που θα σαρωθεί, και απλώς σάρωση λωρίδας με λωρίδα πάνω από το αντικείμενο για να αποκτήσει το προφίλ της επιφάνειάς του σε αυτό το εγκάρσιο τμήμα του αντικειμένου και στη συνέχεια να συλλάβει η προβαλλόμενη λωρίδα της ακόλουθης διατομής του αντικειμένου, για να προσθέσετε όλες τις προβαλλόμενες λωρίδες μαζί Πριν από όλες τις διατομές του obto λαμβάνουμε μια τρισδιάστατη σάρωση της επιφάνειάς του

Βήμα 2:

Εικόνα
Εικόνα

Δεδομένου ότι έχουμε προσδιορίσει τον στόχο μας, το επόμενο βήμα γνωρίζοντας ότι για να απογειωθείτε πρέπει πρώτα να έχετε τα πόδια σας σταθερά στο έδαφος, έτσι ξεκινήσαμε στο έδαφος με ένα πειραματικό πρωτότυπο ενός γραμμικού τρισδιάστατου σαρωτή, για να επικυρώσουμε τη σωστή λειτουργία του βασικού Τρισδιάστατη σάρωση και όπως μπορείτε να δείτε στην παραπάνω εικόνα, χρησιμοποίησα υπολογιστή, OpenCV, Glut of OpenGL, κάμερα, λέιζερ, γεννήτρια αγροκτημάτων λέιζερ (στην περίπτωση αυτή μέσω περιστροφικού καθρέφτη) ηλεκτρονικό σύστημα γραμμικής μετατόπισης (κατασκευασμένο με ράγα και σύστημα που εξάγεται από έναν παλιό εκτυπωτή) από μια βάση στην οποία τοποθετώ τα αντικείμενα προς σάρωση, ξύλο και πλαστελίνη και όπως μπορείτε να δείτε στη φωτογραφία, στον υπολογιστή: κατάφερα να δημιουργήσω και να εμφανίσω με το Glut από το OpenGL ένα τρία μοντέλο διαστάσεων που αναπαράγεται με βάση το σαρωμένο πραγματικό αντικείμενο (σε αυτήν την περίπτωση αράχνη παιχνιδιού)

έτσι είναι περισσότερο από προφανές ότι η αρχή λειτουργίας είναι λειτουργική και ότι με τις αντίστοιχες προσαρμογές και προσαρμογές σε ένα ιπτάμενο σύστημα θα είναι σε θέση να σαρώσει και να αναπαράγει έναν τρισδιάστατο χάρτη της περιοχής στην οποία πετά.

Αλλά αυτό το σύστημα θα χρησιμεύσει μόνο για τη λήψη τρισδιάστατων χαρτών της εξωτερικής επιφάνειας των τόπων όπου πετάει;……

Βήμα 3:

Εικόνα
Εικόνα

χαρτογράφηση του εσωτερικού των σπηλαίων και των αγωγών (όπως στην ταινία του Προμηθέα) Αυτό το σύστημα τρισδιάστατης σάρωσης χρησιμεύει επίσης για την ανακατασκευή τρισδιάστατων μοντέλων του εσωτερικού μεγάλων και κοίλων αντικειμένων, όπως σπηλιές, κτίρια, σήραγγες κ.λπ. ακριβώς το ίδιο όπως ήδη περιγράφηκε και που βασικά αποτελείται από τα ακόλουθα:

  1. τραβήξτε τη φωτογραφία κάθε προβολής της λωρίδας λέιζερ στην επιφάνεια που θα σαρωθεί
  2. φιλτράρετε και αφαιρέστε το χρώμα από την εικόνα
  3. δυαδικοποίηση του χρώματος με ένα δυναμικό όριο εικόνας
  4. εφαρμόστε έναν ανιχνευτή ακμής για να αναγνωρίσετε το καταγεγραμμένο προφίλ κάθε διατομής προβολής λέιζερ
  5. και χρησιμοποιώντας τμηματοποίηση επιλέξτε το κατάλληλο περίγραμμα για την τρισδιάστατη αναπαράσταση αυτής της διατομής του αντικειμένου που θα σαρωθεί και θα αναδημιουργηθεί στον εικονικό τρισδιάστατο χάρτη
  6. τότε αυτά τα βήματα επαναλαμβάνονται απλώς για κάθε φωτογραφία που λαμβάνεται με έναν υπο-τρόπο των λωρίδων λέιζερ που προβάλλονται συνεχώς από κάθε υποενότητα σε υποενότητα.
  7. στρώμα προς στρώμα της αναπαράστασης των διατομών προστίθενται διαδοχικά έως ότου ληφθεί ένα σημειακό νέφος που σχηματίζεται από πολλές αναπαραστάσεις διατομών του αντικειμένου που θα χαρτογραφηθεί

Βήμα 4:

Εικόνα
Εικόνα

Στη συνέχεια, περνάω τα προγράμματα για την επεξεργασία εικόνας των προβολών των επιφανειακών λωρίδων λέιζερ. και της εικονικής τρισδιάστατης ανακατασκευής αυτών των εγκάρσιων εγκάρσιων αναπαραστάσεων στο επεξεργασμένο τρισδιάστατο μοντέλο χάρτη:

ΕΠΕΞΕΡΓΑΣΙΑ ΕΙΚΟΝΑΣ:

ν

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

char f = 0; char name = {"0.jpg"}; int n = 0, s, x, y; CvScalar sp; ΑΡΧΕΙΟ *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; όνομα [0] = f; cout <

IplImage* img0 = cvLoadImage ("00.jpg", 0); εάν (f == '0') {για (y = 1; yheight-2; y ++) {για (x = 1; xwidth-2; x ++) {sp = cvGet2D (img0, y, x); if (sp.val [0]> 50) {Σημεία εγγραφής (); n ++;}}}} άλλα {για (y = 1; yheight-2; y ++) {για (x = 1; xwidth-2; x ++) { sp = cvGet2D (img1, y, x); if (sp.val [0]> 50) {Σημεία εγγραφής (); 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 (& εικόνα); cvReleaseImage (& img); cvReleaseImage (& img0); cvReleaseImage (& img1); cvReleaseImage (& img2); επιστροφή 0? }

3D ανακατασκευή:

#include //////////////////ifidef _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) χρησιμοποιώντας χώρο ονομάτων std; int s, Boton = 1, Pulbut = 1; float mx = 0, my = 0, mtx = 0, mty = 0, mtz = -5.0; const int Avance = 1; γραμμή συμβολοσειράς, Aux; char Caracter = 'H'; ΑΡΧΕΙΟ *NuPu; int NP, h, w; float G = 0, n = 0, cx [5000], cy [5000], x, y, ax, ay, az; int font = (int) GLUT_BITMAP_8_BY_13; στατική ετικέτα κάρτας [100]. buff buff [3]; GLfloat anguloCuboX = 0.0f; GLfloat anguloCuboY = 0,0f; GLfloat anguloEsfera = 0.0f; GLint ancho = 500; GLint alto = 500; int hazPerspectiva = 0; void αναδιαμόρφωση (int πλάτος, int ύψος) {glViewport (0, 0, πλάτος, ύψος); glMatrixMode (GL_PROJECTION); glLoadIdentity (); if (hazPerspectiva) gluPerspective (23.0f, (GLfloat) πλάτος/(GLfloat) ύψος, 1.0f, 20.0f)? αλλιώς glOrtho (-1, 1, -1, 1, -10, 10); glMatrixMode (GL_MODELVIEW); ancho = πλάτος? άλτο = ύψος? } void Kolorear (int K) {float Hip; x = (cx [s] -320)/480; y = (cy [s] -240)/640; Hip = sqrt (pow (x, 2)+pow (y, 2)); αν ((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); για (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); για (c = string; *c! = '\ 0'; c ++) {glutBitmapCharacter (font, *c);}} void 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_To_GROM_TROM_BOTMAP_TOR_GROM_TOR_GROM_TOR_GROUP_GROUP_GROUP_GROUP_GROUP_GROUP_GROME; 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_PRO2, 7, GLUT_AP_IM, GROUT);* / /*glColor3f (1. 0f, 1.0f, 1.0f); setOrthographicProjection (); glPushMatrix (); glLoadIdentity (); renderBitmapString (30, 15, (άκυρο *) γραμματοσειρά, "GLUT Tutorial ---_ ------ _@ 3D Tech"); */ glFlush (); glutSwapBuffers (); anguloCuboX+= 0.1f; anguloCuboY+= 0.1f; anguloEsfera+= 0,2f; } void init () {glClearColor (0, 0, 0, 0); glEnable (GL_DEPTH_TEST); ancho = 500? άλτο = 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.t"); if (myfile.is_open ()) {s = 0; while (getline (myfile, line)) {if ((line [0]! = 'N') && (line [0]! = 'F')) {Aux = line; γραμμή [0] = 48; γραμμή [1] = 48; γραμμή [2] = 48; γραμμή [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 (); } else cout <1780) NP = 1700; cout <void idle () {display (); } πληκτρολόγιο άκυρο (ανυπόγραφο κλειδί char, int x, int y) {switch (key) {case 'p': case 'P': hazPerspectiva = 1; αναδιαμόρφωση (ancho, alto)? Διακοπή; περίπτωση 'o': περίπτωση 'O': hazPerspectiva = 0; αναδιαμόρφωση (ancho, alto)? Διακοπή; θήκη 27: // έξοδος διαφυγής (0). Διακοπή; }} void raton (κουμπί int, κατάσταση int, int x, int y) { / * GLUT_LEFT_BUTTON 0 GLUT_MIDDLE_BUTTON 1 GLUT_RIGHT_BUTTON 2 GLUT_DOWN 0 GLUT_UP 1 * / Boton = κουμπί; Pulbut = κατάσταση? // mx = y; απεικόνιση(); } void ratmov (int x, int y) {if ((Boton == 0) & (Pulbut == 0)) {mx = y; my = x; } if ((Boton == 2) & (Pulbut == 0)) {mtx = (y/200) -1; mty = (x/200) -1; } if ((Boton == 1) & (Pulbut == 0)) {mtz =-(y/40) -5; } απεικόνιση(); } int main (int argc, char ** argv) { /*glutAddMenuEntry () glutAddSubMenu () glutAttachMenu () glutCreateMenu () glutSetMenu () glutStrokeCharacter () glutStrokeLength ()*ανά πλαίσιο buffer glGetPixelMapfv () επιστρέφει τον καθορισμένο χάρτη pixel glGetPixelMapuiv () επιστρέφει τον καθορισμένο χάρτη pixel glGetPointerv () Επιστρέφει τη διεύθυνση του καθορισμένου δείκτη.*/ Init (); λάγνο βλέμμα(); glutInit (& argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition (50, 50); glutInitWindowSize (ancho, alto); glutCreateWindow ("Cubo 1"); μέσα σε αυτό(); glutDisplayFunc (οθόνη); glutReshapeFunc (αναδιαμόρφωση); glutIdleFunc (αδρανές); glutMouseFunc (raton); glutMotionFunc (ratmov); glutKeyboardFunc (πληκτρολόγιο); glutMainLoop (); επιστροφή 0? }

Βήμα 5:

Εικόνα
Εικόνα

προς το παρόν πρέπει να σταματήσω! … Αλλά στο επόμενο κεφάλαιο σας υπόσχομαι ότι θα το εφαρμόσω στο βατόμουρό μου pi 3 ή στο νανομπάρτ μου jetson, ήδη τοποθετημένο σε κάποιο τηλεκατευθυνόμενο αεροσκάφος ή σε κάποιο ρομπότ αράχνη για να σαρώσω το εσωτερικό των σπηλαίων

Συνιστάται: