Skip to content

Commit

Permalink
Various updates from May 2023
Browse files Browse the repository at this point in the history
* Increased search space for iris center to within 10% of the image margins (previously 30%) (#5)
* Increased allowable image size to 1000 height x 680 width from 640 x 480.
* Increased maximum iris diameter search space to 432 pixels from 202
* Note that the increased allowable image size and search space will result in an increased runtime
* Corrected typo for bottom_margin metric evaluation.
* Included ISO sharpness in overall calculation.

Co-authored-by: mbartenschlag <mbartenschlag@mitre.org>
  • Loading branch information
mbartenschlag and mbartenschlag authored May 31, 2023
1 parent e32883d commit e14fbc8
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 27 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ set(CPACK_PACKAGE_VERSION ${VERSION})
set(CPACK_GENERATOR "RPM")
set(CPACK_PACKAGE_NAME "biqt-iris")
set(CPACK_PACKAGE_VERSION_MAJOR 0)
set(CPACK_PACKAGE_VERSION_MINOR 3)
set(CPACK_PACKAGE_VERSION_MINOR 4)
set(CPACK_PACKAGE_VERSION_PATCH 0)
set(CPACK_PACKAGE_VERSION 0.3)
set(CPACK_PACKAGE_VERSION 0.4)
set(CPACK_PACKAGE_RELEASE 1)
set(CPACK_PACKAGE_CONTACT "MITRE Corporation")
set(CPACK_PACKAGE_VENDOR "MITRE Corporation")
Expand Down
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
> NOTICE
>
> This software (or technical data) was produced for the U. S. Government under contract, and is subject to the Rights in Data-General Clause 52.227-14, Alt. IV (DEC 2007)
>
> (C) 2022 The MITRE Corporation. All Rights Reserved.
> (C) 2023 The MITRE Corporation. All Rights Reserved.
> Approved for Public Release; Distribution Unlimited. Public Release Case Number 18-0812.
## Summary ##

BIQTIris is a reference library for computing iris image statistics using various quality attributes, features, and ISO metrics. It is
part of the open-source BIQT Framework.

Support is currently limited to mage files of size 480x480 and 640x480 pixels.
Raw image data is assumed to have a color depth of 8 bpp.
Images smaller than 256x256 or larger than 1000x680 are not supported. Raw image data is assumed to have a color depth of 8 bpp.

### Features ###

Expand All @@ -21,7 +19,7 @@ The following features are reported by this provider:
* `image_width` _value range: [256, +inf)_ - Image width measured in pixels.
* `iris_center_x` _value range: [1, +inf)_ - The x-coordinate of the iris center in the image.
* `iris_center_y` _value range: [1, +inf)_ - The y-coordinate of the iris center in the image.
* `iris_diameter` _value range: [224, 336]_ - Raw diameter of the iris measured in pixels.
* `iris_diameter` _value range: [224, 432]_ - Raw diameter of the iris measured in pixels.
* `pupil_center_x` _value range: [1, +inf)_ - The x-coordinate of the pupil center in the image.
* `pupil_center_y` _value range: [1, +inf)_ - The y-coordinate of the pupil center in the image.
* `pupil_diameter` _value range: [134, 202]_ - Raw diameter of the pupil measured in pixels.
Expand Down Expand Up @@ -68,4 +66,4 @@ NEW! The following ISO normalized statistics are also reported by this provider
* `normalized_iso_iris_sclera_contrast` _value range: [0, 1]_ - Normalized value for `iso_iris_sclera_contrast`.
* `normalized_iso_margin_adequacy` _value range: [0, 1]_ - Normalized value for `iso_margin_adequacy`.
* `normalized_iso_sharpness` _value range: [0, 1]_ - Normalized value for `iso_sharpness`.
* `normalized_iso_usable_iris_area` _value range: [0, 1]_ - Normalized value for `iso_usable_iris_area`.
* `normalized_iso_usable_iris_area` _value range: [0, 1]_ - Normalized value for `iso_usable_iris_area`.
4 changes: 2 additions & 2 deletions descriptor.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name" : "BIQTIris",
"description": "Reference iris image quality algorithm limited to 640x480 and 480x480 images.",
"version" : "0.3",
"description": "A reference iris image quality algorithm including ISO metrics.",
"version" : "0.4",
"sourceLanguage" : "c++",
"modality": "iris",
"attributes": [
Expand Down
6 changes: 3 additions & 3 deletions include/ImageOps.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,10 @@ class IMAGEOPS_EXPORT MFilter {
int GetIrisCenterY();
int GetPupilCenterX();
int GetPupilCenterY();

int min_width_ = 256;
int min_height_ = 256;
int max_width_ = 640;
int max_height_ = 480;
int max_width_ = 1000;
int max_height_ = 680;

private:
void CreateImagePointers(int width, int height);
Expand Down Expand Up @@ -203,6 +202,7 @@ class IMAGEOPS_EXPORT MFilter {
double n_iso_iris_pupil_ratio_value_;
double n_iso_pupil_boundary_circularity_value_;
double n_iso_greyscale_value_;
double n_iso_pupil_iris_contrast_value_;
double n_iso_ip_concentricity_value_;
double n_iso_margin_adequacy_value_;
double n_iso_sharpness_value_;
Expand Down
10 changes: 6 additions & 4 deletions src/BIQTIris.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,19 @@ Provider::EvaluationResult BIQTIris::evaluate(const std::string &file) {
return eval_result;
}

if (img.rows < mfo.min_width_ || img.cols < mfo.min_height_) {
if (img.cols < mfo.min_width_ || img.rows < mfo.min_height_) {
// March 2023 minor revisions
// Changed from if (img.rows < mfo.min_width_ || img.cols < mfo.min_height_)
// BIQT Iris has been observed to segfault on images that are very small. This block is intended
// to prevent that.
std::cerr << "File '" << file << "' is too small to process ("
<< img.rows << "x" << img.cols << ")." << std::endl;
<< img.cols << "x" << img.rows << ")." << std::endl;
eval_result.errorCode = 1;
return eval_result;
}
if (img.rows > mfo.max_width_ || img.cols < mfo.max_height_) {
if (img.cols > mfo.max_width_ || img.rows > mfo.max_height_) {
std::cerr << "File '" << file << "' is too large to process ("
<< img.rows << "x" << img.cols << ")." << std::endl;
<< img.cols << "x" << img.rows << ")." << std::endl;
eval_result.errorCode = 2;
return eval_result;
}
Expand Down
49 changes: 39 additions & 10 deletions src/ImageOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,26 @@ MFilter::MFilter()
iris_center_x_(0), iris_center_y_(0), iris_radius_(0), usable_iris_area_percent_(0),
contrast_low_limit_(30.0), contrast_upper_limit_(50.0),
n_contrast_factor_(1), defocus_low_limit_(60), defocus_upper_limit_(80),
n_defocus_factor_(1), i_d_low_limit_(170), i_d_med_limit_1_(200), i_d_med_limit_2_(350),
n_defocus_factor_(1), i_d_low_limit_(160), i_d_med_limit_1_(200), i_d_med_limit_2_(350),
i_d_upper_limit_(400), n_i_diam_factor_(1), isgs_mean_low_limit_(20),
isgs_mean_upper_limit_(30), n_isgs_factor_(1), iris_vis_low_limit_(0.4),
iris_vis_upper_limit_(0.7), ipgs_diff_low_limit_(15), ipgs_diff_upper_limit_(30),
n_ipgs_diff_factor_(1), n_iris_pupil_ratio_(1),
iris_pupil_ratio_low_limit_(0.20), iris_pupil_ratio_high_limit_(0.60),
n_iris_pupil_ratio_factor_(1), n_iris_vis_factor_(1), combined_quality_low_limit_(0),
combined_quality_upper_limit_(0.80), overall_quality_(0), min_r_trial_(28),
max_r_trial_(42), min_p_r_trial_(8), max_p_r_trial_(32), pupil_cx_(0), pupil_cy_(0),
combined_quality_upper_limit_(0.80), overall_quality_(0), min_r_trial_(20),
max_r_trial_(54), min_p_r_trial_(8), max_p_r_trial_(32), pupil_cx_(0), pupil_cy_(0),
pupil_rad_(5), pupil_d_(10), contrast_score_(0),
overall_margin_(1.0), isgs_diff_mean_avg_(0.0),
iris_pupil_gs_diff_(0.0), max_point_response_(1000), pupil_circularity_avg_deviation_(0.0),
n_iso_sharpness_value_(1.0), n_iso_greyscale_value_(1.0),
n_iso_margin_adequacy_value_(1.0), n_iso_iris_pupil_contrast_value_(1.0), n_iso_iris_pupil_ratio_value_(1.0) ,
n_iso_ip_concentricity_value_(1.0), n_iso_iris_sclera_contrast_value_(1.0), iso_overall_quality_(100){

// Updates for 01 March 2023 minor version
// Increased max_r_trial from 42 to 54 to allow finding rough iris diameters up to 432 pixels
// Decrease min_r_trial from 28 to 20 to allow finding rough iris diameters down to 80 pixels

cos = new int[101];

isgs_vals_ = new int[256];
Expand Down Expand Up @@ -249,7 +253,7 @@ int MFilter::Calc_ISO_Overall_Quality(double n_iso_sharpness_value, double n_iso
int iso_overall_quality_100 = 0;


iso_overall_quality = n_iso_greyscale_value * n_iso_iris_sclera_contrast_value * n_iso_margin_adequacy_value *
iso_overall_quality = n_iso_sharpness_value * n_iso_greyscale_value * n_iso_iris_sclera_contrast_value * n_iso_margin_adequacy_value *
n_iso_iris_pupil_contrast_value * n_iso_ip_concentricity_value;
iso_overall_quality_100 = 100 * iso_overall_quality;
return iso_overall_quality_100;
Expand All @@ -264,7 +268,7 @@ int MFilter::GetQuality(double n_contrast, double n_defocus, double n_iris_d,
n_margin * n_iris_pupil_ratio * n_iris_pupil_ratio_factor_ *
n_ipgs_diff * n_ipgs_diff_factor_);

if (combined_quality_ > combined_quality_low_limit_) {
if (combined_quality_ < combined_quality_low_limit_) {
overall_quality_ = 0;
}
if (combined_quality_ >= combined_quality_low_limit_ && combined_quality_ <= combined_quality_upper_limit_) {
Expand Down Expand Up @@ -396,7 +400,7 @@ double MFilter::NormalizeIrisDiameter(int iris_d) {
double MFilter::NormalizeISGS(int isgs_mean) {
n_isgs_mean_ = 0.0;
if (isgs_mean < isgs_mean_low_limit_) {
n_isgs_mean_ = 0.0; // Revision 2.2 on April 10, 2012
n_isgs_mean_ = 0.0; // Revision 2.2
}
if (isgs_mean >= isgs_mean_low_limit_ && isgs_mean <= isgs_mean_upper_limit_) {
n_isgs_mean_ =
Expand Down Expand Up @@ -808,9 +812,11 @@ void MFilter::ISOMarginAdequacy(int width, int height) {
}

double bottom_margin = (height - iris_center_y_ + iris_radius_) / (iris_radius_ * 0.2);
if (top_margin < 0) {
top_margin = 0;
if (bottom_margin < 0) {
bottom_margin = 0;
}
// March 2023 minor revisions
// Corrected bottom_margin check logic

iso_margin_adequacy_value_ = left_margin;
if (right_margin < iso_margin_adequacy_value_) {
Expand Down Expand Up @@ -873,6 +879,24 @@ void MFilter::ISOSharpness(const uint8_t *raw_img, const int width, const int he

double power = (double) ss / (double) (width * height);
iso_sharpness_value_ = 100.0 * ((power * power) / (power * power + c));


// calculate a normalized iso_sharpness
// Default to 1.0;
n_iso_sharpness_value_ = 1.0;
// Set limits for proportional value calculation
double lpl_iso_sharpness = 0.0;
// Substitute lower proportional limit below for stricter limits
double upl_iso_sharpness= 3.0;
if (iso_sharpness_value_ < lpl_iso_sharpness){
n_iso_sharpness_value_= 0.0;
}
if (iso_sharpness_value_ >= upl_iso_sharpness){
n_iso_sharpness_value_= 1.0;
}
if (iso_sharpness_value_ >= lpl_iso_sharpness && iso_sharpness_value_ <= upl_iso_sharpness){
n_iso_sharpness_value_= (iso_sharpness_value_ - lpl_iso_sharpness)/(upl_iso_sharpness - lpl_iso_sharpness);
}
}

void MFilter::FindIris(const uint8_t *frame_bytes, int width, int height) {
Expand Down Expand Up @@ -940,8 +964,10 @@ void MFilter::FindIrisCenter(int **l_edge_vals, int **r_edge_vals, int width,

int best_response = 0;
for (int r = min_r_trial_; r < max_r_trial_; r++, r++) {
for (int i_x = width * 3 / 10; i_x < width * 7 / 10; i_x++, i_x++) {
for (int i_y = height * 3 / 10; i_y < height * 7 / 10; i_y++, i_y++) {
for (int i_x = width * 1 / 10; i_x < width * 9 / 10; i_x++, i_x++) {
for (int i_y = height * 1 / 10; i_y < height * 9 / 10; i_y++, i_y++) {
// March 2023 minor revisions
// Increased search space for center of iris to within 10% of the left, right, top, and bottom of the image
// Version 2.2.1 change initialize dark_iris_center to zero
int dark_iris_center = 0;
int trial_response = 0;
Expand Down Expand Up @@ -1214,6 +1240,9 @@ void MFilter::FindFineIris(uint8_t **raw_bytes, int width, int height, int rough
}

isgs_diff_mean_avg_ = isgs_total / (pts_used * 15);
if (isgs_diff_mean_avg_< 0) {
isgs_diff_mean_avg_ = 0;
}
}

void MFilter::FindPupilCenter(int **edge_v, int width, int height, int iris_center_x,
Expand Down

0 comments on commit e14fbc8

Please sign in to comment.