Skip to content
This repository has been archived by the owner on Jan 12, 2019. It is now read-only.

feature: scan_progress #73

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
7 changes: 5 additions & 2 deletions card.io/src/main/java/io/card/payment/DetectionInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ class DetectionInfo {
public int expiry_month;
public int expiry_year;
public CreditCard detectedCard;
public int scanProgress; // enum scan completion: edge detect, vseg, hseg, scores, stability, expiry ...

public DetectionInfo() {
complete = false;
scanProgress = 0;

prediction = new int[16];
prediction[0] = -1;
Expand All @@ -35,7 +37,8 @@ public DetectionInfo() {

boolean sameEdgesAs(DetectionInfo other) {
return other.topEdge == this.topEdge && other.bottomEdge == this.bottomEdge
&& other.leftEdge == this.leftEdge && other.rightEdge == this.rightEdge;
&& other.leftEdge == this.leftEdge && other.rightEdge == this.rightEdge &&
this.scanProgress == other.scanProgress;
}

boolean detected() {
Expand Down Expand Up @@ -63,4 +66,4 @@ CreditCard creditCard() {
int numVisibleEdges() {
return (topEdge ? 1 : 0) + (bottomEdge ? 1 : 0) + (leftEdge ? 1 : 0) + (rightEdge ? 1 : 0);
}
}
}
21 changes: 20 additions & 1 deletion card.io/src/main/java/io/card/payment/OverlayView.java
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,25 @@ public void onDraw(Canvas canvas) {
mGuidePaint.setStyle(Paint.Style.FILL);
mGuidePaint.setColor(guideColor);

if (mDInfo != null) {
// set red -> green color based on progress
int scanProgress = mDInfo.scanProgress;
int color = Color.HSVToColor(new float[]{(float)(scanProgress / 8f) * 120f,1f,1f});
mGuidePaint.setColor(color);

// draw Progress Indicator Bars
int width = (int) (GUIDE_STROKE_WIDTH / 2 * mScale);
int height = (int) (50 * mScale);
int offset = (int) (10 * mScale);
for ( int i = 0; i < scanProgress; i++) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spacing is not consistent. Don't put a space before int.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed by e0b1376

int x1 = offset + (offset + width) * i;
int y1 = offset;
int x2 = x1 + width ;
int y2 = y1 + height;
canvas.drawRect(x1, y1, x2, y2, mGuidePaint);
}
}

// top left
canvas.drawRect(
guideStrokeRect(mGuide.left, mGuide.top, mGuide.left + tickLength, mGuide.top),
Expand Down Expand Up @@ -500,4 +519,4 @@ public void setUseCardIOLogo(boolean useCardIOLogo) {
public Rect getTorchRect() {
return mTorchRect;
}
}
}
2 changes: 1 addition & 1 deletion card.io/src/main/jni/card.io-dmz
46 changes: 31 additions & 15 deletions card.io/src/main/jni/nativeRecognizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ static int dmz_refcount = 0;
static ScannerState scannerState;
static bool detectOnly;
static bool flipped;
static bool lastFrameWasUsable;
static bool focusTriggered;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this removed? Is it unused?

Copy link
Contributor Author

@m-schmoock m-schmoock May 26, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, nowhere in it is was used or referenced. I just removed it because I stumbled upon it. I think the iOS part has a variable like this. Maybe it got obsolete somewhere due to refactorization.

static float minFocusScore;

static struct {
Expand All @@ -50,6 +50,7 @@ static struct {
jfieldID expiry_month;
jfieldID expiry_year;
jfieldID detectedCard;
jfieldID scanProgress;
} detectionInfoId;

static struct {
Expand Down Expand Up @@ -135,12 +136,13 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
detectionInfoId.expiry_month = env->GetFieldID(dInfoClass, "expiry_month", "I");
detectionInfoId.expiry_year = env->GetFieldID(dInfoClass, "expiry_year", "I");
detectionInfoId.detectedCard = env->GetFieldID(dInfoClass, "detectedCard", "Lio/card/payment/CreditCard;");
detectionInfoId.scanProgress = env->GetFieldID(dInfoClass, "scanProgress", "I");

if (!(detectionInfoId.complete && detectionInfoId.topEdge && detectionInfoId.bottomEdge
&& detectionInfoId.leftEdge && detectionInfoId.rightEdge
&& detectionInfoId.focusScore && detectionInfoId.prediction
&& detectionInfoId.expiry_month && detectionInfoId.expiry_year
&& detectionInfoId.detectedCard
&& detectionInfoId.detectedCard && detectionInfoId.scanProgress
)) {
dmz_error_log("at least one field was not found for DetectionInfo");
return -1;
Expand All @@ -159,7 +161,7 @@ JNIEXPORT void JNICALL Java_io_card_payment_CardScanner_nSetup(JNIEnv *env, jobj
detectOnly = shouldOnlyDetectCard;
minFocusScore = jMinFocusScore;
flipped = false;
lastFrameWasUsable = false;
focusTriggered = false;

if (dmz == NULL) {
dmz = dmz_context_create();
Expand Down Expand Up @@ -313,7 +315,8 @@ JNIEXPORT void JNICALL Java_io_card_payment_CardScanner_nScanFrame(JNIEnv *env,
orientation = dmz_opposite_orientation(orientation);
}

FrameScanResult result;
FrameScanResult frameResult = {0};
dmz_edges found_edges = {0};

IplImage *image = cvCreateImageHeader(cvSize(width, height), IPL_DEPTH_8U, 1);
jbyte *jBytes = env->GetByteArrayElements(jb, 0);
Expand All @@ -322,7 +325,9 @@ JNIEXPORT void JNICALL Java_io_card_payment_CardScanner_nScanFrame(JNIEnv *env,
float focusScore = dmz_focus_score(image, false);
env->SetFloatField(dinfo, detectionInfoId.focusScore, focusScore);
dmz_trace_log("focus score: %f", focusScore);

if (focusScore >= minFocusScore) {
frameResult.scan_progress = SCAN_PROGRESS_FOCUS;

IplImage *cbcr = cvCreateImageHeader(cvSize(width / 2, height / 2), IPL_DEPTH_8U, 2);
cbcr->imageData = ((char *)jBytes) + width * height;
Expand All @@ -333,33 +338,38 @@ JNIEXPORT void JNICALL Java_io_card_payment_CardScanner_nScanFrame(JNIEnv *env,

cvReleaseImageHeader(&cbcr);

dmz_edges found_edges;
dmz_corner_points corner_points;
bool cardDetected = dmz_detect_edges(image, cb, cr,
orientation,
&found_edges, &corner_points
);

updateEdgeDetectDisplay(env, thiz, dinfo, found_edges);

if (cardDetected) {
frameResult.scan_progress = SCAN_PROGRESS_EDGES;
IplImage *cardY = NULL;
dmz_transform_card(NULL, image, corner_points, orientation, false, &cardY);

if (!detectOnly) {
result.focus_score = focusScore;
result.flipped = flipped;
scanner_add_frame_with_expiry(&scannerState, cardY, jScanExpiry, &result);
if (result.usable) {
ScannerResult scanResult;
scanner_result(&scannerState, &scanResult);
frameResult.focus_score = focusScore;
frameResult.flipped = flipped;
scanner_add_frame_with_expiry(&scannerState, cardY, jScanExpiry, &frameResult);

// trigger focus once when scanprogress reaches certain levels
if(frameResult.scan_progress >= SCAN_PROGRESS_HSEG && !focusTriggered) {
focusTriggered = true;
env->SetFloatField(dinfo, detectionInfoId.focusScore, 0.0f);
dmz_debug_log("forcing re-focus on scan progress");
}

if (frameResult.usable) {
ScannerResult scanResult = {0};
scanner_frame_result(&scannerState, &scanResult, &frameResult);

if (scanResult.complete) {
setScanCardNumberResult(env, dinfo, &scanResult);
logDinfo(env, dinfo);
}
}
else if (result.upside_down) {
} else if (frameResult.upside_down) {
flipped = !flipped;
}
}
Expand All @@ -372,6 +382,12 @@ JNIEXPORT void JNICALL Java_io_card_payment_CardScanner_nScanFrame(JNIEnv *env,
cvReleaseImage(&cr);
}

// set scan progress and update edges (on every frame)
env->SetIntField(dinfo, detectionInfoId.scanProgress, frameResult.scan_progress);
// release focus trigger when frame was shit
if (frameResult.scan_progress < SCAN_PROGRESS_VSEG) focusTriggered = false;
updateEdgeDetectDisplay(env, thiz, dinfo, found_edges);

cvReleaseImageHeader(&image);
env->ReleaseByteArrayElements(jb, jBytes, 0);
}
Expand Down