Բովանդակություն:

Թվային 3D քարտեզագրման հիմնական 3D սկաներ ՝ 5 քայլ
Թվային 3D քարտեզագրման հիմնական 3D սկաներ ՝ 5 քայլ

Video: Թվային 3D քարտեզագրման հիմնական 3D սկաներ ՝ 5 քայլ

Video: Թվային 3D քարտեզագրման հիմնական 3D սկաներ ՝ 5 քայլ
Video: ԳՈՒՆԱՅԻՆ ԹԵՍՏ, ՈՐԸ ԿԱՍԻ ՔՈ ՀՈԳԵՎՈՐ ՏԱՐԻՔԸ 2024, Սեպտեմբեր
Anonim
Թվային 3D քարտեզագրման հիմնական 3D սկաներ
Թվային 3D քարտեզագրման հիմնական 3D սկաներ

Այս նախագծում ես կբնութագրեմ և կբացատրեմ եռաչափ սկանավորման և վերակառուցման հիմնական հիմքերը, որոնք հիմնականում կիրառվում են փոքր կիսաերածո օբյեկտների սկանավորման համար, և որոնց գործողությունը կարող է տարածվել սկանավորման և վերակառուցման համակարգերի վրա, որոնք կարող են տեղադրվել հեռակառավարման օդանավերի վրա: 3D մոդել: այն վայրերից, որտեղ թռչում է ինքնաթիռը, որը նրանց տեղափոխել է

Վերջնական գաղափարն այն է, որ ստանաք ինչ -որ վայրի կամ տարածքի եռաչափ սկանավորում ՝ արտաքին կամ ներքին, այն որպես թվային քարտեզ օգտագործելու համար (ինչպես Պրոմեթևսի ֆիլմում)

Քայլ 1:

Պատկեր
Պատկեր

գաղափարը կայանում է նրանում, որ 3D- ի սկանավորման ամբողջ համակարգը տեղադրվի հեռակառավարվող հարթության վրա, որպեսզի թվայնացվի ցանկացած տարածքի վիրտուալ քարտեզը, որի վրայով այն թռչում է 3D- ով, բայց դրա համար մենք սկսեցինք լազերային եռանկյունաձևման սկզբից լազերային եռանկյունացման միջոցով սկանավորման կամ եռաչափ վերակառուցման հիմքում ընկած է լազերային ճառագայթը պրիզմայով անցնելը, որը առաջացնում է լազերային շերտ `ձեռք բերելով մի ամբողջ լազերային շերտ, որը կցուցադրվի սկանավորման ենթակա օբյեկտի վրա, և երբ այդ լազերային պրոյեկցիան ստացվի մակերեսային սկան ՝ սկանավորման վայրից, պատկերը պետք է նկարահանվի տեսախցիկի միջոցով և ցանկալի է իմանալ այն անկյունը, որը ձևավորվում է արտանետվող լազերային շերտի նախագծման անկյունի նկատմամբ, քանի որ այս պատկերներից յուրաքանչյուրը գրավում է լազերային նախագծված շերտերը: Օբյեկտի մակերևույթի վրա դրանք կվերամշակվեն `սկանավորվող օբյեկտի ծավալային բնութագրերը հանելու համար, և ուղղակի սկանավորելով շերտը առարկայից վերև` օբյեկտի այդ լայնակի հատվածում նրա մակերեսի պրոֆիլը ստանալու և հետագայում գրավելու համար օբյեկտի հետևյալ խաչմերուկի նախագծված ժապավենը `բոլոր նախագծված շերտերն իրար միացնելու համար Նախքան ստերիլի բոլոր խաչմերուկները մենք ստանում ենք դրա մակերեսի եռաչափ սկանավորում

Քայլ 2:

Պատկեր
Պատկեր

Քանի որ մենք բացահայտել ենք մեր նպատակը, հաջորդ քայլը ՝ իմանալով, որ թռիչքի համար նախ պետք է ոտքերը ամուր կանգնած լինել գետնին, ուստի մենք գետնին սկսեցինք գծային 3d սկաների փորձնական նախատիպով ՝ հիմնականի ճիշտ աշխատանքը վավերացնելու համար: 3D սկան և ինչպես տեսնում եք վերևի նկարում, ես օգտագործել եմ համակարգիչ, OpenCV, OpenGL Glut, վեբ -տեսախցիկ, լազերային, լազերային ֆերմայի գեներատոր (այս դեպքում պտտվող հայելու միջոցով) էլեկտրոնային գծային տեղաշարժման համակարգ (պատրաստված երկաթուղով և համակարգ ՝ հանված հին տպիչից) այն հիմքից, որի վրա տեղադրում եմ սկանավորման ենթակա առարկաները ՝ փայտ և պլաստիլին, և ինչպես տեսնում եք լուսանկարում ՝ համակարգչում. ինձ հաջողվեց Glut- ով OpenGL- ից երեք արտադրել ծավալային մոդել, որը վերարտադրվում է սկանավորված իրական օբյեկտի հիման վրա (այս դեպքում ՝ խաղալիք սարդ)

ուստի ավելի քան ակնհայտ է, որ շահագործման սկզբունքը ֆունկցիոնալ է, և որ թռիչքային համակարգին համապատասխան հարմարեցումներով և հարմարեցումներով նա կկարողանա սկանավորել և վերարտադրել տարածքի եռաչափ քարտեզը, որտեղ նա թռչում է:

Բայց այս համակարգը կծառայի միայն այն վայրերի արտաքին մակերևույթի 3D քարտեզների ձեռքբերմանը, որտեղով նա թռչում է……

Քայլ 3:

Պատկեր
Պատկեր

Քարանձավների և ծորանների ինտերիերի քարտեզագրում (ինչպես Պրոմեթևսի ֆիլմում) Այս 3D սկանավորման համակարգը նաև ծառայում է մեծ և խոռոչ օբյեկտների ինտերիերի եռաչափ մոդելների վերակառուցմանը, ինչպիսիք են քարանձավները, շենքերը, թունելները և այլն: Դրա գործունեության սկզբունքն է. ճիշտ նույնը, ինչ արդեն նկարագրված է և որը հիմնականում բաղկացած է հետևյալից.

  1. նկարել սկանավորման մակերեսին լազերային շերտի յուրաքանչյուր պրոյեկցիայի լուսանկարը
  2. զտել և հեռացնել գույնը պատկերից
  3. գույնը դինամիկացնել դինամիկ պատկերի շեմով
  4. կիրառել եզրային դետեկտոր `յուրաքանչյուր լազերային պրոյեկցիայի խաչմերուկի գրավված պրոֆիլը ճանաչելու համար
  5. և օգտագործելով հատվածավորում ընտրեք համապատասխան եզրագիծը օբյեկտի այդ խաչմերուկի 3D պատկերման համար, որը սկանավորվելու և վերակառուցվելու է վիրտուալ 3D քարտեզի վրա
  6. ապա այս քայլերը պարզապես կրկնվում են յուրաքանչյուր լուսանկարի համար, որն արվում է լազերային շերտերի ենթաօրենսդրական եղանակով ՝ շարունակաբար նախագծված յուրաքանչյուր ենթաբաժնի ենթաբաժնում:
  7. խաչմերուկների ներկայացումը շերտ առ շերտ ավելացվում է հաջորդաբար, մինչև ստացվի կետային ամպ, որը ձևավորվում է քարտեզագրվող օբյեկտի լայնակի հատվածների բազմաթիվ ներկայացումներից

Քայլ 4:

Պատկեր
Պատկեր

Հետո անցնում եմ մակերեսային լազերային ժապավենների պրոեկցիաների պատկերի մշակման ծրագրերը: և այս խճճված լայնակի պատկերների վիրտուալ 3-րդ վերակառուցումը `մշակված եռաչափ քարտեզի մոդելում.

պատկերի մշակում

n

#ներառել #ներառել "cv.h" #include "highgui.h" #include // #include #include #include #include

char f = 0; char անունը = {"0.jpg"}; int n = 0, s, x, y; CvScalar sp; ՖԱՅԼ *NuPu;

void Writepoints () {char bufferx [33], buffery [33]; itoa (x, bufferx, 10); itoa (y, բուֆեր, 10); fprintf (NuPu, bufferx); fprintf (NuPu, "\ t"); fprintf (NuPu, բուֆեր); fprintf (NuPu, "\ n"); }

անվավեր 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; անուն [0] = f; cout <

IplImage* img0 = cvLoadImage ("00.jpg", 0); եթե (f == '0') {համար (y = 1; yheight-2; y ++) {համար (x = 1; xwidth-2; x ++) {sp = cvGet2D (img0, y, x); if (sp.val [0]> 50) {Գրելու կետեր (); n ++;}}}} այլ {for (y = 1; yheight-2; y ++) {for (x = 1; xwidth-2; x ++) { sp = cvGet2D (img1, y, x); if (sp.val [0]> 50) {Գրելու կետեր (); n ++;}}}} char buffer [33]; itoa (n, բուֆեր, 10); fprintf (NuPu, "Fin:"); fprintf (NuPu, բուֆեր); fprintf (NuPu, "\ n"); fclose (NuPu);

cvWaitKey (0); //_execlp("calc.exe "," calc.exe ", argstr, NULL); cvDestroyAllWindows (); cvReleaseImage (& պատկեր); cvReleaseImage (& img); cvReleaseImage (& img0); cvReleaseImage (& img1); cvReleaseImage (& img2); վերադարձ 0; }

3D վերակառուցում.

#ներառել //////////////////iifdef _APPLE_ #include #else #include #include #endif #include #include #include #include #include #include

#սահմանել մանուշակը glColor3f (1, 0, 1) #սահմանել azul glColor3f (0, 0, 1) #սահմանել turkeza glColor3f (0, 1, 1) #սահմանել verde glColor3f (0, 1, 0) #սահմանել amarillo glColor3f (1, 1, 0) #սահմանել naranja glColor3f (1,.3, 0) #սահմանել rojo glColor3f (1, 0, 0) անունների տարածքի միջոցով std; int s, Boton = 1, Pulbut = 1; բոց mx = 0, my = 0, mtx = 0, mty = 0, mtz = -5.0; const int Ավանս = 1; լարային տող, Aux; char Caracter = 'H'; ՖԱՅԼ *NuPu; int NP, h, w; բոց G = 0, n = 0, cx [5000], cy [5000], x, y, ax, ay, az; int տառատեսակ = (int) GLUT_BITMAP_8_BY_13; ստատիկ նշանի պիտակ [100]; char buffer [3]; GLfloat anguloCuboX = 0.0f; GLfloat anguloCuboY = 0.0f; GLfloat anguloEsfera = 0.0f; GLint անչո = 500; GLint alto = 500; int hazPerspectiva = 0; դատարկ վերափոխում (int լայնություն, int բարձրություն) {glViewport (0, 0, լայնություն, բարձրություն); glMatrixMode (GL_PROJECTION); glLoadIdentity (); եթե (hazPerspectiva) gluPerspective (23.0f, (GLfloat) լայնություն/(GLfloat) բարձրություն, 1.0f, 20.0f); այլապես glOrtho (-1, 1, -1, 1, -10, 10); glMatrixMode (GL_MODELVIEW); անչո = լայնություն; ալտ = բարձրություն; } դատարկ Kolorear (int K) {float Hip; x = (cx [s] -320)/480; y = (cy [s] -240)/640; Hip = sqrt (pow (x, 2)+pow (y, 2)); եթե ((Hip> = 0) && (Hip =.07) && (Hip =.14) && (Hip =.21) && (Hip =.28) && (Hip =.35) && (Hip =.42) && (Հիպ <=. 49)) {մանուշակ;}} անվավեր drawNuPu (անվավեր) {glColor3f (1, 1, 1); glBegin (GL_LINES); glVertex3f (.2, 0, 0); glVertex3f (-. 2, 0, 0); glVertex3f (0,.2, 0); glVertex3f (0, -.2, 0); glEnd (); ռոջո; 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_ES, BINMAP_T = 0,; s <3; s ++) {glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24, բուֆեր [ներ]);} 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, «Ողջույն տեքստ»); glutBitmAPCharacter (GLUT_AP_Mract_GROT, GLUT '' GROT, GLUT_ROM ');* / /*glColor3f (1. 0f, 1.0f, 1.0f); setOrthographicProjection (); glPushMatrix (); glLoadIdentity (); renderBitmapString (30, 15, (անվավեր *) տառատեսակ, "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); անչո = 500; ալտո = 500; } void leer () {ifstream myfile ("A:/Respaldo sept 2016/D/Respaldos/Respaldo compu CICATA abril 2015/usb1/rekostruccion 3D en Specialized CICATA/Software/Reconstruccion 3D/R3d_0 / bin/Debug/NuPu.t"); if (myfile.is_open ()) {s = 0; while (getline (myfile, line)) {if ((line [0]! = 'N') && (line [0]! = 'F')) {Aux = line; տող [0] = 48; տող [1] = 48; տող [2] = 48; տող [3] = 48; cy [s] = atoi (line.c_str ()); Օքս [4] = 48; Օքս [5] = 48; Օքս [6] = 48; // Aux [7] = 48; cx [s] = atoi (Aux.c_str ()); s ++; }} myfile.close (); } else cout <1780) NP = 1700; cout <դատարկություն պարապ () {ցուցադրում (); } դատարկ ստեղնաշար (անստորագիր char key, int x, int y) {switch (key) {case 'p': case 'P': hazPerspectiva = 1; վերափոխում (անչո, ալտո); ընդմիջում; գործ 'o'. դեպք 'O': hazPerspectiva = 0; վերափոխում (անչո, ալտո); ընդմիջում; գործ 27: // փախուստի ելք (0); ընդմիջում; }} void raton (int կոճակ, int վիճակ, int x, int y) { / * GLUT_LEFT_BUTTON 0 GLUT_MIDDLE_BUTTON 1 GLUT_RIGHT_BUTTON 2 GLUT_DOWN 0 GLUT_UP 1 * / Boton = կոճակ; Պուլբուտ = վիճակ; // mx = y; ցուցադրում (); } void ratmov (int x, int y) {if ((Boton == 0) & (Pulbut == 0)) {mx = y; իմ = x; } if ((Boton == 2) & (Pulbut == 0)) {mtx = (y/200) -1; mty = (x/200) -1; } if ((Boton == 1) & (Pulbut == 0)) {mtz =-(y/40) -5; } ցուցադրում (); } int main (int argc, char ** argv) { /*glutAddMenuEntry () glutAddSubMenu () glutAttachMenu () glutCreateMenu () glutSetMenu () glutStrokeCharacter () glutStrokeLelsth ()*արգելափակումից ()* / /**() շրջանակի բուֆեր glGetPixelMapfv () վերադարձնել նշված պիքսելային քարտեզը glGetPixelMapuiv () վերադարձնել նշված պիքսելային քարտեզը glGetPointerv () Վերադարձնում է նշված ցուցիչի հասցեն:*/ Init (); leer (); glutInit (& argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition (50, 50); glutInitWindowSize (անչո, ալտո); glutCreateWindow («Կուբո 1»); init (); glutDisplayFunc (ցուցադրում); glutReshapeFunc (վերափոխել); glutIdleFunc (անգործուն); glutMouseFunc (ռատոն); glutMotionFunc (ratmov); glutKeyboardFunc (ստեղնաշար); glutMainLoop (); վերադարձ 0; }

Քայլ 5:

Պատկեր
Պատկեր

այս պահին ես պետք է դադարեմ! … Բայց հաջորդ գլխում ես ձեզ խոստանում եմ, որ այն կիրականացնեմ իմ ազնվամորի pi 3-ի կամ իմ jetson nanoboard- ի վրա, որն արդեն տեղադրված է ինչ-որ հեռակառավարվող ինքնաթիռի վրա, կամ ինչ-որ սարդ ռոբոտի վրա `քարանձավների ներքին հատվածը սկանավորելու համար:

Խորհուրդ ենք տալիս: