/// <summary>
        /// Загрузка одного кадра (с изображения)
        /// </summary>
        /// <param name="data">Информация о кадре</param>
        /// <returns>Кадр</returns>
        public Task<GreyVideoFrame> LoadFrameAsync(object data)
        {
            try
            {
                if (data == null)
                    throw new ArgumentNullException("Null data in LoadFrameAsync");
                IOData ioData = (IOData)data;
                string frameFileName = ioData.FileName;
                if (frameFileName == null || frameFileName.Length == 0)
                    throw new ArgumentNullException("Null frameFileName in LoadFrameAsync");
                if (ioData.FrameHeight <= 0)
                    throw new ArgumentException("Error frameHeight value in LoadFrameAsync");
                if (ioData.FrameWidth <= 0)
                    throw new ArgumentException("Error frameWidth value in LoadFrameAsync");

                return Task.Run(() =>
                {
                    Size size = new Size(ioData.FrameWidth, ioData.FrameHeight);
                    Bitmap bitmapFrame = new Bitmap(frameFileName);

                  //  bitmapFrame.SetResolution(ioData.FrameWidth, ioData.FrameHeight);
                    BitmapConvertor bitmapConvertor = new BitmapConvertor();
                    GreyVideoFrame greyVideoFrame = new GreyVideoFrame();

                    greyVideoFrame.Frame = bitmapConvertor.ToGreyImage(bitmapFrame);
                    return greyVideoFrame;
                });
            }
            catch (Exception exception)
            {
                throw exception;
            }
        }
        /// <summary>
        /// Добавление ключевого кадра в список ключевых кадров
        /// </summary>
        /// <param name="keyFrames">Список клбючевых кадров</param>
        /// <param name="frame">Ключевой кадр</param>
        /// <param name="frameFileName">Имя файла для сохранения ключевого кадра</param>
        /// <param name="frameNumber">Номер ключевого кадра</param>
        /// <param name="needProcess">Нуждается ли кадр в обработке</param>
        private void AddKeyFrameFunction(List<GreyVideoFrame> keyFrames, Image<Gray, Byte> frame, string frameFileName, int frameNumber,
            bool needProcess)
        {
            try
            {
                frame.Save(frameFileName);
                Bitmap bitmapFrame = new Bitmap(frameFileName);

                GreyVideoFrame keyFrame = new GreyVideoFrame();
                keyFrame.FrameNumber = frameNumber;
                BitmapConvertor bitmapConvertor = new BitmapConvertor();
                keyFrame.Frame = bitmapConvertor.ToGreyImage(bitmapFrame);
                keyFrame.NeedProcess = needProcess;
                keyFrames.Add(keyFrame);
            }
            catch (Exception exception)
            {
                throw exception;
            }
        }
        /// <summary>
        /// Сохранение одного кадра видео
        /// </summary>
        /// <param name="videoFrame"></param>
        /// <param name="pen"></param>
        /// <param name="saveFileName"></param>
        public Task<bool> SaveVideoFrameAsync(GreyVideoFrame videoFrame, System.Drawing.Pen pen, string saveFileName)
        {
            try
            {
                if (videoFrame == null || videoFrame.Frame == null)
                    throw new ArgumentNullException("Null videoFrame");
                if (saveFileName == null || saveFileName.Length == 0)
                    throw new ArgumentNullException("Null saveFileName");
                if (pen == null)
                    throw new ArgumentNullException("Null pen");

                return Task.Run(() =>
                {
                    BitmapConvertor bitmapConvertor = new BitmapConvertor();
                    Bitmap bitmapFrame = bitmapConvertor.ToBitmap(videoFrame.Frame);

                    Draw.DrawTextBoundingBoxes(bitmapFrame, videoFrame.Frame.TextRegions, pen);
                    bitmapFrame.Save(saveFileName);

                    return true;
                });
            }
            catch (Exception exception)
            {
                throw exception;
            }
        }
        private void AddProcessedFrameToBitmapArray(GreyVideoFrame videoFrame)
        {
            try
            {
                if (this.processedVideoFramesBitmap == null)
                    this.processedVideoFramesBitmap = new List<BitmapImage>();
                if (this.processedVideoFramesBitmapForSave == null)
                    this.processedVideoFramesBitmapForSave = new List<Bitmap>();
                if (this.textRegionsDictionary == null)
                    this.textRegionsDictionary = new Dictionary<int, List<TextRegion>>();

                this.textRegionsDictionary.Add(videoFrame.FrameNumber, videoFrame.Frame.TextRegions);

                BitmapConvertor bitmapConvertor = new BitmapConvertor();
                BitmapImageConvertor bitmapImageConvertor = new Convertors.BitmapImageConvertor();

                Bitmap bitmapFrame = bitmapConvertor.ToBitmap(videoFrame.Frame);
                Draw.DrawTextBoundingBoxes(bitmapFrame, videoFrame.Frame.TextRegions, new System.Drawing.Pen(System.Drawing.Color.Red, 2));
                this.processedVideoFramesBitmapForSave.Add(bitmapFrame);
                this.processedVideoFramesBitmap.Add(bitmapImageConvertor.BitmapToBitmapImage(bitmapFrame));      
            }
            catch (Exception exception)
            {
                throw exception;
            }
        }
        /// <summary>
        /// Выделение текста на на единичном кадре видео
        /// </summary>
        private async void DetectVideoFrameTextFunction()
        {
            try
            {
                EvristicsWindow evristicsWindow = EvristicsWindow.InitializeEvristicsWindow();
                evristicsWindow.capitalText.Text = PARAMETERS_SETTING_STRING;
                evristicsWindow.ShowDialog();

                AlgorithmParametersWindow algorithmParametersWindow = AlgorithmParametersWindow.InitializeAlgorithmParametersWindow();
                algorithmParametersWindow.capitalText.Text = PARAMETERS_SETTING_STRING;
                algorithmParametersWindow.ShowDialog();

                EvristicsWindowViewModel evristicsWindowDataContext = (EvristicsWindowViewModel)evristicsWindow.DataContext;
                AlgorithmParametersViewModel algorithmParametersWindowDataContext = (AlgorithmParametersViewModel)algorithmParametersWindow.DataContext;

                SWTVideoTextDetection SWTVideoTextDetection = new SWTVideoTextDetection(evristicsWindowDataContext.VarienceAverageSWRation,
                    algorithmParametersWindowDataContext.GaussFilterSize, algorithmParametersWindowDataContext.GaussSigma, algorithmParametersWindowDataContext.CannyLowTreshold,
                    algorithmParametersWindowDataContext.CannyHighTreshold, evristicsWindowDataContext.AspectRatio, evristicsWindowDataContext.DiamiterSWRatio,
                    evristicsWindowDataContext.BbPixelsNumberMinRatio, evristicsWindowDataContext.BbPixelsNumberMaxRatio,
                    evristicsWindowDataContext.ImageRegionHeightRationMin, evristicsWindowDataContext.ImageRegionWidthRatioMin, evristicsWindowDataContext.PairsHeightRatio,
                    evristicsWindowDataContext.PairsIntensityRatio, evristicsWindowDataContext.PairsSWRatio, evristicsWindowDataContext.PairsWidthDistanceSqrRatio,
                    evristicsWindowDataContext.PairsOccupationRatio, evristicsWindowDataContext.MinLettersNumberInTextRegion,
                    evristicsWindowDataContext.MergeByDirectionAndChainEnds, evristicsWindowDataContext.UseAdaptiveSmoothing);

                this.StartLoader(DETECT_TEXT_VIDEO_FRAME_STRING);
                await SWTVideoTextDetection.DetectText(this.videoFrame, 4);
                this.StopLoader();

                OkButtonWindow okButtonWindow = OkButtonWindow.InitializeOkButtonWindow();
                okButtonWindow.capitalText.Text = FRAME_PROCESS_STRING;
                okButtonWindow.textInformation.Text = FRAME_PROCESS_SUCCESS_STRING;
                okButtonWindow.ShowDialog();

                BitmapConvertor bitmapConvertor = new BitmapConvertor();
                Bitmap bitmapFrame = bitmapConvertor.ToBitmap(this.videoFrame.Frame);
                Draw.DrawTextBoundingBoxes(bitmapFrame, this.videoFrame.Frame.TextRegions, new System.Drawing.Pen(System.Drawing.Color.Red, 2));

                BitmapImageConvertor bitmapImageConvertor = new Convertors.BitmapImageConvertor();
                this.ProcessedFrameSource = bitmapImageConvertor.BitmapToBitmapImage(bitmapFrame);

                this.IsVideoFrameTabSelected = false;
                this.IsProcessedVideoFramesTabSelected = false;
                this.IsProcessedVideoFrameTabSelected = true;
                this.IsVideoTabSelected = false;
            }
            catch (Exception exception)
            {
                this.StopLoader();
                ShowExceptionMessage(exception.Message);
            }
        }      
        /// <summary>
        /// Запись обработанных ключевых кадров видео в виде BitmapImage, отрисовка прямоугольников текстовых областей
        /// </summary>
        private void CreateBitmapsFromProcessedVideoFrames()
        {
            try
            {
                this.processedVideoFramesBitmap = new List<BitmapImage>();
                BitmapConvertor bitmapConvertor = new BitmapConvertor();
                BitmapImageConvertor bitmapImageConvertor = new Convertors.BitmapImageConvertor();

                for (int i = 0; i < this.video.Frames.Count; i++)
                {
                    Bitmap bitmapFrame = bitmapConvertor.ToBitmap(this.video.Frames[i].Frame);
                    Draw.DrawTextBoundingBoxes(bitmapFrame, this.video.Frames[i].Frame.TextRegions, new System.Drawing.Pen(System.Drawing.Color.Red, 2));
                    this.processedVideoFramesBitmap.Add(bitmapImageConvertor.BitmapToBitmapImage(bitmapFrame));
                }
            }
            catch (Exception exception)
            {
                throw exception;
            }
        }
        /// <summary>
        /// Создание кадра видео 
        /// </summary>
        /// <param name="frame">Кадр</param>
        /// <param name="keyFrameIOInformation">Информация о кадре</param>      
        /// <returns>Кадр</returns>
        private GreyVideoFrame CreateVideoFrame(Image<Gray, byte> frame, KeyFrameIOInformation keyFrameIOInformation)
        {
            try
            {
              //  Bitmap bitmapFrame = new Bitmap(frameFileName);

                ImageConvertor ImageConvertor = new DigitalVideoProcessingLib.IO.ImageConvertor();

                GreyVideoFrame keyFrame = new GreyVideoFrame();
                keyFrame.FrameNumber = keyFrameIOInformation.Number;
                BitmapConvertor bitmapConvertor = new BitmapConvertor();

                keyFrame.Frame = ImageConvertor.ConvertColor(frame);//bitmapConvertor.ToGreyImage(bitmapFrame);

                keyFrame.NeedProcess = keyFrameIOInformation.NeedProcess;
                keyFrame.AspectRatio = keyFrameIOInformation.AspectRatio;
                keyFrame.BbPixelsNumberMaxRatio = keyFrameIOInformation.BbPixelsNumberMaxRatio;
                keyFrame.BbPixelsNumberMinRatio = keyFrameIOInformation.BbPixelsNumberMinRatio;
                keyFrame.DiamiterSWRatio = keyFrameIOInformation.DiamiterSWRatio;
                keyFrame.ImageRegionHeightRationMin = keyFrameIOInformation.ImageRegionHeightRationMin;
                keyFrame.ImageRegionWidthRatioMin = keyFrameIOInformation.ImageRegionWidthRatioMin;
                keyFrame.MergeByDirectionAndChainEnds = keyFrameIOInformation.MergeByDirectionAndChainEnds;
                keyFrame.MinLettersNumberInTextRegion = keyFrameIOInformation.MinLettersNumberInTextRegion;
                keyFrame.PairsHeightRatio = keyFrameIOInformation.PairsHeightRatio;
                keyFrame.PairsIntensityRatio = keyFrameIOInformation.PairsIntensityRatio;
                keyFrame.PairsOccupationRatio = keyFrameIOInformation.PairsOccupationRatio;
                keyFrame.PairsSWRatio = keyFrameIOInformation.PairsSWRatio;
                keyFrame.PairsWidthDistanceSqrRatio = keyFrameIOInformation.PairsWidthDistanceSqrRatio;
                keyFrame.UseAdaptiveSmoothing = keyFrameIOInformation.UseAdaptiveSmoothing;
                keyFrame.VarienceAverageSWRation = keyFrameIOInformation.VarienceAverageSWRation;
                keyFrame.GaussFilterSize = keyFrameIOInformation.GaussFilterSize;
                keyFrame.GaussFilterSigma = keyFrameIOInformation.GaussFilterSigma;
                keyFrame.CannyLowTreshold = keyFrameIOInformation.CannyLowTreshold;
                keyFrame.CannyHighTreshold = keyFrameIOInformation.CannyHighTreshold;
                return keyFrame;
            }
            catch (Exception exception)
            {
                throw exception;
            }
        }