You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
379 lines
9.3 KiB
379 lines
9.3 KiB
using EC.AutoWeightServer.Center;
|
|
using EC.AutoWeightServer.Model.Config;
|
|
using EC.AutoWeightServer.Model.EventArgsEx;
|
|
using EC.AutoWeightServer.SDK;
|
|
using EC.Service.Transport;
|
|
using EC.Utils;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.InteropServices;
|
|
using System.Windows.Forms;
|
|
|
|
namespace EC.AutoWeightServer.UI.UC
|
|
{
|
|
public partial class UCLicensePlate : UserControl
|
|
{
|
|
#region SDK 变量
|
|
|
|
/// <summary>
|
|
/// 相机 IP
|
|
/// </summary>
|
|
private string _ip;
|
|
|
|
/// <summary>
|
|
/// 相机 _port
|
|
/// </summary>
|
|
private ushort _port;
|
|
|
|
private string _username;
|
|
|
|
private string _password;
|
|
|
|
/// <summary>
|
|
/// 相机操作句柄
|
|
/// </summary>
|
|
private int _deviceHandle = 0;
|
|
|
|
/// <summary>
|
|
/// 相机播放句柄
|
|
/// </summary>
|
|
private int _playHandle = 0;
|
|
|
|
private VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK PlateResultCB { get; set; } = null;
|
|
|
|
#endregion SDK 变量
|
|
|
|
public UCLicensePlate()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
#region init & close
|
|
|
|
public void InitForm(string ip, ushort port, string username, string password)
|
|
{
|
|
VzClientSDK.VzLPRClient_Setup();
|
|
_ip = ip;
|
|
_port = port;
|
|
_username = username;
|
|
_password = password;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 关闭
|
|
/// </summary>
|
|
public void CloseForm()
|
|
{
|
|
timeAuto.Enabled = false;
|
|
_ip = string.Empty;
|
|
_port = 0;
|
|
_username = string.Empty;
|
|
_password = string.Empty;
|
|
ClosePlayHandle();
|
|
CloseDeviceHandle();
|
|
VzClientSDK.VzLPRClient_Cleanup();
|
|
}
|
|
|
|
#endregion init & close
|
|
|
|
#region 组件操作响应事件
|
|
|
|
private void Btn_Man_Click(object sender, EventArgs e)
|
|
{
|
|
ForceTrigger();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 定时检测相机状态
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void TimAuto_Tick(object sender, EventArgs e)
|
|
{
|
|
if (!IsDeviceConnected())
|
|
OpenDevice();
|
|
if (!IsPlayConnected())
|
|
OpenPlay();
|
|
}
|
|
|
|
#endregion 组件操作响应事件
|
|
|
|
#region get & set
|
|
|
|
public int GetDateTime()
|
|
{
|
|
var info = new VzClientSDK.VZ_DATE_TIME_INFO();
|
|
var ret = VzClientSDK.VzLPRClient_GetDateTime(_deviceHandle, ref info);
|
|
return ret;
|
|
}
|
|
|
|
public int SetDateTime()
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
public void SetBtnManVisible(bool able)
|
|
{
|
|
this.btnMan.Visible = able;
|
|
}
|
|
|
|
#endregion get & set
|
|
|
|
#region tool methods
|
|
|
|
/// <summary>
|
|
/// 打开相机连接
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool OpenDevice()
|
|
{
|
|
_deviceHandle = OpenDeviceHandle();
|
|
timeAuto.Enabled = true;
|
|
if (!IsDeviceConnected())
|
|
{
|
|
LogUnit.Info("打开设备" + _ip + "失败");
|
|
return false;
|
|
}
|
|
LogUnit.Info("打开设备" + _ip + "成功!");
|
|
|
|
return OpenPlay();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 打开相机监控
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private bool OpenPlay()
|
|
{
|
|
if (!IsDeviceConnected())
|
|
return false;
|
|
pictureBox.Image = null;
|
|
SetVzClientCallBack(null, 0);
|
|
ClosePlayHandle();
|
|
|
|
_playHandle = OpenPlayHandle();
|
|
PlateResultCB = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult);
|
|
SetVzClientCallBack(PlateResultCB, 1);
|
|
timeAuto.Enabled = true;
|
|
LogUnit.Info("开始读取车牌");
|
|
|
|
return IsPlayConnected();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 返回相机操作句柄
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private int OpenDeviceHandle()
|
|
{
|
|
return VzClientSDK.VzLPRClient_Open(_ip, _port, _username, _password);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 关闭相机操作句柄
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private bool CloseDeviceHandle()
|
|
{
|
|
if (!IsDeviceConnected())
|
|
return true;
|
|
var ret = VzClientSDK.VzLPRClient_Close(_deviceHandle);
|
|
if (!ret.Equals(0))
|
|
return false;
|
|
_deviceHandle = 0;
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 返回相机播放句柄
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private int OpenPlayHandle()
|
|
{
|
|
if (!IsDeviceConnected())
|
|
return 0;
|
|
return VzClientSDK.VzLPRClient_StartRealPlay(_deviceHandle, pictureBox.Handle);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 停止相机播放句柄
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private bool ClosePlayHandle()
|
|
{
|
|
if (!IsPlayConnected())
|
|
return true;
|
|
var ret = VzClientSDK.VzLPRClient_StopRealPlay(_playHandle);
|
|
if (!ret.Equals(0))
|
|
return false;
|
|
_playHandle = 0;
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 手动识别
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool ForceTrigger()
|
|
{
|
|
if (!IsDeviceConnected())
|
|
return false;
|
|
var ret = VzClientSDK.VzLPRClient_ForceTrigger(_deviceHandle);
|
|
return ret.Equals(0);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 截图
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetPlatePic(string license)
|
|
{
|
|
if (!IsDeviceConnected() || !IsPlayConnected())
|
|
return string.Empty;
|
|
var path = PhotoService.GetSaveImagePath(license);
|
|
var ret = VzClientSDK.VzLPRClient_GetSnapShootToJpeg2(_playHandle, path, 90);
|
|
return ret.Equals(0) ? path : string.Empty;
|
|
}
|
|
|
|
/// <summary>
|
|
/// func 识别结果回调函数
|
|
/// bEnableImage 指定识别结果的回调是否需要包含截图信息:1为需要,0为不需要
|
|
/// </summary>
|
|
/// <param name="func"></param>
|
|
/// <param name="bEnableImage"></param>
|
|
/// <returns></returns>
|
|
private bool SetVzClientCallBack(VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK func, int bEnableImage)
|
|
{
|
|
if (!IsDeviceConnected())
|
|
return false;
|
|
var ret = VzClientSDK.VzLPRClient_SetPlateInfoCallBack(_deviceHandle, func, IntPtr.Zero, bEnableImage);
|
|
return ret.Equals(0);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取相机连接状态,判断 _deviceHandle 是否有效
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool IsDeviceConnected()
|
|
{
|
|
if (_deviceHandle == -1)
|
|
return false;
|
|
if (_deviceHandle <= 0)
|
|
return false;
|
|
byte stat = 0;
|
|
var ret = VzClientSDK.VzLPRClient_IsConnected(_deviceHandle, ref stat);
|
|
return (ret.Equals(0) && stat.Equals(1));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取相机播放状态,判断 _playHandle 是否有效
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool IsPlayConnected()
|
|
{
|
|
if (!IsDeviceConnected())
|
|
return false;
|
|
if (_playHandle <= 0)
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
#endregion tool methods
|
|
|
|
#region 向外暴露一个可以处理 抓获车牌结果 的委托
|
|
|
|
/// <summary>
|
|
/// 处理相机结果的回调事件
|
|
/// </summary>
|
|
/// <param name="handle"></param>
|
|
/// <param name="pUserData"></param>
|
|
/// <param name="pResult"></param>
|
|
/// <param name="uNumPlates"></param>
|
|
/// <param name="eResultType"></param>
|
|
/// <param name="pImgFull"></param>
|
|
/// <param name="pImgPlateClip"></param>
|
|
/// <returns></returns>
|
|
private int OnPlateResult(int handle, IntPtr pUserData, IntPtr pResult, uint uNumPlates,
|
|
VzClientSDK.VZ_LPRC_RESULT_TYPE eResultType, IntPtr pImgFull, IntPtr pImgPlateClip)
|
|
{
|
|
//如果是实时识别结果,则return,需要稳定识别结果
|
|
if (eResultType == VzClientSDK.VZ_LPRC_RESULT_TYPE.VZ_LPRC_RESULT_REALTIME)
|
|
return -1;
|
|
|
|
var result = (VzClientSDK.TH_PlateResult)Marshal.PtrToStructure(pResult, typeof(VzClientSDK.TH_PlateResult));
|
|
var strLicense = new string(result.license).Replace("\0", "");
|
|
var strColor = new string(result.color).Replace("\0", "");
|
|
|
|
strLicense = PretreatPlate(strLicense);
|
|
|
|
//判断识别车牌是否为正常车牌
|
|
if (!CommonUtil.IsSuccessPlate(strLicense))
|
|
return -1;
|
|
|
|
//判断定时手动检测结果
|
|
if (eResultType == VzClientSDK.VZ_LPRC_RESULT_TYPE.VZ_LPRC_RESULT_FORCE_TRIGGER)
|
|
{
|
|
var truck = ServiceCenter.TruckService.SelectEntityByWhere($"LicensePlate = '{strLicense}'");
|
|
if (truck == null)
|
|
return -1;
|
|
}
|
|
|
|
var path = PhotoService.GetSaveImagePath(strLicense);// strFilePath + fileName;
|
|
VzClientSDK.VzLPRClient_ImageSaveToJpeg(pImgFull, path, 100);
|
|
|
|
LogUnit.Info("车牌 " + strLicense + " " + strColor + " " + path);
|
|
|
|
// 添加 向外暴露的 处理相机结果 的函数
|
|
PlateCallBack(strLicense, strColor, path);
|
|
|
|
return 0;
|
|
}
|
|
|
|
private void PlateCallBack(string plate, string platecolor, string filename)
|
|
{
|
|
PlateInfoCallBack?.Invoke(this, new PlateEventArgs(plate, platecolor, filename));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 一个可以处理 抓获车牌结果 的事件
|
|
/// </summary>
|
|
public event EventHandler<PlateEventArgs> PlateInfoCallBack; //定义一个委托类型的事件
|
|
|
|
#endregion 向外暴露一个可以处理 抓获车牌结果 的委托
|
|
|
|
#region Other
|
|
|
|
/// <summary>
|
|
/// 车牌预处理
|
|
/// </summary>
|
|
public string PretreatPlate(string oldPlate)
|
|
{
|
|
oldPlate = oldPlate.ToUpper();
|
|
if (oldPlate.Length < 7)
|
|
return oldPlate;
|
|
var newPlate = oldPlate.Length > 7 ? oldPlate.Substring(0, 7) : oldPlate;
|
|
if (ServerConfig.IsPretreatPlate > 0)
|
|
{
|
|
var dict = new Dictionary<string, string> { { "O", "0" }, { "I", "1" } };
|
|
newPlate = SubRepString(newPlate, 3, newPlate.Length, dict);
|
|
dict = new Dictionary<string, string> { { "D", "0" } };
|
|
newPlate = SubRepString(newPlate, newPlate.Length - 3, newPlate.Length, dict);
|
|
}
|
|
return newPlate;
|
|
}
|
|
|
|
public string SubRepString(string str, int start, int end, Dictionary<string, string> dict)
|
|
{
|
|
var beforeStr = str.Substring(0, start);
|
|
var changeStr = str.Substring(start, end - start);
|
|
var afterStr = str.Substring(end, str.Length - end);
|
|
foreach (var key in dict.Keys)
|
|
{
|
|
changeStr = changeStr.Replace(key, dict[key]);
|
|
}
|
|
return beforeStr + changeStr + afterStr;
|
|
}
|
|
|
|
#endregion Other
|
|
}
|
|
}
|