Inhaltsverzeichnis:
Video: Grundlegender 3D-Scanner für digitales 3D-Mapping - Gunook
2024 Autor: John Day | [email protected]. Zuletzt bearbeitet: 2024-01-30 07:16
In diesem Projekt beschreibe und erkläre ich die grundlegenden Grundlagen des 3D-Scannens und der Rekonstruktion, die hauptsächlich auf das Scannen kleiner halbflächiger Objekte angewendet werden und deren Betrieb auf Scan- und Rekonstruktionssysteme ausgedehnt werden kann, die auf ferngesteuerten Flugzeugen installiert werden können, um zu erhalten ein 3D-Modell. der Orte, an denen das Flugzeug, das sie befördert, installiert fliegt
Die letzte Idee besteht darin, einen 3D-Scan eines Ortes oder einer Umgebung zu erhalten, entweder von außen oder von innen, um ihn als digitale Karte zu verwenden (wie im Film von Prometeus).
Schritt 1:
Die Idee ist, das gesamte 3D-Scansystem auf einer ferngesteuerten Ebene zu installieren, um die virtuelle Karte eines beliebigen Gebiets, über das es fliegt, in 3D zu digitalisieren, aber dafür haben wir von Anfang an mit dem Betrieb der Lasertriangulation der Methode begonnen des Scannens oder der 3D-Rekonstruktion durch Lasertriangulation besteht im Wesentlichen darin, einen Laserstrahl durch ein Prisma zu führen, das einen Laserstreifen erzeugt, um einen gesamten Laserstreifen zu erhalten, der auf ein zu scannendes Objekt projiziert wird, und sobald diese Laserprojektion auf dem Oberflächenoberfläche Von der zu scannenden Stelle muss das Bild mit einer Art Kamera aufgenommen werden und vorzugsweise in Kenntnis des Winkels, der in Bezug auf den Projektionswinkel des emittierten Laserstreifens gebildet wird, da jedes dieser Bilder die projizierten Laserstreifen erfasst. Auf der Oberfläche des Objekts werden sie vorverarbeitet, um die Dimensionsmerkmale des zu scannenden Objekts zu extrahieren, und einfach streifenweise über dem Objekt scannen, um das Profil seiner Oberfläche in diesem Quersegment des Objekts zu erhalten, und anschließend erfassen den projizierten Streifen des folgenden Querschnitts des Objekts, um alle projizierten Streifen zusammenzuzählen Vor allen Querschnitten des Obto erhalten wir einen dreidimensionalen Scan seiner Oberfläche
Schritt 2:
Da wir unser Ziel identifiziert haben, den nächsten Schritt in dem Wissen, dass Sie zum Abheben zuerst fest auf dem Boden stehen müssen, haben wir mit einem experimentellen Prototyp eines linearen 3D-Scanners auf dem Boden begonnen, um die korrekte Funktionsweise der Basis zu validieren 3D-Scannerund wie Sie im Bild oben sehen können, habe ich einen PC, OpenCV, Glut von OpenGL, eine Webcam, einen Laser, einen Laserfarmgenerator (in diesem Fall durch einen Rotationsspiegel) ein elektronisches Linearverschiebungssystem (hergestellt mit einer Schiene) verwendet und System aus einem alten Drucker) von einem Sockel, auf dem ich die zu scannenden Objekte Holz und Plastilin platziere und, wie auf dem Foto zu sehen, auf dem Computer: Ich habe es geschafft, mit Glut aus OpenGL eine drei- auf Basis des gescannten realen Objekts reproduziertes Maßmodell (in diesem Fall eine Spielzeugspinne)
Es ist also mehr als offensichtlich, dass das Funktionsprinzip funktioniert und es mit seinen entsprechenden Anpassungen und Anpassungen an ein Flugsystem in der Lage sein wird, eine 3D-Karte des Fluggebietes zu scannen und zu reproduzieren.
Aber dieses System wird nur dazu dienen, 3D-Karten der äußeren Oberfläche der Orte zu erhalten, über die es fliegt???…
Schritt 3:
Kartierung des Inneren von Höhlen und Kanälen (wie im Prometeus-Film) Dieses 3D-Scansystem dient auch dazu, dreidimensionale Modelle des Inneren von großen und hohlen Objekten wie Höhlen, Gebäuden, Tunneln usw. zu rekonstruieren. Sein Funktionsprinzip ist genau wie bereits beschrieben und besteht im Wesentlichen aus:
- Nehmen Sie das Foto jeder Projektion des Laserstreifens auf der zu scannenden Oberfläche auf
- filtern und Farbe aus dem Bild entfernen
- Binarisieren der Farbe mit einem dynamischen Bildschwellenwert
- Wenden Sie einen Kantendetektor an, um das erfasste Profil jedes Laserprojektionsquerschnitts zu erkennen
- und unter Verwendung der Segmentierung den geeigneten Rahmen für die 3D-Darstellung des zu scannenden und zu rekonstruierenden Objektquerschnitts auf der virtuellen 3D-Karte auswählen
- dann werden diese Schritte einfach für jedes Foto wiederholt, das in einer Unterart der Laserstreifen aufgenommen wird, die kontinuierlich von jedem Unterabschnitt in Unterabschnitt projiziert werden.
Schicht für Schicht der Darstellung der Querschnitte werden sukzessive hinzugefügt, bis eine Punktwolke erhalten wird, die aus vielen Darstellungen von Querschnitten des abzubildenden Objekts gebildet wird
Schritt 4:
Dann übergebe ich die Programme zur Bildverarbeitung der Projektionen der oberflächlichen Laserstreifen. und der virtuellen 3D-Rekonstruktion dieser sussiven transversalen Darstellungen im ausgearbeiteten dreidimensionalen Kartenmodell:
Bildverarbeitung:
n
#include #include "cv.h" #include "highgui.h" #include //#include #include #include #include
Zeichen f=0; Zeichenname={"0.jpg"}; int n = 0, s, x, y; CvScalar sp; DATEI *NuPu;
void Writepoints() { char bufferx[33], buffery[33]; itoa (x, Pufferx, 10); itoa (y, gepuffert, 10); fprintf(NuPu, Pufferx); fprintf(NuPu, "\t"); fprintf(NuPu, gepuffert); 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; name[0]=f; cout<
IplImage* img0=cvLoadImage("00.jpg", 0); if(f=='0') { for(y=1;yheight-2;y++) { for(x=1;xwidth-2;x++) { sp=cvGet2D(img0, y, x); if(sp.val[0]>50){Writepoints();n++;} } } } else { for(y=1;yheight-2;y++) { for(x=1;xwidth-2;x++) { sp=cvGet2D(img1, y, x); if(sp.val[0]>50){Writepoints();n++;} } } } Zeichenpuffer[33]; itoa (n, Puffer, 10); fprintf(NuPu, "Fin:"); fprintf(NuPu, Puffer); 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); 0 zurückgeben; }
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) using namespace std; int s, Boton=1, Pulbut=1; float mx=0, my=0, mtx=0, mty=0, mtz=-5.0; const int Avance=1; Schnurleitung, Aux; char Zeichen='H'; DATEI *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; statisches Zeichenlabel[100]; Zeichenpuffer [3]; GLfloat anguloCuboX = 0.0f; GLfloat anguloCuboY = 0.0f; GLfloat anguloEsfera = 0.0f; GLint-Ancho = 500; GLint alt="500; int hazPerspectiva = 0; Void reshape (int Breite, int Höhe) { glViewport (0, 0, Breite, Höhe); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(hazPerspectiva) gluPerspective(23.0f, (GLfloat)width/(GLfloat)height, 1.0f, 20.0f); sonst glOrtho(-1, 1, -1, 1, -10, 10); glMatrixMode(GL_MODELVIEW); Anker = Breite; Alt = Höhe; aufrechtzuerhalten. Void Kolorear (int K) { Float Hüfte; x = (cx[s]-320)/480; y = (cy[s]-240)/640; Hüfte=sqrt(pow(x, 2)+pow(y, 2)); if((Hüfte>=0)&&(Hüfte=.07)&&(Hüfte=.14)&&(Hüfte=.21)&&(Hüfte=.28)&&(Hüfte=.35)&&(Hüfte=.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=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_TIMES_ROMAN_24, "Hello Text";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_BITMAP_TIMES_ROMAN_24, '7');*/ /*glColor3f(1. 0f, 1.0f, 1.0f); setOrthographicProjection(); glPushMatrix(); glLoadIdentity(); renderBitmapString(30, 15, (void *)font, "GLUT Tutorial ---_------_@ 3D Tech");*/ glFlush(); glutSwapBuffers(); anguloCuboX+=0,1f; AnguloCuboY+=0,1f; AnguloEsfera+=0,2f; aufrechtzuerhalten. Void init () { glClearColor (0, 0, 0, 0); glEnable(GL_DEPTH_TEST); Anker = 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"); if (myfile.is_open()) { s=0; while(getline(myfile, line)) { if((line[0]!='N')&(line[0]!='F')) { Aux=line; line[0]=48; Zeile[1]=48; Zeile [2] = 48; Zeile [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++; } } meinedatei.close(); } sonst cout <1780)NP=1700; cout< Void im Leerlauf () { Display (); } void keyboard (unsigned char key, int x, int y) { switch (key) { case 'p': case 'P': hazPerspectiva=1; umformen (Ancho, Alt); brechen; Fall 'o': Fall 'O': hazPerspectiva=0; umformen (Ancho, Alt); brechen; Fall 27: // Escape-Exit (0); brechen; }} void raton(int button, int state, int x, int y) {/* GLUT_LEFT_BUTTON 0 GLUT_MIDDLE_BUTTON 1 GLUT_RIGHT_BUTTON 2 GLUT_DOWN 0 GLUT_UP 1 */ Boton=button; Pulbut=Zustand; //mx=y; Anzeige(); aufrechtzuerhalten. Void ratmov (int x, int y) { if ((Boton = = 0) & (Pulbut = = 0)) { mx = y; mein=x; aufrechtzuerhalten. Wenn ((Boton==2)&(Pulbut==0)) {mtx=(y/200)-1; mty=(x/200)-1; } if((Boton==1)&(Pulbut==0)) {mtz=-(y/40)-5; } Anzeige(); } int main(int argc, char **argv) { /*glutAddMenuEntry() glutAddSubMenu() glutAttachMenu() glutCreateMenu() glutSetMenu() glutStrokeCharacter() glutStrokeLength()*/ /*glReadPixels() liest einen Pixelblock aus dem Framebuffer glGetPixelMapfv() gibt die angegebene Pixelmap zurück glGetPixelMapuiv() gibt die angegebene Pixelmap zurück glGetPointerv() Gibt die Adresse des angegebenen Pointers zurück.*/ Init(); leer(); glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition(50, 50); glutInitWindowSize (Ancho, Alt); glutCreateWindow("Cubo 1"); drin(); glutDisplayFunc (Anzeige); glutReshapeFunc (umformen); glutIdleFunc(leer); glutMouseFunc(raton); glutMotionFunc(ratmov); glutKeyboardFunc (Tastatur); glutMainLoop(); 0 zurückgeben; }
Schritt 5:
im Moment muss ich aufhören! …aber im nächsten Kapitel verspreche ich dir, dass ich es auf meinem Raspberry Pi 3 oder meinem Jetson Nanoboard implementieren werde, das bereits auf einem ferngesteuerten Flugzeug montiert ist, oder auf einem Spinnenroboter, um das Innere von Höhlen zu scannen
Empfohlen:
Arduino Auto-Rückfahrwarnsystem - Schritt für Schritt: 4 Schritte
Arduino Auto-Rückfahrwarnsystem | Schritt für Schritt: In diesem Projekt entwerfe ich eine einfache Arduino-Auto-Rückwärts-Parksensorschaltung mit Arduino UNO und dem Ultraschallsensor HC-SR04. Dieses Arduino-basierte Car-Reverse-Warnsystem kann für eine autonome Navigation, Roboter-Ranging und andere Entfernungsr
So deaktivieren Sie die Autokorrektur für nur ein Wort (iOS): 3 Schritte
So deaktivieren Sie die Autokorrektur für nur ein Wort (iOS): Manchmal korrigiert die Autokorrektur möglicherweise etwas, das Sie nicht korrigieren möchten, z. Textabkürzungen beginnen sich in Großbuchstaben zu setzen (imo korrigieren zum Beispiel zu IMO). So erzwingen Sie, dass die Korrektur eines Wortes oder einer Phrase beendet wird, ohne aut zu deaktivieren
Interessante Programmieranleitung für Designer - Bringen Sie Ihr Bild zum Laufen (Teil 2): 8 Schritte
Interessante Programmieranleitung für Designer – Bringen Sie Ihr Bild zum Laufen (Teil 2): Mathematik scheint für die meisten von Ihnen nutzlos zu sein. Die in unserem täglichen Leben am häufigsten verwendete ist einfach Addieren, Subtrahieren, Multiplizieren und Dividieren. Es ist jedoch ganz anders, wenn Sie mit Programm erstellen können. Je mehr Sie wissen, desto mehr wundervolle Ergebnisse werden Sie erhalten
Wie erstelle ich ein digitales Thermometer # 1: 4 Schritte
So erstellen Sie ein digitales Thermometer Nr. 1: In diesem Artikel werde ich ein Projekt namens "Digitales Thermometer" erstellen. Ich verwende "DHT11" für den Temperatursensor. Und verwenden Sie das "7Segmrnt-Modul" als Anzeige. Ich empfehle, diesen Artikel zuerst zu lesen "DHT11" und &q
D4E1: Lese-Tool 2.0 (Grundlegender Produktionsprozess): 9 Schritte (mit Bildern)
D4E1: Reading-Tool 2.0 (Basic Production Process): Info:- Zwei Studenten Industrial Product Design in Kortrijk (Belgien) haben dieses Reading-Tool entwickelt. Wir haben mit einem bestehenden Design angefangen und es zu einem anderen Design weiterentwickelt. Das Lesetool wurde ursprünglich für einen Client entwickelt