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.
1022 lines
49 KiB
1022 lines
49 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Data;
|
|
using System.Windows.Documents;
|
|
using System.Windows.Input;
|
|
using System.Windows.Media;
|
|
using System.Windows.Media.Imaging;
|
|
using System.Windows.Navigation;
|
|
using System.Windows.Shapes;
|
|
using System.IO;
|
|
using DemoUI.SDK;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
using Emgu.CV;
|
|
using Emgu.CV.Structure;
|
|
using DemoUI.Common;
|
|
using System.Net;
|
|
using System.Configuration;
|
|
using System.Collections;
|
|
using Newtonsoft.Json;
|
|
using System.Diagnostics;
|
|
using static DemoUI.CommonMethod;
|
|
|
|
namespace DemoUI
|
|
{
|
|
/// <summary>
|
|
/// MainWindow.xaml 的交互逻辑
|
|
/// </summary>
|
|
public partial class MainWindow : Window
|
|
{
|
|
private Capture m_capture = null; // 摄像头操作对象
|
|
//private Capture m_capture1 = null; // 摄像头操作对象
|
|
private Thread m_threadFaceDet = null; // 检测线程
|
|
private Object m_lock = null; // 锁
|
|
//private Mat m_matFrame = null; // 当前帧
|
|
private Mat m_matFrame = new Mat(); // 当前帧
|
|
//private Mat m_matFrame1 = null; // 当前帧
|
|
|
|
private GCHandle m_gc;
|
|
private bool m_bStartThread = false;
|
|
private DateTime dtNows = DateTime.Now;
|
|
private faceObj? maxFace = null;
|
|
private Dictionary<int, cwFaceAttr> faceDic = new Dictionary<int, cwFaceAttr>();
|
|
private Dictionary<int, DateTime> faceDicTime = new Dictionary<int, DateTime>();
|
|
private Dictionary<int, DateTime?> faceDicStopTime = new Dictionary<int, DateTime?>();
|
|
|
|
private thresholdFp thresholdfp = new thresholdFp();
|
|
|
|
private Dictionary<int, DateTime> liveFace = new Dictionary<int, DateTime>();
|
|
private List<Mat> matList = new List<Mat>();
|
|
|
|
private List<FaceDataModel> listFaceView = new List<FaceDataModel>();
|
|
private string AddressIP = string.Empty;
|
|
private string ServiceUrl = string.Empty;
|
|
private int liveX = 250;
|
|
private int liveY = 250;
|
|
private int liveWidth = 260;
|
|
private int liveHeight = 200;
|
|
|
|
private QMLog log = new QMLog();
|
|
private bool isSendLive = false;
|
|
public MainWindow()
|
|
{
|
|
InitializeComponent();
|
|
VersionUpdate.UpdateVersion();
|
|
Loaded += MainWindow_Loaded;
|
|
ChatWebSocketMiddleware chatWebSocket = new ChatWebSocketMiddleware();
|
|
chatWebSocket.openSocket();
|
|
chatWebSocket.openSocketForFace();
|
|
chatWebSocket.openSocketForLive();
|
|
//初始化一次即可
|
|
/*参数:
|
|
图像宽度
|
|
图像高度
|
|
分辨率
|
|
清晰度
|
|
深度姿态
|
|
亮度
|
|
完整度
|
|
浅度姿态
|
|
*/
|
|
thresholdfp.ResolutionF = float.Parse(ConfigurationManager.AppSettings["ResolutionF"]);
|
|
thresholdfp.ClarityF = double.Parse(ConfigurationManager.AppSettings["ClarityF"]);
|
|
thresholdfp.PoseExF = double.Parse(ConfigurationManager.AppSettings["PoseExF"]);
|
|
thresholdfp.BrigthF = double.Parse(ConfigurationManager.AppSettings["BrigthF"]);
|
|
thresholdfp.IntegF = double.Parse(ConfigurationManager.AppSettings["IntegF"]);
|
|
thresholdfp.PoseF = double.Parse(ConfigurationManager.AppSettings["PoseF"]);
|
|
int init = CommonMethod.initGetFace(640, 480, (int)thresholdfp.ResolutionF);
|
|
if (init == 1)
|
|
{
|
|
Console.WriteLine("初始化成功");
|
|
}
|
|
}
|
|
|
|
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
|
|
{
|
|
m_lock = new object();
|
|
AddressIP = string.Empty;
|
|
foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
|
|
{
|
|
if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
|
|
{
|
|
AddressIP = _IPAddress.ToString();
|
|
}
|
|
}
|
|
|
|
ServiceUrl = ConfigurationManager.AppSettings["HttpUrl"];
|
|
liveX = Convert.ToInt32(ConfigurationManager.AppSettings["liveX"]);
|
|
liveY = Convert.ToInt32(ConfigurationManager.AppSettings["liveY"]);
|
|
liveWidth = Convert.ToInt32(ConfigurationManager.AppSettings["liveWidth"]);
|
|
liveHeight = Convert.ToInt32(ConfigurationManager.AppSettings["liveHeight"]);
|
|
listFaceView.Clear();
|
|
OnBtnOpenUsb();
|
|
}
|
|
|
|
private void Window_Closed(object sender, EventArgs e)
|
|
{
|
|
m_bStartThread = false;
|
|
try
|
|
{
|
|
if (null != m_capture)
|
|
{
|
|
m_capture.Stop();
|
|
m_capture.Dispose();
|
|
}
|
|
}
|
|
catch (Exception exec)
|
|
{
|
|
|
|
}
|
|
|
|
if (m_gc.IsAllocated)
|
|
{
|
|
m_gc.Free();
|
|
}
|
|
try
|
|
{
|
|
var pendingRemoveList = faceDic.Keys.ToList();
|
|
foreach (int id in pendingRemoveList)
|
|
{
|
|
FaceDataModel model = new FaceDataModel();
|
|
model.Age = faceDic[id].age.ToString();
|
|
model.BeginTime = faceDicTime[id];
|
|
model.EndTime = DateTime.Now;
|
|
model.GenderMale = faceDic[id].sex == 1 ? "女" : "男";
|
|
model.StopTime = Convert.ToInt32((DateTime.Now - faceDicTime[id]).TotalSeconds);
|
|
model.IP = AddressIP;
|
|
if (model.StopTime > 1)
|
|
{
|
|
listFaceView.Add(model);
|
|
}
|
|
}
|
|
if (listFaceView.Count > 0)
|
|
{
|
|
var url = ServiceUrl + "/api/Face/UpLoadFace";
|
|
var param = JsonConvert.SerializeObject(listFaceView);
|
|
var _r = PostMoths(url, param);
|
|
listFaceView.Clear();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
}
|
|
Close();
|
|
}
|
|
|
|
// 开启USB摄像头
|
|
private void OnBtnOpenUsb()
|
|
{
|
|
//if (IntPtr.Zero == m_pDet)
|
|
//{
|
|
// MessageBox.Show("检测句柄为空,请先初始化创建句柄");
|
|
// return;
|
|
//}
|
|
if (m_bStartThread)
|
|
{
|
|
MessageBox.Show("摄像头已打开");
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
// 调用emgu打开摄像头,需先将emgu文件夹中的"cvextern.dll"拷贝到编译好的EXE程序目录"build_32/bin"中
|
|
m_capture = new Capture(0);
|
|
//if (m_capture.Height < 1 || m_capture.Width < 1)
|
|
//{
|
|
// MessageBox.Show("红外摄像头打开失败");
|
|
// return;
|
|
//}
|
|
m_capture.ImageGrabbed += ProcessFrame;//图像捕捉事件
|
|
m_capture.Start();
|
|
|
|
|
|
//m_capture1 = new Capture(1);
|
|
//if (m_capture1.Height < 1 || m_capture1.Width < 1)
|
|
//{
|
|
// MessageBox.Show("可见光摄像头打开失败");
|
|
// return;
|
|
//}
|
|
//m_capture1.Start();
|
|
//ThreadFaceDet();
|
|
//m_threadFaceDet = new Thread(new ThreadStart(ThreadFaceDet));
|
|
//m_bStartThread = true;
|
|
//m_threadFaceDet.Start();
|
|
}
|
|
catch (Exception exec)
|
|
{
|
|
MessageBox.Show(exec.Message + "\r\n请将当前目录emgu下的cvextern.dll拷贝到执行程序目录");
|
|
}
|
|
}
|
|
|
|
private void ProcessFrame(object sender, EventArgs arg)
|
|
{
|
|
//Mat frame = new Mat();//获取视频帧
|
|
//m_capture.Retrieve(m_matFrame, 0);
|
|
Mat mat = null;
|
|
lock (m_lock)
|
|
{
|
|
m_capture.Retrieve(m_matFrame, 0);
|
|
if (null != m_matFrame)
|
|
{
|
|
mat = m_matFrame.Clone();
|
|
}
|
|
if (ChatWebSocketMiddleware.isLive && m_matFrame != null)
|
|
{
|
|
//Action ac = new Action(() =>
|
|
//{
|
|
try
|
|
{
|
|
|
|
//Mat newFrame = m_matFrame;
|
|
using (Mat newFrame = new Mat(m_matFrame, new System.Drawing.Rectangle(new System.Drawing.Point(liveX, liveY), new System.Drawing.Size(liveWidth, liveHeight))))
|
|
{
|
|
try
|
|
{
|
|
bool isSussess = false;
|
|
|
|
Emgu.CV.Util.VectorOfByte buff = new Emgu.CV.Util.VectorOfByte();
|
|
CvInvoke.Imencode(".jpg", newFrame, buff);
|
|
|
|
byte[] encodeBuff = new byte[buff.Size];
|
|
Marshal.Copy(buff.StartAddress, encodeBuff, 0, buff.Size);
|
|
|
|
string base64Str = Convert.ToBase64String(encodeBuff);
|
|
//var faceData = new
|
|
//{
|
|
// age = -1,
|
|
// faceID = -1,
|
|
// genderMale = "",
|
|
// faceImage = base64Str
|
|
|
|
//};
|
|
//ChatWebSocketMiddleware.allSocketsForLive.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(faceData)));
|
|
|
|
|
|
var rmat = new Mat();
|
|
CvInvoke.Resize(newFrame, rmat, new System.Drawing.Size(640, 480));
|
|
var bm = rmat.Clone().Bitmap;
|
|
bm.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipY);
|
|
Image<Bgr, byte> image = new Image<Bgr, byte>(bm);
|
|
var newFrame1 = image.Mat;
|
|
|
|
Emgu.CV.Util.VectorOfByte buff1 = new Emgu.CV.Util.VectorOfByte();
|
|
CvInvoke.Imencode(".jpg", newFrame1, buff1);
|
|
var result = CommonMethod.getFaceInfo(CommonMethod.getFace(rmat.Ptr), rmat);
|
|
log.WriteLogFile("faceSize" + result.faceSize);
|
|
if (result.faceSize > 0)
|
|
{
|
|
SDK.cw_errcode_t errCode = cw_errcode_t.CW_OK;
|
|
|
|
foreach (var facepos in result.Faceobj)
|
|
{
|
|
bool niceFace = true;
|
|
|
|
if (facepos.Resolution_score < thresholdfp.ResolutionF)
|
|
{
|
|
niceFace = false;
|
|
}
|
|
if (facepos.Clarity_score < thresholdfp.ClarityF)
|
|
{
|
|
niceFace = false;
|
|
}
|
|
if (facepos.PoseEx_score < thresholdfp.PoseExF)
|
|
{
|
|
niceFace = false;
|
|
}
|
|
if (facepos.Brigth_score < thresholdfp.BrigthF)
|
|
{
|
|
niceFace = false;
|
|
}
|
|
if (facepos.Integ_score < thresholdfp.IntegF)
|
|
{
|
|
niceFace = false;
|
|
}
|
|
if (facepos.Pose_score < thresholdfp.PoseF)
|
|
{
|
|
niceFace = false;
|
|
}
|
|
if (niceFace)
|
|
{
|
|
isSussess = true;
|
|
log.WriteLogFile("isSussess");
|
|
int pAge = 0;
|
|
int pGender = 0;
|
|
|
|
string faceID = string.Empty;
|
|
|
|
if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["KioskUrl"]) && !isSendLive)
|
|
{
|
|
isSendLive = true;
|
|
var quality = new faceProperty();
|
|
if ((facepos.X + facepos.Width) <= rmat.Width && (facepos.Y + facepos.Height) <= rmat.Height)
|
|
{
|
|
quality = CommonMethod.getProperty(rmat.Ptr, facepos);
|
|
if (quality.Sex == -1 || quality.Old == -1)
|
|
{
|
|
continue;
|
|
}
|
|
pGender = quality.Sex;
|
|
pAge = quality.Old;
|
|
}
|
|
var url = ConfigurationManager.AppSettings["KioskUrl"] + "/api/Face/UpLoadFace";
|
|
if (pAge < 1)
|
|
{
|
|
isSendLive = false;
|
|
}
|
|
else
|
|
{
|
|
|
|
//byte[] encodeBuff1 = new byte[buff1.Size];
|
|
//Marshal.Copy(buff1.StartAddress, encodeBuff1, 0, buff1.Size);
|
|
|
|
//string base64Str1 = Convert.ToBase64String(encodeBuff1);
|
|
string data = "Face=" + base64Str + "&ip=" + AddressIP + "&Age=" + pAge + "&GenderMale=" + pGender;
|
|
var _r = PostMothsForm(url, data);
|
|
if (!string.IsNullOrEmpty(_r))
|
|
{
|
|
Dictionary<string, Object> dic = JsonConvert.DeserializeObject<Dictionary<string, Object>>(_r);
|
|
if (dic["code"].ToString() == "200")
|
|
{
|
|
isSendLive = false;
|
|
Dictionary<string, Object> dicData = JsonConvert.DeserializeObject<Dictionary<string, Object>>(dic["data"].ToString());
|
|
faceID = dicData["faceID"] == null ? "" : dicData["faceID"].ToString();
|
|
liveFace.Clear();
|
|
ChatWebSocketMiddleware.isLive = false;
|
|
}
|
|
else
|
|
{
|
|
isSendLive = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
isSendLive = false;
|
|
}
|
|
}
|
|
}
|
|
var faceData = new
|
|
{
|
|
age = pAge,
|
|
faceID,
|
|
genderMale = pGender == 0 ? "男" : "女",
|
|
faceImage = base64Str
|
|
|
|
};
|
|
if (!ChatWebSocketMiddleware.isLive)
|
|
{
|
|
isSendLive = false;
|
|
ChatWebSocketMiddleware.allSocketsForLive.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(faceData)));
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
liveFace.Clear();
|
|
}
|
|
if (ChatWebSocketMiddleware.isLive)
|
|
{
|
|
var faceData = new
|
|
{
|
|
age = -1,
|
|
faceID = -1,
|
|
genderMale = "",
|
|
faceImage = base64Str
|
|
|
|
};
|
|
ChatWebSocketMiddleware.allSocketsForLive.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(faceData)));
|
|
}
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
isSendLive = false;
|
|
log.WriteLogFile(e.ToString(), "live");
|
|
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
isSendLive = false;
|
|
log.WriteLogFile("------" + e.ToString(), "live");
|
|
}
|
|
|
|
|
|
}
|
|
if (mat != null)
|
|
{
|
|
var itr = CommonMethod.getFace(m_matFrame.Ptr);
|
|
var result = CommonMethod.getFaceInfo(itr, m_matFrame);
|
|
faceObj? curMatFace = null;
|
|
var pendingRemoveList = faceDic.Keys.ToList();
|
|
var removeList = new ArrayList();
|
|
if (result.faceSize > 0)
|
|
{
|
|
//SendHttpForNavigation(mat);
|
|
SDK.cw_errcode_t errCode = cw_errcode_t.CW_OK;
|
|
foreach (var facepos in result.Faceobj)
|
|
{
|
|
if (facepos.Pid < 0 || facepos.Width == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
string low = "";
|
|
var bid = "";
|
|
var se = "unknown";
|
|
var temAge1 = "0";
|
|
cwFaceAttr cwFaceAttr = new cwFaceAttr();
|
|
log.WriteLogFile("识别到人脸:" + facepos.Pid, "pid");
|
|
bool niceFace = true;
|
|
if (facepos.Resolution_score < thresholdfp.ResolutionF)
|
|
{
|
|
niceFace = false;
|
|
//log.WriteLogFile("facepos.Resolution_score" + facepos.Resolution_score, "niceFace");
|
|
}
|
|
if (facepos.Clarity_score < thresholdfp.ClarityF)
|
|
{
|
|
niceFace = false;
|
|
//log.WriteLogFile("facepos.Clarity_score" + facepos.Clarity_score, "niceFace");
|
|
}
|
|
if (facepos.PoseEx_score < thresholdfp.PoseExF)
|
|
{
|
|
niceFace = false;
|
|
//log.WriteLogFile("facepos.PoseEx_score" + facepos.PoseEx_score, "niceFace");
|
|
}
|
|
if (facepos.Brigth_score < thresholdfp.BrigthF)
|
|
{
|
|
niceFace = false;
|
|
//log.WriteLogFile("facepos.Brigth_score" + facepos.Brigth_score, "niceFace");
|
|
}
|
|
if (facepos.Integ_score < thresholdfp.IntegF)
|
|
{
|
|
niceFace = false;
|
|
//log.WriteLogFile("facepos.Integ_score" + facepos.Integ_score, "niceFace");
|
|
}
|
|
if (facepos.Pose_score < thresholdfp.PoseF)
|
|
{
|
|
niceFace = false;
|
|
//log.WriteLogFile("facepos.Pose_score" + facepos.Pose_score, "niceFace");
|
|
}
|
|
if (niceFace)
|
|
{
|
|
if ((curMatFace == null || (curMatFace != null && facepos.Width > curMatFace.Value.Width)))
|
|
{
|
|
curMatFace = facepos;
|
|
}
|
|
}
|
|
if (!faceDic.ContainsKey(facepos.Pid))
|
|
{
|
|
if (niceFace)
|
|
{
|
|
var quality = new faceProperty();
|
|
if ((facepos.X + facepos.Width) <= m_matFrame.Width && (facepos.Y + facepos.Height) <= m_matFrame.Height)
|
|
//if (facepos.X * 2 > facepos.Width && facepos.Y * 2 > facepos.Height && (facepos.X + facepos.Width) <= m_matFrame.Width && (facepos.Y + facepos.Height) <= m_matFrame.Height)
|
|
{
|
|
var qmat = new Mat(m_matFrame, new System.Drawing.Rectangle(facepos.X, facepos.Y, facepos.Width, facepos.Height));
|
|
quality = CommonMethod.getProperty(m_matFrame.Ptr, facepos);
|
|
if (quality.Sex == -1 || quality.Old == -1)
|
|
{
|
|
continue;
|
|
}
|
|
se = quality.Sex == 0 ? "man" : "woman";
|
|
temAge1 = quality.Old.ToString();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
low = "facepos.Pid:" + facepos.Pid + (facepos.Resolution_score >= thresholdfp.ResolutionF ? "" : "|ResolutionF:" + facepos.Resolution_score.ToString()) +
|
|
(facepos.Clarity_score >= thresholdfp.ClarityF ? "" : "|Clarity:" + facepos.Clarity_score.ToString()) +
|
|
(facepos.Integ_score >= thresholdfp.IntegF ? "" : "|Integ:" + facepos.Integ_score.ToString()) +
|
|
(facepos.Pose_score >= thresholdfp.PoseF ? "" : "|Pose:" + facepos.Pose_score.ToString()) +
|
|
(facepos.PoseEx_score >= thresholdfp.PoseExF ? "" : "|PoseEx:" + facepos.PoseEx_score.ToString()) +
|
|
(facepos.Brigth_score >= thresholdfp.BrigthF ? "" : "|Brigth:" + facepos.Brigth_score.ToString());
|
|
this.Dispatcher.BeginInvoke(new Action(() =>
|
|
{
|
|
if (facelog.ExtentHeight > 1000)
|
|
{
|
|
facelog.Clear();
|
|
}
|
|
facelog.ScrollToEnd();
|
|
facelog.AppendText(string.IsNullOrEmpty(low) ? "" : low + "\r\n--------------------------------\r\n");
|
|
}));
|
|
}
|
|
|
|
if (facepos.Width > 0)
|
|
{
|
|
CvInvoke.Rectangle(mat, new System.Drawing.Rectangle(facepos.X, facepos.Y, facepos.Width, facepos.Height), new MCvScalar(0, 0, 255), 2);
|
|
CvInvoke.PutText(mat, $"ID:{facepos.Pid}", new System.Drawing.Point(facepos.X, facepos.Y - 5), Emgu.CV.CvEnum.FontFace.HersheyPlain, 1, new MCvScalar(0, 235, 0));
|
|
}
|
|
//0 小孩 1 成年人 2 老人
|
|
cwFaceAttr.age = int.Parse(temAge1);
|
|
cwFaceAttr.sex = se == "man" ? 0 : se == "woman" ? 1 : -1;
|
|
cwFaceAttr.faceid = facepos.Pid.ToString();
|
|
//curMatFace = facepos;
|
|
faceDic.Add(facepos.Pid, cwFaceAttr);
|
|
faceDicTime.Add(facepos.Pid, DateTime.Now);
|
|
Task.Run(() =>
|
|
{
|
|
SendHttpForNavigation(mat, facepos);
|
|
});
|
|
|
|
}
|
|
else
|
|
{
|
|
pendingRemoveList.Remove(facepos.Pid);
|
|
bid = faceDic[facepos.Pid].backid;
|
|
if (faceDic[facepos.Pid].age > 0)
|
|
{
|
|
se = faceDic[facepos.Pid].sex == 0 ? "man" : (faceDic[facepos.Pid].sex == 1 ? "woman" : "unknown");
|
|
temAge1 = faceDic[facepos.Pid].age.ToString();
|
|
}
|
|
else
|
|
{
|
|
if (niceFace)
|
|
{
|
|
var quality = new faceProperty();
|
|
if ((facepos.X + facepos.Width) <= m_matFrame.Width && (facepos.Y + facepos.Height) <= m_matFrame.Height)
|
|
{
|
|
var qmat = new Mat(m_matFrame, new System.Drawing.Rectangle(facepos.X, facepos.Y, facepos.Width, facepos.Height));
|
|
quality = CommonMethod.getProperty(m_matFrame.Ptr, facepos);
|
|
if (quality.Sex == -1 || quality.Old == -1)
|
|
{
|
|
log.WriteLogFile("清晰人脸识别失败", "niceFace");
|
|
continue;
|
|
}
|
|
//se = quality.Sex == 0 ? "man" : "woman";
|
|
temAge1 = quality.Old.ToString();
|
|
faceDic[facepos.Pid].age = quality.Old;
|
|
faceDic[facepos.Pid].sex = quality.Sex;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
low = "facepos.Pid:" + facepos.Pid + (facepos.Resolution_score >= thresholdfp.ResolutionF ? "" : "|ResolutionF:" + facepos.Resolution_score.ToString()) +
|
|
(facepos.Clarity_score >= thresholdfp.ClarityF ? "" : "|Clarity:" + facepos.Clarity_score.ToString()) +
|
|
(facepos.Integ_score >= thresholdfp.IntegF ? "" : "|Integ:" + facepos.Integ_score.ToString()) +
|
|
(facepos.Pose_score >= thresholdfp.PoseF ? "" : "|Pose:" + facepos.Pose_score.ToString()) +
|
|
(facepos.PoseEx_score >= thresholdfp.PoseExF ? "" : "|PoseEx:" + facepos.PoseEx_score.ToString()) +
|
|
(facepos.Brigth_score >= thresholdfp.BrigthF ? "" : "|Brigth:" + facepos.Brigth_score.ToString());
|
|
this.Dispatcher.BeginInvoke(new Action(() =>
|
|
{
|
|
if (facelog.ExtentHeight > 1000)
|
|
{
|
|
facelog.Clear();
|
|
}
|
|
facelog.ScrollToEnd();
|
|
facelog.AppendText(string.IsNullOrEmpty(low) ? "" : low + "\r\n--------------------------------\r\n");
|
|
}));
|
|
}
|
|
|
|
if (facepos.Width > 0)
|
|
{
|
|
|
|
CvInvoke.Rectangle(mat, new System.Drawing.Rectangle(facepos.X, facepos.Y, facepos.Width, facepos.Height), new MCvScalar(0, 0, 255), 2);
|
|
CvInvoke.PutText(mat, $"ID:{facepos.Pid}", new System.Drawing.Point(facepos.X, facepos.Y - 5), Emgu.CV.CvEnum.FontFace.HersheyPlain, 1, new MCvScalar(0, 235, 0));
|
|
}
|
|
}
|
|
}
|
|
if (faceDicStopTime.Keys.Contains(facepos.Pid) && faceDicStopTime[facepos.Pid].HasValue)
|
|
{
|
|
faceDicStopTime[facepos.Pid] = null;
|
|
}
|
|
}
|
|
|
|
foreach (int id in pendingRemoveList)
|
|
{
|
|
if (!faceDicStopTime.Keys.Contains(id))
|
|
{
|
|
faceDicStopTime.Add(id, DateTime.Now);
|
|
}
|
|
else if (!faceDicStopTime[id].HasValue)
|
|
{
|
|
faceDicStopTime[id] = DateTime.Now;
|
|
}
|
|
else if (faceDicStopTime[id].Value.AddSeconds(2) <= DateTime.Now)
|
|
{
|
|
AddFaceView(faceDic[id], faceDicTime[id]);
|
|
faceDic.Remove(id);
|
|
faceDicTime.Remove(id);
|
|
faceDicStopTime.Remove(id);
|
|
if (maxFace.HasValue && maxFace.Value.Pid == id)
|
|
{
|
|
maxFace = null;
|
|
ChatWebSocketMiddleware.CurFaceID = "";
|
|
ChatWebSocketMiddleware.allSockets.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(ChatWebSocketMiddleware.NoFaceModel)));
|
|
}
|
|
}
|
|
}
|
|
if (maxFace.HasValue && !faceDic.Keys.Contains(maxFace.Value.Pid))
|
|
{
|
|
maxFace = null;
|
|
ChatWebSocketMiddleware.CurFaceID = "";
|
|
ChatWebSocketMiddleware.allSockets.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(ChatWebSocketMiddleware.NoFaceModel)));
|
|
}
|
|
if (!maxFace.HasValue && curMatFace.HasValue && faceDicTime[curMatFace.Value.Pid].AddSeconds(2) <= DateTime.Now)
|
|
{
|
|
Task.Run(() =>
|
|
{
|
|
if (SendHttpForKiosk(mat, curMatFace.Value))
|
|
{
|
|
maxFace = curMatFace;
|
|
CvInvoke.Imwrite("./a.jpg", m_matFrame);
|
|
ChatWebSocketMiddleware.CurFaceImage = mat;
|
|
ChatWebSocketMiddleware.CurFaceModel = new cw_face_res_t
|
|
{
|
|
trackId = curMatFace.Value.Pid,
|
|
faceRect = new cw_facepos_rect_t
|
|
{
|
|
height = curMatFace.Value.Height,
|
|
width = curMatFace.Value.Height,
|
|
y = curMatFace.Value.Y,
|
|
x = curMatFace.Value.X,
|
|
}
|
|
};
|
|
}
|
|
});
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (int id in pendingRemoveList)
|
|
{
|
|
if (!faceDicStopTime.Keys.Contains(id))
|
|
{
|
|
faceDicStopTime.Add(id, DateTime.Now);
|
|
}
|
|
else if (!faceDicStopTime[id].HasValue)
|
|
{
|
|
faceDicStopTime[id] = DateTime.Now;
|
|
}
|
|
else if (faceDicStopTime[id].Value.AddSeconds(2) <= DateTime.Now)
|
|
{
|
|
AddFaceView(faceDic[id], faceDicTime[id]);
|
|
faceDic.Remove(id);
|
|
faceDicTime.Remove(id);
|
|
faceDicStopTime.Remove(id);
|
|
}
|
|
}
|
|
if (maxFace.HasValue && !faceDic.Keys.Contains(maxFace.Value.Pid))
|
|
{
|
|
maxFace = null;
|
|
ChatWebSocketMiddleware.CurFaceID = "";
|
|
ChatWebSocketMiddleware.allSockets.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(ChatWebSocketMiddleware.NoFaceModel)));
|
|
}
|
|
}
|
|
|
|
this.Dispatcher.BeginInvoke(new Action(() =>
|
|
{
|
|
if (mat != null && !mat.IsEmpty)
|
|
{
|
|
var imageSource = ToBitmapSource(mat);
|
|
if (imageSource != null)
|
|
{
|
|
video.Source = imageSource; // 显示到界面上
|
|
}
|
|
}
|
|
|
|
}));
|
|
}
|
|
}
|
|
//this.Dispatcher.BeginInvoke(new Action(() =>
|
|
//{
|
|
// video.Source = ToBitmapSource(mat); // 显示到界面上
|
|
//}));
|
|
}
|
|
|
|
private void Facelog_MouseEnter(object sender, MouseEventArgs e)
|
|
{
|
|
CommonMethod.pulse = true;
|
|
}
|
|
|
|
private void Facelog_MouseLeave(object sender, MouseEventArgs e)
|
|
{
|
|
CommonMethod.pulse = false;
|
|
}
|
|
|
|
private bool SendHttpForKiosk(Mat frame, faceObj face)
|
|
{
|
|
|
|
if (faceDic.ContainsKey(face.Pid))
|
|
{
|
|
var age = faceDic[face.Pid].age;
|
|
var sex = faceDic[face.Pid].sex;
|
|
if (age < 1)
|
|
{
|
|
return false;
|
|
}
|
|
int x = face.X;
|
|
int y = face.Y;
|
|
int width = face.Width;
|
|
int height = face.Height;
|
|
//if ((int)face.X > 20)
|
|
//{
|
|
// x = (int)face.X - 20;
|
|
// //qMLog.WriteLogToFile("x:"+ ((int)face.Rect.X)+ " Width"+ ((int)face.Rect.Width)+ " frame"+ frame.Width,"111");
|
|
// width = (x + (int)face.Width + 40) >= frame.Width ? (frame.Width - x) : (int)face.Width + 60;
|
|
// //width += 10;
|
|
//}
|
|
//else
|
|
//{
|
|
// x = 0;
|
|
// width = (int)face.X + (int)face.Width + 40 >= frame.Width ? frame.Width : (int)face.Width + 40 + (int)face.X;
|
|
// //width += x;
|
|
//}
|
|
|
|
//if ((int)face.Y > 60)
|
|
//{
|
|
// y = (int)face.Y - 60;
|
|
// height = (y + (int)face.Height + 40) >= frame.Height ? (frame.Height - y) : (int)face.Height + 100;
|
|
//}
|
|
//else
|
|
//{
|
|
// y = 0;
|
|
// height = (int)face.Y + (int)face.Height + 40 >= frame.Height ? frame.Height : (int)face.Height + 40 + (int)face.Y;
|
|
|
|
//}
|
|
string AddressIP = string.Empty;
|
|
foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
|
|
{
|
|
if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
|
|
{
|
|
AddressIP = _IPAddress.ToString();
|
|
}
|
|
}
|
|
try
|
|
{
|
|
using (Mat newFrame = new Mat(frame, new System.Drawing.Rectangle(new System.Drawing.Point(x, y),
|
|
new System.Drawing.Size(width, height))))
|
|
{
|
|
Emgu.CV.Util.VectorOfByte buff = new Emgu.CV.Util.VectorOfByte();
|
|
CvInvoke.Imencode(".jpg", newFrame, buff);
|
|
|
|
byte[] encodeBuff = new byte[buff.Size];
|
|
Marshal.Copy(buff.StartAddress, encodeBuff, 0, buff.Size);
|
|
|
|
string base64Str = Convert.ToBase64String(encodeBuff);
|
|
var url = ConfigurationManager.AppSettings["KioskUrl"] + "/api/Face/UpLoadFace";
|
|
string data = "Face=" + base64Str + "&ip=" + AddressIP + "&Age=" + age + "&GenderMale=" + sex;
|
|
var _r = PostMothsForm(url, data);
|
|
Dictionary<string, Object> dic = JsonConvert.DeserializeObject<Dictionary<string, Object>>(_r);
|
|
if (dic["code"].ToString() == "200")
|
|
{
|
|
|
|
Dictionary<string, Object> dicData = JsonConvert.DeserializeObject<Dictionary<string, Object>>(dic["data"].ToString());
|
|
var faceData = new { faceID = dicData["faceID"], isValid = dicData["isValid"], beautyScore = dicData["beautyScore"], faceImage = base64Str, age, genderMale = (sex == 0 ? "男" : "女") };
|
|
ChatWebSocketMiddleware.CurFaceID = JsonConvert.SerializeObject(faceData);
|
|
ChatWebSocketMiddleware.allSockets.ToList().ForEach(s => s.Send(ChatWebSocketMiddleware.CurFaceID));
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
log.WriteLogFile(e.Message, "HTTPError");
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//private void SendHttpForNavigation(Mat frame)
|
|
private void SendHttpForNavigation(Mat frame, faceObj face)
|
|
{
|
|
if (ChatWebSocketMiddleware.faceSocketLists.ContainsKey("信发"))
|
|
{
|
|
var richadResult = new { Type = "richad", Data = "" };
|
|
ChatWebSocketMiddleware.faceSocketLists["信发"].Send(JsonConvert.SerializeObject(richadResult));
|
|
}
|
|
if (string.IsNullOrEmpty(ConfigurationManager.AppSettings["KioskUrl"]))
|
|
{
|
|
return;
|
|
}
|
|
log.WriteLogFile("准备接力:"+face.Pid, "relay");
|
|
if (faceDic.ContainsKey(face.Pid))
|
|
{
|
|
try
|
|
{
|
|
var age = faceDic[face.Pid].age;
|
|
var sex = faceDic[face.Pid].sex;
|
|
if (age < 1)
|
|
{
|
|
return;
|
|
}
|
|
bool pcstart = true;
|
|
if (pcstart)
|
|
{
|
|
int x = face.X;
|
|
int y = face.Y;
|
|
int width = face.Width;
|
|
int height = face.Height;
|
|
//if ((int)face.X > 20)
|
|
//{
|
|
// x = (int)face.X - 20;
|
|
// width = (x + (int)face.Width + 40) >= frame.Width ? (frame.Width - x) : (int)face.Width + 60;
|
|
//}
|
|
//else
|
|
//{
|
|
// x = 0;
|
|
// width = (int)face.X + (int)face.Width + 40 >= frame.Width ? frame.Width : (int)face.Width + 40 + (int)face.X;
|
|
//}
|
|
|
|
//if ((int)face.Y > 60)
|
|
//{
|
|
// y = (int)face.Y - 60;
|
|
// height = (y + (int)face.Height + 40) >= frame.Height ? (frame.Height - y) : (int)face.Height + 100;
|
|
//}
|
|
//else
|
|
//{
|
|
// y = 0;
|
|
// height = (int)face.Y + (int)face.Height + 40 >= frame.Height ? frame.Height : (int)face.Height + 40 + (int)face.Y;
|
|
//}
|
|
string AddressIP = string.Empty;
|
|
foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
|
|
{
|
|
if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
|
|
{
|
|
AddressIP = _IPAddress.ToString();
|
|
}
|
|
}
|
|
|
|
using (Mat newFrame = new Mat(frame, new System.Drawing.Rectangle(new System.Drawing.Point(x, y),
|
|
new System.Drawing.Size(width, height))))
|
|
{
|
|
Emgu.CV.Util.VectorOfByte buff = new Emgu.CV.Util.VectorOfByte();
|
|
CvInvoke.Imencode(".jpg", newFrame, buff);
|
|
byte[] encodeBuff = new byte[buff.Size];
|
|
Marshal.Copy(buff.StartAddress, encodeBuff, 0, buff.Size);
|
|
string base64Str = Convert.ToBase64String(encodeBuff);
|
|
var url = ConfigurationManager.AppSettings["KioskUrl"] + "/api/Face/UpLoadFace";
|
|
string data = "Face=" + base64Str + "&ip=" + AddressIP + "&method=relay&Age=" + age + "&GenderMale=" + sex;
|
|
log.WriteLogFile("推送接力:" + data, "relay");
|
|
var _r = PostMothsForm(url, data);
|
|
log.WriteLogFile("推送接力:"+_r, "relay");
|
|
log.WriteLogFile($"客户端数:{ChatWebSocketMiddleware.faceSocketLists.Count}", "relay");
|
|
Dictionary<string, dynamic> dic = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(_r);
|
|
if (dic["code"].ToString() == "200")
|
|
{
|
|
var faceData = new
|
|
{
|
|
faceID = "-1",
|
|
faceImage = dic["data"]?.code,
|
|
data = dic["data"]
|
|
};
|
|
ChatWebSocketMiddleware.faceSocketLists.ToList().ForEach(s => s.Value.Send(JsonConvert.SerializeObject(faceData)));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
log.WriteLogFile(e.Message, "relay");
|
|
}
|
|
}
|
|
}
|
|
|
|
private void AddFaceView(cwFaceAttr faceModel, DateTime dtBegin, bool isSubmit = false)
|
|
{
|
|
|
|
|
|
var url = ServiceUrl + "/api/Face/UpLoadFace";
|
|
try
|
|
{
|
|
FaceDataModel model = new FaceDataModel();
|
|
model.Age = faceModel.age.ToString();
|
|
model.BeginTime = dtBegin;
|
|
model.EndTime = DateTime.Now;
|
|
model.GenderMale = faceModel.sex == 1 ? "女" : "男";
|
|
model.StopTime = Convert.ToInt32((DateTime.Now - dtBegin).TotalSeconds);
|
|
model.IP = AddressIP;
|
|
if (model.StopTime > 1)
|
|
{
|
|
listFaceView.Add(model);
|
|
if (listFaceView.Count >= 5)
|
|
{
|
|
var param = JsonConvert.SerializeObject(listFaceView);
|
|
var _r = PostMoths(url, param);
|
|
if (!string.IsNullOrEmpty(_r))
|
|
{
|
|
Dictionary<string, Object> dic = JsonConvert.DeserializeObject<Dictionary<string, Object>>(_r);
|
|
if (dic["code"].ToString() == "200")
|
|
{
|
|
listFaceView.Clear();
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
log.WriteLogFile(e.ToString(), "addfaceerror");
|
|
//MessageBox.Show(url + e.Message);
|
|
}
|
|
}
|
|
|
|
public string PostMoths(string url, string param)
|
|
{
|
|
string strURL = url;
|
|
System.Net.HttpWebRequest request;
|
|
request = (System.Net.HttpWebRequest)WebRequest.Create(strURL);
|
|
request.Method = "POST";
|
|
request.ContentType = "application/json;charset=UTF-8";
|
|
string paraUrlCoded = param;
|
|
byte[] payload;
|
|
payload = System.Text.Encoding.UTF8.GetBytes(paraUrlCoded);
|
|
request.ContentLength = payload.Length;
|
|
Stream writer = request.GetRequestStream();
|
|
writer.Write(payload, 0, payload.Length);
|
|
writer.Close();
|
|
System.Net.HttpWebResponse response;
|
|
response = (System.Net.HttpWebResponse)request.GetResponse();
|
|
System.IO.Stream s;
|
|
s = response.GetResponseStream();
|
|
string StrDate = "";
|
|
string strValue = "";
|
|
StreamReader Reader = new StreamReader(s, Encoding.UTF8);
|
|
while ((StrDate = Reader.ReadLine()) != null)
|
|
{
|
|
strValue += StrDate + "\r\n";
|
|
}
|
|
return strValue;
|
|
}
|
|
|
|
public static string PostMothsForm(string url, string param)
|
|
{
|
|
string strURL = url;
|
|
System.Net.HttpWebRequest request;
|
|
request = (System.Net.HttpWebRequest)WebRequest.Create(strURL);
|
|
request.Method = "POST";
|
|
request.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
|
|
string paraUrlCoded = param;
|
|
byte[] payload;
|
|
payload = System.Text.Encoding.UTF8.GetBytes(paraUrlCoded);
|
|
request.ContentLength = payload.Length;
|
|
Stream writer = request.GetRequestStream();
|
|
writer.Write(payload, 0, payload.Length);
|
|
writer.Close();
|
|
System.Net.HttpWebResponse response;
|
|
response = (System.Net.HttpWebResponse)request.GetResponse();
|
|
System.IO.Stream s;
|
|
s = response.GetResponseStream();
|
|
string StrDate = "";
|
|
string strValue = "";
|
|
StreamReader Reader = new StreamReader(s, Encoding.UTF8);
|
|
while ((StrDate = Reader.ReadLine()) != null)
|
|
{
|
|
strValue += StrDate + "\r\n";
|
|
}
|
|
return strValue;
|
|
}
|
|
|
|
|
|
[DllImport("gdi32")]
|
|
private static extern int DeleteObject(IntPtr o);
|
|
|
|
public static BitmapSource ToBitmapSource(Mat mat)
|
|
{
|
|
QMLog log = new QMLog();
|
|
try
|
|
{
|
|
|
|
|
|
using (System.Drawing.Bitmap source = mat.ToImage<Bgr, byte>().Bitmap)
|
|
{
|
|
IntPtr ptr = source.GetHbitmap();
|
|
|
|
BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
|
|
ptr,
|
|
IntPtr.Zero,
|
|
Int32Rect.Empty,
|
|
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
|
|
|
|
DeleteObject(ptr);// 释放内存,否则内存泄露
|
|
|
|
return bs;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
|
|
log.WriteLogFile(e.ToString(), "BitmapSource");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|