2017-02-21 24 views
2

我已經通過遵循教程實施了Google的Android移動視覺。我正在嘗試構建一個應用程序,用於掃描收據並查找總數。但是,當我掃描以不同格式打印的不同收據時,API將以似乎任意方式檢測TextBlocks。例如,在一個收據中,如果文本的幾個單詞由單個空格分隔,則它們被分組爲單個TextBlock。但是,如果文本的兩個單詞由大量空格分隔,則它們被分隔爲獨立的TextBlocks,即使它們出現在同一「行」上。我想要做的就是強制API將收據的每一行作爲一個整體進行識別。這可能嗎?如何強制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分解成線,發現同一行線和檢查中的塊,如果組件是所有的價格,然後打印出所有的價值。

almostEqual中的eps值是它檢查行中圖形有多高的容差。

+0

我認爲這隻適用於實時使用相機應用程序,而不是現有的圖像,因爲您需要使用文本識別API的類,CameraSourcePreview和GraphicOverlay,是否正確? – DaveNOTDavid