/// <summary> /// 查找最相似的人脸。 /// </summary> /// <param name="fi"></param> /// <param name="score"></param> /// <param name="outfd"></param> /// <returns></returns> public int FindMostSimilarFace(FaceInfo fi, out int score, out FaceData outfd) { int maxs = 0, s, uid = 0; FaceData ofd = null; foreach (var fl in this) { foreach (FaceData fd in fl.Value) { s = _Face.FaceFeatureMatch(fi, fd); if (s > maxs) { maxs = s; uid = fl.Key; ofd = fd; } } } score = maxs; outfd = ofd; return(uid); }
private void onFaceCollect(FaceInfo f) { try { if (f.angleType == RequestAngleType) { FaceEvent e = new FaceEvent { type = FaceEvent.EventType.FaceCollected, faceinfo = f, }; if (FaceHandler != null) { FaceHandler(e); } } } catch (Exception ex) { Console.WriteLine("FaceCamera->faceCollect:" + ex); } }
private void updateFoundPic(FaceInfo f, FaceData fd) { if (f == null || fd == null) { return; } if (PicBoxFoundPic != null) { Action d = () => { PicBoxFoundPic.Image = Data.GetFaceOrgPic(fd); }; PicBoxFoundPic.BeginInvoke(d); } //自动更新人脸字典数据结构 if (FaceAutoUpdateOn && f.userid != 0) { Data.UpdateFacePicture(f, fd); FaceDic.AddFace(f.userid, f); Console.WriteLine("FaceCamera->AutoFaceDictionaryUpdate: uid=" + f.userid + "FaceAngleType=" + f.angleType); } }
/// <summary> /// 查找相同的人脸 /// </summary> /// <param name="fi"></param> /// <param name="score"></param> /// <param name="outfd"></param> /// <returns></returns> public int FindSameFace(FaceInfo fi, out int score, out FaceData outfd) { if (fi == null) { score = 0; outfd = null; return(0); } int maxs = 0, s, uid = 0; FaceData ofd = null; foreach (var fl in this) { foreach (FaceData fd in fl.Value) { s = _Face.FaceFeatureMatch(fi, fd); if (s > maxs) { maxs = s; uid = fl.Key; ofd = fd; } } } if (maxs >= _Face.SameFaceThreshold) { score = maxs; outfd = ofd; } else { score = 0; outfd = null; uid = 0; } return(uid); }
public int AddUserFace(FaceInfo fi, UserInfo ui) { if (fi == null) { return(0); } int uid = 0; int fid = 0; switch (DataSource) { default: case DataSrcType.FileSystem: uid = _FaceDic.GetNextUserId(ui.username); break; case DataSrcType.DataBase: uid = ui.uid = _FaceDic.GetNextUserId(ui.username); if (!ui.Save()) { return(0); } fid = InsertFaceInfoOverride(fi, uid); if (fid <= 0) { return(fid); } fi.faceid = fid; break; } fi.userid = uid; _FaceDic.AddFace(uid, fi, ui.username);//添加到字典中 return(uid); }
/***************************事件处理方法实现*****************************/ private void onShotFaceHander(FaceInfo f) { switch (_FaceCmd) { case FaceCommand.ShotOneAndFind: onFaceShotAndFind(f, FaceEvent.EventType.ShotOne); break; case FaceCommand.ShotAllAndFind: onFaceShotAndFind(f, FaceEvent.EventType.ShotAll); break; case FaceCommand.NodShakeDetect: onNodShakeDetect(f); break; case FaceCommand.FaceCollect: onFaceCollect(f); break; default: break; } }
public void setInfo(FaceInfo f) { info = f.info; }
public void setPos(FaceInfo f) { info.faceInfo = f.info.faceInfo; }
/// <summary> /// 保存人脸图片到本地,并添加到人脸字典中。 /// </summary> /// <param name="name"></param> /// <param name="fi"></param> /// <param name="bmpsavepath"></param> /// <returns></returns> public int SaveUserFace(string name, int gender, int age, string telephone, FaceInfo fi, string bmpsavepath) { try { if (string.IsNullOrEmpty(name)) { return(0); } if (fi == null) { return(0); } if (string.IsNullOrEmpty(bmpsavepath)) { bmpsavepath = DEFAULT_SAVE_PATH; } if (!Directory.Exists(bmpsavepath)) { Directory.CreateDirectory(bmpsavepath); } if (DataSource == DataSrcType.FileSystem) { switch (fi.angleType) { case FaceData.FaceAngleType.Middle: fi.text = bmpsavepath + "\\" + name + "0.jpg"; break; case FaceData.FaceAngleType.Up: fi.text = bmpsavepath + "\\" + name + "1.jpg"; break; case FaceData.FaceAngleType.Down: fi.text = bmpsavepath + "\\" + name + "2.jpg"; break; case FaceData.FaceAngleType.Left: fi.text = bmpsavepath + "\\" + name + "3.jpg"; break; case FaceData.FaceAngleType.Right: fi.text = bmpsavepath + "\\" + name + "4.jpg"; break; default: break; } //保存图片 fi.FaceShotBmp.Save(fi.text); } int uid = AddUserFace(fi, name, gender, age, telephone); return(uid); } catch (Exception e) { Console.WriteLine("SaveFaceAndAddToDic Error: " + e.ToString()); return(0); } }
/// <summary> /// 用图片添加人脸数据库。同步函数。 /// </summary> /// <param name="path"></param> /// <param name="alldirs"></param> /// <param name="proBar"></param> /// <returns>处理的图片数。</returns> public int LoadFaceData(string path, bool alldirs, ProgressBar proBar) { //if (DataSource != DataSrcType.FileSystem) return 0; if (!Directory.Exists(path)) { return(0); } string[] fs1, fs2, fs3; if (alldirs) { fs1 = Directory.GetFiles(path, "*.BMP", SearchOption.AllDirectories); fs2 = Directory.GetFiles(path, "*.JPG", SearchOption.AllDirectories); fs3 = Directory.GetFiles(path, "*.PNG", SearchOption.AllDirectories); } else { fs1 = Directory.GetFiles(path, "*.BMP", SearchOption.TopDirectoryOnly); fs2 = Directory.GetFiles(path, "*.JPG", SearchOption.TopDirectoryOnly); fs3 = Directory.GetFiles(path, "*.PNG", SearchOption.TopDirectoryOnly); } var files = fs1.Concat(fs2).Concat(fs3); if (proBar != null) { if (proBar.InvokeRequired) { Action a = () => { proBar.Maximum = files.Count(); proBar.Value = 0; }; proBar.Invoke(a); } else { proBar.Maximum = files.Count(); proBar.Value = 0; } } foreach (string fstr in files) { Console.WriteLine(fstr); string fname = Path.GetFileNameWithoutExtension(fstr); //System.IO.Path.GetFileName(fstr); if (fname[0] != '.' && !string.IsNullOrEmpty(fname)) //去除.开头的错误文件 { string n = fname; char lc = fname[fname.Length - 1]; while (lc == ' ' || lc == '-' || lc == '_' || char.IsDigit(lc)) { fname = fname.Remove(fname.Length - 1); if (fname.Length == 0) { fname = n; break; } lc = fname[fname.Length - 1]; } FaceInfo fi = _Face.FaceRecgOne(fstr); int ret = AddUserFace(fi, fname); if (ret < 0) { return(ret); } } if (proBar != null) { if (proBar.InvokeRequired) { Action d = () => { proBar.Value++; }; proBar.Invoke(d); } else { proBar.Value++; } } } //DataSource = DataSrcType.PicFiles; return(files.Count()); }
public int InsertFaceInfoOverride(FaceInfo fi, int userid) { return(UpdateFaceInfo(fi, userid)); }
public int FindTopNSimilarFace(FaceInfo fi, int N, out int[] scores, out FaceInfo[] outfis) { if (N > this.FaceCount) { N = this.FaceCount; } if (fi == null || N == 0) { scores = null; outfis = null; return(-1); } int s, i; scores = new int[N]; FaceData fd0; FaceData[] outfds = new FaceData[N]; foreach (var fl in this) { foreach (FaceData fd in fl.Value) { s = _Face.FaceFeatureMatch(fi, fd); if (s > scores[N - 1]) { scores[N - 1] = s; outfds[N - 1] = fd; } else { continue; } for (i = N - 1; i > 0; i--) { if (scores[i] > scores[i - 1]) { //交换分数 s = scores[i]; scores[i] = scores[i - 1]; scores[i - 1] = s; //交换人脸数据 fd0 = outfds[i]; outfds[i] = outfds[i - 1]; outfds[i - 1] = fd0; } else { break; } } } } outfis = new FaceInfo[N]; for (i = 0; i < N; i++) { outfis[i] = new FaceInfo(outfds[i]); outfis[i].FaceShotBmp = this.GetUserImageById(outfds[i].userid); } return(N); }
private void onFaceShotAndFind(FaceInfo f, FaceEvent.EventType t) { try { bool isSame = false; if (f != null && f.userid == 0) { _LastFaceID = f.faceid; //更新抓拍全景照片 updateFullViewBmp(f); //更新抓拍特写照片 updateShotFace(f); //数据库检索并显示检索到的照片 int score = 0, uid = 0; FaceData fd = null; uid = FaceDic.FindMostSimilarFace(f, out score, out fd); //在TracingList中标记相同人脸 if (score >= Face.SameFaceThreshold) { f.userid = uid; isSame = true; //合并uid相同的人脸 FaceInfo mergeto; if (Face.MergeTracingList(f, out mergeto)) { //被合并后,需要删除 onRemoveFaceHander(f); return; } else { isSame = true; } } else { f.userid = 0; } f.text = score.ToString(); updateFoundPic(f, fd); } FaceEvent e = new FaceEvent { type = t, faceinfo = f, isFoundSame = isSame //userid = uid, //score = score }; if (SpeechEnable && isSame) { //进行语音播报 string text = FaceDic.GetUserName(f.userid); if (text.Trim().Length != 0) { text += ",你好。"; _Speech.SpeakAsync(text); } } //回调上层 if (FaceHandler != null) { FaceHandler(e); } } catch (Exception ex) { Console.WriteLine("FaceCamera->shotFaceAndFind:" + ex); } }
private Rectangle drawFaceWires() { //DateTime t1 = DateTime.Now; Rectangle rect = new Rectangle(Frame.Bitmap.Width / 2 - 50, Frame.Bitmap.Height / 2 - 50, 100, 100); //foreach (FaceInfo f in Face.TracingFaceList) for (int i = 0; i < Face.TracingFaceList.Count; i++) { FaceInfo f = Face.TracingFaceList[i]; if ((DateTime.Now - f.procTime).TotalMilliseconds > FaceRecgnize.MAX_FRAME_INTERVAL * 2) { continue; } //rect = f.getPos(); if (_LastFacePos.ContainsKey(f.faceid)) { rect = _LastFacePos[f.faceid]; //获取上次位置 int dx = f.posLeft + f.posRight - rect.Left - rect.Right; //框中心位置x的偏移量 int dy = f.posTop + f.posBottom - rect.Top - rect.Bottom; //y double d_ratio = Math.Sqrt(dx * dx + dy * dy) / 4 / rect.Width * 0.9; //本次画框坐标调整比率 int dw = f.FaceWidth() - rect.Width; //宽度偏移量 double w_ratio = (double)Math.Abs(dw) / rect.Width * 0.95; //宽度调整比率 rect.Height = rect.Width = rect.Width + (int)(dw * w_ratio); //新框宽高 if (rect.Width > 2 * f.FaceWidth() || rect.Width < f.FaceWidth() / 2) //安全矫正 { rect.Height = rect.Width = f.FaceWidth(); } rect.X = (int)((rect.Left + rect.Right + dx * d_ratio - rect.Width) / 2); //新框左上角x rect.Y = (int)((rect.Top + rect.Bottom + dy * d_ratio - rect.Width) / 2); //新框左上角y if (rect.X < 0 || rect.Y < 0 || rect.X > PictureWidth || rect.Y > PictureHight) //安全矫正 { rect = f.getPos(); } _LastFacePos[f.faceid] = rect;//记录本次位置 } else { rect = _LastFacePos[f.faceid] = f.getPos(); } //设置颜色 if (f.userid != 0) { Face.DrawPenColor = Color.Red; } else { Face.DrawPenColor = Color.Green; } //画框 Face.DrawFaceWire(Frame.Bitmap, rect); //人脸框上写字 if (_FaceCmd == FaceCommand.ShotOneAndFind || _FaceCmd == FaceCommand.ShotAllAndFind) { string strinfo = (f.userid == 0 ? "???" : FaceDic.GetUserName(f.userid)) + " " + (f.gender == FaceInfo.Gender.Mail ? "男" : "女") + " " + f.age + "岁"; Point strPos = new Point(rect.Left + rect.Width / 2, rect.Bottom + 3); StringFormat strformat = new StringFormat(); strformat.Alignment = StringAlignment.Center; Font font = new Font("微软雅黑", Math.Min(f.FaceWidth() / 20 + 7, 20)); SolidBrush sbrush = new SolidBrush(Face.DrawPenColor); Graphics g = Graphics.FromImage(Frame.Bitmap); g.DrawString(strinfo, font, sbrush, strPos, strformat); g.Dispose(); } } //Console.WriteLine("drawFaceWires: runtime=" + (DateTime.Now - t1).TotalMilliseconds); return(rect); }