upeksonly: use fpi_std_sq_dev() and fpi_mean_sq_diff_norm()

Use fpi_mean_sq_diff_norm() for blank line detection and
fpi_mean_sq_diff_norm() for duplicate line detection.
Fixes finger presence and removal detection.
This commit is contained in:
Vasily Khoruzhick 2016-02-09 20:15:38 -08:00
parent 5e29695969
commit e4eedef27e

View file

@ -43,6 +43,11 @@
#define MAX_ROWS 2048 #define MAX_ROWS 2048
#define MIN_ROWS 64 #define MIN_ROWS 64
#define BLANK_THRESHOLD 250
#define FINGER_PRESENT_THRESHOLD 32
#define FINGER_REMOVED_THRESHOLD 100
#define DIFF_THRESHOLD 13
enum { enum {
UPEKSONLY_2016, UPEKSONLY_2016,
UPEKSONLY_1000, UPEKSONLY_1000,
@ -101,8 +106,6 @@ struct sonly_dev {
int num_nonblank; int num_nonblank;
enum sonly_fs finger_state; enum sonly_fs finger_state;
int last_seqnum; int last_seqnum;
int diff_thresh;
int total_thresh;
enum sonly_kill_transfers_action killing_transfers; enum sonly_kill_transfers_action killing_transfers;
int kill_status_code; int kill_status_code;
@ -257,24 +260,6 @@ static void handoff_img(struct fp_img_dev *dev)
cancel_img_transfers(dev); cancel_img_transfers(dev);
} }
static void compute_rows(struct sonly_dev *sdev, unsigned char *a, unsigned char *b, int *diff,
int *total)
{
int i;
int _total = 0;
int _diff = 0;
for (i = 0; i < sdev->img_width; i++) {
if (a[i] > b[i])
_diff += a[i] - b[i];
else
_diff += b[i] - a[i];
_total += b[i];
}
*diff = _diff;
*total = _total;
}
static void row_complete(struct fp_img_dev *dev) static void row_complete(struct fp_img_dev *dev)
{ {
struct sonly_dev *sdev = dev->priv; struct sonly_dev *sdev = dev->priv;
@ -282,10 +267,10 @@ static void row_complete(struct fp_img_dev *dev)
if (sdev->num_rows > 0) { if (sdev->num_rows > 0) {
unsigned char *lastrow = sdev->rows->data; unsigned char *lastrow = sdev->rows->data;
int diff; int std_sq_dev, mean_sq_diff;
int total;
compute_rows(sdev, lastrow, sdev->rowbuf, &diff, &total); std_sq_dev = fpi_std_sq_dev(sdev->rowbuf, sdev->img_width);
mean_sq_diff = fpi_mean_sq_diff_norm(lastrow, sdev->rowbuf, sdev->img_width);
switch (sdev->finger_state) { switch (sdev->finger_state) {
case AWAIT_FINGER: case AWAIT_FINGER:
@ -294,14 +279,14 @@ static void row_complete(struct fp_img_dev *dev)
sdev->kill_ssm = sdev->loopsm; sdev->kill_ssm = sdev->loopsm;
cancel_img_transfers(dev); cancel_img_transfers(dev);
} }
fp_dbg("total: %d", total); fp_dbg("std_sq_dev: %d", std_sq_dev);
if (total < sdev->total_thresh) { if (std_sq_dev > BLANK_THRESHOLD) {
sdev->num_nonblank++; sdev->num_nonblank++;
} else { } else {
sdev->num_nonblank = 0; sdev->num_nonblank = 0;
} }
if (sdev->num_nonblank > 32) { if (sdev->num_nonblank > FINGER_PRESENT_THRESHOLD) {
sdev->finger_state = FINGER_DETECTED; sdev->finger_state = FINGER_DETECTED;
fpi_imgdev_report_finger_status(dev, TRUE); fpi_imgdev_report_finger_status(dev, TRUE);
} else { } else {
@ -314,7 +299,7 @@ static void row_complete(struct fp_img_dev *dev)
break; break;
} }
if (total < sdev->total_thresh) { if (std_sq_dev > BLANK_THRESHOLD) {
sdev->num_blank = 0; sdev->num_blank = 0;
} else { } else {
sdev->num_blank++; sdev->num_blank++;
@ -325,16 +310,16 @@ static void row_complete(struct fp_img_dev *dev)
* actual scan. Happens most commonly if scan is started * actual scan. Happens most commonly if scan is started
* from before the first joint resulting in a gap after the inital touch. * from before the first joint resulting in a gap after the inital touch.
*/ */
if ((sdev->num_blank > 32) if (sdev->num_blank > FINGER_REMOVED_THRESHOLD) {
&& ((sdev->num_rows > MIN_ROWS) || (sdev->num_blank > 5000))) {
sdev->finger_state = FINGER_REMOVED; sdev->finger_state = FINGER_REMOVED;
fp_dbg("detected finger removal. Blank rows: %d, Full rows: %d", sdev->num_blank, sdev->num_rows); fp_dbg("detected finger removal. Blank rows: %d, Full rows: %d", sdev->num_blank, sdev->num_rows);
handoff_img(dev); handoff_img(dev);
return; return;
} }
} }
fp_dbg("diff is %d", diff); fp_dbg("mean_sq_diff: %d, std_sq_dev: %d", mean_sq_diff, std_sq_dev);
if (diff < sdev->diff_thresh) { fp_dbg("num_blank: %d", sdev->num_blank);
if (mean_sq_diff < DIFF_THRESHOLD) {
return; return;
} }
} }
@ -1370,22 +1355,16 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
sdev->img_width = IMG_WIDTH_1000; sdev->img_width = IMG_WIDTH_1000;
upeksonly_driver.img_width = IMG_WIDTH_1000; upeksonly_driver.img_width = IMG_WIDTH_1000;
assembling_ctx.line_width = IMG_WIDTH_1000; assembling_ctx.line_width = IMG_WIDTH_1000;
sdev->diff_thresh = 1200;
sdev->total_thresh = 52000;
break; break;
case UPEKSONLY_1001: case UPEKSONLY_1001:
sdev->img_width = IMG_WIDTH_1001; sdev->img_width = IMG_WIDTH_1001;
upeksonly_driver.img_width = IMG_WIDTH_1001; upeksonly_driver.img_width = IMG_WIDTH_1001;
assembling_ctx.line_width = IMG_WIDTH_1001; assembling_ctx.line_width = IMG_WIDTH_1001;
sdev->diff_thresh = 400;
sdev->total_thresh = 40000;
break; break;
case UPEKSONLY_2016: case UPEKSONLY_2016:
sdev->img_width = IMG_WIDTH_2016; sdev->img_width = IMG_WIDTH_2016;
upeksonly_driver.img_width = IMG_WIDTH_2016; upeksonly_driver.img_width = IMG_WIDTH_2016;
assembling_ctx.line_width = IMG_WIDTH_2016; assembling_ctx.line_width = IMG_WIDTH_2016;
sdev->diff_thresh = 1200;
sdev->total_thresh = 52000;
break; break;
} }
fpi_imgdev_open_complete(dev, 0); fpi_imgdev_open_complete(dev, 0);