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:
parent
5e29695969
commit
e4eedef27e
1 changed files with 16 additions and 37 deletions
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue