Программные средства для заполнения базы персональных данных
Исследование возможностей ускорения процессов заполнения базы персональных данных за счет сокращения ручного ввода данных путем применения технологий оптического распознавания символов. Проектирование, реализация и тестирование автоматизированной системы.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | дипломная работа |
Язык | русский |
Дата добавления | 10.07.2017 |
Размер файла | 2,6 M |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Листинг макета activity_doc_list.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="demidov.docrecognition.DocListActivity">
<ListView
android:id="@+id/documentList"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp" />
</android.support.constraint.ConstraintLayout>
ПРИЛОЖЕНИЕ 7
(обязательное)
Листинг макета list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:layout_marginTop="0dp"
android:text="TextView"
android:textSize="18sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
ПРИЛОЖЕНИЕ 8
(обязательное)
Листинг операции LoginActivity
package demidov.docrecognition;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.TargetApi;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.google.common.hash.Hashing;
import demidov.docrecognition.database.DbHelper;
import demidov.docrecognition.database.DocRecognizerContract;
public class LoginActivity extends AppCompatActivity {
private UserLoginTask mAuthTask = null;
private AutoCompleteTextView mUsernameView;
private EditText mPasswordView;
private View mProgressView;
private View mLoginFormView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mUsernameView = (AutoCompleteTextView) findViewById(R.id.username);
mPasswordView = (EditText) findViewById(R.id.password);
mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
if (id == R.id.login || id == EditorInfo.IME_NULL) {
attemptLogin();
return true;
}
return false;
}
});
Button signInButton = (Button) findViewById(R.id.sign_in_button);
signInButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
attemptLogin();
}
});
mLoginFormView = findViewById(R.id.login_form);
mProgressView = findViewById(R.id.login_progress);
}
private void attemptLogin() {
if (mAuthTask != null) {
return;
}
mUsernameView.setError(null);
mPasswordView.setError(null);
String username = mUsernameView.getText().toString();
String password = mPasswordView.getText().toString();
boolean cancel = false;
View focusView = null;
if (TextUtils.isEmpty(password) || !isPasswordValid(password)) {
mPasswordView.setError(getString(R.string.password_invalid));
focusView = mPasswordView;
cancel = true;
}
if (TextUtils.isEmpty(username) || !isEmailValid(username)) {
mUsernameView.setError(getString(R.string.username_invalid));
focusView = mUsernameView;
cancel = true;
}
if (cancel) {
focusView.requestFocus();
} else {
showProgress(true);
mAuthTask = new UserLoginTask(username, password);
mAuthTask.execute((Void) null);
}
}
private boolean isEmailValid(String username) {
return username.length() >= 4;
}
private boolean isPasswordValid(String password) {
return password.length() >= 4;
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
private void showProgress(final boolean show) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
mLoginFormView.animate().setDuration(shortAnimTime).alpha(
show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
});
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
mProgressView.animate().setDuration(shortAnimTime).alpha(
show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
}
});
} else {
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
}
public class UserLoginTask extends AsyncTask<Void, Void, Long> {
private final String username;
private final String password;
private final DbHelper dbHelper = new DbHelper(LoginActivity.this);
UserLoginTask(String username, String password) {
this.username = username;
this.password = password;
}
@Override
protected Long doInBackground(Void... params) {
String passwordHash = Hashing.sha256().hashUnencodedChars(password).toString();
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.query(DocRecognizerContract.User.TABLE_NAME,
new String[]{DocRecognizerContract.User._ID, DocRecognizerContract.User.COLUMN_NAME_PASSWORD},
DocRecognizerContract.User.COLUMN_NAME_USERNAME + " = ?",
new String[]{username}, null, null, null);
boolean userExists = cursor.moveToNext();
long userId;
if (userExists) {
boolean passwordValid = cursor.getString(1).equals(passwordHash);
if (!passwordValid) {
return null;
}
userId = cursor.getLong(0);
} else {
ContentValues contentValues = new ContentValues();
contentValues.put(DocRecognizerContract.User.COLUMN_NAME_USERNAME,
username);
contentValues.put(DocRecognizerContract.User.COLUMN_NAME_PASSWORD,
passwordHash);
userId = db.insert(DocRecognizerContract.User.TABLE_NAME, null, contentValues);
}
cursor.close();
return userId;
}
@Override
protected void onPostExecute(final Long userId) {
mAuthTask = null;
showProgress(false);
if (userId != null) {
((DocRecogApplication) getApplication()).setUserId(userId);
Intent intent = new Intent(LoginActivity.this, OperationActivity.class);
startActivity(intent);
} else {
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
}
@Override
protected void onCancelled() {
mAuthTask = null;
showProgress(false);
}
}
}
ПРИЛОЖЕНИЕ 9
(обязательное)
Листинг операции OperationActivity
package demidov.docrecognition;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.RadioButton;
import android.widget.RadioGroup;
public class OperationActivity extends AppCompatActivity {
private static final int PERMISSIONS_REQUEST_CAMERA = 1;
private long userId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_operation);
}
public void selectOperation(View view) {
RadioButton operation = (RadioButton) view;
boolean checked = operation.isChecked();
switch (operation.getId()) {
case R.id.createDoc:
if (checked) {
findViewById(R.id.docTypes).setVisibility(View.VISIBLE);
findViewById(R.id.continueButton).setVisibility(View.INVISIBLE);
}
break;
case R.id.existingDoc:
if (checked) {
findViewById(R.id.docTypes).setVisibility(View.GONE);
findViewById(R.id.continueButton).setVisibility(View.VISIBLE);
}
break;
}
}
public void next(View view) {
RadioButton operation = (RadioButton) findViewById(
((RadioGroup) findViewById(R.id.operations)).getCheckedRadioButtonId());
switch (operation.getId()) {
case R.id.createDoc:
requestPermissions();
break;
case R.id.existingDoc:
Intent intent = new Intent(this, DocListActivity.class);
intent.putExtra("userId", userId);
startActivity(intent);
break;
}
}
public void selectDocType(View view) {
RadioButton docType = (RadioButton) view;
boolean checked = docType.isChecked();
if (checked) {
findViewById(R.id.continueButton).setVisibility(View.VISIBLE);
}
}
private void requestPermissions() {
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
processToRecognition();
} else {
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.CAMERA}, PERMISSIONS_REQUEST_CAMERA);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == PERMISSIONS_REQUEST_CAMERA) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
processToRecognition();
}
}
}
private void processToRecognition() {
int buttonId = ((RadioGroup) findViewById(R.id.docTypes)).getCheckedRadioButtonId();
Intent intent = new Intent(this, RecognitionActivity.class);
intent.putExtra("documentType", buttonId);
intent.putExtra("userId", userId);
startActivity(intent);
}
}
ПРИЛОЖЕНИЕ 10
(обязательное)
Листинг операции DocumentActivity
package demidov.docrecognition;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import demidov.docrecognition.database.DbHelper;
import demidov.docrecognition.database.DocRecognizerContract;
public class DocumentActivity extends AppCompatActivity {
private static final Map<PassportField, Integer> passFieldsToViewIds = ImmutableMap.<PassportField, Integer>builder()
.put(PassportField.ISSUER_NAME, R.id.passIssuerName)
.put(PassportField.ISSUER_CODE, R.id.passIssuerCode)
.put(PassportField.ISSUING_DATE, R.id.passIssuingDate)
.put(PassportField.NUMBER, R.id.passNumber)
.put(PassportField.LAST_NAME, R.id.lastName)
.put(PassportField.FIRST_NAME, R.id.firstName)
.put(PassportField.MIDDLE_NAME, R.id.middleName)
.put(PassportField.GENDER, R.id.gender)
.put(PassportField.BIRTH_DATE, R.id.birthDate)
.put(PassportField.BIRTH_PLACE, R.id.birthPlace)
.build();
private static final Map<SnilsField, Integer> snilsFieldsToViewIds = ImmutableMap.<SnilsField, Integer>builder()
.put(SnilsField.SNILS, R.id.snilsNumber)
.put(SnilsField.LAST_NAME, R.id.snilsLastName)
.put(SnilsField.FIRST_NAME, R.id.snilsFirstName)
.put(SnilsField.MIDDLE_NAME, R.id.snilsMiddleName)
.put(SnilsField.BIRTH_DATE, R.id.snilsBirthDate)
.put(SnilsField.BIRTH_PLACE, R.id.snilsBirthPlace)
.put(SnilsField.GENDER, R.id.snilsGender)
.put(SnilsField.REGISTRATION_DATE, R.id.snilsIssuingDate)
.build();
private final DbHelper dbHelper = new DbHelper(this);
private DocumentType documentType;
private long userId;
private Map<DocumentField, String> fields;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_document);
Bundle bundle = getIntent().getExtras();
Bundle documentFields = bundle.getBundle("documentFields");
documentType = DocumentType.valueOf(bundle.getString("documentType"));
userId = ((DocRecogApplication) getApplication()).getUserId();
Long documentId = (Long) getIntent().getExtras().get("documentId");
boolean readOnly = true;
if (documentId == null) {
fields = new HashMap<>();
if (documentType.equals(DocumentType.PASSPORT)) {
for (String key : documentFields.keySet()) {
PassportField field = PassportField.valueOf(key);
fields.put(field, documentFields.getString(key));
}
} else if (documentType.equals(DocumentType.SOCIAL_SECURITY)) {
for (String key : documentFields.keySet()) {
SnilsField field = SnilsField.valueOf(key);
fields.put(field, documentFields.getString(key));
}
}
readOnly = false;
} else {
fields = loadDocument(documentId);
documentType = getDocumentType(documentId);
}
if (readOnly) {
findViewById(R.id.saveButton).setVisibility(View.GONE);
}
if (documentType.equals(DocumentType.PASSPORT)) {
findViewById(R.id.passportVerification).setVisibility(View.VISIBLE);
findViewById(R.id.snilsVerification).setVisibility(View.GONE);
} else if (documentType.equals(DocumentType.SOCIAL_SECURITY)) {
findViewById(R.id.snilsVerification).setVisibility(View.VISIBLE);
findViewById(R.id.passportVerification).setVisibility(View.GONE);
}
for (Map.Entry<DocumentField, String> entry : fields.entrySet()) {
int fieldId;
if (documentType.equals(DocumentType.PASSPORT)) {
fieldId = passFieldsToViewIds.get(entry.getKey());
} else {
fieldId = snilsFieldsToViewIds.get(entry.getKey());
}
EditText textView = (EditText) findViewById(fieldId);
textView.setText(entry.getValue());
textView.setFocusable(!readOnly);
}
}
public void saveData(View view) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
String documentType = null;
switch (this.documentType) {
case PASSPORT:
documentType = DocRecognizerContract.DocumentType.VALUE_CODE_PASSPORT;
break;
case SOCIAL_SECURITY:
documentType = DocRecognizerContract.DocumentType.VALUE_CODE_SNILS;
break;
}
Cursor cursor = db.query(DocRecognizerContract.DocumentType.TABLE_NAME,
new String[]{DocRecognizerContract.DocumentType._ID},
DocRecognizerContract.DocumentType.COLUMN_NAME_CODE + " = ?",
new String[] {documentType}, null, null, null);
cursor.moveToFirst();
long docTypeId = cursor.getLong(
cursor.getColumnIndexOrThrow(DocRecognizerContract.DocumentType._ID)
);
cursor.close();
Gson gson = new GsonBuilder().create();
String json = gson.toJson(fields);
ContentValues docValues = new ContentValues();
docValues.put(DocRecognizerContract.Document.COLUMN_NAME_DOC_TYPE_ID, docTypeId);
docValues.put(DocRecognizerContract.Document.COLUMN_NAME_DATA, json);
docValues.put(DocRecognizerContract.Document.COLUMN_NAME_USER_ID, userId);
db.insert(DocRecognizerContract.Document.TABLE_NAME, null, docValues);
Intent intent = new Intent(this, OperationActivity.class);
intent.putExtra("userId", userId);
startActivity(intent);
}
private Map<DocumentField, String> loadDocument(long documentId) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT " + DocRecognizerContract.Document.TABLE_NAME + "."
+ DocRecognizerContract.Document.COLUMN_NAME_DATA + ", " + DocRecognizerContract.DocumentType.TABLE_NAME
+ "." + DocRecognizerContract.DocumentType.COLUMN_NAME_CODE
+ " FROM " + DocRecognizerContract.Document.TABLE_NAME + " JOIN "
+ DocRecognizerContract.DocumentType.TABLE_NAME + " ON " + DocRecognizerContract.Document.TABLE_NAME
+ "." + DocRecognizerContract.Document.COLUMN_NAME_DOC_TYPE_ID + " = "
+ DocRecognizerContract.DocumentType.TABLE_NAME + "." + DocRecognizerContract.DocumentType._ID
+ " WHERE " + DocRecognizerContract.Document.TABLE_NAME + "." + DocRecognizerContract.Document._ID
+ " = ?", new String[] {String.valueOf(documentId)});
cursor.moveToNext();
String documentData = cursor.getString(0);
String documentType = cursor.getString(1);
cursor.close();
Type type = null;
switch (documentType) {
case DocRecognizerContract.DocumentType.VALUE_CODE_PASSPORT:
type = new TypeToken<Map<PassportField, String>>(){}.getType();
break;
case DocRecognizerContract.DocumentType.VALUE_CODE_SNILS:
type = new TypeToken<Map<SnilsField, String>>(){}.getType();
break;
}
Gson gson = new GsonBuilder().create();
Map<DocumentField, String> result = gson.fromJson(documentData, type);
return result;
}
private DocumentType getDocumentType(Long documentId) {
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT " + DocRecognizerContract.DocumentType.TABLE_NAME
+ "." + DocRecognizerContract.DocumentType.COLUMN_NAME_CODE
+ " FROM " + DocRecognizerContract.Document.TABLE_NAME + " JOIN "
+ DocRecognizerContract.DocumentType.TABLE_NAME + " ON " + DocRecognizerContract.Document.TABLE_NAME
+ "." + DocRecognizerContract.Document.COLUMN_NAME_DOC_TYPE_ID + " = "
+ DocRecognizerContract.DocumentType.TABLE_NAME + "." + DocRecognizerContract.DocumentType._ID
+ " WHERE " + DocRecognizerContract.Document.TABLE_NAME + "." + DocRecognizerContract.Document._ID
+ " = ?", new String[] {String.valueOf(documentId)});
DocumentType documentType = null;
cursor.moveToNext();
switch (cursor.getString(0)) {
case DocRecognizerContract.DocumentType.VALUE_CODE_PASSPORT:
documentType = DocumentType.PASSPORT;
break;
case DocRecognizerContract.DocumentType.VALUE_CODE_SNILS:
documentType = DocumentType.SOCIAL_SECURITY;
break;
}
return documentType;
}
}
ПРИЛОЖЕНИЕ 11
(обязательное)
Листинг операции DocListActivity
package demidov.docrecognition;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import demidov.docrecognition.database.DbHelper;
import demidov.docrecognition.database.DocRecognizerContract;
public class DocListActivity extends AppCompatActivity {
private final DbHelper dbHelper = new DbHelper(this);
private long userId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_doc_list);
ListView listView = (ListView) findViewById(R.id.documentList);
final SQLiteDatabase db = dbHelper.getWritableDatabase();
final String alias = "DOC_NAME";
final Cursor cursor = db.rawQuery("SELECT " + DocRecognizerContract.Document.TABLE_NAME + "."
+ DocRecognizerContract.Document._ID + ", " + DocRecognizerContract.DocumentType.TABLE_NAME
+ "." + DocRecognizerContract.DocumentType.COLUMN_NAME_NAME + " || \" \" || "
+ DocRecognizerContract.Document.TABLE_NAME + "." + DocRecognizerContract.Document._ID
+ " AS " + alias + " FROM " + DocRecognizerContract.Document.TABLE_NAME + " JOIN "
+ DocRecognizerContract.DocumentType.TABLE_NAME + " ON " + DocRecognizerContract.Document.TABLE_NAME
+ "." + DocRecognizerContract.Document.COLUMN_NAME_DOC_TYPE_ID + " = "
+ DocRecognizerContract.DocumentType.TABLE_NAME + "." + DocRecognizerContract.DocumentType._ID
+ " WHERE " + DocRecognizerContract.Document.TABLE_NAME + "."
+ DocRecognizerContract.Document.COLUMN_NAME_USER_ID + " = ?", new String[]{String.valueOf(userId)});
String[] from = {alias};
int[] to = {R.id.textView2};
final SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.list_item, cursor, from, to);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(getApplicationContext(), DocumentActivity.class);
intent.putExtra("userId", userId);
intent.putExtra("documentId", id);
startActivity(intent);
}
});
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
db.delete(DocRecognizerContract.Document.TABLE_NAME, DocRecognizerContract.Document._ID
+ " = ?", new String[] {String.valueOf(id)});
adapter.changeCursor(db.rawQuery("SELECT " + DocRecognizerContract.Document.TABLE_NAME + "."
+ DocRecognizerContract.Document._ID + ", " + DocRecognizerContract.DocumentType.TABLE_NAME
+ "." + DocRecognizerContract.DocumentType.COLUMN_NAME_NAME + " || \" \" || "
+ DocRecognizerContract.Document.TABLE_NAME + "." + DocRecognizerContract.Document._ID
+ " AS " + alias + " FROM " + DocRecognizerContract.Document.TABLE_NAME + " JOIN "
+ DocRecognizerContract.DocumentType.TABLE_NAME + " ON " + DocRecognizerContract.Document.TABLE_NAME
+ "." + DocRecognizerContract.Document.COLUMN_NAME_DOC_TYPE_ID + " = "
+ DocRecognizerContract.DocumentType.TABLE_NAME + "." + DocRecognizerContract.DocumentType._ID, null));
return true;
}
});
}
}
ПРИЛОЖЕНИЕ 12
(обязательное)
Листинг операции RecognitionActivity
package demidov.docrecognition;
import android.app.Activity;
import android.hardware.Camera;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import org.bytedeco.javacpp.tesseract;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import static org.bytedeco.javacpp.opencv_core.Mat;
public class RecognitionActivity extends Activity implements CvCameraPreview.CvCameraViewListener, View.OnClickListener {
final String TAG = "RecognitionActivity";
private CvCameraPreview cameraView;
private tesseract.TessBaseAPI api;
private BaseDocRecognitionService documentExtractor;
private int documentTypeId;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recognition);
initTesseract();
cameraView = (CvCameraPreview) findViewById(R.id.camera_view);
cameraView.setCvCameraViewListener(this);
findViewById(R.id.recorder_control).setOnClickListener(this);
documentTypeId = getIntent().getExtras().getInt("documentType");
}
@Override
protected void onPause() {
super.onPause();
cameraView.setVisibility(View.GONE);
}
@Override
public void onCameraViewStarted(int width, int height, Camera camera) {
switch (documentTypeId) {
case (R.id.passport):
documentExtractor = new PassportRecognitionService(height, width, camera, api, getApplicationContext(), this, cameraView);
break;
case (R.id.socialSecurity):
documentExtractor = new SnilsRecognitionService(height, width, camera, api, getApplicationContext(), this, cameraView);
break;
}
}
@Override
public void onCameraViewStopped() {
}
@Override
public Mat onCameraFrame(Mat rgbaMat) {
return documentExtractor.processPreview(rgbaMat);
}
@Override
public void onClick(View v) {
documentExtractor.takeFullSizePicture();
}
private void initTesseract() {
File f = new File(getCacheDir(), "tessdata/rus.traineddata");
if (!f.exists()) try {
InputStream is = getAssets().open("tessdata/rus.traineddata");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
f.getParentFile().mkdirs();
FileOutputStream fos = new FileOutputStream(f);
fos.write(buffer);
fos.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
api = new tesseract.TessBaseAPI();
if (api.Init(getCacheDir().getPath(), "rus") != 0) {
Log.d(TAG, "Could not initialize tesseract");
}
}
}
ПРИЛОЖЕНИЕ 13
(обязательное)
Листинг класса BaseDocRecognitionService
package demidov.docrecognition;
import android.content.Context;
import android.content.Intent;
import android.hardware.Camera;
import android.os.Bundle;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.SortedSetMultimap;
import com.google.common.collect.TreeMultimap;
import org.bytedeco.javacpp.opencv_core;
import org.bytedeco.javacpp.opencv_core.Mat;
import org.bytedeco.javacpp.opencv_core.MatVector;
import org.bytedeco.javacpp.opencv_core.Rect;
import org.bytedeco.javacv.FFmpegFrameFilter;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameFilter;
import org.bytedeco.javacv.OpenCVFrameConverter;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.bytedeco.javacpp.avutil.AV_PIX_FMT_NV21;
import static org.bytedeco.javacpp.opencv_imgproc.CHAIN_APPROX_NONE;
import static org.bytedeco.javacpp.opencv_imgproc.CV_RGBA2GRAY;
import static org.bytedeco.javacpp.opencv_imgproc.INTER_AREA;
import static org.bytedeco.javacpp.opencv_imgproc.RETR_EXTERNAL;
import static org.bytedeco.javacpp.opencv_imgproc.approxPolyDP;
import static org.bytedeco.javacpp.opencv_imgproc.boundingRect;
import static org.bytedeco.javacpp.opencv_imgproc.cvtColor;
import static org.bytedeco.javacpp.opencv_imgproc.findContours;
import static org.bytedeco.javacpp.opencv_imgproc.rectangle;
import static org.bytedeco.javacpp.opencv_imgproc.resize;
public abstract class BaseDocRecognitionService {
private final Camera camera;
private final Context applicationContext;
private final Context context;
private final CvCameraPreview cameraView;
final Map<DocumentField, Rect> fieldsSearchingAreas;
final double previewToPictureRatio;
final Rect mask;
public BaseDocRecognitionService(int width, int height, Camera camera, Context applicationContext, Context context, CvCameraPreview cameraView) {
this.mask = getMask(width, height);
this.camera = camera;
this.previewToPictureRatio = ((double) camera.getParameters().getPreviewSize().height) /
camera.getParameters().getPictureSize().height;
this.fieldsSearchingAreas = calculateSearchingAreas(mask.size());
this.applicationContext = applicationContext;
this.context = context;
this.cameraView = cameraView;
}
public Mat processPreview(Mat image) {
Multimap<DocumentField, Rect> detectedFields = detect(image);
if (isAllFieldsFound(detectedFields.keySet())) {
takeFullSizePicture();
}
Mat preview = visualizeRects(image, detectedFields);
return preview;
}
public Multimap<DocumentField, Rect> detect(Mat image) {
Mat croppedImage = image.apply(mask);
cvtColor(croppedImage, croppedImage, CV_RGBA2GRAY);
findEdges(croppedImage);
applyMorphology(croppedImage);
return detectFields(croppedImage);
}
public Mat visualizeRects(Mat input, Multimap<DocumentField, Rect> fields) {
Mat croppedImage = input.apply(mask);
drawFieldRects(croppedImage, fields);
drawSearchingAreas(croppedImage, fieldsSearchingAreas);
return recoverToSize(input.size(), mask, croppedImage,
org.bytedeco.javacpp.helper.opencv_core.AbstractScalar.WHITE);
}
private boolean isAllFieldsFound(Collection<DocumentField> fields) {
return fields.containsAll(getAllFields());
}
void takeFullSizePicture() {
try {
camera.takePicture(null, null, new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Camera.Size pictureSize = camera.getParameters().getPictureSize();
Frame filteredFrame = filterFrame(data, pictureSize.width, pictureSize.height);
OpenCVFrameConverter.ToMat converterToMat = new OpenCVFrameConverter.ToMat();
Mat mat = converterToMat.convert(filteredFrame);
Mat smallImage = new Mat();
resize(mat, smallImage, new opencv_core.Size(),
previewToPictureRatio, previewToPictureRatio, INTER_AREA);
Multimap<DocumentField, Rect> detectedFields = detect(smallImage);
Map<DocumentField, String> fieldValues = recognize(mat, sortFields(detectedFields));
processToVerification(fieldValues);
}
});
} catch (RuntimeException e) {
}
}
private Frame filterFrame(byte[] data, int width, int height) {
Frame frame = new Frame(width, height, Frame.DEPTH_UBYTE, 2);
((ByteBuffer) frame.image[0].position(0)).put(data);
FFmpegFrameFilter filter = new FFmpegFrameFilter("transpose=1,format=pix_fmts=rgba", width, height);
filter.setPixelFormat(AV_PIX_FMT_NV21);
Frame filteredFrame = null;
try {
filter.start();
filter.push(frame);
filteredFrame = filter.pull();
filter.stop();
} catch (FrameFilter.Exception e) {
e.printStackTrace();
}
return filteredFrame;
}
void processToVerification(Map<DocumentField, String> fieldValues) {
Intent intent = new Intent(applicationContext, DocumentActivity.class);
Bundle bundle = new Bundle();
for (Map.Entry<DocumentField, String> entry : fieldValues.entrySet()) {
bundle.putString(entry.getKey().getName(), entry.getValue());
}
intent.putExtra("documentFields", bundle);
intent.putExtra("documentType", getDocumentType().name());
context.startActivity(intent);
}
abstract Map<DocumentField, String> recognize(Mat image, Multimap<DocumentField, Rect> fields);
abstract DocumentType getDocumentType();
Rect scaleRect(Rect input) {
int x = (int) ((mask.x() + input.x()) / previewToPictureRatio);
int y = (int) ((mask.y() + input.y()) / previewToPictureRatio);
int width = (int) (input.width() / previewToPictureRatio);
int height = (int) (input.height() / previewToPictureRatio);
return new Rect(x, y, width, height);
}
private Rect getMask(int width, int height) {
double docRatio = getRatio();
int x = 0, y = 0;
if (((double) width)/height > docRatio) {
double desiredWidth = height * docRatio;
int margin = (int) ((width - desiredWidth) / 2);
x = margin;
width = (int) desiredWidth;
} else {
double desiredHeight = width / docRatio;
int margin = (int) ((height - desiredHeight) / 2);
y = margin;
height = (int) desiredHeight;
}
return new Rect(x, y, width, height);
}
abstract void findEdges(Mat image);
abstract void applyMorphology(Mat input);
private Multimap<DocumentField, Rect> detectFields(Mat input) {
Multimap<DocumentField, Rect> detectedFields = ArrayListMultimap.create();
MatVector contours = new MatVector();
findContours(input, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
for (int i = 0; i < contours.size(); i++) {
Mat contour = new Mat();
approxPolyDP(contours.get(i), contour, 3, true);
Rect rect = boundingRect(contour);
rect.x(rect.x() - 3);
rect.y(rect.y() - 3);
rect.width(rect.width() + 6);
rect.height(rect.height() + 6);
DocumentField field = getFieldCorrespondingTo(rect);
if (field != null) {
detectedFields.put(field, rect);
}
}
return detectedFields;
}
private void drawFieldRects(Mat originalImage, Multimap<DocumentField, Rect> fields) {
for (Rect rect : fields.values()) {
rectangle(originalImage, rect, new opencv_core.Scalar(255, 0, 0, 0));
}
}
private void drawSearchingAreas(Mat originalImage, Map<DocumentField, Rect> areas) {
for (Rect rect : areas.values()) {
rectangle(originalImage, rect, new opencv_core.Scalar(0, 255, 0, 0));
}
}
private DocumentField getFieldCorrespondingTo(Rect textRect) {
for (Map.Entry<DocumentField, Rect> entry : fieldsSearchingAreas.entrySet()) {
Rect value = entry.getValue();
if (value.contains(textRect.br()) && value.contains(textRect.tl())) {
return entry.getKey();
}
}
return null;
}
private Mat recoverToSize(opencv_core.Size size, Rect mask,
Mat image, opencv_core.Scalar backgroundColor) {
Mat result = new Mat(size, image.type(), backgroundColor);
image.copyTo(result.apply(mask));
return result;
}
abstract double getRatio();
abstract List<DocumentField> getAllFields();
SortedSetMultimap<DocumentField, Rect> sortFields(Multimap<DocumentField, Rect> fieldsToSort) {
SortedSetMultimap<DocumentField, Rect> result = TreeMultimap.create(new Comparator<DocumentField>() {
@Override
public int compare(DocumentField o1, DocumentField o2) {
if (o1.getRelativeSearchingArea().y() > o2.getRelativeSearchingArea().y()) {
return 1;
} else if (o1.getRelativeSearchingArea().y() < o2.getRelativeSearchingArea().y()) {
return -1;
} else if (o1.getRelativeSearchingArea().x() > o2.getRelativeSearchingArea().x()) {
return 1;
} else if (o1.getRelativeSearchingArea().x() < o2.getRelativeSearchingArea().x()) {
return -1;
} else {
return 0;
}
}
}, new Comparator<Rect>() {
@Override
public int compare(Rect o1, Rect o2) {
return o1.y() - o2.y();
}
});
result.putAll(fieldsToSort);
return result;
}
private Map<DocumentField, Rect> calculateSearchingAreas(opencv_core.Size imageSize) {
Map<DocumentField, Rect> result = new HashMap<>();
for (DocumentField field : getAllFields()) {
opencv_core.Rectd relativeSearchingArea = field.getRelativeSearchingArea();
int x = (int) (imageSize.width() * relativeSearchingArea.x());
int y = (int) (imageSize.height() * relativeSearchingArea.y());
int width = (int) (imageSize.width() * relativeSearchingArea.width());
int height = (int) (imageSize.height() * relativeSearchingArea.height());
result.put(field, new Rect(x, y, width, height));
}
return result;
}
}
ПРИЛОЖЕНИЕ 14
(обязательное)
Листинг класса PassportRecognitionService
package demidov.docrecognition;
import android.content.Context;
import android.hardware.Camera;
import com.google.common.collect.Multimap;
import org.bytedeco.javacpp.BytePointer;
import org.bytedeco.javacpp.opencv_core.Mat;
import org.bytedeco.javacpp.opencv_core.Rect;
import org.bytedeco.javacpp.opencv_core.Size;
import org.bytedeco.javacpp.tesseract.TessBaseAPI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.bytedeco.javacpp.opencv_imgproc.ADAPTIVE_THRESH_MEAN_C;
import static org.bytedeco.javacpp.opencv_imgproc.CV_MOP_CLOSE;
import static org.bytedeco.javacpp.opencv_imgproc.CV_MOP_OPEN;
import static org.bytedeco.javacpp.opencv_imgproc.CV_RGBA2GRAY;
import static org.bytedeco.javacpp.opencv_imgproc.Canny;
import static org.bytedeco.javacpp.opencv_imgproc.MORPH_ELLIPSE;
import static org.bytedeco.javacpp.opencv_imgproc.MORPH_RECT;
import static org.bytedeco.javacpp.opencv_imgproc.THRESH_BINARY;
import static org.bytedeco.javacpp.opencv_imgproc.adaptiveThreshold;
import static org.bytedeco.javacpp.opencv_imgproc.cvtColor;
import static org.bytedeco.javacpp.opencv_imgproc.getStructuringElement;
import static org.bytedeco.javacpp.opencv_imgproc.morphologyEx;
public class CardRecognitionService extends BaseDocRecognitionService {
private final Size closingKernelSize;
private final Size openingKernelSize;
private final int thresholdingKernelSize;
private final Size recognitionClosingKernelSize;
private final TessBaseAPI tesseractApi;
public CardRecognitionService(int width, int height, Camera camera, TessBaseAPI tesseractApi, Context applicationContext, Context context, CvCameraPreview cameraView) {
super(width, height, camera, applicationContext, context, cameraView);
this.tesseractApi = tesseractApi;
double fontSize = mask.height() * 14.0 / 185;
this.closingKernelSize = new Size((int) (2 * fontSize), (int) (0.1 * fontSize));
this.openingKernelSize = new Size((int) (0.9 * fontSize), (int) (0.9 * fontSize));
int thresholdingKernelSize = (int) (2 * fontSize / previewToPictureRatio);
this.thresholdingKernelSize = thresholdingKernelSize % 2 == 0 ? thresholdingKernelSize + 1
: thresholdingKernelSize;
this.recognitionClosingKernelSize = new Size((int) (0.1 * fontSize / previewToPictureRatio),
(int) (0.08 * fontSize / previewToPictureRatio));
}
@Override
Map<DocumentField, String> recognize(Mat image, Multimap<DocumentField, Rect> fields) {
Map<DocumentField, String> recognizedFields = new HashMap<>();
cvtColor(image, image, CV_RGBA2GRAY);
for (Map.Entry<DocumentField, Rect> entry : fields.entries()) {
Rect wordRect = scaleRect(entry.getValue());
Mat word = new Mat();
image.apply(wordRect).copyTo(word);
adaptiveThreshold(word, word, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, thresholdingKernelSize, 10);
morphologyEx(word, word, CV_MOP_CLOSE, getStructuringElement(MORPH_ELLIPSE, recognitionClosingKernelSize));
tesseractApi.TesseractRect(word.data(), 1, word.cols(), 0, 0, word.cols(), word.rows());
BytePointer text = tesseractApi.GetUTF8Text();
String fieldValue = recognizedFields.get(entry.getKey());
if (text != null) {
if (fieldValue == null) {
recognizedFields.put(entry.getKey(), text.getString());
} else {
recognizedFields.put(entry.getKey(), fieldValue + " " + text.getString());
}
}
}
return recognizedFields;
}
@Override
void applyMorphology(Mat image) {
morphologyEx(image, image, CV_MOP_CLOSE,
getStructuringElement(MORPH_RECT, closingKernelSize));
morphologyEx(image, image, CV_MOP_OPEN, getStructuringElement(MORPH_RECT, openingKernelSize));
}
@Override
double getRatio() {
return 85.6 / 53.98;
}
@Override
List<DocumentField> getAllFields() {
return new ArrayList<DocumentField>(Arrays.asList(CardField.values()));
}
@Override
void findEdges(Mat image) {
cvtColor(image, image, CV_RGBA2GRAY);
Canny(image, image, 150, 400, 3, false);
}
@Override
DocumentType getDocumentType() {
return DocumentType.CARD;
}
}
ПРИЛОЖЕНИЕ 15
(обязательное)
Листинг класса SnilsRecognitionService
package demidov.docrecognition;
import android.content.Context;
import android.hardware.Camera;
import com.google.common.collect.Multimap;
import org.bytedeco.javacpp.BytePointer;
import org.bytedeco.javacpp.opencv_core.Mat;
import org.bytedeco.javacpp.opencv_core.Rect;
import org.bytedeco.javacpp.opencv_core.Size;
import org.bytedeco.javacpp.tesseract.TessBaseAPI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.bytedeco.javacpp.opencv_imgproc.ADAPTIVE_THRESH_MEAN_C;
import static org.bytedeco.javacpp.opencv_imgproc.CV_MOP_CLOSE;
import static org.bytedeco.javacpp.opencv_imgproc.CV_MOP_OPEN;
import static org.bytedeco.javacpp.opencv_imgproc.CV_RGBA2GRAY;
import static org.bytedeco.javacpp.opencv_imgproc.Canny;
import static org.bytedeco.javacpp.opencv_imgproc.MORPH_ELLIPSE;
import static org.bytedeco.javacpp.opencv_imgproc.MORPH_RECT;
import static org.bytedeco.javacpp.opencv_imgproc.THRESH_BINARY;
import static org.bytedeco.javacpp.opencv_imgproc.adaptiveThreshold;
import static org.bytedeco.javacpp.opencv_imgproc.cvtColor;
import static org.bytedeco.javacpp.opencv_imgproc.getStructuringElement;
import static org.bytedeco.javacpp.opencv_imgproc.morphologyEx;
public class SnilsRecognitionService extends BaseDocRecognitionService {
private final Size closingKernelSize;
private final Size openingKernelSize;
private final int thresholdingKernelSize;
private final Size recognitionClosingKernelSize;
private final TessBaseAPI tesseractApi;
public SnilsRecognitionService(int width, int height, Camera camera, TessBaseAPI tesseractApi, Context applicationContext, Context context, CvCameraPreview cameraView) {
super(width, height, camera, applicationContext, context, cameraView);
this.tesseractApi = tesseractApi;
double fontSize = mask.height() * 7.0 / 200;
this.closingKernelSize = new Size((int) (2 * fontSize), (int) (0.1 * fontSize));
this.openingKernelSize = new Size((int) (0.9 * fontSize), (int) (0.9 * fontSize));
int thresholdingKernelSize = (int) (2 * fontSize / previewToPictureRatio);
this.thresholdingKernelSize = thresholdingKernelSize % 2 == 0 ? thresholdingKernelSize + 1
: thresholdingKernelSize;
this.recognitionClosingKernelSize = new Size((int) (0.1 * fontSize / previewToPictureRatio),
(int) (0.08 * fontSize / previewToPictureRatio));
}
@Override
Map<DocumentField, String> recognize(Mat image, Multimap<DocumentField, Rect> fields) {
Map<DocumentField, String> recognizedFields = new HashMap<>();
cvtColor(image, image, CV_RGBA2GRAY);
for (Map.Entry<DocumentField, Rect> entry : fields.entries()) {
Rect wordRect = scaleRect(entry.getValue());
Mat word = new Mat();
image.apply(wordRect).copyTo(word);
adaptiveThreshold(word, word, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, thresholdingKernelSize, 10);
morphologyEx(word, word, CV_MOP_CLOSE, getStructuringElement(MORPH_ELLIPSE, recognitionClosingKernelSize));
tesseractApi.TesseractRect(word.data(), 1, word.cols(), 0, 0, word.cols(), word.rows());
BytePointer text = tesseractApi.GetUTF8Text();
String fieldValue = recognizedFields.get(entry.getKey());
if (text != null) {
if (fieldValue == null) {
recognizedFields.put(entry.getKey(), text.getString());
} else {
recognizedFields.put(entry.getKey(), fieldValue + " " + text.getString());
}
}
}
return recognizedFields;
}
@Override
void applyMorphology(Mat image) {
morphologyEx(image, image, CV_MOP_CLOSE,
getStructuringElement(MORPH_RECT, closingKernelSize));
morphologyEx(image, image, CV_MOP_OPEN, getStructuringElement(MORPH_RECT, openingKernelSize));
}
@Override
double getRatio() {
return 85.0/55;
}
@Override
List<DocumentField> getAllFields() {
return new ArrayList<DocumentField>(Arrays.asList(SnilsField.values()));
}
@Override
void findEdges(Mat image) {
Canny(image, image, 100, 250, 3, false);
}
@Override
DocumentType getDocumentType() {
return DocumentType.SOCIAL_SECURITY;
}
}
ПРИЛОЖЕНИЕ 16
(обязательное)
Листинг класса DocumentField
package demidov.docrecognition;
import org.bytedeco.javacpp.opencv_core;
public interface DocumentField {
String getName();
opencv_core.Rectd getRelativeSearchingArea();
}
ПРИЛОЖЕНИЕ 17
(обязательное)
Листинг класса PassportField
package demidov.docrecognition;
import org.bytedeco.javacpp.opencv_core;
public enum PassportField implements DocumentField {
ISSUER_NAME("Кем выдан", new opencv_core.Rectd(29.0/426, 40.0/600, 371.0/426, 85.0/600)),
ISSUING_DATE("Дата выдачи", new opencv_core.Rectd(29.0/426, 110.0/600, 154.0/426, 40.0/600)),
ISSUER_CODE("Код подразделения", new opencv_core.Rectd(187.0/426, 110.0/600, 209.0/426, 40.0/600)),
LAST_NAME("Фамилия", new opencv_core.Rectd(149.0/426, 341.0/600, 216.0/426, 45.0/600)),
FIRST_NAME("Имя", new opencv_core.Rectd(149.0/426, 380.0/600, 239.0/426, 30.0/600)),
MIDDLE_NAME("Отчество", new opencv_core.Rectd(149.0/426, 405.0/600, 239.0/426, 30.0/600)),
GENDER("Пол", new opencv_core.Rectd(149.0/426, 430.0/600, 68.0/426, 30.0/600)),
BIRTH_DATE("Дата рождения", new opencv_core.Rectd(241.0/426, 430.0/600, 147.0/426, 30.0/600)),
BIRTH_PLACE("Место рождения", new opencv_core.Rectd(149.0/426, 455.0/600, 246.0/426, 80.0/600)),
NUMBER("Номер паспорта", new opencv_core.Rectd(390.0/426, 63.0/600, 30.0/426, 167.0/600));
private String fieldName;
private opencv_core.Rectd relativeSearchingArea;
PassportField(String fieldName, opencv_core.Rectd relativeSearchingArea) {
this.fieldName = fieldName;
this.relativeSearchingArea = relativeSearchingArea;
}
public String getName() {
return this.name();
}
@Override
public opencv_core.Rectd getRelativeSearchingArea() {
return relativeSearchingArea;
}
}
ПРИЛОЖЕНИЕ 18
(обязательное)
Листинг класса SnilsField
package demidov.docrecognition;
import org.bytedeco.javacpp.opencv_core;
public enum SnilsField implements DocumentField {
SNILS("СНИЛС", new opencv_core.Rectd(53.0/300, 47.0/200, 166.0/300, 29.0/200)),
LAST_NAME("Фамилия", new opencv_core.Rectd(45.0/300, 71.0/200, 141.0/300, 20.0/200)),
FIRST_NAME("Имя", new opencv_core.Rectd(45.0/300, 83.0/200, 141.0/300, 20.0/200)),
MIDDLE_NAME("Отчество", new opencv_core.Rectd(45.0/300, 94.0/200, 141.0/300, 20.0/200)),
BIRTH_DATE("Дата рождения", new opencv_core.Rectd(115.0/300, 100.0/200, 161.0/300, 30.0/200)),
BIRTH_PLACE("Место рождения", new opencv_core.Rectd(17.0/300, 121.0/200, 180.0/300, 45.0/200)),
GENDER("Пол", new opencv_core.Rectd(35.0/300, 160.0/200, 64.0/300, 20.0/200)),
REGISTRATION_DATE("Дата регистрации", new opencv_core.Rectd(90.0/300, 175.0/200, 112.0/300, 20.0/200));
private String fieldName;
private opencv_core.Rectd relativeSearchingArea;
SnilsField(String fieldName, opencv_core.Rectd relativeSearchingArea) {
this.fieldName = fieldName;
this.relativeSearchingArea = relativeSearchingArea;
}
public String getName() {
return this.name();
}
@Override
public opencv_core.Rectd getRelativeSearchingArea() {
return relativeSearchingArea;
}
}
ПРИЛОЖЕНИЕ 19
(обязательное)
Листинг класса DocRecognizerContract
package demidov.docrecognition.database;
import android.provider.BaseColumns;
public final class DocRecognizerContract {
private DocRecognizerContract() {
}
public static class Document implements BaseColumns {
public static final String TABLE_NAME = "DOCUMENT";
public static final String COLUMN_NAME_DOC_TYPE_ID = "DOC_TYPE_ID";
public static final String COLUMN_NAME_USER_ID = "USER_ID";
public static final String COLUMN_NAME_INSERT_DATE = "INSERT_DATE";
Подобные документы
Основы безопасности персональных данных. Классификация угроз информационной безопасности персональных данных, характеристика их источников. Базы персональных данных. Контроль и управление доступом. Разработка мер защиты персональных данных в банке.
дипломная работа [3,2 M], добавлен 23.03.2018Законодательные основы защиты персональных данных. Классификация угроз информационной безопасности. База персональных данных. Устройство и угрозы ЛВС предприятия. Основные программные и аппаратные средства защиты ПЭВМ. Базовая политика безопасности.
дипломная работа [2,5 M], добавлен 10.06.2011Понятие информационной и автоматизированной системы. Жизненный цикл базы данных: этап начальной разработки, проектирование, реализация и загрузка, тестирование и оценка, функционирование. Структурный анализ и проектирование, средства моделирования.
лекция [216,9 K], добавлен 07.12.2013Сущности и функциональные зависимости базы данных. Атрибуты и связи. Таблицы базы данных. Построение ER-диаграммы. Организация ввода и корректировки данных. Реляционная схема базы данных. Реализация запросов, получение отчетов. Защита базы данных.
курсовая работа [2,4 M], добавлен 06.02.2016Реализация приложения "Книжный магазин" средствами систем управления базами данных. Проектирование структуры базы данных, определение сущности и атрибутов. Логическое проектирование базы данных и реализация базы данных в СУБД Microsoft Office Access.
курсовая работа [7,8 M], добавлен 13.02.2023Технологии защиты персональных данных и их применение. Юридический аспект защиты персональных данных в России. Описание результатов опроса среди рядовых российских пользователей. Прогноз развития технологий в связи с аспектом защиты персональных данных.
дипломная работа [149,6 K], добавлен 03.07.2017Проектирование базы данных для автоматизированной системы "Склад". Разработка концептуальной модели (ER-диаграмма). Преобразование в реляционную модель и ее нормализация. Разработка запросов к базе данных на языке SQL. Скрипт для создания базы данных.
курсовая работа [161,8 K], добавлен 07.10.2013Понятие базы данных, модели данных. Классификация баз данных. Системы управления базами данных. Этапы, подходы к проектированию базы данных. Разработка базы данных, которая позволит автоматизировать ведение документации, необходимой для деятельности ДЮСШ.
курсовая работа [1,7 M], добавлен 04.06.2015Концептуальное и инфологическое проектирование базы данных в системе управления базами данных Microsoft Access. Физическое проектирование базы данных "Магазин спорттоваров". Тестирование и отладка базы данных, составление руководства пользователя.
курсовая работа [6,7 M], добавлен 22.11.2022Характеристика основных этапов создания программной системы. Сведения, хранимые в базе данных информационной системы музея. Описание данных, их типов и ограничений. Проектирование базы данных методом нормальных форм. Технические и программные средства.
курсовая работа [1,8 M], добавлен 23.01.2014