【问题标题】:Extracting information from OCR recognized text [closed]从 OCR 识别的文本中提取信息 [关闭]
【发布时间】:2015-12-25 16:33:44
【问题描述】:

我目前正在尝试开发一个光学字符识别 (OCR) 应用程序,它将识别出的数据从名片传递到我的手机联系人数据库。我已经设法识别出名片中的数据。

项目流程图:

  1. Main Menu.用户必须点击“拍照”按钮才能使用相机拍照。

2.名片中识别出来的文字会像“拍照”按钮下的文字一样显示出来。

  1. 然后用户必须点击“保存到联系人”按钮将联系人信息保存在电话联系人数据库中。识别文本中的联系人姓名、联系电话和电子邮件地址将传递到受人尊敬的contact information fields中我的手机联系人数据库

使用 OCR(主菜单)识别代码:

package com.datumdroid.android.ocr.simple;

import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.googlecode.tesseract.android.TessBaseAPI;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class SimpleAndroidOCRActivity extends Activity {
  public static final String PACKAGE_NAME = "com.datumdroid.android.ocr.simple";
  public static final String DATA_PATH = Environment
    .getExternalStorageDirectory().toString() + "/SimpleAndroidOCR/";

  // You should have the trained data file in assets folder

  public static final String lang = "eng";

  private static final String TAG = "SimpleAndroidOCR.java";

  protected Button _button;
  // protected ImageView _image;
  protected EditText _field;
  protected String _path;
  protected boolean _taken;

  protected static final String PHOTO_TAKEN = "photo_taken";

  Button button2; //step 1


  @
  Override
  public void onCreate(Bundle savedInstanceState) {

    String[] paths = new String[] {
      DATA_PATH, DATA_PATH + "tessdata/"
    };

    for (String path: paths) {
      File dir = new File(path);
      if (!dir.exists()) {
        if (!dir.mkdirs()) {
          Log.v(TAG, "ERROR: Creation of directory " + path + " on sdcard failed");
          return;
        } else {
          Log.v(TAG, "Created directory " + path + " on sdcard");
        }
      }

    }

    // lang.traineddata file with the app (in assets folder)


    if (!(new File(DATA_PATH + "tessdata/" + lang + ".traineddata")).exists()) {
      try {

        AssetManager assetManager = getAssets();
        InputStream in = assetManager.open("tessdata/" + lang + ".traineddata");
        //GZIPInputStream gin = new GZIPInputStream(in);
        OutputStream out = new FileOutputStream(DATA_PATH + "tessdata/" + lang + ".traineddata");

        // Transfer bytes from in to out
        byte[] buf = new byte[1024];
        int len;
        //while ((lenf = gin.read(buff)) > 0) {
        while ((len = in .read(buf)) > 0) {
          out.write(buf, 0, len);
        } in .close();
        //gin.close();
        out.close();

        Log.v(TAG, "Copied " + lang + " traineddata");
      } catch (IOException e) {
        Log.e(TAG, "Was unable to copy " + lang + " traineddata " + e.toString());
      }
    }

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);
    button2 = (Button) findViewById(R.id.button2); //step 2


    // _image = (ImageView) findViewById(R.id.image);
    _field = (EditText) findViewById(R.id.field);
    _button = (Button) findViewById(R.id.button);
    _button.setOnClickListener(new ButtonClickHandler());

    _path = DATA_PATH + "/ocr.jpg";
  }
  public void onClickbutton2(View v) //step 3
    {
      startActivity(new Intent("android.intent.action.BUTTON2"));
    }



  public class ButtonClickHandler implements View.OnClickListener {
    public void onClick(View view) {
      Log.v(TAG, "Starting Camera app");
      startCameraActivity();
    }
  }

  // Simple android photo capture:
  // http://labs.makemachine.net/2010/03/simple-android-photo-capture/

  protected void startCameraActivity() {
    File file = new File(_path);
    Uri outputFileUri = Uri.fromFile(file);

    final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);

    startActivityForResult(intent, 0);
  }

  @
  Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    Log.i(TAG, "resultCode: " + resultCode);

    if (resultCode == -1) {
      onPhotoTaken();
    } else {
      Log.v(TAG, "User cancelled");
    }
  }

  @
  Override
  protected void onSaveInstanceState(Bundle outState) {
    outState.putBoolean(SimpleAndroidOCRActivity.PHOTO_TAKEN, _taken);
  }

  @
  Override
  protected void onRestoreInstanceState(Bundle savedInstanceState) {
    Log.i(TAG, "onRestoreInstanceState()");
    if (savedInstanceState.getBoolean(SimpleAndroidOCRActivity.PHOTO_TAKEN)) {
      onPhotoTaken();
    }
  }

  protected void onPhotoTaken() {
    _taken = true;

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = 4;

    Bitmap bitmap = BitmapFactory.decodeFile(_path, options);

    try {
      ExifInterface exif = new ExifInterface(_path);
      int exifOrientation = exif.getAttributeInt(
        ExifInterface.TAG_ORIENTATION,
        ExifInterface.ORIENTATION_NORMAL);

      Log.v(TAG, "Orient: " + exifOrientation);

      int rotate = 0;

      switch (exifOrientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
          rotate = 90;
          break;
        case ExifInterface.ORIENTATION_ROTATE_180:
          rotate = 180;
          break;
        case ExifInterface.ORIENTATION_ROTATE_270:
          rotate = 270;
          break;
      }

      Log.v(TAG, "Rotation: " + rotate);

      if (rotate != 0) {

        // Getting width & height of the given image.
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();

        // Setting pre rotate
        Matrix mtx = new Matrix();
        mtx.preRotate(rotate);

        // Rotating Bitmap
        bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);
      }

      // Convert to ARGB_8888, required by tess
      bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);

    } catch (IOException e) {
      Log.e(TAG, "Couldn't correct orientation: " + e.toString());
    }

    // _image.setImageBitmap( bitmap );

    Log.v(TAG, "Before baseApi");

    TessBaseAPI baseApi = new TessBaseAPI();
    baseApi.setDebug(true);
    baseApi.init(DATA_PATH, lang);
    baseApi.setImage(bitmap);

    String recognizedText = baseApi.getUTF8Text();

    baseApi.end();

    // You now have the text in recognizedText var, you can do anything with it.
    // We will display a stripped out trimmed alpha-numeric version of it (if lang is eng)
    // so that garbage doesn't make it to the display.

    Log.v(TAG, "OCRED TEXT: " + recognizedText);

    if (lang.equalsIgnoreCase("eng")) {
      recognizedText = recognizedText.replaceAll("[^a-zA-Z0-9]+", " ");
    }

    recognizedText = recognizedText.trim();

    if (recognizedText.length() != 0) {
      _field.setText(_field.getText().toString().length() == 0 ? recognizedText : _field.getText() + " " + recognizedText);
      _field.setSelection(_field.getText().toString().length());
    }

  }


}

添加联系人信息字段:

package com.datumdroid.android.ocr.simple;


import android.content.ContentProviderOperation;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.RawContacts;
import android.provider.MediaStore;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;


public class Contacts extends AppCompatActivity {

  EditText edtTxtContactName, edtTxtContactNumber, edtTxtContactEmail;
  ImageView imgContactPhoto;
  Button btnAddContact;
  View view;
  String imagePath = null;
  Uri uri;
  ExifInterface exif;
  boolean isButtonClicked = false;
  View snackView;
  Bitmap rotateBitmap;
  InputMethodManager inm;
  public static boolean isUpdate;
  String cID, cName, cNumber, cEmail; //
  Bitmap cPhoto;
  public boolean FLAG = true;
  Button button3;

  @
  Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.add_contact_activity_main);

    view = findViewById(R.id.rootView);

    edtTxtContactName = (EditText) findViewById(R.id.edtTxtContactName);
    edtTxtContactNumber = (EditText) findViewById(R.id.edtTxtContactNumber);
    edtTxtContactEmail = (EditText) findViewById(R.id.edtTxtContactEmail);

    imgContactPhoto = (ImageView) findViewById(R.id.imgContactPhoto);

    btnAddContact = (Button) findViewById(R.id.btnAddContact);
    inm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

    button3 = (Button) findViewById(R.id.button3);

    if (isUpdate) {
      cID = getIntent().getExtras().getString("cID");
      cName = getIntent().getExtras().getString("cName");

      cNumber = getIntent().getExtras().getString("cNumber"); //
      cEmail = getIntent().getExtras().getString("cEmail");
      cPhoto = getIntent().getParcelableExtra("cPhoto");
      btnAddContact.setText(getString(R.string.update_contact));
      edtTxtContactName.setText(cName);
      edtTxtContactNumber.setText(cNumber); //
      edtTxtContactEmail.setText(cEmail);
      imgContactPhoto.setImageBitmap(cPhoto);
      FLAG = false;

    } else {
      btnAddContact.setText(getString(R.string.add_contact));
    }
    btnAddContact.setOnClickListener(new View.OnClickListener() {@
      Override
      public void onClick(View v) {

        if (btnAddContact.getText().toString().equals(getString(R.string.add_contact))) {

          if (edtTxtContactName.getText().toString().trim().isEmpty()) {
            Snackbar.make(v, "You must provide name.", Snackbar.LENGTH_INDEFINITE).setAction("OK", new View.OnClickListener() {@
              Override
              public void onClick(View v) {

              }
            }).show();
          } else if (edtTxtContactNumber.getText().toString().trim().isEmpty()) {
            Snackbar.make(v, "You must provide number.", Snackbar.LENGTH_INDEFINITE).setAction("OK", new View.OnClickListener() {@
              Override
              public void onClick(View v) {

              }
            }).show();
          } else {
            isButtonClicked = true;
            snackView = v;
            inm.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
            addContact();
          }
        } else if (btnAddContact.getText().toString().equals(getString(R.string.update_contact))) {
          String strName = edtTxtContactName.getText().toString();
          String strNumber = edtTxtContactNumber.getText().toString();
          String strEmail = edtTxtContactEmail.getText().toString();
          imgContactPhoto.setDrawingCacheEnabled(true);
          Bitmap bitmap = imgContactPhoto.getDrawingCache();

          if (updateContact(cID, strName, strNumber, strEmail, bitmap)) {
            Snackbar.make(v, "Contact updated successfully.", Snackbar.LENGTH_LONG).show();
          } else {
            Snackbar.make(v, "Failed to update contact.", Snackbar.LENGTH_LONG).show();
          }

        } else {
          Snackbar.make(v, "Some internal error occured, Please try after some time.", Snackbar.LENGTH_LONG).show();
        }

      }
    });

    imgContactPhoto.setOnClickListener(new View.OnClickListener() {@
      Override
      public void onClick(View v) {
        selectImage();
      }
    });

  }
  public void onClickbutton3(View v) //step 3
    {
      startActivity(new Intent("android.intent.action.BUTTON3"));
    }

  private void selectImage() {
    final CharSequence[] option = {
      "Take Photo", "Choose from Gallery"
    };
    AlertDialog.Builder builder = new AlertDialog.Builder(
      Contacts.this);
    builder.setTitle("Add Photo!");
    builder.setNegativeButton("Cancel",
      new DialogInterface.OnClickListener() {@
        Override
        public void onClick(DialogInterface dialog, int which) {}
      });
    builder.setItems(option, new DialogInterface.OnClickListener() {

      @
      Override
      public void onClick(DialogInterface dialog, int item) {

        if (option[item].equals("Take Photo")) {
          clickPhotoFromCamera();
        } else if (option[item].equals("Choose from Gallery")) {
          uploadPhotoFromCamera();
        }
      }

    });
    builder.show();
  }

  private void clickPhotoFromCamera() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + ".jpg";
    File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), imageFileName);
    uri = Uri.fromFile(imageStorageDir);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
    startActivityForResult(intent, 1);

  }

  private void uploadPhotoFromCamera() {

    Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    intent.setType("image/*");
    startActivityForResult(intent, 2);
  }

  @
  Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
      if (requestCode == 1) {
        imagePath = uri.getPath();
        displayImageBitmap(imagePath);
      } else if (requestCode == 2) {
        Uri selectedImage = data.getData();
        String[] filePath = {
          MediaStore.Images.Media.DATA
        };
        Cursor c = getContentResolver().query(selectedImage, filePath,
          null, null, null);
        c.moveToFirst();
        int columnIndex = c.getColumnIndex(filePath[0]);
        String picturePath = c.getString(columnIndex);
        c.close();
        displayImageBitmap(picturePath);
      }
    }
  }

  public void displayImageBitmap(String image_path) {
    File mediaFile = new File(image_path);
    Bitmap myBitmap = BitmapFactory.decodeFile(mediaFile.getAbsolutePath());
    int height = (myBitmap.getHeight() * 512 / myBitmap.getWidth());
    Bitmap scale = Bitmap.createScaledBitmap(myBitmap, 512, height, true);
    int rotate = 0;
    try {
      exif = new ExifInterface(mediaFile.getAbsolutePath());
    } catch (IOException e) {
      e.printStackTrace();
    }
    int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
    switch (orientation) {
      case ExifInterface.ORIENTATION_NORMAL:
        rotate = 0;
        break;
      case ExifInterface.ORIENTATION_ROTATE_270:
        rotate = 270;
        break;
      case ExifInterface.ORIENTATION_ROTATE_180:
        rotate = 180;
        break;
      case ExifInterface.ORIENTATION_ROTATE_90:
        rotate = 90;
        break;
    }

    Matrix matrix = new Matrix();
    matrix.postRotate(rotate);
    rotateBitmap = Bitmap.createBitmap(scale, 0, 0, scale.getWidth(), scale.getHeight(), matrix, true);
    imgContactPhoto.setImageBitmap(rotateBitmap);
  }

  public void addContact() {
    ArrayList < ContentProviderOperation > insertOperation = new ArrayList < ContentProviderOperation > ();
    int rawContactID = insertOperation.size();

    // Adding insert operation to operations list
    // For insert a new raw contact in the ContactsContract.RawContacts
    insertOperation.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
      .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
      .withValue(RawContacts.ACCOUNT_NAME, null)
      .build());
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    if (rotateBitmap != null) { // If an image is selected successfully
      rotateBitmap.compress(Bitmap.CompressFormat.PNG, 75, stream);

      // For insert Photo in the ContactsContract.Data
      insertOperation.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
        .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactID)
        .withValue(ContactsContract.Data.IS_SUPER_PRIMARY, 1)
        .withValue(ContactsContract.Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE)
        .withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, stream.toByteArray())
        .build());

      try {
        stream.flush();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    // For insert display name in the ContactsContract.Data
    insertOperation.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
      .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactID)
      .withValue(ContactsContract.Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
      .withValue(StructuredName.DISPLAY_NAME, edtTxtContactName.getText().toString())
      .build());
    // For insert Mobile Number in the ContactsContract.Data
    insertOperation.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
      .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactID)
      .withValue(ContactsContract.Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
      .withValue(Phone.NUMBER, edtTxtContactNumber.getText().toString())
      .withValue(Phone.TYPE, Phone.TYPE_MOBILE)
      .build());
    // For insert Work Email in the ContactsContract.Data
    insertOperation.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
      .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactID)
      .withValue(ContactsContract.Data.MIMETYPE, Email.CONTENT_ITEM_TYPE)
      .withValue(Email.ADDRESS, edtTxtContactEmail.getText().toString())
      .withValue(Email.TYPE, Email.TYPE_WORK)
      .build());
    try {
      // Executing all the insert operations as a single database transaction
      getContentResolver().applyBatch(ContactsContract.AUTHORITY, insertOperation);
      if (isButtonClicked == true) {
        edtTxtContactName.setText("");
        edtTxtContactNumber.setText("");
        edtTxtContactEmail.setText("");
        imgContactPhoto.setImageResource(R.drawable.default_contact);
        Snackbar.make(snackView, "Contact added successfully", Snackbar.LENGTH_INDEFINITE).setAction("Hide", new View.OnClickListener() {@
          Override
          public void onClick(View v) {

          }
        }).show();
      } else {
        Toast.makeText(getBaseContext(), "Contact is successfully added", Toast.LENGTH_SHORT).show();
        finish();
      }

    } catch (RemoteException e) {
      e.printStackTrace();
    } catch (OperationApplicationException e) {
      e.printStackTrace();
    }
  }

  boolean updateContact(String contactID, String contactName, String contactNumber, String contactEmailAdd, Bitmap bitmap) {
    ArrayList < ContentProviderOperation > ops = new ArrayList < > ();
    ops.add(ContentProviderOperation
      .newUpdate(ContactsContract.Data.CONTENT_URI)
      .withSelection(ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[] {
        contactID, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
      })
      .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, contactName)
      .build());

    ops.add(ContentProviderOperation
      .newUpdate(ContactsContract.Data.CONTENT_URI)
      .withSelection(ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=? AND " + ContactsContract.CommonDataKinds.Organization.TYPE + "=?", new String[] {
        contactID, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE, String.valueOf(ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
      })
      .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, contactNumber)
      .build());
    ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
      .withSelection(ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=? AND " + ContactsContract.CommonDataKinds.Organization.TYPE + "=?", new String[] {
        contactID, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE, String.valueOf(Email.TYPE_WORK)
      })
      .withValue(Email.ADDRESS, contactEmailAdd)
      .build());
    try {
      ByteArrayOutputStream image = new ByteArrayOutputStream();
      bitmap.compress(Bitmap.CompressFormat.PNG, 100, image);

      ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
        .withSelection(ContactsContract.Data.CONTACT_ID + "=? AND " +
          ContactsContract.Data.MIMETYPE + "=?", new String[] {
            contactID, Photo.CONTENT_ITEM_TYPE
          })
        .withValue(ContactsContract.Data.IS_SUPER_PRIMARY, 1)
        .withValue(Photo.PHOTO, image.toByteArray())
        .build());

      /*Builder builder;
      builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
      builder.withSelection(ContactsContract.Data.CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + "=?",
              new String[]{contactID, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE});
      builder.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, image.toByteArray());
      ops.add(builder.build());*/
    } catch (Exception e) {
      e.printStackTrace();
    }
    try {
      getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
    return true;
  }

  @
  Override
  public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.add_contact_menu, menu);

    MenuItem item = menu.findItem(R.id.action_save);
    if (FLAG) {
      item.setVisible(true);
      this.invalidateOptionsMenu();
    } else {
      item.setVisible(false);
      this.invalidateOptionsMenu();
    }
    return true;
  }

  @
  Override
  public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
      return true;
    }
    switch (id) {
      case android.R.id.home:
        onBackPressed();
        return true;

    }
    if (id == R.id.action_save) {

      if (edtTxtContactName.getText().toString().trim().isEmpty()) {
        Toast.makeText(getApplicationContext(), "You must provide name.", Toast.LENGTH_LONG).show();

      } else if (edtTxtContactNumber.getText().toString().trim().isEmpty()) {
        Toast.makeText(getApplicationContext(), "You must provide number.", Toast.LENGTH_LONG).show();

      } else {
        inm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
        isButtonClicked = false;
        addContact();
      }

      return true;
    }
    return super.onOptionsItemSelected(item);
  }

  @
  Override
  public void onBackPressed() {
    super.onBackPressed();
  }
}

问题是我不知道如何将每个文本与已识别文本中的姓名、联系电话、电子邮件地址分开并将它们传递到我的联系人数据库中的这些字段中。

名片的结构/格式并不具体,有点难以假设。但假设很少:

  1. “@”包含字符串,主要是电子邮件 ID。

  2. 所有带大括号或 + 号的数字大多是电话号码。

【问题讨论】:

  • 你检查了吗:guidingtech.com/11155/…
  • 正如我在帖子中所说,我已经可以识别名片中的文字。问题是我不知道如何从识别的文字中提取重要信息,例如姓名、电话号码和电子邮件地址将传递到我的手机联系人数据库@piotrek1543
  • @HelpMeSenpai 你能分享你的布局文件吗??

标签: java android-studio ocr


【解决方案1】:

从文本中搜索、正确定位和提取特定值的过程称为解析。正如您所说,它有时基于假设,例如如果存在“@”,则该字符串是一封电子邮件。

可以通过冗余和自适应决策来提高解析代码的稳健性。例如:定位包含“@”的字符串表示一个电子邮件地址。然后再找“Email”或“E-mail”标签既可以确认之前找到的结果,也可以找到丢失的e-mail地址,以防“@”被OCR误识别,第一次找不到搜索。

假设 OCR 很少 100% 准确,尤其是在名片这样复杂的文档类型上(由于小字体、歪斜的图片、颜色和背景、艺术字体)是一个很好的规则,需要冗余和特殊情况处理。

也可能存在误报,例如“@”可以在不是电子邮件地址的字符串中找到,例如在“@YourTwitterName”之类的 Twitter 句柄中。通过排除可预测的误报可以改进您的解析代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多