Spisu treści:
Wideo: Podstawowy skaner 3D do cyfrowego mapowania 3D: 5 kroków
2024 Autor: John Day | [email protected]. Ostatnio zmodyfikowany: 2024-01-30 11:28
W tym projekcie opiszę i wyjaśnię podstawowe podstawy skanowania i rekonstrukcji 3D stosowane przede wszystkim do skanowania małych obiektów półpłaszczyznowych, a których działanie można rozszerzyć o systemy skanowania i rekonstrukcji, które można zainstalować na samolotach zdalnie sterowanych w celu uzyskania model 3D. miejsc, w których samolot, który je zabiera, zainstalował muchy
Ostatecznym pomysłem jest uzyskanie skanu 3D jakiegoś miejsca lub obszaru, na zewnątrz lub wewnątrz, aby użyć go jako mapy cyfrowej (jak w filmie Prometeusza)
Krok 1:
chodzi o zainstalowanie całego systemu skanowania 3d na zdalnie sterowanym samolocie, aby zdigitalizować wirtualną mapę dowolnego obszaru, nad którym leci w 3d, ale w tym celu rozpoczęliśmy od początku działanie metody triangulacji laserowej skanowania lub rekonstrukcji 3D za pomocą triangulacji laserowej zasadniczo polega na przepuszczeniu wiązki laserowej przez pryzmat generujący pasek laserowy w celu uzyskania całego paska laserowego, który zostanie rzutowany na skanowany obiekt, a po uzyskaniu projekcji laserowej na powierzchnia Z miejsca do skanowania obraz musi być uchwycony za pomocą pewnego rodzaju kamery i najlepiej znając kąt, który jest utworzony w odniesieniu do kąta rzutu emitowanego paska laserowego, ponieważ każdy z tych obrazów rejestruje wyświetlane paski laserowe. Na powierzchni obiektu zostaną one wstępnie przetworzone w celu wyodrębnienia cech wymiarowych obiektu, który ma być zeskanowany, i po prostu zeskanuj pasek po pasku nad obiektem, aby uzyskać profil jego powierzchni w tym poprzecznym segmencie obiektu, a następnie uchwycić rzutowany pasek o kolejnym przekroju obiektu, aby zsumować wszystkie rzutowane paski ze sobą Przed wszystkimi przekrojami obto uzyskujemy trójwymiarowy skan jego powierzchni
Krok 2:
Ponieważ określiliśmy nasz cel, następnym krokiem jest świadomość, że aby wystartować, musisz najpierw mocno stąpać po ziemi, więc rozpoczęliśmy na ziemi od eksperymentalnego prototypu liniowego skanera 3d, aby sprawdzić poprawność działania podstawowego skaner 3d i jak widać na powyższym obrazku użyłem komputera PC, OpenCV, Glut of OpenGL, kamerki internetowej, lasera, generatora farmy laserowej (w tym przypadku poprzez lustro obrotowe) elektronicznego systemu przemieszczenia liniowego (wykonanego z szyny i system wypakowany ze starej drukarki) z bazy, na której umieszczam obiekty do zeskanowania, drewno i plastelina i jak widać na zdjęciu, na komputerze: udało mi się wygenerować i wyświetlić za pomocą Glut z OpenGL trzy- model wymiarowy odtworzony na podstawie zeskanowanego obiektu rzeczywistego (w tym przypadku pająka-zabawki)
więc jest bardziej niż oczywiste, że zasada działania jest funkcjonalna i że dzięki odpowiednim dostosowaniom i adaptacjom do systemu latającego będzie w stanie zeskanować i odtworzyć trójwymiarową mapę obszaru, w którym lata.
Ale ten system będzie służył tylko do uzyskania map 3D zewnętrznej powierzchni miejsc, nad którymi przelatuje???…
Krok 3:
mapowanie wnętrz jaskiń i kanałów (tak jak w filmie Prometeusz) Ten system skanowania 3D służy również do rekonstrukcji trójwymiarowych modeli wnętrza dużych i pustych w środku obiektów takich jak jaskinie, budynki, tunele itp. jego zasadą działania jest dokładnie to samo, co już opisano i które zasadniczo składa się z następujących elementów:
- Zrób zdjęcie każdego rzutu paska laserowego na skanowaną powierzchnię
- filtruj i usuwaj kolor z obrazu
- zbinaryzować kolor z dynamicznym progiem obrazu
- zastosuj detektor krawędzi, aby rozpoznać przechwycony profil każdego przekroju projekcji laserowej;
- i za pomocą segmentacji wybierz odpowiednią granicę dla reprezentacji 3D tego przekroju obiektu, który ma być zeskanowany i zrekonstruowany na wirtualnej mapie 3D
- następnie te kroki są po prostu powtarzane dla każdego zdjęcia wykonanego w podsekcji pasków laserowych wyświetlanych w sposób ciągły przez każdą podsekcję w podsekcji.
warstwa po warstwie reprezentacji przekrojów są dodawane sukcesywnie aż do uzyskania chmury punktów utworzonej z wielu reprezentacji przekrojów obiektu przeznaczonego do mapowania
Krok 4:
Następnie przekazuję programy do obróbki obrazu rzutów powierzchniowych pasków laserowych. oraz wirtualną rekonstrukcję 3D tych suspensywnych reprezentacji poprzecznych w opracowanym trójwymiarowym modelu mapy:
przetwarzanie obrazu:
n
#include #include "cv.h" #include "highgui.h" #include //#include #include #include #include
znak f=0; nazwa znaku={"0.jpg"}; int n=0, s, x, y; CvScalar sp; PLIK *NuPu;
void Writepoints() { char bufferx[33], buffery[33]; itoa (x, buforx, 10); itoa (y, buforowy, 10); fprintf(NuPu, buforx); fprintf(NuPu, "\t"); fprintf(NuPu, bufor); 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; nazwa[0]=f; szajka<
IplImage* img0=cvLoadImage("00.jpg", 0); if(f=='0') { for(y=1;ywysokość-2;y++) { for(x=1;xszerokość-2;x++) { sp=cvGet2D(img0, y, x); if(sp.val[0]>50){Punkty zapisu();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, bufor, 10); fprintf(NuPu, "Fin:"); fprintf(NuPu, bufor); fprintf(NuPu, "\n"); fzamknij (NuPu);
cvWaitKey(0); //_execlp("calc.exe", "calc.exe", argstr, NULL); cvZniszczWszystkieOkna(); cvReleaseImage(&obraz); cvReleaseImage(&img); cvReleaseImage(&img0); cvReleaseImage(&img1); cvReleaseImage(&img2); zwróć 0; }
Rekonstrukcja 3D:
#include ////////////////// #ifdef _APPLE_ #include #else #include #include #endif #include #include #include #include #include #include
#define fioletowa 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, moj=0, mtx=0, mty=0, mtz=-5,0; const int Avance=1; linia strunowa, Aux; char Znak='H'; PLIK *NuPu; int NP, h, w; float G=0, n=0, cx[5000], cy[5000], x, y, ax, ay, az; int czcionka=(int)GLUT_BITMAP_8_BY_13; etykieta ze znakami statycznymi[100]; bufor znaków [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 szerokość, int wysokość) { glViewport(0, 0, szerokość, wysokość); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(hazPerspectiva) gluPerspective(23.0f, (GLfloat)width/(GLfloat)height, 1.0f, 20.0f); w przeciwnym razie glOrtho(-1, 1, -1, 1, -10, 10); glMatrixMode(GL_MODELVIEW); Ancho = szerokość; alt=wysokość; } void Kolorear(int K) { float Hip; x=(cx[s]-320)/480; y=(cy[s]-240)/640; Hip=sqrt(pow(x, 2)+pow(y, 2)); if((biodro>=0)&&(biodro=.07)&&(biodro=.14)&&(biodro=.21)&&(biodro=.28)&&(biodro=.35)&&(biodro=.42) &&(Hip<=.49)){fiolet;} } void drawNuPu(void) { glColor3f(1, 1, 1); glPoczątek(GL_LINES); glVertex3f(.2, 0, 0); glVertex3f(-.2, 0, 0); glVertex3f (0, 0,2, 0); glVertex3f(0, -0,2, 0); gLend(); rojo; glPoczątek(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_HROMAN_24);;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,);*/ /*glColor3f(1. 0f, 1,0f, 1,0f); setOrthographicProjection(); glPushMatrix(); glLoadIdentity(); renderBitmapString(30, 15, (void *)font, "Poradnik GLUT ---_------_@Technologia 3D");*/ glFlush(); glutSwapBufory(); 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 (mojplik.is_open()) { s=0; while(getline(myfile, line)) { if((line[0]!='N')&&(line[0]!='F')) { Aux=line; linia[0]=48; linia[1]=48; linia[2]=48; linia[3]=48; cy[s]=atoi(linia.c_str()); Pomoc[4]=48; Aux[5]=48; Aux[6]=48; //Pomoc[7]=48; cx[s]=atoi(Aux.c_str()); s++; } } mójplik.zamknij(); } w przeciwnym razie cout <1780)NP=1700; cout< void bezczynny() { display(); } void keyboard(unsigned char key, int x, int y) { switch(key) { case 'p': case 'P': hazPerspectiva=1; zmienić kształt(ancho, alt); przerwa; przypadek 'o': przypadek 'O': hazPerspectiva=0; zmienić kształt(ancho, alt); przerwa; przypadek 27: // wyjście ewakuacyjne(0); przerwa; } } void raton(int przycisk, int stan, 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=stan; //mx=y; wyświetlacz(); } void ratmov(int x, int y) { if((Boton==0)&(Pulbut==0)) { mx=y; mój=x; } if((Boton==2)&(Pulbut==0)) { mtx=(y/200)-1; mty=(x/200)-1; } if((Boton==1)&(Pulbut==0)) { mtz=-(y/40)-5; } wyświetlacz(); } int main(int argc, char **argv) { /*glutAddMenuEntry() glutAddSubMenu() glutAttachMenu() glutCreateMenu() glutSetMenu() glutStrokeCharacter() glutStrokeLength()*/ /*glReadPixels() odczytuje blok pikseli z bufor ramki glGetPixelMapfv() zwraca określoną mapę pikseli glGetPixelMapuiv() zwraca określoną mapę pikseli glGetPointerv() Zwraca adres podanego wskaźnika.*/ Init(); chytre spojrzenie(); glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition(50, 50); glutInitWindowSize(ancho, alt); glutCreateWindow("Cubo 1"); w tym(); glutDisplayFunc(wyświetlanie); glutReshapeFunc(przekształcenie); funkcja glutIdle(bezczynny); glutMouseFunc(raton); glutMotionFunc(ratmov); glutKeyboardFunc(klawiatura); glutMainLoop(); zwróć 0; }
Krok 5:
na razie muszę przestać! …ale w następnym rozdziale obiecuję, że zaimplementuję go na mojej raspberry pi 3 lub mojej nanoboardzie jetson, zamontowanych już na jakimś zdalnie sterowanym samolocie, lub na jakimś pajęczym robocie do skanowania wnętrz jaskiń
Zalecana:
Wskazówki dotyczące mapowania: 3 kroki
Wskazówki dotyczące mapowania: niezależnie od aktywności, czy to chodzenia, wędrówek, jazdy na rowerze, a nawet jazdy, możesz rejestrować przebyte trasy. Następnie możesz udostępniać te trasy znajomym i rodzinie. Ponadto możesz użyć nagranej trasy, aby dodać lokalizacje do dowolnych zdjęć, które
Pedał opóźnienia cyfrowego: 19 kroków (ze zdjęciami)
Digital Delay Pedal: Budowanie pedałów gitarowych jest czasochłonnym, często frustrującym i kosztownym procesem. Jeśli myślisz, że zaoszczędzisz czas i pieniądze, tworząc swój własny cyfrowy pedał opóźniający, gorąco radzę przeczytać R.G. Strona Keen na temat ekonomiki budowy pedałów
Korzystanie z 4-cyfrowego i 7-segmentowego wyświetlacza z Arduino: 7 kroków
Korzystanie z 4-cyfrowego i 7-segmentowego wyświetlacza z Arduino: W tym samouczku pokażę, jak korzystać z 7-segmentowego wyświetlacza z 4-cyfrowymi za pomocą arduino. Kilka podstawowych rzeczy, na które chciałbym zwrócić uwagę, to to, że zajmuje to prawie wszystkie cyfrowe piny w arduino uno, leonardo, płytach z 13 cyframi
Opracuj własny zestaw do zmiany mapowania PS4: 4 kroki
Opracuj swój własny zestaw do zmiany mapowania PS4: Stwórz własny zestaw do zmiany mapowania PS4 poprzez inżynierię wsteczną projektu układu FPC zestawu do zmiany mapowania. Wyprowadzanie plików Gerber z zestawu remappera PS4. Pliki Gerber są dostępne dla Ciebie, tylko w skrzynce odbiorczej. Układ można zmienić również w razie potrzeby
Wczesne ostrzeżenie Światło pasa startowego Raspberry PI przy użyciu danych mapowania lotu: 14 kroków (ze zdjęciami)
Wczesne ostrzeżenie Światło pasa startowego Raspberry PI wykorzystujące dane mapowania lotu: Ta lampa powstała z kilku powodów, ponieważ zawsze interesują mnie samoloty, które latają nad głową, a latem w weekendy często latają całkiem ekscytujące. Chociaż słyszysz je tylko wtedy, gdy mijają