Table des matières:

Scanner 3D de base pour la cartographie numérique 3D : 5 étapes
Scanner 3D de base pour la cartographie numérique 3D : 5 étapes

Vidéo: Scanner 3D de base pour la cartographie numérique 3D : 5 étapes

Vidéo: Scanner 3D de base pour la cartographie numérique 3D : 5 étapes
Vidéo: # 216 - Présentation du scanner 3D Ciclop 2024, Septembre
Anonim
Scanner 3D de base pour la cartographie 3D numérique
Scanner 3D de base pour la cartographie 3D numérique

Dans ce projet, je décrirai et expliquerai les bases de base de la numérisation et de la reconstruction 3D appliquées principalement à la numérisation de petits objets semi-plans, et dont le fonctionnement peut être étendu aux systèmes de numérisation et de reconstruction qui peuvent être installés sur des avions télécommandés pour obtenir un modèle 3D. des endroits où vole l'avion qui les emmène installé

L'idée finale est d'obtenir un scan 3D d'un endroit ou d'une zone, que ce soit son extérieur ou son intérieur, pour l'utiliser comme une carte numérique (comme dans le film de Prometeus)

Étape 1:

Image
Image

l'idée est d'installer l'ensemble du système de scan 3d sur un avion télécommandé, afin de numériser la carte virtuelle de n'importe quelle zone sur laquelle il survole en 3d, mais pour cela nous avons commencé dès le début de l'opération de la triangulation laser la méthode de numérisation ou reconstruction 3D par triangulation laser consiste essentiellement à faire passer un faisceau laser à travers un prisme qui génère un ruban laser pour obtenir un ruban laser entier qui sera projeté sur un objet à numériser, et une fois cette projection laser obtenue sur le surface de surface De l'endroit à scanner, l'image doit être capturée avec un certain type de caméra et de préférence en connaissant l'angle qui est formé par rapport à l'angle de projection de la bande laser émise, puisque chacune de ces images capture les bandes laser projetées. Sur la surface de l'objet, ils seront prétraités pour extraire les caractéristiques dimensionnelles de l'objet à scanner, et simplement scanner bande par bande au-dessus de l'objet pour obtenir le profil de sa surface dans ce segment transversal de l'objet, et ensuite capturer la bande projetée de la coupe transversale suivante de l'objet, pour additionner toutes les rayures projetées ensemble Avant toutes les coupes transversales de l'obto on obtient un scan en trois dimensions de sa surface

Étape 2:

Image
Image

Depuis que nous avons identifié notre objectif, la prochaine étape sachant que pour décoller il faut d'abord avoir les pieds bien sur le sol, nous sommes donc partis au sol avec un prototype expérimental d'un scanner 3d linéaire, pour valider le bon fonctionnement de la base Scanner 3D et comme vous pouvez le voir dans l'image ci-dessus, j'ai utilisé un PC, OpenCV, Glut d'OpenGL, une webcam, un laser, un générateur de ferme laser (dans ce cas à travers un miroir rotatif) un système électronique de déplacement linéaire (fait avec un rail et système extrait d'une ancienne imprimante) à partir d'un socle sur lequel je place les objets à numériser, bois et pâte à modeler et comme vous pouvez le voir sur la photo, sur l'ordinateur: j'ai réussi à générer et afficher avec Glut depuis OpenGL un trois- modèle dimensionnel reproduit sur la base de l'objet réel scanné (dans ce cas une araignée jouet)

il est donc plus qu'évident que le principe de fonctionnement est fonctionnel, et qu'avec ses réglages et adaptations respectifs à un système de vol il pourra scanner et reproduire une carte 3D de la zone dans laquelle il vole.

Mais ce système ne servira qu'à obtenir des cartes 3D de la surface externe des lieux qu'il survole ???…

Étape 3:

Image
Image

cartographier l'intérieur des grottes et des conduits (comme dans le film Prometeus). exactement le même que déjà décrit et qui se compose essentiellement des éléments suivants:

  1. capturer la photo de chaque projection de la bande laser sur la surface à scanner
  2. filtrer et supprimer la couleur de l'image
  3. binariser la couleur avec un seuil d'image dynamique
  4. appliquer un détecteur de bord pour reconnaître le profil capturé de chaque section transversale de projection laser
  5. et à l'aide de la segmentation, sélectionnez la bordure appropriée pour la représentation 3D de cette section transversale de l'objet à numériser et à reconstruire sur la carte virtuelle 3D
  6. puis ces étapes sont simplement répétées pour chaque photo prise d'une sous-manière des bandes laser projetées en continu par chaque sous-section en sous-section.
  7. couche par couche de la représentation des coupes sont additionnées successivement jusqu'à obtenir un nuage de points formé de plusieurs représentations de coupes de l'objet à cartographier

Étape 4:

Image
Image

Puis je passe les programmes de traitement d'image des projections des bandes laser superficielles. et de la reconstruction virtuelle en 3D de ces représentations transversales sussives dans le modèle cartographique tridimensionnel élaboré:

traitement d'image:

m

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

caractère f=0; nom de caractère={"0.jpg"}; entier n=0, s, x, y; CvScalar sp; FICHIER *NuPu;

void Writepoints() { char bufferx[33], buffery[33]; itoa (x, bufferx, 10); itoa (y, tampon, 10); fprintf(NuPu, bufferx); fprintf(NuPu, "\t"); fprintf(NuPu, tampon); fprintf(NuPu, "\n"); }

void noteblockInit() { NuPu=fopen("NuPu.txt", "w"); fcherche(NuPu, 0, 0); fprintf(NuPu, "NP:"); fprintf(NuPu, "\n"); }

int main() { char argstr[128]; blocnoteInit(); cout<<"Teklea!…:"f; nom[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++;} } } } char buffer[33]; itoa (n, tampon, 10); fprintf(NuPu, "Fin:"); fprintf(NuPu, tampon); fprintf(NuPu, "\n"); fclose(NuPu);

cvWaitKey(0); //_execlp("calc.exe", "calc.exe", argstr, NULL); cvDestroyAllWindows(); cvReleaseImage(&image); cvReleaseImage(&img); cvReleaseImage(&img0); cvImageRelease(&img1); cvReleaseImage(&img2); renvoie 0; }

Reconstitution 3D:

#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) en utilisant l'espace de noms std; int s, Boton=1, Pulbut=1; float mx=0, my=0, mtx=0, mty=0, mtz=-5,0; const int Avance=1; ligne de chaîne, Aux; caractère Caractère='H'; FICHIER *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; étiquette de caractère statique[100]; tampon de caractères[3]; GLfloat anguloCuboX = 0.0f; GLfloat anguloCuboY = 0.0f; GLfloat anguloEsfera = 0.0f; GLint ancho=500; GLint alto=500; int hazPerspectiva = 0; void reshape(int largeur, int hauteur) { glViewport(0, 0, largeur, hauteur); glModeMatrice(GL_PROJECTION); glLoadIdentity(); if(hazPerspectiva) gluPerspective(23.0f, (GLfloat)largeur/(GLfloat)hauteur, 1.0f, 20.0f); sinon glOrtho(-1, 1, -1, 1, -10, 10); glModeMatrice(GL_MODELVIEW); ancho = largeur; alto = hauteur; } void Kolorear(int K) { float Hip; x=(cx[s]-320)/480; y=(cy[s]-240)/640; Hanche=sqrt(pow(x, 2)+pow(y, 2)); if((Hanche>=0)&&(Hanche=.07)&&(Hanche=.14)&&(Hanche=.21)&&(Hanche=.28)&&(Hanche=.35)&&(Hanche=.42) &&(Hip<=.49)){violeta;} } void drawNuPu(void) { glColor3f(1, 1, 1); glDébut(GL_LINES); glVertex3f(.2, 0, 0); glVertex3f(-.2, 0, 0); glVertex3f(0,.2, 0); glVertex3f(0, -.2, 0); glFin(); rojo; glDébut(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, "Bonjour le texte0");;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');*/ /*glCouleur3f(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; } void init() { glClearColor(0, 0, 0, 0); glEnable(GL_DEPTH_TEST); ancho = 500; alto = 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 (monfichier.is_open()) { s=0; while(getline(myfile, line)) { if((line[0]!='N')&&(line[0]!='F')) { Aux=line; ligne[0]=48; ligne[1]=48; ligne[2]=48; ligne[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++; } } monfichier.close(); } else cout <1780)NP=1700; cout< void inactif() { display(); } void keyboard(unsigned char key, int x, int y) { switch(key) { case 'p': case 'P': hazPerspectiva=1; remodeler (ancho, alto); Pause; cas 'o': cas 'O': hazPerspectiva=0; remodeler (ancho, alto); Pause; case 27: // escape exit(0); Pause; } } 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=bouton; Pulbut=état; //mx=y; affichage(); } void ratmov(int x, int y) { if((Boton==0)&(Pulbut==0)) { mx=y; mon=x; } if((Boton==2)&(Pulbut==0)) { mtx=(y/200)-1; mty=(x/200)-1; } if((Boton==1)&(Pulbut==0)) { mtz=-(y/40)-5; } affichage(); } int main(int argc, char **argv) { /*glutAddMenuEntry() glutAddSubMenu() glutAttachMenu() glutCreateMenu() glutSetMenu() glutStrokeCharacter() glutStrokeLength()*/ /*glReadPixels() lit un bloc de pixels à partir du frame buffer glGetPixelMapfv() renvoie la carte de pixels spécifiée glGetPixelMapuiv() renvoie la carte de pixels spécifiée glGetPointerv() Renvoie l'adresse du pointeur spécifié.*/ Init(); lorgner(); glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition (50, 50); glutInitWindowSize(ancho, alto); glutCreateWindow("Cubo 1"); init(); glutDisplayFunc(affichage); glutReshapeFunc(remodeler); glutIdleFunc(inactif); glutMouseFunc(raton); glutMotionFunc(ratmov); glutKeyboardFunc(clavier); glutMainLoop(); renvoie 0; }

Étape 5:

Image
Image

pour le moment je dois arrêter ! …mais dans le prochain chapitre je vous promets que je vais l'implémenter sur mon raspberry pi 3 ou mon jetson nanoboard, déjà monté sur certains avions télécommandés, ou sur quelque robot araignée pour scanner l'intérieur des grottes

Conseillé: