קוד לזיהוי תנועה
-
אני משתמש בספריה emguCV (עטיפה דוטנטית לספריה OpenCV) ואני מנסה לכתוב פונקציה שתחזיר לי ערך בוליאני האם התרחשה תנועה או לא.
כתבתי את הקוד הבא: ע"פ התיעוד שלהם כאן
Capture capture; Image<Bgr, Byte> currentFrame = new Image<Bgr, Byte>(640, 480); Image<Bgr, Byte> previousFrame; Image<Bgr, Byte> Difference; DateTime time; Image<Gray, Byte> des = new Image<Gray, Byte>(640, 480); Image<Gray, Byte> thres = new Image<Gray, Byte>(640, 480); Image<Gray, Byte> eroded = new Image<Gray, Byte>(640, 480); public void ProcessFrame() { if (previousFrame == null) { currentFrame = capture.QueryFrame().ToImage<Bgr, Byte>(); time = DateTime.Now; } else { currentFrame = capture.QueryFrame().ToImage<Bgr, Byte>(); Difference = previousFrame.AbsDiff(currentFrame); Difference = Difference.ThresholdBinary(new Bgr(25, 25, 25), new Bgr(255, 255, 255)); //איך אני יכול לדעת האם ישנם פיקסלים לבנים בתמונה?? } }
השאלה היא כיצד אני יכול לדעת האם ישנם פיקסלים לבנים בתמונה, שזה אומר שהייתה תזוזה, ואז אני רוצה להקליט את התנועה?
אני מבין שיש פונקציה בשם erode אך אני לא מצליח להשתמש בה (ראיתי כאן שהוא משתמש בה אבל זה קוד ישן, והיום היא דורשת פרמטרים נוספים שאין לי מושג מהם
אשמח לעזרה!! תודה רבה!!פורסם במקור בפורום CODE613 ב12/01/2017 21:05 (+02:00)
-
מצאתי כאן פוסט יפה בעברית, אך הוא עושה זאת בPyton.
הקוד שלו הוא כזה:def have_motion(frame1, frame2): delta = cv2.absdiff(frame1, frame2) thresh = cv2.threshold(delta, 25, 255, cv2.THRESH_BINARY)[1] return numpy.sum(thresh) > 0
השאלה שלי היא מה עושה הפונקציה: numpy.sum (אני מבין שnumpy זו הספריה המתמטית של pyton), וכיצד אני יכול לעשות משהו דומה בC#?
תודה רבה רבה מראש לכולם!!
שבת שלום.
אברהםפורסם במקור בפורום CODE613 ב13/01/2017 09:30 (+02:00)
-
טוב זה מה שיצא לי לבסוף.
אשמח לשמוע הערות והארות.
אני משתמש בספריה הזאת :using Emgu.CV; using Emgu.CV.Structure; using System; using System.Linq; namespace MotionDetection { public static class ProcessImage { //אובייקט המצלמה private static Capture capture = new Capture(); //הגדרת גודל הפריים, ככל שהוא קטן יותר כך ידרשו פחות משאבים לעיבוד התמונה private static System.Drawing.Size frameSize = new System.Drawing.Size(640, 480); private static Image<Bgr, Byte> currentFrame = new Image<Bgr, Byte>(frameSize); private static Image<Bgr, Byte> previousFrame; private static DateTime time; private static Image<Gray, Byte> diff = new Image<Gray, Byte>(frameSize); public static void ProcessFrame() { if (previousFrame == null) { currentFrame = capture.QueryFrame().ToImage<Bgr, Byte>(); time = DateTime.Now; previousFrame = currentFrame.Copy(); } else { currentFrame = capture.QueryFrame().ToImage<Bgr, Byte>(); if (haveMotion(currentFrame, previousFrame)) { //להקליט את התנועה ולשמור ולשלוח } else { //אין תנועה ממשיכים בניטור ProcessFrame(); } } } /// <summary> /// פונקציה שמשווה שתי תמונות ובודקת אם הייתה תזוזה /// </summary> /// <param name="currentImg"></param> /// <param name="prevImg"></param> /// <returns></returns> private static bool haveMotion(Image<Bgr, Byte> currentImg, Image<Bgr, Byte> prevImg) { //המרת התמונות לאפור לצורך עיבוד קל var grayCurrent = currentImg.Convert<Gray, byte>(); var grayPrev = prevImg.Convert<Gray, byte>(); //יצירת קובץ חדש שמכיל את השינויים CvInvoke.AbsDiff(grayPrev, grayCurrent, diff); //המרת הפיקסלים של התזוזה ללבן, והפיקסלים שלא השתנו לשחור //הערך הראשון מגדיר מספר שממנו ומטה כולם יולבנו, כדי לסנן רעשים var threso = diff.ThresholdBinary(new Gray(80), new Gray(255)); previousFrame = currentImg.Copy(); //כאשר הערך הוא 0 סימן שאין שינויים בין התמונות ולא הייתה תזוזה var x = threso.CountNonzero(); //ככל שהערך קטן יותר זו תזוזה קלה מאד, לכן רצוי לא לשים 0 כדי לסנן רעשי רקע (אור וכדומה if (x.Sum() > 1000) { return true; } else { return false; } } } }
השימוש ע"י קריאה בלולאה כך:
var success = true; while (success) { ProcessImage.ProcessFrame(); }
שבת שלום!!
פורסם במקור בפורום CODE613 ב13/01/2017 15:08 (+02:00)