שמירת קובץ וידאו - שימוש בספריה EmguCV
-
טוב, אני מנסה שוב פעם, למרות שאני תוהה לעצמי אם מישהו מכיר את הספריה הזאת?? או שמא אתם בכלל ממליצים לי על ספריה אחרת?
בכל אופן, כתבתי את הקוד הבא שאמור להקליט קובץ וידאו ולשמור אותו על המחשב, אך משום מה זה לא עובד לי.
דיבגתי את הקוד, זה עובד ופועל, מתקבל מערך של כ500 פריימים וכביכול זה כותב אותו לקובץ, אך משום מה - אני לא רואה במחשב שלי שום קובץ וידאו שנוצר
חיפשתי וחיפשתי בגוגל, ולכאו' אני עושה בדיוק מה שאמורים לעשות, אך זה לא עובד..הנה הקוד:
public class RecordVideo { private static string folder = @"C:\Users\Avraham\Documents\demo\"; public static void Record(int Time_millisecounds =10000) { List<Image<Bgr, Byte>> Image_Array; //יצירת מופע של וידאו ורייטר על מנת לשמור לקובץ using (VideoWriter vm = new VideoWriter(folder + DateTime.Now + ".avi", 30, new Size(640, 480), true)) { Image_Array = GetVideoFrames(Time_millisecounds); foreach (var frame in Image_Array) { //כתיבת התמונה לקובץ הוידאו vm.Write(frame.Mat); } } } /// <summary> /// מקליטה וידאו באורך זמן מוגדרא מראש /// </summary> /// <param name="Time_millisecounds"></param> /// <returns></returns> private static List<Image<Bgr, Byte>> GetVideoFrames(int Time_millisecounds) { List<Image<Bgr, Byte>> image_array = new List<Image<Bgr, Byte>>(); Stopwatch SW = new System.Diagnostics.Stopwatch(); bool Reading = true; Capture _capture = new Capture(); //מגדיר את הגובה והרוחב של התמונה _capture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameWidth, 640); _capture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameHeight, 480); SW.Start(); //לולאה שמצלמת תמונות ושומרת אותם למערך while (Reading) { Image<Bgr, Byte> frame = _capture.QueryFrame().ToImage<Bgr, Byte>(); if (frame != null) { image_array.Add(frame.Copy()); if (SW.ElapsedMilliseconds >= Time_millisecounds) Reading = false; } else { Reading = false; } } return image_array; } }
קישורים לסטאק:
אשמח לעצות ועזרה!!
תודה רבה רבה מראש, אברהם.פורסם במקור בפורום CODE613 ב15/01/2017 09:52 (+02:00)
-
כן.
היא מחזירה לי תמונה מהמצלמה.
שים לב, שבדוגמאות בסטאק בד"כ משתמשים בqueryFrame לבד, אך בגרסאות החדשות יותר של הספריה צריך לכתוב כמו שכתבתי:_capture.QueryFrame().ToImage<Bgr, Byte>();
דהיינו לבחור את סוג התמונה שתוחזר.
פורסם במקור בפורום CODE613 ב15/01/2017 18:24 (+02:00)
-
כעת עובד לי, לא עבד לי כי פשוט המצלמה לא עבדה.
שתי הערות:
א. אתה מעתיק פריימים בלולאה ללא הגבלת מהירות, ייתכן שזה מידי fps לצרכים שלך.
ב. אתה שומר את התמונות בזיכרון במקום לכתוב ישירות לקובץ. תוכל שהמתודה GetVideoFrames תחזיר IEnumerable של סוג Mat ואז תכתוב במקום הוספה למערך yield return frame.Mat ככה גם אתה חוסך את הcopy.פורסם במקור בפורום CODE613 ב15/01/2017 21:04 (+02:00)
-
@דוד ל.ט.
כעת עובד לי, לא עבד לי כי פשוט המצלמה לא עבדה.
שתי הערות:
א. אתה מעתיק פריימים בלולאה ללא הגבלת מהירות, ייתכן שזה מידי fps לצרכים שלך.
ב. אתה שומר את התמונות בזיכרון במקום לכתוב ישירות לקובץ. תוכל שהמתודה GetVideoFrames תחזיר IEnumerable של סוג Mat ואז תכתוב במקום הוספה למערך yield return frame.Mat ככה גם אתה חוסך את הcopy.א. תודה רבה! סוף סוף זה עובד
ב. איך אפשר להגביל מהירות, לשלוח את הטרייד לישון קצת ??
ג. צודק!פורסם במקור בפורום CODE613 ב16/01/2017 00:16 (+02:00)
-
@דוד ל.ט.
א. אתה מעתיק פריימים בלולאה ללא הגבלת מהירות, ייתכן שזה מידי fps לצרכים שלך.
בעקרון בקוד הזה:
using (VideoWriter vm = new VideoWriter(fileName, 30, new Size(640, 480), true)) { var frames = GetVideoFrames(Time_millisecounds); foreach (var frame in frames) { vm.Write(frame); } }
המספר 30 בשורה הראשונה - מגדיר את כמות הפריימים לשניה.
אך אני לא בטוח שזה באמת עובד..
זה הקוד המלא והמתוקן - תודה רבה לדוד ל.ט.!public class RecordVideo { private static string folder = @"C:\Users\Avraham\Documents\demo\"; private static string fileName; public static void Record(int Time_millisecounds =10000) { fileName = folder + dateTimeToString(DateTime.Now) + ".avi"; //יצירת מופע של וידאו ורייטר על מנת לשמור לקובץ using (VideoWriter vm = new VideoWriter(fileName, 30, new Size(640, 480), true)) { var frames = GetVideoFrames(Time_millisecounds); foreach (var frame in frames) { vm.Write(frame); } } } /// <summary> /// מקליטה וידאו באורך זמן מוגדרא מראש /// </summary> /// <param name="Time_millisecounds"></param> /// <returns></returns> private static IEnumerable<Mat> GetVideoFrames(int Time_millisecounds) { List<Image<Bgr, Byte>> image_array = new List<Image<Bgr, Byte>>(); Stopwatch SW = new System.Diagnostics.Stopwatch(); bool Reading = true; Capture _capture = new Capture(); //מגדיר את הגובה והרוחב של התמונה _capture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameWidth, 640); _capture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameHeight, 480); SW.Start(); //לולאה שמצלמת תמונות while (Reading) { Image<Bgr, Byte> frame = _capture.QueryFrame().ToImage<Bgr, Byte>(); if (frame != null) { yield return frame.Mat; if (SW.ElapsedMilliseconds >= Time_millisecounds) Reading = false; } else { Reading = false; } } } private static string dateTimeToString(DateTime dateTime) { return string.Format("DateRec{0}-{1}-{2}_Time{3}-{4}-{5}", dateTime.Day, dateTime.Month, dateTime.Year, dateTime.Hour, dateTime.Minute, dateTime.Second); } }
פורסם במקור בפורום CODE613 ב17/01/2017 14:51 (+02:00)