Obsah:

Základní 3D skener pro digitální 3D mapování: 5 kroků
Základní 3D skener pro digitální 3D mapování: 5 kroků

Video: Základní 3D skener pro digitální 3D mapování: 5 kroků

Video: Základní 3D skener pro digitální 3D mapování: 5 kroků
Video: Photogrammetry 2 – 3D scanning with just PHONE/CAMERA simpler, better than ever! 2024, Listopad
Anonim
Základní 3D skener pro digitální 3D mapování
Základní 3D skener pro digitální 3D mapování

V tomto projektu popíšu a vysvětlím základní základy 3D skenování a rekonstrukce aplikované primárně na skenování malých poloplošných objektů a jejichž provoz lze rozšířit na skenovací a rekonstrukční systémy, které lze instalovat na dálkově ovládaná letadla za účelem získání 3D model. z míst, kde letadlo, které je vezme, nainstalované létá

Konečným nápadem je získat 3D sken nějakého místa nebo oblasti, ať už exteriéru nebo interiéru, a použít ji jako digitální mapu (jako ve filmu Prometeus)

Krok 1:

obraz
obraz

myšlenka je nainstalovat celý 3D skenovací systém na dálkově ovládané letadlo, aby se digitalizovala virtuální mapa jakékoli oblasti, nad kterou letí ve 3D, ale kvůli tomu jsme začali od začátku provozu laserové triangulace metoda skenování nebo 3D rekonstrukce laserovou triangulací v zásadě spočívá v průchodu laserového paprsku hranolem, který generuje laserový proužek k získání celého laserového pruhu, který bude promítán na skenovaný objekt, a jakmile bude tato laserová projekce získána na povrchový povrch Z místa ke skenování musí být obraz zachycen nějakým typem kamery a nejlépe s vědomím úhlu, který je vytvořen s ohledem na projekční úhel vyzařovaného laserového pruhu, protože každý z těchto obrazů zachycuje promítané laserové pásy. Na povrchu předmětu budou předzpracovány, aby se extrahovaly rozměrové charakteristiky předmětu, který má být skenován, a jednoduše skenují proužek po pásu nad objektem, aby se získal profil jeho povrchu v tomto příčném segmentu předmětu, a následně zachytily promítaný pás následujícího průřezu objektu, sečíst všechny promítané pruhy dohromady Před všemi příčnými řezy obta získáme trojrozměrné skenování jeho povrchu

Krok 2:

obraz
obraz

Protože jsme identifikovali náš cíl, další krok s vědomím, že ke vzletu musíte mít nejprve nohy pevně na zemi, a proto jsme začali na zemi s experimentálním prototypem lineárního 3D skeneru, abychom ověřili správnou činnost základního 3D skener a jak vidíte na obrázku výše, použil jsem PC, OpenCV, Glut of OpenGL, webovou kameru, laser, generátor laserové farmy (v tomto případě přes rotační zrcadlo) elektronický lineární systém posunu (vyrobený s kolejnicí) a systém extrahovaný ze staré tiskárny) ze základny, na kterou položím skenované objekty, dřevo a plastelínu a jak vidíte na fotografii, na počítači: Podařilo se mi vygenerovat a zobrazit pomocí Glut z OpenGL tři rozměrový model reprodukovaný na základě naskenovaného skutečného objektu (v tomto případě pavouka)

je tedy více než evidentní, že operační princip je funkční a že s příslušnými úpravami a přizpůsobeními létajícímu systému bude schopen skenovat a reprodukovat 3D mapu oblasti, ve které létá.

Tento systém ale bude sloužit pouze k získávání 3D map vnějšího povrchu míst, nad kterými létá ???…

Krok 3:

obraz
obraz

mapování vnitřku jeskyní a potrubí (stejně jako ve filmu Prometeus) Tento 3D skenovací systém také slouží k rekonstrukci trojrozměrných modelů interiéru velkých a dutých předmětů, jako jsou jeskyně, budovy, tunely atd., jeho princip činnosti je přesně to samé, co již bylo popsáno a které v zásadě sestává z následujícího:

  1. pořiďte fotografii každé projekce laserového proužku na skenovaný povrch
  2. filtrovat a odstranit barvu z obrázku
  3. binarizujte barvu pomocí dynamického prahu obrazu
  4. použijte detektor hran k rozpoznání zachyceného profilu každého průřezu laserové projekce
  5. a pomocí segmentace vyberte příslušné ohraničení pro 3D reprezentaci tohoto průřezu objektu, který má být skenován a rekonstruován na virtuální 3D mapě
  6. pak se tyto kroky jednoduše opakují pro každou fotografii pořízenou podoblastí laserových pruhů nepřetržitě promítaných každým dílčím úsekem v dílčím řezu.
  7. vrstva po vrstvě zobrazení příčných řezů se přidává postupně, dokud se nezíská mračno bodů tvořené mnoha reprezentacemi příčných řezů mapovaného objektu

Krok 4:

obraz
obraz

Poté předávám programy pro zpracování obrazu projekcí povrchových laserových pásů. a virtuální 3D rekonstrukci těchto sussivních transverzálních reprezentací ve zpracovaném trojrozměrném mapovém modelu:

zpracování obrazu:

n

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

znak f = 0; char name = {"0.jpg"}; int n = 0, s, x, y; CvScalar sp; SOUBOR *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; jméno [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, buffer, 10); fprintf (NuPu, "Fin:"); fprintf (NuPu, buffer); fprintf (NuPu, "\ n"); fclose (NuPu);

cvWaitKey (0); //_execlp("calc.exe "," calc.exe ", argstr, NULL); cvDestroyAllWindows (); cvReleaseImage (& obrázek); cvReleaseImage (& img); cvReleaseImage (& img0); cvReleaseImage (& img1); cvReleaseImage (& img2); návrat 0; }

3D rekonstrukce:

#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) pomocí oboru názvů std; int s, Boton = 1, Pulbut = 1; float mx = 0, my = 0, mtx = 0, mty = 0, mtz = -5,0; const int Avance = 1; struna, Aux; char Caracter = 'H'; SOUBOR *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; štítek se statickým znakem [100]; char buffer [3]; GLfloat anguloCuboX = 0,0f; GLfloat anguloCuboY = 0,0f; GLfloat anguloEsfera = 0,0f; GLint ancho = 500; GLint alt=500; int hazardPerspectiva = 0; void reshape (int width, int height) {glViewport (0, 0, width, height); glMatrixMode (GL_PROJECTION); glLoadIdentity (); if (hazPerspectiva) gluPerspective (23.0f, (GLfloat) width/(GLfloat) height, 1.0f, 20.0f); jinak glOrtho (-1, 1, -1, 1, -10, 10); glMatrixMode (GL_MODELVIEW); ancho = šířka; alt=výška; } neplatné Kolorear (int K) {float Hip; x = (cx [s] -320)/480; y = (cy [s] -240)/640; Hip = sqrt (pow (x, 2)+pow (y, 2)); if ((Hip> = 0) && (Hip =.07) && (Hip = 0,14) && (Hip = 0,21) && (Hip = 0,28) && (Hip = 0,35) && (Hip = 0,42) && (Hip <=. 49)) {violeta;}} neplatné drawNuPu (neplatné) {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_BITM "; 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 ');* / /*glColor3f (1. 0f, 1,0f, 1,0f); setOrthographicProjection (); glPushMatrix (); glLoadIdentity (); renderBitmapString (30, 15, (void *) písmo, „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; 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; řádek [0] = 48; řádek [1] = 48; řádek [2] = 48; řádek [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 (); } prázdná klávesnice (znak bez znaménka, int x, int y) {přepínač (klíč) {case 'p': case 'P': hazardPerspectiva = 1; přetvořit (ancho, alt); přestávka; případ 'o': případ 'O': hazardPerspectiva = 0; přetvořit (ancho, alt); přestávka; případ 27: // escape exit (0); přestávka; }} neplatný raton (tlačítko int, stav int, int x, int y) { / * GLUT_LEFT_BUTTON 0 GLUT_MIDDLE_BUTTON 1 GLUT_RIGHT_BUTTON 2 GLUT_DOWN 0 GLUT_UP 1 * / Boton = tlačítko; Pulbut = stav; // mx = y; Zobrazit(); } 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; } Zobrazit(); } int main (int argc, char ** argv) { /*glutAddMenuEntry () glutAddSubMenu () glutAttachMenu () glutCreateMenu () glutSetMenu () glutStrokeCharacter () glutStrokeLength ()* / /*glReadPixels () načíst blok pixelů z vyrovnávací paměť rámce glGetPixelMapfv () vrátí zadanou mapu pixelů glGetPixelMapuiv () vrátí zadanou mapu pixelů glGetPointerv () Vrátí adresu zadaného ukazatele.*/ Init (); leer (); glutInit (& argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition (50, 50); glutInitWindowSize (ancho, alt); glutCreateWindow ("Cubo 1"); init (); glutDisplayFunc (zobrazení); glutReshapeFunc (přetvořit); glutIdleFunc (nečinný); glutMouseFunc (raton); glutMotionFunc (ratmov); glutKeyboardFunc (klávesnice); glutMainLoop (); návrat 0; }

Krok 5:

obraz
obraz

pro tuto chvíli musím přestat! … Ale v další kapitole vám slibuji, že to implementuji na svém malinovém pi 3 nebo nanoboardu jetson, který je již namontován na nějakém dálkově ovládaném letadle, nebo na nějakém pavoučím robotu, aby skenoval vnitřek jeskyní

Doporučuje: