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

3 years ago
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
}
}