สารบัญ:
วีดีโอ: สแกนเนอร์ 3 มิติขั้นพื้นฐานสำหรับการทำแผนที่ 3 มิติแบบดิจิทัล: 5 ขั้นตอน
2024 ผู้เขียน: John Day | [email protected]. แก้ไขล่าสุด: 2024-01-30 13:03
ในโครงการนี้ ฉันจะอธิบายและอธิบายพื้นฐานพื้นฐานของการสแกน 3 มิติและการสร้างใหม่ที่ใช้เป็นหลักในการสแกนวัตถุกึ่งระนาบขนาดเล็ก และการดำเนินการดังกล่าวสามารถขยายไปถึงระบบการสแกนและการสร้างใหม่ที่สามารถติดตั้งบนเครื่องบินควบคุมระยะไกลได้ โมเดล 3 มิติ ของสถานที่ซึ่งเครื่องบินที่รับพวกเขาติดตั้งบิน
แนวคิดสุดท้ายคือการได้รับการสแกน 3 มิติของสถานที่หรือพื้นที่บางแห่ง ไม่ว่าจะเป็นภายนอกหรือภายใน เพื่อใช้เป็นแผนที่ดิจิทัล (เช่นเดียวกับในภาพยนตร์เรื่อง Prometeus)
ขั้นตอนที่ 1:
แนวคิดคือการติดตั้งระบบสแกน 3 มิติทั้งหมดบนระนาบที่ควบคุมจากระยะไกล เพื่อทำแผนที่เสมือนของพื้นที่ใดๆ ที่มันบินเป็น 3 มิติในรูปแบบดิจิทัล แต่สำหรับสิ่งนี้ เราเริ่มต้นจากจุดเริ่มต้นของการทำงานของสามเหลี่ยมเลเซอร์วิธีการ ของการสแกนหรือการสร้างใหม่ 3 มิติโดยเลเซอร์สามเหลี่ยม โดยพื้นฐานแล้วประกอบด้วยการส่งลำแสงเลเซอร์ผ่านปริซึมที่สร้างแถบเลเซอร์เพื่อให้ได้แถบเลเซอร์ทั้งหมดที่จะฉายลงบนวัตถุที่จะสแกน และเมื่อได้การฉายเลเซอร์นี้บน พื้นผิวพื้นผิว จากตำแหน่งที่จะสแกน รูปภาพจะต้องถูกจับภาพด้วยกล้องบางประเภทและควรทราบมุมที่เกิดขึ้นตามมุมการฉายของแถบเลเซอร์ที่ปล่อยออกมา เนื่องจากแต่ละภาพเหล่านี้จะจับแถบเลเซอร์ที่ฉาย บนพื้นผิวของวัตถุ พวกมันจะถูกประมวลผลล่วงหน้าเพื่อแยกลักษณะเชิงมิติของวัตถุที่จะสแกน และเพียงแค่สแกนแถบโดยแถบเหนือวัตถุเพื่อให้ได้โปรไฟล์ของพื้นผิวในส่วนตามขวางของวัตถุนั้น จากนั้นจึงจับภาพ แถบที่ฉายของส่วนตัดขวางต่อไปนี้ของวัตถุ เพื่อเพิ่มแถบที่ฉายทั้งหมดเข้าด้วยกัน ก่อนส่วนตัดขวางทั้งหมดของ obto เราจะได้การสแกนพื้นผิวสามมิติ
ขั้นตอนที่ 2:
เนื่องจากเราได้ระบุวัตถุประสงค์ของเราแล้ว ขั้นต่อไปโดยรู้ว่าในการออกตัวคุณต้องวางเท้าของคุณให้มั่นคงบนพื้น ดังนั้นเราจึงเริ่มต้นบนพื้นดินด้วยต้นแบบทดลองของเครื่องสแกน 3 มิติเชิงเส้น เพื่อตรวจสอบการทำงานที่ถูกต้องของพื้นฐาน สแกนเนอร์ 3 มิติและอย่างที่คุณเห็นในภาพด้านบน ฉันใช้ PC, OpenCV, Glut ของ OpenGL, เว็บแคม, เลเซอร์, เครื่องกำเนิดเลเซอร์ฟาร์ม (ในกรณีนี้ผ่านกระจกหมุน) ระบบรางไฟฟ้าแบบเชิงเส้น (ทำด้วยราง) และระบบที่แยกจากเครื่องพิมพ์เก่า) จากฐานที่ฉันวางวัตถุที่จะสแกน ไม้และดินน้ำมัน และอย่างที่คุณเห็นในภาพถ่าย บนคอมพิวเตอร์: ฉันจัดการเพื่อสร้างและแสดงด้วย Glut จาก OpenGL สาม- แบบจำลองมิติที่ทำซ้ำตามวัตถุจริงที่สแกน (ในกรณีนี้คือแมงมุมของเล่น)
ดังนั้นจึงเป็นที่แน่ชัดมากกว่าว่าหลักการทำงานนั้นใช้งานได้ และด้วยการปรับแต่งและดัดแปลงให้เข้ากับระบบการบิน จะสามารถสแกนและสร้างแผนที่ 3 มิติของพื้นที่ที่มันบินได้
แต่ระบบนี้จะให้บริการเพื่อรับแผนที่ 3 มิติของพื้นผิวภายนอกของสถานที่ที่มันบินเท่านั้น???…
ขั้นตอนที่ 3:
การทำแผนที่ภายในถ้ำและท่อต่างๆ (เช่นเดียวกับในภาพยนตร์ Prometeus) ระบบสแกน 3 มิตินี้ยังทำหน้าที่ในการสร้างแบบจำลองสามมิติของการตกแต่งภายในของวัตถุขนาดใหญ่และกลวง เช่น ถ้ำ อาคาร อุโมงค์ เป็นต้น โดยมีหลักการทำงานคือ ตรงตามที่อธิบายไว้แล้วและโดยพื้นฐานแล้วประกอบด้วยสิ่งต่อไปนี้:
- จับภาพของการฉายแต่ละแถบเลเซอร์บนพื้นผิวที่จะสแกน
- กรองและลบสีออกจากภาพ
- ทำให้สีเป็นสองเท่าด้วยเกณฑ์ภาพไดนามิก
- ใช้เครื่องตรวจจับขอบเพื่อรับรู้โปรไฟล์ที่จับได้ของส่วนตัดขวางของเลเซอร์แต่ละส่วน
- และการใช้การแบ่งส่วน เลือกเส้นขอบที่เหมาะสมสำหรับการแสดงภาพ 3 มิติของส่วนตัดขวางของวัตถุที่จะสแกนและสร้างใหม่บนแผนที่ 3 มิติเสมือนจริง
- จากนั้นขั้นตอนเหล่านี้จะถูกทำซ้ำสำหรับภาพถ่ายแต่ละภาพที่ถ่ายในลักษณะย่อยของแถบเลเซอร์ที่ฉายอย่างต่อเนื่องโดยแต่ละส่วนย่อยในส่วนย่อย
ทีละชั้นของการแสดงภาพตัดขวางทีละชั้น จนกระทั่งได้จุดเมฆที่เกิดขึ้นจากการแทนส่วนต่างๆ ของวัตถุที่จะทำการแมป
ขั้นตอนที่ 4:
จากนั้นฉันก็ผ่านโปรแกรมสำหรับการประมวลผลภาพของแถบเลเซอร์ผิวเผิน และการสร้างภาพสามมิติเสมือนขึ้นมาใหม่ของการแทนแนวขวางที่น่าสงสัยเหล่านี้ในแบบจำลองแผนที่สามมิติอย่างละเอียดถี่ถ้วน:
การประมวลผลภาพ:
NS
#รวม #รวม "cv.h" #รวม "highgui.h" #รวม //#รวม #รวม #รวม #รวม
ถ่าน f=0; ชื่อถ่าน={"0.jpg"}; int n=0, s, x, y; CvScalar sp; ไฟล์ *NuPu;
เป็นโมฆะ Writepoints () { ถ่านบัฟเฟอร์ [33] บัฟเฟอร์ [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() { ถ่าน argstr[128]; noteblockInit(); ศาล<<"Teklea!…:"f; ชื่อ[0]=f; ศาล<
IplImage* img0=cvLoadImage("00.jpg", 0); if(f=='0') { สำหรับ (y=1;yheight-2;y++) { สำหรับ (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++;} } } } บัฟเฟอร์ถ่าน [33]; itoa (n, บัฟเฟอร์, 10); fprintf(NuPu, "ครีบ:"); fprintf(NuPu, บัฟเฟอร์); fprintf(NuPu, "\n"); fclose(นูปู);
cvWaitKey(0); //_execlp("calc.exe", "calc.exe", argstr, NULL); cvDestroyAllWindows(); cvReleaseImage (&ภาพ); cvReleaseImage(&img); cvReleaseImage(&img0); cvReleaseImage(&img1); cvReleaseImage(&img2); กลับ 0; }
การสร้างใหม่ 3 มิติ:
#รวม ///////////////// #ifdef _APPLE_ #include #else #include #include #endif #include #include #include #include #include #include
#define สีม่วง glColor3f(1, 0, 1) #define azul glColor3f(0, 0, 1) #define turkeza glColor3f(0, 1, 1) #define verde glColor3f(0, 1, 0) #define อามาริลโล glColor3f(1, 1, 0) #define naranja glColor3f(1,.3, 0) #define rojo glColor3f(1, 0, 0) โดยใช้เนมสเปซ std; int s, Boton=1, Pulbut=1; float mx=0, my=0, mtx=0, mty=0, mtz=-5.0; const int Avance=1; สายสตริง Aux; ถ่าน Caracter='H'; ไฟล์ *NuPu; int NP, h, w; ลอย G=0, n=0, cx[5000], cy[5000], x, y, ขวาน, ay, az; แบบอักษร int=(int)GLUT_BITMAP_8_BY_13; ฉลากถ่านแบบคงที่[100]; ถ่านบัฟเฟอร์[3]; GLfloat anguloCuboX = 0.0f; GLfloat anguloCuboY = 0.0f; GLfloat anguloEsfera = 0.0f; GLint ancho=500; GLint อัลโต=500; int hazPerspectiva = 0; โมฆะก่อร่างใหม่ (ความกว้าง int ความสูง int) { glViewport (0, 0, ความกว้าง, ความสูง); glMatrixMode(GL_PROJECTION); glLoadIdentity(); ถ้า(hazPerspectiva) gluPerspective(23.0f, (GLfloat)width/(GLfloat)height, 1.0f, 20.0f); glOrtho(-1, 1, -1, 1, -10, 10); glMatrixMode(GL_MODELVIEW); ancho = ความกว้าง; อัลโต = ความสูง; } เป็นโมฆะ Kolorear (int K) { float Hip; x=(cx[s]-320)/480; y=(cy[s]-240)/640; สะโพก=sqrt(pow(x, 2)+pow(y, 2)); if((สะโพก>=0)&&(สะโพก=.07)&&(สะโพก=.14)&&(สะโพก=.21)&&(สะโพก=.28)&&(สะโพก=.35)&&(สะโพก=.42) &&(สะโพก<=.49)){violeta;} } โมฆะ 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) { ถ่าน *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 สำหรับ (=สวัสดีข้อความ");;s<3;s++) { glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24, บัฟเฟอร์ [s]); } glTranslatef (mty, -mtx, mtz); glRotatef (mx, 1.0f, 0.0f, 0.0f); glRotatef (ของฉัน, 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_BITMAP_TIMES'_ROMAN'_24, glutBitmapCharacter);*/ /*glColor3f(1. 0f, 1.0f, 1.0f); setOrthographicProjection(); glPushMatrix(); glLoadIdentity(); renderBitmapString (30, 15, (เป็นโมฆะ *) แบบอักษร "บทช่วยสอน GLUT ---_------_@ 3D Tech");*/ glFlush(); glutSwapBuffers(); anguloCuboX+=0.1f; anguloCuboY+=0.1f; anguloEsfera+=0.2f; } เป็นโมฆะ init () { glClearColor(0, 0, 0, 0); glEnable(GL_DEPTH_TEST); ancho = 500; อัลโต = 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"); ถ้า (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()); Aux[4]=48; Aux[5]=48; Aux[6]=48; //Aux[7]=48; cx[s]=atoi(Aux.c_str()); เอส++; } } myfile.close(); } อื่นๆ cout <1780) NP=1700; cout < โมฆะไม่ได้ใช้งาน () { แสดง (); } แป้นพิมพ์เป็นโมฆะ (คีย์ถ่านที่ไม่ได้ลงชื่อ, int x, int y) { สวิตช์ (คีย์) { case 'p': case 'P': hazPerspectiva=1; ก่อร่างใหม่(ancho, alto); หยุดพัก; ตัวพิมพ์ 'o': ตัวพิมพ์ 'O': hazPerspectiva=0; ก่อร่างใหม่(ancho, alto); หยุดพัก; กรณีที่ 27: // ทางออกทางหนี(0); หยุดพัก; } } โมฆะ raton (ปุ่ม int, int state, 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=รัฐ; //mx=y; แสดง(); } โมฆะ 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, ถ่าน ** argv) { /*glutAddMenuEntry() glutAddSubMenu() glutAttachMenu() glutCreateMenu() glutSetMenu() glutStrokeCharacter() glutStrokeLength()*/ /*glReadPixels เฟรมบัฟเฟอร์ glGetPixelMapfv() คืนค่าแผนที่พิกเซลที่ระบุ glGetPixelMapuiv() คืนค่าแผนที่พิกเซลที่ระบุ glGetPointerv() ส่งกลับที่อยู่ของตัวชี้ที่ระบุ*/ Init(); เลียร์(); glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowตำแหน่ง(50, 50); glutInitWindowSize(อันโช, อัลโต); glutCreateWindow("คิวโบ 1"); ในนั้น(); glutDisplayFunc (แสดงผล); glutReshapeFunc(ก่อร่างใหม่); glutIdleFunc(ว่าง); glutMouseFunc(เรตัน); glutMotionFunc(ratmov); glutKeyboardFunc(คีย์บอร์ด); glutMainLoop(); กลับ 0; }
ขั้นตอนที่ 5:
ถึงคราวต้องหยุด! …แต่ในบทต่อไป ฉันสัญญากับคุณว่าฉันจะนำไปใช้กับราสเบอร์รี่ pi 3 หรือนาโนบอร์ด jetson ของฉัน ซึ่งติดตั้งอยู่บนเครื่องบินที่ควบคุมจากระยะไกลอยู่แล้ว หรือบนหุ่นยนต์แมงมุมบางตัวเพื่อสแกนภายในถ้ำ
แนะนำ:
การออกแบบเกมในการสะบัดใน 5 ขั้นตอน: 5 ขั้นตอน
การออกแบบเกมในการสะบัดใน 5 ขั้นตอน: การตวัดเป็นวิธีง่ายๆ ในการสร้างเกม โดยเฉพาะอย่างยิ่งเกมปริศนา นิยายภาพ หรือเกมผจญภัย
การตรวจจับใบหน้าบน Raspberry Pi 4B ใน 3 ขั้นตอน: 3 ขั้นตอน
การตรวจจับใบหน้าบน Raspberry Pi 4B ใน 3 ขั้นตอน: ในคำแนะนำนี้ เราจะทำการตรวจจับใบหน้าบน Raspberry Pi 4 ด้วย Shunya O/S โดยใช้ Shunyaface Library Shunyaface เป็นห้องสมุดจดจำใบหน้า/ตรวจจับใบหน้า โปรเจ็กต์นี้มีจุดมุ่งหมายเพื่อให้เกิดความเร็วในการตรวจจับและจดจำได้เร็วที่สุดด้วย
วิธีการติดตั้งปลั๊กอินใน WordPress ใน 3 ขั้นตอน: 3 ขั้นตอน
วิธีการติดตั้งปลั๊กอินใน WordPress ใน 3 ขั้นตอน: ในบทช่วยสอนนี้ ฉันจะแสดงขั้นตอนสำคัญในการติดตั้งปลั๊กอิน WordPress ให้กับเว็บไซต์ของคุณ โดยทั่วไป คุณสามารถติดตั้งปลั๊กอินได้สองวิธี วิธีแรกคือผ่าน ftp หรือผ่าน cpanel แต่ฉันจะไม่แสดงมันเพราะมันสอดคล้องกับ
สแกนเนอร์ RFID อย่างง่ายใช้แบตเตอรี่ (MiFare, MFRC522, Oled, Lipo, TP4056): 5 ขั้นตอน
Simple RFID Scanner Battery Powered (MiFare, MFRC522, Oled, Lipo, TP4056): ในคำแนะนำนี้ ฉันแสดงให้คุณเห็นว่าฉันสร้างเครื่องอ่าน RFID UID แบบง่าย ๆ ที่อ่าน UID ของการ์ด Mifare RFID ได้อย่างไร โปรแกรมค่อนข้างง่ายและบนเขียงหั่นขนม ผู้อ่านถูกสร้างขึ้นอย่างรวดเร็ว จากนั้นฉันก็บัดกรีมันทั้งหมดบนแผ่นกระดานที่สมบูรณ์แบบ และฉันออกแบบ
สแกนเนอร์ DIY 3D ตามโครงสร้างแสงและการมองเห็นสเตอริโอในภาษา Python: 6 ขั้นตอน (พร้อมรูปภาพ)
สแกนเนอร์ DIY 3D ที่อิงตามโครงสร้างแสงและการมองเห็นสเตอริโอในภาษา Python: สแกนเนอร์ 3 มิตินี้สร้างขึ้นโดยใช้รายการทั่วไปที่มีต้นทุนต่ำ เช่น โปรเจ็กเตอร์วิดีโอและเว็บแคม เครื่องสแกน 3 มิติแบบแสงที่มีโครงสร้างเป็นอุปกรณ์สแกน 3 มิติสำหรับวัดรูปร่างสามมิติของวัตถุโดยใช้รูปแบบแสงที่ฉายและระบบกล้อง