/// <summary> /// Encapsulates the entire parking lot state /// change, triggerd by Camera changes /// </summary> public void Update() { if (Baseline != null && Baseline.SameSize(Camera.CurrentImage)) { lock (this) { // Reset percentDifferences to zero Annotations.ForEach(a => a.PercentDifference = 0); // Maps annotations to their area in pixels Dictionary <Annotation, int> annotationPixelAreas = Annotations.ToDictionary(a => a, a => 0); // Get the raw pixel difference (color sensitive) Bitmap baseline = Baseline; Bitmap current = Camera.CurrentImage; Bitmap difference = baseline.Difference( current.Add( // Adjust the current image by the average light difference // between the baseline and current image AverageDifference( baseline, current, Annotations.Where(a => a.Type == Annotation.AnnotationType.Constant ) ) ) ); // Sum up difference percentage contained by each annotation for (int x = 0; x < difference.Width; x++) { for (int y = 0; y < difference.Height; y++) { Vector2 pixelPoint = new Vector2((double)x / difference.Width, (double)y / difference.Height); foreach (Annotation annotation in Annotations.Where(a => a.Contains(pixelPoint))) { annotationPixelAreas[annotation]++; annotation.PercentDifference += difference.GetPixel(x, y).Value(); } } } // Normalize the difference percentages by dividing out the total pixel area foreach (var pixelArea in annotationPixelAreas.Where(p => p.Value > 0)) { pixelArea.Key.PercentDifference /= pixelArea.Value; } } } }