Программные средства для заполнения базы персональных данных

Исследование возможностей ускорения процессов заполнения базы персональных данных за счет сокращения ручного ввода данных путем применения технологий оптического распознавания символов. Проектирование, реализация и тестирование автоматизированной системы.

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 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

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.