private unsafe Target[] SearchFaces() { IntPtr retTarget = IntPtr.Zero; int count = NativeIconExtractor.SearchFaces(ref retTarget); if (count <= 0) return new Target[0]; Target* pTarget = (Target*)retTarget; IList<Target> targets = new List<Target>(); for (int i = 0; i < count; i++) { Target face = pTarget[i]; targets.Add(face); } Target[] tgArr = new Target[targets.Count]; targets.CopyTo(tgArr, 0); return tgArr; }
private void DetectMotion() { DateTime lastTime = DateTime.Now.AddMinutes(-3); CvVideoWriter videoWriter = null; uint count = 0; while (true) { Frame newFrame = GetNewFrame(); if (newFrame.image != IntPtr.Zero) { DateTime dtFrame = DateTime.FromBinary(newFrame.timeStamp); IplImage ipl = new IplImage(newFrame.image); ipl.IsEnabledDispose = false; //new minute start, create new vide file if (dtFrame.Minute != lastTime.Minute) { if (videoWriter != null) { Cv.ReleaseVideoWriter(videoWriter); videoWriter = null; } videoWriter = Cv.CreateVideoWriter( @"d:\" + dtFrame.Minute + ".avi", "XVID", 10, ipl.Size ); System.Diagnostics.Debug.WriteLine(@"d:\" + dtFrame.Minute + ".avi"); } videoWriter.WriteFrame(ipl); lastTime = dtFrame; Frame frameToProcess = new Frame(); bool groupCaptured = false; count++; if (count % 5 == 0) { if (Properties.Settings.Default.DetectMotion) groupCaptured = MotionDetect.MotionDetect.PreProcessFrame(newFrame, ref frameToProcess); else groupCaptured = NoneMotionDetect.PreProcessFrame(newFrame, ref frameToProcess); } else { Cv.Release(ref newFrame.image); } count %= uint.MaxValue; if (IsStaticFrame(frameToProcess)) { Cv.Release(ref frameToProcess.image); } else { SaveFrame(frameToProcess); NativeIconExtractor.AddInFrame(frameToProcess); motionFrames.Enqueue(frameToProcess); } if (groupCaptured) { Target[] tgts = SearchFaces(); //remove duplicated faces int upLimit = tgts.Length; if (Properties.Settings.Default.DetectMotion && Properties.Settings.Default.removeDuplicatedFace) { upLimit = Math.Min(upLimit, Properties.Settings.Default.MaxDupFaces); } Target[] removed = new Target[upLimit]; Array.ConstrainedCopy(tgts, 0, removed, 0, upLimit); ImageDetail[] details = this.SaveImage(removed); this.screen.ShowImages(details); Frame[] frames = motionFrames.ToArray(); motionFrames.Clear(); //release memory Array.ForEach(frames, f => Cv.Release(ref f.image)); } } else goDetectMotion.WaitOne(); } }
unsafe ImageDetail[] SaveImage(Target[] targets) { IList<ImageDetail> imgs = new List<ImageDetail>(); foreach (Target t in targets) { Frame frame = t.BaseFrame; DateTime dt = DateTime.FromBinary(frame.timeStamp); for (int j = 0; j < t.FaceCount; ++j) { IntPtr* f = ((IntPtr*)(t.FaceData)) + j; IplImage aFace = new IplImage(*f); aFace.IsEnabledDispose = false; string facePath = GetFacePath(frame, dt, j); aFace.SaveImage(facePath); imgs.Add(ImageDetail.FromPath(facePath)); } } ImageDetail[] details = new ImageDetail[imgs.Count]; imgs.CopyTo(details, 0); return details; }
unsafe void SearchFace() { while (true) { Frame[] frames = null; lock (locker) { if (framesQueue.Count > 0) { frames = framesQueue.Dequeue(); } } if (frames != null) { for (int i = 0; i < frames.Length; ++i) { DateTime dt = DateTime.FromBinary(frames[i].timeStamp); NativeIconExtractor.AddInFrame(frames[i]); } IntPtr target = IntPtr.Zero; int count = NativeIconExtractor.SearchFaces(ref target); if (count > 0) { Target* pTarget = (Target*)target; IList<Target> targets = new List<Target>(); int upLimit = count; if (frames.Length > 1 && Properties.Settings.Default.DetectMotion && Properties.Settings.Default.removeDuplicatedFace) { upLimit = Math.Min(count, Properties.Settings.Default.MaxDupFaces); } for (int i = 0; i < upLimit; i++) { Target face = pTarget[i]; Frame frm = face.BaseFrame; int idx = Array.FindIndex(frames, fm => fm.cameraID == frm.cameraID && fm.image == frm.image && fm.timeStamp == frm.timeStamp); Debug.Assert(idx != -1); targets.Add(face); } Target[] tgArr = new Target[targets.Count]; targets.CopyTo(tgArr, 0); ImageDetail[] imgs = this.SaveImage(tgArr); this.screen.ShowImages(imgs); } NativeIconExtractor.ReleaseMem(); Array.ForEach(frames, f => Cv.Release(ref f.image)); } else goSearch.WaitOne(); } }