using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; //подключение библиотек using Emgu.CV; using Emgu.CV.Structure; using Emgu.CV.Face; using Emgu.CV.CvEnum; using System.IO; using System.Threading; using System.Xml; using System.Drawing.Imaging; using System.Data.SqlClient; using DirectShowLib; using Emgu.CV.Util; using System.Runtime.CompilerServices; using Timer = System.Windows.Forms.Timer; using ZedGraph; using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel; namespace ImpulseVision { public partial class FormMain : Form { #region <Переменные> public event PropertyChangedEventHandler PropertyChanged; private VideoCapture Capture; private CascadeClassifier HaarCascade; private Image BgrFrame = null; private Image DetectedFace = null; private List FaceList = new List(); private VectorOfMat ImageList = new VectorOfMat(); private List NameList = new List(); private VectorOfInt LabelList = new VectorOfInt(); private EigenFaceRecognizer recognizer; private Timer CaptureTimer; #region FaceName private string UserName = string.Empty; private string faceName; public string FaceName { get { return faceName; } set { faceName = value.ToUpper(); UserName = faceName; //PbxFaces.Invoke(DispatcherPriority.Normal, new Action(() => { lblFaceName.Content = faceName; })); NotifyPropertyChanged(); } } #endregion #region CameraCaptureImage private Bitmap cameraCapture; public Bitmap CameraCapture { get { return cameraCapture; } set { cameraCapture = value; //imgCamera.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { imgCamera.Source = BitmapToImageSource(cameraCapture); })); PbxEther.Image = cameraCapture; //PbxFaces.Image = BitmapToImageSource(cameraCapture); NotifyPropertyChanged(); } } #endregion #region CameraCaptureFaceImage private Bitmap cameraCaptureFace; public Bitmap CameraCaptureFace { get { return cameraCaptureFace; } set { cameraCaptureFace = value; //imgDetectFace.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { imgDetectFace.Source = BitmapToImageSource(cameraCaptureFace); })); //PbxFaces.Image = BitmapToImageSource(cameraCapture); PbxEther.Image = cameraCapture; NotifyPropertyChanged(); } } #endregion int SelectedCameraID = -1; //доступные видеокамеры private DsDevice[] WebCams = null; int CountCams = -1; //множество для хранения списка камер HashSet HtBefore = new HashSet(); //включена ли на данный момент камера bool IsWorking = false; public static string TxtCon = $@"Data Source=213.155.192.79,3002;Initial Catalog=ImpulseVisionApp;Persist Security Info=True;User ID=u20teresh;Password=bfg2"; //хранение информации о выбранном пользователе UserItem CurrentUser = null; SqlConnection SCon = new SqlConnection(Properties.Settings.Default.ImpulseVisionAppConnectionString); //список с пользователями системы List LstUsers = new List(); //ID пользователя, который был только что добавлен string AddingUserID = string.Empty; //список, в котором хранятся пути изображений пользователей List LstPathImage = new List(); //уведомление о том, что сохранение выполнено bool Saving = false; #endregion //пути доступа к изображениям пользователей List LstUserPictures = new List(); struct Pictures { public string UserID, PicturePath; } struct Users { public string FIO, PassportSeria, PassportNum, UserID; } public FormMain() { InitializeComponent(); CaptureTimer = new Timer() { Interval = Config.TimerResponseValue }; CaptureTimer.Tick += CaptureTimer_Tick; } private void CaptureTimer_Tick(object sender, EventArgs e) { ProcessFrame(); } /// /// получение данных с камеры и обработка изображени /// private void ProcessFrame() { BgrFrame = Capture.QueryFrame().ToImage().Flip(FlipType.Horizontal); Pen PenForFace = new Pen(Brushes.Red, 5); Brush BrushForFace = Brushes.White; Font MyFont = new Font("Segoe UI Variable Small Semibol; 14pt; style=Bold", 14, FontStyle.Regular); Brush BrushInfo = Brushes.White; Pen PenInfo = new Pen(Brushes.White, 4); if (BgrFrame != null) { try {//for emgu cv bug Image grayframe = BgrFrame.Convert(); Rectangle[] Faces = HaarCascade.DetectMultiScale(grayframe, 1.2, 10, new System.Drawing.Size(50, 50), new System.Drawing.Size(200, 200)); //detect face FaceName = "No face detected"; foreach (var face in Faces) { BgrFrame.Draw(face, new Bgr(53, 23, 247), 2); DetectedFace = BgrFrame.Copy(face).Convert(); FaceRecognition(); break; } CameraCapture = BgrFrame.ToBitmap(); } catch (Exception ex) { //todo log } } } /// /// получение данных об изображениях /// public void GetFacesList() { //haar cascade classifier if (!File.Exists(Config.HaarCascadePath)) { string text = "Cannot find Haar cascade data file:\n\n"; text += Config.HaarCascadePath; DialogResult result = MessageBox.Show(text, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } HaarCascade = new CascadeClassifier(Config.HaarCascadePath); FaceList.Clear(); string line; FaceData faceInstance = null; // Create empty directory / file for face data if it doesn't exist if (!Directory.Exists(Config.FacePhotosPath)) { Directory.CreateDirectory(Config.FacePhotosPath); } if (!File.Exists(Config.FaceListTextFile)) { string text = "Cannot find face data file:\n\n"; text += Config.FaceListTextFile + "\n\n"; text += "If this is your first time running the app, an empty file will be created for you."; DialogResult result = MessageBox.Show(text, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); switch (result) { case DialogResult.OK: String dirName = Path.GetDirectoryName(Config.FaceListTextFile); Directory.CreateDirectory(dirName); File.Create(Config.FaceListTextFile).Close(); break; } } StreamReader reader = new StreamReader(Config.FaceListTextFile); int i = 0; while ((line = reader.ReadLine()) != null) { string[] lineParts = line.Split(':'); faceInstance = new FaceData(); faceInstance.FaceImage = new Image(Config.FacePhotosPath + lineParts[0] + Config.ImageFileExtension); faceInstance.PersonName = lineParts[1]; FaceList.Add(faceInstance); } foreach (var face in FaceList) { ImageList.Push(face.FaceImage.Mat); NameList.Add(face.PersonName); LabelList.Push(new[] { i++ }); } reader.Close(); // Train recogniser if (ImageList.Size > 0) { recognizer = new EigenFaceRecognizer(ImageList.Size); recognizer.Train(ImageList, LabelList); } } /// /// распознавание лица /// private void FaceRecognition() { if (ImageList.Size != 0) { //Eigen Face Algorithm FaceRecognizer.PredictionResult result = recognizer.Predict(DetectedFace.Resize(100, 100, Inter.Cubic)); FaceName = NameList[result.Label]; CameraCaptureFace = DetectedFace.ToBitmap(); } else { FaceName = "Please Add Face"; } } protected virtual void NotifyPropertyChanged([CallerMemberName] String propertyName = "") { var handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } private void FormMain_Load(object sender, EventArgs e) { HideAdding(); //скрытие заголовков вкладок в TabControl TabPages.Appearance = TabAppearance.FlatButtons; TabPages.ItemSize = new Size(0, 1); TabPages.SizeMode = TabSizeMode.Fixed; this.Show(); GetCams(); //ColorRegular(false); CmbCams.Visible = false; TslSelCamText.Visible = false; GetUsersFromDB(); } /// /// получение списка доступных камер /// private void GetCams() { WebCams = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice); CountCams = WebCams.Length; CmbCams.Items.Clear(); for (int i = 0; i < CountCams; i++) { CmbCams.Items.Add(WebCams[i].Name); HtBefore.Add(WebCams[i].Name); } if (CountCams > 0) { CmbCams.SelectedIndex = 0; SelectedCameraID = 0; } } private void BtnDelUser_Click(object sender, EventArgs e) { string IdUser = string.Empty; IdUser = CurrentUser.UserID; DialogResult Res = MessageBox.Show("Подтверждение данной операции приведёт к безвозвратному удалению пользователя из системы.\r\nПодтвердить удаление?", "ImpulseVision", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation); if (Res == DialogResult.No) return; SCon.Open(); string QueryDelUser = $@"delete from FaceImages where UserID = '{IdUser}'"; SqlCommand Cmd = new SqlCommand(QueryDelUser, SCon); Cmd.ExecuteNonQuery(); QueryDelUser = $@"delete from Users where ID = '{IdUser}'"; Cmd = new SqlCommand(QueryDelUser, SCon); Cmd.ExecuteNonQuery(); SCon.Close(); string PhotoName = string.Empty; for (int i = 0; i < LstUsers.Count; i++) { if (LstUsers[i].UserID == IdUser) { PhotoName = LstUsers[i].FIO.Split(' ')[1] + LstUsers[i].PassportSeria + LstUsers[i].PassportNum; } } try { //удалить из папки фотографию пользователя File.Delete(Application.StartupPath + Config.FacePhotosPath + $"{PhotoName}.bmp"); } catch { MessageBox.Show("Фотографии пользователя не найдены!", "ImpulseVision", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } GetUsersFromDB(); MessageBox.Show("Пользователь безвозвратно удалён из системы!", "ImpulseVision", MessageBoxButtons.OK, MessageBoxIcon.Information); } /// /// получение информации об идентификаторах пользователей и путях доступа к их фотографиям /// private void GetPicturesPath() { SCon.Open(); string Query1 = $@"select UserID,Picture from FaceImages"; SqlCommand Cmd = new SqlCommand(Query1, SCon); SqlDataReader Res = Cmd.ExecuteReader(); if (Res.HasRows) { LstUserPictures.Clear(); while (Res.Read()) { Pictures Pic = new Pictures(); Pic.UserID = Res["UserID"].ToString(); Pic.PicturePath = Res["Picture"].ToString(); LstUserPictures.Add(Pic); } } else { MessageBox.Show("Не удалось получить информацию об изображениях!", "ImpulseVision", MessageBoxButtons.OK, MessageBoxIcon.Error); } SCon.Close(); } /// /// показ окна добавления /// private void ShowAdding() { TableLayoutWorks.ColumnStyles[0].Width = 250; TableLayoutWorks.BackColor = Color.White; } /// /// скрытие окна добавления /// private void HideAdding() { TableLayoutWorks.ColumnStyles[0].Width = 0; TableLayoutWorks.BackColor = Color.Black; } private void PbxEther_Click(object sender, EventArgs e) { HideAdding(); } /// /// добавление нового пользоввателя /// private void BtnAddUser_Click(object sender, EventArgs e) { CmbCams.Visible = true; TslSelCamText.Visible = true; BtnEditUser.Enabled = false; BtnDelUser.Enabled = false; TbxLastname.Text = ""; TbxFirstname.Text = ""; TbxPatronymic.Text = ""; TbxPasportSeria.Text = ""; TbxPasportNum.Text = ""; TabPages.SelectTab(1); if (IsWorking) return; TableLayoutWorks.BackColor = Color.Black; IsWorking = true;//камера включена GetFacesList(); Capture = new VideoCapture(Config.ActiveCameraIndex); Capture.SetCaptureProperty(CapProp.Fps, 30); Capture.SetCaptureProperty(CapProp.FrameHeight, 450); Capture.SetCaptureProperty(CapProp.FrameWidth, 370); CaptureTimer.Start(); ShowAdding(); //ColorRegular(IsWorking); } /// /// распознавание изображения, его отображение и сохранение /// /* private void VideoCapture_ImageGrabbed(object sender, EventArgs e) { int CountAllRectangle = 0; int CountRecognize = 0; if (VideoCapture == null && VideoCapture.Ptr == IntPtr.Zero) return; //1. Захват видео VideoCapture.Retrieve(Frame, 0);//восстановить нулевой кадр CurrentFrame = Frame.ToImage().Flip(FlipType.Horizontal); //2. Обнаружение лиц if (FacesDetectionEnabled) { //преобразовать изображение в серое Mat GrayImage = new Mat(); CvInvoke.CvtColor(CurrentFrame, GrayImage, ColorConversion.Bgr2Gray); //выравнивание гистограммы изображения CvInvoke.EqualizeHist(GrayImage, GrayImage); CvInvoke.EqualizeHist(GrayImage, GrayImage); CvInvoke.EqualizeHist(GrayImage, GrayImage); Pen PenForFace = new Pen(Brushes.Red, 5); Brush BrushForFace = Brushes.White; Font MyFont = new Font("Segoe UI Variable Small Semibol; 14pt; style=Bold", 14, FontStyle.Regular); Brush BrushInfo = Brushes.White; Pen PenInfo = new Pen(Brushes.White, 4); Point PointInfo = new Point(CurrentFrame.Width - CurrentFrame.Width, 0); Graphics GraphInfo = Graphics.FromImage(CurrentFrame.Bitmap); //записать распознанные изображения в массив Rectangle[] RectFaces = Classifier.DetectMultiScale(GrayImage, 1.1, 3, Size.Empty, Size.Empty); GraphInfo.DrawString("Перед сохранением, убедитесь, что лицо\r\nхорошо освещено и находится в красном прямоугольнике.", MyFont, BrushInfo, PointInfo); //если лица обнаружены if (RectFaces.Length > 0) { foreach (Rectangle CurrentFace in RectFaces) { CountAllRectangle++; //нарисовать прямоугольники вокруг лиц //CvInvoke.Rectangle(CurrentFrame, CurrentFace, new Bgr(Color.White).MCvScalar, 5); Point PointForFace = new Point(CurrentFace.X, CurrentFace.Y); //результирующее изображение Image ResultImage = CurrentFrame.Convert(); Graphics Graph = Graphics.FromImage(CurrentFrame.Bitmap); Graph.DrawRectangle(PenForFace, PointForFace.X, PointForFace.Y, CurrentFace.Width, CurrentFace.Height); //позиция отрисовки имени человека Point PersonName = new Point(CurrentFace.X, CurrentFace.Y - 25); //Graph.DrawString("Распознано", MyFont, MyBrush, PersonName); //3. Добавление человека (лица) ////результирующее изображение //Image ResultImage = CurrentFrame.Convert(); ResultImage.ROI = CurrentFace; //отобразить на форме найденное изображение //PbxDetected.Image = ResultImage.ToBitmap(); //****************** TempImageForRazn = ResultImage; //если сохранение изображения включено if (EnableSaveImage) { //создать каталог, если он не существует string Path = Directory.GetCurrentDirectory() + $@"\TrainedImages\{TbxFirstname.Text.Trim()}{TbxPasportSeria.Text.Trim()}{TbxPasportNum.Text.Trim()}"; string PathPhoto = $@"\TrainedImages\{TbxFirstname.Text.Trim()}{TbxPasportSeria.Text.Trim()}{TbxPasportNum.Text.Trim()}"; if (!Directory.Exists(Path)) { Directory.CreateDirectory(Path); } //сохранить 30 изображений Task.Factory.StartNew(() => { Saving = false; string FullPath = string.Empty; LstPathImage.Clear(); for (int i = 0; i < 60; i++) { FullPath = PathPhoto + @"\" + TbxLastname.Text.Trim() + "+" + TbxFirstname.Text.Trim() + "__" + DateTime.Now.ToString("dd-MM-yyyy-hh-mm-ss") + Guid.NewGuid().ToString().Substring(0, 6) + ".jpg"; ResultImage.Resize(200, 200, Inter.Cubic).Save(Application.StartupPath + FullPath); LstPathImage.Add(FullPath); Thread.Sleep(200); } Saving = true; MessageBox.Show("Сохранение завершено!", "Результат операции.", MessageBoxButtons.OK, MessageBoxIcon.Information); //TrainImageFromDir(); }); } EnableSaveImage = false; if (BtnSave.InvokeRequired) { BtnSave.Invoke(new ThreadStart(delegate { BtnSave.Enabled = true; })); } //5. Узнавание изображения if (IsTrained) { Image GrayFaceResult = ResultImage.Convert().Resize(200, 200, Inter.Cubic); CvInvoke.EqualizeHist(GrayFaceResult, GrayFaceResult); var Result = Recognizer.Predict(GrayFaceResult); if (Result.Label > 0)//если лица найдены { CountRecognize++; BrushForFace = Brushes.LightGreen; Graph.DrawString($"{LstPersonNames[Result.Label]}", MyFont, BrushForFace, PersonName); GraphInfo.DrawString($"На изображении: {LstPersonNames[Result.Label]}", MyFont, BrushInfo, PointInfo); } else { BrushForFace = Brushes.LightPink; Graph.DrawString("Неизвестный", MyFont, BrushForFace, PersonName); } } } if(CountRecognize > CountRecognize/2) { MessageBox.Show("Распознан"); } } } //NormalizeImage(CurrentFrame); try { //вывести изображение в PictureBox PbxEther.Image = CurrentFrame.Bitmap; } catch(Exception ex) { MessageBox.Show(ex.Message, "Внимание!", MessageBoxButtons.OK, MessageBoxIcon.Error); } } */ /// /// выключение распознавания /// private void RecogniseOff() { HideAdding(); BtnDelUser.Enabled = true; if (Capture != null) { BgrFrame = null; Capture.Stop(); Capture.Dispose(); Capture = null; } PbxEther.Image = Properties.Resources._9110852_video_no_icon; TableLayoutWorks.BackColor = Color.Gray; IsWorking = false; } /// /// переключение цветов кнопок включения/выключения /// /// статус работы камеры private void ColorRegular(bool IsWorking) { if(IsWorking) { BtnAddUser.BackColor = Color.LightGreen; BtnEditUser.BackColor = Color.White; } else { BtnAddUser.BackColor = Color.White; BtnEditUser.BackColor = Color.LightPink; } } /// /// сохранение информации для нового пользователя /// private void BtnSave_Click(object sender, EventArgs e) { if (DetectedFace == null) { MessageBox.Show("Лица не обнаружены!\r\nУбедитесь что лицо находится в кадре и обведено красным прямоугольником.", "ImpulseVision", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } string PhotoPath = string.Empty; ProgressTrain.Value = 0; bool Flag = TbxLastname.Text.Trim() == "" || TbxFirstname.Text.Trim() == "" || TbxPasportSeria.Text.Trim() == "" || TbxPasportNum.Text.Trim() == ""; if(Flag) { MessageBox.Show("Заполните все поля и повторите попытку!", "Ошибка добавления!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } SCon.Open(); string QueryCheckPassport = $@"select PassportSeria,PassportNum from Users where PassportSeria = '{TbxPasportSeria.Text.Trim()}' and PassportNum = '{TbxPasportNum.Text.Trim()}'"; SqlCommand CmdCheck = new SqlCommand(QueryCheckPassport, SCon); SqlDataReader Res = CmdCheck.ExecuteReader(); if(Res.HasRows) { MessageBox.Show("Данные паспорта указаны неверно!", "ImpulseVision", MessageBoxButtons.OK, MessageBoxIcon.Error); SCon.Close(); ProgressTrain.Value = 0; return; } SCon.Close(); SCon.Open(); string QueryAdd = $@"insert into Users (Lastname,Firstname, Patronymic, PassportSeria, PassportNum,Phone, IDUserType) values (@last,@first,@patr,@seria,@number,@phone,3)"; SqlCommand Cmd = new SqlCommand(QueryAdd, SCon); Cmd.Parameters.AddWithValue("@last", TbxLastname.Text.Trim()); Cmd.Parameters.AddWithValue("@first", TbxFirstname.Text.Trim()); Cmd.Parameters.AddWithValue("@patr", TbxPatronymic.Text.Trim()); Cmd.Parameters.AddWithValue("@seria", TbxPasportSeria.Text.Trim()); Cmd.Parameters.AddWithValue("@number", TbxPasportNum.Text.Trim()); Cmd.Parameters.AddWithValue("@phone", TbxPhone.Text.Trim()); Cmd.ExecuteNonQuery();//выполнить запрос SCon.Close(); SCon.Open(); string QueryAddingUserID = $@"select MAX(ID) as LastID from Users"; Cmd = new SqlCommand(QueryAddingUserID, SCon); SqlDataReader ResID = Cmd.ExecuteReader(); if(ResID.HasRows) { ResID.Read(); //получить id только что добавленного пользователя AddingUserID = ResID["LastID"].ToString(); } SCon.Close(); //изменить размеры изображения DetectedFace = DetectedFace.Resize(100, 100, Inter.Cubic); //сохранить изображение в папку DetectedFace.Save(Config.FacePhotosPath + $"{TbxFirstname.Text.Trim()}{TbxPasportSeria.Text.Trim()}{TbxPasportNum.Text.Trim()}" + Config.ImageFileExtension); PhotoPath = Config.FacePhotosPath + $"{TbxFirstname.Text.Trim()}{TbxPasportSeria.Text.Trim()}{TbxPasportNum.Text.Trim()}" + Config.ImageFileExtension; TslStatus.Text = "Сохранение данных о пользователе..."; ProgressTrain.Value = 50; BtnSave.Text = "Сохранение..."; BtnSave.Text = "Сохранить"; //сохранение пути до фотографии SCon.Open(); string QueryAddPathImage = $@"insert into FaceImages (UserID,Picture) values ({AddingUserID},'{PhotoPath}')"; Cmd = new SqlCommand(QueryAddPathImage, SCon); Cmd.ExecuteNonQuery();//выполнить запрос на добавление пути фото для пользователя SCon.Close(); MessageBox.Show("Успешно сохранено!", "ImpulseVision", MessageBoxButtons.OK, MessageBoxIcon.Information); TimerSaving.Enabled = true; TimerSaving.Start(); TslStatus.Text = "Готов"; ProgressTrain.Value = 100; } /// /// тренировка изображения /// /// результат тренировки (true или false) /* private void TrainImageFromDir() { int CountImage = 0; //порог double Threshold = 10000; LstTrainedFaces.Clear(); PersonLabes.Clear(); LstPersonNames.Clear(); try { //ProgressTrain.Value += 15; string MyPath = Directory.GetCurrentDirectory() + @"\TrainedImages\"; string[] Files = Directory.GetFiles(MyPath, "*.jpg", SearchOption.AllDirectories); int n = Files.Length; foreach (string file in Files) { //ProgressTrain.Value += (int)PlusDigit; Image TrainedImage = new Image(file); //добавить обученное изображение LstTrainedFaces.Add(TrainedImage); PersonLabes.Add(CountImage); string CurrentFileName = Path.GetFileName(file); string Name = CurrentFileName.Remove(CurrentFileName.IndexOf("_"), CurrentFileName.Length - CurrentFileName.IndexOf("_")); //(0, CurrentFileName.Length - CurrentFileName.IndexOf("_") + 1); //добавить имя LstPersonNames.Add(Name); CountImage++; } if (CountImage == 0) { IsTrained = false; return; } //тренировка изображения Recognizer = new EigenFaceRecognizer(CountImage, Threshold); Recognizer.Train(LstTrainedFaces.ToArray(), PersonLabes.ToArray()); //ProgressTrain.Value += 100 - ProgressTrain.Value; //записать, что обучен IsTrained = true; MessageBox.Show("Тренировка изображений выполнена!"); } catch (Exception ex) { IsTrained = false; } } */ private void CmbCams_SelectedIndexChanged(object sender, EventArgs e) { try { //если захват видео уже идёт //if(VideoCapture != null) //{ // VideoCapture.Pause(); // VideoCapture.Stop(); // VideoCapture.Dispose(); // VideoCapture = null; // PbxEther.Image = null; // SelectedCameraID = -1; //} } catch(Exception ex) { MessageBox.Show(ex.Message, "Внимание!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } SelectedCameraID = CmbCams.SelectedIndex; if (IsWorking) { //VideoCapture = new VideoCapture(SelectedCameraID); //////VideoCapture.ImageGrabbed += VideoCapture_ImageGrabbed; //VideoCapture.Start(); //FacesDetectionEnabled = true;//включить распознавание //CvInvoke.UseOpenCL = true; } } private void FormMain_FormClosing(object sender, FormClosingEventArgs e) { } private void TimerNewCam_Tick(object sender, EventArgs e) { DsDevice[] Cams = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice); int Count = Cams.Length; //если количество подключённых камер изменилось if(Count != CountCams) { if (Count > CountCams) { StatusAddNewDevice(Cams); } else if(Count < CountCams) { StatusOffDevice(Cams); } GetCams(); } } /// /// уведомление об отключении web-камеры /// /// массив с доступными камерами async void StatusOffDevice(DsDevice[] cams) { HashSet HtAfter = new HashSet(); foreach(DsDevice device in cams) { HtAfter.Add(device.Name); } HtBefore.Except(HtAfter); ProgressTrain.Value = 0; TslStatus.Text = $"Устройство: {string.Join(" ",HtBefore)} - отключено"; await Task.Delay(1000); ProgressTrain.Value = 100; TslStatus.Text = "Готов"; } /// /// уведомление о подключении нового устройствва /// /// массив с доступными web-камерами async void StatusAddNewDevice(DsDevice[] Cams) { TslStatus.Text = "Добавление нового устройства.."; ProgressTrain.Value = 0; while(ProgressTrain.Value < 100) { ProgressTrain.Value += 5; await Task.Delay(50); } TslStatus.Text = "Добавлено новое устройство"; await Task.Delay(1000); TslStatus.Text = $"{Cams[Cams.Length-1].Name}"; await Task.Delay(1000); ProgressTrain.Value = 100; TslStatus.Text = "Готов"; } private void BtnCheck_Click(object sender, EventArgs e) { TslStatus.Text = "Подождите.. выполняется анализ лица.."; ProgressTrain.Value = 45; //TrainImageFromDir(); //FaceDifferent(); //Task.Factory.StartNew(new Action(() => TrainImageFromDir())); //ProgressTrain.Value = 55; //TslStatus.Text = "Готов"; } private void PbxEther_Click_1(object sender, EventArgs e) { //HideAdding(); } private void STools_Click(object sender, EventArgs e) { TabPages.SelectTab(2); ToolsMenu.Enabled = false; } /// /// получить список пользователй системы /// private void SUsers_Click(object sender, EventArgs e) { } /// /// получение пользователей из БД /// private void GetUsersFromDB() { SCon.Open(); string QueryForGetUser = @"select ID, Lastname + ' ' + Firstname + ' ' + Patronymic as FIO, PassportSeria, PassportNum from Users"; SqlCommand Cmd = new SqlCommand(QueryForGetUser, SCon); SqlDataReader Res = Cmd.ExecuteReader(); LstUsers.Clear(); while (Res.Read()) { Users user = new Users(); user.FIO = Res["FIO"].ToString(); user.UserID = Res["ID"].ToString(); user.PassportSeria = Res["PassportSeria"].ToString(); user.PassportNum = Res["PassportNum"].ToString(); LstUsers.Add(user); } SCon.Close(); TabPages.SelectTab(0); TableUsers.Controls.Clear(); for (int i = 0; i < LstUsers.Count; i++) { UserItem Item = new UserItem(); Item.UserID = LstUsers[i].UserID; Item.LblNameUser.Text = LstUsers[i].FIO; Item.Click += User_Click; Item.LblNameUser.Click += Object_Click; TableUsers.Controls.Add(Item); if (TableUsers.Controls.Count == 1) { CurrentUser = Item; CurrentUser.BackColor = ColorTranslator.FromHtml("#C3EB78"); } } } /// /// выбор пользователя из списка /// private void Object_Click(object sender, EventArgs e) { CurrentUser.BackColor = Color.FromArgb(((int)(((byte)(184)))), ((int)(((byte)(184)))), ((int)(((byte)(255))))); CurrentUser = (sender as Control).Parent as UserItem; CurrentUser.BackColor = ColorTranslator.FromHtml("#C3EB78"); } private void User_Click(object sender, EventArgs e) { CurrentUser.BackColor = Color.FromArgb(((int)(((byte)(184)))), ((int)(((byte)(184)))), ((int)(((byte)(255))))); CurrentUser = sender as UserItem; CurrentUser.BackColor = ColorTranslator.FromHtml("#C3EB78"); } private void MExit_Click(object sender, EventArgs e) { Close(); } private void MMain_Click(object sender, EventArgs e) { CmbCams.Visible = false; TslSelCamText.Visible = false; BtnEditUser.Enabled = true; BtnDelUser.Enabled = true; RecogniseOff(); TabPages.SelectTab(0); } private void BtnEditUser_Click(object sender, EventArgs e) { FormEditUser FEdit = new FormEditUser(); FEdit.LblSelectUserID.Text = CurrentUser.UserID.ToString(); FEdit.ShowDialog(); GetUsersFromDB(); } private void TimerSaving_Tick(object sender, EventArgs e) { if (Saving) { MMain_Click(sender, e); GetUsersFromDB(); TimerSaving.Stop(); TimerSaving.Enabled = false; } } } }