תוכן עניינים:
וִידֵאוֹ: סורק תלת מימד בסיסי למיפוי תלת מימד דיגיטלי: 5 שלבים
2024 מְחַבֵּר: John Day | [email protected]. שונה לאחרונה: 2024-01-30 09:12
בפרויקט זה, אתאר ואסביר את היסודות הבסיסיים של סריקה ושחזור תלת-ממד המיושמים בעיקר על סריקה של אובייקטים קטנים של מטוס למחצה, ואפשר להרחיב את פעולתם למערכות סריקה ושחזור שניתן להתקין במטוסים בשלט רחוק כדי להשיג דגם תלת מימד. מהמקומות שבהם המטוס שלוקח אותם טס
הרעיון הסופי הוא להשיג סריקה תלת מימדית של מקום או אזור כלשהו, החיצוניים או הפנימיים שלו, להשתמש בו כמפה דיגיטלית (כמו בסרט פרומאוס)
שלב 1:
הרעיון הוא להתקין את כל מערכת הסריקה התלת-ממדית על מטוס בשלט רחוק, על מנת להפוך את המפה הווירטואלית של כל אזור שעליו היא עפה בתלת-ממד דיגיטציה, אך לשם כך התחלנו מתחילת הפעולה של טריאנגולציית הלייזר השיטה של סריקה או שחזור תלת מימד על ידי טריאנגולציה בלייזר בעצם מורכב מהעברת קרן לייזר דרך פריזמה שיוצרת פס לייזר כדי להשיג פס לייזר שלם שיוקרן על אובייקט שייסרק, וברגע שהתקבלה הקרנת לייזר זו על פני השטח מהמקום לסריקה, יש לצלם את התמונה בעזרת מצלמה כלשהי ורצוי להכיר את הזווית שנוצרת ביחס לזווית ההקרנה של פס הלייזר הנפלט, שכן כל אחת מהתמונות הללו לוכדת את רצועות הלייזר המוקרנות. על פני השטח של האובייקט, הם יהיו מעובדים מראש כדי לחלץ את המאפיינים הממדיים של האובייקט שיש לסרוק, ופשוט לסרוק רצועה אחר רצועה מעל האובייקט כדי להשיג את פרופיל פני השטח שלו באותו קטע רוחבי של האובייקט, ולאחר מכן ללכוד הרצועה המוקרנת של החתך הבא של האובייקט, כדי להוסיף את כל הפסים המוקרנים יחדיו לפני כל חתכי האובטו נקבל סריקה תלת ממדית של פני השטח שלו
שלב 2:
מכיוון שזיהינו את המטרה שלנו, השלב הבא בידיעה שכדי להמריא עליך קודם כל להניח את הרגליים היטב על הקרקע, אז התחלנו על הקרקע עם אב טיפוס ניסיוני של סורק תלת מימד ליניארי, כדי לאמת את הפעולה הנכונה של הבסיסי. סורק תלת מימד וכפי שאתה יכול לראות בתמונה למעלה השתמשתי במחשב PC, OpenCV, Glut של OpenGL, מצלמת רשת, לייזר, מחולל לייזר (במקרה זה דרך מראה סיבובית) במערכת תזוזה לינארית אלקטרונית (עשויה מסילה ומערכת המופקת ממדפסת ישנה) מבסיס שעליו אני מניח את האובייקטים לסריקה, עץ ופלסטלינה וכפי שאתה יכול לראות בתמונה, במחשב: הצלחתי לייצר ולהציג עם גלוט מ- OpenGL שלשה- מודל ממדי משוכפל על סמך האובייקט האמיתי הסרוק (במקרה זה עכביש צעצוע)
כך שברור כי עקרון הפעולה הוא פונקציונלי, וכי בעזרת ההתאמות והתאמות שלו למערכת מעופפת הוא יוכל לסרוק ולשחזר מפה תלת מימדית של האזור בו הוא טס.
אבל מערכת זו תשמש רק להשגת מפות תלת מימד של המשטח החיצוני של המקומות עליה היא טסה ??? …
שלב 3:
מיפוי פנים המערות והתעלות (ממש כמו בסרט Prometeus) מערכת סריקה תלת מימדית זו משמשת גם לשחזור מודלים תלת מימדיים של פנים אובייקטים גדולים וחלולים כגון מערות, בניינים, מנהרות וכו 'עקרון הפעולה שלה הוא בדיוק אותו הדבר כפי שכבר תואר ואשר בעצם מורכב מהדברים הבאים:
- לצלם את התמונה של כל הקרנה של פס הלייזר על פני השטח שיש לסרוק
- לסנן ולהסיר צבע מהתמונה
- בינארי את הצבע עם סף תמונה דינאמי
- החלת גלאי קצה כדי לזהות את הפרופיל שצולם של כל חתך הקרנת לייזר
- ובאמצעות פילוח בחר את הגבול המתאים לייצוג תלת מימד של אותו חתך של האובייקט שיש לסרוק ולבנות מחדש על מפת התלת מימד הווירטואלית.
- אז השלבים האלה פשוט חוזרים על כל תמונה שצולמה בתת-משנה של פסי הלייזר שמוקרנים ברציפות על ידי כל תת-חלק בקטע משנה.
שכבה אחר שכבה של הייצוג של חתכי הרוחב מתווספים ברצף עד לקבלת ענן נקודה שנוצר על ידי ייצוגים רבים של חתכים של האובייקט שיש למפות
שלב 4:
אחר כך אני מעביר את התוכניות לעיבוד תמונה של הקרנות רצועות הלייזר השטחיות. ושל שחזור תלת מימד וירטואלי של ייצוגים רוחביים אלה במודל המפה התלת ממדי המשוכלל:
עיבוד תמונה:
נ
#include #include "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, buffery, 10); fprintf (NuPu, bufferx); fprintf (NuPu, "\ t"); fprintf (NuPu, buffery); 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; שם [0] = f; להתייחס <
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) {Writepoints (); n ++;}}}} else {עבור (y = 1; yheight-2; y ++) {עבור (x = 1; xwidth-2; x ++) { sp = cvGet2D (img1, y, x); if (sp.val [0]> 50) {Writepoints (); n ++;}}}} מאגר צ'אר [33]; itoa (n, buffer, 10); fprintf (NuPu, "Fin:"); fprintf (NuPu, חיץ); fprintf (NuPu, "\ n"); fclose (NuPu);
cvWaitKey (0); //_execlp("calc.exe "," calc.exe ", argstr, NULL); cvDestroyAllWindows (); cvReleaseImage (& image); cvReleaseImage (& img); cvReleaseImage (& img0); cvReleaseImage (& img1); cvReleaseImage (& img2); החזר 0; }
שחזור תלת מימד:
#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) באמצעות מרחב שמות std; int s, Boton = 1, Pulbut = 1; צף mx = 0, my = 0, mtx = 0, mty = 0, mtz = -5.0; const int Avance = 1; קו מחרוזת, Aux; char Character = 'H'; קובץ *NuPu; int NP, h, w; לצוף G = 0, n = 0, cx [5000], cy [5000], x, y, ax, ay, az; int font = (int) GLUT_BITMAP_8_BY_13; תווית צ'ארטית סטטית [100]; חיץ חרוך [3]; GLfloat anguloCuboX = 0.0f; GLfloat anguloCuboY = 0.0f; GLfloat anguloEsfera = 0.0f; אנצ'ו גלינט = 500; אלט גלינט = 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); אנצ'ו = רוחב; alt=גובה; } void Kolorear (int K) {float Hip; x = (cx [s] -320)/480; y = (cy [s] -240)/640; ירך = sqrt (pow (x, 2)+pow (y, 2)); אם ((ירך> = 0) && (ירך =.07) && (ירך =.14) && (ירך =.21) && (ירך =.28) && (ירך =.35) && (ירך =.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 (); רוג'ו; 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); עבור (c = string; *c! = '\ 0'; c ++) {glutBitmapCharacter (פונט, *c);}} תצוגת חלל () {// 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_,; 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, "שלום טקסט"); glutBitmapCharacter (GLUT_BIT_BIT_BITM_);* / /*glColor3f (1. 0f, 1.0f, 1.0f); setOrthographicProjection (); glPushMatrix (); glLoadIdentity (); renderBitmapString (30, 15, (void *) גופן, "הדרכה GLUT ---_ ------ _@ 3D Tech"); */ glFlush (); glutSwapBuffers (); anguloCuboX+= 0.1f; anguloCuboY+= 0.1f; anguloEsfera+= 0.2f; } חלל init () {glClearColor (0, 0, 0, 0); glEnable (GL_DEPTH_TEST); אנצ'ו = 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"); אם (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 ()); s ++; }} myfile.close (); } else cout <1780) NP = 1700; cout <void idle () {display (); } מקלדת חלל (מפתח צ'אר לא חתום, int x, int y) {switch (מפתח) {case 'p': case 'P': hazPerspectiva = 1; צור מחדש (אנצ'ו, אלט); לשבור; מקרה 'o': מקרה 'O': hazPerspectiva = 0; צור מחדש (אנצ'ו, אלט); לשבור; מקרה 27: // יציאת בריחה (0); לשבור; }} void raton (כפתור int, 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 = כפתור; Pulbut = מדינה; // mx = y; לְהַצִיג(); } void ratmov (int x, int y) {if ((Boton == 0) & (Pulbut == 0)) {mx = y; שלי = x; } אם ((Boton == 2) & (Pulbut == 0)) {mtx = (y/200) -1; mty = (x/200) -1; } אם ((Boton == 1) & (Pulbut == 0)) {mtz =-(y/40) -5; } תצוגה (); } int main (int argc, char ** argv) { /*glutAddMenuEntry () glutAddSubMenu () glutAttachMenu () glutCreateMenu () glutSetMenu () glutStrokeCharacter () glutStrokeLength ()* / /*glReadPixels () מסגרת מאגר glGetPixelMapfv () מחזירה את מפת הפיקסלים שצוין glGetPixelMapuiv () מחזירה את מפת הפיקסלים שצוין glGetPointerv () מחזירה את כתובת המצביע שצוין.*/ Init (); leer (); glutInit (& argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition (50, 50); glutInitWindowSize (אנצ'ו, אלטו); glutCreateWindow ("קובו 1"); init (); glutDisplayFunc (תצוגה); glutReshapeFunc (עיצוב מחדש); glutIdleFunc (סרק); glutMouseFunc (raton); glutMotionFunc (ratmov); glutKeyboardFunc (מקלדת); glutMainLoop (); החזר 0; }
שלב 5:
כרגע אני חייב לעצור! … אבל בפרק הבא אני מבטיח לך שאיישם אותו על פטל pi 3 שלי או על ננובארד ג'טסון שלי, שכבר מותקן על כמה מטוסים בשלט רחוק, או על רובוט עכביש לסרוק את פנים המערות
מוּמלָץ:
סורק תלת מימד אוטומטי: 4 שלבים
סורק תלת מימד אוטומטי: קודם כל אני רוצה להודות ל- daveyclk (https://www.thingiverse.com/thing:1762299) ולפריימר (https://www.thingiverse.com/thing:2237740/remixes) על רעיונות בסיסיים . מצאתי אותו ב- Thingiverse והחלטתי לעשות גרסה אוטומטית של הסריקה התלת -ממדית
מעטפת חום למדפסת תלת מימד: תקן עיוות בהדפסות תלת מימד: 4 שלבים
מעטפת חום למדפסת תלת מימד: תיקון עיוות בהדפסות תלת מימד: כל מי שהיה לו מדפסת תלת מימד נתקל בשלב זה או אחר בבעיית העיוות. הדפסים שלוקחים שעות בסופו של דבר נהרסים בגלל שהבסיס התקלף מהמיטה. נושא זה יכול להיות מתסכל ולוקח זמן. אז מה בעצם
סורק תלת מימד של סיקלופ שלי צעד אחר צעד: 16 שלבים (עם תמונות)
סורק תלת מימד של סיקלופ שלי צעד אחר צעד: שלום לכולם, אני עומד לממש את סורק התלת מימד המפורסם של סיקלופ. כל הצעד שמוסבר היטב על הפרויקט המקורי אינו קיים. עשיתי כמה תיקונים כדי לפשט את התהליך, ראשית אני מדפיס את הבסיס, וממה שאני מחדש את הלוח PCB, אבל ממשיך
סורק CT ושולחן תלת מימד עם Arduino: 12 שלבים (עם תמונות)
סורק מחשב שולחני וסורק תלת מימד עם Arduino: טומוגרפיה ממוחשבת (CT) או טומוגרפיה צירית ממוחשבת (CAT) קשורה לרוב בהדמיה של הגוף מכיוון שהיא מאפשרת לרופאים לראות את המבנה האנטומי בתוך המטופל מבלי לבצע כל ניתוח. לתמונה בתוך האדם האנושי
סורק תלת מימד DIY מבוסס על אור מובנה וחזון סטריאו בשפת פייתון: 6 שלבים (עם תמונות)
סורק תלת מימד DIY מבוסס על אור מובנה וחזון סטריאו בשפת פייתון: סורק תלת מימד זה נעשה באמצעות פריטים קונבנציונאליים בעלות נמוכה כמו מקרן וידיאו ומצלמות רשת. סורק תלת-ממד בעל מבנה אור הוא מכשיר סריקה תלת-ממדי למדידת הצורה התלת-ממדית של אובייקט באמצעות דפוסי אור מוקרנים ומערכות מצלמה