public static OsdFieldInfo ExtractFieldInfo(List<OcredChar> ocredChars)
        {
            var rv = new OsdFieldInfo();

            var output = new StringBuilder();
            foreach (OcredChar ocredChar in ocredChars)
            {
                if (ocredChar.RecognizedChar != '\0')
                    output.Append(ocredChar.RecognizedChar);
                else
                {
                    if (ocredChar.CharId == 0) ocredChar.FailedToRecognizeCorrectly = true;
                    if (ocredChar.CharId == 1) ocredChar.FailedToRecognizeCorrectly = true;
                    if (ocredChar.CharId >= 3 && ocredChar.CharId <= 8) ocredChar.FailedToRecognizeCorrectly = true;
                    if (ocredChar.CharId == 17) ocredChar.FailedToRecognizeCorrectly = true;

                    output.Append(" ");
                }
            }

            string charsOnly = output.ToString();

            rv.GpsFixStyatus = charsOnly[0] + "";
            if (!int.TryParse(charsOnly[1] + "", out rv.NumSatellites))
                ocredChars[1].FailedToRecognizeCorrectly = true;
            else
            {
                if (rv.GpsFixStyatus == "N" && rv.NumSatellites != 0)
                    ocredChars[1].FailedToRecognizeCorrectly = true;
                else if (rv.GpsFixStyatus == "G" && (rv.NumSatellites < 1 || rv.NumSatellites > 3))
                    ocredChars[1].FailedToRecognizeCorrectly = true;
                else if (rv.GpsFixStyatus == "P" && rv.NumSatellites < 4)
                    ocredChars[1].FailedToRecognizeCorrectly = true;
            }

            int hh = 0;
            int.TryParse(charsOnly.Substring(3, 2).Trim(), out hh);

            int mm = 0;
            int.TryParse(charsOnly.Substring(5, 2).Trim(), out mm);

            int ss = 0;
            int.TryParse(charsOnly.Substring(7, 2).Trim(), out ss);

            int ms1 = 0;
            if (!int.TryParse(charsOnly.Substring(9, 4).Trim(), out ms1))
            {
                string strToParse = charsOnly.Substring(9, 4);
                if (strToParse.Trim().Length > 0)
                {
                    for (int i = 0; i < strToParse.Length; i++)
                    {
                        if (strToParse[i] == ' ')
                            ocredChars[9 + i].FailedToRecognizeCorrectly = true;
                    }
                }
            }

            int ms2 = 0;
            if (!int.TryParse(charsOnly.Substring(13, 4).Trim(), out ms2))
            {
                string strToParse = charsOnly.Substring(9, 4);
                if (strToParse.Trim().Length > 0)
                {
                    for (int i = 0; i < strToParse.Length; i++)
                    {
                        if (strToParse[i] == ' ')
                            ocredChars[13 + i].FailedToRecognizeCorrectly = true;
                    }
                }
            }

            string fieldNoStr = charsOnly.Substring(17).TrimEnd();
            if (string.IsNullOrEmpty(fieldNoStr))
                rv.FieldNumber = -1;
            else
            {
                if (!long.TryParse(fieldNoStr, out rv.FieldNumber))
                {

                    for (int i = 0; i < fieldNoStr.Length; i++)
                    {
                        if (fieldNoStr[i] == ' ')
                            ocredChars[17 + i].FailedToRecognizeCorrectly = true;
                    }
                }
            }

            Trace.WriteLine(string.Format("{0}{1}{2}|{3}{4}:{5}{6}:{7}{8} {9}{10}{11}{12}{13}{14}{15}{16}|{17}{18}{19}{20}{21}{22}",
                charsOnly[0], charsOnly[1], charsOnly[2],
                charsOnly[3], charsOnly[4],
                charsOnly[5], charsOnly[6],
                charsOnly[7], charsOnly[8],
                charsOnly[9], charsOnly[10],charsOnly[11], charsOnly[12],
                charsOnly[13], charsOnly[14],charsOnly[15], charsOnly[16],
                charsOnly[17], charsOnly[18], charsOnly[19], charsOnly[20], charsOnly[21], charsOnly[22]));

            rv.TimeStamp = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, hh, mm, ss);

            if (ms1 != 0)
                rv.TimeStamp = rv.TimeStamp.AddMilliseconds(ms1 / 10);
            else
                rv.TimeStamp = rv.TimeStamp.AddMilliseconds(ms2 / 10);

            return rv;
        }
 public OsdFrameInfo(OsdFieldInfo oddField, OsdFieldInfo evenField)
 {
     ReCalculate(oddField, evenField);
 }
        private void ReCalculate(OsdFieldInfo field1, OsdFieldInfo field2)
        {
            bothFieldNumbersAndTimeStampsAreBad = false;

            if (Math.Abs(field1.FieldNumber - field2.FieldNumber) == 1)
                FrameNumber = Math.Min(field1.FieldNumber, field2.FieldNumber);

            GpsFixStyatus = field1.GpsFixStyatus;
            GpsAlmanacOk = field1.GpsAlmanacOk && field2.GpsAlmanacOk;
            NumSatellites = field1.NumSatellites;

            if (Math.Abs(field1.FieldNumber - field2.FieldNumber) == 1)
            {
                // Field numbers of the consequtive frames are OK. Use them to determine which frame is first and which is second
                if (field1.FieldNumber < field2.FieldNumber)
                {
                    StartTime = field1.TimeStamp;
                    EndTime = field2.TimeStamp;

                    FirstField = field1;
                    SecondField = field2;
                }
                else
                {
                    StartTime = field2.TimeStamp;
                    EndTime = field1.TimeStamp;

                    FirstField = field2;
                    SecondField = field1;
                }
            }
            else if (Math.Abs(new TimeSpan(field1.TimeStamp.Ticks - field2.TimeStamp.Ticks).TotalMilliseconds) - 20 <= 1)
            {
                // Timestamps are OK. Use them to determine which frame is first and which is second
                if (field1.TimeStamp.Ticks < field2.TimeStamp.Ticks)
                {
                    StartTime = field1.TimeStamp;
                    EndTime = field2.TimeStamp;

                    FirstField = field1;
                    SecondField = field2;
                }
                else
                {
                    StartTime = field2.TimeStamp;
                    EndTime = field1.TimeStamp;

                    FirstField = field2;
                    SecondField = field1;
                }
            }
            else
            {
                bothFieldNumbersAndTimeStampsAreBad = true;
                FirstField = field1;
                SecondField = field2;
            }
        }
Beispiel #4
0
        public OsdFrameInfo ProcessFrame(int[,] pixels, long frameNo)
        {
            if (!ocrEnabled)
                return null;

            int IMAGE_HEIGHT = pixels.GetLength(0);
            int IMAGE_WIDTH = pixels.GetLength(1);

            int[,] tsPixelsOdd = new int[3 * ocrConfig.Alignment.CharHeight, IMAGE_WIDTH];
            int[,] tsPixelsEven = new int[3 * ocrConfig.Alignment.CharHeight, IMAGE_WIDTH];

            int OCR_LINES_FROM = ocrConfig.Alignment.FrameTopOdd;
            int OCR_LINES_TO = ocrConfig.Alignment.FrameTopEven + 2 * ocrConfig.Alignment.CharHeight;

            List<int> medianArray = new List<int>();

            for (int y = 0; y < IMAGE_HEIGHT; y++)
            {
                for (int x = 0; x < IMAGE_WIDTH; x++)
                {
                    if (y == 10 || y == 11)
                        medianArray.Add(pixels[y, x]);

                    int packedVal = zoneChecker.OcrPixelMap[y, x];
                    if (packedVal != 0)
                    {
                        int charId;
                        bool isOddField;
                        int zoneId;
                        int zonePixelId;

                        OcrZoneChecker.UnpackValue(packedVal, out charId, out isOddField, out zoneId, out zonePixelId);

                        OcredChar ocredChar = isOddField ? ocredCharsOdd[charId] : ocredCharsEven[charId];

                        ocredChar.Zones[zoneId][zonePixelId] = pixels[y, x];

                        if (isOddField)
                        {
                            int top = (y - OCR_LINES_FROM)/2;
                            tsPixelsOdd[top, x] = pixels[y, x];
                        }
                        else
                        {
                            int top = (y - OCR_LINES_FROM + 1) / 2;
                            tsPixelsEven[top, x] = pixels[y, x];
                        }
                    }

                    if (y >= OCR_LINES_FROM && y <= OCR_LINES_TO)
                    {
                        bool isOddFieldLine = (y - OCR_LINES_FROM) % 2 == 0;

                        if (isOddFieldLine)
                        {
                            int top = ocrConfig.Alignment.CharHeight + (y - OCR_LINES_FROM) / 2;
                            if (top >= 0 && top < tsPixelsOdd.GetLength(0) && x >= 0 && x < tsPixelsOdd.GetLength(1))
                                tsPixelsOdd[top, x] = pixels[y, x];
                            else
                                throw new IndexOutOfRangeException();
                        }
                        else
                        {
                            int top = ocrConfig.Alignment.CharHeight + (y - OCR_LINES_FROM + 1) / 2;
                            if (top >= 0 && top < tsPixelsEven.GetLength(0) && x >= 0 && x < tsPixelsEven.GetLength(1))
                                tsPixelsEven[top, x] = pixels[y, x];
                            else
                                throw new IndexOutOfRangeException();
                        }
                    }

                }
            }

            medianArray.Sort();
            int median = medianArray[medianArray.Count/2];

            for (int i = 0; i < ocredCharsOdd.Count; i++)
            {
                OcredChar ocredChar = ocredCharsOdd[i];
                ProcessChar(ocredChar, median, i);
            }

            for (int i = 0; i < ocredCharsEven.Count; i++)
            {
                OcredChar ocredChar = ocredCharsEven[i];
                ProcessChar(ocredChar, median, i);
            }

            OsdFieldInfo oddFieldInfo = null;
            OsdFieldInfo evenFieldInfo = null;

            try
            {
                oddFieldInfo = OsdFieldInfoExtractor.ExtractFieldInfo(ocredCharsOdd);
                evenFieldInfo = OsdFieldInfoExtractor.ExtractFieldInfo(ocredCharsEven);
            }
            catch (Exception)
            {
                oddFieldInfo = new OsdFieldInfo() { FieldNumber = 1 };
                evenFieldInfo = new OsdFieldInfo() { FieldNumber = 2 };
            }

            var frameInfo = new OsdFrameInfo(oddFieldInfo, evenFieldInfo);

            TestFrameResult testResult = frameInfo.FrameInfoIsOk() ? TestFrameResult.Okay : TestFrameResult.ErrorSaveScreenShotImages;// testContext.TestTimeStamp(frameInfo);

            if (ocrErrorReporting && testResult == TestFrameResult.ErrorSaveScreenShotImages && (oddFieldInfo.FieldNumber >= 0 || evenFieldInfo.FieldNumber >= 0))
            {
                Bitmap bmpOdd = CreateBitmapFromPixels(tsPixelsOdd);
                Bitmap bmpEven = CreateBitmapFromPixels(tsPixelsEven);

                int MAX_OFF_VALUE = median + (OcrCharRecognizer.MIN_ON_VALUE - median) / 4;

                using (Graphics g = Graphics.FromImage(bmpOdd))
                {
                    foreach (OcredChar ocredChar in ocredCharsOdd)
                    {
                        if (ocredChar.FailedToRecognizeCorrectly)
                            g.DrawString(ocredChar.RecognizedChar == '\0' ? "?" : ocredChar.RecognizedChar + "", s_DebugFont, Brushes.Tomato, ocredChar.LeftFrom + ocrConfig.Alignment.CharPositions[0], 2 * ocrConfig.Alignment.CharHeight - 2);
                        else
                            g.DrawString(ocredChar.RecognizedChar + "", s_DebugFont, Brushes.Yellow, ocredChar.LeftFrom + ocrConfig.Alignment.CharPositions[0], 2 * ocrConfig.Alignment.CharHeight - 2);

                        if (ocrConfig.Mode == DefinitionMode.Standard)
                        {
                            double[] zoneValues = ocredChar.ComputeZones();
                            for (int i = 0; i < zoneValues.Length; i++)
                            {
                                int left = ocredChar.LeftFrom + ocrConfig.Alignment.CharPositions[0] + 2 + i;
                                g.DrawLine(i % 2 == 0 ? Pens.Green : Pens.Red, left, 3 * ocrConfig.Alignment.CharHeight - 3, left, 3 * ocrConfig.Alignment.CharHeight);
                                Pen zonePen = Pens.Black;

                                    if (zoneValues[i] >= OcrCharRecognizer.MIN_ON_VALUE)
                                        zonePen = Pens.White;
                                    else if (zoneValues[i] > MAX_OFF_VALUE)
                                        zonePen = Pens.LightSalmon;
                                g.DrawLine(zonePen, left, 3 * ocrConfig.Alignment.CharHeight - 2, left, 3 * ocrConfig.Alignment.CharHeight);
                                g.DrawLine(i % 2 == 0 ? Pens.Green : Pens.Red, left, 3 * ocrConfig.Alignment.CharHeight - 1, left, 3 * ocrConfig.Alignment.CharHeight);
                            }
                        }
                        else if (ocrConfig.Mode == DefinitionMode.SplitZones)
                        {
                            double[] topZones;
                            double[] bottomZones;
                            ocredChar.ComputeSplitZones(out topZones, out bottomZones);
                            for (int i = 0; i < topZones.Length; i++)
                            {
                                int left = ocredChar.LeftFrom + ocrConfig.Alignment.CharPositions[0] + 2 + i;
                                g.DrawLine(i % 2 == 0 ? Pens.Green : Pens.Red, left, 3 * ocrConfig.Alignment.CharHeight - 3, left, 3 * ocrConfig.Alignment.CharHeight);
                                Pen zonePen = Pens.Black;

                                if (topZones[i] >= OcrCharRecognizer.MIN_ON_VALUE && bottomZones[i] < OcrCharRecognizer.MAX_OFF_VALUE)
                                    zonePen = Pens.White;
                                else if (topZones[i] < OcrCharRecognizer.MAX_OFF_VALUE && bottomZones[i] >= OcrCharRecognizer.MIN_ON_VALUE)
                                    zonePen = Pens.Black;
                                else
                                    zonePen = Pens.DarkRed;

                                g.DrawLine(zonePen, left, 3 * ocrConfig.Alignment.CharHeight - 2, left, 3 * ocrConfig.Alignment.CharHeight);
                                g.DrawLine(i % 2 == 0 ? Pens.Green : Pens.Red, left, 3 * ocrConfig.Alignment.CharHeight - 1, left, 3 * ocrConfig.Alignment.CharHeight);
                            }
                        }
                    }

                    g.Save();
                }

                using (Graphics g = Graphics.FromImage(bmpEven))
                {
                    foreach (OcredChar ocredChar in ocredCharsEven)
                    {
                        if (ocredChar.FailedToRecognizeCorrectly)
                            g.DrawString(ocredChar.RecognizedChar == '\0' ? "?" : ocredChar.RecognizedChar + "", s_DebugFont, Brushes.Tomato, ocredChar.LeftFrom + ocrConfig.Alignment.CharPositions[0], 2 * ocrConfig.Alignment.CharHeight - 2);
                        else
                            g.DrawString(ocredChar.RecognizedChar + "", s_DebugFont, Brushes.Yellow, ocredChar.LeftFrom + ocrConfig.Alignment.CharPositions[0], 2 * ocrConfig.Alignment.CharHeight - 2);

                        if (ocrConfig.Mode == DefinitionMode.Standard)
                        {
                            double[] zoneValues = ocredChar.ComputeZones();
                            for (int i = 0; i < zoneValues.Length; i++)
                            {
                                int left = ocredChar.LeftFrom + ocrConfig.Alignment.CharPositions[0] + 2 + i;
                                g.DrawLine(i % 2 == 0 ? Pens.Green : Pens.Red, left, 3 * ocrConfig.Alignment.CharHeight - 3, left, 3 * ocrConfig.Alignment.CharHeight);
                                Pen zonePen = Pens.Black;

                                if (zoneValues[i] >= OcrCharRecognizer.MIN_ON_VALUE)
                                    zonePen = Pens.White;
                                else if (zoneValues[i] > MAX_OFF_VALUE)
                                    zonePen = Pens.LightSalmon;
                                g.DrawLine(zonePen, left, 3 * ocrConfig.Alignment.CharHeight - 2, left, 3 * ocrConfig.Alignment.CharHeight);
                                g.DrawLine(i % 2 == 0 ? Pens.Green : Pens.Red, left, 3 * ocrConfig.Alignment.CharHeight - 1, left, 3 * ocrConfig.Alignment.CharHeight);
                            }
                        }
                        else if (ocrConfig.Mode == DefinitionMode.SplitZones)
                        {
                            double[] topZones;
                            double[] bottomZones;
                            ocredChar.ComputeSplitZones(out topZones, out bottomZones);
                            for (int i = 0; i < topZones.Length; i++)
                            {
                                int left = ocredChar.LeftFrom + ocrConfig.Alignment.CharPositions[0] + 2 + i;
                                g.DrawLine(i % 2 == 0 ? Pens.Green : Pens.Red, left, 3 * ocrConfig.Alignment.CharHeight - 3, left, 3 * ocrConfig.Alignment.CharHeight);
                                Pen zonePen = Pens.Black;

                                if (topZones[i] >= OcrCharRecognizer.MIN_ON_VALUE && bottomZones[i] < OcrCharRecognizer.MAX_OFF_VALUE)
                                    zonePen = Pens.White;
                                else if (topZones[i] < OcrCharRecognizer.MAX_OFF_VALUE && bottomZones[i] >= OcrCharRecognizer.MIN_ON_VALUE)
                                    zonePen = Pens.Black;
                                else
                                    zonePen = Pens.DarkRed;

                                g.DrawLine(zonePen, left, 3 * ocrConfig.Alignment.CharHeight - 2, left, 3 * ocrConfig.Alignment.CharHeight);
                                g.DrawLine(i % 2 == 0 ? Pens.Green : Pens.Red, left, 3 * ocrConfig.Alignment.CharHeight - 1, left, 3 * ocrConfig.Alignment.CharHeight);
                            }
                        }
                    }

                    g.Save();
                }

                outputDebugFileCounter++;
                EnsureOutputDirectory();
                bmpOdd.Save(Path.GetFullPath(string.Format("{0}\\{1}-odd-ts({2}).bmp", outputDebugFolder, frameNo, outputDebugFileCounter)));
                bmpEven.Save(Path.GetFullPath(string.Format("{0}\\{1}-even-ts({2}).bmp", outputDebugFolder, frameNo, outputDebugFileCounter)));
            }

            return frameInfo;
        }