|
|
@@ -33,8 +33,7 @@ namespace CCDCount.DLL
|
|
|
private List<int> _ChannelsRoi = new List<int>();
|
|
|
private int ChannelWidth = 0;//每个区域的宽度
|
|
|
private int IdentifyImageWidth = -1;
|
|
|
- private static readonly object _lockObj = new object(); // 专用锁对象\
|
|
|
- private static readonly object taskLock = new object(); // 异步专用锁
|
|
|
+ private static readonly object _lockObj = new object(); // 专用锁对象
|
|
|
private int ObjectNum = 0;
|
|
|
public int ImageNum { get { return IFrameDatas.Count; } }
|
|
|
#endregion
|
|
|
@@ -126,7 +125,6 @@ namespace CCDCount.DLL
|
|
|
item.Num = ObjectNum += 1;
|
|
|
item.ChannelNO = ActiveChannel(item);
|
|
|
item.EndCheckTime = DateTime.Now;
|
|
|
- OneActive.Add(item);
|
|
|
item.MaxLength = GetActionMaxLength(item.RowsData);
|
|
|
if ((item.LastSeenLine - item.StartLine) > shuLiConfig.MAX_Idetify_Height)
|
|
|
{
|
|
|
@@ -179,6 +177,7 @@ namespace CCDCount.DLL
|
|
|
Console.WriteLine("颗粒编号{0}:正常粒", item.Num);
|
|
|
}
|
|
|
}
|
|
|
+ OneActive.Add(item);
|
|
|
}
|
|
|
|
|
|
if (OneActive.Count > 0)
|
|
|
@@ -424,14 +423,90 @@ namespace CCDCount.DLL
|
|
|
}
|
|
|
IsPrintLightOnError = false;
|
|
|
}
|
|
|
+ lock (_lockObj)
|
|
|
+ {
|
|
|
+ foreach (var region in currentRegions)
|
|
|
+ {
|
|
|
+ // 查找全部可合并的活跃物体(有重叠+在允许间隔内)
|
|
|
+ var matcheds = activeObjects.Where(o =>
|
|
|
+ IsOverlapping(o, region) &&
|
|
|
+ (currentLine - o.LastSeenLine - 1) <= shuLiConfig.MAX_GAP).ToList();
|
|
|
+ //当有多个可合并的活跃物体时,将多个物体合并
|
|
|
+ if (matcheds.Count >= 2)
|
|
|
+ {
|
|
|
+ // 合并有效区域队列
|
|
|
+ var CopeRowsData = new List<RowStartEndCol>();
|
|
|
+ matcheds.ForEach(o => CopeRowsData = CopeRowsData.Concat(o.RowsData).ToList());
|
|
|
+ // 合并有效区域并保存在新的区域中
|
|
|
+ var MergeMatched = new ActiveObjectClass
|
|
|
+ {
|
|
|
+ MinStartCol = matcheds.Min(o => o.MinStartCol),
|
|
|
+ MaxEndCol = matcheds.Max(o => o.MaxEndCol),
|
|
|
+ StartLine = matcheds.Min(o => o.StartLine),
|
|
|
+ LastSeenLine = matcheds.Max(o => o.LastSeenLine),
|
|
|
+ LastSeenLineStartCol = matcheds.Min(o => o.LastSeenLineStartCol),
|
|
|
+ LastSeenLineEndCol = matcheds.Max(o => o.LastSeenLineEndCol),
|
|
|
+ StartCheckTime = matcheds.Min(o => o.StartCheckTime),
|
|
|
+ EndCheckTime = matcheds.Max(o => o.EndCheckTime),
|
|
|
+ Area = matcheds.Sum(o => o.Area),
|
|
|
+ RowsData = CopeRowsData,
|
|
|
+ ImageWidth = matcheds.FirstOrDefault().ImageWidth,
|
|
|
+ //StateCode = 8
|
|
|
+ };
|
|
|
+ // 从活跃区域中删除被合并的区域
|
|
|
+ matcheds.ForEach(o => activeObjects.Remove(o));
|
|
|
+ // 保存新的区域到活跃区域中
|
|
|
+ activeObjects.Add(MergeMatched);
|
|
|
+ }
|
|
|
|
|
|
- MergeCurrentRegions(currentRegions);
|
|
|
+ // 搜获可用且可合并的活跃区域
|
|
|
+ var matched = activeObjects.FirstOrDefault(o =>
|
|
|
+ IsOverlapping(o, region) &&
|
|
|
+ (currentLine - o.LastSeenLine - 1) <= shuLiConfig.MAX_GAP);
|
|
|
+ if (matched != null)
|
|
|
+ {
|
|
|
+ // 合并区域:扩展物体边界并更新状态
|
|
|
+ matched.MinStartCol = Math.Min(matched.MinStartCol, region.Start);
|
|
|
+ matched.MaxEndCol = Math.Max(matched.MaxEndCol, region.End);
|
|
|
+ matched.Area += region.End - region.Start + 1;
|
|
|
+ matched.LastSeenLine = currentLine;
|
|
|
+ matched.RowsData.Add(new RowStartEndCol
|
|
|
+ {
|
|
|
+ StartCol = region.Start,
|
|
|
+ EndCol = region.End,
|
|
|
+ RowsCol = currentLine,
|
|
|
+ });
|
|
|
+ matched.LastSeenLineStartCol = region.Start;
|
|
|
+ matched.LastSeenLineEndCol = region.End;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // 创建新物体(首次出现的区域)
|
|
|
+ activeObjects.Add(new ActiveObjectClass
|
|
|
+ {
|
|
|
+ MinStartCol = region.Start,
|
|
|
+ MaxEndCol = region.End,
|
|
|
+ StartLine = currentLine,
|
|
|
+ LastSeenLine = currentLine,
|
|
|
+ LastSeenLineStartCol = region.Start,
|
|
|
+ LastSeenLineEndCol = region.End,
|
|
|
+ StartCheckTime = DateTime.Now,
|
|
|
+ Area = region.End - region.Start + 1,
|
|
|
+ ImageWidth = IdentifyImageWidth,
|
|
|
+ RowsData = new List<RowStartEndCol> {
|
|
|
+ new RowStartEndCol {
|
|
|
+ StartCol = region.Start,
|
|
|
+ EndCol = region.End,
|
|
|
+ RowsCol = currentLine,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
currentRegions.Clear();
|
|
|
- // 更新有效物体的最后一行的起始点
|
|
|
- activeObjects.Where(o => o.LastSeenLine == currentLine).ToList().ForEach(o => o.LastSeenLineStartCol = o.RowsData.Where(p => p.RowsCol == currentLine).Min(p => p.StartCol));
|
|
|
- activeObjects.Where(o => o.LastSeenLine == currentLine).ToList().ForEach(o => o.LastSeenLineEndCol = o.RowsData.Where(p => p.RowsCol == currentLine).Max(p => p.EndCol));
|
|
|
-
|
|
|
+
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
@@ -460,7 +535,7 @@ namespace CCDCount.DLL
|
|
|
{
|
|
|
regions.Add(new ValidRegionModelClass()
|
|
|
{
|
|
|
- Start = start,
|
|
|
+ Start = start,
|
|
|
End = (i - 1) % (int)image.Width
|
|
|
}); // 记录有效区域
|
|
|
}
|
|
|
@@ -481,9 +556,9 @@ namespace CCDCount.DLL
|
|
|
// 检查区域宽度是否达标
|
|
|
if (i - start >= shuLiConfig.MIN_OBJECT_WIDTH)
|
|
|
{
|
|
|
- regions.Add(new ValidRegionModelClass()
|
|
|
+ regions.Add(new ValidRegionModelClass()
|
|
|
{
|
|
|
- Start = start,
|
|
|
+ Start = start,
|
|
|
End = (i - 1) % (int)image.Width
|
|
|
}); // 记录有效区域
|
|
|
}
|
|
|
@@ -496,7 +571,8 @@ namespace CCDCount.DLL
|
|
|
// 处理行尾未闭合的区域
|
|
|
if (start != -1 && image.Width - start >= shuLiConfig.MIN_OBJECT_WIDTH)
|
|
|
{
|
|
|
- regions.Add(new ValidRegionModelClass() {
|
|
|
+ regions.Add(new ValidRegionModelClass()
|
|
|
+ {
|
|
|
Start = start,
|
|
|
End = (int)image.Width - 1
|
|
|
});
|
|
|
@@ -510,7 +586,7 @@ namespace CCDCount.DLL
|
|
|
/// <param name="obj">活跃物体</param>
|
|
|
/// <param name="region">当前区域</param>
|
|
|
/// <returns>是否发生重叠</returns>
|
|
|
- private bool IsOverlapping(ActiveObjectClass obj,ValidRegionModelClass region)
|
|
|
+ private bool IsOverlapping(ActiveObjectClass obj, ValidRegionModelClass region)
|
|
|
{
|
|
|
// 判断区域是否不相交的逆条件
|
|
|
return !(region.End < obj.LastSeenLineStartCol || region.Start > obj.LastSeenLineEndCol);
|
|
|
@@ -648,119 +724,6 @@ namespace CCDCount.DLL
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
-
|
|
|
- private bool MergeCurrentRegions(List<ValidRegionModelClass> validRegions)
|
|
|
- {
|
|
|
- bool Result = false;
|
|
|
- ExecuteAsyncOperations(validRegions).GetAwaiter().GetResult();
|
|
|
- return Result;
|
|
|
- }
|
|
|
-
|
|
|
- private async Task ExecuteAsyncOperations(List<ValidRegionModelClass> validRegions)
|
|
|
- {
|
|
|
- // 创建异步操作任务列表
|
|
|
- var tasks = new List<Task<string>>();
|
|
|
- for (int i = 0; i < validRegions.Count; i++)
|
|
|
- {
|
|
|
- tasks.Add(AsyncOperation(validRegions[i],i));
|
|
|
- }
|
|
|
-
|
|
|
- try
|
|
|
- {
|
|
|
- // 等待所有异步操作完成
|
|
|
- var results = await Task.WhenAll(tasks);
|
|
|
- Console.WriteLine($"All operations completed: [{string.Join(", ", results)}]");
|
|
|
- }
|
|
|
- catch (Exception ex)
|
|
|
- {
|
|
|
- Console.WriteLine($"One or more operations failed: {ex.Message}");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private async Task<string> AsyncOperation(ValidRegionModelClass region,int i)
|
|
|
- {
|
|
|
- // 模拟异步操作,比如网络请求或I/O操作
|
|
|
- await Task.Run(() => {
|
|
|
- lock(taskLock)
|
|
|
- {
|
|
|
- // 查找全部可合并的活跃物体(有重叠+在允许间隔内)
|
|
|
- var matcheds = activeObjects.Where(o =>
|
|
|
- IsOverlapping(o, region) &&
|
|
|
- (currentLine - o.LastSeenLine - 1) <= shuLiConfig.MAX_GAP).ToList();
|
|
|
- //当有多个可合并的活跃物体时,将多个物体合并
|
|
|
- if (matcheds.Count >= 2)
|
|
|
- {
|
|
|
- // 合并有效区域队列
|
|
|
- var CopeRowsData = new List<RowStartEndCol>();
|
|
|
- matcheds.ForEach(o => CopeRowsData = CopeRowsData.Concat(o.RowsData).ToList());
|
|
|
- // 合并有效区域并保存在新的区域中
|
|
|
- var MergeMatched = new ActiveObjectClass
|
|
|
- {
|
|
|
- MinStartCol = matcheds.Min(o => o.MinStartCol),
|
|
|
- MaxEndCol = matcheds.Max(o => o.MaxEndCol),
|
|
|
- StartLine = matcheds.Min(o => o.StartLine),
|
|
|
- LastSeenLine = matcheds.Max(o => o.LastSeenLine),
|
|
|
- LastSeenLineStartCol = matcheds.Min(o => o.LastSeenLineStartCol),
|
|
|
- LastSeenLineEndCol = matcheds.Max(o => o.LastSeenLineEndCol),
|
|
|
- StartCheckTime = matcheds.Min(o => o.StartCheckTime),
|
|
|
- EndCheckTime = matcheds.Max(o => o.EndCheckTime),
|
|
|
- Area = matcheds.Sum(o => o.Area),
|
|
|
- RowsData = CopeRowsData,
|
|
|
- ImageWidth = matcheds.FirstOrDefault().ImageWidth,
|
|
|
- //StateCode = 8
|
|
|
- };
|
|
|
- // 从活跃区域中删除被合并的区域
|
|
|
- matcheds.ForEach(o => activeObjects.Remove(o));
|
|
|
- // 保存新的区域到活跃区域中
|
|
|
- activeObjects.Add(MergeMatched);
|
|
|
- }
|
|
|
-
|
|
|
- // 搜获可用且可合并的活跃区域
|
|
|
- var matched = activeObjects.FirstOrDefault(o =>
|
|
|
- IsOverlapping(o, region) &&
|
|
|
- (currentLine - o.LastSeenLine - 1) <= shuLiConfig.MAX_GAP);
|
|
|
- if (matched != null)
|
|
|
- {
|
|
|
- // 合并区域:扩展物体边界并更新状态
|
|
|
- matched.MinStartCol = Math.Min(matched.MinStartCol, region.Start);
|
|
|
- matched.MaxEndCol = Math.Max(matched.MaxEndCol, region.End);
|
|
|
- matched.Area += region.End - region.Start + 1;
|
|
|
- matched.LastSeenLine = currentLine;
|
|
|
- matched.RowsData.Add(new RowStartEndCol
|
|
|
- {
|
|
|
- StartCol = region.Start,
|
|
|
- EndCol = region.End,
|
|
|
- RowsCol = currentLine,
|
|
|
- });
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- // 创建新物体(首次出现的区域)
|
|
|
- activeObjects.Add(new ActiveObjectClass
|
|
|
- {
|
|
|
- MinStartCol = region.Start,
|
|
|
- MaxEndCol = region.End,
|
|
|
- StartLine = currentLine,
|
|
|
- LastSeenLine = currentLine,
|
|
|
- LastSeenLineStartCol = region.Start,
|
|
|
- LastSeenLineEndCol = region.End,
|
|
|
- StartCheckTime = DateTime.Now,
|
|
|
- Area = region.End - region.Start + 1,
|
|
|
- ImageWidth = IdentifyImageWidth,
|
|
|
- RowsData = new List<RowStartEndCol> {
|
|
|
- new RowStartEndCol {
|
|
|
- StartCol = region.Start,
|
|
|
- EndCol = region.End,
|
|
|
- RowsCol = currentLine,
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- }); // 延迟
|
|
|
- Console.WriteLine($"Operation {i} completed");
|
|
|
- return $"Result {i}";
|
|
|
- }
|
|
|
#endregion
|
|
|
|
|
|
#region 线程方法
|
|
|
@@ -776,7 +739,7 @@ namespace CCDCount.DLL
|
|
|
if (IFrameDatas.Count() > 0)
|
|
|
{
|
|
|
stopwatch.Restart();
|
|
|
- if(IFrameDatas.Count()>50)
|
|
|
+ if (IFrameDatas.Count() > 50)
|
|
|
FaultLog.RecordErrorMessage($"图像数据队列中数据过多,请及时处理!当前数据数量为:{IFrameDatas.Count()}");
|
|
|
IFrameDatas.TryDequeue(out IImage IframeData);
|
|
|
//是否成功取得数据
|