Índice:
Vídeo: Scanner 3D básico para mapeamento 3D digital: 5 etapas
2024 Autor: John Day | [email protected]. Última modificação: 2024-01-30 11:35
Neste projeto, vou descrever e explicar os fundamentos básicos da digitalização e reconstrução 3D aplicada principalmente à digitalização de pequenos objetos semiplanos, e cuja operação pode ser estendida a sistemas de digitalização e reconstrução que podem ser instalados em aeronaves de controle remoto para obter um modelo 3D. dos locais onde voa o avião que os leva instalado
A ideia final é obter uma digitalização 3D de algum lugar ou área, seja seu exterior ou interior, para utilizá-lo como um mapa digital (como no filme do Prometeus)
Passo 1:
a ideia é instalar todo o sistema de escaneamento 3d em um plano de controle remoto, a fim de digitalizar o mapa virtual de qualquer área sobre a qual voe em 3d, mas para isso partimos do início da operação de triangulação a laser o método de digitalização ou reconstrução 3d por triangulação a laser consiste basicamente em passar um feixe de laser através de um prisma que gera uma faixa de laser para obter uma faixa de laser inteira que será projetada em um objeto a ser digitalizado, e uma vez que essa projeção de laser tenha sido obtida no superfície superfície Do local a ser escaneado, a imagem deve ser capturada com algum tipo de câmera e de preferência conhecendo o ângulo que se forma em relação ao ângulo de projeção da faixa de laser emitida, pois cada uma dessas imagens captura as faixas de laser projetadas. Na superfície do objeto, eles serão pré-processados para extrair as características dimensionais do objeto a ser digitalizado, e simplesmente digitalizar tira por tira acima do objeto para obter o perfil de sua superfície naquele segmento transversal do objeto e, posteriormente, capturar a tira projetada da seguinte seção transversal do objeto, para somar todas as listras projetadas juntas. Antes de todas as seções transversais do obto, obtemos uma varredura tridimensional de sua superfície
Passo 2:
Já que identificamos nosso objetivo, o próximo passo sabendo que para decolar é preciso primeiro ter os pés bem assentes no chão, por isso partimos no solo com um protótipo experimental de um scanner linear 3D, para validar o correto funcionamento do básico Scanner 3D e como você pode ver na imagem acima, usei um PC, OpenCV, Glut of OpenGL, uma webcam, um laser, gerador de laser farm (neste caso através de um espelho rotacional) um sistema eletrônico de deslocamento linear (feito com trilho e sistema extraído de uma impressora antiga) de uma base na qual coloco os objetos a serem digitalizados, madeira e plasticina e como vocês podem ver na foto, no computador: Consegui gerar e exibir com o Glut do OpenGL um três- modelo dimensional reproduzido com base no objeto real digitalizado (neste caso, uma aranha de brinquedo)
portanto, é mais do que evidente que o princípio de funcionamento é funcional, e que com seus respectivos ajustes e adaptações a um sistema voador será capaz de escanear e reproduzir um mapa 3D da área em que voa.
Mas este sistema servirá apenas para obter mapas 3D da superfície externa dos locais por onde sobrevoa ???…
Etapa 3:
mapeamento do interior das cavernas e dutos (assim como no filme Prometeus) Este sistema de digitalização 3D também serve para reconstruir modelos tridimensionais do interior de objetos grandes e ocos, como cavernas, edifícios, túneis, etc. seu princípio de funcionamento é exatamente o mesmo já descrito e que consiste basicamente no seguinte:
- capture a foto de cada projeção da faixa de laser na superfície a ser digitalizada
- filtrar e remover a cor da imagem
- binarize a cor com um limiar de imagem dinâmico
- aplique um detector de borda para reconhecer o perfil capturado de cada seção transversal de projeção de laser
- e usando a segmentação, selecione a borda apropriada para a representação 3d daquela seção transversal do objeto a ser digitalizado e reconstruído no mapa 3D virtual
- em seguida, essas etapas são simplesmente repetidas para cada foto tirada em uma subseção das faixas de laser continuamente projetadas por cada subseção na subseção.
camada por camada da representação das seções transversais são adicionadas sucessivamente até a obtenção de uma nuvem de pontos formada por várias representações das seções transversais do objeto a ser mapeado
Passo 4:
Em seguida, passo os programas para processamento de imagem das projeções das tiras de laser superficiais. e da reconstrução virtual em 3D dessas representações transversais no modelo de mapa tridimensional elaborado:
processamento de imagem:
n
#include #include "cv.h" #include "highgui.h" #include // #include #include #include #include
char f = 0; nome do char = {"0.jpg"}; int n = 0, s, x, y; CvScalar sp; ARQUIVO * NuPu;
void Writepoints () {char bufferx [33], buffery [33]; itoa (x, bufferx, 10); itoa (y, buffery, 10); fprintf (NuPu, bufferx); fprintf (NuPu, "\ t"); fprintf (NuPu, buffer); 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; nome [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 (& imagem); cvReleaseImage (& img); cvReleaseImage (& img0); cvReleaseImage (& img1); cvReleaseImage (& img2); return 0; }
Reconstrução 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) usando namespace std; int s, Boton = 1, Pulbut = 1; float mx = 0, my = 0, mtx = 0, mty = 0, mtz = -5,0; const int Avance = 1; linha de string, Aux; char Caracter = 'H'; ARQUIVO * NuPu; int NP, h, w; flutuante G = 0, n = 0, cx [5000], cy [5000], x, y, ax, ay, az; fonte int = (int) GLUT_BITMAP_8_BY_13; etiqueta de char estática [100]; buffer char [3]; GLfloat anguloCuboX = 0,0f; GLfloat anguloCuboY = 0,0f; GLfloat anguloEsfera = 0,0f; GLint ancho = 500; GLint alto = 500; int hazPerspectiva = 0; void reshape (largura interna, altura interna) {glViewport (0, 0, largura, altura); glMatrixMode (GL_PROJECTION); glLoadIdentity (); if (hazPerspectiva) gluPerspective (23.0f, (GLfloat) largura / (GLfloat) height, 1.0f, 20.0f); senão glOrtho (-1, 1, -1, 1, -10, 10); glMatrixMode (GL_MODELVIEW); ancho = largura; alto = altura; } 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 ((Hip> = 0) && (Hip = 0,07) && (Hip = 0,14) && (Hip = 0,21) && (Hip = 0,28) && (Hip = 0,35) && (Hip = 0,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, para "Hello Text" 0; s <3; s ++) {glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24, buffer [s]);} glTranslatef (mty, -mtx, mtz); glRotatef (mx, 1.0f, 0.0f, 0.0f); glRotatef (meu, 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"); glutBitmap_ROM24 '); * / / * 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; } void init () {glClearColor (0, 0, 0, 0); glEnable (GL_DEPTH_TEST); ancho = 500; alto = 500; } void leer () {ifstream myfile ("A: / Respaldo set 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; linha [0] = 48; linha [1] = 48; linha [2] = 48; linha [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 ++; }} meuarquivo.close (); } else cout <1780) NP = 1700; cout <void idle () {display (); } teclado vazio (tecla sem sinal, int x, int y) {switch (tecla) {case 'p': case 'P': hazPerspectiva = 1; remodelar (ancho, alto); pausa; caso 'o': caso 'O': hazPerspectiva = 0; remodelar (ancho, alto); pausa; caso 27: // escape exit (0); pausa; }} void raton (int botão, int estado, int x, int y) {/ * GLUT_LEFT_BUTTON 0 GLUT_MIDDLE_BUTTON 1 GLUT_RIGHT_BUTTON 2 GLUT_DOWN 0 GLUT_UP 1 * / Boton = botão; Pulbut = estado; // mx = y; exibição(); } void ratmov (int x, int y) {if ((Botão == 0) & (Pulbut == 0)) {mx = y; meu = x; } if ((Botão == 2) & (Pulbut == 0)) {mtx = (y / 200) -1; mty = (x / 200) -1; } if ((Botão == 1) & (Pulbut == 0)) {mtz = - (y / 40) -5; } exibição(); } int main (int argc, char ** argv) {/ * glutAddMenuEntry () glutAddSubMenu () glutAttachMenu () glutCreateMenu () glutSetMenu () glutStrokeCharacter () glutStrokeLength () * / / * glReadPixels de leitura de um bloco de pixels () buffer de quadro glGetPixelMapfv () retorna o mapa de pixel especificado glGetPixelMapuiv () retorna o mapa de pixel especificado glGetPointerv () Retorna o endereço do ponteiro especificado. * / Init (); olhar malicioso (); glutInit (& argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition (50, 50); glutInitWindowSize (ancho, alto); glutCreateWindow ("Cubo 1"); iniciar(); glutDisplayFunc (display); glutReshapeFunc (remodelar); glutIdleFunc (idle); glutMouseFunc (raton); glutMotionFunc (ratmov); glutKeyboardFunc (teclado); glutMainLoop (); return 0; }
Etapa 5:
por enquanto, tenho que parar! … Mas no próximo capítulo prometo que irei implementá-lo no meu raspberry pi 3 ou no meu jetson nanoboard, já montado em alguma aeronave de controle remoto, ou em algum robô aranha para escanear o interior de cavernas
Recomendado:
Dicas de mapeamento: 3 etapas
Dicas de mapeamento: qualquer que seja a sua atividade, seja caminhar, caminhar, andar de bicicleta ou até mesmo dirigir, você pode registrar as rotas que faz. Depois, você pode compartilhar essas rotas com amigos e familiares. Além disso, você pode usar a rota gravada para adicionar locais a quaisquer fotos que você possa h
Mapeamento do controlador de jogo para PC (Linux e Windows): 5 etapas
Mapeamento do controlador de jogos para PC (Linux e Windows): se você está começando no campo de jogos em um computador pessoal, pode ser necessário seguir algumas etapas para chegar lá. Hoje, vou mostrar a vocês como usar um controlador de jogo USB até mesmo com os jogos mais antigos para PC, gratuitamente. A técnica
O Mappifier - Sistema de Mapeamento + Notificação: 9 etapas
O Mappifier - Sistema de Mapeamento + Notificação: Dirigir à noite é muito divertido. Mas muitas vezes acaba sendo um pesadelo, na forma de animais atravessando a estrada (especialmente aqueles gatos e cachorros vadios, que esperam você passar perto deles para que eles possam atravessar !!). Então pensei em fazer
Luz de pista do Raspberry PI de alerta precoce usando dados de mapeamento de vôo: 14 etapas (com imagens)
Luz de pista do Raspberry PI de alerta antecipado usando dados de mapeamento de vôo: Esta lâmpada surgiu por vários motivos, pois estou sempre interessado nos aviões que voam lá em cima e, durante o verão, nos finais de semana, muitas vezes há alguns muito emocionantes voando por aí. Embora você só tenda a ouvi-los enquanto passam
Como fazer o mapeamento de projeção com a tampa do Pi: 9 etapas (com imagens)
Como fazer o mapeamento de projeção com o Pi Cap: Nós nos inspiramos em seus projetos e criamos um tutorial de mapeamento de projeção usando o Pi Cap. Se você deseja que seu projeto funcione sem fio em WiFi, este é o tutorial para você. Usamos MadMapper como um software de mapeamento de projeção