/// <summary>
        /// Вычисление метрик для видеоряда
        /// </summary>
        /// <param name="metricsList">Метрики</param>
        /// <param name="patternTextBlocks">Эталонные текстовые блоки</param>
        /// <param name="generatedTextBlocks">Сгенерированные текстовые блоки</param>
        private void CalculateMetricsForVideo(Dictionary<int, List<Metric>> metricsList, List<TextRegion> patternTextBlocks, List<TextRegion> generatedTextBlocks)
        {
            try
            {
                AbstractMetricFactory firstTypeErrorProbabilityMF = new FirstTypeErrorProbabilityMetricFactory();
                AbstractMetricFactory secondTypeErrorProbabilityMF = new SecondTypeErrorProbabilityMetricFactory();
                AbstractMetricFactory missingTypeErrorProbabilityMF = new MissingProbabilityMetricFactory();
                AbstractMetricFactory precisionMetricFactory = new PrecisionMetricFactory();
                AbstractMetricFactory recallMetricFactory = new RecallMetricFactory();
                AbstractMetricFactory f1MeasureMetricFactory = new F1MeasureMetricFactory();

                int textBlocksWithMissedDataNumber = 0;
                int falseTextBlockNumber = 0;
                int notDetectedTextBlocksNumber = 0;
                double precision = 0.0;
                CalculateTextBlocksTypesNumber(patternTextBlocks, generatedTextBlocks, out textBlocksWithMissedDataNumber,
                    out falseTextBlockNumber, out notDetectedTextBlocksNumber, out precision);

                List<Metric> metrics = new List<Metric>();
                metrics.Add(secondTypeErrorProbabilityMF.GetMetric(falseTextBlockNumber, generatedTextBlocks.Count));
                metrics.Add(firstTypeErrorProbabilityMF.GetMetric(notDetectedTextBlocksNumber, patternTextBlocks.Count));
                metrics.Add(missingTypeErrorProbabilityMF.GetMetric(textBlocksWithMissedDataNumber, generatedTextBlocks.Count - falseTextBlockNumber));
                metrics.Add(precisionMetricFactory.GetMetric(precision));

                double recall = 0.0;
                CalculateTextBlocksTypesNumber(generatedTextBlocks, patternTextBlocks, out textBlocksWithMissedDataNumber,
                    out falseTextBlockNumber, out notDetectedTextBlocksNumber, out recall);

                metrics.Add(recallMetricFactory.GetMetric(recall));
                if (precision == Metric.UNDEFINED_METRIC || recall == Metric.UNDEFINED_METRIC)
                    metrics.Add(f1MeasureMetricFactory.GetMetric(precision, recall));
                else
                {
                    double denominator = (this.Alhpa / precision) + ((1 - this.Alhpa) / recall);
                    metrics.Add(f1MeasureMetricFactory.GetMetric(1.0, denominator));
                }
                metricsList.Add(VIDEO_METRICS, metrics);
            }
            catch (Exception exception)
            {
                throw exception;
            }
        }
        /// <summary>
        /// Вычисленение метрик для видео
        /// </summary>
        /// <param name="metricsList">Метрики</param>
        private void CalculateMetricsForVideo(Dictionary<int, List<Metric>> metricsList)
        {
            try
            {
                AbstractMetricFactory firstTypeErrorProbabilityMF = new FirstTypeErrorProbabilityMetricFactory();
                AbstractMetricFactory secondTypeErrorProbabilityMF = new SecondTypeErrorProbabilityMetricFactory();
                AbstractMetricFactory missingTypeErrorProbabilityMF = new MissingProbabilityMetricFactory();
                AbstractMetricFactory precisionMetricFactory = new PrecisionMetricFactory();
                AbstractMetricFactory recallMetricFactory = new RecallMetricFactory();
                AbstractMetricFactory f1MeasureMetricFactory = new F1MeasureMetricFactory();

                double secondTypeErrorMetric = 0, firstTypeErrorMetric = 0, precisionMetric = 0,
                    recallMetric = 0, f1Metric = 0, missingTypeErrorMetric = 0;
                int secondTypeErrorMetricNumber = 0, firstTypeErrorMetricNumber = 0, precisionMetricNumber = 0,
                    recallMetricNumber = 0, f1MetricNumber = 0, missingTypeErrorMetricNumber = 0;
                foreach (var pair in metricsList)
                {
                    List<Metric> metrisFrame = pair.Value;
                    for (int i = 0; i < metrisFrame.Count; i++)
                    {
                        if (metrisFrame[i].GetType() == typeof(SecondTypeErrorProbability) && metrisFrame[i].Value != Metric.UNDEFINED_METRIC)
                        {
                            secondTypeErrorMetric += metrisFrame[i].Value;
                            secondTypeErrorMetricNumber++;
                        }
                        else if (metrisFrame[i].GetType() == typeof(FirstTypeErrorProbability) && metrisFrame[i].Value != Metric.UNDEFINED_METRIC)
                        {
                            firstTypeErrorMetric += metrisFrame[i].Value;
                            firstTypeErrorMetricNumber++;
                        }
                        else if (metrisFrame[i].GetType() == typeof(MissingProbability) && metrisFrame[i].Value != Metric.UNDEFINED_METRIC)
                        {
                            missingTypeErrorMetric += metrisFrame[i].Value;
                            missingTypeErrorMetricNumber++;
                        }
                        else if (metrisFrame[i].GetType() == typeof(Precision) && metrisFrame[i].Value != Metric.UNDEFINED_METRIC)
                        {
                            precisionMetric += metrisFrame[i].Value;
                            precisionMetricNumber++;
                        }
                        else if (metrisFrame[i].GetType() == typeof(Recall) && metrisFrame[i].Value != Metric.UNDEFINED_METRIC)
                        {
                            recallMetric += metrisFrame[i].Value;
                            recallMetricNumber++;
                        }
                        else if (metrisFrame[i].GetType() == typeof(F1Measure) && metrisFrame[i].Value != Metric.UNDEFINED_METRIC)
                        {
                            f1Metric += metrisFrame[i].Value;
                            f1MetricNumber++;
                        }
                    }
                }
                List<Metric> videoMetricList = new List<Metric>();
                videoMetricList.Add(secondTypeErrorProbabilityMF.GetMetric(secondTypeErrorMetric, secondTypeErrorMetricNumber));
                videoMetricList.Add(firstTypeErrorProbabilityMF.GetMetric(firstTypeErrorMetric, firstTypeErrorMetricNumber));
                videoMetricList.Add(missingTypeErrorProbabilityMF.GetMetric(missingTypeErrorMetric, missingTypeErrorMetricNumber));
                videoMetricList.Add(precisionMetricFactory.GetMetric(precisionMetric, precisionMetricNumber));
                videoMetricList.Add(recallMetricFactory.GetMetric(recallMetric, recallMetricNumber));
                videoMetricList.Add(f1MeasureMetricFactory.GetMetric(f1Metric, f1MetricNumber));

                metricsList.Add(VIDEO_METRICS, videoMetricList);
            }
            catch (Exception exception)
            {
                throw exception;
            }
        }
        /// <summary>
        /// Обработка метрик одного узла файла
        /// </summary>
        /// <param name="xmlNode">Узел</param>
        /// <param name="metricsList">Метрики</param>
        /// <param name="frameNumber">Номер кадра</param>
        private static void ReadXmlNode(XmlNode xmlNode, out List<Metric> metricsList, out int frameNumber)
        {
            try
            {
                metricsList = new List<Metric>();
                frameNumber = 0;
                AbstractMetricFactory firstTypeErrorProbabilityMF = new FirstTypeErrorProbabilityMetricFactory();
                AbstractMetricFactory secondTypeErrorProbabilityMF = new SecondTypeErrorProbabilityMetricFactory();
                AbstractMetricFactory missingTypeErrorProbabilityMF = new MissingProbabilityMetricFactory();
                AbstractMetricFactory precisionMetricFactory = new PrecisionMetricFactory();
                AbstractMetricFactory recallMetricFactory = new RecallMetricFactory();
                AbstractMetricFactory f1MeasureMetricFactory = new F1MeasureMetricFactory();

                if (xmlNode.Attributes != null)
                {
                    string attributeValue = xmlNode.Attributes["ID"].Value;
                    if (attributeValue != null)
                        frameNumber = Convert.ToInt32(attributeValue);
                }
                string secondTypeString = xmlNode["SecondTypeErrorProbability"].InnerText;
                if (secondTypeString == "UNDEFINED_METRIC")
                    metricsList.Add(secondTypeErrorProbabilityMF.GetMetric(Metric.UNDEFINED_METRIC));
                else
                    metricsList.Add(secondTypeErrorProbabilityMF.GetMetric(Convert.ToDouble(secondTypeString)));

                string firstTypeString = xmlNode["FirstTypeErrorProbability"].InnerText;
                if (firstTypeString == "UNDEFINED_METRIC")
                    metricsList.Add(firstTypeErrorProbabilityMF.GetMetric(Metric.UNDEFINED_METRIC));
                else
                    metricsList.Add(firstTypeErrorProbabilityMF.GetMetric(Convert.ToDouble(firstTypeString)));

                string missingTypeString = xmlNode["MissingProbability"].InnerText;
                if (missingTypeString == "UNDEFINED_METRIC")
                    metricsList.Add(missingTypeErrorProbabilityMF.GetMetric(Metric.UNDEFINED_METRIC));
                else
                    metricsList.Add(missingTypeErrorProbabilityMF.GetMetric(Convert.ToDouble(missingTypeString)));

                string precisionString = xmlNode["Precision"].InnerText;
                if (precisionString == "UNDEFINED_METRIC")
                    metricsList.Add(precisionMetricFactory.GetMetric(Metric.UNDEFINED_METRIC));
                else
                    metricsList.Add(precisionMetricFactory.GetMetric(Convert.ToDouble(precisionString)));

                string recallString = xmlNode["Recall"].InnerText;
                if (recallString == "UNDEFINED_METRIC")
                    metricsList.Add(recallMetricFactory.GetMetric(Metric.UNDEFINED_METRIC));
                else
                    metricsList.Add(recallMetricFactory.GetMetric(Convert.ToDouble(recallString)));

                string f1MeasureString = xmlNode["F1Measure"].InnerText;
                if (f1MeasureString == "UNDEFINED_METRIC")
                    metricsList.Add(f1MeasureMetricFactory.GetMetric(Metric.UNDEFINED_METRIC));
                else
                    metricsList.Add(f1MeasureMetricFactory.GetMetric(Convert.ToDouble(f1MeasureString)));
            }
            catch (Exception exception)
            {
                throw exception;
            }
        }