Skip to content

Commit

Permalink
Merge pull request #6 from BlinkID/feature/AND-323/vin_detection_impr…
Browse files Browse the repository at this point in the history
…ovements

[Android] Vin detection improvements
  • Loading branch information
i1E authored Mar 13, 2018
2 parents 52470c4 + d5710f7 commit 5d3ac97
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 61 deletions.
6 changes: 5 additions & 1 deletion BlinkMoto/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@
<source-file src="src/android/java/com/phonegap/plugins/blinkid/BlinkIdScanner.java" target-dir="src/com/phonegap/plugins/blinkid" />
<source-file src="src/android/java/com/phonegap/plugins/blinkid/ScanActivity.java" target-dir="src/com/phonegap/plugins/blinkid" />
<source-file src="src/android/java/com/phonegap/plugins/blinkid/FakeR.java" target-dir="src/com/phonegap/plugins/blinkid" />


<source-file src="src/android/java/com/phonegap/plugins/blinkid/resulthistory/AcceptFirstResultHistory.java" target-dir="src/com/phonegap/plugins/blinkid/resulthistory" />
<source-file src="src/android/java/com/phonegap/plugins/blinkid/resulthistory/ResultHistory.java" target-dir="src/com/phonegap/plugins/blinkid/resulthistory" />
<source-file src="src/android/java/com/phonegap/plugins/blinkid/resulthistory/VinResultHistory.java" target-dir="src/com/phonegap/plugins/blinkid/resulthistory" />

<resource-file src="src/android/res/drawable/blinkid_button_accent_text_color.xml" target="res/drawable/blinkid_button_accent_text_color.xml" />
<resource-file src="src/android/res/drawable/blinkid_button_accent.xml" target="res/drawable/blinkid_button_accent.xml" />
<resource-file src="src/android/res/drawable/blinkid_button_normal.xml" target="res/drawable/blinkid_button_normal.xml" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,12 @@
import com.microblink.view.recognition.RecognizerView;
import com.microblink.view.recognition.ScanResultListener;
import com.microblink.view.viewfinder.PointSetView;
import com.phonegap.plugins.blinkid.resulthistory.AcceptFirstResultHistory;
import com.phonegap.plugins.blinkid.resulthistory.ResultHistory;
import com.phonegap.plugins.blinkid.resulthistory.VinResultHistory;

public class ScanActivity extends Activity implements ScanResultListener, CameraEventsListener, MetadataListener, OnActivityFlipListener {

public static final String EXTRAS_LICENSE_KEY = "key_license_string";
public static final String EXTRAS_RECOGNIZER_TYPE = "key_recognizer_type_string";
public static final String EXTRAS_TITLE_STRING = "key_title_string";
Expand All @@ -74,6 +78,7 @@ public class ScanActivity extends Activity implements ScanResultListener, Camera
public static final String EXTRAS_RESULT_STRING = "key_result_string";

private static final float SCANNING_REGION_ASPECT_RATIO = 1 / 4f;
private ResultHistory mResultHistory;

public enum RecognizerType {
VIN, LICENCE_PLATES
Expand All @@ -90,11 +95,9 @@ public enum RecognizerType {

private FrameLayout mRecognizerViewRoot;
private FrameLayout mScanViewfinder;
private TextView mScanTitleView;
private TextView mScanResultStringView;
private ImageView mScanResultImageView;
private Button mAcceptButton;
private Button mCancelButton;
private Button mRepeatButton;

private Image mResultImage;
Expand Down Expand Up @@ -133,7 +136,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
// Set internationalized strings.
Bundle extras = getIntent().getExtras();

mRecognizerView = (RecognizerView) findViewById(mFakeR.getId("recognizerView"));
mRecognizerView = findViewById(mFakeR.getId("recognizerView"));

// Set license key.
String licenseKey = extras.getString(EXTRAS_LICENSE_KEY);
Expand All @@ -145,7 +148,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {

// Add the camera permissions overlay.
mCameraPermManager = new CameraPermissionManager(this);
mRecognizerViewRoot = (FrameLayout) findViewById(mFakeR.getId("recognizerViewRoot"));
mRecognizerViewRoot = findViewById(mFakeR.getId("recognizerViewRoot"));
View cameraPermissionView = mCameraPermManager.getAskPermissionOverlay();
if (cameraPermissionView != null) {
mRecognizerViewRoot.addView(cameraPermissionView);
Expand All @@ -157,7 +160,11 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
throw new NullPointerException("Recognizer type extra missing.");
}

RecognizerSettings[] settArray = setupSettingsArray((RecognizerType) extras.getSerializable(EXTRAS_RECOGNIZER_TYPE));
RecognizerType recognizerType = (RecognizerType) extras.getSerializable(EXTRAS_RECOGNIZER_TYPE);

createResultHistory(recognizerType);

RecognizerSettings[] settArray = setupSettingsArray(recognizerType);
if (!RecognizerCompatibility.cameraHasAutofocus(CameraType.CAMERA_BACKFACE, this)) {
settArray = RecognizerSettingsUtils.filterOutRecognizersThatRequireAutofocus(settArray);
}
Expand Down Expand Up @@ -215,13 +222,13 @@ public void onOrientationChange(Orientation orientation) {
// Inflate the overlay view.
final ViewGroup overlay = (ViewGroup) getLayoutInflater().inflate(mFakeR.getIdFrom("layout", "custom_scan_overlay"), null);
// Bind view elements.
mScanViewfinder = (FrameLayout) overlay.findViewById(mFakeR.getId("fl_scan_frame"));
mScanTitleView = (TextView) overlay.findViewById(mFakeR.getId("tv_scan_title"));
mScanResultStringView = (TextView) overlay.findViewById(mFakeR.getId("tv_scan_result"));
mScanResultImageView = (ImageView) overlay.findViewById(mFakeR.getId("iv_scan_result"));
mAcceptButton = (Button) overlay.findViewById(mFakeR.getId("btn_accept"));
mCancelButton = (Button) overlay.findViewById(mFakeR.getId("btn_cancel"));
mRepeatButton = (Button) overlay.findViewById(mFakeR.getId("btn_repeat"));
mScanViewfinder = overlay.findViewById(mFakeR.getId("fl_scan_frame"));
TextView mScanTitleView = overlay.findViewById(mFakeR.getId("tv_scan_title"));
mScanResultStringView = overlay.findViewById(mFakeR.getId("tv_scan_result"));
mScanResultImageView = overlay.findViewById(mFakeR.getId("iv_scan_result"));
mAcceptButton = overlay.findViewById(mFakeR.getId("btn_accept"));
Button mCancelButton = overlay.findViewById(mFakeR.getId("btn_cancel"));
mRepeatButton = overlay.findViewById(mFakeR.getId("btn_repeat"));
// Set user defined titles.
mScanTitleView.setText(extras.getString(EXTRAS_TITLE_STRING, mFakeR.getString("blinkid_scanning_title")));
mAcceptButton.setText(extras.getString(EXTRAS_ACCEPT_STRING, mFakeR.getString("blinkid_accept")));
Expand All @@ -238,6 +245,14 @@ public void onOrientationChange(Orientation orientation) {
resizeScanningRegion();
}

private void createResultHistory(RecognizerType recognizerType) {
if(recognizerType == RecognizerType.VIN) {
mResultHistory = new VinResultHistory();
} else {
mResultHistory = new AcceptFirstResultHistory();
}
}

private void resizeScanningRegion() {
if (mRecognizerView == null || mRecognizerViewRoot == null) {
return;
Expand Down Expand Up @@ -440,6 +455,7 @@ public void onButtonClicked(View view) {
finish();

} else if (id == mFakeR.getId("btn_repeat")) {
mResultHistory.clear();
mScanResultImageView.setBackground(null);
mScanResultImageView.setVisibility(View.GONE);
mScanResultStringView.setVisibility(View.INVISIBLE);
Expand All @@ -462,63 +478,70 @@ public void onScanningDone(@Nullable final RecognitionResults recognitionResults
return;
}

if (!isFinishing() && mRecognizerView != null && mRecognizerView.getCameraViewState() == BaseCameraView.CameraViewState.RESUMED) {
final BaseRecognitionResult result = recognitionResults.getRecognitionResults()[0];
if(isFinishing() || mRecognizerView == null || mRecognizerView.getCameraViewState() != BaseCameraView.CameraViewState.RESUMED) {
mRecognizerView.resumeScanning(false);
return;
}

runOnUiThread(new Runnable() {
@Override
public void run() {
mAcceptButton.setEnabled(true);
mRepeatButton.setEnabled(true);
mScanResultImageView.setVisibility(View.VISIBLE);
mScanResultStringView.setVisibility(View.VISIBLE);
final BaseRecognitionResult result = recognitionResults.getRecognitionResults()[0];
mResultHistory.onNewResult(extractResultString(result));
if (!mResultHistory.hasValidResult()) {
mRecognizerView.resumeScanning(false);
return;
}

if (mResultImage != null) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mAcceptButton.setEnabled(true);
mRepeatButton.setEnabled(true);
mScanResultImageView.setVisibility(View.VISIBLE);
mScanResultStringView.setVisibility(View.VISIBLE);

Bitmap bitmap = mResultImage.convertToBitmap();
if (bitmap == null) {
return;
}
Matrix matrix = new Matrix();
switch (mResultImage.getImageOrientation()) {
case ORIENTATION_LANDSCAPE_LEFT:
matrix.postRotate(180);
break;
case ORIENTATION_PORTRAIT:
matrix.postRotate(90);
break;
case ORIENTATION_PORTRAIT_UPSIDE:
matrix.postRotate(-90);
break;
}
if (mResultImage != null) {

bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
mScanResultImageView.setImageBitmap(bitmap);
Bitmap bitmap = mResultImage.convertToBitmap();
if (bitmap == null) {
return;
}
Matrix matrix = new Matrix();
switch (mResultImage.getImageOrientation()) {
case ORIENTATION_LANDSCAPE_LEFT:
matrix.postRotate(180);
break;
case ORIENTATION_PORTRAIT:
matrix.postRotate(90);
break;
case ORIENTATION_PORTRAIT_UPSIDE:
matrix.postRotate(-90);
break;
}

String resultString = mFakeR.getString("blinkid_unknown_result");

if (result instanceof VinScanResult) {
resultString = ((VinScanResult) result).getVin();
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
mScanResultImageView.setImageBitmap(bitmap);
}

} else if (result instanceof BlinkInputRecognitionResult) {
BlinkInputRecognitionResult biResult = (BlinkInputRecognitionResult) result;
if (biResult.isValid() && !biResult.isEmpty()) {
String parsedAmount = biResult.getParsedResult(OCR_PARSER_NAME);
if (parsedAmount != null && !parsedAmount.isEmpty()) {
resultString = parsedAmount;
}
} else {
resultString = mFakeR.getString("blinkid_invalid_result_message");
}
}
mScanResultStringView.setText(mResultHistory.getResult());
}
});
}

mScanResultStringView.setText(resultString);
private String extractResultString(BaseRecognitionResult result) {
String resultString = mFakeR.getString("blinkid_unknown_result");
if (result instanceof VinScanResult) {
resultString = ((VinScanResult) result).getVin();
} else if (result instanceof BlinkInputRecognitionResult) {
BlinkInputRecognitionResult biResult = (BlinkInputRecognitionResult) result;
if (biResult.isValid() && !biResult.isEmpty()) {
String parsedAmount = biResult.getParsedResult(OCR_PARSER_NAME);
if (parsedAmount != null && !parsedAmount.isEmpty()) {
resultString = parsedAmount;
}
});
} else {
mRecognizerView.resumeScanning(false);
} else {
resultString = mFakeR.getString("blinkid_invalid_result_message");
}
}
return resultString;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.phonegap.plugins.blinkid.resulthistory;

public class AcceptFirstResultHistory implements ResultHistory {

private String mResult;

@Override
public void onNewResult(String result) {
mResult = result;
}

@Override
public String getResult() {
return mResult;
}

@Override
public boolean hasValidResult() {
return true;
}

@Override
public void clear() {
mResult = null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.phonegap.plugins.blinkid.resulthistory;

public interface ResultHistory {

void onNewResult(String result);
String getResult();
boolean hasValidResult();
void clear();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.phonegap.plugins.blinkid.resulthistory;

//accept result as valid only if we got it 3 times in a row
public class VinResultHistory implements ResultHistory {

private static final int SAME_RESULT_COUNT_REQUIRED_FOR_SUCCESS = 3;
private int mSameScannedVinCount = 0;
private String mLastScannedVin;

@Override
public void onNewResult(String result) {
if(result != null && result.equals(mLastScannedVin)) {
mSameScannedVinCount++;
} else {
mSameScannedVinCount = 0;
mLastScannedVin = result;
}
}

@Override
public String getResult() {
return mLastScannedVin;
}

@Override
public boolean hasValidResult() {
return mSameScannedVinCount >= SAME_RESULT_COUNT_REQUIRED_FOR_SUCCESS;
}

@Override
public void clear() {
mSameScannedVinCount = 0;
mLastScannedVin = null;
}

}
2 changes: 1 addition & 1 deletion initCordovaDemoApp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ cordova plugin add ../BlinkMoto --variable CAMERA_USAGE_DESCRIPTION="Camera perm

# add android and ios support to the project
cordova platform add ios
cordova platform add android
cordova platform add android@6

# copy content of the www folder
cp -f -r ../www .
Expand Down

0 comments on commit 5d3ac97

Please sign in to comment.