2017-02-21 3 views
2

Я внедрил Mobile Vision для Android от Google, следуя руководству. Я пытаюсь создать приложение, которое сканирует квитанцию ​​и найдет числовое число. Однако, сканируя разные квитанции, которые печатаются в разных форматах, API обнаруживает TextBlocks в том, что кажется произвольным. Например, в одной квитанции, если несколько слов текста разделены одиночными пробелами, они группируются в один текстовый блок. Однако, если два слова текста разделены множеством пробелов, они разделяются как независимые TextBlocks, хотя они отображаются в одной и той же строке. То, что я пытаюсь сделать, - заставить API распознавать каждую целую строку квитанции как отдельную сущность. Это возможно?Как заставить Mobile Vision для Android читать полные строки текста

+0

Вы нашли решение для этого? Если да, могли ли вы обнаруживать существующие изображения, а не использовать приложение для камеры в режиме реального времени? – DaveNOTDavid

ответ

0
public ArrayList<T> getAllGraphicsInRow(float rawY) { 
    synchronized (mLock) { 
     ArrayList<T> row = new ArrayList<>(); 
     // Get the position of this View so the raw location can be offset relative to the view. 
     int[] location = new int[2]; 
     this.getLocationOnScreen(location); 
     for (T graphic : mGraphics) { 
      float rawX = this.getWidth(); 
      for (int i=0; i<rawX; i+=10){ 
       if (graphic.contains(i - location[0], rawY - location[1])) { 
        if(!row.contains(graphic)) { 
         row.add(graphic); 
        } 
       } 
      } 
     } 
     return row; 
    } 
} 

Это должно быть в файле GraphicOverlay.java и, по существу, извлекает всю графику в этой строке.

public static boolean almostEqual(double a, double b, double eps){ 
    return Math.abs(a-b)<(eps); 
} 

public static boolean pointAlmostEqual(Point a, Point b){ 
    return almostEqual(a.y,b.y,10); 
} 
public static boolean cornerPointAlmostEqual(Point[] rect1, Point[] rect2){ 
    boolean almostEqual=true; 
    for (int i=0; i<rect1.length;i++){ 
      if (!pointAlmostEqual(rect1[i],rect2[i])){ 
       almostEqual=false; 
      } 
     } 
    return almostEqual; 
} 
private boolean onTap(float rawX, float rawY) { 
    String priceRegex = "(\\d+[,.]\\d\\d)"; 
    ArrayList<OcrGraphic> graphics = mGraphicOverlay.getAllGraphicsInRow(rawY); 
    OcrGraphic currentGraphics = mGraphicOverlay.getGraphicAtLocation(rawX,rawY); 
    if (graphics !=null && currentGraphics!=null) { 
     List<? extends Text> currentComponents = currentGraphics.getTextBlock().getComponents(); 
     final Pattern pattern = Pattern.compile(priceRegex); 
     final Pattern pattern1 = Pattern.compile(priceRegex); 

     TextBlock text = null; 
     Log.i("text results", "This many in the row: " + Integer.toString(graphics.size())); 

     ArrayList<Text> combinedComponents = new ArrayList<>(); 
     for (OcrGraphic graphic : graphics) { 
      if (!graphic.equals(currentGraphics)) { 
       text = graphic.getTextBlock(); 
       Log.i("text results", text.getValue()); 
       combinedComponents.addAll(text.getComponents()); 
      } 
     } 

     for (Text currentText : currentComponents) { // goes through components in the row 
      final Matcher matcher = pattern.matcher(currentText.getValue()); // looks for 
      Point[] currentPoint = currentText.getCornerPoints(); 

      for (Text otherCurrentText : combinedComponents) {//Looks for other components that are in the same row 
       final Matcher otherMatcher = pattern1.matcher(otherCurrentText.getValue()); // looks for 
       Point[] innerCurrentPoint = otherCurrentText.getCornerPoints(); 

       if (cornerPointAlmostEqual(currentPoint, innerCurrentPoint)) { 
        if (matcher.find()) { // if you click on the price 
         Log.i("oh yes", "Item: " + otherCurrentText.getValue()); 
         Log.i("oh yes", "Value: " + matcher.group(1)); 
         itemList.add(otherCurrentText.getValue()); 
         priceList.add(Float.valueOf(matcher.group(1))); 
        } 
        if (otherMatcher.find()) { // if you click on the item 
         Log.i("oh yes", "Item: " + currentText.getValue()); 
         Log.i("oh yes", "Value: " + otherMatcher.group(1)); 
         itemList.add(currentText.getValue()); 
         priceList.add(Float.valueOf(otherMatcher.group(1))); 
        }      
        Toast toast = Toast.makeText(this, " Text Captured!" , Toast.LENGTH_SHORT); 
        toast.show(); 
       } 
      } 

     } 
     return true; 
    } 
    return false; 
} 

Это должно быть в OcrCaptureActivity.java и разбивает TextBlock на линию и находят блоки в той же строке, что и линия и проверяют компоненты все цены, и печатает все значения соответственно.

Значение eps в почтиEqual - это толерантность к тому, насколько высок он проверяет графику в строке.

+0

Я предполагаю, что это работает только при использовании приложения для камеры в реальном времени, в отличие от существующих изображений, так как вам нужно будет использовать классы API распознавания текста, CameraSourcePreview и GraphicOverlay, правильно? – DaveNOTDavid

Смежные вопросы