public void SetShiftByMarker(TextMarker Marker) { SetTarget(Marker.TargetWidth, Marker.TargetHeigth); ShiftX = 0; ShiftY = 0; int DirtyPosX = PosX; int DirtyPosY = PosY; int ShiftedPosX = DirtyPosX + Marker.ShiftX; int ShiftedPosY = DirtyPosY + Marker.ShiftY; int ResultPosX = (int)(Marker.ActualPosX + (ShiftedPosX - Marker.ActualPosX) * Math.Cos(Marker.ActualSkew) - (ShiftedPosY - Marker.ActualPosY) * Math.Sin(Marker.ActualSkew)); int ResultPosY = (int)(Marker.ActualPosY + (ShiftedPosY - Marker.ActualPosY) * Math.Cos(Marker.ActualSkew) + (ShiftedPosX - Marker.ActualPosX) * Math.Sin(Marker.ActualSkew)); ShiftX = ResultPosX - DirtyPosX; ShiftY = ResultPosY - DirtyPosY; }
protected void OnRecognizeActionActivated(object sender, EventArgs e) { if(DocTemplate == null) { DocTemplate = new RecognizeTemplate(); labelTemplateName.LabelProp = "Новый"; //FIXME Убрать тестовый документ DocTemplate.Name = "Торг12-тест"; RecognazeRule testrule = new RecognazeRule(); testrule.Box = new RelationalRectangle(0.357468643, 0.321774194, 0.088939567, 0.026612903); DocTemplate.NumberRule = testrule; testrule = new RecognazeRule(); testrule.Box = new RelationalRectangle(0.444412771, 0.323387097, 0.08608894, 0.021774194); DocTemplate.DateRule = testrule; TextMarker Marker = new TextMarker(); Marker.Text = "ТОВАРНАЯ НАКЛАДНАЯ"; Marker.PatternPosX = 0.206100342; Marker.PatternPosY = 0.324193548; Marker.Zone = new RelationalRectangle(0.181299886, 0.292741935, 0.196693273, 0.12); DocTemplate.Markers = new TextMarker[]{Marker}; } //FIXME Открыть диалог настройки шаблона. }
private void RecognizeTess() { using (var engine = new TesseractEngine(@"./tessdata", "rus", EngineMode.Default)) { TextMarker Marker = Doc.Template.Markers[0]; Pixbuf PixBox; logger.Info("Вычисляем сдвиг"); Pixbuf WorkImage = Images[0]; Marker.SetTarget(WorkImage.Width, WorkImage.Height); RelationalRectangle WorkZone = Marker.Zone.Clone(); for (int i = 1; i <= 7; i++) { logger.Debug("Попытка {0}, box: x={1},y={2},w={3},h={4}", i, WorkZone.PosX, WorkZone.PosY, WorkZone.Width, WorkZone.Heigth); PixBox = new Pixbuf(WorkImage, WorkZone.PosX, WorkZone.PosY, WorkZone.Width, WorkZone.Heigth); using (var img = RecognizeHelper.PixbufToPix(PixBox)) { using (var page = engine.Process(img, PageSegMode.Auto)) { int Distance, MarkerPosX, MarkerPosY; double MarkerSkew; RecognazeRule[] rules = new RecognazeRule[] { Doc.Template.NumberRule, Doc.Template.DateRule }; Distance = GetTextPosition(Marker.Text, page, out MarkerPosX, out MarkerPosY, out MarkerSkew, rules); if (Distance < 5) { logger.Debug("TextMarker <{0}> Distance: {1} Try:{2}", Marker.Text, Distance, i); Marker.ActualPosX = MarkerPosX + WorkZone.PosX; Marker.ActualPosY = MarkerPosY + WorkZone.PosY; Marker.ActualSkew = MarkerSkew; Marker.Confidence = page.GetMeanConfidence(); logger.Debug("Image Shift X: {0}", Marker.ShiftX); logger.Debug("Image Shift Y: {0}", Marker.ShiftY); break; } else if (i == 7 || (WorkZone.RelativePosX == 0 && WorkZone.RelativePosY == 0 && WorkZone.RelativeHeigth == 1 && WorkZone.RelativeWidth == 1)) { Marker.ActualPosX = (int)(Marker.PatternPosX * Marker.TargetWidth); Marker.ActualPosY = (int)(Marker.PatternPosY * Marker.TargetHeigth); Marker.ActualSkew = 0; ShowImage(PixBox, "Маркер не найден. Зона маркера."); } else { //Увеличиваем размер зоны поиска. ExpandRelativeZone(WorkZone); } } } } RecognazeRule CurRule; logger.Info("Распознаем номер"); if (Doc.Template.NumberRule != null) { CurRule = Doc.Template.NumberRule; if (CurRule.Box != null) { CurRule.Box.SetShiftByMarker(Marker); logger.Debug("Number Shift X: {0}", CurRule.Box.ShiftX); logger.Debug("Number Shift Y: {0}", CurRule.Box.ShiftY); WorkZone = CurRule.Box.Clone(); //FIXME С этим пока работает лучше WorkZone.RelativePosX += WorkZone.RelativeWidth * 0.2; WorkZone.RelativePosY += WorkZone.RelativeHeigth * 0.2; WorkZone.RelativeWidth *= 0.6; WorkZone.RelativeHeigth *= 0.6; Doc.DocNumberConfidence = 0; for (int i = 1; i <= 5; i++) { PixBox = new Pixbuf(WorkImage, WorkZone.PosX, WorkZone.PosY, WorkZone.Width, WorkZone.Heigth); using (var img = RecognizeHelper.PixbufToPix(PixBox)) { using (var page = engine.Process(img, PageSegMode.SingleLine)) { string FieldText = page.GetText().Trim(); if (page.GetMeanConfidence() > Doc.DocNumberConfidence) { Doc.DocNumber = FieldText; Doc.DocNumberConfidence = page.GetMeanConfidence(); logger.Debug("Try: {0}", i); logger.Debug("Found Field Value: {0}", FieldText); logger.Debug("Recognize confidence: {0}", page.GetMeanConfidence()); if (FieldText == "") { ShowImage(PixBox, "Номер пустой. Зона номера документа."); } else { ShowImage(PixBox, "Зона номера документа."); } } if (CurRule.Validate == ValidationTypes.IsNumber) { int tempInt; bool BoxIsNumber = int.TryParse(Doc.DocNumber, out tempInt); if (BoxIsNumber) { break; } else { Doc.DocNumberConfidence = 0; } } if (Doc.DocNumberConfidence > 0.8) { break; } else //Увеличиваем размер зоны поиска. { ExpandRelativeZone(WorkZone); } } } } } else if (CurRule.NextAfterTextMarker) { logger.Debug("By after market detection: {0}", CurRule.AfterTextMarkerValue); Doc.DocNumber = CurRule.AfterTextMarkerValue; Doc.DocNumberConfidence = CurRule.AfterTextMarkerConfidence; } } logger.Info("Распознаем Дату"); if (Doc.Template.DateRule != null) { CurRule = Doc.Template.DateRule; if (CurRule.Box != null) { CurRule.Box.SetShiftByMarker(Marker); PixBox = new Pixbuf(WorkImage, CurRule.Box.PosX, CurRule.Box.PosY, CurRule.Box.Width, CurRule.Box.Heigth); using (var img = RecognizeHelper.PixbufToPix(PixBox)) { using (var page = engine.Process(img, PageSegMode.SingleLine)) { string FieldText = page.GetText().Trim(); DateTime TempDate; string [] words = FieldText.Split(new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); string Date = ""; foreach (string word in words) { if (DateTime.TryParse(word, out TempDate)) { Date = word; } } if (DateTime.TryParse(Date, out TempDate)) { Doc.DocDate = TempDate; Doc.DocDateConfidence = page.GetMeanConfidence(); } else { Doc.DocDateConfidence = -2; } logger.Debug("Found Field Value: {0}", FieldText); logger.Debug("Split date Value: {0}", Date); logger.Debug("Recognize confidence: {0}", page.GetMeanConfidence()); if (FieldText == "") { ShowImage(PixBox, "Дата пустая. Зона даты документа."); } else { ShowImage(PixBox, "Зона даты документа."); } } } } else { logger.Debug("By after market detection: {0}", CurRule.AfterTextMarkerValue); if (DateTime.TryParse(CurRule.AfterTextMarkerValue, out Doc.DocDate)) { logger.Debug("Date parsed:{0}", Doc.DocDate); Doc.DocDateConfidence = CurRule.AfterTextMarkerConfidence; } else { Doc.DocDateConfidence = -2; } } } //FIXME Добавить распознование дополнительных полей. } }