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; } }
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; }