/// <summary>
        /// Compare the ImageData with this Template and return a number from 0-100 that describe how the image close to the template
        /// </summary>
        public static double Compare(TemplateLogoInfo Template, byte[,] ImageData, int Start_X, int Start_Y, int Threshold)
        {
            var width  = Math.Min(ImageData.GetLength(0) - Start_X, Template.Width);
            var height = Math.Min(ImageData.GetLength(1) - Start_Y, Template.Height);

            if (width < Template.Width * 0.7)
            {
                return(0);
            }
            if (height < Template.Height * 0.7)
            {
                return(0);
            }

            byte[] backgroundColors = new byte[Template.BackgroundPixels.Count];
            byte[] objectsColors = new byte[Template.ObjectsPixels.Count];
            int    backgrounCounter = 0, objectsCounter = 0;

            foreach (var item in Template.BackgroundPixels)
            {
                backgroundColors[backgrounCounter++] = ImageData[item.X + Start_X, item.Y + Start_Y];
            }
            foreach (var item in Template.ObjectsPixels)
            {
                objectsColors[objectsCounter++] = ImageData[item.X + Start_X, item.Y + Start_Y];
            }

            var minObjectsPixels    = (int)(objectsColors.Length * 0.55);
            var minBackgroundPixels = (int)(backgroundColors.Length * 0.8);


            Array.Sort(objectsColors, 0, objectsCounter);
            var compareColor = objectsColors[objectsColors.Length / 2];

            var similarObjectsCount            = countCloseValues(objectsColors, compareColor, Threshold);
            var differentBackgroundPixelsCount = countDifferentValues(backgroundColors, compareColor, minBackgroundPixels, Threshold + 3);

            var failRatio = Math.Min(50.0 * similarObjectsCount / minObjectsPixels, 50.0 * differentBackgroundPixelsCount / minBackgroundPixels);

            if (failRatio > 40)
            {
            }
            if (failRatio < 50)
            {
                return(failRatio);
            }

            var vaildRatio = (65.0 * similarObjectsCount / objectsColors.Length) + (35.0 * differentBackgroundPixelsCount / backgroundColors.Length);

            return(vaildRatio);
        }
        /// <summary>
        /// Compare the ImageData with this Template and return a number from 0-100 that describe how the image close to the template
        /// </summary>
        public static double DetectLogo(Bitmap source)
        {
            var imageData = GetBitmapData(source, 1, RGBtoYUV);

            TemplateLogoInfo bestTemplate = null;
            int    bestTemplate_x = 0, bestTemplate_y = 0;
            double bestCompareValue = 0, temp;

            foreach (var template in LogoTemplates)
            {
                var width  = source.Width - template.Width;
                var height = source.Height - template.Height;
                for (int i = 0; i < width; i += 2)
                {
                    temp = 0;
                    for (int j = 0; j < height; j += 2)
                    {
                        var compare = Compare(template, imageData, i, j, 20);
                        if (compare < 50)
                        {
                            compare = Math.Max(compare, Compare(template, imageData, i, j, 13));
                        }
                        if (compare > temp)
                        {
                            temp = compare;
                        }
                        if (compare > bestCompareValue)
                        {
                            bestCompareValue = compare;
                            bestTemplate     = template;
                            bestTemplate_x   = i;
                            bestTemplate_y   = j;
                        }
                        if (bestCompareValue >= 50)
                        {
                            break;
                        }
                        if (compare < 25)
                        {
                            j += 2;
                        }
                    }
                    if (bestCompareValue >= 50)
                    {
                        break;
                    }
                    if (temp < 25)
                    {
                        i += 2;
                    }
                }

                if (bestCompareValue >= 50)
                {
                    break;
                }
            }
            //
            if (bestTemplate != null && bestCompareValue >= 50)
            {
                var data = bestTemplate.GetTemplateData(0, 1, 0);
                SetBitmapData(data, source, bestTemplate_x, bestTemplate_y, c => c == 0?Color.Empty: Color.Red);
            }
            return(bestCompareValue);
        }