1: /*
2: Copyright (c) 2010 <a href="http://www.gutgames.com">James Craig</a>
3:
4: Permission is hereby granted, free of charge, to any person obtaining a copy
5: of this software and associated documentation files (the "Software"), to deal
6: in the Software without restriction, including without limitation the rights
7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8: copies of the Software, and to permit persons to whom the Software is
9: furnished to do so, subject to the following conditions:
10:
11: The above copyright notice and this permission notice shall be included in
12: all copies or substantial portions of the Software.
13:
14: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20: THE SOFTWARE.*/
21:
22: #region Usings
23: using System.Drawing;
24: using System.Drawing.Imaging;
25: #endregion
26:
27: namespace Utilities.Media.Image
28: {
29: /// <summary>
30: /// Used for motion detection
31: /// </summary>
32: public static class MotionDetection
33: {
34: #region Public Static Functions
35:
36: /// <summary>
37: /// Runs the motion detection algorithm
38: /// </summary>
39: /// <param name="NewImage">The "new" frame</param>
40: /// <param name="OldImage">The "old" frame</param>
41: /// <param name="Threshold">The threshold used to detect changes in the image</param>
42: /// <param name="DetectionColor">Color to display changes in the images as</param>
43: /// <returns>A bitmap indicating where changes between frames have occurred overlayed on top of the new image.</returns>
44: public static Bitmap Process(Bitmap NewImage, Bitmap OldImage, int Threshold, Color DetectionColor)
45: {
46: using (Bitmap NewImage1 = Utilities.Media.Image.Image.ConvertBlackAndWhite(NewImage))
47: {
48: using (Bitmap OldImage1 = Utilities.Media.Image.Image.ConvertBlackAndWhite(OldImage))
49: {
50: using (Bitmap NewImage2 = Utilities.Media.Image.Image.SNNBlur(NewImage1, 5))
51: {
52: using (Bitmap OldImage2 = Utilities.Media.Image.Image.SNNBlur(OldImage1, 5))
53: {
54: using (Bitmap OutputImage = new Bitmap(NewImage2, NewImage2.Width, NewImage2.Height))
55: {
56: using (Bitmap Overlay = new Bitmap(NewImage, NewImage.Width, NewImage.Height))
57: {
58: BitmapData NewImage2Data = Image.LockImage(NewImage2);
59: int NewImage2PixelSize = Image.GetPixelSize(NewImage2Data);
60: BitmapData OldImage2Data = Image.LockImage(OldImage2);
61: int OldImage2PixelSize = Image.GetPixelSize(OldImage2Data);
62: BitmapData OverlayData = Image.LockImage(Overlay);
63: int OverlayPixelSize = Image.GetPixelSize(OverlayData);
64: for (int x = 0; x < OutputImage.Width; ++x)
65: {
66: for (int y = 0; y < OutputImage.Height; ++y)
67: {
68: Color NewPixel = Image.GetPixel(NewImage2Data, x, y, NewImage2PixelSize);
69: Color OldPixel = Image.GetPixel(OldImage2Data, x, y, OldImage2PixelSize);
70: if (System.Math.Pow((double)(NewPixel.R - OldPixel.R), 2.0) > Threshold)
71: {
72: Image.SetPixel(OverlayData, x, y, Color.FromArgb(100, 0, 100), OverlayPixelSize);
73: }
74: else
75: {
76: Image.SetPixel(OverlayData, x, y, Color.FromArgb(200, 0, 200), OverlayPixelSize);
77: }
78: }
79: }
80: Image.UnlockImage(Overlay, OverlayData);
81: Image.UnlockImage(NewImage2, NewImage2Data);
82: Image.UnlockImage(OldImage2, OldImage2Data);
83: using (Bitmap Overlay2 = Utilities.Media.Image.Image.EdgeDetection(Overlay, 25, DetectionColor))
84: {
85: BitmapData Overlay2Data = Image.LockImage(Overlay2);
86: int Overlay2PixelSize = Image.GetPixelSize(Overlay2Data);
87: for (int x = 0; x < OutputImage.Width; ++x)
88: {
89: for (int y = 0; y < OutputImage.Height; ++y)
90: {
91: Color Pixel1 = Image.GetPixel(Overlay2Data, x, y, Overlay2PixelSize);
92: if (Pixel1.R != DetectionColor.R || Pixel1.G != DetectionColor.G || Pixel1.B != DetectionColor.B)
93: {
94: Image.SetPixel(Overlay2Data, x, y, Color.FromArgb(200, 0, 200), Overlay2PixelSize);
95: }
96: }
97: }
98: Image.UnlockImage(Overlay2, Overlay2Data);
99: return Utilities.Media.Image.Image.Watermark(OutputImage, Overlay2, 1.0f, 0, 0, Color.FromArgb(200, 0, 200));
100: }
101: }
102: }
103: }
104: }
105: }
106: }
107: }
108:
109: #endregion
110: }
111: }