Sisukord:

Põhiline 3D -skanner digitaalseks 3D -kaardistamiseks: 5 sammu
Põhiline 3D -skanner digitaalseks 3D -kaardistamiseks: 5 sammu

Video: Põhiline 3D -skanner digitaalseks 3D -kaardistamiseks: 5 sammu

Video: Põhiline 3D -skanner digitaalseks 3D -kaardistamiseks: 5 sammu
Video: 40 полезных автотоваров с Aliexpress, которые упростят жизнь любому автовладельцу #5 2024, September
Anonim
Põhiline 3D -skanner digitaalseks 3D -kaardistamiseks
Põhiline 3D -skanner digitaalseks 3D -kaardistamiseks

Selles projektis kirjeldan ja selgitan 3D-skaneerimise ja rekonstrueerimise põhialuseid, mida rakendatakse peamiselt väikeste pooltasapinnaliste objektide skaneerimisel ja mille toimimist saab laiendada skaneerimis- ja rekonstrueerimissüsteemidele, mida saab kaugjuhtimispuldile paigaldada. 3D mudel. kohtadest, kuhu neid paigaldav lennuk lendab

Lõplik mõte on hankida 3D -skannimine mõnest kohast või piirkonnast, kas selle välisest või sisemusest, et kasutada seda digitaalse kaardina (nagu Prometeuse filmis)

Samm 1:

Pilt
Pilt

idee on paigaldada kogu 3D skaneerimissüsteem kaugjuhtimisega tasapinnale, et digitaliseerida mis tahes piirkonna virtuaalne kaart, mille kohal see 3D-s lendab, kuid selle jaoks alustasime laser-kolmnurga toimimise algusest skaneerimine või 3D rekonstrueerimine laserkolmnurga abil koosneb põhimõtteliselt laserkiire läbimisest läbi prisma, mis tekitab laserriba, et saada terve laserriba, mis projitseeritakse skaneeritavale objektile, ja kui see laserprojektsioon on pinna pind Skaneerimiskohast tuleb pilt jäädvustada teatud tüüpi kaameraga ja eelistatavalt teades nurka, mis moodustub kiirgava laserriba projektsiooninurga suhtes, kuna kõik need pildid jäädvustavad projitseeritud laserribasid. Objekti pinnal töödeldakse neid eeltöödel, et eraldada skannitava objekti mõõtmed, ja lihtsalt skaneeritakse riba haaval objekti kohal, et saada selle pinna profiil selle objekti põiksegmendis, ja seejärel jäädvustada objekti järgmise ristlõike projitseeritud riba, et kõik projitseeritud triibud kokku liita Enne obto kõiki ristlõikeid saame selle pinna kolmemõõtmelise skaneeringu

2. samm:

Pilt
Pilt

Kuna oleme oma eesmärgi kindlaks määranud, on järgmine samm teada, et õhkutõusmiseks peavad jalad kõigepealt kindlalt maapinnale jääma, nii et alustasime kohapeal lineaarse 3D -skanneri eksperimentaalse prototüübiga, et kinnitada põhitõdede õige toimimine. 3D -skannimine ja nagu ülaltoodud pildil näha, kasutasin arvutit, OpenCV -d, OpenGL -i glutti, veebikaamerat, laserit, laserfarmi generaatorit (antud juhul läbi pöördpeegli) elektroonilist lineaarset nihutussüsteemi (valmistatud rööpaga) ja süsteem, mis on välja võetud vanast printerist) alusest, kuhu asetan skannitavad objektid, puidu ja plastiliini ning nagu fotol näha, arvutisse: mul õnnestus OpenGL-ist Glutiga genereerida ja kuvada kolm- mõõtmetega mudel, mis on reprodutseeritud skaneeritud reaalse objekti (antud juhul mänguämbliku) põhjal

seega on enam kui ilmne, et tööpõhimõte on funktsionaalne ning et koos vastavate kohanduste ja kohandustega lendavale süsteemile on see võimeline skaneerima ja reprodutseerima 3D -kaarti selle piirkonna kohta, milles see lendab.

Kuid see süsteem on mõeldud ainult 3D -kaartide saamiseks nende kohtade välispinnast, millest see üle lendab ???…

3. samm:

Pilt
Pilt

koobaste ja kanalite sisemuse kaardistamine (täpselt nagu Prometeuse filmis) See 3D-skaneerimissüsteem on ette nähtud ka suurte ja õõnsate objektide, näiteks koobaste, hoonete, tunnelite jms sisemuse kolmemõõtmeliste mudelite rekonstrueerimiseks. täpselt sama, mis juba kirjeldatud ja mis koosneb põhimõtteliselt järgmisest:

  1. jäädvustage foto igast laserriba projektsioonist skannitavale pinnale
  2. filtreerige ja eemaldage pildilt värv
  3. binaarige värv dünaamilise pildilävega
  4. rakendage servaandurit, et ära tunda iga laserprojektsiooni ristlõike jäädvustatud profiil
  5. ja kasutades segmenteerimist, valige skaneeritava ja virtuaalsel 3D -kaardil rekonstrueeritava objekti ristlõike 3D -kujutise jaoks sobiv piir.
  6. siis korratakse neid samme lihtsalt iga foto puhul, mis on tehtud alammeetodil laserribade abil, mida iga alajaotis pidevalt projitseerib.
  7. kiht -kihilt ristlõigete esitus lisatakse järjest, kuni saadakse punktpilv, mis on moodustatud paljudest kaardistatava objekti ristlõigete kujutistest

4. samm:

Pilt
Pilt

Seejärel läbin pindmiste laserribade projektsioonide pilditöötlusprogrammid. ja nende keerukate põikisuunaliste esituste virtuaalse 3D rekonstrueerimise kohta väljatöötatud kolmemõõtmelises kaardimudelis:

pildi töötlemine:

n

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

char f = 0; char nimi = {"0.jpg"}; int n = 0, s, x, y; CvScalar sp; FILE *NuPu;

tühine Writepoints () {char bufferx [33], buffery [33]; itoa (x, puhverx, 10); itoa (y, puhver, 10); fprintf (NuPu, bufferx); fprintf (NuPu, "\ t"); fprintf (NuPu, puhver); 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; nimi [0] = f; cout <

IplImage* img0 = cvLoadImage ("00.jpg", 0); kui (f == '0') {jaoks (y = 1; yheight-2; y ++) {for (x = 1; xwidth-2; x ++) {sp = cvGet2D (img0, y, x); kui (sp.val [0]> 50) {Writepoints (); n ++;}}}} else {jaoks (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, puhver, 10); fprintf (NuPu, "Fin:"); fprintf (NuPu, puhver); fprintf (NuPu, "\ n"); fclose (NuPu);

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

3D rekonstrueerimine:

#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) kasutades nimeruumi std; int s, Boton = 1, Pulbut = 1; ujuk mx = 0, minu = 0, mtx = 0, mty = 0, mtz = -5,0; const int Avance = 1; stringirida, Aux; char Märk = 'H'; FILE *NuPu; int NP, h, w; ujuk G = 0, n = 0, cx [5000], cy [5000], x, y, ax, ay, az; int font = (int) GLUT_BITMAP_8_BY_13; staatiline sümbol [100]; söe puhver [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 laius, int kõrgus) {glViewport (0, 0, laius, kõrgus); glMatrixMode (GL_PROJECTION); glLoadIdentity (); kui (hazPerspectiva) gluPerspective (23,0f, (GLfloat) laius/(GLfloat) kõrgus, 1,0f, 20,0f); muidu glOrtho (-1, 1, -1, 1, -10, 10); glMatrixMode (GL_MODELVIEW); ancho = laius; alto = kõrgus; } tühine Kolorear (int K) {float Hip; x = (cx [s] -320)/480; y = (cy [s] -240)/640; Puusa = sqrt (pow (x, 2)+pow (y, 2)); kui ((Hip> = 0) && (Hip =.07) && (Hip =.14) && (Hip =.21) && (Hip =.28) && (Hip =.35) && (Hip =.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); (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); jaoks (c = string; *c! = '\ 0'; c ++) {glutBitmapCharacter (font, *c);}} tühi kuva () {// mx = 468; itoa (mx, puhver, 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_;; s <3; s ++) {glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24, puhver [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, "Tere tekst"); glutBitmapCharacter (GLU_BIM_IMIT,);* / /*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; } tühine init () {glClearColor (0, 0, 0, 0); glEnable (GL_DEPTH_TEST); ankur = 500; alto = 500; } void leer () {ifstream myfile ("A:/Respaldo sept 2016/D/Respaldos/Respaldo compu CICATA abril 2015/usb1/rekostruccion 3D et Spetsiaalne CICATA/Tarkvara/Reconstruccion 3D/R3d_0 / bin/Debug/NuPu.txt"); kui (myfile.is_open ()) {s = 0; while (getline (minufail, rida)) {if ((rida [0]! = 'N') && (rida [0]! = 'F')) {Aux = rida; rida [0] = 48; rida [1] = 48; rida [2] = 48; rida [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 () {kuva (); } tühi klaviatuur (allkirjastamata char -klahv, int x, int y) {lüliti (võti) {case 'p': case 'P': hazPerspectiva = 1; ümber kujundama (ancho, alto); murda; juhtum 'o': juhtum 'O': hazPerspectiva = 0; ümber kujundama (ancho, alto); murda; juhtum 27: // põgeneda väljapääsu (0); murda; }} void raton (int nupp, int olek, int x, int y) { / * GLUT_LEFT_BUTTON 0 GLUT_MIDDLE_BUTTON 1 GLUT_RIGHT_BUTTON 2 GLUT_DOWN 0 GLUT_UP 1 * / Boton = nupp; Pulbut = olek; // mx = y; kuva (); } tühine ratmov (int x, int y) {if ((Boton == 0) & (Pulbut == 0)) {mx = y; minu = x; } kui ((Boton == 2) & (Pulbut == 0)) {mtx = (y/200) -1; mty = (x/200) -1; } kui ((Boton == 1) & (Pulbut == 0)) {mtz =-(y/40) -5; } kuva (); } int main (int argc, char ** argv) { /*glutAddMenuEntry () glutAddSubMenu () glutAttachMenu () glutCreateMenu () glutSetMenu () glutStrokeCharacter () glutStrokeLength ()* / /*gl Pikslite lugemine frame buffer glGetPixelMapfv () tagastab määratud pikslikaardi glGetPixelMapuiv () tagastab määratud pikslikaardi glGetPointerv () Annab vastuseks määratud osuti aadressi.*/ Init (); leer (); glutInit (& argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition (50, 50); glutInitWindowSize (ancho, alt); glutCreateWindow ("Cubo 1"); selles(); glutDisplayFunc (ekraan); glutReshapeFunc (ümberkujundamine); glutIdleFunc (jõude); glutMouseFunc (raton); glutMotionFunc (ratmov); glutKeyboardFunc (klaviatuur); glutMainLoop (); tagasitulek 0; }

5. samm:

Pilt
Pilt

hetkeks pean lõpetama! … Kuid järgmises peatükis luban teile, et rakendan selle oma vaarika pi 3 või oma jetsoni nanoplaadile, mis on juba paigaldatud mõnele kaugjuhtimisega lennukile, või mõnele ämblikrobotile, et skaneerida koobaste sisemust

Soovitan: