Skip to content

Commit

Permalink
* MaskManager now keeps the threshold percent as a whole number to be…
Browse files Browse the repository at this point in the history
… consistent with UI settings, and makes sure to update the camera name and threshold percent on every save/load just in case they have changed. This may help with weirdness around existing masks not always matching static ones when you think they should.

* Add LastSeenDate to dynamic mask lists
* Default sorting in Mask Detail dialog is newest at top
  • Loading branch information
VorlonCD committed Sep 11, 2020
1 parent 2b32632 commit 9922a62
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 27 deletions.
16 changes: 11 additions & 5 deletions src/UI/Frm_DynamicMaskDetails.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@ private void Frm_DynamicMaskDetails_Load(object sender, EventArgs e)
{
loading = true;

Global_GUI.ConfigureFOLV(ref FOLV_MaskHistory, typeof(ObjectPosition), null, null);
Global_GUI.ConfigureFOLV(ref FOLV_Masks, typeof(ObjectPosition), null, null);
Global_GUI.ConfigureFOLV(ref FOLV_MaskHistory, typeof(ObjectPosition), null, null, "createDate", SortOrder.Descending);
Global_GUI.ConfigureFOLV(ref FOLV_Masks, typeof(ObjectPosition), null, null, "createDate", SortOrder.Descending);

Global_GUI.RestoreWindowState(this);

Expand Down Expand Up @@ -419,6 +419,8 @@ private void FOLV_MaskHistory_SelectionChanged(object sender, EventArgs e)
if (FOLV_MaskHistory.SelectedObjects != null && FOLV_MaskHistory.SelectedObjects.Count > 0)
{
contextMenuPosObj = (ObjectPosition)FOLV_MaskHistory.SelectedObject;
this.cam = AITOOL.GetCamera(contextMenuPosObj.cameraName);

ShowMaskImage();

foreach (object obj in FOLV_MaskHistory.SelectedObjects)
Expand All @@ -437,6 +439,8 @@ private void FOLV_Masks_SelectionChanged(object sender, EventArgs e)
if (FOLV_Masks.SelectedObjects != null && FOLV_Masks.SelectedObjects.Count > 0)
{
contextMenuPosObj = (ObjectPosition)FOLV_Masks.SelectedObject;
this.cam = AITOOL.GetCamera(contextMenuPosObj.cameraName);

ShowMaskImage();

foreach (object obj in FOLV_Masks.SelectedObjects)
Expand Down Expand Up @@ -481,6 +485,7 @@ private void FOLV_MaskHistory_CellRightClick(object sender, BrightIdeasSoftware.
if (e.Model != null)
{
contextMenuPosObj = (ObjectPosition)e.Model;
this.cam = AITOOL.GetCamera(contextMenuPosObj.cameraName);
}
}

Expand Down Expand Up @@ -608,7 +613,8 @@ private void BtnDynamicMaskingSettings_Click(object sender, EventArgs e)
frm.num_history_mins.Value = cam.maskManager.history_save_mins;//load minutes to retain history objects that have yet to become masks
frm.num_mask_create.Value = cam.maskManager.history_threshold_count; // load mask create counter
frm.num_mask_remove.Value = cam.maskManager.mask_counter_default; //load mask remove counter
frm.num_percent_var.Value = (decimal)cam.maskManager.thresholdPercent * 100;
//frm.num_percent_var.Value = (decimal)cam.maskManager.thresholdPercent * 100;
frm.num_percent_var.Value = (decimal)cam.maskManager.thresholdPercent;

frm.cb_enabled.Checked = cam.maskManager.masking_enabled;

Expand All @@ -623,12 +629,12 @@ private void BtnDynamicMaskingSettings_Click(object sender, EventArgs e)
Int32.TryParse(frm.num_percent_var.Text, out int variance);

////convert to percent
Double percent_variance = (double)variance / 100;
//Double percent_variance = (double)variance / 100;

cam.maskManager.history_save_mins = history_mins;
cam.maskManager.history_threshold_count = mask_create_counter;
cam.maskManager.mask_counter_default = mask_remove_counter;
cam.maskManager.thresholdPercent = percent_variance;
cam.maskManager.thresholdPercent = variance;

cam.maskManager.masking_enabled = frm.cb_enabled.Checked;

Expand Down
6 changes: 3 additions & 3 deletions src/UI/Global.cs
Original file line number Diff line number Diff line change
Expand Up @@ -983,10 +983,9 @@ public static bool GetDateStrict(string InpDate, ref DateTime OutDate)
{
CreateFormatList();
}
int CurCnt = 0;
foreach (ClsDateFormat df in DateFormatList)
for (int i = 0; i < DateFormatList.Count; i++)
{
CurCnt = CurCnt + 1;
ClsDateFormat df = DateFormatList[i];
Ret = DateTime.TryParseExact(InpDate, df.Fmt, null, System.Globalization.DateTimeStyles.None, out OutDate); //New CultureInfo("en-US")
if (Ret)
{
Expand All @@ -1006,6 +1005,7 @@ public static bool GetDateStrict(string InpDate, ref DateTime OutDate)
Ret = false;
}
}

}

if (!Ret)
Expand Down
78 changes: 78 additions & 0 deletions src/UI/MaskManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,72 @@ public MaskManager()
cleanHistoryTimer.Interval = 60000; // 1min = 60,000ms
}

public void Update(Camera cam)
{
//This will run on save/load settings

//lets store thresholdpercent as the same value the user sees in UI for easier troubleshooting in mask dialog
if (this.thresholdPercent < 1)
{
this.thresholdPercent = this.thresholdPercent * 100;
}

foreach (ObjectPosition op in this.last_positions_history)
{
//Update threshold since it could have been changed since mask created
op.thresholdPercent = this.thresholdPercent;
//update the camera name since it could have been renamed since the mask was created
op.cameraName = cam.name;
//update last seen date if hasnt been set
if (op.LastSeenDate == DateTime.MinValue)
{
op.LastSeenDate = op.createDate;
}
//if null image from older build, force to have the last image from the camera:
if (op.imagePath == null || string.IsNullOrEmpty(op.imagePath))
{
//first, set to empty string rather than null to fix bug I saw
op.imagePath = "";
//next, fill with most recent image with detections
if (!string.IsNullOrEmpty(cam.last_image_file_with_detections))
{
op.imagePath = cam.last_image_file_with_detections;
}
else if (!string.IsNullOrEmpty(cam.last_image_file))
{
op.imagePath = cam.last_image_file;
}
}
}
foreach (ObjectPosition op in this.masked_positions)
{
//Update threshold since it could have been changed since mask created
op.thresholdPercent = this.thresholdPercent;
//update the camera name since it could have been renamed since the mask was created
op.cameraName = cam.name;
//update last seen date if hasnt been set
if (op.LastSeenDate == DateTime.MinValue)
{
op.LastSeenDate = op.createDate;
}
//if null image from older build, force to have the last image from the camera:
if (op.imagePath == null || string.IsNullOrEmpty(op.imagePath))
{
//first, set to empty string rather than null to fix bug I saw
op.imagePath = "";
//next, fill with most recent image with detections
if (!string.IsNullOrEmpty(cam.last_image_file_with_detections))
{
op.imagePath = cam.last_image_file_with_detections;
}
else if (!string.IsNullOrEmpty(cam.last_image_file))
{
op.imagePath = cam.last_image_file;
}
}
}
}

public bool CreateDynamicMask(ObjectPosition currentObject)
{
bool maskExists = false;
Expand All @@ -58,6 +124,12 @@ public bool CreateDynamicMask(ObjectPosition currentObject)
int indexLoc = last_positions_history.IndexOf(currentObject);
ObjectPosition foundObject = last_positions_history[indexLoc];

foundObject.LastSeenDate = DateTime.Now;

//Update last image that has same detection, and camera name found for existing mask
foundObject.imagePath = currentObject.imagePath;
foundObject.cameraName = currentObject.cameraName;

Global.Log("Found in last_positions_history: " + foundObject.ToString() + " for camera: " + currentObject.cameraName);

if (foundObject.counter < history_threshold_count)
Expand All @@ -77,6 +149,12 @@ public bool CreateDynamicMask(ObjectPosition currentObject)
{
ObjectPosition maskedObject = (ObjectPosition)masked_positions[masked_positions.IndexOf(currentObject)];

maskedObject.LastSeenDate = DateTime.Now;

//Update last image that has same detection, and camera name found for existing mask
maskedObject.imagePath = currentObject.imagePath;
maskedObject.cameraName = currentObject.cameraName;

if (maskedObject.counter < mask_counter_default)
{
maskedObject.counter++;
Expand Down
17 changes: 11 additions & 6 deletions src/UI/ObjectPosition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@ public class ObjectPosition:IEquatable<ObjectPosition>
{
public string label { get; } = "";
public DateTime createDate { get; set; }
public DateTime LastSeenDate { get; set; } = DateTime.MinValue;

public int counter { get; set; }
public double thresholdPercent { get; set; }
public Boolean isStatic { get; set; } = false;
public int xmin { get; }
public int ymin { get; }
public int xmax { get; }
public int ymax { get; }
public int height { get; }
public int width { get; }
public double thresholdPercent { get; set; }
public Boolean isStatic { get; set; } = false;
public long key { get; }
public int imageWidth { get; set; }
public int imageHeight { get; set; }
Expand Down Expand Up @@ -62,11 +64,14 @@ public bool Equals(ObjectPosition other)
double xPercentVariance = (double)(Math.Abs(this.xmin - other.xmin)) / imageWidth;
double yPercentVariance = (double)(Math.Abs(this.ymin - other.ymin)) / imageHeight;

//convert whole number to percent
double percent = thresholdPercent / 100;

return (other != null &&
(xPercentVariance <= thresholdPercent) &&
(yPercentVariance <= thresholdPercent) &&
(widthVariance <= thresholdPercent) &&
(heightVariance <= thresholdPercent));
(xPercentVariance <= percent) &&
(yPercentVariance <= percent) &&
(widthVariance <= percent) &&
(heightVariance <= percent));
}

public override int GetHashCode()
Expand Down
15 changes: 13 additions & 2 deletions src/UI/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using System.Diagnostics;
using System.Threading;
using SixLabors.ImageSharp;
using System.Collections.ObjectModel;

namespace AITool
{
Expand Down Expand Up @@ -106,6 +107,12 @@ public static bool Save()
File.Delete(AppSettings.Settings.SettingsFileName);
}

//update threshold in all masks if changed during session
foreach (Camera cam in AppSettings.Settings.CameraList)
{
cam.maskManager.Update(cam);
}

Settings.SettingsValid = true;
String CurSettingsJSON = Global.WriteToJsonFile<ClsSettings>(AppSettings.Settings.SettingsFileName, Settings);

Expand Down Expand Up @@ -337,8 +344,12 @@ public static bool Load()
cam.maskManager = new MaskManager();
Global.Log("Warning: Had to reset MaskManager for camera " + cam.name);
}
}


//update threshold in all masks if changed during session
cam.maskManager.Update(cam);

}

//load cameras the old way if needed
if (Settings.CameraList.Count == 0)
{
Expand Down
16 changes: 5 additions & 11 deletions src/UI/Shell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2607,14 +2607,7 @@ private void button1_Click(object sender, EventArgs e)

private void Chk_AutoScroll_CheckedChanged(object sender, EventArgs e)
{
if (Chk_AutoScroll.Checked)
{
RTFLogger.AutoScroll = true;
}
else
{
RTFLogger.AutoScroll = false;
}
RTFLogger.AutoScroll = Chk_AutoScroll.Checked;
}

private void tableLayoutPanel7_Paint(object sender, PaintEventArgs e)
Expand Down Expand Up @@ -2654,7 +2647,8 @@ private void BtnDynamicMaskingSettings_Click(object sender, EventArgs e)
frm.num_history_mins.Value = cam.maskManager.history_save_mins;//load minutes to retain history objects that have yet to become masks
frm.num_mask_create.Value = cam.maskManager.history_threshold_count; // load mask create counter
frm.num_mask_remove.Value = cam.maskManager.mask_counter_default; //load mask remove counter
frm.num_percent_var.Value = (decimal)cam.maskManager.thresholdPercent * 100;
//frm.num_percent_var.Value = (decimal)cam.maskManager.thresholdPercent * 100;
frm.num_percent_var.Value = (decimal)cam.maskManager.thresholdPercent;

frm.cb_enabled.Checked = this.cb_masking_enabled.Checked;

Expand All @@ -2669,12 +2663,12 @@ private void BtnDynamicMaskingSettings_Click(object sender, EventArgs e)
Int32.TryParse(frm.num_percent_var.Text, out int variance);

////convert to percent
Double percent_variance = (double)variance / 100;
//Double percent_variance = (double)variance / 100;

cam.maskManager.history_save_mins = history_mins;
cam.maskManager.history_threshold_count = mask_create_counter;
cam.maskManager.mask_counter_default = mask_remove_counter;
cam.maskManager.thresholdPercent = percent_variance;
cam.maskManager.thresholdPercent = variance;

this.cb_masking_enabled.Checked = frm.cb_enabled.Checked;

Expand Down

0 comments on commit 9922a62

Please sign in to comment.