238 lines
7.5 KiB
C#
238 lines
7.5 KiB
C#
|
|
using MainShell.EventArgsFolder;
|
||
|
|
using MainShell.Log;
|
||
|
|
using MainShell.Vision;
|
||
|
|
using MwFramework.Device;
|
||
|
|
using MwFramework.Device.Model;
|
||
|
|
using Stylet;
|
||
|
|
using System;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.Linq;
|
||
|
|
|
||
|
|
using AppCameraType = MainShell.Common.CameraType;
|
||
|
|
|
||
|
|
namespace MainShell.ToolBox.ViewModel
|
||
|
|
{
|
||
|
|
public class VisionDisplayTestState : PropertyChangedBase
|
||
|
|
{
|
||
|
|
private AppCameraType _selectedCameraType = AppCameraType.TopPositionCamera;
|
||
|
|
|
||
|
|
public AppCameraType SelectedCameraType
|
||
|
|
{
|
||
|
|
get
|
||
|
|
{
|
||
|
|
return _selectedCameraType;
|
||
|
|
}
|
||
|
|
set
|
||
|
|
{
|
||
|
|
SetAndNotify(ref _selectedCameraType, value);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private bool _clearShapesBeforeDisplay = true;
|
||
|
|
|
||
|
|
public bool ClearShapesBeforeDisplay
|
||
|
|
{
|
||
|
|
get
|
||
|
|
{
|
||
|
|
return _clearShapesBeforeDisplay;
|
||
|
|
}
|
||
|
|
set
|
||
|
|
{
|
||
|
|
SetAndNotify(ref _clearShapesBeforeDisplay, value);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private string _statusMessage = "请选择主界面相机区域后发送测试事件。";
|
||
|
|
|
||
|
|
public string StatusMessage
|
||
|
|
{
|
||
|
|
get
|
||
|
|
{
|
||
|
|
return _statusMessage;
|
||
|
|
}
|
||
|
|
set
|
||
|
|
{
|
||
|
|
SetAndNotify(ref _statusMessage, value);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public class VisionDisplayTestViewModel : PropertyChangedBase
|
||
|
|
{
|
||
|
|
private const int ImageWidth = 320;
|
||
|
|
private const int ImageHeight = 240;
|
||
|
|
private readonly IEventAggregator _eventAggregator;
|
||
|
|
private readonly VisionDisplayTestState _state;
|
||
|
|
private readonly AppCameraType[] _cameraTypes;
|
||
|
|
|
||
|
|
public VisionDisplayTestState State
|
||
|
|
{
|
||
|
|
get
|
||
|
|
{
|
||
|
|
return _state;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public IEnumerable<AppCameraType> CameraTypes
|
||
|
|
{
|
||
|
|
get
|
||
|
|
{
|
||
|
|
return _cameraTypes;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public VisionDisplayTestViewModel(IEventAggregator eventAggregator)
|
||
|
|
{
|
||
|
|
_eventAggregator = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator));
|
||
|
|
_state = new VisionDisplayTestState();
|
||
|
|
_cameraTypes = Enum.GetValues(typeof(AppCameraType)).Cast<AppCameraType>().ToArray();
|
||
|
|
}
|
||
|
|
|
||
|
|
public void SendImageEvent()
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
CameraData cameraData = CreateTestCameraData();
|
||
|
|
DisplayImageEventArgs message = new DisplayImageEventArgs(State.SelectedCameraType, cameraData);
|
||
|
|
_eventAggregator.Publish(message);
|
||
|
|
State.StatusMessage = $"已发送图片事件到 {State.SelectedCameraType},请查看主界面相机区域。";
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
State.StatusMessage = $"发送图片事件失败:{ex.Message}";
|
||
|
|
($"VisionDisplayTestViewModel.SendImageEvent exception: {ex}").LogSysError();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public void SendDisplayEvent()
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
FindTemplateResult result = CreateTestTemplateResult();
|
||
|
|
DisplayFindTemplateResultEventArgs message = new DisplayFindTemplateResultEventArgs(
|
||
|
|
State.SelectedCameraType,
|
||
|
|
result,
|
||
|
|
State.ClearShapesBeforeDisplay);
|
||
|
|
_eventAggregator.Publish(message);
|
||
|
|
State.StatusMessage = $"已发送结果显示事件到 {State.SelectedCameraType},请查看主界面图形叠加。";
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
State.StatusMessage = $"发送结果显示事件失败:{ex.Message}";
|
||
|
|
($"VisionDisplayTestViewModel.SendDisplayEvent exception: {ex}").LogSysError();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public void ClearDisplayEvent()
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
DisplayFindTemplateResultEventArgs message = new DisplayFindTemplateResultEventArgs(
|
||
|
|
State.SelectedCameraType,
|
||
|
|
null,
|
||
|
|
true);
|
||
|
|
_eventAggregator.Publish(message);
|
||
|
|
State.StatusMessage = $"已清空 {State.SelectedCameraType} 的图形叠加。";
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
State.StatusMessage = $"清空结果显示失败:{ex.Message}";
|
||
|
|
($"VisionDisplayTestViewModel.ClearDisplayEvent exception: {ex}").LogSysError();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static CameraData CreateTestCameraData()
|
||
|
|
{
|
||
|
|
byte[] buffer = new byte[ImageWidth * ImageHeight * 3];
|
||
|
|
|
||
|
|
for (int y = 0; y < ImageHeight; y++)
|
||
|
|
{
|
||
|
|
for (int x = 0; x < ImageWidth; x++)
|
||
|
|
{
|
||
|
|
int offset = ((y * ImageWidth) + x) * 3;
|
||
|
|
buffer[offset] = (byte)((x * 255) / ImageWidth);
|
||
|
|
buffer[offset + 1] = (byte)((y * 255) / ImageHeight);
|
||
|
|
buffer[offset + 2] = 40;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
AddCrossMark(buffer, ImageWidth / 2, ImageHeight / 2, 36, 255, 255, 255);
|
||
|
|
|
||
|
|
CameraData cameraData = new CameraData(
|
||
|
|
buffer,
|
||
|
|
(uint)ImageWidth,
|
||
|
|
(uint)ImageHeight,
|
||
|
|
CustomPixelFormat.Rgb8Packed,
|
||
|
|
0L,
|
||
|
|
DateTime.Now,
|
||
|
|
false);
|
||
|
|
cameraData.Bit = 3;
|
||
|
|
return cameraData;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void AddCrossMark(byte[] buffer, int centerX, int centerY, int halfLength, byte blue, byte green, byte red)
|
||
|
|
{
|
||
|
|
for (int offsetX = -halfLength; offsetX <= halfLength; offsetX++)
|
||
|
|
{
|
||
|
|
SetPixel(buffer, centerX + offsetX, centerY, blue, green, red);
|
||
|
|
}
|
||
|
|
|
||
|
|
for (int offsetY = -halfLength; offsetY <= halfLength; offsetY++)
|
||
|
|
{
|
||
|
|
SetPixel(buffer, centerX, centerY + offsetY, blue, green, red);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void SetPixel(byte[] buffer, int x, int y, byte blue, byte green, byte red)
|
||
|
|
{
|
||
|
|
if (x < 0 || x >= ImageWidth || y < 0 || y >= ImageHeight)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
int offset = ((y * ImageWidth) + x) * 3;
|
||
|
|
buffer[offset] = blue;
|
||
|
|
buffer[offset + 1] = green;
|
||
|
|
buffer[offset + 2] = red;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static FindTemplateResult CreateTestTemplateResult()
|
||
|
|
{
|
||
|
|
FindTemplateResult result = new FindTemplateResult();
|
||
|
|
result.CenterX = 160d;
|
||
|
|
result.CenterY = 120d;
|
||
|
|
result.Score = 0.987d;
|
||
|
|
result.Contour = new FindTemplateContourResult
|
||
|
|
{
|
||
|
|
StartX = 90d,
|
||
|
|
StartY = 70d,
|
||
|
|
EndX = 230d,
|
||
|
|
EndY = 170d
|
||
|
|
};
|
||
|
|
|
||
|
|
result.Circles.Add(new FindTemplateCircleResult
|
||
|
|
{
|
||
|
|
CenterX = 160d,
|
||
|
|
CenterY = 120d,
|
||
|
|
Radius = 24d
|
||
|
|
});
|
||
|
|
result.Lines.Add(new FindTemplateLineResult
|
||
|
|
{
|
||
|
|
StartX = 80d,
|
||
|
|
StartY = 40d,
|
||
|
|
EndX = 260d,
|
||
|
|
EndY = 200d
|
||
|
|
});
|
||
|
|
result.Rectangles.Add(new FindTemplateRectangleResult
|
||
|
|
{
|
||
|
|
StartX = 110d,
|
||
|
|
StartY = 85d,
|
||
|
|
Width = 90d,
|
||
|
|
Height = 48d,
|
||
|
|
Angle = Math.PI / 9d
|
||
|
|
});
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|