Emgucv_Motion_Detection_MotionHistory_Human_Activity_in_video




This topic introduces you to the function MotionHistory of emgucv .


The motion history image (MHI) is a static image template helps in understanding the motion location and path as it progresses.


In MHI, the temporal motion information is collapsed into a single image template where intensity is a function of recency of motion.





The MHI pixel intensity is a function of the motion history at that location, where brighter values correspond to a more recent motion.


Using MHI, moving parts of a video sequence can be engraved with a single image, from where one can predict the motion flow as well as the moving parts of the video action.


Video  Effect 


Algorithm1

=========================================================

for each time t
  Bt := absolute_difference(It, It-1) > threshold
end for

=========================================================



Algorithm2

=========================================================
for each time t
  for each pixel (x,y)
    if Bt(x,y) = 1
      MHIt(x,y) := τ
    else if MHIt-1 ≠ 0
      MHIt(x,y) := MHIt-1(x,y) - 1
    else
      MHIt(x,y) := 0
    end if
end for
=========================================================

If you want to know more information about

motion history

you can see this video

Video1





Video2_Image Moments








Video3_MHI




Code 






  1. /*
  2. * Copyright (c) 2016 Samuel <dryjoker007@gmail.com>
  3. *
  4. * BSD Simplified License.
  5. * For information on usage and redistribution, and for a DISCLAIMER OF ALL
  6. *
  7. */
  8. using System;
  9. using System.Collections.Generic;
  10. using System.ComponentModel;
  11. using System.Data;
  12. using System.Drawing;
  13. using System.Linq;
  14. using System.Text;
  15. using System.Threading.Tasks;
  16. using System.Windows.Forms;
  17. using Emgu.CV;
  18. using Emgu.CV.Util;
  19. using Emgu.CV.Structure;
  20. using Emgu.CV.VideoSurveillance;
  21. using Emgu.CV.CvEnum;
  22. namespace emgucv2._4._2_ex
  23. {
  24. public partial class Form1 : Form
  25. {
  26. private Capture _capture = new Capture();
  27. private MotionHistory _motionHistory;
  28. private IBGFGDetector<Bgr> _forgroundDetector;
  29. public Form1()
  30. {
  31. InitializeComponent();
  32. //try to create the capture
  33. if (_capture == null)
  34. {
  35. try
  36. {
  37. _capture = new Capture();
  38. }
  39. catch (NullReferenceException excpt)
  40. { //show errors if there is any
  41. MessageBox.Show(excpt.Message);
  42. }
  43. }
  44. if (_capture != null) //if camera capture has been successfully created
  45. {
  46. _motionHistory = new MotionHistory(
  47. 1.0, //in second, the duration of motion history you wants to keep
  48. 0.05, //in second, maxDelta for cvCalcMotionGradient
  49. 0.5); //in second, minDelta for cvCalcMotionGradient
  50. _capture.ImageGrabbed += ProcessFrame;
  51. _capture.Start();
  52. }
  53. }
  54. private void ProcessFrame(object sender, EventArgs e)
  55. {
  56. using (Image<Bgr, Byte> image = _capture.RetrieveBgrFrame())
  57. using (MemStorage storage = new MemStorage()) //create storage for motion components
  58. {
  59. if (_forgroundDetector == null)
  60. {
  61. //_forgroundDetector = new BGCodeBookModel<Bgr>();
  62. //_forgroundDetector = new FGDetector<Bgr>(Emgu.CV.CvEnum.FORGROUND_DETECTOR_TYPE.MOG);
  63. _forgroundDetector = new BGStatModel<Bgr>(image, Emgu.CV.CvEnum.BG_STAT_TYPE.FGD_STAT_MODEL);
  64. }
  65. _forgroundDetector.Update(image);
  66. capturedImageBox.Image = image.Bitmap;
  67. //update the motion history
  68. _motionHistory.Update(_forgroundDetector.ForgroundMask);
  69. //forgroundImageBox.Image = _forgroundDetector.ForgroundMask.Bitmap;
  70. #region get a copy of the motion mask and enhance its color
  71. double[] minValues, maxValues;
  72. Point[] minLoc, maxLoc;
  73. _motionHistory.Mask.MinMax(out minValues, out maxValues, out minLoc, out maxLoc);
  74. Image<Gray, Byte> motionMask = _motionHistory.Mask.Mul(255.0 / maxValues[0]);
  75. #endregion
  76. //create the motion image
  77. Image<Bgr, Byte> motionImage = new Image<Bgr, byte>(motionMask.Size);
  78. //display the motion pixels in blue (first channel)
  79. motionImage[2] = motionMask;
  80. //Threshold to define a motion area, reduce the value to detect smaller motion
  81. double minArea = 150;
  82. storage.Clear(); //clear the storage
  83. Seq<MCvConnectedComp> motionComponents = _motionHistory.GetMotionComponents(storage);
  84. //iterate through each of the motion component
  85. foreach (MCvConnectedComp comp in motionComponents)
  86. {
  87. //reject the components that have small area;
  88. if (comp.area < minArea) continue;
  89. // find the angle and motion pixel count of the specific area
  90. double angle, motionPixelCount;
  91. _motionHistory.MotionInfo(comp.rect, out angle, out motionPixelCount);
  92. //reject the area that contains too few motion
  93. if (motionPixelCount < comp.area * 0.05) continue;
  94. //Draw each individual motion in red
  95. //DrawMotion(motionImage, comp.rect, angle, new Bgr(Color.Red));
  96. }
  97. // find and draw the overall motion angle
  98. double overallAngle, overallMotionPixelCount;
  99. _motionHistory.MotionInfo(motionMask.ROI, out overallAngle, out overallMotionPixelCount);
  100. //DrawMotion(motionImage, motionMask.ROI, overallAngle, new Bgr(Color.Tomato));
  101. //Display the amount of motions found on the current image
  102. UpdateText(String.Format("Total Motions found: {0}; Motion Pixel count: {1}", motionComponents.Total, overallMotionPixelCount));
  103. //Display the image of the motion
  104. motionImageBox.Image = motionImage.Bitmap;
  105. }
  106. }
  107. private void UpdateText(String text)
  108. {
  109. if (InvokeRequired && !IsDisposed)
  110. {
  111. Invoke((Action<String>)UpdateText, text);
  112. }
  113. else
  114. {
  115. label1.Text = text;
  116. }
  117. }
  118. private static void DrawMotion(Image<Bgr, Byte> image, Rectangle motionRegion, double angle, Bgr color)
  119. {
  120. float circleRadius = (motionRegion.Width + motionRegion.Height) >> 2;
  121. Point center = new Point(motionRegion.X + motionRegion.Width >> 1, motionRegion.Y + motionRegion.Height >> 1);
  122. CircleF circle = new CircleF(
  123. center,
  124. circleRadius);
  125. int xDirection = (int)(Math.Cos(angle * (Math.PI / 180.0)) * circleRadius);
  126. int yDirection = (int)(Math.Sin(angle * (Math.PI / 180.0)) * circleRadius);
  127. Point pointOnCircle = new Point(
  128. center.X + xDirection,
  129. center.Y - yDirection);
  130. LineSegment2D line = new LineSegment2D(center, pointOnCircle);
  131. image.Draw(circle, color, 1);
  132. image.Draw(line, color, 2);
  133. }
  134. private void Form1_FormClosed(object sender, FormClosedEventArgs e)
  135. {
  136. _capture.Stop();
  137. }
  138. }
  139. }




留言

這個網誌中的熱門文章

何謂淨重(Net Weight)、皮重(Tare Weight)與毛重(Gross Weight)

Architecture(架構) 和 Framework(框架) 有何不同?_軟體設計前的事前規劃的藍圖概念

經得起原始碼資安弱點掃描的程式設計習慣培養(五)_Missing HSTS Header